<commit_before>var Path = require('path');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var webpack = require('webpack');
var LiveReloadPlugin = require('webpack-livereload-plugin');

module.exports = {
	entry: {
		app_min:'./src/App.js',
		background:'./src/background.js'
		// popup_min:'./src/popup.jsx'
	},
	output:{
		path:Path.resolve(__dirname, 'ComicsScroller/'),
		filename: 'js/[name].js'
	},
	module:{
		loaders: [
			{
				test: /\.json?$/,
				loader: 'json-loader'
			},{
				test: /\.jsx?$/,
				loader: 'babel-loader',
				exclude: /node_modules/,
				query: { compact: false }
			},{
				test: /\.less$/,
				loader: ExtractTextPlugin.extract('style-loader','css-loader!less-loader')
			},{
				test: /\.css$/,
				loader: ExtractTextPlugin.extract('style-loader','css-loader')
			},
			{
				test: /\.scss$/,
				loaders: ['style', 'css', 'sass']
			},
			{
				test: /\.(png|jpg|gif)$/,
				loader: 'url-loader?limit=8192'
			},
			{ test: /\.(ttf|eot|svg)$/,
				loader: 'url-loader?limit=100000'
			}
		]
	},
	plugins: [
		new ExtractTextPlugin('css/[name].css'),
		// new webpack.IgnorePlugin(/ReactContext|react\/addons/),
		new LiveReloadPlugin({appendScriptTag: true})
	]
	devtool: '#inline-source-map'
};
<commit_msg>fix dev webpack config<commit_after>var Path = require('path');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var LiveReloadPlugin = require('webpack-livereload-plugin');

module.exports = {
	entry: {
		app_min:'./src/App.js',
		background:'./src/background.js'
		// popup_min:'./src/popup.jsx'
	},
	output:{
		path:Path.resolve(__dirname, 'ComicsScroller/'),
		filename: 'js/[name].js'
	},
	module:{
		loaders: [
			{
				test: /\.json?$/,
				loader: 'json-loader'
			},{
				test: /\.jsx?$/,
				loader: 'babel-loader',
				exclude: /node_modules/,
				query: { compact: false }
			},{
				test: /\.less$/,
				loader: ExtractTextPlugin.extract('style-loader','css-loader!less-loader')
			},{
				test: /\.css$/,
				loader: ExtractTextPlugin.extract('style-loader','css-loader')
			},
			{
				test: /\.scss$/,
				loaders: ['style', 'css', 'sass']
			},
			{
				test: /\.(png|jpg|gif)$/,
				loader: 'url-loader?limit=8192'
			},
			{ test: /\.(ttf|eot|svg)$/,
				loader: 'url-loader?limit=100000'
			}
		]
	},
	plugins: [
		new ExtractTextPlugin('css/[name].css'),
		// new webpack.IgnorePlugin(/ReactContext|react\/addons/),
		new LiveReloadPlugin({appendScriptTag: true})
	],
	devtool: '#inline-source-map'
};
<|endoftext|>


<commit_before>const webpack = require("webpack");
const path = require("path");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    entry: "./src/com/mendix/widget/carousel/Carousel.ts",
    output: {
        path: path.resolve(__dirname, "dist/tmp"),
        filename: "src/com/mendix/widget/carousel/Carousel.js",
        libraryTarget:  "umd",
        umdNamedDefine: true,
        library: "com.mendix.widget.carousel.Carousel"
    },
    resolve: {
        extensions: [ "", ".ts", ".js", ".json" ]
    },
    errorDetails: true,
    module: {
        loaders: [
            { test: /\.ts?$/, loader: "ts-loader" },
            { test: /\.json$/, loader: "json" },
            { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }
        ],
        postLoaders: [ {
            test: /\.ts$/,
            loader: "istanbul-instrumenter",
            include: path.resolve(__dirname, "src"),
            exclude: /\.(spec)\.ts$/
        } ]
    },
    devtool: "source-map",
    externals: [ "mxui/widget/_WidgetBase", "dojo/_base/declare" ],
    plugins: [
        new CopyWebpackPlugin([
            { from: "src/**/*.js" },
            { from: "src/**/*.xml" }
        ], {
            copyUnmodified: true
        }),
        new ExtractTextPlugin("./src/com/mendix/widget/ProgressCircle/ui/ProgressCircle.css")
    ],
    watch: true
};
<commit_msg>fixup! Widget scaffolding with project tools and dependencies<commit_after>const webpack = require("webpack");
const path = require("path");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
    entry: "./src/com/mendix/widget/ProgressCircle/ProgressCircle.ts",
    output: {
        path: path.resolve(__dirname, "dist/tmp"),
        filename: "src/com/mendix/widget/ProgressCircle/ProgressCircle.js",
        libraryTarget:  "umd",
        umdNamedDefine: true,
        library: "com.mendix.widget.ProgressCircle.ProgressCircle"
    },
    resolve: {
        extensions: [ "", ".ts", ".js", ".json" ]
    },
    errorDetails: true,
    module: {
        loaders: [
            { test: /\.ts?$/, loader: "ts-loader" },
            { test: /\.json$/, loader: "json" },
            { test: /\.css$/, loader: ExtractTextPlugin.extract("style-loader", "css-loader") }
        ],
        postLoaders: [ {
            test: /\.ts$/,
            loader: "istanbul-instrumenter",
            include: path.resolve(__dirname, "src"),
            exclude: /\.(spec)\.ts$/
        } ]
    },
    devtool: "source-map",
    externals: [ "mxui/widget/_WidgetBase", "dojo/_base/declare" ],
    plugins: [
        new CopyWebpackPlugin([
            { from: "src/**/*.js" },
            { from: "src/**/*.xml" }
        ], {
            copyUnmodified: true
        }),
        new ExtractTextPlugin("./src/com/mendix/widget/ProgressCircle/ui/ProgressCircle.css")
    ],
    watch: true
};
<|endoftext|>


<commit_before>// Helper: root() is defined at the bottom
var path = require('path');
var webpack = require('webpack');

// Webpack Plugins
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
var autoprefixer = require('autoprefixer');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;

/**
 * Env
 * Get npm lifecycle event to identify the environment
 */
var ENV = process.env.npm_lifecycle_event;
var isTestWatch = ENV === 'test-watch';
var isTest = ENV === 'test' || isTestWatch;
var isProd = ENV === 'build';

var BACKEND_API_URL = process.env.BACKEND_API_URL;
if (!BACKEND_API_URL && !isTest) {
  throw new Error('Environment variable BACKEND_API_URL is required');
}

//Proxy config
var leadingSlash = BACKEND_API_URL[BACKEND_API_URL.length -1] === '/';
var redirectTo =  leadingSlash ? BACKEND_API_URL.substr(0, BACKEND_API_URL.length - 1) : BACKEND_API_URL;
var apiUrl = '/client/api';
var consoleUrl = '/client/console';

module.exports = function makeWebpackConfig() {
  /**
   * Config
   * Reference: http://webpack.github.io/docs/configuration.html
   * This is the object where all configuration gets set
   */
  var config = {};

  /**
   * Devtool
   * Reference: http://webpack.github.io/docs/configuration.html#devtool
   * Type of sourcemap to use per build type
   */
  if (isProd) {
    config.devtool = 'source-map';
  }
  else if (isTest) {
    config.devtool = 'inline-source-map';
  }
  else {
    config.devtool = 'eval';
  }

  /**
   * Entry
   * Reference: http://webpack.github.io/docs/configuration.html#entry
   */
  config.entry = isTest ? {} : {
    'polyfills': './src/polyfills.ts',
    'vendor': './src/vendor.ts',
    'app': './src/main.ts' // our angular app
  };

  /**
   * Output
   * Reference: http://webpack.github.io/docs/configuration.html#output
   */
  config.output = isTest ? {} : {
    path: root('dist'),
    publicPath: isProd ? '/' : 'http://localhost:8080/',
    filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js',
    chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'
  };

  /**
   * Resolve
   * Reference: http://webpack.github.io/docs/configuration.html#resolve
   */
  config.resolve = {
    // only discover files that have those extensions
    extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html'],
  };

  var atlOptions = '';
  if (isTest && !isTestWatch) {
    // awesome-typescript-loader needs to output inlineSourceMap for code coverage to work with source maps.
    atlOptions = 'inlineSourceMap=true&sourceMap=false';
  }

  /**
   * Loaders
   * Reference: http://webpack.github.io/docs/configuration.html#module-loaders
   * List: http://webpack.github.io/docs/list-of-loaders.html
   * This handles most of the magic responsible for converting modules
   */
  config.module = {
    rules: [
      // Support for .ts files.
      {
        test: /\.ts$/,
        loaders: ['awesome-typescript-loader?' + atlOptions, 'angular2-template-loader', '@angularclass/hmr-loader'],
        exclude: [isTest ? /\.(e2e)\.ts$/ : /\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/]
      },

      // copy those assets to output
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'file-loader?name=fonts/[name].[hash].[ext]?'
      },

      // Support for *.json files.
      {test: /\.json$/, loader: 'json-loader'},

      // Support for CSS as raw text
      // use 'null' loader in test mode (https://github.com/webpack/null-loader)
      // all css in src/style will be bundled in an external css file
      {
        test: /\.css$/,
        exclude: root('src', 'app'),
        loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: ['css-loader', 'postcss-loader']})
      },
      // all css required in src/app files will be merged in js files
      {test: /\.css$/, include: root('src', 'app'), loader: 'raw-loader!postcss-loader'},

      // support for .scss files
      // use 'null' loader in test mode (https://github.com/webpack/null-loader)
      // all css in src/style will be bundled in an external css file
      {
        test: /\.(scss|sass)$/,
        exclude: root('src', 'app'),
        loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: ['css-loader', 'postcss-loader', 'sass-loader']})
      },
      // all css required in src/app files will be merged in js files
      {test: /\.(scss|sass)$/, exclude: root('src', 'style'), loader: 'raw-loader!postcss-loader!sass-loader'},

      // support for .html as raw text
      // todo: change the loader to something that adds a hash to images
      {test: /\.html$/, loader: 'raw-loader',  exclude: root('src', 'public')}
    ]
  };

  if (isTest && !isTestWatch) {
    // instrument only testing sources with Istanbul, covers ts files
    config.module.rules.push({
      test: /\.ts$/,
      enforce: 'post',
      include: path.resolve('src'),
      loader: 'istanbul-instrumenter-loader',
      exclude: [/\.spec\.ts$/, /\.e2e\.ts$/, /node_modules/]
    });
  }

  if (!isTest || !isTestWatch) {
    // tslint support
    config.module.rules.push({
      test: /\.ts$/,
      enforce: 'pre',
      loader: 'tslint-loader'
    });
  }

  /**
   * Plugins
   * Reference: http://webpack.github.io/docs/configuration.html#plugins
   * List: http://webpack.github.io/docs/list-of-plugins.html
   */
  config.plugins = [
    // Define env variables to help with builds
    // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
    new webpack.DefinePlugin({
      // Environment helpers
      'process.env': {
        ENV: JSON.stringify(ENV)
      }
    }),

    // Workaround needed for angular 2 angular/angular#11580
      new webpack.ContextReplacementPlugin(
        // The (\\|\/) piece accounts for path separators in *nix and Windows
        /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
        root('./src') // location of your src
      ),

    // Tslint configuration for webpack 2
    new webpack.LoaderOptionsPlugin({
      options: {
        /**
         * Apply the tslint loader as pre/postLoader
         * Reference: https://github.com/wbuchwalter/tslint-loader
         */
        tslint: {
          emitErrors: false,
          failOnHint: false
        },
        /**
         * Sass
         * Reference: https://github.com/jtangelder/sass-loader
         * Transforms .scss files to .css
         */
        sassLoader: {
          //includePaths: [path.resolve(__dirname, "node_modules/foundation-sites/scss")]
        },
        /**
         * PostCSS
         * Reference: https://github.com/postcss/autoprefixer-core
         * Add vendor prefixes to your css
         */
        postcss: [
          autoprefixer({
            browsers: ['last 2 version']
          })
        ]
      }
    })
  ];

  if (!isTest && !isTestWatch) {
    config.plugins.push(
      new ForkCheckerPlugin(),

      // Generate common chunks if necessary
      // Reference: https://webpack.github.io/docs/code-splitting.html
      // Reference: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
      new CommonsChunkPlugin({
        name: ['vendor', 'polyfills']
      }),

      // Inject script and link tags into html files
      // Reference: https://github.com/ampedandwired/html-webpack-plugin
      new HtmlWebpackPlugin({
        template: './src/public/index.html',
        chunksSortMode: 'dependency'
      }),

      // Extract css files
      // Reference: https://github.com/webpack/extract-text-webpack-plugin
      // Disabled when in test mode or not in build mode
      new ExtractTextPlugin({filename: 'css/[name].[hash].css', disable: !isProd})
    );
  }

  // Add build specific plugins
  if (isProd) {
    config.plugins.push(
      // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
      // Only emit files when there are no errors
      new webpack.NoErrorsPlugin(),

      // // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
      // // Dedupe modules in the output
      // new webpack.optimize.DedupePlugin(),

      // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
      // Minify all javascript, switch loaders to minimizing mode
      new webpack.optimize.UglifyJsPlugin({
        beautify: false,
        output: {
          comments: false
        },
        mangle: {
          screw_ie8: true
        },
        compress: {
          screw_ie8: true,
          warnings: false,
          conditionals: true,
          unused: true,
          comparisons: true,
          sequences: true,
          dead_code: true,
          evaluate: true,
          if_return: true,
          join_vars: true,
          negate_iife: true
        }
      }),

      // Copy assets from the public folder
      // Reference: https://github.com/kevlened/copy-webpack-plugin
      new CopyWebpackPlugin([
        {from: root('src/public'), ignore: ['config-dev.json']},
      ])
    );
  }

  /**
   * Dev server configuration
   * Reference: http://webpack.github.io/docs/configuration.html#devserver
   * Reference: http://webpack.github.io/docs/webpack-dev-server.html
   */
  config.devServer = {
    proxy: { },
    contentBase: './src/public',
    historyApiFallback: true,
    quiet: true,
    stats: 'minimal' // none (or false), errors-only, minimal, normal (or true) and verbose
  };

  config.devServer.proxy[apiUrl] = {
    target: redirectTo + apiUrl,
    secure: false
  };

  config.devServer.proxy[consoleUrl] = {
    target: redirectTo + consoleUrl,
    pathRewrite: { }
  };

  config.devServer.proxy[consoleUrl].pathRewrite["^" + consoleUrl] = "";

  return config;
}();

