<commit_before>var upload = (require('multer'))();
var fs = require('fs');
var path = require('path');
var zlib = require('zlib');
var parse = require(global.server_root+'/parse/parse');
var parse_modules = require(global.server_root+'/parse/modules');

module.exports = function(app)
{
    app.put('/flight_log', upload.single('uploaded_file'), function(req, res)
    {
        var user_id = req.body.user_id;
        var user_name = req.body.user_name;
        // TODO: user_id/user_name (what's the difference?) should be figured well before individual server tasks
        var file_name = req.body.file_name;
        var is_gzip = req.body.is_gzip;
        var file = req.file;

        if (file == null || file.size <= 0)
        {
            res.json({
                transfer_id: req.body.transfer_id,
                success: false,
                reason: 'no csv file'
            });

            return;
        }
        else if (file_name == null || file_name.trim() == '')
        {
            res.json({
                transfer_id: req.body.transfer_id,
                success: false,
                reason: 'bad file name'
            });

            return;
        }
        // TODO - maybe check indexOf ('.csv') here?
        var user_folder = path.join(global.server_root, global.ROOT_LOG_FOLDER, user_id);

        try
        {
            fs.statSync(user_folder);
        }
        catch (e)
        {
            var dir_name = user_id;
            fs.mkdirSync(user_folder);
            console.log('Created user folder ' + dir_name);
        }

        // Create a meta entry linking the user_id to name.
        try
        {
            fs.statSync(user_folder + '/.meta.txt');
        }
        catch (e)
        {
            fs.writeFileSync(user_folder + '/meta.txt', 'Name: ' + user_name);
        }

        var write_file = function(buffer)
        {
            fs.writeFile(path.join(user_folder, file_name), buffer, function(err, result)
            {
                if (err != null)
                {
                    console.log(err);
                    res.json({
                        transfer_id: req.body.transfer_id,
                        success: false,
                        reason: 'File write error'
                    });

                    return;
                }

                res.json({
                    transfer_id: req.body.transfer_id,
                    success: true
                });
            });
        };

        if (is_gzip === undefined)
        {
            write_file(file.buffer);
        }
        else
        {
            zlib.gunzip(file.buffer, function(err, buffer)
            {
                if (err != null)
                {
                    res.json({
                        transfer_id: req.body.transfer_id,
                        success: false,
                        reason: 'File encoding error'
                    });

                    return;
                }

                write_file(buffer);
            });
        }

        setTimeout(function()
        {
            fs.readFile(path.join(user_folder, file_name), 'utf8', function(err, data)
            {
                var data = parse(data, parse_modules);
                data.name = file_name.replace('.csv','');
                data.user = user_id;

                var flight_logs = global.db.collection('flight_logs');
                flight_logs.insert(data, function(err,data)
                {
                    // Seems like something ought to go here
                });
            });
        }, 0);
    });
};

<commit_msg>Slight tweaks<commit_after>var upload = (require('multer'))();
var fs = require('fs');
var path = require('path');
var zlib = require('zlib');
var parse = require(global.server_root + '/parse/parse');
var parse_modules = require(global.server_root + '/parse/modules');

module.exports = function(app)
{
	app.put('/flight_log', upload.single('uploaded_file'), function(req, res)
	{
		var user_id = req.body.user_id;
		var user_name = req.body.user_name;
		// TODO: user_id/user_name (what's the difference?) should be figured well before individual server tasks
		var file_name = req.body.file_name;
		var is_gzip = req.body.is_gzip;
		var file = req.file;

		if (file == null || file.size <= 0)
		{
			res.json({
				transfer_id: req.body.transfer_id,
				success: false,
				reason: 'no csv file'
			});

			return;
		}
		else if (file_name == null || file_name.trim() == '')
		{
			res.json({
				transfer_id: req.body.transfer_id,
				success: false,
				reason: 'bad file name'
			});

			return;
		}
		// TODO - maybe check indexOf ('.csv') here?
		var user_folder = path.join(global.server_root, global.ROOT_LOG_FOLDER, user_id);

		try
		{
			fs.statSync(user_folder);
		}
		catch (e)
		{
			var dir_name = user_id;
			fs.mkdirSync(user_folder);
			console.log('Created user folder ' + dir_name);
		}

		// Create a meta entry linking the user_id to name.
		try
		{
			fs.statSync(user_folder + '/.meta.txt');
		}
		catch (e)
		{
			fs.writeFileSync(user_folder + '/meta.txt', 'Name: ' + user_name);
		}

		var put_into_database = function()
		{
			fs.readFile(path.join(user_folder, file_name), 'utf8', function(err, data)
			{
				var data = parse(data, parse_modules);
				data.name = file_name.replace('.csv', '');
				data.user = user_id;

				var flight_logs = global.db.collection('flight_logs');
				// TODO - use insertOne (insert is a deprecated method)
				flight_logs.insert(data, function(err, data)
				{
					// Seems like something ought to go here
				});
			});
		};

		var write_file = function(buffer)
		{
			fs.writeFile(path.join(user_folder, file_name), buffer, function(err, result)
			{
				if (err != null)
				{
					console.log(err);
					res.json({
						transfer_id: req.body.transfer_id,
						success: false,
						reason: 'File write error'
					});

					return;
				}

				res.json({
					transfer_id: req.body.transfer_id,
					success: true
				});

				put_into_database();
			});
		};

		if (is_gzip === undefined)
		{
			write_file(file.buffer);
		}
		else
		{
			zlib.gunzip(file.buffer, function(err, buffer)
			{
				if (err != null)
				{
					res.json({
						transfer_id: req.body.transfer_id,
						success: false,
						reason: 'File encoding error'
					});

					return;
				}

				write_file(buffer);
			});
		}
	});
};

<|endoftext|>


<commit_before>'use strict';

process.env.NODE_ENV = 'production';

const scriptsPackagename = require('../../config/const').scriptsPackagename;

const path = require('path');
const fs = require('fs-extra');
const chalk = require('chalk');
const util = require('react-boilerplate-app-utils');
const paths = require(util.pathResolve('config/paths.js', scriptsPackagename));
const webpack = require('webpack');
const cwdPackageJsonConfig = util.getDefaultCwdPackageJsonConfig(
  scriptsPackagename
);
const basename = cwdPackageJsonConfig.basename;
const config = require(paths.webpackProdConfig);
const Table = require('cli-table');
const gzipSize = require('gzip-size').sync;

//清空build文件夹
fs.emptyDirSync(util.getTopBuildFolderPath(paths.appBuild, basename));

console.log();
console.log('Building...');
console.log('This might take a couple minutes.');
console.log();
webpack(config).run(function(err, stats) {
  if (err) {
    console.log(chalk.red('Failed to build.'));
    console.error(err.stack || err);
    if (err.details) {
      console.error(err.details);
    }
    return;
  }

  //复制除了index.html外的静态文件，所以public文件夹不要放不使用的文件
  fs.copySync(paths.appPublic, paths.appBuild, {
    dereference: true,
    filter: file => {
      if (file === paths.appHtml) {
        return false;
      }
      //public/mock目录不复制
      if (file === path.resolve(paths.appPublic, 'mock')) {
        return false;
      }
      return true;
    },
  });

  const info = stats.toJson();
  if (stats.hasErrors()) {
    util.printValidationResults(info.errors, 'error');
  }

  if (stats.hasWarnings()) {
    util.printValidationResults(info.warnings, 'warning');
  }
  //处理header
  var head = ['Asset', 'Real Size', 'Gzip Size', 'Chunks', '', 'Chunk Names'];
  head = head.reduce((a, b) => {
    a.push(chalk.cyan(b));
    return a;
  }, []);
  var table = new Table({
    head,
  });
  info.assets &&
    info.assets.forEach(v => {
      var sizeAfterGzip;
      if (v.name.match(/(.js$)|(.css$)/)) {
        var fileContents = fs.readFileSync(
          path.resolve(paths.appBuild, v.name)
        );
        sizeAfterGzip = gzipSize(fileContents);
      }
      table.push([
        chalk.green(basename + '/' + v.name),
        util.transformToKBMBGB(v.size, { decimals: 2 }),
        sizeAfterGzip
          ? util.transformToKBMBGB(sizeAfterGzip, { decimals: 2 })
          : '',
        v.chunks,
        v.emitted ? chalk.green('[emitted]') : '',
        v.chunkNames,
      ]);
    });
  console.log(`Hash: ${chalk.cyan(info.hash)}`);
  console.log(`Version: ${chalk.cyan(info.version)}`);
  console.log(`Time: ${chalk.cyan(info.time / 1000 + 's')}`);
  console.log();
  console.log(table.toString());
  console.log();
  const useYarn = util.shouldUseYarn();
  console.log(`The ${chalk.cyan('build')} folder is ready to be served.`);
  console.log('You may serve it with a static server:');
  console.log();
  var displayedCommand = 'npm run';
  if (useYarn) {
    displayedCommand = 'yarn';
  }
  console.log(chalk.cyan(` ${displayedCommand} serve-build`));
});
<commit_msg>update<commit_after>'use strict';

process.env.NODE_ENV = 'production';

const scriptsPackagename = require('../../config/const').scriptsPackagename;

const path = require('path');
const fs = require('fs-extra');
const chalk = require('chalk');
const util = require('react-boilerplate-app-utils');
const paths = require(util.pathResolve('config/paths.js', scriptsPackagename));
const webpack = require('webpack');
const cwdPackageJsonConfig = util.getDefaultCwdPackageJsonConfig(
  scriptsPackagename
);
const basename = cwdPackageJsonConfig.basename;
const config = require(paths.webpackProdConfig);
const Table = require('cli-table');
const gzipSize = require('gzip-size').sync;

const topBuildFolder = util.getTopBuildFolderPath(paths.appBuild, basename);
//清空build文件夹
fs.emptyDirSync(topBuildFolder);

