<commit_before>#!/usr/bin/env node
/* tslint:disable:no-implicit-dependencies */
import * as React from 'react';
import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';

import { compile } from 'handlebars';
import { createServer, IncomingMessage, ServerResponse } from 'http';
import { dirname, join, resolve } from 'path';

import * as zlib from 'zlib';

// @ts-ignore
import { createStore, loadAndBundleSpec, Redoc } from 'redoc';

import { watch } from 'chokidar';
import { createReadStream, existsSync, readFileSync, ReadStream, writeFileSync } from 'fs';
import * as mkdirp from 'mkdirp';

import * as YargsParser from 'yargs';

interface Options {
  ssr?: boolean;
  watch?: boolean;
  cdn?: boolean;
  output?: string;
  title?: string;
  port?: number;
  templateFileName?: string;
  templateOptions?: any;
  redocOptions?: any;
}

const BUNDLES_DIR = dirname(require.resolve('redoc'));

/* tslint:disable-next-line */
YargsParser.command(
  'serve <spec>',
  'start the server',
  yargs => {
    yargs.positional('spec', {
      describe: 'path or URL to your spec',
    });

    yargs.option('s', {
      alias: 'ssr',
      describe: 'Enable server-side rendering',
      type: 'boolean',
    });

    yargs.option('p', {
      alias: 'port',
      type: 'number',
      default: 8080,
    });

    yargs.option('w', {
      alias: 'watch',
      type: 'boolean',
    });

    yargs.demandOption('spec');
    return yargs;
  },
  async argv => {
    const config: Options = {
      ssr: argv.ssr as boolean,
      watch: argv.watch as boolean,
      templateFileName: argv.template as string,
      templateOptions: argv.templateOptions || {},
      redocOptions: argv.options || {},
    };

    try {
      await serve(argv.port as number, argv.spec as string, config);
    } catch (e) {
      handleError(e);
    }
  },
)
  .command(
    'bundle <spec>',
    'bundle spec into zero-dependency HTML-file',
    yargs => {
      yargs.positional('spec', {
        describe: 'path or URL to your spec',
      });

      yargs.option('o', {
        describe: 'Output file',
        alias: 'output',
        type: 'string',
        default: 'redoc-static.html',
      });

      yargs.options('title', {
        describe: 'Page Title',
        type: 'string',
        default: 'ReDoc documentation',
      });

      yargs.option('cdn', {
        describe: 'Do not include ReDoc source code into html page, use link to CDN instead',
        type: 'boolean',
        default: false,
      });

      yargs.demandOption('spec');
      return yargs;
    },
    async argv => {
      const config: Options = {
        ssr: true,
        output: argv.o as string,
        cdn: argv.cdn as boolean,
        title: argv.title as string,
        templateFileName: argv.template as string,
        templateOptions: argv.templateOptions || {},
        redocOptions: argv.options || {},
      };

      try {
        await bundle(argv.spec, config);
      } catch (e) {
        handleError(e);
      }
    },
  )
  .demandCommand()
  .options('t', {
    alias: 'template',
    describe: 'Path to handlebars page template, see https://git.io/vh8fP for the example ',
    type: 'string',
  })
  .options('templateOptions', {
    describe:
      'Additional options that you want pass to template. Use dot notation, e.g. templateOptions.metaDescription',
  })
  .options('options', {
    describe: 'ReDoc options, use dot notation, e.g. options.nativeScrollbars',
  }).argv;