// Helper functions
function root(args) {
  args = Array.prototype.slice.call(arguments, 0);
  return path.join.apply(path, [__dirname].concat(args));
}
<commit_msg>fix webpack config<commit_after>// Helper: root() is defined at the bottom
var path = require('path');
var webpack = require('webpack');

// Webpack Plugins
var CommonsChunkPlugin = webpack.optimize.CommonsChunkPlugin;
var autoprefixer = require('autoprefixer');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var CopyWebpackPlugin = require('copy-webpack-plugin');
var ForkCheckerPlugin = require('awesome-typescript-loader').ForkCheckerPlugin;

/**
 * Env
 * Get npm lifecycle event to identify the environment
 */
var ENV = process.env.npm_lifecycle_event;
var isTestWatch = ENV === 'test-watch';
var isTest = ENV === 'test' || isTestWatch;
var isProd = ENV === 'build';
var isDev = !isTest && !isProd;

var BACKEND_API_URL = process.env.BACKEND_API_URL;
if (!BACKEND_API_URL && isDev) {
  throw new Error('Environment variable BACKEND_API_URL is required');
}

//Proxy config
var redirectTo;
if (isDev) {
  var leadingSlash = BACKEND_API_URL[BACKEND_API_URL.length -1] === '/';
  redirectTo =  leadingSlash ? BACKEND_API_URL.substr(0, BACKEND_API_URL.length - 1) : BACKEND_API_URL;
}
var apiUrl = '/client/api';
var consoleUrl = '/client/console';

module.exports = function makeWebpackConfig() {
  /**
   * Config
   * Reference: http://webpack.github.io/docs/configuration.html
   * This is the object where all configuration gets set
   */
  var config = {};

  /**
   * Devtool
   * Reference: http://webpack.github.io/docs/configuration.html#devtool
   * Type of sourcemap to use per build type
   */
  if (isProd) {
    config.devtool = 'source-map';
  }
  else if (isTest) {
    config.devtool = 'inline-source-map';
  }
  else {
    config.devtool = 'eval';
  }

  /**
   * Entry
   * Reference: http://webpack.github.io/docs/configuration.html#entry
   */
  config.entry = isTest ? {} : {
    'polyfills': './src/polyfills.ts',
    'vendor': './src/vendor.ts',
    'app': './src/main.ts' // our angular app
  };

  /**
   * Output
   * Reference: http://webpack.github.io/docs/configuration.html#output
   */
  config.output = isTest ? {} : {
    path: root('dist'),
    publicPath: isProd ? '/' : 'http://localhost:8080/',
    filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js',
    chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'
  };

  /**
   * Resolve
   * Reference: http://webpack.github.io/docs/configuration.html#resolve
   */
  config.resolve = {
    // only discover files that have those extensions
    extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html'],
  };

  var atlOptions = '';
  if (isTest && !isTestWatch) {
    // awesome-typescript-loader needs to output inlineSourceMap for code coverage to work with source maps.
    atlOptions = 'inlineSourceMap=true&sourceMap=false';
  }

  /**
   * Loaders
   * Reference: http://webpack.github.io/docs/configuration.html#module-loaders
   * List: http://webpack.github.io/docs/list-of-loaders.html
   * This handles most of the magic responsible for converting modules
   */
  config.module = {
    rules: [
      // Support for .ts files.
      {
        test: /\.ts$/,
        loaders: ['awesome-typescript-loader?' + atlOptions, 'angular2-template-loader', '@angularclass/hmr-loader'],
        exclude: [isTest ? /\.(e2e)\.ts$/ : /\.(spec|e2e)\.ts$/, /node_modules\/(?!(ng2-.+))/]
      },

      // copy those assets to output
      {
        test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'file-loader?name=fonts/[name].[hash].[ext]?'
      },

      // Support for *.json files.
      {test: /\.json$/, loader: 'json-loader'},

      // Support for CSS as raw text
      // use 'null' loader in test mode (https://github.com/webpack/null-loader)
      // all css in src/style will be bundled in an external css file
      {
        test: /\.css$/,
        exclude: root('src', 'app'),
        loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: ['css-loader', 'postcss-loader']})
      },
      // all css required in src/app files will be merged in js files
      {test: /\.css$/, include: root('src', 'app'), loader: 'raw-loader!postcss-loader'},

      // support for .scss files
      // use 'null' loader in test mode (https://github.com/webpack/null-loader)
      // all css in src/style will be bundled in an external css file
      {
        test: /\.(scss|sass)$/,
        exclude: root('src', 'app'),
        loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallbackLoader: 'style-loader', loader: ['css-loader', 'postcss-loader', 'sass-loader']})
      },
      // all css required in src/app files will be merged in js files
      {test: /\.(scss|sass)$/, exclude: root('src', 'style'), loader: 'raw-loader!postcss-loader!sass-loader'},

      // support for .html as raw text
      // todo: change the loader to something that adds a hash to images
      {test: /\.html$/, loader: 'raw-loader',  exclude: root('src', 'public')}
    ]
  };

  if (isTest && !isTestWatch) {
    // instrument only testing sources with Istanbul, covers ts files
    config.module.rules.push({
      test: /\.ts$/,
      enforce: 'post',
      include: path.resolve('src'),
      loader: 'istanbul-instrumenter-loader',
      exclude: [/\.spec\.ts$/, /\.e2e\.ts$/, /node_modules/]
    });
  }

  if (!isTest || !isTestWatch) {
    // tslint support
    config.module.rules.push({
      test: /\.ts$/,
      enforce: 'pre',
      loader: 'tslint-loader'
    });
  }

  /**
   * Plugins
   * Reference: http://webpack.github.io/docs/configuration.html#plugins
   * List: http://webpack.github.io/docs/list-of-plugins.html
   */
  config.plugins = [
    // Define env variables to help with builds
    // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
    new webpack.DefinePlugin({
      // Environment helpers
      'process.env': {
        ENV: JSON.stringify(ENV)
      }
    }),

    // Workaround needed for angular 2 angular/angular#11580
      new webpack.ContextReplacementPlugin(
        // The (\\|\/) piece accounts for path separators in *nix and Windows
        /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
        root('./src') // location of your src
      ),

    // Tslint configuration for webpack 2
    new webpack.LoaderOptionsPlugin({
      options: {
        /**
         * Apply the tslint loader as pre/postLoader
         * Reference: https://github.com/wbuchwalter/tslint-loader
         */
        tslint: {
          emitErrors: false,
          failOnHint: false
        },
        /**
         * Sass
         * Reference: https://github.com/jtangelder/sass-loader
         * Transforms .scss files to .css
         */
        sassLoader: {
          //includePaths: [path.resolve(__dirname, "node_modules/foundation-sites/scss")]
        },
        /**
         * PostCSS
         * Reference: https://github.com/postcss/autoprefixer-core
         * Add vendor prefixes to your css
         */
        postcss: [
          autoprefixer({
            browsers: ['last 2 version']
          })
        ]
      }
    })
  ];

  if (!isTest && !isTestWatch) {
    config.plugins.push(
      new ForkCheckerPlugin(),

      // Generate common chunks if necessary
      // Reference: https://webpack.github.io/docs/code-splitting.html
      // Reference: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
      new CommonsChunkPlugin({
        name: ['vendor', 'polyfills']
      }),

      // Inject script and link tags into html files
      // Reference: https://github.com/ampedandwired/html-webpack-plugin
      new HtmlWebpackPlugin({
        template: './src/public/index.html',
        chunksSortMode: 'dependency'
      }),

      // Extract css files
      // Reference: https://github.com/webpack/extract-text-webpack-plugin
      // Disabled when in test mode or not in build mode
      new ExtractTextPlugin({filename: 'css/[name].[hash].css', disable: !isProd})
    );
  }

  // Add build specific plugins
  if (isProd) {
    config.plugins.push(
      // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
      // Only emit files when there are no errors
      new webpack.NoErrorsPlugin(),

      // // Reference: http://webpack.github.io/docs/list-of-plugins.html#dedupeplugin
      // // Dedupe modules in the output
      // new webpack.optimize.DedupePlugin(),

      // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
      // Minify all javascript, switch loaders to minimizing mode
      new webpack.optimize.UglifyJsPlugin({
        beautify: false,
        output: {
          comments: false
        },
        mangle: {
          screw_ie8: true
        },
        compress: {
          screw_ie8: true,
          warnings: false,
          conditionals: true,
          unused: true,
          comparisons: true,
          sequences: true,
          dead_code: true,
          evaluate: true,
          if_return: true,
          join_vars: true,
          negate_iife: true
        }
      }),

      // Copy assets from the public folder
      // Reference: https://github.com/kevlened/copy-webpack-plugin
      new CopyWebpackPlugin([
        {from: root('src/public'), ignore: ['config-dev.json']},
      ])
    );
  }

  /**
   * Dev server configuration
   * Reference: http://webpack.github.io/docs/configuration.html#devserver
   * Reference: http://webpack.github.io/docs/webpack-dev-server.html
   */
  config.devServer = {
    proxy: { },
    contentBase: './src/public',
    historyApiFallback: true,
    quiet: true,
    stats: 'minimal' // none (or false), errors-only, minimal, normal (or true) and verbose
  };

  if (isDev) {
    config.devServer.proxy[apiUrl] = {
      target: redirectTo + apiUrl,
      secure: false
    };

    config.devServer.proxy[consoleUrl] = {
      target: redirectTo + consoleUrl,
      pathRewrite: { }
    };

    config.devServer.proxy[consoleUrl].pathRewrite["^" + consoleUrl] = "";
  }

  return config;
}();