console.log();
console.log('Building...');
console.log('This might take a couple minutes.');
console.log();
webpack(config).run(function(err, stats) {
  if (err) {
    console.log(chalk.red('Failed to build.'));
    console.error(err.stack || err);
    if (err.details) {
      console.error(err.details);
    }
    return;
  }

  //复制除了index.html外的静态文件，所以public文件夹不要放不使用的文件
  fs.copySync(paths.appPublic, paths.appBuild, {
    dereference: true,
    filter: file => {
      if (file === paths.appHtml) {
        return false;
      }
      //public/mock目录不复制
      if (file === path.resolve(paths.appPublic, 'mock')) {
        return false;
      }
      return true;
    },
  });

  const info = stats.toJson();
  if (stats.hasErrors()) {
    util.printValidationResults(info.errors, 'error');
  }

  if (stats.hasWarnings()) {
    util.printValidationResults(info.warnings, 'warning');
  }
  if (info.assets && info.assets[0]) {
    //处理header
    var head = ['Asset', 'Real Size', 'Gzip Size', 'Chunks', '', 'Chunk Names'];
    head = head.reduce((a, b) => {
      a.push(chalk.cyan(b));
      return a;
    }, []);
    var table = new Table({
      head,
    });
    info.assets.forEach(v => {
      var sizeAfterGzip;
      if (v.name.match(/(.js$)|(.css$)/)) {
        var fileContents = fs.readFileSync(
          path.resolve(paths.appBuild, v.name)
        );
        sizeAfterGzip = gzipSize(fileContents);
      }
      table.push([
        chalk.green(basename + '/' + v.name),
        util.transformToKBMBGB(v.size, { decimals: 2 }),
        sizeAfterGzip
          ? util.transformToKBMBGB(sizeAfterGzip, { decimals: 2 })
          : '',
        v.chunks,
        v.emitted ? chalk.green('[emitted]') : '',
        v.chunkNames,
      ]);
    });
    console.log(`Hash: ${chalk.cyan(info.hash)}`);
    console.log(`Version: ${chalk.cyan(info.version)}`);
    console.log(`Time: ${chalk.cyan(info.time / 1000 + 's')}`);
    console.log();
    console.log(table.toString());
    console.log();
    const useYarn = util.shouldUseYarn();
    console.log(`The ${chalk.cyan('build')} folder: `);
    console.log(chalk.cyan(topBuildFolder));
    console.log('is ready to be served.');
    console.log('You may serve it with a static server:');
    console.log();
    var displayedCommand = 'npm run';
    if (useYarn) {
      displayedCommand = 'yarn';
    }
    console.log(chalk.cyan(` ${displayedCommand} serve-build`));
  }
});
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2016-present, Nicolas Gallagher.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @providesModule UIManager
 * @noflow
 */

import requestAnimationFrame from 'fbjs/lib/requestAnimationFrame';
import setImmediate from 'fbjs/lib/setImmediate';
import setValueForStyles from '../../vendor/setValueForStyles';

const getRect = node => {
  const height = node.offsetHeight;
  const width = node.offsetWidth;
  let left = 0;
  let top = 0;
  while (node && node.nodeType === 1 /* Node.ELEMENT_NODE */) {
    left += node.offsetLeft;
    top += node.offsetTop;
    node = node.offsetParent;
  }
  return { height, left, top, width };
};

let hasRequestedAnimationFrame = false;
const measureLayoutQueue = [];

const processLayoutQueue = () => {
  measureLayoutQueue.splice(0, 250).forEach(item => {
    const [node, relativeToNativeNode, callback] = item;
    const relativeNode = relativeToNativeNode || (node && node.parentNode);

    if (node && relativeNode) {
      const relativeRect = getRect(relativeNode);
      const { height, left, top, width } = getRect(node);
      const x = left - relativeRect.left;
      const y = top - relativeRect.top;
      callback(x, y, width, height, left, top);
    }
  });

  if (measureLayoutQueue.length > 0) {
    setImmediate(processLayoutQueue);
  }
};

const measureLayout = (node, relativeToNativeNode, callback) => {
  if (!hasRequestedAnimationFrame) {
    requestAnimationFrame(() => {
      hasRequestedAnimationFrame = false;
      processLayoutQueue();
    });
  }

  hasRequestedAnimationFrame = true;
  measureLayoutQueue.push([node, relativeToNativeNode, callback]);
};

const UIManager = {
  blur(node) {
    try {
      node.blur();
    } catch (err) {}
  },

  focus(node) {
    try {
      node.focus();
    } catch (err) {}
  },

  measure(node, callback) {
    measureLayout(node, null, callback);
  },

  measureInWindow(node, callback) {
    requestAnimationFrame(() => {
      if (node) {
        const { height, left, top, width } = getRect(node);
        callback(left, top, width, height);
      }
    });
  },

  measureLayout(node, relativeToNativeNode, onFail, onSuccess) {
    measureLayout(node, relativeToNativeNode, onSuccess);
  },

  updateView(node, props, component /* only needed to surpress React errors in development */) {
    for (const prop in props) {
      if (!Object.prototype.hasOwnProperty.call(props, prop)) {
        continue;
      }

      const value = props[prop];
      switch (prop) {
        case 'style': {
          setValueForStyles(node, value, component._reactInternalInstance);
          break;
        }
        case 'class':
        case 'className': {
          node.setAttribute('class', value);
          break;
        }
        case 'text':
        case 'value':
          // native platforms use `text` prop to replace text input value
          node.value = value;
          break;
        default:
          node.setAttribute(prop, value);
      }
    }
  }
};

export default UIManager;
<commit_msg>[fix] NativeMethodsMixin measure/measureInWindow with scroll<commit_after>/**
 * Copyright (c) 2016-present, Nicolas Gallagher.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @providesModule UIManager
 * @noflow
 */

import requestAnimationFrame from 'fbjs/lib/requestAnimationFrame';
import setImmediate from 'fbjs/lib/setImmediate';
import setValueForStyles from '../../vendor/setValueForStyles';

const getRect = node => {
  const height = node.offsetHeight;
  const width = node.offsetWidth;
  let left = node.offsetLeft;
  let top = node.offsetTop;
  node = node.offsetParent;

  while (node && node.nodeType === 1 /* Node.ELEMENT_NODE */) {
    left += node.offsetLeft - node.scrollLeft;
    top += node.offsetTop - node.scrollTop;
    node = node.offsetParent;
  }
  return { height, left, top, width };
};

let hasRequestedAnimationFrame = false;
const measureLayoutQueue = [];

const processLayoutQueue = () => {
  measureLayoutQueue.splice(0, 250).forEach(item => {
    const [node, relativeToNativeNode, callback] = item;
    const relativeNode = relativeToNativeNode || (node && node.parentNode);

    if (node && relativeNode) {
      const relativeRect = getRect(relativeNode);
      const { height, left, top, width } = getRect(node);
      const x = left - relativeRect.left;
      const y = top - relativeRect.top;
      callback(x, y, width, height, left, top);
    }
  });

  if (measureLayoutQueue.length > 0) {
    setImmediate(processLayoutQueue);
  }
};

const measureLayout = (node, relativeToNativeNode, callback) => {
  if (!hasRequestedAnimationFrame) {
    requestAnimationFrame(() => {
      hasRequestedAnimationFrame = false;
      processLayoutQueue();
    });
  }

  hasRequestedAnimationFrame = true;
  measureLayoutQueue.push([node, relativeToNativeNode, callback]);
};

const UIManager = {
  blur(node) {
    try {
      node.blur();
    } catch (err) {}
  },

  focus(node) {
    try {
      node.focus();
    } catch (err) {}
  },

  measure(node, callback) {
    measureLayout(node, null, callback);
  },

  measureInWindow(node, callback) {
    requestAnimationFrame(() => {
      if (node) {
        const { height, left, top, width } = getRect(node);
        callback(left, top, width, height);
      }
    });
  },

  measureLayout(node, relativeToNativeNode, onFail, onSuccess) {
    measureLayout(node, relativeToNativeNode, onSuccess);
  },

  updateView(node, props, component /* only needed to surpress React errors in development */) {
    for (const prop in props) {
      if (!Object.prototype.hasOwnProperty.call(props, prop)) {
        continue;
      }

      const value = props[prop];
      switch (prop) {
        case 'style': {
          setValueForStyles(node, value, component._reactInternalInstance);
          break;
        }
        case 'class':
        case 'className': {
          node.setAttribute('class', value);
          break;
        }
        case 'text':
        case 'value':
          // native platforms use `text` prop to replace text input value
          node.value = value;
          break;
        default:
          node.setAttribute(prop, value);
      }
    }
  }
};

export default UIManager;
<|endoftext|>


