import { command } from 'yargs';
import _get from 'lodash/fp/get';
import { readJsonSync, ensureDir, remove as remove$1, outputJSONSync, emptyDir, pathExists, copy, readFileSync, readJSONSync, pathExistsSync, existsSync as existsSync$1 } from 'fs-extra';
import { get, set } from 'env-dot-prop';
import humanize from 'humanize-string';
import titleize from 'titleize';
import { realpathSync, existsSync } from 'fs';
import { join, resolve, delimiter, isAbsolute, relative, parse, extname, normalize, dirname } from 'path';
import { sync } from 'resolve';
import logger__default, { error, Signale, warn, fatal, log } from 'signale';
import { __rest } from 'tslib';
import { getParsedData, headingsFromAst, parseMdx } from 'docz-utils/lib/mdast';
import { compiled, touch } from 'docz-utils/lib/fs';
import glob from 'fast-glob';
import { createHash } from 'crypto';
import slugify from '@sindresorhus/slugify';
import _isFunction from 'lodash/fp/isFunction';
import pReduce from 'p-reduce';
import getPkgRepo from 'get-pkg-repo';
import findup from 'find-up';
import WS from 'ws';
import _merge from 'lodash/fp/merge';
import _omit from 'lodash/fp/omit';
import { loadFrom, load, finds } from 'load-cfg';
import detectPort from 'detect-port';
import Config from 'webpack-chain';
import frontmatter from 'remark-frontmatter';
import remarkDocz from 'remark-docz';
import rehypeDocz from 'rehype-docz';
import slug from 'rehype-slug';
import webpack, { IgnorePlugin, HotModuleReplacementPlugin } from 'webpack';
import webpackBarPlugin from 'webpackbar';
import { minify } from 'html-minifier';
import miniHtmlWebpack, { generateCSSReferences, generateJSReferences } from 'mini-html-webpack-plugin';
import manifestPlugin from 'webpack-manifest-plugin';
import watchMissingNodeModules from 'react-dev-utils/WatchMissingNodeModulesPlugin';
import 'react-dev-utils/ModuleNotFoundPlugin';
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer';
import { TemplateTag, replaceResultTransformer, trimResultTransformer, oneLineTrim, html as html$1 } from 'common-tags';
import * as TerserPlugin from 'terser-webpack-plugin';
import getCacheIdentifier from 'react-dev-utils/getCacheIdentifier';
import WebpackDevServer from 'webpack-dev-server';
import { prepareUrls, createCompiler } from 'react-dev-utils/WebpackDevServerUtils';
import { static as static$1 } from 'express';
import errorOverlayMiddleware from 'react-dev-utils/errorOverlayMiddleware';
import evalSourceMapMiddleware from 'react-dev-utils/evalSourceMapMiddleware';
import ignoredFiles from 'react-dev-utils/ignoredFiles';
import chalk$1 from 'chalk';
import chokidar from 'chokidar';
import equal from 'fast-deep-equal';
import get$1 from 'lodash/get';
import _propEq from 'lodash/fp/propEq';
import externalProptypesHandler from 'react-docgen-external-proptypes-handler';
import actualNameHandler from 'react-docgen-actual-name-handler';
import reactDocgen from 'react-docgen';
import _entries from 'lodash/fp/entries';
import _contains from 'lodash/fp/contains';
import _prop from 'lodash/fp/prop';
import _isEmpty from 'lodash/fp/isEmpty';
import reactDocgenTs from 'react-docgen-typescript';
import ts$1 from 'typescript';
import spawn$1 from 'cross-spawn';

const ensureSlash = (filepath, needsSlash) => {
  const hasSlash = filepath.endsWith('/');

  if (hasSlash && !needsSlash) {
    return filepath.substr(filepath, filepath.length - 1);
  } else if (!hasSlash && needsSlash) {
    return `${filepath}/`;
  } else {
    return filepath;
  }
};
const root = realpathSync(process.cwd());
const resolveApp = to => resolve(root, to);
const resolveOwn = to => resolve(__dirname, '../', to);
const templates = join(sync('docz-core'), '../templates');
const packageJson = resolveApp('package.json');
const servedPath = base => ensureSlash(base, true);
const docz = resolveApp('.docz');
const app = resolve(docz, 'app/');
const cache = resolve(docz, 'cache/');
const appPublic = resolve(docz, 'public/');
const appNodeModules = resolveApp('node_modules');
const appPackageJson = resolveApp('package.json');
const appYarnLock = resolveOwn('yarn.lock');
const ownNodeModules = resolveOwn('node_modules');
const getDist = dest => join(root, dest);
const distPublic = dest => join(dest, 'public/');
const importsJs = resolve(app, 'imports.js');
const rootJs = resolve(app, 'root.jsx');
const indexJs = resolve(app, 'index.jsx');
const indexHtml = resolve(app, 'index.html');
const db = resolve(app, 'db.json');

var paths = /*#__PURE__*/Object.freeze({
  ensureSlash: ensureSlash,
  root: root,
  resolveApp: resolveApp,
  resolveOwn: resolveOwn,
  templates: templates,
  packageJson: packageJson,
  servedPath: servedPath,
  docz: docz,
  app: app,
  cache: cache,
  appPublic: appPublic,
  appNodeModules: appNodeModules,
  appPackageJson: appPackageJson,
  appYarnLock: appYarnLock,
  ownNodeModules: ownNodeModules,
  getDist: getDist,
  distPublic: distPublic,
  importsJs: importsJs,
  rootJs: rootJs,
  indexJs: indexJs,
  indexHtml: indexHtml,
  db: db
});

const getEnv = (val, defaultValue = null) => get(val, defaultValue, {
  parse: true
});