// Helper functions
function root(args) {
  args = Array.prototype.slice.call(arguments, 0);
  return path.join.apply(path, [__dirname].concat(args));
}
<|endoftext|>


<commit_before>const webpack = require('webpack');
const path = require('path');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

module.exports = (env => {

  if (!env) env = { production: false, karma: false };

  let mode = env.production ? "production" : "development";
  let tsconfig = !env.karma ? "tsconfig.json" : "tsconfig.test.json";
  let output = env.production ? "dist" : "dev";
  let filename = env.production ? "robotlegs-pixi.min.js" : "robotlegs-pixi.js";

  return {
    mode: mode,
    entry: {
      main: path.join(__dirname, "src/index.ts")
    },

    output: {
      path: path.join(__dirname, output),
      filename: filename,

      libraryTarget: "var",
      library: "RobotlegsJSPixi"
    },

    devtool: env.production ? undefined : "inline-source-map",

    module: {
      rules: [
        {
          test: /\.ts$/,
          loader: "ts-loader?configFile=" + tsconfig
        },
        {
          test: ((env.production) /* disable this loader for production builds */
            ? /^$/
            : /^(.(?!\.test))*\.ts$/),
          loader: "istanbul-instrumenter-loader",
          query: {
            embedSource: true
          },
          enforce: "post"
        }
      ]
    },

    plugins: (
      (env.production)
        ? [ new UglifyJSPlugin() ]
        : [ new webpack.SourceMapDevToolPlugin({ test: /\.ts$/i }) ]
    ),

    resolve: {
      extensions: ['.ts', '.js', '.json']
    }
  }
});
<commit_msg>update webpack configuration<commit_after>const webpack = require("webpack");
const path = require("path");
const UglifyJsPlugin = require("uglifyjs-webpack-plugin");

module.exports = env => {

  if (!env) env = { production: false, karma: false };

  let mode = env.production ? "production" : "development";
  let tsconfig = !env.karma ? "tsconfig.json" : "tsconfig.test.json";
  let output = env.production ? "dist" : "dist-test";
  let filename = env.production ? "robotlegs-pixi.min.js" : "robotlegs-pixi.js";

  return {
    mode: mode,

    entry: {
      main: path.join(__dirname, "src/index.ts")
    },

    output: {
      path: path.join(__dirname, output),
      filename: filename,

      libraryTarget: "var",
      library: "RobotlegsJSPixi"
    },

    devtool: env.production ? undefined : "inline-source-map",

    module: {
      rules: [
        {
          test: /\.ts$/,
          loader: "ts-loader?configFile=" + tsconfig
        },
        {
          test: ((env.production) /* disable this loader for production builds */
            ? /^$/
            : /^(.(?!\.test))*\.ts$/),
          loader: "istanbul-instrumenter-loader",
          query: {
            embedSource: true
          },
          enforce: "post"
        }
      ]
    },

    plugins: (
      (env.production)
        ? []
        : [ new webpack.SourceMapDevToolPlugin({ test: /\.ts$/i }) ]
    ),

    optimization:
      (env.production)
        ? {
            concatenateModules: true,
            minimize: true,
            minimizer: [
              new UglifyJsPlugin({
                cache: true,
                parallel: 4,
                uglifyOptions: {
                  output: {
                    comments: false
                  }
                }
              })
            ]
          }
        : {}
    ,

    resolve: {
      extensions: [".ts", ".js", ".json"]
    }
  }
};
<|endoftext|>


<commit_before>/*
 msbuild.js

 copyright (c) 2014 jonathan haker
 Licensed under the MIT license.
 https://github.com/jhaker/nodejs-msbuild

*/
if (!String.prototype.endsWith) {
  String.prototype.endsWith = function(searchString, position) {
      var subjectString = this.toString();
      if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
        position = subjectString.length;
      }
      position -= searchString.length;
      var lastIndex = subjectString.indexOf(searchString, position);
      return lastIndex !== -1 && lastIndex === position;
  };
}

var events = require('events'),
	async = require('async'),
	colors = require('colors'),
	fs = require('fs'),
	path = require('path'),
	spawn = require('child_process').spawn;

var default_os = require('os').platform();

if (default_os !== 'linux') default_os = "windows";

var args = [];

for (var arg in process.argv) {
     args.push(process.argv[arg]);
}

var help = args.splice(2,1);
var x = function(){};
var _ = new x();

_.isPlainObject = function (obj) {
  var ctor, key;
  if (typeof obj != 'object' || !obj || toString.call(obj) != '[object Object]') {
    return false;
  }
  ctor = typeof obj.constructor == 'function' && obj.constructor.prototype;
  if (!ctor || !hasOwnProperty.call(ctor, 'isPrototypeOf')) {
    return false;
  }
  for (key in obj) {}
  return key === void 0 || hasOwnProperty.call(obj, key);
};

var validateCmdParameter = function(param){
	if (param.length < 2)  return false;
	return true;
}

var validFrameworkDir = function(dir) {
	return dir.indexOf('1') === 0;
}

var getFrameworkDirectories = function(msbuildDir){
	if (fs.existsSync(msbuildDir)) {
		return fs.readdirSync(msbuildDir)
			.filter(validFrameworkDir);
	} else {
		return [];
	}
}

var mapProcessor = function(processor) {
	if(!isNaN(processor) && processor !== undefined){
		processor = 'x'+processor;
	}
	if(processor !== 'x64'){
		processor = 'x86';
	}
	return processor;
}

var defaultPath = process.cwd();

var lineBreak = '\n- - - - - - - - - - - - - - - -';

var msbuild = function(){
	events.EventEmitter.call(this);
	this.showHelp = help == '?';
	this.processors = { 'x86': 'Framework', 'x64': 'Framework64' };
	this.os 				= default_os;  	// windows, linux
	this.processor 			= 'x64';  		// 'x86', 'x64'
	this.version			= '15.0';		// tools version; determines local path to msbuild.exe
	this.sourcePath 		= defaultPath;  // 'c:/mypath/mysolution.sln'   or   'c:/mypath/myproject.csproj
	this.configuration 		= undefined;   	// solution configurations; targets an environment (debug,release)
	this.publishProfile 	= undefined;   	// publish profiles; targets a specific machine (app01,app02)
	this.outputPath 		= ''; 			// 'c:/deploys/release'
	this.verbose 			= false;
	/***
	property overrides (example: ['/clp:ErrorsOnly;', '/p:WarningLevel=2','/p:OutputDir=bin\Debug']  )
	target framework overrides (example:  ['/tv:4.0'] )
	***/
	this.overrideParams		= [];
};

msbuild.prototype.toolsVersion = {
		'2.0': '2.0.50727',
		'3.0':'3.0',
		'3.5': '3.5',
		'4.0': '4.0.30319',
		'4.5': '4.0.30319',
		'12.0': '12.0',
        '14.0':'14.0',
		'15.0':'15.0'
	};

msbuild.prototype.__proto__ = events.EventEmitter.prototype;

msbuild.prototype.logger = function(msg){
	console.log(msg);
}

msbuild.prototype.getMSBuildPath = function(os,processor,version){
	if(os === 'linux' || os === 'darwin') return "xbuild";

	var frameworkDirectories,programFilesDir,msbuildDir,exeDir;
	var vs2017Type = {
		Pro: 'Professional',
		Enterprise: 'Enterprise',
		Community: 'Community',
		BuildTools: 'BuildTools'
	};

	programFilesDir = process.env['programfiles(x86)'] || process.env.PROGRAMFILES;

	// For the msbuild 15.0 version, use the appropriate VS2017 directories
	if (version === "15.0") {

		// If VSINSTALLDIR env. var cannot be found, see what could be the directory by searching the usual suspects
		// (while giving higher priority to the VS2017 IDE installs over the Build Tools only install)
		if (process.env.vsInstallDir === undefined) {
			var possibleVSInstallDir = programFilesDir + '\\' + 'Microsoft Visual Studio\\2017\\';
			if (fs.existsSync(possibleVSInstallDir + vs2017Type.Pro))
				msbuildDir = possibleVSInstallDir + vs2017Type.Pro + '\\';
			else if (fs.existsSync(possibleVSInstallDir + vs2017Type.Enterprise + '\\'))
				msbuildDir = possibleVSInstallDir + vs2017Type.Enterprise + '\\';
			else if (fs.existsSync(possibleVSInstallDir + vs2017Type.Community + '\\'))
				msbuildDir = possibleVSInstallDir + vs2017Type.Community + '\\';
			else if (fs.existsSync(possibleVSInstallDir + vs2017Type.BuildTools + '\\'))
				msbuildDir = possibleVSInstallDir + vs2017Type.BuildTools + '\\';
		}
		else
			msbuildDir = process.env.vsInstallDir;

		exeDir = msbuildDir + 'MSBuild\\15.0\\bin\\msbuild.exe';

	}

	// If the msbuild.exe file exists, we are done.
	if (exeDir != undefined && fs.existsSync(exeDir))
		return exeDir;

	// Otherwise, look for the older msbuild versions
	msbuildDir = programFilesDir + '\\' + 'MSBuild';
	frameworkDirectories = getFrameworkDirectories(msbuildDir);

	if(this.toolsVersion[version] == undefined ){
		if (frameworkDirectories.length > 0)
			version = frameworkDirectories.pop();
	}

	exeDir = msbuildDir + '\\' + version + '\\' + 'bin';
	processor = mapProcessor(processor);

	if(processor === 'x64')
		exeDir = exeDir + '\\' + 'amd64';

	if (!fs.existsSync(exeDir))
		exeDir = process.env.WINDIR + '\\' + 'microsoft.net' + '\\' + this.processors[processor] + '\\' + 'v' + this.toolsVersion[version];

	return exeDir + '\\' + 'msbuild.exe';
}