<commit_before>/**
 * Copyright IBM Corp. 2016, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import PropTypes from 'prop-types';
import React, { Component } from 'react';
import classNames from 'classnames';
import { ChevronDown16 } from '@carbon/icons-react';
import { settings } from 'carbon-components';
import Copy from '../Copy';
import CopyButton from '../CopyButton';
import uid from '../../tools/uniqueId';

const { prefix } = settings;

export default class CodeSnippet extends Component {
  static propTypes = {
    /**
     * Provide the type of Code Snippet
     */
    type: PropTypes.oneOf(['single', 'inline', 'multi']),

    /**
     * Specify an optional className to be applied to the container node
     */
    className: PropTypes.string,

    /**
     * Provide the content of your CodeSnippet as a string
     */
    children: PropTypes.string,

    /**
     * Specify the string displayed when the snippet is copied
     */
    feedback: PropTypes.string,

    /**
     * Specify the description for the Copy Button
     */
    copyButtonDescription: PropTypes.string,

    /**
     * An optional handler to listen to the `onClick` even fired by the Copy
     * Button
     */
    onClick: PropTypes.func,

    /**
     * Specify a label to be read by screen readers on the containing <textbox>
     * node
     */
    copyLabel: PropTypes.string,

    /**
     * Specify a label to be read by screen readers on the containing <textbox>
     * node
     */
    ariaLabel: PropTypes.string,

    /**
     * Specify a string that is displayed when the Code Snippet text is more
     * than 15 lines
     */
    showMoreText: PropTypes.string,

    /**
     * Specify a string that is displayed when the Code Snippet has been
     * interacted with to show more lines
     */
    showLessText: PropTypes.string,

    /**
     * Specify whether you are using the light variant of the Code Snippet,
     * typically used for inline snippet to display an alternate color
     */
    light: PropTypes.bool,
  };

  static defaultProps = {
    type: 'single',
    showMoreText: 'Show more',
    showLessText: 'Show less',
  };

  state = {
    shouldShowMoreLessBtn: false,
    expandedCode: false,
  };

  componentDidMount() {
    if (this.codeContent) {
      if (this.codeContent.getBoundingClientRect().height > 255) {
        this.setState({ shouldShowMoreLessBtn: true });
      }
    }
  }

  componentDidUpdate(prevProps) {
    if (this.props.children !== prevProps.children && this.codeContent) {
      if (this.codeContent.getBoundingClientRect().height > 255) {
        this.setState({ shouldShowMoreLessBtn: true });
      }
    }
  }

  expandCode = () => {
    this.setState({ expandedCode: !this.state.expandedCode });
  };

  render() {
    const {
      className,
      type,
      children,
      feedback,
      onClick,
      ariaLabel,
      copyLabel, //TODO: Merge this prop to `ariaLabel` in `v11`
      copyButtonDescription,
      light,
      showMoreText,
      showLessText,
      ...other
    } = this.props;

    // a unique id generated for aria-describedby
    this.uid = uid();

    const codeSnippetClasses = classNames(className, {
      [`${prefix}--snippet`]: true,
      [`${prefix}--snippet--${type}`]: type,
      [`${prefix}--snippet--expand`]: this.state.expandedCode,
      [`${prefix}--snippet--light`]: light,
    });

    const expandCodeBtnText = this.state.expandedCode
      ? showLessText
      : showMoreText;

    const moreLessBtn = (
      <button
        className={`${prefix}--btn ${prefix}--btn--ghost ${prefix}--btn--sm ${prefix}--snippet-btn--expand`}
        type="button"
        onClick={this.expandCode}>
        <span className={`${prefix}--snippet-btn--text`}>
          {expandCodeBtnText}

        <ChevronDown16
          aria-label={expandCodeBtnText}
          className={`${prefix}--icon-chevron--down ${prefix}--snippet__icon`}
          name="chevron--down"
          role="img"
        />
      </button>
    );

    const code = (
      <div
        role="textbox"
        tabIndex={0}
        className={`${prefix}--snippet-container`}
        aria-label={ariaLabel || copyLabel || 'code-snippet'}>

 {
              this.codeContent = codeContent;
            }}>
            {children}

    );

    const copy = (
      <CopyButton
        onClick={onClick}
        feedback={feedback}
        iconDescription={copyButtonDescription}
      />
    );

    if (type === 'inline') {
      return (
        <Copy
          {...other}
          onClick={onClick}
          aria-label={copyLabel || ariaLabel}
          aria-describedby={this.uid}
          className={codeSnippetClasses}
          feedback={feedback}>
          {children}
        </Copy>
      );
    }

    if (type === 'single') {
      return (

          {code}
          {copy}

      );
    }

    if (!this.state.shouldShowMoreLessBtn && type === 'multi') {
      return (

          {code}
          {copy}

      );
    }

    if (this.state.shouldShowMoreLessBtn && type === 'multi') {
      return (

          {code}
          {copy}
          {moreLessBtn}

      );
    }
  }
}
<commit_msg>refactor(CodeSnippet): use hooks clean up render logic (#4636)<commit_after>/**
 * Copyright IBM Corp. 2016, 2018
 *
 * This source code is licensed under the Apache-2.0 license found in the
 * LICENSE file in the root directory of this source tree.
 */

import PropTypes from 'prop-types';
import React, { useState, useRef, useLayoutEffect } from 'react';
import classNames from 'classnames';
import { ChevronDown16 } from '@carbon/icons-react';
import { settings } from 'carbon-components';
import Copy from '../Copy';
import Button from '../Button';
import CopyButton from '../CopyButton';
import getUniqueId from '../../tools/uniqueId';

const { prefix } = settings;

function CodeSnippet({
  className,
  type,
  children,
  feedback,
  onClick,
  ariaLabel,
  copyLabel, //TODO: Merge this prop to `ariaLabel` in `v11`
  copyButtonDescription,
  light,
  showMoreText,
  showLessText,
  ...rest
}) {
  const [expandedCode, setExpandedCode] = useState(false);
  const [shouldShowMoreLessBtn, setShouldShowMoreLessBtn] = useState(false);
  const { current: uid } = useRef(getUniqueId());
  const codeContentRef = useRef();

  useLayoutEffect(() => {
    if (codeContentRef.current) {
      const { height } = codeContentRef.current.getBoundingClientRect();
      setShouldShowMoreLessBtn(type === 'multi' && height > 255);
    }
  }, [children, type]);

  const codeSnippetClasses = classNames(className, {
    [`${prefix}--snippet`]: true,
    [`${prefix}--snippet--${type}`]: type,
    [`${prefix}--snippet--expand`]: expandedCode,
    [`${prefix}--snippet--light`]: light,
  });

  const expandCodeBtnText = expandedCode ? showLessText : showMoreText;

  if (type === 'inline') {
    return (
      <Copy
        {...rest}
        onClick={onClick}
        aria-label={copyLabel || ariaLabel}
        aria-describedby={uid}
        className={codeSnippetClasses}
        feedback={feedback}>
        {children}
      </Copy>
    );
  }

  return (

      <div
        role="textbox"
        tabIndex={0}
        className={`${prefix}--snippet-container`}
        aria-label={ariaLabel || copyLabel || 'code-snippet'}>

{children}

      <CopyButton
        onClick={onClick}
        feedback={feedback}
        iconDescription={copyButtonDescription}
      />
      {shouldShowMoreLessBtn && (
        <Button
          kind="ghost"
          size="small"
          className={`${prefix}--snippet-btn--expand`}
          onClick={() => setExpandedCode(!expandedCode)}>
          <span className={`${prefix}--snippet-btn--text`}>
            {expandCodeBtnText}

          <ChevronDown16
            aria-label={expandCodeBtnText}
            className={`${prefix}--icon-chevron--down ${prefix}--snippet__icon`}
            name="chevron--down"
            role="img"
          />
        </Button>
      )}

  );
}

CodeSnippet.propTypes = {
  /**
   * Provide the type of Code Snippet
   */
  type: PropTypes.oneOf(['single', 'inline', 'multi']),

  /**
   * Specify an optional className to be applied to the container node
   */
  className: PropTypes.string,

  /**
   * Provide the content of your CodeSnippet as a string
   */
  children: PropTypes.string,

  /**
   * Specify the string displayed when the snippet is copied
   */
  feedback: PropTypes.string,

  /**
   * Specify the description for the Copy Button
   */
  copyButtonDescription: PropTypes.string,

  /**
   * An optional handler to listen to the `onClick` even fired by the Copy
   * Button
   */
  onClick: PropTypes.func,

  /**
   * Specify a label to be read by screen readers on the containing <textbox>
   * node
   */
  copyLabel: PropTypes.string,

  /**
   * Specify a label to be read by screen readers on the containing <textbox>
   * node
   */
  ariaLabel: PropTypes.string,

  /**
   * Specify a string that is displayed when the Code Snippet text is more
   * than 15 lines
   */
  showMoreText: PropTypes.string,

  /**
   * Specify a string that is displayed when the Code Snippet has been
   * interacted with to show more lines
   */
  showLessText: PropTypes.string,

  /**
   * Specify whether you are using the light variant of the Code Snippet,
   * typically used for inline snippet to display an alternate color
   */
  light: PropTypes.bool,
};

CodeSnippet.defaultProps = {
  type: 'single',
  showMoreText: 'Show more',
  showLessText: 'Show less',
};

export default CodeSnippet;
<|endoftext|>


<commit_before>var hookTypes = ["created", "rendered", "destroyed"];
var globalHooks = {created: [], rendered: [], destroyed: []};
var templateHooks = {created: {}, rendered: {}, destroyed: {}};

// Setup for multiple hooks support
// We assume that no other code will be directly defining
// a hook once the client has started.
Meteor.startup(function () {
  Template.forEach(function (template) {
    var i;

    function defineHook(type) {
      // see if there's an existing callback set directly on the template instance
      var orig = template[type];

      // Basically scraping callbacks set directly on instance and saving
      // in templateHooks
      if (typeof orig === 'function') {
        var name = parseName(template.viewName);
        templateHooks[type][name] = templateHooks[type][name] || [];
        templateHooks[type][name].push(orig);
      }

      // set our own callback directly on the template instance
      template[type] = function () {
        //console.log(type, orig);
        // call all defined global hooks
        runGlobalHooks(type, this, arguments);
        // call all defined hooks for this template instance
        runTemplateHooks(type, this, arguments);
        // call the existing callback if there was one
        if (typeof orig === "function") {
          orig.apply(this, arguments);
        }
      };
    }

    for (i = hookTypes.length - 1; i >= 0; i--) {
      defineHook(hookTypes[i]);
    }
  });
});

Template.forEach = function (callback) {
  // for some reason we get the "body" template twice when looping, so
  // we track that and only call the callback once.
  var alreadyDidBody = false;
  for (var t in Template) {
    if (Template.hasOwnProperty(t)) {
      var tmpl = Template[t];
      if (Blaze.isTemplate(tmpl)) {
        if (tmpl.viewName === "body") {
          if (!alreadyDidBody) {
            alreadyDidBody = true;
            callback(tmpl);
          }
        } else {
          callback(tmpl);
        }
      }
    }
  }
};

Template.onCreated = function (callback) {
  globalHooks.created.push(callback);
};

Template.onRendered = function (callback) {
  globalHooks.rendered.push(callback);
};

Template.onDestroyed = function (callback) {
  globalHooks.destroyed.push(callback);
};

Template.prototype.hooks = function (hooks) {
  var self = this;

  if (typeof hooks !== "object") {
    throw new Error("hooks argument must be an object with created, rendered, and/or destroyed properties, each set to a function");
  }

  var name = parseName(self.viewName);

  // Store a reference to the hooks so they can be called by our own
  // already defined callbacks
  var i, type;
  for (i = hookTypes.length - 1; i >= 0; i--) {
    type = hookTypes[i];
    if (typeof hooks[type] === "function") {
      templateHooks[type][name] = templateHooks[type][name] || [];
      templateHooks[type][name].push(hooks[type]);
    }
  }
};

Template.prototype.replaces = function (replacedTemplateName) {
  var self = this;

  var replacedTemplate = Template[replacedTemplateName];

  if (!replacedTemplate) {
    console.warn("Can't replace template " + replacedTemplateName + " because it hasn't been defined yet.");
    return;
  }

  var name = parseName(self.viewName);
  replacedTemplate.renderFunction = Template[name].renderFunction;
};

Template.prototype.inheritsHelpersFrom = function (otherTemplateName) {
  var self = this;

  var otherTemplate = Template[otherTemplateName];
  if (!otherTemplate) {
    console.warn("Can't inherit helpers from template " + otherTemplateName + " because it hasn't been defined yet.");
    return;
  }

  var name = parseName(self.viewName);
  var thisTemplate = Template[name];
  if (otherTemplate.__helpers) {
    thisTemplate.__helpers = $.extend({}, thisTemplate.__helpers, otherTemplate.__helpers);
  }

  else {
    // backwards compatibility; pre-0.9.4 Meteor
    for (var h in otherTemplate) {
      if (otherTemplate.hasOwnProperty(h) && (h.slice(0, 2) !== "__") && h !== "viewName" && h !== "renderFunction") {
        thisTemplate[h] = otherTemplate[h];
      }
    }
  }
};

Template.prototype.inheritsEventsFrom = function (otherTemplateName) {
  var self = this;

  var otherTemplate = Template[otherTemplateName];
  if (!otherTemplate) {
    console.warn("Can't inherit events from template " + otherTemplateName + " because it hasn't been defined yet.");
    return;
  }

  var name = parseName(self.viewName);
  Template[name].__eventMaps = otherTemplate.__eventMaps;
};

Template.prototype.inheritsHooksFrom = function (otherTemplateName) {
  var self = this;
  var name = parseName(self.viewName);

  var inheritHooks = function(templateName) {
    // Check for existence of templateName template
    var otherTemplate = Template[templateName];
    if (!otherTemplate) {
      console.warn("Can't inherit hooks from template " + templateName + " because it hasn't been defined yet.");
      return;
    }
    // For each hookType check if there are existing templateHooks for templateName
    _.each(hookTypes, function (type) {
      var hooks = templateHooks[type][templateName];
      // For each existing hook for templateName
      _.each(hooks, function (hook) {
        // Initialize the target template's templateHooks array
        templateHooks[type][name] = templateHooks[type][name] || [];
        // Add hook
        templateHooks[type][name].push(hook);
      });
    });
  };

  //Allow this function to be called with an array or string
  if (_.isArray(otherTemplateName)) {
    _.each(otherTemplateName, function (name) {
      inheritHooks(name);
    });
  } else {
    inheritHooks(otherTemplateName);
  }
};

Template.prototype.copyAs = function (newTemplateName) {
  var self = this;

  var createNewTemplate = function (templateName) {
    var newTemplate =
    Template[templateName] = new Template('Template.' + templateName, self.renderFunction);

    var name = parseName(self.viewName);
    newTemplate.inheritsHelpersFrom(name);
    newTemplate.inheritsEventsFrom(name);
    newTemplate.inheritsHooksFrom(name);
  };

  //Check if newTemplateName is an array
  if (_.isArray(newTemplateName)) {
    _.each(newTemplateName, function (name) {
      createNewTemplate(name);
    });
  } else { //newTemplateName is a string
    createNewTemplate(newTemplateName);
  }
};

// Allow easy access to a template instance field when you do not know exactly
// on which instance (this, or parent, or parent's parent, ...) a field is defined.
// This allows easy restructuring of templates in HTML, moving things to included
// templates without having to change everywhere in the code instance levels.
// It also allows different structures of templates, when once template is included
// at one level, and some other time at another. Levels do not matter anymore, just
// that the field exists somewhere.
Blaze.TemplateInstance.prototype.get = function (fieldName) {
  var template = this;
  while (template) {
    if (fieldName in template) {
      return template[fieldName];
    }
    template = template.parent(1, true);
  }
};

// Access parent template instance. "height" is the number of levels beyond the
// current template instance to look. By default block helper template instances
// are skipped, but if "includeBlockHelpers" is set to true, they are not.
// See https://github.com/meteor/meteor/issues/3071
Blaze.TemplateInstance.prototype.parent = function(height, includeBlockHelpers) {
  // If height is null or undefined, we default to 1, the first parent.
  if (height == null) {
    height = 1;
  }

  var i = 0;
  var template = this;
  while (i < height && template) {
    var view = parentView(template.view, includeBlockHelpers);
    // We skip contentBlock views which are injected by Meteor when using
    // block helpers (in addition to block helper view). This matches more
    // the visual structure of templates and not the internal implementation.
    while (view && (!view.template || view.name === '(contentBlock)')) {
      view = parentView(view, includeBlockHelpers);
    }
    if (!view) {
      return null;
    }
    // Body view has template field, but not templateInstance,
    // which more or less signals that we reached the top.
    template = typeof view.templateInstance === 'function' ? view.templateInstance() : null;
    i++;
  }
  return template;
};

// Allow to specify a function to test parent data for at various
// levels, instead of specifying a fixed number of levels to traverse.
var originalParentData = Blaze._parentData;
Blaze._parentData = function (height, _functionWrapped) {
  // If height is not a function, simply call original implementation.
  if (typeof height !== 'function') {
    return originalParentData(height, _functionWrapped);
  }

  var theWith = Blaze.getView('with');
  var test = function () {
    return height(theWith.dataVar.get());
  };
  while (theWith) {
    if (Tracker.nonreactive(test)) break;
    theWith = Blaze.getView(theWith, 'with');
  }

  // _functionWrapped is internal and will not be
  // specified with non numeric height, so we ignore it.
  if (!theWith) return null;
  // This registers a Tracker dependency.
  return theWith.dataVar.get();
};

Template.parentData = Blaze._parentData;

/* PRIVATE */

function parentView(view, includeBlockHelpers) {
  if (includeBlockHelpers) {
    return view.originalParentView || view.parentView;
  }
  else {
    return view.parentView;
  }
}

function parseName(name) {
  if (!name) {
    return
  }
  // post 0.9.1 kludge to get template name from viewName
  var prefix = 'Template.';
  if (name.indexOf(prefix) === 0) {
    return name.slice(prefix.length);
  }
  return name;
}

function runGlobalHooks(type, template, args) {
  var i, h = globalHooks[type], hl = h.length;
  for (i = 0; i < hl; i++) {
    h[i].apply(template, args);
  }
}

function runTemplateHooks(type, template, args) {
  var i, name = parseName(template.viewName), h = templateHooks[type][name];
  var hl = h ? h.length : 0;
  for (i = 0; i < hl; i++) {
    h[i].apply(template, args);
  }
}
<commit_msg>Remove calling existing callbacks in defineHook method<commit_after>var hookTypes = ["created", "rendered", "destroyed"];
var globalHooks = {created: [], rendered: [], destroyed: []};
var templateHooks = {created: {}, rendered: {}, destroyed: {}};

// Setup for multiple hooks support
// We assume that no other code will be directly defining
// a hook once the client has started.
Meteor.startup(function () {
  Template.forEach(function (template) {
    var i;

    function defineHook(type) {
      // see if there's an existing callback set directly on the template instance
      var orig = template[type];

      // Basically scraping callbacks set directly on instance and saving
      // in templateHooks
      if (typeof orig === 'function') {
        var name = parseName(template.viewName);
        templateHooks[type][name] = templateHooks[type][name] || [];
        templateHooks[type][name].push(orig);
      }

      // set our own callback directly on the template instance
      template[type] = function () {
        //console.log(type, orig);
        // call all defined global hooks
        runGlobalHooks(type, this, arguments);
        // call all defined hooks for this template instance
        runTemplateHooks(type, this, arguments);
      };
    }

    for (i = hookTypes.length - 1; i >= 0; i--) {
      defineHook(hookTypes[i]);
    }
  });
});

Template.forEach = function (callback) {
  // for some reason we get the "body" template twice when looping, so
  // we track that and only call the callback once.
  var alreadyDidBody = false;
  for (var t in Template) {
    if (Template.hasOwnProperty(t)) {
      var tmpl = Template[t];
      if (Blaze.isTemplate(tmpl)) {
        if (tmpl.viewName === "body") {
          if (!alreadyDidBody) {
            alreadyDidBody = true;
            callback(tmpl);
          }
        } else {
          callback(tmpl);
        }
      }
    }
  }
};

Template.onCreated = function (callback) {
  globalHooks.created.push(callback);
};

Template.onRendered = function (callback) {
  globalHooks.rendered.push(callback);
};

Template.onDestroyed = function (callback) {
  globalHooks.destroyed.push(callback);
};

Template.prototype.hooks = function (hooks) {
  var self = this;

  if (typeof hooks !== "object") {
    throw new Error("hooks argument must be an object with created, rendered, and/or destroyed properties, each set to a function");
  }

  var name = parseName(self.viewName);

  // Store a reference to the hooks so they can be called by our own
  // already defined callbacks
  var i, type;
  for (i = hookTypes.length - 1; i >= 0; i--) {
    type = hookTypes[i];
    if (typeof hooks[type] === "function") {
      templateHooks[type][name] = templateHooks[type][name] || [];
      templateHooks[type][name].push(hooks[type]);
    }
  }
};

Template.prototype.replaces = function (replacedTemplateName) {
  var self = this;

  var replacedTemplate = Template[replacedTemplateName];

  if (!replacedTemplate) {
    console.warn("Can't replace template " + replacedTemplateName + " because it hasn't been defined yet.");
    return;
  }

  var name = parseName(self.viewName);
  replacedTemplate.renderFunction = Template[name].renderFunction;
};

Template.prototype.inheritsHelpersFrom = function (otherTemplateName) {
  var self = this;

  var otherTemplate = Template[otherTemplateName];
  if (!otherTemplate) {
    console.warn("Can't inherit helpers from template " + otherTemplateName + " because it hasn't been defined yet.");
    return;
  }

  var name = parseName(self.viewName);
  var thisTemplate = Template[name];
  if (otherTemplate.__helpers) {
    thisTemplate.__helpers = $.extend({}, thisTemplate.__helpers, otherTemplate.__helpers);
  }

  else {
    // backwards compatibility; pre-0.9.4 Meteor
    for (var h in otherTemplate) {
      if (otherTemplate.hasOwnProperty(h) && (h.slice(0, 2) !== "__") && h !== "viewName" && h !== "renderFunction") {
        thisTemplate[h] = otherTemplate[h];
      }
    }
  }
};

Template.prototype.inheritsEventsFrom = function (otherTemplateName) {
  var self = this;

  var otherTemplate = Template[otherTemplateName];
  if (!otherTemplate) {
    console.warn("Can't inherit events from template " + otherTemplateName + " because it hasn't been defined yet.");
    return;
  }

  var name = parseName(self.viewName);
  Template[name].__eventMaps = otherTemplate.__eventMaps;
};

Template.prototype.inheritsHooksFrom = function (otherTemplateName) {
  var self = this;
  var name = parseName(self.viewName);

  var inheritHooks = function(templateName) {
    // Check for existence of templateName template
    var otherTemplate = Template[templateName];
    if (!otherTemplate) {
      console.warn("Can't inherit hooks from template " + templateName + " because it hasn't been defined yet.");
      return;
    }
    // For each hookType check if there are existing templateHooks for templateName
    _.each(hookTypes, function (type) {
      var hooks = templateHooks[type][templateName];
      // For each existing hook for templateName
      _.each(hooks, function (hook) {
        // Initialize the target template's templateHooks array
        templateHooks[type][name] = templateHooks[type][name] || [];
        // Add hook
        templateHooks[type][name].push(hook);
      });
    });
  };

  //Allow this function to be called with an array or string
  if (_.isArray(otherTemplateName)) {
    _.each(otherTemplateName, function (name) {
      inheritHooks(name);
    });
  } else {
    inheritHooks(otherTemplateName);
  }
};

Template.prototype.copyAs = function (newTemplateName) {
  var self = this;

  var createNewTemplate = function (templateName) {
    var newTemplate =
    Template[templateName] = new Template('Template.' + templateName, self.renderFunction);

    var name = parseName(self.viewName);
    newTemplate.inheritsHelpersFrom(name);
    newTemplate.inheritsEventsFrom(name);
    newTemplate.inheritsHooksFrom(name);
  };

  //Check if newTemplateName is an array
  if (_.isArray(newTemplateName)) {
    _.each(newTemplateName, function (name) {
      createNewTemplate(name);
    });
  } else { //newTemplateName is a string
    createNewTemplate(newTemplateName);
  }
};

// Allow easy access to a template instance field when you do not know exactly
// on which instance (this, or parent, or parent's parent, ...) a field is defined.
// This allows easy restructuring of templates in HTML, moving things to included
// templates without having to change everywhere in the code instance levels.
// It also allows different structures of templates, when once template is included
// at one level, and some other time at another. Levels do not matter anymore, just
// that the field exists somewhere.
Blaze.TemplateInstance.prototype.get = function (fieldName) {
  var template = this;
  while (template) {
    if (fieldName in template) {
      return template[fieldName];
    }
    template = template.parent(1, true);
  }
};

// Access parent template instance. "height" is the number of levels beyond the
// current template instance to look. By default block helper template instances
// are skipped, but if "includeBlockHelpers" is set to true, they are not.
// See https://github.com/meteor/meteor/issues/3071
Blaze.TemplateInstance.prototype.parent = function(height, includeBlockHelpers) {
  // If height is null or undefined, we default to 1, the first parent.
  if (height == null) {
    height = 1;
  }

  var i = 0;
  var template = this;
  while (i < height && template) {
    var view = parentView(template.view, includeBlockHelpers);
    // We skip contentBlock views which are injected by Meteor when using
    // block helpers (in addition to block helper view). This matches more
    // the visual structure of templates and not the internal implementation.
    while (view && (!view.template || view.name === '(contentBlock)')) {
      view = parentView(view, includeBlockHelpers);
    }
    if (!view) {
      return null;
    }
    // Body view has template field, but not templateInstance,
    // which more or less signals that we reached the top.
    template = typeof view.templateInstance === 'function' ? view.templateInstance() : null;
    i++;
  }
  return template;
};

// Allow to specify a function to test parent data for at various
// levels, instead of specifying a fixed number of levels to traverse.
var originalParentData = Blaze._parentData;
Blaze._parentData = function (height, _functionWrapped) {
  // If height is not a function, simply call original implementation.
  if (typeof height !== 'function') {
    return originalParentData(height, _functionWrapped);
  }

  var theWith = Blaze.getView('with');
  var test = function () {
    return height(theWith.dataVar.get());
  };
  while (theWith) {
    if (Tracker.nonreactive(test)) break;
    theWith = Blaze.getView(theWith, 'with');
  }

  // _functionWrapped is internal and will not be
  // specified with non numeric height, so we ignore it.
  if (!theWith) return null;
  // This registers a Tracker dependency.
  return theWith.dataVar.get();
};

Template.parentData = Blaze._parentData;

/* PRIVATE */

function parentView(view, includeBlockHelpers) {
  if (includeBlockHelpers) {
    return view.originalParentView || view.parentView;
  }
  else {
    return view.parentView;
  }
}

function parseName(name) {
  if (!name) {
    return
  }
  // post 0.9.1 kludge to get template name from viewName
  var prefix = 'Template.';
  if (name.indexOf(prefix) === 0) {
    return name.slice(prefix.length);
  }
  return name;
}

function runGlobalHooks(type, template, args) {
  var i, h = globalHooks[type], hl = h.length;
  for (i = 0; i < hl; i++) {
    h[i].apply(template, args);
  }
}

function runTemplateHooks(type, template, args) {
  var i, name = parseName(template.viewName), h = templateHooks[type][name];
  var hl = h ? h.length : 0;
  for (i = 0; i < hl; i++) {
    h[i].apply(template, args);
  }
}
<|endoftext|>


<commit_before>const root = '/me/connected-applications/';

class MeConnectedApp {

	/**
	 * `MeConnectedApp` constructor.
	 *
	 * @param {String} appId - application identifier
	 * @param {WPCOM} wpcom - wpcom instance
	 * @return {Null} null
	 */
	constructor( appId, wpcom ) {
		if ( ! ( this instanceof MeConnectedApp ) ) {
			return new MeConnectedApp( wpcom );
		}
		this._id = appId;
		this.wpcom = wpcom;
	}

	/**
	 * Get one of current user's connected applications.
	 *
	 * @param {Object} [query] - query object parameter
	 * @param {Function} fn - callback function
	 * @return {Function} request handler
	 */
	get( query, fn ) {
		return this.wpcom.req.get( root + this._id, query, fn );
	}

	/**
	 * Delete the app of the  current user
	 * through of the given appId
	 *
	 * @param {Object} [query] - query object parameter
	 * @param {Function} fn - callback function
	 * @return {Function} request handler
	 */
	delete( query, fn ) {
		return this.wpcom.req.del( root + this._id + '/delete', query, fn );
	}
}

/**
* Expose `MeConnectedApp` module
*/
module.exports = MeConnectedApp;
<commit_msg>me.connectedAppication: fix constructor params<commit_after>const root = '/me/connected-applications/';

class MeConnectedApp {

	/**
	 * `MeConnectedApp` constructor.
	 *
	 * @param {String} appId - application identifier
	 * @param {WPCOM} wpcom - wpcom instance
	 * @return {Null} null
	 */
	constructor( appId, wpcom ) {
		if ( ! ( this instanceof MeConnectedApp ) ) {
			return new MeConnectedApp( appId, wpcom );
		}
		this._id = appId;
		this.wpcom = wpcom;
	}

	/**
	 * Get one of current user's connected applications.
	 *
	 * @param {Object} [query] - query object parameter
	 * @param {Function} fn - callback function
	 * @return {Function} request handler
	 */
	get( query, fn ) {
		return this.wpcom.req.get( root + this._id, query, fn );
	}

	/**
	 * Delete the app of the  current user
	 * through of the given appId
	 *
	 * @param {Object} [query] - query object parameter
	 * @param {Function} fn - callback function
	 * @return {Function} request handler
	 */
	delete( query, fn ) {
		return this.wpcom.req.del( root + this._id + '/delete', query, fn );
	}
}

/**
* Expose `MeConnectedApp` module
*/
module.exports = MeConnectedApp;
<|endoftext|>


<commit_before>89072ce2-2e9b-11e5-91f5-10ddb1c7c412<commit_msg>Final commit :sunglasses:<commit_after>println('Hello world')<|endoftext|>


<commit_before>'use strict';

const { memoize } = require('underscore');

const util = require('util');

const accountClient = require('abacus-accountclient');
const batch = require('abacus-batch');
const breaker = require('abacus-breaker');
const dbClient = require('abacus-dbclient');
const meteringClient = require('abacus-metering-config');
const oauth = require('abacus-oauth');
const ratingClient = require('abacus-rating-config');
const pricingClient = require('abacus-pricing-config');
const partition = require('abacus-partition');
const request = require('abacus-request');
const retry = require('abacus-retry');
const router = require('abacus-router');
const urienv = require('abacus-urienv');
const vcapenv = require('abacus-vcapenv');
const webapp = require('abacus-webapp');

const { ConnectionManager, Consumer, amqpMessageToJSON } = require('abacus-rabbitmq');
const { MessageHandler } = require('./lib/message-handler');
const Meter = require('./lib/meter');
const Normalizer = require('./lib/normalizer');
const createRequestRouting = require('./lib/request-routing');
const ProvisioningClient = require('./lib/provisioning-plugin-client');
const AccumulatorClient = require('./lib/accumulator-client');
const dbClientWrapper = require('./lib/db-client-wrapper');
const createRetriever = require('./lib/routes/document-retriver');

const brequest = retry(breaker(batch(request)));
const httpClient = {
  get: util.promisify(brequest.get),
  post: util.promisify(brequest.post)
};

const debug = require('abacus-debug')('abacus-usage-meter');

const dbalias = process.env.DBALIAS || 'db';

const uris = memoize(() =>
  urienv({
    [dbalias]: 5984,
    api : 9882,
    auth_server: 9883,
    provisioning: 9880,
    accumulator: 9200
  })
);

// Partitioning function that can be used for range queries
const checkKeyPart = partition.partitioner(
  partition.bucket,
  partition.period,
  partition.forward,
  partition.balance,
  true
);

// NB: collectorDb should be removed after retention period
// start
const dbPartitions = process.env.DB_PARTITIONS ? parseInt(process.env.DB_PARTITIONS) : 1;
const collectorKeyPart = partition.partitioner(
  partition.bucket,
  partition.period,
  partition.createForwardFn(dbPartitions, 4000),
  partition.balance,
  true
);
// end

// TODO: extact config

const prefetchLimit = process.env.PREFETCH_LIMIT || 100;
const rabbitUris =
  process.env.RABBIT_URI
    ? [process.env.RABBIT_URI]
    : vcapenv.serviceInstancesCredentials(process.env.RABBIT_SERVICE_NAME, 'uris');
const secured = process.env.SECURED === 'true';

const getMeteringPlan = util.promisify(meteringClient.plan);
const getPricingPlan = util.promisify(pricingClient.plan);

const getMeteringId = util.promisify(meteringClient.id);
const getRatingId = util.promisify(ratingClient.id);
const getPricingId = util.promisify(pricingClient.id);

const errorDb = dbClient(checkKeyPart, dbClient.dburi(uris()[dbalias], 'abacus-business-errors'));
const outputDb = dbClient(checkKeyPart, dbClient.dburi(uris()[dbalias], 'abacus-meter'));
// NB: collectorDb should be removed after retention period
const collectorInputDb = dbClient(collectorKeyPart,
  dbClient.dburi(uris()[dbalias], 'abacus-collector-collected-usage'));

const buildKeyFn = (usageDoc) => {
  return dbClient.tkuri(
    util.format(
      '%s/%s/%s/%s/%s/%s',
      usageDoc.organization_id,
      usageDoc.space_id,
      usageDoc.consumer_id,
      usageDoc.resource_id,
      usageDoc.plan_id,
      usageDoc.resource_instance_id
    ),
    usageDoc.processed_id);
};

let server;
let messageConsumer;

const startApp = async() => {
  debug('Starting meter app ...');
  const queueName = process.env.ABACUS_COLLECT_QUEUE || 'abacus-collect-queue';
  const token = oauth.cache(uris().api,
    process.env.CLIENT_ID,
    process.env.CLIENT_SECRET, 'abacus.usage.read abacus.usage.write');

  const createAuthHeader = async() => {
    if(!secured)
      return undefined;

    await util.promisify(token.start)();
    return token();
  };

  debug('Creating provisioning client with url %s', uris().provisioning);
  const provisioningClient = new ProvisioningClient(uris().provisioning, createAuthHeader);

  const provisioningPluginClient = {
    getResourceType: (resourceId) => provisioningClient.getResourceType(resourceId),
    getPricingPlan: async(planId, pricingCountry) =>
      getPricingPlan(planId, pricingCountry, await createAuthHeader())
  };

  const accountPluginClient = {
    getAccount: async(usageDoc) => accountClient.getAccount(usageDoc, await createAuthHeader()),
    getMeteringId: async(organizationId, resourceType, planId, timestamp) =>
      getMeteringId(organizationId, resourceType, planId, timestamp, await createAuthHeader()),
    getRatingId: async(organizationId, resourceType, planId, timestamp) =>
      getRatingId(organizationId, resourceType, planId, timestamp, await createAuthHeader()),
    getPricingId: async(organizationId, resourceType, planId, timestamp) =>
      getPricingId(organizationId, resourceType, planId, timestamp, await createAuthHeader())
  };

  debug('Creating meter db client');

  debug('Creating normalizer with provisioning client %o and account client %o',
    provisioningPluginClient, accountPluginClient);
  const normalizer = new Normalizer(provisioningPluginClient, accountPluginClient);

  const meter = new Meter({
    getPlan: async(planId) => getMeteringPlan(planId, await createAuthHeader())
  });

  debug('Creating accumulator client with url %s', uris().accumulator);
  const urlBuilder = createRequestRouting(partition, process.env.ACCUMULATOR_APPS, uris().accumulator);
  const accumulatorClient = new AccumulatorClient(urlBuilder, httpClient, createAuthHeader);

  const meterOutputDbClient = dbClientWrapper(outputDb, buildKeyFn);
  const meterErrorDbClient = dbClientWrapper(errorDb, buildKeyFn);
  const collectorInputDbClient = dbClientWrapper(collectorInputDb, () => {
    throw new Error('Unsupported database PUT operation');
  });

  const messageHandler = new MessageHandler(normalizer, meter, accumulatorClient,
    meterOutputDbClient, meterErrorDbClient);
  const amqpMessageHandler = amqpMessageToJSON(messageHandler);

  const connectionManager = new ConnectionManager(rabbitUris[0]);

  debug(`Creating RabbitMQ consumer with queueName ${queueName} and prefetchLimit ${prefetchLimit}`);
  messageConsumer = new Consumer(connectionManager, queueName, prefetchLimit);

  await messageConsumer.process(amqpMessageHandler);

  const documentRetriever = createRetriever(meterOutputDbClient, meterErrorDbClient, collectorInputDbClient);
  const routes = router();
  routes.get('/v1/metering/collected/usage/t/:time/k/:key(*)',
    require('./lib/routes/routes')(documentRetriever));

  const app = webapp();
  app.use(routes);
  app.use(/^\/v1\/metering|^\/batch$/, oauth.validator(process.env.JWTKEY, process.env.JWTALGO));
  return app.listen();
};

const runCLI = async() => {
  server = await startApp();
};

process.on('SIGTERM', () => {
  debug('Meter is terminated');
  messageConsumer.close();
  if (server) server.close();
  process.exit(0);
});

module.exports = startApp;
module.exports.runCLI = runCLI;

<commit_msg>fix(meter) oauth fix (#942)<commit_after>'use strict';

const { memoize } = require('underscore');

const util = require('util');

const accountClient = require('abacus-accountclient');
const batch = require('abacus-batch');
const breaker = require('abacus-breaker');
const dbClient = require('abacus-dbclient');
const meteringClient = require('abacus-metering-config');
const oauth = require('abacus-oauth');
const ratingClient = require('abacus-rating-config');
const pricingClient = require('abacus-pricing-config');
const partition = require('abacus-partition');
const request = require('abacus-request');
const retry = require('abacus-retry');
const router = require('abacus-router');
const urienv = require('abacus-urienv');
const vcapenv = require('abacus-vcapenv');
const webapp = require('abacus-webapp');

const { ConnectionManager, Consumer, amqpMessageToJSON } = require('abacus-rabbitmq');
const { MessageHandler } = require('./lib/message-handler');
const Meter = require('./lib/meter');
const Normalizer = require('./lib/normalizer');
const createRequestRouting = require('./lib/request-routing');
const ProvisioningClient = require('./lib/provisioning-plugin-client');
const AccumulatorClient = require('./lib/accumulator-client');
const dbClientWrapper = require('./lib/db-client-wrapper');
const createRetriever = require('./lib/routes/document-retriver');

const brequest = retry(breaker(batch(request)));
const httpClient = {
  get: util.promisify(brequest.get),
  post: util.promisify(brequest.post)
};

const debug = require('abacus-debug')('abacus-usage-meter');

const dbalias = process.env.DBALIAS || 'db';

const uris = memoize(() =>
  urienv({
    [dbalias]: 5984,
    api : 9882,
    auth_server: 9883,
    provisioning: 9880,
    accumulator: 9200
  })
);

// Partitioning function that can be used for range queries
const checkKeyPart = partition.partitioner(
  partition.bucket,
  partition.period,
  partition.forward,
  partition.balance,
  true
);

// NB: collectorDb should be removed after retention period
// start
const dbPartitions = process.env.DB_PARTITIONS ? parseInt(process.env.DB_PARTITIONS) : 1;
const collectorKeyPart = partition.partitioner(
  partition.bucket,
  partition.period,
  partition.createForwardFn(dbPartitions, 4000),
  partition.balance,
  true
);
// end

// TODO: extact config

const prefetchLimit = process.env.PREFETCH_LIMIT || 100;
const rabbitUris =
  process.env.RABBIT_URI
    ? [process.env.RABBIT_URI]
    : vcapenv.serviceInstancesCredentials(process.env.RABBIT_SERVICE_NAME, 'uris');
const secured = process.env.SECURED === 'true';

const getMeteringPlan = util.promisify(meteringClient.plan);
const getPricingPlan = util.promisify(pricingClient.plan);

const getMeteringId = util.promisify(meteringClient.id);
const getRatingId = util.promisify(ratingClient.id);
const getPricingId = util.promisify(pricingClient.id);

const errorDb = dbClient(checkKeyPart, dbClient.dburi(uris()[dbalias], 'abacus-business-errors'));
const outputDb = dbClient(checkKeyPart, dbClient.dburi(uris()[dbalias], 'abacus-meter'));
// NB: collectorDb should be removed after retention period
const collectorInputDb = dbClient(collectorKeyPart,
  dbClient.dburi(uris()[dbalias], 'abacus-collector-collected-usage'));

const buildKeyFn = (usageDoc) => {
  return dbClient.tkuri(
    util.format(
      '%s/%s/%s/%s/%s/%s',
      usageDoc.organization_id,
      usageDoc.space_id,
      usageDoc.consumer_id,
      usageDoc.resource_id,
      usageDoc.plan_id,
      usageDoc.resource_instance_id
    ),
    usageDoc.processed_id);
};

let server;
let messageConsumer;

const startApp = async() => {
  debug('Starting meter app ...');
  const queueName = process.env.ABACUS_COLLECT_QUEUE || 'abacus-collect-queue';
  const token = oauth.cache(uris().api,
    process.env.CLIENT_ID,
    process.env.CLIENT_SECRET, 'abacus.usage.read abacus.usage.write');

  if(secured)
    await util.promisify(token.start)();

  const createAuthHeader = async() => {
    if(!secured)
      return undefined;

    return token();
  };

  debug('Creating provisioning client with url %s', uris().provisioning);
  const provisioningClient = new ProvisioningClient(uris().provisioning, createAuthHeader);

  const provisioningPluginClient = {
    getResourceType: (resourceId) => provisioningClient.getResourceType(resourceId),
    getPricingPlan: async(planId, pricingCountry) =>
      getPricingPlan(planId, pricingCountry, await createAuthHeader())
  };

  const accountPluginClient = {
    getAccount: async(usageDoc) => accountClient.getAccount(usageDoc, await createAuthHeader()),
    getMeteringId: async(organizationId, resourceType, planId, timestamp) =>
      getMeteringId(organizationId, resourceType, planId, timestamp, await createAuthHeader()),
    getRatingId: async(organizationId, resourceType, planId, timestamp) =>
      getRatingId(organizationId, resourceType, planId, timestamp, await createAuthHeader()),
    getPricingId: async(organizationId, resourceType, planId, timestamp) =>
      getPricingId(organizationId, resourceType, planId, timestamp, await createAuthHeader())
  };

  debug('Creating meter db client');

  debug('Creating normalizer with provisioning client %o and account client %o',
    provisioningPluginClient, accountPluginClient);
  const normalizer = new Normalizer(provisioningPluginClient, accountPluginClient);

  const meter = new Meter({
    getPlan: async(planId) => getMeteringPlan(planId, await createAuthHeader())
  });

  debug('Creating accumulator client with url %s', uris().accumulator);
  const urlBuilder = createRequestRouting(partition, process.env.ACCUMULATOR_APPS, uris().accumulator);
  const accumulatorClient = new AccumulatorClient(urlBuilder, httpClient, createAuthHeader);

  const meterOutputDbClient = dbClientWrapper(outputDb, buildKeyFn);
  const meterErrorDbClient = dbClientWrapper(errorDb, buildKeyFn);
  const collectorInputDbClient = dbClientWrapper(collectorInputDb, () => {
    throw new Error('Unsupported database PUT operation');
  });

  const messageHandler = new MessageHandler(normalizer, meter, accumulatorClient,
    meterOutputDbClient, meterErrorDbClient);
  const amqpMessageHandler = amqpMessageToJSON(messageHandler);

  const connectionManager = new ConnectionManager(rabbitUris[0]);

  debug(`Creating RabbitMQ consumer with queueName ${queueName} and prefetchLimit ${prefetchLimit}`);
  messageConsumer = new Consumer(connectionManager, queueName, prefetchLimit);

  await messageConsumer.process(amqpMessageHandler);

  const documentRetriever = createRetriever(meterOutputDbClient, meterErrorDbClient, collectorInputDbClient);
  const routes = router();
  routes.get('/v1/metering/collected/usage/t/:time/k/:key(*)',
    require('./lib/routes/routes')(documentRetriever));

  const app = webapp();
  app.use(routes);
  app.use(/^\/v1\/metering|^\/batch$/, oauth.validator(process.env.JWTKEY, process.env.JWTALGO));
  return app.listen();
};

const runCLI = async() => {
  server = await startApp();
};

process.on('SIGTERM', () => {
  debug('Meter is terminated');
  messageConsumer.close();
  if (server) server.close();
  process.exit(0);
});

module.exports = startApp;
module.exports.runCLI = runCLI;

<|endoftext|>


<commit_before>var BadRequestHttpError = require('../errors/httpError/badRequest');
var transformer         = require('transformer');
var _                   = require('lodash');

/**
 * @param {Function} paramsConfigFunction
 * @param {Object}   [options={}]
 * @param {Boolean}    [options.dropFirstLevelUndefinedParams=false]
 *
 * @returns {Function}
 */
module.exports = function(paramsConfigFunction, options) {
    options = options || {};

    var dropFirstLevelUndefinedParams = options.dropFirstLevelUndefinedParams || false;

    return function(req, res, next) {
        var paramsConfig  = paramsConfigFunction(req);
        var requestParams = _.merge({}, req.query, req.body, req.params);

        var chain = transformer(requestParams, paramsConfig).clean();

        if (dropFirstLevelUndefinedParams) {
            chain = chain.dropFirstLevelUndefinedProperties();
        }

        chain
            .filter()
            .setDefaults()
            .validate()
            .result
            .then(function(params) {
                req.parameters = params;
                next();
            })
            .catch(function(errors) {
                var err;

                if (errors instanceof Error) {
                    err = errors;
                } else {
                    err = new BadRequestHttpError();

                    _.forOwn(errors, function(fieldErrors, fieldName) {
                        err.addErrorField(fieldName, fieldErrors[0]);
                    });
                }

                next(err);
            });
    };
};<commit_msg>set req.rawParameters<commit_after>var BadRequestHttpError = require('../errors/httpError/badRequest');
var transformer         = require('transformer');
var _                   = require('lodash');

/**
 * @param {Function} paramsConfigFunction
 * @param {Object}   [options={}]
 * @param {Boolean}    [options.dropFirstLevelUndefinedParams=false]
 *
 * @returns {Function}
 */
module.exports = function(paramsConfigFunction, options) {
    options = options || {};

    var dropFirstLevelUndefinedParams = options.dropFirstLevelUndefinedParams || false;

    return function(req, res, next) {
        var paramsConfig  = paramsConfigFunction(req);
        req.rawParameters = _.merge({}, req.query, req.body, req.params);

        var chain = transformer(req.rawParameters, paramsConfig).clean();

        if (dropFirstLevelUndefinedParams) {
            chain = chain.dropFirstLevelUndefinedProperties();
        }

        chain
            .filter()
            .setDefaults()
            .validate()
            .result
            .then(function(params) {
                req.parameters = params;
                next();
            })
            .catch(function(errors) {
                var err;

                if (errors instanceof Error) {
                    err = errors;
                } else {
                    err = new BadRequestHttpError();

                    _.forOwn(errors, function(fieldErrors, fieldName) {
                        err.addErrorField(fieldName, fieldErrors[0]);
                    });
                }

                next(err);
            });
    };
};<|endoftext|>


<commit_before>'use strict';

// Taken from https://github.com/mrdoob/three.js/blob/master/src/core/Object3D.js and adapted
var traverse = function(obj, callback) {
    var children = obj.children;

    callback(obj);

    if (children && children.length) {
        children.forEach(function(child) {
            traverse(child, callback);
        });
    }
};

if (typeof exports === 'object') {
    module.exports = traverse;
} else {
    window.traverseTree = traverse;
}
<commit_msg>removing TraverseTree file due to casing error<commit_after><|endoftext|>


<commit_before>let async = require('async');

const ContractDeployer = require('./contract_deployer.js');
const cloneDeep = require('clone-deep');

class DeployManager {
  constructor(embark, options) {
    const self = this;
    this.config = embark.config;
    this.logger = embark.logger;
    this.blockchainConfig = this.config.blockchainConfig;

    this.events = embark.events;
    this.plugins = options.plugins;
    this.blockchain = options.blockchain;
    this.gasLimit = false;
    this.fatalErrors = false;
    this.deployOnlyOnConfig = false;
    this.onlyCompile = options.onlyCompile !== undefined ? options.onlyCompile : false;

    this.contractDeployer = new ContractDeployer({
      logger: this.logger,
      events: this.events,
      plugins: this.plugins
    });

    this.events.setCommandHandler('deploy:setGasLimit', (gasLimit) => {
      self.gasLimit = gasLimit;
    });

    this.events.setCommandHandler('deploy:contracts', (cb) => {
      self.deployContracts(cb);
    });

    this.events.setCommandHandler('deploy:contracts:test', (cb) => {
      self.fatalErrors = true;
      self.deployOnlyOnConfig = true;
      self.deployContracts(cb);
    });
  }

  deployAll(done) {
    let self = this;

    self.events.request('contracts:dependencies', (err, contractDependencies) => {
      self.events.request('contracts:list', (err, contracts) => {
        if (err) {
          return done(err);
        }

        self.logger.info(__("deploying contracts"));
        async.waterfall([
          function (next) {
            self.plugins.emitAndRunActionsForEvent("deploy:beforeAll", next);
          },
          function () {
            const contractDeploys = {};
            const errors = [];
            contracts.forEach(contract => {
              function deploy(result, callback) {
                if (typeof result === 'function') {
                  callback = result;
                }
                contract._gasLimit = self.gasLimit;
                self.events.request('deploy:contract', contract, (err) => {
                  if (err) {
                    contract.error = err.message || err;
                    self.logger.error(err.message || err);
                    errors.push(err);
                  }
                  callback();
                });
              }

              const className = contract.className;
              if (!contractDependencies[className] || contractDependencies[className].length === 0) {
                contractDeploys[className] = deploy;
                return;
              }
              contractDeploys[className] = cloneDeep(contractDependencies[className]);
              contractDeploys[className].push(deploy);
            });

            try {
              async.auto(contractDeploys, function(_err, _results) {
                if (errors.length) {
                  _err = __("Error deploying contracts. Please fix errors to continue.");
                  self.logger.error(_err);
                  return done(_err);
                }
                if (contracts.length === 0) {
                  self.logger.info(__("no contracts found"));
                  return done();
                }
                self.logger.info(__("finished deploying contracts"));
                done(err);
              });
            } catch (e) {
              self.logger.error(e.message || e);
              done(__('Error deploying'));
            }
          }
        ]);
      });
    });
  }

  deployContracts(done) {
    let self = this;

    if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
      self.logger.info(__("Blockchain component is disabled in the config").underline);
      this.events.emit('blockchainDisabled', {});
      return done();
    }

    async.waterfall([
      function requestBlockchainConnector(callback) {
        self.events.request("blockchain:object", (blockchain) => {
          self.blockchain = blockchain;
          callback();
        });
      },

      function buildContracts(callback) {
        self.events.request("contracts:build", self.deployOnlyOnConfig, (err) => {
          callback(err);
        });
      },

      // TODO: shouldn't be necessary
      function checkCompileOnly(callback) {
        if (self.onlyCompile) {
          self.events.emit('contractsDeployed');
          return done();
        }
        return callback();
      },

      // TODO: could be implemented as an event (beforeDeployAll)
      function checkIsConnectedToBlockchain(callback) {
        self.blockchain.onReady((err) => {
          callback(err);
        });
      },

      // TODO: this can be done on the fly or as part of the initialization
      function determineDefaultAccount(callback) {
        self.blockchain.determineDefaultAccount((err) => {
          callback(err);
        });
      },

      function deployAllContracts(callback) {
        self.deployAll(function (err) {
          if (!err) {
            self.events.emit('contractsDeployed');
          }
          if (err && self.fatalErrors) {
            return callback(err);
          }
          callback();
        });
      },
      function runAfterDeploy(callback) {
        self.plugins.emitAndRunActionsForEvent('contracts:deploy:afterAll', callback);
      }
    ], function (err, _result) {
      done(err);
    });
  }

}

module.exports = DeployManager;
<commit_msg>limit deployment to 1 for now<commit_after>let async = require('async');

const ContractDeployer = require('./contract_deployer.js');
const cloneDeep = require('clone-deep');

class DeployManager {
  constructor(embark, options) {
    const self = this;
    this.config = embark.config;
    this.logger = embark.logger;
    this.blockchainConfig = this.config.blockchainConfig;

    this.events = embark.events;
    this.plugins = options.plugins;
    this.blockchain = options.blockchain;
    this.gasLimit = false;
    this.fatalErrors = false;
    this.deployOnlyOnConfig = false;
    this.onlyCompile = options.onlyCompile !== undefined ? options.onlyCompile : false;

    this.contractDeployer = new ContractDeployer({
      logger: this.logger,
      events: this.events,
      plugins: this.plugins
    });

    this.events.setCommandHandler('deploy:setGasLimit', (gasLimit) => {
      self.gasLimit = gasLimit;
    });

    this.events.setCommandHandler('deploy:contracts', (cb) => {
      self.deployContracts(cb);
    });

    this.events.setCommandHandler('deploy:contracts:test', (cb) => {
      self.fatalErrors = true;
      self.deployOnlyOnConfig = true;
      self.deployContracts(cb);
    });
  }

  deployAll(done) {
    let self = this;

    self.events.request('contracts:dependencies', (err, contractDependencies) => {
      self.events.request('contracts:list', (err, contracts) => {
        if (err) {
          return done(err);
        }

        self.logger.info(__("deploying contracts"));
        async.waterfall([
          function (next) {
            self.plugins.emitAndRunActionsForEvent("deploy:beforeAll", next);
          },
          function () {
            const contractDeploys = {};
            const errors = [];
            contracts.forEach(contract => {
              function deploy(result, callback) {
                if (typeof result === 'function') {
                  callback = result;
                }
                contract._gasLimit = self.gasLimit;
                self.events.request('deploy:contract', contract, (err) => {
                  if (err) {
                    contract.error = err.message || err;
                    self.logger.error(err.message || err);
                    errors.push(err);
                  }
                  callback();
                });
              }

              const className = contract.className;
              if (!contractDependencies[className] || contractDependencies[className].length === 0) {
                contractDeploys[className] = deploy;
                return;
              }
              contractDeploys[className] = cloneDeep(contractDependencies[className]);
              contractDeploys[className].push(deploy);
            });

            try {
              async.auto(contractDeploys, 1, function(_err, _results) {
                if (errors.length) {
                  _err = __("Error deploying contracts. Please fix errors to continue.");
                  self.logger.error(_err);
                  return done(_err);
                }
                if (contracts.length === 0) {
                  self.logger.info(__("no contracts found"));
                  return done();
                }
                self.logger.info(__("finished deploying contracts"));
                done(err);
              });
            } catch (e) {
              self.logger.error(e.message || e);
              done(__('Error deploying'));
            }
          }
        ]);
      });
    });
  }

  deployContracts(done) {
    let self = this;

    if (self.blockchainConfig === {} || self.blockchainConfig.enabled === false) {
      self.logger.info(__("Blockchain component is disabled in the config").underline);
      this.events.emit('blockchainDisabled', {});
      return done();
    }

    async.waterfall([
      function requestBlockchainConnector(callback) {
        self.events.request("blockchain:object", (blockchain) => {
          self.blockchain = blockchain;
          callback();
        });
      },

      function buildContracts(callback) {
        self.events.request("contracts:build", self.deployOnlyOnConfig, (err) => {
          callback(err);
        });
      },

      // TODO: shouldn't be necessary
      function checkCompileOnly(callback) {
        if (self.onlyCompile) {
          self.events.emit('contractsDeployed');
          return done();
        }
        return callback();
      },

      // TODO: could be implemented as an event (beforeDeployAll)
      function checkIsConnectedToBlockchain(callback) {
        self.blockchain.onReady((err) => {
          callback(err);
        });
      },

      // TODO: this can be done on the fly or as part of the initialization
      function determineDefaultAccount(callback) {
        self.blockchain.determineDefaultAccount((err) => {
          callback(err);
        });
      },

      function deployAllContracts(callback) {
        self.deployAll(function (err) {
          if (!err) {
            self.events.emit('contractsDeployed');
          }
          if (err && self.fatalErrors) {
            return callback(err);
          }
          callback();
        });
      },
      function runAfterDeploy(callback) {
        self.plugins.emitAndRunActionsForEvent('contracts:deploy:afterAll', callback);
      }
    ], function (err, _result) {
      done(err);
    });
  }

}

module.exports = DeployManager;
<|endoftext|>


<commit_before>const async = require('async');
let serveStatic = require('serve-static');
const {canonicalHost, defaultHost, dockerHostSwap} = require('../../utils/host');
const expressWebSocket = require('express-ws');
const express = require('express');
const fs = require('../../core/fs');
require('http-shutdown').extend();
var cors = require('cors');
let path = require('path');
var bodyParser = require('body-parser');
const helmet = require('helmet');

class Server {
  constructor(options) {
    this.logger = options.logger;
    this.buildDir = options.buildDir;
    this.events = options.events;
    this.port = options.port || 8000;
    this.dist = options.dist || 'dist/';
    this.hostname = dockerHostSwap(options.host) || defaultHost;
    this.isFirstStart = true;
    this.opened = false;
    this.openBrowser = options.openBrowser;
    this.logging = false;
    this.plugins = options.plugins;
    this.enableCatchAll = options.enableCatchAll;

    this.events.once('outputDone', () => {
      this.logger.info(this._getMessage());
    });
  }

  enableLogging(callback) {
    this.logging = true;
    return callback(null, __("Enabled Webserver Logs"));
  }

  disableLogging(callback) {
    this.logging = false;
    return callback(null, __("Disabled Webserver Logs"));
  }

  start(callback) {
    callback = callback || function() {};
    const self = this;
    if (this.server && this.server.listening) {
      let message = __("a webserver is already running at") + " " +
        ("http://" + canonicalHost(this.hostname) +
          ":" + this.port).bold.underline.green;
      return callback(null, message);
    }

    const coverage = serveStatic(fs.dappPath('coverage/__root__/'), {'index': ['index.html', 'index.htm']});
    const coverageStyle = serveStatic(fs.dappPath('coverage/'));
    const main = serveStatic(this.buildDir, {'index': ['index.html', 'index.htm']});

    this.app = express();
    const expressWs = expressWebSocket(this.app);
    // Assign Logging Function
    this.app.use(function(req, res, next) {
      if (self.logging) {
        if (!req.headers.upgrade) {
          console.log('Webserver> ' + req.method + " " + req.originalUrl);
        }
      }
      next();
    });

    this.app.use(helmet.noCache());
    this.app.use(cors());
    this.app.use(main);
    this.app.use('/coverage', coverage);
    this.app.use(coverageStyle);

    this.app.use(express.static(path.join(fs.dappPath(this.dist)), {'index': ['index.html', 'index.htm']}));
    this.app.use('/embark', express.static(path.join(__dirname, '../../../embark-ui/build')));

    this.app.use(bodyParser.json()); // support json encoded bodies
    this.app.use(bodyParser.urlencoded({extended: true})); // support encoded bodies

    this.app.ws('/logs', function(ws, _req) {
      self.events.on("log", function(logLevel, logMsg) {
        ws.send(JSON.stringify({msg: logMsg, msg_clear: logMsg.stripColors, logLevel: logLevel}), () => {});
      });
    });

    if (self.plugins) {
      let apiCalls = self.plugins.getPluginsProperty("apiCalls", "apiCalls");
      this.app.get('/embark-api/plugins', function(req, res) {
        res.send(JSON.stringify(self.plugins.plugins.map((plugin) => {
          return {name: plugin.name};
        })));
      });

      for (let apiCall of apiCalls) {
        console.dir("adding " + apiCall.method + " " + apiCall.endpoint);
        this.app[apiCall.method].apply(this.app, [apiCall.endpoint, this.applyAPIFunction.bind(this, apiCall.cb)]);
      }
    }
    const wss = expressWs.getWss('/');

    self.events.on('outputDone', () => {
      wss.clients.forEach(function (client) {
        client.send('outputDone');
      });
      self.events.on('outputError', () => {
        wss.clients.forEach(function (client) {
          client.send('outputError');
        });
      });
    });

    this.events.on('plugins:register:api', (apiCall) => {
      console.dir("adding " + apiCall.method + " " + apiCall.endpoint);
      self.app[apiCall.method].apply(self.app, [apiCall.endpoint, this.applyAPIFunction.bind(this, apiCall.cb)]);
    });

    this.app.get('/embark/*', function (req, res) {
      self.logger.trace('webserver> GET ' + req.path);
      res.sendFile(path.join(__dirname, '../../../embark-ui/build', 'index.html'));
    });

    if (this.enableCatchAll === true) {
      this.app.get('/*', function (req, res) {
        self.logger.trace('webserver> GET ' + req.path);
        res.sendFile(path.join(fs.dappPath(self.dist, 'index.html')));
      });
    }

    async.waterfall([
      function createPlaceholderPage(next) {
        if (!self.isFirstStart) {
          return next();
        }
        self.isFirstStart = false;
        self.events.request('build-placeholder', next);
      },
      function listen(next) {
        self.server = self.app.listen(self.port, self.hostname, () => {
          self.port = self.server.address().port;
          next();
        });
      },
      function openBrowser(next) {
        if (!self.openBrowser || self.opened) {
          return next();
        }
        self.opened = true;
        self.events.request('open-browser', next);
      }
    ], function (err) {
      if (err) {
        return callback(err);
      }

      callback(null, self._getMessage(), self.port);
    });
  }

  _getMessage() {
    return __('webserver available at') + ' ' +
    ('http://' + canonicalHost(this.hostname) + ':' + this.port).bold.underline.green;
  }

   applyAPIFunction (cb, req, res) {
     const authToken = (!res.send) ? req.protocol : req.headers.authorization;
    if (!res.send) {
      return cb(req, res);
    }
    this.events.request('authenticator:authorize', authToken, (err) => {
      if (err) {
        const send = res.send ? res.send.bind(res) : req.send.bind(req); // WS only has the first params
        return send(err);
      }
      cb(req, res);
    });
  }

  stop(callback) {
    callback = callback || function () {};
    if (!this.server || !this.server.listening) {
      return callback(null, __("no webserver is currently running"));
    }
    this.server.close(function() {
      callback(null, __("Webserver stopped"));
    });
  }
}

module.exports = Server;
<commit_msg>remove blockcing if<commit_after>const async = require('async');
let serveStatic = require('serve-static');
const {canonicalHost, defaultHost, dockerHostSwap} = require('../../utils/host');
const expressWebSocket = require('express-ws');
const express = require('express');
const fs = require('../../core/fs');
require('http-shutdown').extend();
var cors = require('cors');
let path = require('path');
var bodyParser = require('body-parser');
const helmet = require('helmet');

class Server {
  constructor(options) {
    this.logger = options.logger;
    this.buildDir = options.buildDir;
    this.events = options.events;
    this.port = options.port || 8000;
    this.dist = options.dist || 'dist/';
    this.hostname = dockerHostSwap(options.host) || defaultHost;
    this.isFirstStart = true;
    this.opened = false;
    this.openBrowser = options.openBrowser;
    this.logging = false;
    this.plugins = options.plugins;
    this.enableCatchAll = options.enableCatchAll;

    this.events.once('outputDone', () => {
      this.logger.info(this._getMessage());
    });
  }

  enableLogging(callback) {
    this.logging = true;
    return callback(null, __("Enabled Webserver Logs"));
  }

  disableLogging(callback) {
    this.logging = false;
    return callback(null, __("Disabled Webserver Logs"));
  }

  start(callback) {
    callback = callback || function() {};
    const self = this;
    if (this.server && this.server.listening) {
      let message = __("a webserver is already running at") + " " +
        ("http://" + canonicalHost(this.hostname) +
          ":" + this.port).bold.underline.green;
      return callback(null, message);
    }

    const coverage = serveStatic(fs.dappPath('coverage/__root__/'), {'index': ['index.html', 'index.htm']});
    const coverageStyle = serveStatic(fs.dappPath('coverage/'));
    const main = serveStatic(this.buildDir, {'index': ['index.html', 'index.htm']});

    this.app = express();
    const expressWs = expressWebSocket(this.app);
    // Assign Logging Function
    this.app.use(function(req, res, next) {
      if (self.logging) {
        if (!req.headers.upgrade) {
          console.log('Webserver> ' + req.method + " " + req.originalUrl);
        }
      }
      next();
    });

    this.app.use(helmet.noCache());
    this.app.use(cors());
    this.app.use(main);
    this.app.use('/coverage', coverage);
    this.app.use(coverageStyle);

    this.app.use(express.static(path.join(fs.dappPath(this.dist)), {'index': ['index.html', 'index.htm']}));
    this.app.use('/embark', express.static(path.join(__dirname, '../../../embark-ui/build')));

    this.app.use(bodyParser.json()); // support json encoded bodies
    this.app.use(bodyParser.urlencoded({extended: true})); // support encoded bodies

    this.app.ws('/logs', function(ws, _req) {
      self.events.on("log", function(logLevel, logMsg) {
        ws.send(JSON.stringify({msg: logMsg, msg_clear: logMsg.stripColors, logLevel: logLevel}), () => {});
      });
    });

    if (self.plugins) {
      let apiCalls = self.plugins.getPluginsProperty("apiCalls", "apiCalls");
      this.app.get('/embark-api/plugins', function(req, res) {
        res.send(JSON.stringify(self.plugins.plugins.map((plugin) => {
          return {name: plugin.name};
        })));
      });

      for (let apiCall of apiCalls) {
        console.dir("adding " + apiCall.method + " " + apiCall.endpoint);
        this.app[apiCall.method].apply(this.app, [apiCall.endpoint, this.applyAPIFunction.bind(this, apiCall.cb)]);
      }
    }
    const wss = expressWs.getWss('/');

    self.events.on('outputDone', () => {
      wss.clients.forEach(function (client) {
        client.send('outputDone');
      });
      self.events.on('outputError', () => {
        wss.clients.forEach(function (client) {
          client.send('outputError');
        });
      });
    });

    this.events.on('plugins:register:api', (apiCall) => {
      console.dir("adding " + apiCall.method + " " + apiCall.endpoint);
      self.app[apiCall.method].apply(self.app, [apiCall.endpoint, this.applyAPIFunction.bind(this, apiCall.cb)]);
    });

    this.app.get('/embark/*', function (req, res) {
      self.logger.trace('webserver> GET ' + req.path);
      res.sendFile(path.join(__dirname, '../../../embark-ui/build', 'index.html'));
    });

    if (this.enableCatchAll === true) {
      this.app.get('/*', function (req, res) {
        self.logger.trace('webserver> GET ' + req.path);
        res.sendFile(path.join(fs.dappPath(self.dist, 'index.html')));
      });
    }

    async.waterfall([
      function createPlaceholderPage(next) {
        if (!self.isFirstStart) {
          return next();
        }
        self.isFirstStart = false;
        self.events.request('build-placeholder', next);
      },
      function listen(next) {
        self.server = self.app.listen(self.port, self.hostname, () => {
          self.port = self.server.address().port;
          next();
        });
      },
      function openBrowser(next) {
        if (!self.openBrowser || self.opened) {
          return next();
        }
        self.opened = true;
        self.events.request('open-browser', next);
      }
    ], function (err) {
      if (err) {
        return callback(err);
      }

      callback(null, self._getMessage(), self.port);
    });
  }

  _getMessage() {
    return __('webserver available at') + ' ' +
    ('http://' + canonicalHost(this.hostname) + ':' + this.port).bold.underline.green;
  }

   applyAPIFunction (cb, req, res) {
     const authToken = (!res.send) ? req.protocol : req.headers.authorization;
    this.events.request('authenticator:authorize', authToken, (err) => {
      if (err) {
        const send = res.send ? res.send.bind(res) : req.send.bind(req); // WS only has the first params
        return send(err);
      }
      cb(req, res);
    });
  }

  stop(callback) {
    callback = callback || function () {};
    if (!this.server || !this.server.listening) {
      return callback(null, __("no webserver is currently running"));
    }
    this.server.close(function() {
      callback(null, __("Webserver stopped"));
    });
  }
}

module.exports = Server;
<|endoftext|>