const getInitialTitle = pkg => {
  const name = _get('name', pkg) || 'MyDoc';
  return titleize(humanize(name.replace(/^@.*\//, '')));
};

const getInitialDescription = pkg => _get('description', pkg) || 'My awesome app using docz';

const setArgs = yargs => {
  const pkg = readJsonSync(appPackageJson, {
    throws: false
  });
  return yargs.option('base', {
    type: 'string',
    default: getEnv('docz.base', '/')
  }).option('source', {
    alias: 'src',
    type: 'string',
    default: getEnv('docz.source', './')
  }).option('files', {
    type: 'string',
    default: getEnv('docz.files', '**/*.{md,markdown,mdx}')
  }).option('ignore', {
    type: 'array',
    default: getEnv('docz.ignore', [])
  }).option('public', {
    type: 'string',
    default: getEnv('docz.public', '/public')
  }).option('dest', {
    alias: 'd',
    type: 'string',
    default: getEnv('docz.dest', '.docz/dist')
  }).option('editBranch', {
    alias: 'eb',
    type: 'string',
    default: getEnv('docz.edit.branch', 'master')
  }).option('config', {
    type: 'string',
    default: getEnv('docz.config', '')
  }).option('title', {
    type: 'string',
    default: getEnv('docz.title', getInitialTitle(pkg))
  }).option('description', {
    type: 'string',
    default: getEnv('docz.description', getInitialDescription(pkg))
  }).option('theme', {
    type: 'string',
    default: getEnv('docz.theme', 'theme')
  }).option('typescript', {
    alias: 'ts',
    type: 'boolean',
    default: getEnv('docz.typescript', false)
  }).option('propsParser', {
    type: 'boolean',
    default: getEnv('docz.props.parser', true)
  }).option('wrapper', {
    type: 'string',
    default: getEnv('docz.wrapper', null)
  }).option('indexHtml', {
    type: 'string',
    default: getEnv('docz.index.html', null)
  }).option('debug', {
    type: 'boolean',
    default: getEnv('docz.debug', false)
  }).option('clearConsole', {
    type: 'boolean',
    default: getEnv('docz.clear.console', true)
  }).option('host', {
    type: 'string',
    default: getEnv('docz.host', '127.0.0.1')
  }).option('port', {
    alias: 'p',
    type: 'number',
    default: getEnv('docz.port', 3000)
  }).option('websocketHost', {
    type: 'string',
    default: getEnv('docz.websocket.host', '127.0.0.1')
  }).option('websocketPort', {
    type: 'number',
    default: getEnv('docz.websocket.port', 60505)
  }).option('native', {
    type: 'boolean',
    default: getEnv('docz.native', false)
  }).option('codeSandbox', {
    type: 'boolean',
    default: getEnv('docz.codeSandbox', true)
  }).option('sourcemaps', {
    type: 'boolean',
    default: getEnv('docz.sourcemaps', true)
  }).option('separator', {
    type: 'string',
    default: getEnv('docz.separator', '-')
  }).option('open', {
    alias: 'o',
    describe: 'auto open browser in dev mode',
    type: 'boolean',
    default: false
  });
};

const populateNodePath = () => {
  // We support resolving modules according to `NODE_PATH`.
  // It works similar to `NODE_PATH` in Node itself:
  // https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
  // Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
  // Otherwise, we risk importing Node.js core modules into an app instead of Webpack shims.
  // https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421
  // We also resolve them to make sure all tools using them work consistently.
  set('node.path', get('node.path', '').split(delimiter).filter(folder => folder && !isAbsolute(folder)).map(folder => resolve(root, folder)).join(delimiter));
};

const configDotEnv = () => {
  const NODE_ENV = get('node.env');
  const dotenv = resolveApp('.env');
  const dotenvFiles = [`${dotenv}.${NODE_ENV}.local`, `${dotenv}.${NODE_ENV}`, // Don't include `.env.local` for `test` environment
  // since normally you expect tests to produce the same
  // results for everyone
  NODE_ENV !== 'test' && `${dotenv}.local`, dotenv]; // Load environment variables from .env* files. Suppress warnings using silent
  // if this file is missing. dotenv will never modify any environment variables
  // that have already been set.  Variable expansion is supported in .env files.
  // https://github.com/motdotla/dotenv

  dotenvFiles.filter(Boolean).forEach(dotenvFile => {
    require('dotenv').config({
      path: dotenvFile
    });
  });
};

const setEnv = env => {
  set('babel.env', env);
  set('node.env', env);
  configDotEnv();
  populateNodePath();
};
const getClientEnvironment = publicUrl => {
  const APP_TEST = /^(REACT_APP_)|(ANGULAR_APP_)|(VUE_APP_)|(DOCZ_)/i;
  const raw = Object.keys(process.env).filter(key => APP_TEST.test(key)).reduce((env, key) => {
    env[key] = process.env[key];
    return env;
  }, {
    // Useful for determining whether we’re running in production mode. Most
    // importantly, it switches React into the correct mode.
    NODE_ENV: get('node.env') || 'development',
    // Useful for resolving the correct path to static assets in `public`. For
    // example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />. This should
    // only be used as an escape hatch. Normally you would put images into the `src`
    // and `import` them in code to get their
    PUBLIC_URL: publicUrl
  });
  const stringified = {
    'process.env': Object.keys(raw).reduce((env, key) => {
      env[key] = JSON.stringify(raw[key]);
      return env;
    }, {})
  };
  return {
    raw,
    stringified
  };
};

const createId = file => createHash('md5').update(file).digest('hex');

const mountRoute = (base, route) => {
  if (base === '/') return route;
  const baseHasSlash = base.endsWith('/');
  if (baseHasSlash) return base.substr(0, base.length - 1) + route;
  return base + route;
};

class Entry {
  constructor(ast, file, src, config) {
    const filepath = this.getFilepath(file, src);
    const parsed = getParsedData(ast);
    const name = this.getName(filepath, parsed);
    this.id = createId(file);
    this.filepath = filepath;
    this.link = '';
    this.slug = this.slugify(filepath, config.separator);
    this.route = this.getRoute(parsed, config.base);
    this.name = name;
    this.menu = parsed.menu || '';
    this.headings = headingsFromAst(ast);
    this.settings = parsed;
  }

  setLink(url) {
    if (url) {
      this.link = url.replace('{{filepath}}', this.filepath);
    }
  }

  getFilepath(file, src) {
    const srcPath = resolve(root, src);
    const filepath = relative(srcPath, file);

    if (process.platform === 'win32') {
      return filepath.split('\\').join('/');
    }

    return filepath;
  }

  getName(filepath, parsed) {
    const filename = humanize(parse(filepath).name);
    return parsed && parsed.name ? parsed.name : filename;
  }

  slugify(filepath, separator) {
    const ext = extname(filepath);
    const fileWithoutExt = filepath.replace(ext, '');
    return slugify(fileWithoutExt, {
      separator
    });
  }

  getRoute(parsed, base) {
    const parsedRoute = _get('route', parsed);

    const route = parsedRoute || `/${this.slug}`;
    return mountRoute(base, route);
  }

}

class Plugin {
  constructor(p) {
    this.setConfig = p.setConfig;
    this.modifyBundlerConfig = p.modifyBundlerConfig;
    this.modifyBabelRc = p.modifyBabelRc;
    this.modifyFiles = p.modifyFiles;
    this.onPreCreateApp = p.onPreCreateApp;
    this.onCreateWebpackChain = p.onCreateWebpackChain;
    this.onCreateApp = p.onCreateApp;
    this.onServerListening = p.onServerListening;
    this.onPreBuild = p.onPreBuild;
    this.onPostBuild = p.onPostBuild;
    this.onPreRender = p.onPreRender;
    this.onPostRender = p.onPostRender;
  }

  static runPluginsMethod(plugins) {
    return (method, ...args) => {
      if (plugins && plugins.length > 0) {
        for (const plugin of plugins) {
          const fn = _get(method, plugin);

          _isFunction(fn) && fn(...args);
        }
      }
    };
  }

  static propsOfPlugins(plugins) {
    return prop => plugins && plugins.length > 0 ? plugins.map(p => _get(prop, p)).filter(Boolean) : [];
  }

  static reduceFromPlugins(plugins) {
    return (method, initial, ...args) => {
      return [...(plugins || [])].reduce((obj, plugin) => {
        const fn = _get(method, plugin);

        return fn && _isFunction(fn) ? fn(obj, ...args) : obj;
      }, initial);
    };
  }

  static reduceFromPluginsAsync(plugins) {
    return (method, initial, ...args) => {
      return pReduce([...(plugins || [])], (obj, plugin) => {
        const fn = _get(method, plugin);

        return Promise.resolve(fn && _isFunction(fn) ? fn(obj, ...args) : obj);
      }, initial);
    };
  }

}
function createPlugin(factory) {
  return new Plugin(factory);
}

const parseRepo = () => {
  try {
    const pkg = readJsonSync(appPackageJson);
    return getPkgRepo(pkg);
  } catch (err) {
    return null;
  }
};
const getRepoUrl = () => {
  const repo = parseRepo();
  return repo && (repo.browsetemplate && repo.browsetemplate.replace('{domain}', repo.domain).replace('{user}', repo.user).replace('{project}', repo.project).replace('{/tree/committish}', '') || repo.browse && repo.browse());
};

const getBitBucketPath = (branch, relative) => {
  const querystring = `?mode=edit&spa=0&at=${branch}&fileviewer=file-view-default`;
  const filepath = join(`/src/${branch}`, relative, `{{filepath}}`);
  return `${filepath}${querystring}`;
};

const getTree = (repo, branch, relative) => {
  const defaultPath = join(`/edit/${branch}`, relative, `{{filepath}}`);
  const bitBucketPath = getBitBucketPath(branch, relative);
  if (repo && repo.type === 'bitbucket') return bitBucketPath;
  return defaultPath;
};

const getRepoEditUrl = (src, branch) => {
  try {
    const repo = parseRepo();
    const project = parse(findup.sync('.git')).dir;
    const root$1 = join(root, src);
    const relative$1 = relative(project, root$1);
    const tree = getTree(repo, branch, relative$1);
    return repo && repo.browsetemplate && repo.browsetemplate.replace('{domain}', repo.domain).replace('{user}', repo.user).replace('{project}', repo.project).replace('{/tree/committish}', tree);
  } catch (err) {
    return null;
  }
};

const fromTemplates = file => join(templates, file);

const mapToObj = map => Array.from(map.entries()).reduce((obj, [key, value]) => Object.assign({}, obj, {
  [`${key}`]: value
}), {});

const matchFilesWithSrc = config => files => {
  const src = relative(root, config.src);
  return files.map(file => file.startsWith(src) ? file : join(src, file));
};

const writeAppFiles = async (config, dev) => {
  const {
    plugins,
    theme
  } = config;
  const props = Plugin.propsOfPlugins(plugins);
  const onPreRenders = props('onPreRender');
  const onPostRenders = props('onPostRender');
  const isProd = !dev;
  const root = await compiled(fromTemplates('root.tpl.js'), {
    minimize: false
  });
  const js = await compiled(fromTemplates('index.tpl.js'), {
    minimize: false
  });
  const websocketUrl = `ws://${config.websocketHost}:${config.websocketPort}`;
  const rawRootJs = root({
    theme,
    isProd,
    wrapper: config.wrapper,
    websocketUrl
  });
  const rawIndexJs = js({
    onPreRenders,
    onPostRenders,
    isProd
  });
  await remove$1(rootJs);
  await remove$1(indexJs);
  await touch(rootJs, rawRootJs);
  await touch(indexJs, rawIndexJs);
};

class Entries {
  static async writeApp(config, dev) {
    await ensureDir(app);
    await writeAppFiles(config, dev);
  }

  static async writeImports(map) {
    const imports = await compiled(fromTemplates('imports.tpl.js'));
    const rawImportsJs = imports({
      entries: Object.values(map)
    });
    await touch(join(app, 'imports.js'), rawImportsJs);
  }

  constructor(config) {
    this.repoEditUrl = getRepoEditUrl(config.src, config.editBranch);
    this.all = new Map();

    this.get = async () => this.getMap(config);
  }

  async getMap(config) {
    const {
      src,
      files: pattern,
      ignore,
      plugins,
      mdPlugins
    } = config;
    const arr = Array.isArray(pattern) ? pattern : [pattern];
    const toMatch = matchFilesWithSrc(config);
    const files = await glob(toMatch(arr), {
      ignore: ['**/node_modules/**'].concat(ignore),
      onlyFiles: true,
      unique: true,
      nocase: true,
      matchBase: true
    });

    const createEntry = async file => {
      try {
        const ast = await parseMdx(file, mdPlugins);
        const entry = new Entry(ast, file, src, config);
        if (this.repoEditUrl) entry.setLink(this.repoEditUrl);

        const {
          settings
        } = entry,
              rest = __rest(entry, ["settings"]);

        return Object.assign({}, settings, rest);
      } catch (err) {
        error(err);
        return null;
      }
    };

    const reduce = Plugin.reduceFromPlugins(plugins);
    const modifiedFiles = reduce('modifyFiles', files);
    const map = new Map();
    const entries = await Promise.all(modifiedFiles.map(createEntry).filter(Boolean));

    for (const entry of entries) {
      if (entry) {
        map.set(entry.filepath, entry);
      }
    }

    this.all = map;
    return mapToObj(map);
  }

}

class DataServer {
  constructor() {
    this.states = new Set();
    this.state = new Map();
    this.listeners = new Set();
  }

  register(states) {
    for (const state of states) this.states.add(state);

    return this;
  }

  async start() {
    const setState = (key, val) => this.setState(key, val);

    const getState = () => this.getState();

    await Promise.all(Array.from(this.states).map(async state => {
      if (!_isFunction(state.start)) return;
      return state.start({
        setState,
        getState
      });
    }));
  }

  close() {
    for (const state of this.states) {
      _isFunction(state.close) && state.close();
    }
  }

  onStateChange(listener) {
    this.listeners.add(listener);
    return () => this.listeners.clear();
  }

  getState() {
    return this.mapToObject(this.state);
  }

  setState(key, val) {
    const prev = _get(key, this.getState());

    const next = typeof val === 'function' ? val(prev) : val;
    this.state.set(key, next);
    this.writeDbFile();
    this.listeners.forEach(listener => {
      listener({
        type: `state.${key}`,
        payload: next
      });
    });
  }

  async writeDbFile() {
    outputJSONSync(db, this.mapToObject(this.state), {
      spaces: 2
    });
  }

  mapToObject(map) {
    return Array.from(map.entries()).reduce((obj, [key, val]) => Object.assign({}, obj, {
      [key]: val
    }), {});
  }

}

const onSignal = cb => {
  const signals = ['SIGINT', 'SIGTERM'];

  for (const sig of signals) {
    process.on(sig, async () => {
      await cb();
      process.exit();
    });
  }
};

const isSocketOpened = socket => socket.readyState === WS.OPEN;

const sender = socket => (type, payload) => {
  if (socket && isSocketOpened(socket)) {
    socket.send(JSON.stringify({
      type,
      payload
    }));
  }
};

class Socket {
  constructor(server, host, port) {
    if (server) {
      this.client = new WS.Server({
        server,
        host,
        port
      });
    }
  }

  onConnection(listener) {
    if (!this.client) return;
    this.client.on('connection', socket => {
      const emit = sender(socket);
      const subs = listener(socket, emit);

      const handleClose = async () => {
        subs();
        socket.terminate();
      };

      this.client.on('close', handleClose);
      onSignal(handleClose);
    });
  }

}

const toOmit = ['_', '$0', 'version', 'help'];
const htmlContext = {
  lang: 'en',
  favicon: 'https://cdn-std.dprcdn.net/files/acc_649651/LUKiMl'
};
const doczRcBaseConfig = {
  htmlContext,
  themeConfig: {},
  docgenConfig: {},
  filterComponents: files => files.filter(filepath => /\/[A-Z]\w*\.(js|jsx|ts|tsx)$/.test(filepath)),
  modifyBundlerConfig: config => config,
  modifyBabelRc: babelrc => babelrc,
  onCreateWebpackChain: () => null,
  menu: [],
  plugins: [],
  mdPlugins: [],
  hastPlugins: [],
  ignore: ['**/readme.md', '**/changelog.md', '**/code_of_conduct.md', '**/contributing.md', '**/license.md']
};
const getBaseConfig = (argv, custom) => {
  const initial = _omit(toOmit, argv);

  const base = Object.assign({}, initial, doczRcBaseConfig, {
    paths
  });
  return _merge(base, custom);
};
const parseConfig = async (argv, custom) => {
  const port = await detectPort(argv.port);
  const websocketPort = await detectPort(argv.websocketPort);
  const defaultConfig = getBaseConfig(argv, Object.assign({
    port,
    websocketPort,
    htmlContext
  }, custom));
  const config = argv.config ? loadFrom(resolve(argv.config), defaultConfig) : load('docz', defaultConfig);
  const reduceAsync = Plugin.reduceFromPluginsAsync(config.plugins);
  return reduceAsync('setConfig', config);
};

class Bundler {
  constructor(params) {
    const {
      args,
      config,
      server,
      build
    } = params;
    const run = Plugin.runPluginsMethod(args.plugins);
    this.args = args;
    this.config = config;
    this.server = server;
    this.builder = build;
    this.hooks = {
      onCreateWebpackChain(config, dev, args) {
        run('onCreateWebpackChain', config, dev, args);
      },

      onPreCreateApp(app) {
        run('onPreCreateApp', app);
      },

      onCreateApp(app) {
        run('onCreateApp', app);
      },

      onServerListening(server) {
        run('onServerListening', server);
      }

    };
  }

  async mountConfig(env) {
    const {
      plugins
    } = this.args;
    const isDev = env !== 'production';
    const reduce = Plugin.reduceFromPlugins(plugins);
    const userConfig = await this.config(this.hooks);
    const config = reduce('modifyBundlerConfig', userConfig, isDev, this.args);
    return this.args.modifyBundlerConfig(config, isDev, this.args);
  }

  async createApp(config) {
    return this.server(config, this.hooks);
  }

  async build(config) {
    const dist = getDist(this.args.dest);
    const publicDir = join(root, this.args.public);

    if (root === resolve(dist)) {
      logger__default.fatal(new Error('Unexpected option: "dest" cannot be set to the current working directory.'));
      process.exit(1);
    }

    await this.builder(config, dist, publicDir);
  }

}

const excludeNodeModules = filepath => /node_modules/.test(filepath) || /@babel(?:\/|\\{1,2})runtime/.test(filepath);

const sourceMaps = (config, args) => {
  const srcPath = resolve(root, args.src);
  config.module.rule('sourcemaps').test(/\.(js|mjs|jsx|ts|tsx|md|mdx)$/).include.add(srcPath).add(app).end().exclude.add(excludeNodeModules).end().use('sourcemaps').loader(require.resolve('source-map-loader')).end().enforce('pre');
};

const addScriptLoaders = opts => {
  const {
    rule,
    threadLoader = true,
    babelrc,
    args
  } = opts;
  return rule.when(!args.debug, rule => rule.use('cache-loader').loader(require.resolve('cache-loader')).options({
    cacheDirectory: cache
  })).when(Boolean(threadLoader), rule => rule.use('thread-loader').loader(require.resolve('thread-loader')).options({
    workers: require('os').cpus().length - 1
  })).use('babel-loader').loader(require.resolve('babel-loader')).options(babelrc).end();
};

const js = (config, args, babelrc) => {
  const srcPath = resolve(root, args.src);
  const rule = config.module.rule('js').test(/\.(jsx?|mjs)$/).include.add(srcPath).add(app).end().exclude.add(excludeNodeModules).end();
  addScriptLoaders({
    rule,
    babelrc,
    args
  });
};
const ts = (config, args, babelrc) => {
  const srcPath = resolve(root, args.src);
  const rule = config.module.rule('ts').test(/\.tsx?$/).include.add(srcPath).add(app).end().exclude.add(excludeNodeModules).end();
  addScriptLoaders({
    rule,
    babelrc,
    args
  });
};
const mdx = (config, args, babelrc) => {
  const {
    mdPlugins,
    hastPlugins
  } = args;
  const srcPath = resolve(root, args.src);
  const rule = config.module.rule('mdx').test(/\.(md|markdown|mdx)$/).include.add(srcPath).add(root).add(app).end().exclude.add(excludeNodeModules).end();
  addScriptLoaders({
    rule,
    babelrc,
    args,
    threadLoader: false
  }).use('mdx-loader').loader(require.resolve('@mdx-js/loader')).options({
    remarkPlugins: mdPlugins.concat([[frontmatter, {
      type: 'yaml',
      marker: '-'
    }], remarkDocz]),
    rehypePlugins: hastPlugins.concat([[rehypeDocz, {
      root: root,
      useCodeSandbox: args.codeSandbox
    }], slug])
  });
};
const INLINE_LIMIT = 10000;
const images = config => {
  config.module.rule('images').test(/\.(png|jpe?g|gif)(\?.*)?$/).use('url-loader').loader(require.resolve('url-loader')).options({
    limit: INLINE_LIMIT,
    name: `static/img/[name].[hash:8].[ext]`
  });
};
const svg = config => {
  config.module.rule('svg').test(/\.(svg)(\?.*)?$/).use('file-loader').loader(require.resolve('file-loader')).options({
    name: `static/img/[name].[hash:8].[ext]`
  });
};
const media = config => {
  config.module.rule('media').test(/\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/).use('url-loader').loader(require.resolve('url-loader')).options({
    limit: INLINE_LIMIT,
    name: `static/media/[name].[hash:8].[ext]`
  });
};
const fonts = config => {
  config.module.rule('fonts').test(/\.(woff2?|eot|ttf|otf)(\?.*)?$/i).use('url-loader').loader(require.resolve('url-loader')).options({
    limit: INLINE_LIMIT,
    name: `static/fonts/[name].[hash:8].[ext]`
  });
};

const wrapItems = item => Object.keys(item).map(key => `${key}="${item[key]}"`).join(' ');

const generateTags = template => (items = []) => items.map(template).join('');

const generateMetaTags = generateTags(item => `<meta ${wrapItems(item)}>`);
const generateLinkTags = generateTags(item => `<link ${wrapItems(item)}>`);
const generateScriptTags = generateTags(item => `<script ${wrapItems(item)}></script>`);

const generateRawTags = (items = []) => {
  if (typeof items === 'string' || items instanceof String) return items;
  return items.map(item => item).join('');
};

const getHtmlFilepath = indexHtml => indexHtml ? resolve(root, indexHtml) : fromTemplates('index.tpl.html');

const getPublicUrl = (config, dev) => {
  const prefix = config.base === '/' ? '' : config.base;
  return dev ? prefix : `${prefix}/public`;
};

const emptyLineTrim = new TemplateTag(replaceResultTransformer(/^\s*[\r\n]/gm, ''), trimResultTransformer);
const htmlTemplate = async indexHtml => compiled(getHtmlFilepath(indexHtml), {
  minimize: false,
  escape: false
});
const parseHtml = ({
  config,
  ctx,
  dev,
  template
}) => {
  const {
    title,
    description
  } = config;
  const {
    publicPath,
    css,
    js,
    lang = 'en',
    favicon,
    head = [],
    body = [],
    trimWhitespace
  } = ctx;
  const headStr = `
    ${favicon ? `<link rel="icon" type="image/x-icon" href="${favicon}">` : ''}
    ${head.meta ? generateMetaTags(head.meta) : ''}
    ${head.links ? generateLinkTags(head.links) : ''}
    ${head.raw ? generateRawTags(head.raw) : ''}
    ${head.scripts ? generateScriptTags(head.scripts) : ''}
    ${generateCSSReferences(css, publicPath)}`;
  const footerStr = `
    ${body.raw ? generateRawTags(body.raw) : ''}
    ${body.scripts ? generateScriptTags(body.scripts) : ''}
    ${generateJSReferences(js, publicPath)}`;
  const doc = html$1(template({
    title,
    description,
    lang,
    head: headStr,
    footer: footerStr,
    publicUrl: getPublicUrl(config, dev)
  }));
  return trimWhitespace ? oneLineTrim(doc) : emptyLineTrim(doc);
};

const assets = (config, args, env) => {
  const isProd = env === 'production';
  const base = servedPath(args.base);
  const publicPath = isProd ? base : '/';
  config.plugin('assets-plugin').use(manifestPlugin, [{
    publicPath,
    fileName: 'assets.json'
  }]);
};
const analyzer = config => {
  config.plugin('bundle-analyzer').use(BundleAnalyzerPlugin, [{
    generateStatsFile: true,
    openAnalyzer: false,
    analyzerMode: 'static'
  }]);
};
const injections = (config, args, env) => {
  const {
    stringify
  } = JSON;
  const base = servedPath(args.base);

  const plugin = require('webpack/lib/DefinePlugin');

  config.plugin('injections').use(plugin, [Object.assign({}, getClientEnvironment(base).stringified, {
    NODE_ENV: stringify(env),
    DOCZ_BASE_URL: stringify(base)
  })]);
};
const ignore = config => {
  config.plugin('ignore-plugin').use(IgnorePlugin, [/(regenerate\-unicode\-properties)|(elliptic)/, /node_modules/]);
};
const hot = config => {
  config.plugin('hot-module-replacement').use(HotModuleReplacementPlugin, [{
    multiStep: true
  }]);
};
const html = async (config, args, env) => {
  const dev = env !== 'production';
  const template = await htmlTemplate(args.indexHtml);
  config.plugin('html-plugin').use(miniHtmlWebpack, [{
    context: Object.assign({}, args.htmlContext, {
      trimWhitespace: true
    }),
    template: ctx => {
      const doc = parseHtml({
        ctx,
        dev,
        template,
        config: args
      });
      return dev ? doc : minify(doc, {
        removeComments: true,
        collapseWhitespace: true,
        removeRedundantAttributes: true,
        useShortDoctype: true,
        removeEmptyAttributes: true,
        removeStyleLinkTypeAttributes: true,
        keepClosingSlash: true,
        minifyJS: true,
        minifyCSS: true,
        minifyURLs: true
      });
    }
  }]);
};
const webpackBar = (config, args) => {
  config.plugin('webpackbar').use(webpackBarPlugin, [{
    name: 'Docz',
    color: '#41b883'
  }]);
};
const watchNodeModulesPlugin = config => {
  config.plugin('watch-missing-node-modules').use(watchMissingNodeModules, [appNodeModules]);
};

const minifier = (config, args) => {
  config.optimization.minimizer('js').use(TerserPlugin, [{
    terserOptions: {
      parse: {
        ecma: 8
      },
      compress: {
        ecma: 5,
        warnings: false,
        comparisons: false
      },
      mangle: {
        safari10: true
      },
      output: {
        ecma: 5,
        comments: false,
        ascii_only: true
      }
    },
    parallel: true,
    cache: !args.debug,
    sourceMap: args.sourcemaps
  }]);
};

const getBabelConfig = async (args, env, typescript) => {
  const isProd = env === 'production';
  const isDev = env === 'development';
  const localBabelRc = load('babel', {
    presets: [],
    plugins: []
  }, false, true);
  const presets = [[require.resolve('babel-preset-react-app'), {
    typescript,
    flow: !args.typescript
  }]];
  const defaultPlugins = [[require.resolve('babel-plugin-export-metadata'), {
    notUseSpecifiers: args.notUseSpecifiers
  }], [require.resolve('babel-plugin-named-asset-import'), {
    loaderMap: {
      svg: {
        ReactComponent: '@svgr/webpack?-prettier,-svgo![path]'
      }
    }
  }]];

  const config = _merge(localBabelRc, {
    presets,
    babelrc: false,
    cacheCompression: args.debug ? false : isProd,
    cacheDirectory: !args.debug,
    cacheIdentifier: args.debug ? null : getCacheIdentifier(isProd ? 'production' : isDev && 'development', ['docz', 'docz-core']),
    compact: isProd,
    customize: require.resolve('babel-preset-react-app/webpack-overrides'),
    plugins: defaultPlugins.concat(!isProd ? [require.resolve('react-hot-loader/babel')] : [])
  });

  const reduce = Plugin.reduceFromPlugins(args.plugins);
  const newConfig = reduce('modifyBabelRc', config, args);
  return args.modifyBabelRc(newConfig, args);
};

/* eslint-disable @typescript-eslint/camelcase */
const createConfig = (args, env) => async hooks => {
  const {
    debug
  } = args;
  const config = new Config();
  const isProd = env === 'production';
  const base = servedPath(args.base);
  const dist = getDist(args.dest);
  const srcPath = resolve(root, args.src);
  const publicPath = isProd ? base : '/';
  /**
   * general
   */

  config.context(root);
  config.set('mode', env);
  config.when(args.sourcemaps, cfg => cfg.devtool(isProd ? 'source-map' : 'cheap-module-eval-source-map'), cfg => cfg.devtool(false));
  config.node.merge({
    child_process: 'empty',
    dgram: 'empty',
    fs: 'empty',
    net: 'empty',
    tls: 'empty'
  });
  /**
   * output
   */

  const outputProd = output => output.filename('static/js/[name].[hash].js').sourceMapFilename('static/js/[name].[hash].js.map').chunkFilename('static/js/[name].[chunkhash:8].js');

  const outputDev = output => output.filename('static/js/[name].js').sourceMapFilename('static/js/[name].js.map');

  config.output.pathinfo(true).path(resolve(root, dist)).publicPath(publicPath).when(isProd, outputProd, outputDev).crossOriginLoading('anonymous').devtoolModuleFilenameTemplate(info => resolve(info.resourcePath).replace(/\\/g, '/'));
  /**
   * entries
   */

  config.entry('app').when(!isProd, entry => entry.add(require.resolve('react-dev-utils/webpackHotDevClient'))).add(indexJs);
  /**
   * resolve
   */

  config.resolve.set('symlinks', true);
  config.resolve.extensions.add('.web.js').add('.mjs').add('.js').add('.json').add('.web.jsx').add('.jsx').add('.mdx').end();
  config.resolve.alias.set('react-native$', 'react-native-web');

  const inYarnWorkspaces = __dirname.includes('/docz/core/docz-core');

  const doczDependenciesDir = inYarnWorkspaces ? join(__dirname, '../../../../node_modules') : ownNodeModules;
  config.resolve.modules.add('node_modules').add(doczDependenciesDir).add(srcPath).add(root).merge(get('node.path').split(delimiter).filter(Boolean));
  config.resolveLoader.set('symlinks', true).modules // prioritize our own
  .add('node_modules').add(doczDependenciesDir).add(root);
  /**
   * loaders
   */

  const jsBabelrc = await getBabelConfig(args, env);
  const tsBabelrc = await getBabelConfig(args, env, true);
  config.when(args.sourcemaps, cfg => sourceMaps(cfg, args));
  js(config, args, jsBabelrc);
  mdx(config, args, jsBabelrc);
  images(config);
  svg(config);
  media(config);
  fonts(config);
  await html(config, args, env);
  assets(config, args, env);
  ignore(config);
  injections(config, args, env);
  isProd && hot(config);
  config.when(debug, cfg => analyzer(cfg));
  config.when(!isProd, cfg => watchNodeModulesPlugin(cfg));
  config.when(!debug && !isProd, cfg => webpackBar(cfg, args));
  /**
   * typescript setup
   */

  config.when(args.typescript, cfg => {
    cfg.resolve.extensions.prepend('.ts').prepend('.tsx').end();
    ts(cfg, args, tsBabelrc);
  });
  /**
   * optimization
   */

  config.optimization.nodeEnv(env).namedModules(true).minimize(isProd).splitChunks({
    cacheGroups: {
      vendor: {
        test: /[\\/]node_modules[\\/]/,
        name: 'vendors',
        chunks: 'all'
      }
    }
  });
  config.performance.hints(false);
  config.when(isProd, cfg => minifier(cfg, args));
  hooks.onCreateWebpackChain(config, !isProd, args);
  args.onCreateWebpackChain(config, !isProd, args);
  return config.toConfig();
};

const devServerConfig = (hooks, args) => {
  const srcPath = resolve(root, args.src);
  const publicDir = resolve(root, args.public);
  const nonExistentDir = resolve(__dirname, 'non-existent');
  return {
    publicPath: '/',
    compress: true,
    logLevel: args.debug ? 'debug' : 'silent',
    clientLogLevel: args.debug ? 'info' : 'none',
    contentBase: [nonExistentDir],
    watchContentBase: true,
    hot: true,
    quiet: !args.debug,
    open: true,
    watchOptions: {
      ignored: ignoredFiles(srcPath)
    },
    overlay: false,
    host: args.host,
    port: args.port,
    historyApiFallback: {
      disableDotRule: true
    },
    disableHostCheck: true,

    before(app, server) {
      app.use('/public', static$1(publicDir));
      app.use(evalSourceMapMiddleware(server));
      app.use(errorOverlayMiddleware());
      hooks.onPreCreateApp(app);
    },

    after(app) {
      hooks.onCreateApp(app);
    }

  };
};

const useYarn = existsSync(appYarnLock);
const server = args => async (config, hooks) => ({
  start: async () => {
    const serverConfig = devServerConfig(hooks, args);
    const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';

    const appName = require(packageJson).name;

    const useTypescript = args.typescript;
    const urls = prepareUrls(protocol, args.host, args.port);
    const devSocket = {
      warnings: warnings => devServer.sockWrite(devServer.sockets, 'warnings', warnings),
      errors: errors => devServer.sockWrite(devServer.sockets, 'errors', errors)
    };
    const compiler = createCompiler({
      appName,
      config,
      devSocket,
      urls,
      useYarn,
      useTypescript,
      webpack
    });
    const devServer = new WebpackDevServer(compiler, serverConfig);
    return devServer.listen(args.port, args.host, err => {
      if (err) return logger__default.fatal(err);
      hooks.onServerListening(devServer);
    });
  }
});

const FSR = require('react-dev-utils/FileSizeReporter');

const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const {
  measureFileSizesBeforeBuild,
  printFileSizesAfterBuild
} = FSR;
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;

const hasCiEnvVar = () => get('ci', false, {
  parse: true
});

const copyPublicFolder = async (dest, publicDir) => {
  if (await pathExists(publicDir)) {
    await copy(publicDir, distPublic(dest), {
      dereference: true,
      filter: file => file !== indexHtml
    });
  }
};

const compile = config => new Promise((resolve, reject) => {
  let compiler;

  try {
    compiler = webpack(config);
  } catch (err) {
    onError(err);
  }

  compiler && compiler.run((err, stats) => {
    if (err) reject(err);
    resolve(stats);
  });
});

const builder = async (config, previousFileSizes) => new Promise(async (resolve, reject) => {
  try {
    const stats = await compile(config);
    const messages = formatWebpackMessages(stats.toJson({}, true));

    if (messages.errors.length) {
      return reject(new Error(messages.errors.join('\n\n')));
    }

    if (hasCiEnvVar() && messages.warnings.length) {
      warn('\nTreating warnings as errors because process.env.CI = true.\n' + 'Most CI servers set it automatically.\n');
      return reject(new Error(messages.warnings.join('\n\n')));
    }

    return resolve({
      stats,
      previousFileSizes,
      warnings: messages.warnings
    });
  } catch (err) {
    reject(err);
  }
});

const onSuccess = (dist, {
  stats,
  previousFileSizes,
  warnings
}) => {
  if (warnings.length) {
    log();
    warn('Compiled with warnings.\n');
    warn(warnings.join('\n\n'));
    warn('\nSearch for the ' + chalk$1.underline(chalk$1.yellow('keywords')) + ' to learn more about each warning.');
    warn('To ignore, add ' + chalk$1.cyan('// eslint-disable-next-line') + ' to the line before.\n');
  }

  log();
  log(`File sizes after gzip:\n`);
  printFileSizesAfterBuild(stats, previousFileSizes, dist, WARN_AFTER_BUNDLE_GZIP_SIZE, WARN_AFTER_CHUNK_GZIP_SIZE);
  log();
};

const onError = err => {
  log();
  fatal(err);
  process.exit(1);
  log();
};

const build = async (config, dist, publicDir) => {
  const interactive = new Signale({
    interactive: true,
    scope: 'build'
  });

  try {
    interactive.start('Creating an optimized bundle');
    await ensureDir(dist);
    const previousFileSizes = await measureFileSizesBeforeBuild(dist);
    await emptyDir(dist);
    await copyPublicFolder(dist, publicDir);
    const result = await builder(config, previousFileSizes);
    interactive.success('Build successfully created');
    onSuccess(dist, result);
  } catch (err) {
    fatal(chalk$1.red('Failed to compile.\n'));
    onError(err);
  }
};

const bundler = (args, env) => new Bundler({
  args,
  build,
  config: createConfig(args, env),
  server: server(args)
});

/**
 * Copyright (c) 2015-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.
 */

var chalk = require('chalk');

var execSync = require('child_process').execSync;

var spawn = require('cross-spawn');

var opn = require('opn'); // https://github.com/sindresorhus/opn#app


var OSX_CHROME = 'google chrome';
const Actions = Object.freeze({
  NONE: 0,
  BROWSER: 1,
  SCRIPT: 2
});

function getBrowserEnv() {
  // Attempt to honor this environment variable.
  // It is specific to the operating system.
  // See https://github.com/sindresorhus/opn#app for documentation.
  const value = process.env.BROWSER;
  let action;

  if (!value) {
    // Default.
    action = Actions.BROWSER;
  } else if (value.toLowerCase().endsWith('.js')) {
    action = Actions.SCRIPT;
  } else if (value.toLowerCase() === 'none') {
    action = Actions.NONE;
  } else {
    action = Actions.BROWSER;
  }

  return {
    action,
    value
  };
}

function executeNodeScript(scriptPath, url) {
  const extraArgs = process.argv.slice(2);
  const child = spawn('node', [scriptPath, ...extraArgs, url], {
    stdio: 'inherit'
  });
  child.on('close', code => {
    if (code !== 0) {
      console.log();
      console.log(chalk.red('The script specified as BROWSER environment variable failed.'));
      console.log(chalk.cyan(scriptPath) + ' exited with code ' + code + '.');
      console.log();
      return;
    }
  });
  return true;
}

function startBrowserProcess(browser, url) {
  // If we're on OS X, the user hasn't specifically
  // requested a different browser, we can try opening
  // Chrome with AppleScript. This lets us reuse an
  // existing tab when possible instead of creating a new one.
  const shouldTryOpenChromeWithAppleScript = process.platform === 'darwin' && (typeof browser !== 'string' || browser === OSX_CHROME);

  if (shouldTryOpenChromeWithAppleScript) {
    try {
      // Try our best to reuse existing tab
      // on OS X Google Chrome with AppleScript
      execSync('ps cax | grep "Google Chrome"');
      execSync('osascript openChrome.applescript "' + encodeURI(url) + '"', {
        cwd: __dirname,
        stdio: 'ignore'
      });
      return true;
    } catch (err) {// Ignore errors.
    }
  } // Another special case: on OS X, check if BROWSER has been set to "open".
  // In this case, instead of passing `open` to `opn` (which won't work),
  // just ignore it (thus ensuring the intended behavior, i.e. opening the system browser):
  // https://github.com/facebook/create-react-app/pull/1690#issuecomment-283518768


  if (process.platform === 'darwin' && browser === 'open') {
    browser = undefined;
  } // Fallback to opn
  // (It will always open new tab)


  try {
    var options = {
      app: browser,
      wait: false
    };
    opn(url, options).catch(() => {}); // Prevent `unhandledRejection` error.

    return true;
  } catch (err) {
    return false;
  }
}
/**
 * Reads the BROWSER environment variable and decides what to do with it. Returns
 * true if it opened a browser or ran a node.js script, otherwise false.
 */


function openBrowser(url) {
  const {
    action,
    value
  } = getBrowserEnv();

  switch (action) {
    case Actions.NONE:
      // Special case: BROWSER="none" will prevent opening completely.
      return false;

    case Actions.SCRIPT:
      return executeNodeScript(value, url);

    case Actions.BROWSER:
      return startBrowserProcess(value, url);

    default:
      throw new Error('Not implemented.');
  }
}

const mapToArray = (map = []) => Object.entries(map).map(entry => entry && {
  key: entry[0],
  value: entry[1]
}).filter(Boolean);

const updateEntries = entries => async p => {
  const prev = _get('entries', p.getState());

  const map = await entries.get();

  if (map && !equal(prev, map)) {
    await Entries.writeImports(map);
    p.setState('entries', mapToArray(map));
  }
};

const state = (entries, config, dev) => {
  const src = relative(root, config.src);
  const files = Array.isArray(config.files) ? config.files.map(filePath => join(src, filePath)) : join(src, config.files);
  const ignored = config.watchIgnore || /(((^|[\/\\])\..+)|(node_modules))/;
  const watcher = chokidar.watch(files, {
    cwd: root,
    ignored,
    persistent: true
  });
  watcher.setMaxListeners(Infinity);
  return {
    id: 'entries',
    start: async params => {
      const update = updateEntries(entries);
      await update(params);

      if (dev) {
        watcher.on('add', async () => update(params));
        watcher.on('change', async () => update(params));
        watcher.on('unlink', async () => update(params));
        watcher.on('raw', async (event, path, details) => {
          if (details.event === 'moved' && details.type === 'directory') {
            await update(params);
          }
        });
      }
    },
    close: () => {
      watcher.close();
    }
  };
};

const getInitialConfig = config => {
  const pkg = readJsonSync(appPackageJson, {
    throws: false
  });
  const repoUrl = getRepoUrl();
  return {
    title: config.title,
    description: config.description,
    menu: config.menu,
    version: get$1(pkg, 'version'),
    repository: repoUrl,
    native: config.native,
    codeSandbox: config.codeSandbox,
    themeConfig: config.themeConfig,
    separator: config.separator
  };
};

const update = async (params, initial, {
  config
}) => {
  const next = config ? loadFrom(resolve(config), initial, true, true) : load('docz', initial, true, true);
  params.setState('config', next);
};

const state$1 = (config, dev) => {
  const initial = getInitialConfig(config);
  const glob = config.config || finds('docz');
  const ignored = config.watchIgnore || /(((^|[\/\\])\..+)|(node_modules))/;
  const watcher = chokidar.watch(glob, {
    cwd: root,
    ignored,
    persistent: true
  });
  watcher.setMaxListeners(Infinity);
  return {
    id: 'config',
    start: async params => {
      const fn = async () => update(params, initial, config);

      await update(params, initial, config);

      if (dev) {
        watcher.on('add', fn);
        watcher.on('change', fn);
        watcher.on('unlink', fn);
      }
    },
    close: () => {
      watcher.close();
    }
  };
};

const throwError = err => {
  logger__default.fatal(`Error parsing static types`);
  logger__default.error(err);
};

const jsParser = (files, config) => {
  const resolver = config.docgenConfig.resolver || reactDocgen.resolver.findAllExportedComponentDefinitions;

  const parseFilepathProps = filepath => {
    const handlers = reactDocgen.defaultHandlers.concat([externalProptypesHandler(filepath), actualNameHandler]);

    try {
      const code = readFileSync(filepath, 'utf-8');
      const props = reactDocgen.parse(code, resolver, handlers);
      return {
        key: normalize(filepath),
        value: props
      };
    } catch (err) {
      if (config.debug) throwError(err);
      return null;
    }
  };

  return files.map(parseFilepathProps).filter(Boolean);
};

const digest = str => createHash('md5').update(str).digest('hex');

const cacheFilepath = join(cache, 'propsParser.json');

const readCacheFile = () => readJSONSync(cacheFilepath, {
  throws: false
});

function checkFilesOnCache(files) {
  const cache = readCacheFile();
  if (_isEmpty(cache)) return files;
  return files.filter(filepath => {
    const normalized = normalize(filepath);
    const hash = digest(readFileSync(normalized, 'utf-8'));

    const found = _get(normalized, cache);

    return found && hash !== found.hash;
  });
}

function writePropsOnCache(items) {
  const cache = readCacheFile();
  const newCache = items.reduce((obj, {
    key: filepath,
    value
  }) => {
    const normalized = normalize(filepath);
    const hash = digest(readFileSync(normalized, 'utf-8'));
    return Object.assign({}, obj, {
      [normalized]: {
        hash,
        props: value
      }
    });
  }, {});
  outputJSONSync(cacheFilepath, Object.assign({}, cache, newCache));
}

function getPropsOnCache() {
  const cache = readCacheFile();

  if (_isEmpty(cache)) {
    warn('Any cache was found with your props definitions');
    warn("We'll parse your components to get props from them");
    warn('Depending on your components, this could take while...');
    return [];
  }

  return Object.entries(cache).map(([key, value]) => ({
    key,
    value: _get('props', value)
  }));
}

const mergeWithCache = (cache, props) => {
  const keys = props.map(_prop('key'));
  return cache.filter(item => !_contains(item.key, keys)).concat(props);
};

const removeFromCache = filepath => {
  const cache = readCacheFile();
  outputJSONSync(cacheFilepath, _omit(filepath, cache));
};

const getInitialFilesMap = () => {
  const cache = readCacheFile();
  if (_isEmpty(cache)) return new Map();
  const map = new Map();

  _entries(cache).forEach(([filepath]) => {
    const exist = pathExistsSync(filepath);

    if (!exist) {
      removeFromCache(filepath);
    } else {
      map.set(filepath, {
        text: readFileSync(filepath, 'utf-8'),
        version: 0
      });
    }
  });

  return map;
};

let languageService = null;
const filesMap = getInitialFilesMap();

function getTSConfigFile(tsconfigPath) {
  const basePath = dirname(tsconfigPath);
  const configFile = ts$1.readConfigFile(tsconfigPath, ts$1.sys.readFile);
  return ts$1.parseJsonConfigFileContent(configFile.config, ts$1.sys, basePath, {}, tsconfigPath);
}

function loadFiles(filesToLoad) {
  filesToLoad.forEach(filepath => {
    const normalized = normalize(filepath);
    const found = filesMap.get(normalized);
    filesMap.set(normalized, {
      text: readFileSync(normalized, 'utf-8'),
      version: found ? found.version + 1 : 0
    });
  });
}

function createServiceHost(compilerOptions, files) {
  return {
    getScriptFileNames: () => {
      return [...files.keys()];
    },
    getScriptVersion: fileName => {
      const file = files.get(fileName);
      return file && file.version.toString() || '';
    },
    getScriptSnapshot: fileName => {
      if (!existsSync$1(fileName)) {
        return undefined;
      }

      let file = files.get(fileName);

      if (file === undefined) {
        const text = readFileSync(fileName).toString();
        file = {
          version: 0,
          text
        };
        files.set(fileName, file);
      }

      return ts$1.ScriptSnapshot.fromString(file.text);
    },
    getCurrentDirectory: () => process.cwd(),
    getCompilationSettings: () => compilerOptions,
    getDefaultLibFileName: options => ts$1.getDefaultLibFilePath(options),
    fileExists: ts$1.sys.fileExists,
    readFile: ts$1.sys.readFile,
    readDirectory: ts$1.sys.readDirectory
  };
}

const parseFiles = (files, config, tsconfig) => {
  const opts = {
    propFilter(prop) {
      if (prop.parent == null) return true;
      const propFilter = config.docgenConfig.propFilter;
      const val = propFilter && _isFunction(propFilter) && propFilter(prop);
      return !prop.parent.fileName.includes('node_modules') || Boolean(val);
    },

    componentNameResolver(exp, source) {
      const componentNameResolver = config.docgenConfig.resolver;
      const val = componentNameResolver && _isFunction(componentNameResolver) && componentNameResolver(exp, source);
      return val;
    }

  };
  loadFiles(files);
  const parser = reactDocgenTs.withCustomConfig(tsconfig, opts);

  const compilerOptions = _get('options', getTSConfigFile(tsconfig));

  const programProvider = () => {
    if (languageService) return languageService.getProgram();
    const servicesHost = createServiceHost(compilerOptions, filesMap);
    const documentRegistry = ts$1.createDocumentRegistry();
    languageService = ts$1.createLanguageService(servicesHost, documentRegistry);
    return languageService.getProgram();
  };

  return files.map(filepath => ({
    key: normalize(filepath),
    value: parser.parseWithProgramProvider(filepath, programProvider)
  }));
};

const tsParser = (files, config, tsconfig) => {
  if (!tsconfig) return null;
  const filesToLoad = checkFilesOnCache(files);
  const propsOnCache = getPropsOnCache();
  if (!filesToLoad.length) return propsOnCache;
  const next = parseFiles(filesToLoad, config, tsconfig);
  writePropsOnCache(next);
  return mergeWithCache(propsOnCache, next);
};

const docgen = async (files, config) => {
  const tsconfig = await findup('tsconfig.json', {
    cwd: root
  });
  return config.typescript ? tsParser(files, config, tsconfig) : jsParser(files, config);
};

const getPattern = config => {
  const {
    ignore,
    src: source,
    typescript: ts,
    docgenConfig: docgenConfig
  } = config;
  const src = relative(root, docgenConfig.searchPath ? docgenConfig.searchPath : source);
  return ignore.map(entry => `!**/${entry}`).concat([join(src, ts ? '**/*.{ts,tsx}' : '**/*.{js,jsx,mjs}'), '!**/node_modules', '!**/doczrc.js']);
};

const removeFilepath = (items, filepath) => items.filter(item => item.key !== filepath);

const initial = (config, pattern) => async p => {
  const {
    filterComponents
  } = config;
  const files = await glob(pattern, {
    cwd: root
  });
  const filtered = filterComponents ? filterComponents(files) : files;
  const metadata = await docgen(filtered, config);
  p.setState('props', metadata);
};

const change = (p, config) => async filepath => {
  const prev = _get('props', p.getState());

  const metadata = await docgen([filepath], config);
  const filtered = metadata.filter(_propEq('key', filepath));
  const next = removeFilepath(prev, filepath).concat(filtered);
  p.setState('props', next);
};

const remove = p => async filepath => {
  const prev = _get('props', p.getState());

  const next = removeFilepath(prev, filepath);
  p.setState('props', next);
};

const state$2 = (config, dev) => {
  const pattern = getPattern(config);
  const ignored = config.watchIgnore || /(((^|[\/\\])\..+)|(node_modules))/;
  const watcher = chokidar.watch(pattern, {
    cwd: root,
    ignored,
    persistent: true
  });
  watcher.setMaxListeners(Infinity);
  return {
    id: 'props',
    start: async params => {
      const addInitial = initial(config, pattern);
      await addInitial(params);

      if (dev) {
        watcher.on('change', change(params, config));
        watcher.on('unlink', remove(params));
      }
    },
    close: () => {
      watcher.close();
    }
  };
};



var index = /*#__PURE__*/Object.freeze({
  entries: state,
  config: state$1,
  props: state$2
});

process.setMaxListeners(Infinity);
const dev = async args => {
  const env = get('node.env');
  const config = await parseConfig(args);
  const bundler$1 = bundler(config, env);
  const entries = new Entries(config);
  const {
    websocketHost,
    websocketPort
  } = config;
  const bundlerConfig = await bundler$1.mountConfig(env);
  const app = await bundler$1.createApp(bundlerConfig);

  try {
    await Entries.writeApp(config, true);
    await Entries.writeImports((await entries.get()));
  } catch (err) {
    fatal('Failed to build your files');
    error(err);
    process.exit(1);
  }

  const server = await app.start();
  const dataServer = new DataServer();
  const socket = new Socket(server, websocketHost, websocketPort);
  if (config.propsParser) dataServer.register([state$2(config, true)]);
  dataServer.register([state$1(config, true), state(entries, config, true)]);

  try {
    await dataServer.start();
    if (args.open || args.o) openBrowser(`http://${config.host}:${config.port}`);
  } catch (err) {
    fatal('Failed to process data server');
    error(err);
    dataServer.close();
    process.exit(1);
  }

  socket.onConnection((_, emit) => {
    const subscribe = dataServer.onStateChange(action => {
      emit(action.type, action.payload);
    });
    return () => subscribe();
  });
  onSignal(async () => {
    dataServer.close();
    server.close();
  });
  server.on('close', async () => {
    dataServer.close();
  });
};

const build$1 = async args => {
  const env = get('node.env');
  const config = await parseConfig(args);
  const entries = new Entries(config);
  const bundler$1 = bundler(config, env);
  const bundlerConfig = await bundler$1.mountConfig(env);
  const run = Plugin.runPluginsMethod(config.plugins);
  const dataServer = new DataServer();
  if (config.propsParser) dataServer.register([state$2(config)]);
  dataServer.register([state$1(config), state(entries, config)]);

  try {
    await Entries.writeApp(config, false);
    await Entries.writeImports((await entries.get()));
    await dataServer.start();
    await run('onPreBuild', config);
    await bundler$1.build(bundlerConfig);
    await run('onPostBuild', config);
    dataServer.close();
  } catch (err) {
    error(err);
    process.exit(1);
    dataServer.close();
  }
};

const serve = async args => {
  const config = await parseConfig(args);
  const dist = getDist(config.dest);
  spawn$1.sync('serve', ['-s', dist], {
    stdio: 'inherit'
  });
};

const cli = () => {
  return command('dev', 'initialize docz dev server', setArgs, async args => {
    setEnv('development');
    await dev(args);
  }).command('build', 'build dir as static site', setArgs, async args => {
    setEnv('production');
    await build$1(args);
    process.exit();
  }).command('serve', 'serve dir as static site', setArgs, async args => {
    setEnv('production');
    await build$1(args);
    await serve(args);
    process.exit();
  }).demandCommand().help().wrap(72).epilog('for more information visit https://github.com/pedronauck/docz').showHelpOnFail(false, 'whoops, something went wrong! run with --help').argv;
};

/** cli exports */

export { DataServer, Entries, Entry, Plugin, cli, createPlugin, getBaseConfig, parseConfig, setArgs, index as states };