msbuild.prototype.buildexe = function(){
	return this.getMSBuildPath(this.os,this.processor,this.version);
}

msbuild.prototype.config =  function(name, value) {

	if(name.toLowerCase() === 'targetframework') {
		this.logger('\n * CONFIG WARNING: \''.concat(name,'\'  has been deprecated\n   Please use overrideParams (example: overrideParams = [\'/tv:4.0\'] )\n'));
		return;
	}

	var map;

	if (_.isPlainObject(name)) { map = name; }
	else if (value !== undefined) { this[name] = value; return this;	}
	else if (name === undefined) { return this.values; }
	else { return this[name]; }

	for (var key in map) { this.values[name] = map[key]; }

	return this;
};

msbuild.prototype.setConfig = function(cg){
	this.os = 				cg.os 				|| this.os;
	this.processor =		cg.processor 		|| this.processor;
	this.version =			cg.version 			|| this.version;
	this.sourcePath = 		cg.sourcePath 		|| this.sourcePath;
	this.configuration = 	cg.configuration 	|| this.configuration;
	this.publishProfile =	cg.publishProfile 	|| this.publishProfile;
	this.overrideParams = 	cg.overrideParams	|| this.overrideParams;
	this.outputPath  =  	cg.outputPath		|| this.outputPath;
}

msbuild.prototype.abort = function (msg) {
	var self = this;
	self.emit('error','',msg);
	return;
}

msbuild.prototype.exec = function(exe,params,cb){
	var self = this;
	if(self.showHelp) { self.printHelp(); return; }

	function onClose(code) {
		var msg = '';
		if (code === 0) {
			msg = msg+('\n finished - (0) errors'.white.greenBG);
			self.emit('done',null,msg);
		 }
		else {
			msg = ('\n error code: ' + code).grey+('\n failed - errors'.white.redBG);
			msg += '\n'+exe;
			if(params !== undefined && typeof params === 'array'){
				params.forEach(function(p){msg += ' ' + p; });
			}
			self.emit('error',code,msg);
			return;
		}
		cb();
	}

    return spawn(exe, params, { stdio: 'inherit'}).on('close', onClose );
}

msbuild.prototype.getBuildParams = function(params){
	if(params.indexOf('configuration') === -1 && this.configuration)
		params.push('/p:configuration='+this.configuration);

	if(params.indexOf('publishprofile') === -1 && this.publishProfile)
		params.push('/p:publishprofile=' + this.publishProfile);

	return params;
}

msbuild.prototype.getPackageParams = function(params){
	if(params.indexOf('package') === -1)
		params.push('/t:package');

	if(params.indexOf('deployonbuild') === -1)
		params.push('/p:deployonbuild=false');

	if(params.indexOf('outputpath') === -1 && this.outputPath)
		params.push('/p:outputpath='+this.outputPath);

	return params;
}

msbuild.prototype.getPublishParams = function(params){
	if(params.indexOf('deployonbuild') === -1)
		params.push('/p:deployonbuild=true');

	if(params.indexOf('allowUntrustedCertificate') === -1)
		params.push('/p:allowUntrustedCertificate=true');

	return params;
}

msbuild.prototype.getOverrideParams = function(params){
	this.overrideParams.forEach(function (param) {
		if (!validateCmdParameter(param)) {
			this.logger('error: invalid parameter "'+param+'"');
			return;
		}
		params.push(param);
	});
	return params;
}

msbuild.prototype.emitStatusStart = function(action){
	var startingMsg = ('  '+action+' starting').cyan;
	this.emit('status',null,startingMsg);
}

msbuild.prototype.validateSourcePath = function () {
    return fs.existsSync(this.sourcePath);
}

msbuild.prototype.build = function(){
	this.emitStatusStart('build');

	var params = [];
	var self = this;
	params.push(this.sourcePath);
	this.getBuildParams(params);
	this.getOverrideParams(params);

	if(!this.validateSourcePath()){
	    this.abort('aborting...bad source path');
		return;
	}

	this.exec(this.buildexe(),params,function(){
		self.logger('build done');
	});
}

msbuild.prototype.package = function(){
	this.emitStatusStart('package');

	var params = [];
	var self = this;
	params.push(this.sourcePath);
	this.getBuildParams(params);
	this.getOverrideParams(params);
	this.getPackageParams(params);

	if(!this.validateSourcePath()){
		this.abort('aborting...bad source path');
		return;
	}

	this.exec(this.buildexe(),params,function(){self.logger('package done');});
}

msbuild.prototype.publish = function(){
	this.emitStatusStart('publish');

	var params = [];
	var self = this;
	params.push(this.sourcePath);
	this.getBuildParams(params);
	this.getOverrideParams(params);
	this.getPublishParams(params);

	if(!this.validateSourcePath()){
		this.abort('aborting...bad source path');
		return;
	}

	this.exec(this.buildexe(),params,function(){self.logger('publish done');});
}

msbuild.prototype.printHelp = function(){
	var o = this;
	var helpFunctionsToIgnore = ['exec','path','buildexe','on','once','emit','addListener','removeListener','removeAllListeners','listeners','setMaxListeners','printHelp'];
	this.logger("\nfunctions".cyan.bold);
	this.logger('*******************'.cyan);

	for(var p in o){
		if(typeof(o[p]) == 'function'){
			if(helpFunctionsToIgnore.indexOf(p) > -1) continue;
			if(p == 'printOptions') continue;
			if(p == '?') continue;
			this.logger(p.redBG);
		}
	}

	this.logger("\nevents".cyan.bold + ' [err,results]'.grey);
	this.logger('*******************'.cyan);
	this.logger('status'.redBG+' // msbuild.on(\'status\',myfunc)'.grey);
	this.logger('error'.redBG+' // msbuild.on(\'error\',myfunc)'.grey);
	this.logger('done'.redBG+' // msbuild.on(\'done\',myfunc)'.grey);
}

module.exports = function(callback){
	var msb = new msbuild(callback);
	msb.on('status',function(err,results){
			if(this.showHelp) return;
			if(err) this.logger(err.redBG);
			this.logger(results);
		});
	msb.on('error',
		function(err,results){
			this.logger('  error'.red);
			if(err) this.logger(err.redBG);
			this.logger(results.red);
		});
	msb.on('done',function(err,results){
			this.logger(results);
			this.logger(lineBreak);
			if(typeof callback == 'function') callback();
		});
	return msb;
};
<commit_msg>Find the correct msbuild.exe for VS2019 installs<commit_after>/*
 msbuild.js

 copyright (c) 2014 jonathan haker
 Licensed under the MIT license.
 https://github.com/jhaker/nodejs-msbuild

*/
if (!String.prototype.endsWith) {
  String.prototype.endsWith = function(searchString, position) {
      var subjectString = this.toString();
      if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
        position = subjectString.length;
      }
      position -= searchString.length;
      var lastIndex = subjectString.indexOf(searchString, position);
      return lastIndex !== -1 && lastIndex === position;
  };
}

var events = require('events'),
	async = require('async'),
	colors = require('colors'),
	fs = require('fs'),
	path = require('path'),
	spawn = require('child_process').spawn;

var default_os = require('os').platform();

if (default_os !== 'linux') default_os = "windows";

var args = [];

for (var arg in process.argv) {
     args.push(process.argv[arg]);
}

var help = args.splice(2,1);
var x = function(){};
var _ = new x();

_.isPlainObject = function (obj) {
  var ctor, key;
  if (typeof obj != 'object' || !obj || toString.call(obj) != '[object Object]') {
    return false;
  }
  ctor = typeof obj.constructor == 'function' && obj.constructor.prototype;
  if (!ctor || !hasOwnProperty.call(ctor, 'isPrototypeOf')) {
    return false;
  }
  for (key in obj) {}
  return key === void 0 || hasOwnProperty.call(obj, key);
};

var validateCmdParameter = function(param){
	if (param.length < 2)  return false;
	return true;
}

var validFrameworkDir = function(dir) {
	return dir.indexOf('1') === 0;
}

var getFrameworkDirectories = function(msbuildDir){
	if (fs.existsSync(msbuildDir)) {
		return fs.readdirSync(msbuildDir)
			.filter(validFrameworkDir);
	} else {
		return [];
	}
}

var mapProcessor = function(processor) {
	if(!isNaN(processor) && processor !== undefined){
		processor = 'x'+processor;
	}
	if(processor !== 'x64'){
		processor = 'x86';
	}
	return processor;
}

var defaultPath = process.cwd();

var lineBreak = '\n- - - - - - - - - - - - - - - -';

var msbuild = function(){
	events.EventEmitter.call(this);
	this.showHelp = help == '?';
	this.processors = { 'x86': 'Framework', 'x64': 'Framework64' };
	this.os 				= default_os;  	// windows, linux
	this.processor 			= 'x64';  		// 'x86', 'x64'
	this.version			= 'current';		// tools version; determines local path to msbuild.exe
	this.sourcePath 		= defaultPath;  // 'c:/mypath/mysolution.sln'   or   'c:/mypath/myproject.csproj
	this.configuration 		= undefined;   	// solution configurations; targets an environment (debug,release)
	this.publishProfile 	= undefined;   	// publish profiles; targets a specific machine (app01,app02)
	this.outputPath 		= ''; 			// 'c:/deploys/release'
	this.verbose 			= false;
	/***
	property overrides (example: ['/clp:ErrorsOnly;', '/p:WarningLevel=2','/p:OutputDir=bin\Debug']  )
	target framework overrides (example:  ['/tv:4.0'] )
	***/
	this.overrideParams		= [];
};

msbuild.prototype.toolsVersion = {
		'2.0': '2.0.50727',
		'3.0':'3.0',
		'3.5': '3.5',
		'4.0': '4.0.30319',
		'4.5': '4.0.30319',
		'12.0': '12.0',
    '14.0': '14.0',
		'15.0': '(not used)',
		'16.0': '(not used)'
	};

msbuild.prototype.__proto__ = events.EventEmitter.prototype;

msbuild.prototype.logger = function(msg){
	console.log(msg);
}