async function serve(port: number, pathToSpec: string, options: Options = {}) {
  let spec = await loadAndBundleSpec(pathToSpec);
  let pageHTML = await getPageHTML(spec, pathToSpec, options);

  const server = createServer((request, response) => {
    console.time('GET ' + request.url);
    if (request.url === '/redoc.standalone.js') {
      respondWithGzip(
        createReadStream(join(BUNDLES_DIR, 'redoc.standalone.js'), 'utf8'),
        request,
        response,
        {
          'Content-Type': 'application/javascript',
        },
      );
    } else if (request.url === '/') {
      respondWithGzip(pageHTML, request, response);
    } else if (request.url === '/spec.json') {
      const specStr = JSON.stringify(spec, null, 2);
      respondWithGzip(specStr, request, response, {
        'Content-Type': 'application/json',
      });
    } else {
      response.writeHead(404);
      response.write('Not found');
      response.end();
    }

    console.timeEnd('GET ' + request.url);
  });

  console.log();<commit_msg>fix(cli): Add missing content type header on compressed responses of /<commit_after>#!/usr/bin/env node
/* tslint:disable:no-implicit-dependencies */
import * as React from 'react';
import { renderToString } from 'react-dom/server';
import { ServerStyleSheet } from 'styled-components';

import { compile } from 'handlebars';
import { createServer, IncomingMessage, ServerResponse } from 'http';
import { dirname, join, resolve } from 'path';

import * as zlib from 'zlib';

// @ts-ignore
import { createStore, loadAndBundleSpec, Redoc } from 'redoc';

import { watch } from 'chokidar';
import { createReadStream, existsSync, readFileSync, ReadStream, writeFileSync } from 'fs';
import * as mkdirp from 'mkdirp';

import * as YargsParser from 'yargs';

interface Options {
  ssr?: boolean;
  watch?: boolean;
  cdn?: boolean;
  output?: string;
  title?: string;
  port?: number;
  templateFileName?: string;
  templateOptions?: any;
  redocOptions?: any;
}

const BUNDLES_DIR = dirname(require.resolve('redoc'));

/* tslint:disable-next-line */
YargsParser.command(
  'serve <spec>',
  'start the server',
  yargs => {
    yargs.positional('spec', {
      describe: 'path or URL to your spec',
    });

    yargs.option('s', {
      alias: 'ssr',
      describe: 'Enable server-side rendering',
      type: 'boolean',
    });

    yargs.option('p', {
      alias: 'port',
      type: 'number',
      default: 8080,
    });

    yargs.option('w', {
      alias: 'watch',
      type: 'boolean',
    });

    yargs.demandOption('spec');
    return yargs;
  },
  async argv => {
    const config: Options = {
      ssr: argv.ssr as boolean,
      watch: argv.watch as boolean,
      templateFileName: argv.template as string,
      templateOptions: argv.templateOptions || {},
      redocOptions: argv.options || {},
    };

    try {
      await serve(argv.port as number, argv.spec as string, config);
    } catch (e) {
      handleError(e);
    }
  },
)
  .command(
    'bundle <spec>',
    'bundle spec into zero-dependency HTML-file',
    yargs => {
      yargs.positional('spec', {
        describe: 'path or URL to your spec',
      });

      yargs.option('o', {
        describe: 'Output file',
        alias: 'output',
        type: 'string',
        default: 'redoc-static.html',
      });

      yargs.options('title', {
        describe: 'Page Title',
        type: 'string',
        default: 'ReDoc documentation',
      });

      yargs.option('cdn', {
        describe: 'Do not include ReDoc source code into html page, use link to CDN instead',
        type: 'boolean',
        default: false,
      });

      yargs.demandOption('spec');
      return yargs;
    },
    async argv => {
      const config: Options = {
        ssr: true,
        output: argv.o as string,
        cdn: argv.cdn as boolean,
        title: argv.title as string,
        templateFileName: argv.template as string,
        templateOptions: argv.templateOptions || {},
        redocOptions: argv.options || {},
      };

      try {
        await bundle(argv.spec, config);
      } catch (e) {
        handleError(e);
      }
    },
  )
  .demandCommand()
  .options('t', {
    alias: 'template',
    describe: 'Path to handlebars page template, see https://git.io/vh8fP for the example ',
    type: 'string',
  })
  .options('templateOptions', {
    describe:
      'Additional options that you want pass to template. Use dot notation, e.g. templateOptions.metaDescription',
  })
  .options('options', {
    describe: 'ReDoc options, use dot notation, e.g. options.nativeScrollbars',
  }).argv;

async function serve(port: number, pathToSpec: string, options: Options = {}) {
  let spec = await loadAndBundleSpec(pathToSpec);
  let pageHTML = await getPageHTML(spec, pathToSpec, options);

  const server = createServer((request, response) => {
    console.time('GET ' + request.url);
    if (request.url === '/redoc.standalone.js') {
      respondWithGzip(
        createReadStream(join(BUNDLES_DIR, 'redoc.standalone.js'), 'utf8'),
        request,
        response,
        {
          'Content-Type': 'application/javascript',
        },
      );
    } else if (request.url === '/') {
      respondWithGzip(pageHTML, request, response, {
        'Content-Type': 'text/html',
      });
    } else if (request.url === '/spec.json') {
      const specStr = JSON.stringify(spec, null, 2);
      respondWithGzip(specStr, request, response, {
        'Content-Type': 'application/json',
      });
    } else {
      response.writeHead(404);
      response.write('Not found');
      response.end();
    }

    console.timeEnd('GET ' + request.url);
  });

  console.log();
{'fraction_non_alphanumeric': 0.1450580449170012, 'fraction_numerical': 0.002169903439296951, 'mean_word_length': 2.6666666666666665, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1008263', 'n_tokens_mistral': 2851, 'n_tokens_neox': 2801, 'n_words': 731}