msbuild.prototype.getMSBuildPath = function(os,processor,version){
	if(os === 'linux' || os === 'darwin') return "xbuild";

	var frameworkDirectories,programFilesDir,msbuildDir,exeDir;
	var vsIdeType = {
		Pro: 'Professional',
		Enterprise: 'Enterprise',
		Community: 'Community',
		BuildTools: 'BuildTools'
	};

	programFilesDir = process.env['programfiles(x86)'] || process.env.PROGRAMFILES;

	// For the msbuild 15.0 pr 16.0 version, use the appropriate VS2017 pr VS2019 directories
	if (version === "15.0" || version === "16.0") {

		// MSBuild 16.0 is installed in the "\current" folder under each version of Visual Studio or BuildTools folder.
		// See https://docs.microsoft.com/en-us/visualstudio/msbuild/whats-new-msbuild-16-0?view=vs-2019
		var vsIdeVersion = "2019";
		var msBuildSubDir = "current";

		// MSBuild 15.0 is installed in the "\15.0" folder under each version of Visual Studio or BuildTools folder.
		// See https://docs.microsoft.com/en-us/visualstudio/msbuild/what-s-new-in-msbuild-15-0?view=vs-2017
		if (version === "15.0") {
			vsIdeVersion = "2017";
			msBuildSubDir = version;
		}

		// If VSINSTALLDIR env. var cannot be found, see what could be the directory by searching the usual suspects
		// (while giving higher priority to the VS2017/2019 IDE installs over the Build Tools only install)
		if (process.env.vsInstallDir === undefined) {
			var possibleVSInstallDir = programFilesDir + '\\' + 'Microsoft Visual Studio\\' + vsIdeVersion + '\\';
			if (fs.existsSync(possibleVSInstallDir + vsIdeType.Pro))
				msbuildDir = possibleVSInstallDir + vsIdeType.Pro + '\\';
			else if (fs.existsSync(possibleVSInstallDir + vsIdeType.Enterprise + '\\'))
				msbuildDir = possibleVSInstallDir + vsIdeType.Enterprise + '\\';
			else if (fs.existsSync(possibleVSInstallDir + vsIdeType.Community + '\\'))
				msbuildDir = possibleVSInstallDir + vsIdeType.Community + '\\';
			else if (fs.existsSync(possibleVSInstallDir + vsIdeType.BuildTools + '\\'))
				msbuildDir = possibleVSInstallDir + vsIdeType.BuildTools + '\\';
		}
		else {
			msbuildDir = process.env.vsInstallDir;
		}

		exeDir = msbuildDir + 'MSBuild\\' + msBuildSubDir + '\\bin\\msbuild.exe';
		// console.log('found msbuild.exe dir = ' + exeDir);
	}

	// If the msbuild.exe file exists, we are done.
	if (exeDir != undefined && fs.existsSync(exeDir)) {
		// console.log('using msbuild 15.0+ exeDir = ' + exeDir)
		return exeDir;
	}

	// Otherwise, look for the older msbuild versions
	msbuildDir = programFilesDir + '\\' + 'MSBuild';
	frameworkDirectories = getFrameworkDirectories(msbuildDir);

	if(this.toolsVersion[version] == undefined ){
		if (frameworkDirectories.length > 0)
			version = frameworkDirectories.pop();
	}

	exeDir = msbuildDir + '\\' + version + '\\' + 'bin';
	processor = mapProcessor(processor);

	if(processor === 'x64')
		exeDir = exeDir + '\\' + 'amd64';

	if (!fs.existsSync(exeDir))
		exeDir = process.env.WINDIR + '\\' + 'microsoft.net' + '\\' + this.processors[processor] + '\\' + 'v' + this.toolsVersion[version];

	return exeDir + '\\' + 'msbuild.exe';
}

msbuild.prototype.buildexe = function(){
	return this.getMSBuildPath(this.os,this.processor,this.version);
}

msbuild.prototype.config =  function(name, value) {

	if(name.toLowerCase() === 'targetframework') {
		this.logger('\n * CONFIG WARNING: \''.concat(name,'\'  has been deprecated\n   Please use overrideParams (example: overrideParams = [\'/tv:4.0\'] )\n'));
		return;
	}

	var map;

	if (_.isPlainObject(name)) { map = name; }
	else if (value !== undefined) { this[name] = value; return this;	}
	else if (name === undefined) { return this.values; }
	else { return this[name]; }

	for (var key in map) { this.values[name] = map[key]; }

	return this;
};

msbuild.prototype.setConfig = function(cg){
	this.os = 				cg.os 				|| this.os;
	this.processor =		cg.processor 		|| this.processor;
	this.version =			cg.version 			|| this.version;
	this.sourcePath = 		cg.sourcePath 		|| this.sourcePath;
	this.configuration = 	cg.configuration 	|| this.configuration;
	this.publishProfile =	cg.publishProfile 	|| this.publishProfile;
	this.overrideParams = 	cg.overrideParams	|| this.overrideParams;
	this.outputPath  =  	cg.outputPath		|| this.outputPath;
}

msbuild.prototype.abort = function (msg) {
	var self = this;
	self.emit('error','',msg);
	return;
}

msbuild.prototype.exec = function(exe,params,cb){
	var self = this;
	if(self.showHelp) { self.printHelp(); return; }

	function onClose(code) {
		var msg = '';
		if (code === 0) {
			msg = msg+('\n finished - (0) errors'.white.greenBG);
			self.emit('done',null,msg);
		 }
		else {
			msg = ('\n error code: ' + code).grey+('\n failed - errors'.white.redBG);
			msg += '\n'+exe;
			if(params !== undefined && typeof params === 'array'){
				params.forEach(function(p){msg += ' ' + p; });
			}
			self.emit('error',code,msg);
			return;
		}
		cb();
	}

    return spawn(exe, params, { stdio: 'inherit'}).on('close', onClose );
}

msbuild.prototype.getBuildParams = function(params){
	if(params.indexOf('configuration') === -1 && this.configuration)
		params.push('/p:configuration='+this.configuration);

	if(params.indexOf('publishprofile') === -1 && this.publishProfile)
		params.push('/p:publishprofile=' + this.publishProfile);

	return params;
}

msbuild.prototype.getPackageParams = function(params){
	if(params.indexOf('package') === -1)
		params.push('/t:package');

	if(params.indexOf('deployonbuild') === -1)
		params.push('/p:deployonbuild=false');

	if(params.indexOf('outputpath') === -1 && this.outputPath)
		params.push('/p:outputpath='+this.outputPath);

	return params;
}

msbuild.prototype.getPublishParams = function(params){
	if(params.indexOf('deployonbuild') === -1)
		params.push('/p:deployonbuild=true');

	if(params.indexOf('allowUntrustedCertificate') === -1)
		params.push('/p:allowUntrustedCertificate=true');

	return params;
}

msbuild.prototype.getOverrideParams = function(params){
	this.overrideParams.forEach(function (param) {
		if (!validateCmdParameter(param)) {
			this.logger('error: invalid parameter "'+param+'"');
			return;
		}
		params.push(param);
	});
	return params;
}

msbuild.prototype.emitStatusStart = function(action){
	var startingMsg = ('  '+action+' starting').cyan;
	this.emit('status',null,startingMsg);
}

msbuild.prototype.validateSourcePath = function () {
    return fs.existsSync(this.sourcePath);
}

msbuild.prototype.build = function(){
	this.emitStatusStart('build');

	var params = [];
	var self = this;
	params.push(this.sourcePath);
	this.getBuildParams(params);
	this.getOverrideParams(params);

	if(!this.validateSourcePath()){
	    this.abort('aborting...bad source path');
		return;
	}

	this.exec(this.buildexe(),params,function(){
		self.logger('build done');
	});
}

msbuild.prototype.package = function(){
	this.emitStatusStart('package');

	var params = [];
	var self = this;
	params.push(this.sourcePath);
	this.getBuildParams(params);
	this.getOverrideParams(params);
	this.getPackageParams(params);

	if(!this.validateSourcePath()){
		this.abort('aborting...bad source path');
		return;
	}

	this.exec(this.buildexe(),params,function(){self.logger('package done');});
}

msbuild.prototype.publish = function(){
	this.emitStatusStart('publish');

	var params = [];
	var self = this;
	params.push(this.sourcePath);
	this.getBuildParams(params);
	this.getOverrideParams(params);
	this.getPublishParams(params);

	if(!this.validateSourcePath()){
		this.abort('aborting...bad source path');
		return;
	}

	this.exec(this.buildexe(),params,function(){self.logger('publish done');});
}

msbuild.prototype.printHelp = function(){
	var o = this;
	var helpFunctionsToIgnore = ['exec','path','buildexe','on','once','emit','addListener','removeListener','removeAllListeners','listeners','setMaxListeners','printHelp'];
	this.logger("\nfunctions".cyan.bold);
	this.logger('*******************'.cyan);

	for(var p in o){
		if(typeof(o[p]) == 'function'){
			if(helpFunctionsToIgnore.indexOf(p) > -1) continue;
			if(p == 'printOptions') continue;
			if(p == '?') continue;
			this.logger(p.redBG);
		}
	}

	this.logger("\nevents".cyan.bold + ' [err,results]'.grey);
	this.logger('*******************'.cyan);
	this.logger('status'.redBG+' // msbuild.on(\'status\',myfunc)'.grey);
	this.logger('error'.redBG+' // msbuild.on(\'error\',myfunc)'.grey);
	this.logger('done'.redBG+' // msbuild.on(\'done\',myfunc)'.grey);
}

module.exports = function(callback){
	var msb = new msbuild(callback);
	msb.on('status',function(err,results){
			if(this.showHelp) return;
			if(err) this.logger(err.redBG);
			this.logger(results);
		});
	msb.on('error',
		function(err,results){
			this.logger('  error'.red);
			if(err) this.logger(err.redBG);
			this.logger(results.red);
		});
	msb.on('done',function(err,results){
			this.logger(results);
			this.logger(lineBreak);
			if(typeof callback == 'function') callback();
		});
	return msb;
};
<|endoftext|>


<commit_before>var path = require('path');
var EventEmitter = require('events').EventEmitter;

exports.createApp = createApp;
function createApp(config, options, callback) {
    if (typeof callback === "undefined") {
        callback = options;
        options = {};
    }
    config = processConfig(config, options);
    // console.log("compiled config:");
    // console.log(JSON.stringify(config));
    startContainers(config, callback);
}

// Gather and preflight the config.
exports.processConfig = processConfig;
function processConfig(configPath, options) {
    options = options || {};
    var config = {};

    // Allow passing in either config path or config object
    if (typeof configPath === "object") {
        config = configPath;
        configPath = "<provided config object>";
        if (!config.basePath) {
            var err = new Error("'basePath' required in config object");
            return callback(err);
        }
    } else {
        configPath = require.resolve(configPath);
        config = require(configPath);
    }

    // Overwrite console object from config if set in createApp options
    if (typeof options.console !== "undefined") {
        config.console = options.console;
    } else {
        config.console = console;
    }

    // Default basePath to the dirname of the config file
    var basePath = config.basePath = config.basePath || path.dirname(configPath);

    // Resolve plugin paths to the basePath and merge in plugin configs from
    // package.json files.
    Object.keys(config.containers).forEach(function (containerName) {
        var containerConfig = config.containers[containerName];
        var pluginsConfigs = containerConfig.plugins;
        pluginsConfigs && pluginsConfigs.forEach(function (pluginConfig, index) {

            // if plugin is a string it is interpreted as the package path
            if (typeof pluginConfig === "string") {
                pluginsConfigs[index] = pluginConfig = {
                    packagePath: pluginConfig
                };
            }

            // packagePath is required on all plugins
            if (!pluginConfig.hasOwnProperty("packagePath")) {
                var err = new Error("'packagePath' required in `" +
                    configPath + "` at " + containerName + "[" + index + "]");
                return callback(err);
            }

            var pluginConfigBase;

            // the architect app can inject plugins into the master
            if (pluginConfig.plugin) {
                if (containerName !== "master")
                    return new Error("Plugins can only be injected into the master container");

                var pluginConfigBase = pluginConfig.plugin;
            }
            else {
                // Replace with fully resolved path
                var packagePath = resolvePackage(basePath, pluginConfig.packagePath);
                pluginConfig.packagePath = packagePath;

                // Look up the provides and consumes in the package.json and merge.
                try {
                    pluginConfigBase = require(packagePath).plugin;
                } catch(err) {
                    throw new Error("Error '" + err + "' loading config from " + packagePath);
                }
            }

            if (!pluginConfigBase) {
                throw new Error("Missing 'plugin' section in " + packagePath);
            }

            for (var key in pluginConfigBase) {
                if (!pluginConfig.hasOwnProperty(key)) {
                    pluginConfig[key] = pluginConfigBase[key];
                }
            }

            // provide defaults
            pluginConfig.provides = pluginConfig.provides || [];
            pluginConfig.consumes = pluginConfig.consumes || [];
        });
    });

    // Set a tmpdir for anything that might need it.
    config.tmpdir = config.tmpdir || path.join(process.cwd(), ".architect");

    // Tell which containers need to listen for inbound connections. Also set
    // name and tmpdir for all containers.
    Object.keys(config.containers).forEach(function (containerName) {
        var containerConfig = config.containers[containerName];
        if (needsServe(config.containers, containerName)) {
            containerConfig.needsServe = true;
        }
        containerConfig.name = containerName;
        containerConfig.tmpdir = config.tmpdir;
    });

    // Make sure there are no dependency cycles that would prevent the app
    // from starting.
    checkCycles(config);

    return config;

    // pre flight dependency check
    function checkCycles(config) {
        var plugins = [];
        var containers = config.containers;
        Object.keys(containers).forEach(function(containerName) {
            var pluginConfigs = containers[containerName].plugins || [];
            pluginConfigs.forEach(function(pluginConfig) {
                plugins.push({
                    packagePath: pluginConfig.packagePath,
                    provides: pluginConfig.provides.concat(),
                    consumes: pluginConfig.consumes.concat()
                });
            });
        });

        var resolved = {
            hub: true
        };
        var changed = true;

        while(plugins.length && changed) {
            changed = false;

            plugins.concat().forEach(function(plugin) {
                var consumes = plugin.consumes.concat();

                var resolvedAll = true;
                for (var i=0; i<consumes.length; i++) {
                    var service = consumes[i];
                    if (!resolved[service]) {
                        resolvedAll = false;
                    } else {
                        plugin.consumes.splice(plugin.consumes.indexOf(service), 1);
                    }
                }

                if (!resolvedAll)
                    return;

                plugins.splice(plugins.indexOf(plugin), 1);
                plugin.provides.forEach(function(service) {
                    resolved[service] = true;
                });
                changed = true;
            });
        }

        if (plugins.length) {
            console.error("Could not resolve dependencies of these plugins:", plugins);
            console.error("Resovled services:", resolved);
            throw new Error("Could not resolve dependencies");
        }
    }

    function calcProvides(container) {
        var provides = {};
        var plugins = container.plugins;
        plugins && plugins.forEach(function (plugin) {
            plugin.provides.forEach(function (service) {
                provides[service] = true;
            });
        });
        return provides;
    }

    function calcDepends(container, provides) {
        if (!container.plugins) return false;
        var i = container.plugins.length;
        while (i--) {
            var consumes = container.plugins[i].consumes;
            var j = consumes.length;
            while (j--) {
                if (provides[consumes[j]]) return true;
            }
        }
        return false;
    }

    function needsServe(containers, name) {
        var provides = calcProvides(containers[name]);
        // First calculate what all services this container provides.
        for (var key in containers) {
            if (!containers.hasOwnProperty(key)) continue;
            if (key === name) continue;
            if (calcDepends(containers[key], provides)) return true;
        }
        return false;
    }
}

exports.startContainers = startContainers;
function startContainers(config, callback) {
    var hub = new EventEmitter();
    var Agent = require('architect-agent').Agent;

    var containers = {};

    // This agent is used for the star topology of events.  All child processes have access to it.
    var hubAgent = new Agent({
        broadcast: broadcast
    });

    // Create all the containers in parallel (as dumb workers).  Then once
    // they are all created, tell them all to initialize in parallel.  When
    // they are all ready, call the callback.
    var createLeft, readyLeft;
    createLeft = readyLeft = Object.keys(config.containers).length;
    // Create all the containers in parallel.
    Object.keys(config.containers).forEach(function (name) {
        var createContainer = (name === "master") ?
            require('./container').createContainer :
            spawnContainer;

        createContainer(name, broadcast, function (err, container) {
            if (err) throw err;
            containers[name] = container;
            broadcast("containerCreated", name);
            if (--createLeft) return;
            Object.keys(containers).forEach(function (name) {
                containers[name].initialize(config.containers[name]);
            });
        });

    });

    hub.on('containerReady', checkReady);

    function checkReady() {
        if (--readyLeft) return;
        broadcast("containersDone", Object.keys(containers));
        callback(null, containers);
    }

    // A function that all containers have access to that enables broadcasting.
    // The following kinds messages are broadcasts to all containers:
    //  - serviceReady { container, socket, name, functions }
    //  - servicesDone {} - all services are initialized
    //  - serviceDied {serviceName}
    //  - containerReady { container }
    //  - containerDied {containerName}
    //  - containersDone {} - all containers are initialized
    function broadcast(name, message) {
        if (config.console && config.console.info) {
            //console.info("BROADCAST: " + name, message);
        }
        hub.emit(name, message);
        process.nextTick(function () {
            Object.keys(containers).forEach(function (key) {
                if (typeof containers[key].onBroadcast !== "function") {
                    console.log("containers[%s]", key, containers[key]);
                }
                containers[key].onBroadcast(name, message);
            });
        });
    }

    // Create a new container in a child process
    function spawnContainer(name, broadcast, callback) {
        var spawn = require('child_process').spawn;
        var Agent = require('architect-agent').Agent;
        var socketTransport = require('architect-socket-transport');

        var child = spawn(process.execPath, [require.resolve('./worker-process.js')], {
            customFds: [-1, 1, 2],
            stdinStream: createPipe(true),
            env: { ARCHITECT_CONTAINER_NAME: name }
        });

        var transport = socketTransport(child.stdin);
        hubAgent.attach(transport, function (container) {
            callback(null, container);
        });
        child.stdin.resume();

        // TODO: Monitor child for life
    }

}

// Taken from node's child process code.
var Pipe;
function createPipe(ipc) {
  // Lazy load
  if (!Pipe) {
    Pipe = process.binding('pipe_wrap').Pipe;
  }
  return new Pipe(ipc);
}

// Node style package resolving so that plugins' package.json can be found relative to the config file
// It's not the full node require system algorithm, but it's the 99% case
function resolvePackage(base, packagePath) {
    if (packagePath[0] === "." || packagePath[0] === "/") {
        var newPath = path.resolve(base, packagePath, "package.json");
        if (path.existsSync(newPath)) return newPath;
    }
    else {
        while (base) {
            var newPath = path.resolve(base, "node_modules", packagePath, "package.json");
            if (path.existsSync(newPath)) return newPath;
            base = base.substr(0, base.lastIndexOf("/"));
        }
    }
    throw new Error("Can't find '" + packagePath + "' relative to '" + base + '"');
}

<commit_msg>throw directly (callback is optional)<commit_after>var path = require('path');
var EventEmitter = require('events').EventEmitter;

exports.createApp = createApp;
function createApp(config, options, callback) {
    if (typeof callback === "undefined") {
        callback = options;
        options = {};
    }
    config = processConfig(config, options);
    // console.log("compiled config:");
    // console.log(JSON.stringify(config));
    startContainers(config, callback);
}

// Gather and preflight the config.
exports.processConfig = processConfig;
function processConfig(configPath, options) {
    options = options || {};
    var config = {};

    // Allow passing in either config path or config object
    if (typeof configPath === "object") {
        config = configPath;
        configPath = "<provided config object>";
        if (!config.basePath) {
            throw new Error("'basePath' required in config object");
        }
    } else {
        configPath = require.resolve(configPath);
        config = require(configPath);
    }

    // Overwrite console object from config if set in createApp options
    if (typeof options.console !== "undefined") {
        config.console = options.console;
    } else {
        config.console = console;
    }

    // Default basePath to the dirname of the config file
    var basePath = config.basePath = config.basePath || path.dirname(configPath);

    // Resolve plugin paths to the basePath and merge in plugin configs from
    // package.json files.
    Object.keys(config.containers).forEach(function (containerName) {
        var containerConfig = config.containers[containerName];
        var pluginsConfigs = containerConfig.plugins;
        pluginsConfigs && pluginsConfigs.forEach(function (pluginConfig, index) {

            // if plugin is a string it is interpreted as the package path
            if (typeof pluginConfig === "string") {
                pluginsConfigs[index] = pluginConfig = {
                    packagePath: pluginConfig
                };
            }

            // packagePath is required on all plugins
            if (!pluginConfig.hasOwnProperty("packagePath")) {
                var err = new Error("'packagePath' required in `" +
                    configPath + "` at " + containerName + "[" + index + "]");
                return callback(err);
            }

            var pluginConfigBase;

            // the architect app can inject plugins into the master
            if (pluginConfig.plugin) {
                if (containerName !== "master")
                    return new Error("Plugins can only be injected into the master container");

                var pluginConfigBase = pluginConfig.plugin;
            }
            else {
                // Replace with fully resolved path
                var packagePath = resolvePackage(basePath, pluginConfig.packagePath);
                pluginConfig.packagePath = packagePath;

                // Look up the provides and consumes in the package.json and merge.
                try {
                    pluginConfigBase = require(packagePath).plugin;
                } catch(err) {
                    throw new Error("Error '" + err + "' loading config from " + packagePath);
                }
            }

            if (!pluginConfigBase) {
                throw new Error("Missing 'plugin' section in " + packagePath);
            }

            for (var key in pluginConfigBase) {
                if (!pluginConfig.hasOwnProperty(key)) {
                    pluginConfig[key] = pluginConfigBase[key];
                }
            }

            // provide defaults
            pluginConfig.provides = pluginConfig.provides || [];
            pluginConfig.consumes = pluginConfig.consumes || [];
        });
    });

    // Set a tmpdir for anything that might need it.
    config.tmpdir = config.tmpdir || path.join(process.cwd(), ".architect");

    // Tell which containers need to listen for inbound connections. Also set
    // name and tmpdir for all containers.
    Object.keys(config.containers).forEach(function (containerName) {
        var containerConfig = config.containers[containerName];
        if (needsServe(config.containers, containerName)) {
            containerConfig.needsServe = true;
        }
        containerConfig.name = containerName;
        containerConfig.tmpdir = config.tmpdir;
    });

    // Make sure there are no dependency cycles that would prevent the app
    // from starting.
    checkCycles(config);

    return config;

    // pre flight dependency check
    function checkCycles(config) {
        var plugins = [];
        var containers = config.containers;
        Object.keys(containers).forEach(function(containerName) {
            var pluginConfigs = containers[containerName].plugins || [];
            pluginConfigs.forEach(function(pluginConfig) {
                plugins.push({
                    packagePath: pluginConfig.packagePath,
                    provides: pluginConfig.provides.concat(),
                    consumes: pluginConfig.consumes.concat()
                });
            });
        });

        var resolved = {
            hub: true
        };
        var changed = true;

        while(plugins.length && changed) {
            changed = false;

            plugins.concat().forEach(function(plugin) {
                var consumes = plugin.consumes.concat();

                var resolvedAll = true;
                for (var i=0; i<consumes.length; i++) {
                    var service = consumes[i];
                    if (!resolved[service]) {
                        resolvedAll = false;
                    } else {
                        plugin.consumes.splice(plugin.consumes.indexOf(service), 1);
                    }
                }

                if (!resolvedAll)
                    return;

                plugins.splice(plugins.indexOf(plugin), 1);
                plugin.provides.forEach(function(service) {
                    resolved[service] = true;
                });
                changed = true;
            });
        }

        if (plugins.length) {
            console.error("Could not resolve dependencies of these plugins:", plugins);
            console.error("Resovled services:", resolved);
            throw new Error("Could not resolve dependencies");
        }
    }

    function calcProvides(container) {
        var provides = {};
        var plugins = container.plugins;
        plugins && plugins.forEach(function (plugin) {
            plugin.provides.forEach(function (service) {
                provides[service] = true;
            });
        });
        return provides;
    }

    function calcDepends(container, provides) {
        if (!container.plugins) return false;
        var i = container.plugins.length;
        while (i--) {
            var consumes = container.plugins[i].consumes;
            var j = consumes.length;
            while (j--) {
                if (provides[consumes[j]]) return true;
            }
        }
        return false;
    }

    function needsServe(containers, name) {
        var provides = calcProvides(containers[name]);
        // First calculate what all services this container provides.
        for (var key in containers) {
            if (!containers.hasOwnProperty(key)) continue;
            if (key === name) continue;
            if (calcDepends(containers[key], provides)) return true;
        }
        return false;
    }
}

exports.startContainers = startContainers;
function startContainers(config, callback) {
    var hub = new EventEmitter();
    var Agent = require('architect-agent').Agent;

    var containers = {};

    // This agent is used for the star topology of events.  All child processes have access to it.
    var hubAgent = new Agent({
        broadcast: broadcast
    });

    // Create all the containers in parallel (as dumb workers).  Then once
    // they are all created, tell them all to initialize in parallel.  When
    // they are all ready, call the callback.
    var createLeft, readyLeft;
    createLeft = readyLeft = Object.keys(config.containers).length;
    // Create all the containers in parallel.
    Object.keys(config.containers).forEach(function (name) {
        var createContainer = (name === "master") ?
            require('./container').createContainer :
            spawnContainer;

        createContainer(name, broadcast, function (err, container) {
            if (err) throw err;
            containers[name] = container;
            broadcast("containerCreated", name);
            if (--createLeft) return;
            Object.keys(containers).forEach(function (name) {
                containers[name].initialize(config.containers[name]);
            });
        });

    });

    hub.on('containerReady', checkReady);

    function checkReady() {
        if (--readyLeft) return;
        broadcast("containersDone", Object.keys(containers));
        callback(null, containers);
    }

    // A function that all containers have access to that enables broadcasting.
    // The following kinds messages are broadcasts to all containers:
    //  - serviceReady { container, socket, name, functions }
    //  - servicesDone {} - all services are initialized
    //  - serviceDied {serviceName}
    //  - containerReady { container }
    //  - containerDied {containerName}
    //  - containersDone {} - all containers are initialized
    function broadcast(name, message) {
        if (config.console && config.console.info) {
            //console.info("BROADCAST: " + name, message);
        }
        hub.emit(name, message);
        process.nextTick(function () {
            Object.keys(containers).forEach(function (key) {
                if (typeof containers[key].onBroadcast !== "function") {
                    console.log("containers[%s]", key, containers[key]);
                }
                containers[key].onBroadcast(name, message);
            });
        });
    }

    // Create a new container in a child process
    function spawnContainer(name, broadcast, callback) {
        var spawn = require('child_process').spawn;
        var Agent = require('architect-agent').Agent;
        var socketTransport = require('architect-socket-transport');

        var child = spawn(process.execPath, [require.resolve('./worker-process.js')], {
            customFds: [-1, 1, 2],
            stdinStream: createPipe(true),
            env: { ARCHITECT_CONTAINER_NAME: name }
        });

        var transport = socketTransport(child.stdin);
        hubAgent.attach(transport, function (container) {
            callback(null, container);
        });
        child.stdin.resume();

        // TODO: Monitor child for life
    }

}

// Taken from node's child process code.
var Pipe;
function createPipe(ipc) {
  // Lazy load
  if (!Pipe) {
    Pipe = process.binding('pipe_wrap').Pipe;
  }
  return new Pipe(ipc);
}

// Node style package resolving so that plugins' package.json can be found relative to the config file
// It's not the full node require system algorithm, but it's the 99% case
function resolvePackage(base, packagePath) {
    if (packagePath[0] === "." || packagePath[0] === "/") {
        var newPath = path.resolve(base, packagePath, "package.json");
        if (path.existsSync(newPath)) return newPath;
    }
    else {
        while (base) {
            var newPath = path.resolve(base, "node_modules", packagePath, "package.json");
            if (path.existsSync(newPath)) return newPath;
            base = base.substr(0, base.lastIndexOf("/"));
        }
    }
    throw new Error("Can't find '" + packagePath + "' relative to '" + base + '"');
}

<|endoftext|>


<commit_before>import {Pos} from "../model"
import {defineOption} from "../edit"
import {Rule, addInputRules, removeInputRules} from "./inputrules"

defineOption("autoInput", false, function(pm, val, old) {
  if (val && !old) addInputRules(pm, rules)
  else if (!val && old) removeInputRules(pm, rules)
})

export var rules = [
  new Rule("-", /--$/, "—"),
  new Rule('"', /\s(")$/, "“"),
  new Rule('"', /"$/, "”"),
  new Rule("'", /\s(')$/, "‘"),
  new Rule("'", /'$/, "’"),

  new Rule(" ", /^\s*> $/, function(pm, _, pos) {
    wrapAndJoin(pm, pos, "blockquote")
  }),
  new Rule(" ", /^(\d+)\. $/, function(pm, match, pos) {
    let order = +match[1]
    wrapAndJoin(pm, pos, "ordered_list", {order: order || null, tight: true},
                node => node.content.length + (node.attrs.order || 1) == order)
  }),
  new Rule(" ", /^\s*([-+*]) $/, function(pm, match, pos) {
    let bullet = match[1]
    wrapAndJoin(pm, pos, "bullet_list", {bullet: bullet, tight: true},
                node => node.attrs.bullet == bullet)
  }),
  new Rule("`", /^```$/, function(pm, _, pos) {
    setAs(pm, pos, "code_block", {params: ""})
  }),
  new Rule(" ", /^(#{1,6}) $/, function(pm, match, pos) {
    setAs(pm, pos, "heading", {level: match[1].length})
  })
]

function wrapAndJoin(pm, pos, type, attrs = null, predicate = null) {
  let parentOffset = pos.path[pos.path.length - 1]
  let sibling = parentOffset > 0 && pm.doc.path(pos.shorten()).content[parentOffset - 1]
  let join = sibling.type.name == type && (!predicate || predicate(sibling))
  let tr = pm.tr.wrap(pos, pos, new Node(type, attrs))
  let delPos = tr.map(pos).pos
  tr.delete(new Pos(delPos.path, 0), delPos)
  if (join) tr.join(tr.map(pos, -1).pos)
  pm.apply(tr)
}

function setAs(pm, pos, type, attrs) {
  pm.apply(pm.tr.setBlockType(pos, pos, new Node(type, attrs))
                .delete(new Pos(pos.path, 0), pos))
}
<commit_msg>Repair autoinput wrapAndJoin<commit_after>import {Pos, Node} from "../model"
import {defineOption} from "../edit"
import {Rule, addInputRules, removeInputRules} from "./inputrules"

defineOption("autoInput", false, function(pm, val, old) {
  if (val && !old) addInputRules(pm, rules)
  else if (!val && old) removeInputRules(pm, rules)
})

export var rules = [
  new Rule("-", /--$/, "—"),
  new Rule('"', /\s(")$/, "“"),
  new Rule('"', /"$/, "”"),
  new Rule("'", /\s(')$/, "‘"),
  new Rule("'", /'$/, "’"),

  new Rule(" ", /^\s*> $/, function(pm, _, pos) {
    wrapAndJoin(pm, pos, "blockquote")
  }),
  new Rule(" ", /^(\d+)\. $/, function(pm, match, pos) {
    let order = +match[1]
    wrapAndJoin(pm, pos, "ordered_list", {order: order || null, tight: true},
                node => node.content.length + (node.attrs.order || 1) == order)
  }),
  new Rule(" ", /^\s*([-+*]) $/, function(pm, match, pos) {
    let bullet = match[1]
    wrapAndJoin(pm, pos, "bullet_list", {bullet: bullet, tight: true},
                node => node.attrs.bullet == bullet)
  }),
  new Rule("`", /^```$/, function(pm, _, pos) {
    setAs(pm, pos, "code_block", {params: ""})
  }),
  new Rule(" ", /^(#{1,6}) $/, function(pm, match, pos) {
    setAs(pm, pos, "heading", {level: match[1].length})
  })
]

function wrapAndJoin(pm, pos, type, attrs = null, predicate = null) {
  let parentOffset = pos.path[pos.path.length - 1]
  let sibling = parentOffset > 0 && pm.doc.path(pos.shorten()).content[parentOffset - 1]
  let join = sibling && sibling.type.name == type && (!predicate || predicate(sibling))
  let tr = pm.tr.wrap(pos, pos, new Node(type, null, attrs))
  let delPos = tr.map(pos)
  tr.delete(new Pos(delPos.path, 0), delPos)
  if (join) tr.join(tr.map(pos, -1))
  pm.apply(tr)
}

function setAs(pm, pos, type, attrs) {
  pm.apply(pm.tr.setBlockType(pos, pos, new Node(type, null, attrs))
                .delete(new Pos(pos.path, 0), pos))
}
<|endoftext|>


<commit_before>// Based on:
// https://github.com/babel/babel/blob/8b096ac7057379fd698eea3a33a2f77a8311a363/src/babel/transformation/helpers/build-react-transformer.js

var esutils = require('esutils');
var isIdentifierNameES6 = esutils.keyword.isIdentifierNameES6;

// this.scope.hasBinding("name")` checks for local bindings
// this.scope.hasOwnBinding("name")` only checks the current scope
// this.scope.hasGlobal("name")`

module.exports = function(babel) {
  var t = babel.types;

  return new babel.Transformer('jsx-ir', {
    // @done
    JSXIdentifier: function (node) {
      if (node.name === 'this' && this.isReferenced()) {
        return t.thisExpression();
      } else if (isIdentifierNameES6(node.name)) {
        node.type = 'Identifier';
      } else {
        return t.literal(node.name);
      }
    },
    // @done
    JSXNamespacedName: function(node) {
      node = t.identifier(node.namespace.name + ':' + node.name.name);
      node.namespaced = true;

      return node;
    },
    // @done
    JSXMemberExpression: {
      exit: function(node) {
        // node.computed = t.isLiteral(node.property);
        // node.type = "MemberExpression";
        return t.identifier(node.object.name + '.' + node.property.name);
      }
    },
    // @done
    JSXEmptyExpression: function (node) {
      node.type = 'Literal';
      node.value = null;
    },
    // @done
    JSXExpressionContainer: function(node) {
      return node.expression;
    },
    // @done
    JSXAttribute: {
      enter: function(node) {
        var value = node.value;

        if (t.isLiteral(value) && typeof value.value === 'string') {
          value.value = value.value.replace(/\n\s+/g, ' ');
        }
      },

      exit: function(node) {
        var name = node.name;
        var value = node.value || t.literal(true);

        return t.inherits(t.property('init', name, value), node);
      }
    },
    // @done
    JSXOpeningElement: {
      exit: function(node, parent, scope, file) {
        var props = node.attributes;

        if (props.length) {
          // props = handleProps(props, scope, file, t);
          props = handleSpreadProps(props, scope, file, t);
        } else {
          props = t.literal(null);
        }

        var item = t.objectExpression([
          t.property('init', t.identifier('tag'), t.literal(node.name.name)),
          t.property('init', t.identifier('props'), props)
        ]);

        return item;
      }
    },
    // @done
    JSXElement: {
      exit: function(node) {
        var item = node.openingElement;
        var children = buildChildren(node.children, t);

        children = children.length ? t.arrayExpression(children) : t.literal(null);
        item.properties.push(
          t.property('init', t.identifier('children'), children)
        );

        return t.inherits(item, node);
      }
    },

    Expression: function(node, parent) {
      if (this.isCompletionRecord()) {
        // console.log(parent);
      }
    },
    Program: function(node) {
      // console.log(node);
    }
  });
};

function cleanChildren(child) {
  var lines = child.value.split(/\r\n|\n|\r/);
  var lastNonEmptyLine = 0;

  for (var i = 0; i < lines.length; i++) {
    if (lines[i].match(/[^ \t]/)) {
      lastNonEmptyLine = i;
    }
  }

  var str = '';

  for (var i = 0; i < lines.length; i++) {
    var line = lines[i];

    var isFirstLine = i === 0;
    var isLastLine = i === lines.length - 1;
    var isLastNonEmptyLine = i === lastNonEmptyLine;

    // replace rendered whitespace tabs with spaces
    var trimmedLine = line.replace(/\t/g, ' ');

    // trim whitespace touching a newline
    if (!isFirstLine) {
      trimmedLine = trimmedLine.replace(/^[ ]+/, '');
    }

    // trim whitespace touching an endline
    if (!isLastLine) {
      trimmedLine = trimmedLine.replace(/[ ]+$/, '');
    }

    if (trimmedLine) {
      if (!isLastNonEmptyLine) {
        trimmedLine += ' ';
      }

      str += trimmedLine;
    }
  }

  return str;
}

function buildChildren(children, t) {
  var elems = [];

  for (var i = 0; i < children.length; i++) {
    var child = children[i];

    if (t.isLiteral(child) && typeof child.value === 'string') {
      var str = cleanChildren(child, t);
      if (str) elems.push(t.literal(str));

      continue;
    }

    elems.push(child);
  }

  return elems;
}

function handleProps(props, scope, file, t) {
  // scope.push({ id: t.identifier("id"), init: t.identifier("init") });
  props = props.map(function(prop) {
    var propName = prop.key.name || prop.key.value;

    if (isIdentifierNameES6(propName)) {
      propName = t.identifier(propName);
    } else {
      propName = t.literal(propName);
    }

    return t.property('init', propName, prop.value);
  });

  return t.objectExpression(props);
}

function handleSpreadProps(props, scope, file, t) {
  var propsStack = [];
  var objectsStack = [];

  var pushProps = function () {
    if (!propsStack.length) return;

    objectsStack.push(t.objectExpression(propsStack));
    propsStack = [];
  };

  var makeProp = function(prop) {
    var propName = prop.key.name || prop.key.value;

    if (isIdentifierNameES6(propName)) {
      propName = t.identifier(propName);
    } else {
      propName = t.literal(propName);
    }

    return t.property('init', propName, prop.value);
  };

  for (var i = 0, len = props.length; i < len; i++) {
    var prop = props[i];

    if (t.isJSXSpreadAttribute(prop)) {
      pushProps();
      objectsStack.push(prop.argument);
    } else {
      propsStack.push(makeProp(prop));
    }
  }

  pushProps();

  if (objectsStack.length === 1) {
    // only one object
    props = objectsStack[0];
  } else {
    // looks like we have multiple objects
    if (!t.isObjectExpression(objectsStack[0])) {
      objectsStack.unshift(t.objectExpression([]));
    }

    // spread it
    props = t.callExpression(
      file.addHelper('extends'),
      objectsStack
    );

    /*var propsKey = scope.generateUidIdentifier('props');

    scope.push({
      id: propsKey,
      init: props
    });

    props = t.identifier(propsKey.name);*/
  }

  return props;
};<commit_msg>Do not use invalid indentifier names<commit_after>// Based on:
// https://github.com/babel/babel/blob/8b096ac7057379fd698eea3a33a2f77a8311a363/src/babel/transformation/helpers/build-react-transformer.js

var esutils = require('esutils');
var isIdentifierNameES6 = esutils.keyword.isIdentifierNameES6;

// this.scope.hasBinding("name")` checks for local bindings
// this.scope.hasOwnBinding("name")` only checks the current scope
// this.scope.hasGlobal("name")`

module.exports = function(babel) {
  var t = babel.types;

  return new babel.Transformer('jsx-ir', {
    // @done
    JSXIdentifier: function (node) {
      if (node.name === 'this' && this.isReferenced()) {
        return t.thisExpression();
      } else if (isIdentifierNameES6(node.name)) {
        node.type = 'Identifier';
      } else {
        return t.literal(node.name);
      }
    },
    // @done
    JSXNamespacedName: function(node) {
      return t.literal(node.namespace.name + ':' + node.name.name);
    },
    // @done
    JSXMemberExpression: {
      exit: function(node) {
        node.computed = t.isLiteral(node.property);
        node.type = 'MemberExpression';
      }
    },
    // @done
    JSXEmptyExpression: function (node) {
      node.type = 'Literal';
      node.value = null;
    },
    // @done
    JSXExpressionContainer: function(node) {
      return node.expression;
    },
    // @done
    JSXAttribute: {
      enter: function(node) {
        var value = node.value;

        if (t.isLiteral(value) && typeof value.value === 'string') {
          value.value = value.value.replace(/\n\s+/g, ' ');
        }
      },

      exit: function(node) {
        var name = node.name;
        var value = node.value || t.literal(true);

        return t.inherits(t.property('init', name, value), node);
      }
    },
    // @done
    JSXOpeningElement: {
      exit: function(node, parent, scope, file) {
        var props = node.attributes;

        if (props.length) {
          // props = handleProps(props, scope, file, t);
          props = handleSpreadProps(props, scope, file, t);
        } else {
          props = t.literal(null);
        }

        var tag;

        if (t.isMemberExpression(node.name)) {
          node = node.name;
          tag = [];

          do {
            tag.push(node.property.name);
          } while (t.isMemberExpression(node = node.object));

          tag.push(node.name);
          tag = t.literal(tag.join('.'));
        } else {
          tag = t.literal(node.name.name || node.name.value);
        }

        var item = t.objectExpression([
          t.property('init', t.identifier('tag'), tag),
          t.property('init', t.identifier('props'), props)
        ]);

        return item;
      }
    },
    // @done
    JSXElement: {
      exit: function(node) {
        var item = node.openingElement;
        var children = buildChildren(node.children, t);

        children = children.length ? t.arrayExpression(children) : t.literal(null);
        item.properties.push(
          t.property('init', t.identifier('children'), children)
        );

        return t.inherits(item, node);
      }
    },

    Expression: function(node, parent) {
      if (this.isCompletionRecord()) {
        // console.log(parent);
      }
    },
    Program: function(node) {
      // console.log(node);
    }
  });
};

function cleanChildren(child) {
  var lines = child.value.split(/\r\n|\n|\r/);
  var lastNonEmptyLine = 0;

  for (var i = 0; i < lines.length; i++) {
    if (lines[i].match(/[^ \t]/)) {
      lastNonEmptyLine = i;
    }
  }

  var str = '';

  for (var i = 0; i < lines.length; i++) {
    var line = lines[i];

    var isFirstLine = i === 0;
    var isLastLine = i === lines.length - 1;
    var isLastNonEmptyLine = i === lastNonEmptyLine;

    // replace rendered whitespace tabs with spaces
    var trimmedLine = line.replace(/\t/g, ' ');

    // trim whitespace touching a newline
    if (!isFirstLine) {
      trimmedLine = trimmedLine.replace(/^[ ]+/, '');
    }

    // trim whitespace touching an endline
    if (!isLastLine) {
      trimmedLine = trimmedLine.replace(/[ ]+$/, '');
    }

    if (trimmedLine) {
      if (!isLastNonEmptyLine) {
        trimmedLine += ' ';
      }

      str += trimmedLine;
    }
  }

  return str;
}

function buildChildren(children, t) {
  var elems = [];

  for (var i = 0; i < children.length; i++) {
    var child = children[i];

    if (t.isLiteral(child) && typeof child.value === 'string') {
      var str = cleanChildren(child, t);
      if (str) elems.push(t.literal(str));

      continue;
    }

    elems.push(child);
  }

  return elems;
}

function handleProps(props, scope, file, t) {
  // scope.push({ id: t.identifier("id"), init: t.identifier("init") });
  props = props.map(function(prop) {
    var propName = prop.key.name || prop.key.value;

    if (isIdentifierNameES6(propName)) {
      propName = t.identifier(propName);
    } else {
      propName = t.literal(propName);
    }

    return t.property('init', propName, prop.value);
  });

  return t.objectExpression(props);
}

function handleSpreadProps(props, scope, file, t) {
  var propsStack = [];
  var objectsStack = [];

  var pushProps = function () {
    if (!propsStack.length) return;

    objectsStack.push(t.objectExpression(propsStack));
    propsStack = [];
  };

  var makeProp = function(prop) {
    var propName = prop.key.name || prop.key.value;

    if (isIdentifierNameES6(propName)) {
      propName = t.identifier(propName);
    } else {
      propName = t.literal(propName);
    }

    return t.property('init', propName, prop.value);
  };

  for (var i = 0, len = props.length; i < len; i++) {
    var prop = props[i];

    if (t.isJSXSpreadAttribute(prop)) {
      pushProps();
      objectsStack.push(prop.argument);
    } else {
      propsStack.push(makeProp(prop));
    }
  }

  pushProps();

  if (objectsStack.length === 1) {
    // only one object
    props = objectsStack[0];
  } else {
    // looks like we have multiple objects
    if (!t.isObjectExpression(objectsStack[0])) {
      objectsStack.unshift(t.objectExpression([]));
    }

    // spread it
    props = t.callExpression(
      file.addHelper('extends'),
      objectsStack
    );

    /*var propsKey = scope.generateUidIdentifier('props');

    scope.push({
      id: propsKey,
      init: props
    });

    props = t.identifier(propsKey.name);*/
  }

  return props;
};<|endoftext|>