<commit_before>/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */

import { options } from 'preact';

// Internal helpers from preact
import { ATTR_KEY } from '../src/constants';

/**
 * Return a ReactElement-compatible object for the current state of a preact
 * component.
 */
function createReactElement(component) {
	return {
		type: component.constructor,
		key: component.key,
		ref: null, // Unsupported
		props: component.props
	};
}

/**
 * Create a ReactDOMComponent-compatible object for a given DOM node rendered
 * by preact.
 *
 * This implements the subset of the ReactDOMComponent interface that
 * React DevTools requires in order to display DOM nodes in the inspector with
 * the correct type and properties.
 *
 * @param {Node} node
 */
function createReactDOMComponent(node) {
	const childNodes = node.nodeType === Node.ELEMENT_NODE ?
		Array.from(node.childNodes) : [];

	const isText = node.nodeType === Node.TEXT_NODE;

	return {
		// --- ReactDOMComponent interface
		_currentElement: isText ? node.textContent : {
			type: node.nodeName.toLowerCase(),
			props: node[ATTR_KEY]
		},
		_renderedChildren: childNodes.map(child => {
			if (child._component) {
				return updateReactComponent(child._component);
			}
			return updateReactComponent(child);
		}),
		_stringText: isText ? node.textContent : null,

		// --- Additional properties used by preact devtools

		// A flag indicating whether the devtools have been notified about the
		// existence of this component instance yet.
		// This is used to send the appropriate notifications when DOM components
		// are added or updated between composite component updates.
		_inDevTools: false,
		node
	};
}

/**
 * Return the name of a component created by a `ReactElement`-like object.
 *
 * @param {ReactElement} element
 */
function typeName(element) {
	if (typeof element.type === 'function') {
		return element.type.displayName || element.type.name;
	}
	return element.type;
}

/**
 * Return a ReactCompositeComponent-compatible object for a given preact
 * component instance.
 *
 * This implements the subset of the ReactCompositeComponent interface that
 * the DevTools requires in order to walk the component tree and inspect the
 * component's properties.
 *
 * See https://github.com/facebook/react-devtools/blob/e31ec5825342eda570acfc9bcb43a44258fceb28/backend/getData.js
 */
function createReactCompositeComponent(component) {
	const _currentElement = createReactElement(component);
	const node = component.base;

	let instance = {
		// --- ReactDOMComponent properties
		getName() {
			return typeName(_currentElement);
		},
		_currentElement: createReactElement(component),
		props: component.props,
		state: component.state,
		forceUpdate: component.forceUpdate && component.forceUpdate.bind(component),
		setState: component.setState && component.setState.bind(component),

		// --- Additional properties used by preact devtools
		node
	};

	// React DevTools exposes the `_instance` field of the selected item in the
	// component tree as `$r` in the console.  `_instance` must refer to a
	// React Component (or compatible) class instance with `props` and `state`
	// fields and `setState()`, `forceUpdate()` methods.
	instance._instance = component;

	// If the root node returned by this component instance's render function
	// was itself a composite component, there will be a `_component` property
	// containing the child component instance.
	if (component._component) {
		instance._renderedComponent = updateReactComponent(component._component);
	} else {
		// Otherwise, if the render() function returned an HTML/SVG element,
		// create a ReactDOMComponent-like object for the DOM node itself.
		instance._renderedComponent = updateReactComponent(node);
	}

	return instance;
}

/**
 * Map of Component|Node to ReactDOMComponent|ReactCompositeComponent-like
 * object.
 *
 * The same React*Component instance must be used when notifying devtools
 * about the initial mount of a component and subsequent updates.
 */
let instanceMap = typeof Map==='function' && new Map();

/**
 * Update (and create if necessary) the ReactDOMComponent|ReactCompositeComponent-like
 * instance for a given preact component instance or DOM Node.
 *
 * @param {Component|Node} componentOrNode
 */
function updateReactComponent(componentOrNode) {
	const newInstance = componentOrNode instanceof Node ?
		createReactDOMComponent(componentOrNode) :
		createReactCompositeComponent(componentOrNode);
	if (instanceMap.has(componentOrNode)) {
		let inst = instanceMap.get(componentOrNode);
		Object.assign(inst, newInstance);
		return inst;
	}
	instanceMap.set(componentOrNode, newInstance);
	return newInstance;
}

function nextRootKey(roots) {
	return '.' + Object.keys(roots).length;
}

/**
 * Find all root component instances rendered by preact in `node`'s children
 * and add them to the `roots` map.
 *
 * @param {DOMElement} node
 * @param {[key: string] => ReactDOMComponent|ReactCompositeComponent}
 */
function findRoots(node, roots) {
	Array.from(node.childNodes).forEach(child => {
		if (child._component) {
			roots[nextRootKey(roots)] = updateReactComponent(child._component);
		} else {
			findRoots(child, roots);
		}
	});
}

/**
 * Create a bridge for exposing preact's component tree to React DevTools.
 *
 * It creates implementations of the interfaces that ReactDOM passes to
 * devtools to enable it to query the component tree and hook into component
 * updates.
 *
 * See https://github.com/facebook/react/blob/59ff7749eda0cd858d5ee568315bcba1be75a1ca/src/renderers/dom/ReactDOM.js
 * for how ReactDOM exports its internals for use by the devtools and
 * the `attachRenderer()` function in
 * https://github.com/facebook/react-devtools/blob/e31ec5825342eda570acfc9bcb43a44258fceb28/backend/attachRenderer.js
 * for how the devtools consumes the resulting objects.
 */
function createDevToolsBridge() {
	// The devtools has different paths for interacting with the renderers from
	// React Native, legacy React DOM and current React DOM.
	//
	// Here we emulate the interface for the current React DOM (v15+) lib.

	// ReactDOMComponentTree-like object
	const ComponentTree = {
		getNodeFromInstance(instance) {
			return instance.node;
		},
		getClosestInstanceFromNode(node) {
			while (node && !node._component) {
				node = node.parentNode;
			}
			return node ? updateReactComponent(node._component) : null;
		}
	};

	// Map of root ID (the ID is unimportant) to component instance.
	let roots = {};
	findRoots(document.body, roots);

	// ReactMount-like object
	//
	// Used by devtools to discover the list of root component instances and get
	// notified when new root components are rendered.
	const Mount = {
		_instancesByReactRootID: roots,

		// Stub - React DevTools expects to find this method and replace it
		// with a wrapper in order to observe new root components being added
		_renderNewRootComponent(/* instance, ... */) { }
	};

	// ReactReconciler-like object
	const Reconciler = {
		// Stubs - React DevTools expects to find these methods and replace them
		// with wrappers in order to observe components being mounted, updated and
		// unmounted
		mountComponent(/* instance, ... */) { },
		performUpdateIfNecessary(/* instance, ... */) { },
		receiveComponent(/* instance, ... */) { },
		unmountComponent(/* instance, ... */) { }
	};

	/** Notify devtools that a new component instance has been mounted into the DOM. */
	const componentAdded = component => {
		const instance = updateReactComponent(component);
		if (isRootComponent(component)) {
			instance._rootID = nextRootKey(roots);
			roots[instance._rootID] = instance;
			Mount._renderNewRootComponent(instance);
		}
		visitNonCompositeChildren(instance, childInst => {
			childInst._inDevTools = true;
			Reconciler.mountComponent(childInst);
		});
		Reconciler.mountComponent(instance);
	};

	/** Notify devtools that a component has been updated with new props/state. */
	const componentUpdated = component => {
		const prevRenderedChildren = [];
		visitNonCompositeChildren(instanceMap.get(component), childInst => {
			prevRenderedChildren.push(childInst);
		});

		// Notify devtools about updates to this component and any non-composite
		// children
		const instance = updateReactComponent(component);
		Reconciler.receiveComponent(instance);
		visitNonCompositeChildren(instance, childInst => {
			if (!childInst._inDevTools) {
				// New DOM child component
				childInst._inDevTools = true;
				Reconciler.mountComponent(childInst);
			} else {
				// Updated DOM child component
				Reconciler.receiveComponent(childInst);
			}
		});

		// For any non-composite children that were removed by the latest render,
		// remove the corresponding ReactDOMComponent-like instances and notify
		// the devtools
		prevRenderedChildren.forEach(childInst => {
			if (!document.body.contains(childInst.node)) {
				instanceMap.delete(childInst.node);
				Reconciler.unmountComponent(childInst);
			}
		});
	};

	/** Notify devtools that a component has been unmounted from the DOM. */
	const componentRemoved = component => {
		const instance = updateReactComponent(component);
		visitNonCompositeChildren(childInst => {
			instanceMap.delete(childInst.node);
			Reconciler.unmountComponent(childInst);
		});
		Reconciler.unmountComponent(instance);
		instanceMap.delete(component);
		if (instance._rootID) {
			delete roots[instance._rootID];
		}
	};

	return {
		componentAdded,
		componentUpdated,
		componentRemoved,

		// Interfaces passed to devtools via __REACT_DEVTOOLS_GLOBAL_HOOK__.inject()
		ComponentTree,
		Mount,
		Reconciler
	};
}

/**
 * Return `true` if a preact component is a top level component rendered by
 * `render()` into a container Element.
 */
function isRootComponent(component) {
	// `_parentComponent` is actually `__u` after minification
	if (component._parentComponent || component.__u) {
		// Component with a composite parent
		return false;
	}
	if (component.base.parentElement && component.base.parentElement[ATTR_KEY]) {
		// Component with a parent DOM element rendered by Preact
		return false;
	}
	return true;
}

/**
 * Visit all child instances of a ReactCompositeComponent-like object that are
 * not composite components (ie. they represent DOM elements or text)
 *
 * @param {Component} component
 * @param {(Component) => void} visitor
 */
function visitNonCompositeChildren(component, visitor) {
	if (component._renderedComponent) {
		if (!component._renderedComponent._component) {
			visitor(component._renderedComponent);
			visitNonCompositeChildren(component._renderedComponent, visitor);
		}
	} else if (component._renderedChildren) {
		component._renderedChildren.forEach(child => {
			visitor(child);
			if (!child._component) visitNonCompositeChildren(child, visitor);
		});
	}
}

/**
 * Create a bridge between the preact component tree and React's dev tools
 * and register it.
 *
 * After this function is called, the React Dev Tools should be able to detect
 * "React" on the page and show the component tree.
 *
 * This function hooks into preact VNode creation in order to expose functional
 * components correctly, so it should be called before the root component(s)
 * are rendered.
 *
 * Returns a cleanup function which unregisters the hooks.
 */
export function initDevTools() {
	if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
		// React DevTools are not installed
		return;
	}

	// Notify devtools when preact components are mounted, updated or unmounted
	const bridge = createDevToolsBridge();

	const nextAfterMount = options.afterMount;
	options.afterMount = component => {
		bridge.componentAdded(component);
		if (nextAfterMount) nextAfterMount(component);
	};

	const nextAfterUpdate = options.afterUpdate;
	options.afterUpdate = component => {
		bridge.componentUpdated(component);
		if (nextAfterUpdate) nextAfterUpdate(component);
	};

	const nextBeforeUnmount = options.beforeUnmount;
	options.beforeUnmount = component => {
		bridge.componentRemoved(component);
		if (nextBeforeUnmount) nextBeforeUnmount(component);
	};

	// Notify devtools about this instance of "React"
	__REACT_DEVTOOLS_GLOBAL_HOOK__.inject(bridge);

	return () => {
		options.afterMount = nextAfterMount;
		options.afterUpdate = nextAfterUpdate;
		options.beforeUnmount = nextBeforeUnmount;
	};
}
<commit_msg>fix: preact-compat unstable_renderSubtreeIntoContainer throw error in preact/devtools<commit_after>/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */

import { options } from 'preact';

// Internal helpers from preact
import { ATTR_KEY } from '../src/constants';

/**
 * Return a ReactElement-compatible object for the current state of a preact
 * component.
 */
function createReactElement(component) {
	return {
		type: component.constructor,
		key: component.key,
		ref: null, // Unsupported
		props: component.props
	};
}

/**
 * Create a ReactDOMComponent-compatible object for a given DOM node rendered
 * by preact.
 *
 * This implements the subset of the ReactDOMComponent interface that
 * React DevTools requires in order to display DOM nodes in the inspector with
 * the correct type and properties.
 *
 * @param {Node} node
 */
function createReactDOMComponent(node) {
	const childNodes = node.nodeType === Node.ELEMENT_NODE ?
		Array.from(node.childNodes) : [];

	const isText = node.nodeType === Node.TEXT_NODE;

	return {
		// --- ReactDOMComponent interface
		_currentElement: isText ? node.textContent : {
			type: node.nodeName.toLowerCase(),
			props: node[ATTR_KEY]
		},
		_renderedChildren: childNodes.map(child => {
			if (child._component) {
				return updateReactComponent(child._component);
			}
			return updateReactComponent(child);
		}),
		_stringText: isText ? node.textContent : null,

		// --- Additional properties used by preact devtools

		// A flag indicating whether the devtools have been notified about the
		// existence of this component instance yet.
		// This is used to send the appropriate notifications when DOM components
		// are added or updated between composite component updates.
		_inDevTools: false,
		node
	};
}

/**
 * Return the name of a component created by a `ReactElement`-like object.
 *
 * @param {ReactElement} element
 */
function typeName(element) {
	if (typeof element.type === 'function') {
		return element.type.displayName || element.type.name;
	}
	return element.type;
}

/**
 * Return a ReactCompositeComponent-compatible object for a given preact
 * component instance.
 *
 * This implements the subset of the ReactCompositeComponent interface that
 * the DevTools requires in order to walk the component tree and inspect the
 * component's properties.
 *
 * See https://github.com/facebook/react-devtools/blob/e31ec5825342eda570acfc9bcb43a44258fceb28/backend/getData.js
 */
function createReactCompositeComponent(component) {
	const _currentElement = createReactElement(component);
	const node = component.base;

	let instance = {
		// --- ReactDOMComponent properties
		getName() {
			return typeName(_currentElement);
		},
		_currentElement: createReactElement(component),
		props: component.props,
		state: component.state,
		forceUpdate: component.forceUpdate && component.forceUpdate.bind(component),
		setState: component.setState && component.setState.bind(component),

		// --- Additional properties used by preact devtools
		node
	};

	// React DevTools exposes the `_instance` field of the selected item in the
	// component tree as `$r` in the console.  `_instance` must refer to a
	// React Component (or compatible) class instance with `props` and `state`
	// fields and `setState()`, `forceUpdate()` methods.
	instance._instance = component;

	// If the root node returned by this component instance's render function
	// was itself a composite component, there will be a `_component` property
	// containing the child component instance.
	if (component._component) {
		instance._renderedComponent = updateReactComponent(component._component);
	} else {
		// Otherwise, if the render() function returned an HTML/SVG element,
		// create a ReactDOMComponent-like object for the DOM node itself.
		instance._renderedComponent = updateReactComponent(node);
	}

	return instance;
}

/**
 * Map of Component|Node to ReactDOMComponent|ReactCompositeComponent-like
 * object.
 *
 * The same React*Component instance must be used when notifying devtools
 * about the initial mount of a component and subsequent updates.
 */
let instanceMap = typeof Map==='function' && new Map();

/**
 * Update (and create if necessary) the ReactDOMComponent|ReactCompositeComponent-like
 * instance for a given preact component instance or DOM Node.
 *
 * @param {Component|Node} componentOrNode
 */
function updateReactComponent(componentOrNode) {
	const newInstance = componentOrNode instanceof Node ?
		createReactDOMComponent(componentOrNode) :
		createReactCompositeComponent(componentOrNode);
	if (instanceMap.has(componentOrNode)) {
		let inst = instanceMap.get(componentOrNode);
		Object.assign(inst, newInstance);
		return inst;
	}
	instanceMap.set(componentOrNode, newInstance);
	return newInstance;
}

function nextRootKey(roots) {
	return '.' + Object.keys(roots).length;
}

/**
 * Find all root component instances rendered by preact in `node`'s children
 * and add them to the `roots` map.
 *
 * @param {DOMElement} node
 * @param {[key: string] => ReactDOMComponent|ReactCompositeComponent}
 */
function findRoots(node, roots) {
	Array.from(node.childNodes).forEach(child => {
		if (child._component) {
			roots[nextRootKey(roots)] = updateReactComponent(child._component);
		} else {
			findRoots(child, roots);
		}
	});
}

/**
 * Create a bridge for exposing preact's component tree to React DevTools.
 *
 * It creates implementations of the interfaces that ReactDOM passes to
 * devtools to enable it to query the component tree and hook into component
 * updates.
 *
 * See https://github.com/facebook/react/blob/59ff7749eda0cd858d5ee568315bcba1be75a1ca/src/renderers/dom/ReactDOM.js
 * for how ReactDOM exports its internals for use by the devtools and
 * the `attachRenderer()` function in
 * https://github.com/facebook/react-devtools/blob/e31ec5825342eda570acfc9bcb43a44258fceb28/backend/attachRenderer.js
 * for how the devtools consumes the resulting objects.
 */
function createDevToolsBridge() {
	// The devtools has different paths for interacting with the renderers from
	// React Native, legacy React DOM and current React DOM.
	//
	// Here we emulate the interface for the current React DOM (v15+) lib.

	// ReactDOMComponentTree-like object
	const ComponentTree = {
		getNodeFromInstance(instance) {
			return instance.node;
		},
		getClosestInstanceFromNode(node) {
			while (node && !node._component) {
				node = node.parentNode;
			}
			return node ? updateReactComponent(node._component) : null;
		}
	};

	// Map of root ID (the ID is unimportant) to component instance.
	let roots = {};
	findRoots(document.body, roots);

	// ReactMount-like object
	//
	// Used by devtools to discover the list of root component instances and get
	// notified when new root components are rendered.
	const Mount = {
		_instancesByReactRootID: roots,

		// Stub - React DevTools expects to find this method and replace it
		// with a wrapper in order to observe new root components being added
		_renderNewRootComponent(/* instance, ... */) { }
	};

	// ReactReconciler-like object
	const Reconciler = {
		// Stubs - React DevTools expects to find these methods and replace them
		// with wrappers in order to observe components being mounted, updated and
		// unmounted
		mountComponent(/* instance, ... */) { },
		performUpdateIfNecessary(/* instance, ... */) { },
		receiveComponent(/* instance, ... */) { },
		unmountComponent(/* instance, ... */) { }
	};

	/** Notify devtools that a new component instance has been mounted into the DOM. */
	const componentAdded = component => {
		const instance = updateReactComponent(component);
		if (isRootComponent(component)) {
			instance._rootID = nextRootKey(roots);
			roots[instance._rootID] = instance;
			Mount._renderNewRootComponent(instance);
		}
		visitNonCompositeChildren(instance, childInst => {
			childInst._inDevTools = true;
			Reconciler.mountComponent(childInst);
		});
		Reconciler.mountComponent(instance);
	};

	/** Notify devtools that a component has been updated with new props/state. */
	const componentUpdated = component => {
		// Must updateReactComponent first, incase unstable_renderSubtreeIntoContainer component not in instanceMap
		// Notify devtools about updates to this component and any non-composite
		// children
		const instance = updateReactComponent(component);

		const prevRenderedChildren = [];
		visitNonCompositeChildren(instanceMap.get(component), childInst => {
			prevRenderedChildren.push(childInst);
		});

		Reconciler.receiveComponent(instance);
		visitNonCompositeChildren(instance, childInst => {
			if (!childInst._inDevTools) {
				// New DOM child component
				childInst._inDevTools = true;
				Reconciler.mountComponent(childInst);
			} else {
				// Updated DOM child component
				Reconciler.receiveComponent(childInst);
			}
		});

		// For any non-composite children that were removed by the latest render,
		// remove the corresponding ReactDOMComponent-like instances and notify
		// the devtools
		prevRenderedChildren.forEach(childInst => {
			if (!document.body.contains(childInst.node)) {
				instanceMap.delete(childInst.node);
				Reconciler.unmountComponent(childInst);
			}
		});
	};

	/** Notify devtools that a component has been unmounted from the DOM. */
	const componentRemoved = component => {
		const instance = updateReactComponent(component);
		visitNonCompositeChildren(childInst => {
			instanceMap.delete(childInst.node);
			Reconciler.unmountComponent(childInst);
		});
		Reconciler.unmountComponent(instance);
		instanceMap.delete(component);
		if (instance._rootID) {
			delete roots[instance._rootID];
		}
	};

	return {
		componentAdded,
		componentUpdated,
		componentRemoved,

		// Interfaces passed to devtools via __REACT_DEVTOOLS_GLOBAL_HOOK__.inject()
		ComponentTree,
		Mount,
		Reconciler
	};
}

/**
 * Return `true` if a preact component is a top level component rendered by
 * `render()` into a container Element.
 */
function isRootComponent(component) {
	// `_parentComponent` is actually `__u` after minification
	if (component._parentComponent || component.__u) {
		// Component with a composite parent
		return false;
	}
	if (component.base.parentElement && component.base.parentElement[ATTR_KEY]) {
		// Component with a parent DOM element rendered by Preact
		return false;
	}
	return true;
}

/**
 * Visit all child instances of a ReactCompositeComponent-like object that are
 * not composite components (ie. they represent DOM elements or text)
 *
 * @param {Component} component
 * @param {(Component) => void} visitor
 */
function visitNonCompositeChildren(component, visitor) {
	if (component._renderedComponent) {
		if (!component._renderedComponent._component) {
			visitor(component._renderedComponent);
			visitNonCompositeChildren(component._renderedComponent, visitor);
		}
	} else if (component._renderedChildren) {
		component._renderedChildren.forEach(child => {
			visitor(child);
			if (!child._component) visitNonCompositeChildren(child, visitor);
		});
	}
}

/**
 * Create a bridge between the preact component tree and React's dev tools
 * and register it.
 *
 * After this function is called, the React Dev Tools should be able to detect
 * "React" on the page and show the component tree.
 *
 * This function hooks into preact VNode creation in order to expose functional
 * components correctly, so it should be called before the root component(s)
 * are rendered.
 *
 * Returns a cleanup function which unregisters the hooks.
 */
export function initDevTools() {
	if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
		// React DevTools are not installed
		return;
	}

	// Notify devtools when preact components are mounted, updated or unmounted
	const bridge = createDevToolsBridge();

	const nextAfterMount = options.afterMount;
	options.afterMount = component => {
		bridge.componentAdded(component);
		if (nextAfterMount) nextAfterMount(component);
	};

	const nextAfterUpdate = options.afterUpdate;
	options.afterUpdate = component => {
		bridge.componentUpdated(component);
		if (nextAfterUpdate) nextAfterUpdate(component);
	};

	const nextBeforeUnmount = options.beforeUnmount;
	options.beforeUnmount = component => {
		bridge.componentRemoved(component);
		if (nextBeforeUnmount) nextBeforeUnmount(component);
	};

	// Notify devtools about this instance of "React"
	__REACT_DEVTOOLS_GLOBAL_HOOK__.inject(bridge);

	return () => {
		options.afterMount = nextAfterMount;
		options.afterUpdate = nextAfterUpdate;
		options.beforeUnmount = nextBeforeUnmount;
	};
}
<|endoftext|>


<commit_before>// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.

$(document).on("ajax:success", "form", function(status, data, xhr){
  if (data.length > 1) {
    $('.message0').text("All your plants have been watered!");
    $('.message0').show().delay(1000).fadeOut();
  }
  else {
    $('.message' + data.plant_id).text("Plant Watered!");
    $('.message' + data.plant_id).show().delay(1000).fadeOut();
  }
});
<commit_msg>Add comments to water events script<commit_after>// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
// Handles the response from the server and creates confirmation message in DOM if success

$(document).on("ajax:success", "form", function(status, data, xhr){
  if (data.length > 1) {
    $('.message0').text("All your plants have been watered!");
    $('.message0').show().delay(1000).fadeOut();
  }
  else {
    $('.message' + data.plant_id).text("Plant Watered!");
    $('.message' + data.plant_id).show().delay(1000).fadeOut();
  }
});
<|endoftext|>


<commit_before>'use strict';

const
	Amqp = require('../service/amqp'),

	publishAction = ({ topic, message, channel }) => {
		return Amqp.apply(channel => {
			// Convert the message into a Buffer and enqueue against the topic
			return channel.sendToQueue(topic, Buffer.from(message));
		});
	};

class Publisher {
	static publish(topic, message) {
		// Opens a connection to the RabbitMQ server, and publish the message
		return Amqp.apply(channel => publishAction({ topic, message, channel }));
	}
}

module.exports = Publisher;
<commit_msg>hopefully didnt break everything<commit_after>'use strict';

const
	Amqp = require('../service/amqp'),

	publishAction = ({ topic, message, channel }) => {
		// Convert the message into a Buffer and enqueue against the topic
		return channel.sendToQueue(topic, Buffer.from(message));
	};

class Publisher {
	static publish(topic, message) {
		// Opens a connection to the RabbitMQ server, and publish the message
		return Amqp.apply(channel => publishAction({ topic, message, channel }));
	}
}

module.exports = Publisher;
<|endoftext|>


<commit_before>const Generator = require('yeoman-generator');
const Util = require('../../Utils/util');
const chalk = require('chalk');
const yosay = require('yosay');

/**
 * yo demoiselle <project-name>
 *
 * Demoiselle generator for new projects.
 */
module.exports = class AppGenerator extends Generator {
  constructor(args, opts) {
    super(args, opts);

    // Change the path to the Util/templates
    Util.changeRootPath(this);

    // Arguments - passados direto pela cli (ex.: yo demoiselle my-project myprefix)
    this.argument('project', {
      desc: 'Nome do projeto',
      type: String,
      required: false
    });

    this.argument('prefix', {
      desc: 'prefixo dos componentes',
      type: String,
      required: false
    });

    // Options - parecido com "argument", mas vão como "flags" (--option)
    this.option('skip-message');
    this.option('skip-install');
    this.option('skip-frontend');
    this.option('skip-backend');
  }

  /**
   * Your initialization methods (checking current project state, getting configs, etc)
   */
  initializing() {
    // this.log('[initializing] done.');
    if (!this.options['skip-message']) {
      this.log(yosay(
        'Bem vindo ao ' + chalk.red('generator-demoiselle') + '. Começe seu projeto!'
      ));
    }
  }

  /**
   * Where you prompt users for options (where you'd call this.prompt())
   * Examples: name of app? which frameworks? which template engine?
   */
  prompting() {
    let prompts = [];

    if (!this.options.project) {
      prompts.push({
        type: 'input',
        name: 'project',
        message: 'Dê um nome para o seu projeto:',
        default: 'Todo'
      });
    }

    if (!this.options.prefix) {
      prompts.push({
        type: 'input',
        name: 'project',
        message: 'Dê um prefixo para os seus componentes:',
        default: 'my'
      });
    }

    if (!this.options['skip-frontend'] && !this.options['skip-backend']) {
      prompts.push({
        type: 'checkbox',
        name: 'skips',
        message: 'Você quer gerar arquivos para:',
        choices: [{
          name: 'frontend',
          checked: true
        }, {
          name: 'backend',
          checked: true
        }]
      });
    }

    return this.prompt(prompts).then(function (answers) {
      this.answers = answers;
      this.name = this.options.project || answers.project;
      this.prefix = this.options.prefix || answers.prefix;

      this.options['skip-frontend'] = !(answers.skips.indexOf('frontend') > -1);
      this.options['skip-backend'] = !(answers.skips.indexOf('backend') > -1);
    }.bind(this));
  }

  /**
   * Where you write the generator specific files (routes, controllers, etc)
   */
  writing() {
    // Generate Project
    if (!this.options['skip-frontend']) {
      this._generateTodoProjectFrontend();
    } else {
      this.log('[writing] frontend ignored.');
    }

    if (!this.options['skip-backend']) {
      this._generateTodoProjectBackend();
    } else {
      this.log('[writing] backend ignored.');
    }
  }

  /**
   * Where conflicts are handled (used internally)
   */
  conflicts() {
    // this.log('[conflicts] done.');
  }

  /**
   * Where installation are run (npm, bower)
   */
  install() {
    let skipInstall = this.options['skip-install'];

    if (!skipInstall) {
      this.spawnCommand('npm', ['install'], { cwd: 'frontend' });
      this.spawnCommand('mvn', ['install'], { cwd: 'frontend' });
    } else {
      this.log('[install] ignored.');
    }
  }

  // ---------------
  // PRIVATE methods
  // ---------------

  _generateTodoProjectFrontend() {
    let template = {
      name: Util.createNames(this.name),
      prefix: Util.createNames(this.prefix)
    };

    let from = this.templatePath('todo/frontend/');
    let to = this.destinationPath('frontend/');
    this.fs.copyTpl(from, to, template);
  }

  _generateTodoProjectBackend() {
    let template = {
      name: Util.createNames(this.name)
    };

    let from = this.templatePath('todo/backend/');
    let to = this.destinationPath('backend/');
    this.fs.copyTpl(from, to, template);
  }
};

<commit_msg>add (app): pergunta se deseja pular a etapa de instalação<commit_after>const Generator = require('yeoman-generator');
const Util = require('../../Utils/util');
const chalk = require('chalk');
const yosay = require('yosay');

/**
 * yo demoiselle <project-name>
 *
 * Demoiselle generator for new projects.
 */
module.exports = class AppGenerator extends Generator {
  constructor(args, opts) {
    super(args, opts);

    // Change the path to the Util/templates
    Util.changeRootPath(this);

    // Arguments - passados direto pela cli (ex.: yo demoiselle my-project myprefix)
    this.argument('project', {
      desc: 'Nome do projeto',
      type: String,
      required: false
    });

    this.argument('prefix', {
      desc: 'prefixo dos componentes',
      type: String,
      required: false
    });

    // Options - parecido com "argument", mas vão como "flags" (--option)
    this.option('skip-message');
    this.option('skip-install');
    this.option('skip-frontend');
    this.option('skip-backend');
  }

  /**
   * Your initialization methods (checking current project state, getting configs, etc)
   */
  initializing() {
    // this.log('[initializing] done.');
    if (!this.options['skip-message']) {
      this.log(yosay(
        'Bem vindo ao ' + chalk.red('generator-demoiselle') + '. Começe seu projeto!'
      ));
    }
  }

  /**
   * Where you prompt users for options (where you'd call this.prompt())
   * Examples: name of app? which frameworks? which template engine?
   */
  prompting() {
    let prompts = [];

    if (!this.options.project) {
      prompts.push({
        type: 'input',
        name: 'project',
        message: 'Dê um nome para o seu projeto:',
        default: 'Todo'
      });
    }

    if (!this.options.prefix) {
      prompts.push({
        type: 'input',
        name: 'project',
        message: 'Dê um prefixo para os seus componentes:',
        default: 'my'
      });
    }

    if (!this.options['skip-frontend'] && !this.options['skip-backend']) {
      prompts.push({
        type: 'checkbox',
        name: 'skips',
        message: 'Você quer gerar arquivos para:',
        choices: [{
          name: 'frontend',
          checked: true
        }, {
          name: 'backend',
          checked: true
        }]
      });
    }

    if (!this.options['skip-install']) {
      prompts.push({
        type: 'confirm',
        name: 'skip-install',
        message: 'Deseja instalar as dependências (isso pode demorar alguns minutos)?',
        default: false
      });
    }

    return this.prompt(prompts).then(function (answers) {
      this.answers = answers;
      this.name = this.options.project || answers.project;
      this.prefix = this.options.prefix || answers.prefix;
      this.options['skip-frontend'] = !(answers.skips.indexOf('frontend') > -1);
      this.options['skip-backend'] = !(answers.skips.indexOf('backend') > -1);

      if (!this.options['skip-install']) {
        this.options['skip-install'] = answers['skip-install'];
      }
    }.bind(this));
  }

  /**
   * Where you write the generator specific files (routes, controllers, etc)
   */
  writing() {
    // Generate Project
    if (!this.options['skip-frontend']) {
      this._generateTodoProjectFrontend();
    } else {
      this.log('[writing] frontend ignored.');
    }

    if (!this.options['skip-backend']) {
      this._generateTodoProjectBackend();
    } else {
      this.log('[writing] backend ignored.');
    }
  }

  /**
   * Where conflicts are handled (used internally)
   */
  conflicts() {
    // this.log('[conflicts] done.');
  }

  /**
   * Where installation are run (npm, bower)
   */
  install() {
    let skipInstall = this.options['skip-install'];

    if (!skipInstall) {
      this.spawnCommand('npm', ['install'], { cwd: 'frontend' });
      this.spawnCommand('mvn', ['install'], { cwd: 'frontend' });
    } else {
      this.log('[install] ignored.');
    }
  }

  // ---------------
  // PRIVATE methods
  // ---------------

  _generateTodoProjectFrontend() {
    let template = {
      name: Util.createNames(this.name),
      prefix: Util.createNames(this.prefix)
    };

    let from = this.templatePath('todo/frontend/');
    let to = this.destinationPath('frontend/');
    this.fs.copyTpl(from, to, template);
  }

  _generateTodoProjectBackend() {
    let template = {
      name: Util.createNames(this.name)
    };

    let from = this.templatePath('todo/backend/');
    let to = this.destinationPath('backend/');
    this.fs.copyTpl(from, to, template);
  }
};

<|endoftext|>


<commit_before>'use strict';
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');

module.exports = class extends Generator {
  prompting() {
    // Have Yeoman greet the user.
    this.log(yosay(
      "Welcome to the Sid's " + chalk.red('Express-API-Stub') + " generator!"
    ));

    const prompts = [{
      type: 'input',
      name: 'name',
      message: 'Your project name',
      default: this.appname
    }];

    return this.prompt(prompts).then(props => {
      // To access props later use this.props.someAnswer;
      this.props = props;
    });
  }

  writing() {

  this.fs.copyTpl(
      this.templatePath('../dynamic_temps/_package.json'),
      this.destinationPath('package.json'),
      { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/_www'),
    this.destinationPath('bin/www'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/default.json'),
    this.destinationPath('config/default.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/development.json'),
    this.destinationPath('config/development.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/production.json'),
    this.destinationPath('config/production.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/staging.json'),
    this.destinationPath('config/staging.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/test.json'),
    this.destinationPath('config/test.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/db.js'),
    this.destinationPath('mongo_models/db.js'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/authentication.js'),
    this.destinationPath('helpers/authentication.js'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/index.js'),
    this.destinationPath('models/index.js'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/readme.md'),
    this.destinationPath('readme.md'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/app.js'),
    this.destinationPath('app.js'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/.gitignore'),
    this.destinationPath('.gitignore'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/router'),
    this.destinationPath('router/'+this.props.name),
    { name: this.props.name }
  );

  this.fs.copy(
      this.templatePath(),
      this.destinationPath()
    );
  }

  install() {
    this.installDependencies();
  }
};
<commit_msg>updated the code with amqp helper and routes<commit_after>'use strict';
const Generator = require('yeoman-generator');
const chalk = require('chalk');
const yosay = require('yosay');

module.exports = class extends Generator {
  prompting() {
    // Have Yeoman greet the user.
    this.log(yosay(
      "Welcome to the Sid's " + chalk.red('Express-API-Stub') + " generator!"
    ));

    const prompts = [{
      type: 'input',
      name: 'name',
      message: 'Your project name',
      default: this.appname
    }];

    return this.prompt(prompts).then(props => {
      // To access props later use this.props.someAnswer;
      this.props = props;
    });
  }

  writing() {

  this.fs.copyTpl(
      this.templatePath('../dynamic_temps/_package.json'),
      this.destinationPath('package.json'),
      { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/_www'),
    this.destinationPath('bin/www'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/default.json'),
    this.destinationPath('config/default.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/development.json'),
    this.destinationPath('config/development.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/production.json'),
    this.destinationPath('config/production.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/staging.json'),
    this.destinationPath('config/staging.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/test.json'),
    this.destinationPath('config/test.json'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/db.js'),
    this.destinationPath('mongo_models/db.js'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/authentication.js'),
    this.destinationPath('helpers/authentication.js'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/index.js'),
    this.destinationPath('models/index.js'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/readme.md'),
    this.destinationPath('readme.md'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/app.js'),
    this.destinationPath('app.js'),
    { name: this.props.name }
  );
  this.fs.copyTpl(
    this.templatePath('../dynamic_temps/.gitignore'),
    this.destinationPath('.gitignore'),
    { name: this.props.name }
  );

  this.fs.copy(
      this.templatePath(),
      this.destinationPath()
    );
  }

  install() {
    this.installDependencies();
  }
};
<|endoftext|>


<commit_before>'use strict';
var yeoman = require('yeoman-generator');
var yosay = require('yosay');
var _ = require('lodash');
var extend = _.merge;
var parseAuthor = require('parse-author');
var path = require('path');
var githubUsername = require('github-username');
var askName = require('inquirer-npm-name');
var chalk = require('chalk');
var message = require('../message');

module.exports = yeoman.Base.extend({
  constructor: function () {
    yeoman.Base.apply(this, arguments);

    this.option('travis', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.travis
    });

    this.option('boilerplate', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.boilerplate
    });

    this.option('gulp', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.gulp
    });

    this.option('license', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.license
    });

    this.option('name', {
      type: String,
      required: false,
      desc: message.name
    });

    this.option('githubAccount', {
      type: String,
      required: false,
      desc: message.githubAccount
    });

    this.option('projectRoot', {
      type: String,
      required: false,
      defaults: 'lib',
      desc: message.projectRoot
    });

    this.option('readme', {
      type: String,
      required: false,
      desc: message.readme
    });

    this.option('browser', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.browser
    });

    this.option('styles', {
      type: Boolean,
      required: false,
      defaults: false,
      desc: message.styles
    });

    this.option('scss', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.scss
    });

    this.option('bower', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.browser
    });

    this.option('testFramework', {
      type: String,
      required: false,
      defaults: 'jasmine',
      desc: message.testFramework
    });
  },

  initializing: function () {
    this.pkg = this.fs.readJSON(this.destinationPath('package.json'), {});

    // Pre set the default props from the information we have at this point
    this.props = {
      name: this.pkg.name,
      description: this.pkg.description,
      version: this.pkg.version,
      homepage: this.pkg.homepage
    };

    if (_.isObject(this.pkg.author)) {
      this.props.authorName = this.pkg.author.name;
      this.props.authorEmail = this.pkg.author.email;
      this.props.authorUrl = this.pkg.author.url;
    } else if (_.isString(this.pkg.author)) {
      var info = parseAuthor(this.pkg.author);
      this.props.authorName = info.name;
      this.props.authorEmail = info.email;
      this.props.authorUrl = info.url;
    }
  },

  prompting: {
    showWelcome: function() {
      this.log(yosay(message.welcome));
      this.log(chalk.magenta(message.generator));
    },

    askForModuleName: function () {
      if (this.pkg.name || this.options.name) {
        this.props.name = this.pkg.name || _.kebabCase(this.options.name);
        return;
      }

      var done = this.async();

      askName({
        name: 'name',
        message: message.name,
        default: path.basename(process.cwd()),
        filter: _.kebabCase,
        validate: function (str) {
          return str.length > 0;
        }
      }, this, function (name) {
        this.props.name = name;
        done();
      }.bind(this));
    },

    askFor: function () {
      var done = this.async();

      var prompts = [{
        name: 'description',
        message: message.description,
        when: !this.props.description
      }, {
        name: 'homepage',
        message: message.homepage,
        when: !this.props.homepage
      }, {
        name: 'authorName',
        message: message.authorName,
        when: !this.props.authorName,
        default: this.user.git.name(),
        store: true
      }, {
        name: 'authorEmail',
        message: message.authorEmail,
        when: !this.props.authorEmail,
        default: this.user.git.email(),
        store: true
      }, {
        name: 'authorUrl',
        message: message.authorUrl,
        when: !this.props.authorUrl,
        store: true
      }, {
        name: 'keywords',
        message: message.keywords,
        when: !this.pkg.keywords,
        filter: function (words) {
          return words.split(/\s*,\s*/g);
        }
      }];

      this.prompt(prompts, function (props) {
        this.props = extend(this.props, props);
        done();
      }.bind(this));
    },

    confirmBrowserSupport: function () {
      var done = this.async();

      var prompt = {
        type: 'confirm',
        name: 'browser',
        message: message.browser,
        default: true
      };

      this.prompt(prompt, function (prop) {
        this.props.browser = prop.browser;
        done();
      }.bind(this));
    },

    confirmBowerAdd: function () {
      var done = this.async();

      var prompt = {
        type: 'confirm',
        name: 'bower',
        message: message.bower,
        default: true,
        when: this.props.browser
      };

      this.prompt(prompt, function (prop) {
        this.props.bower = prop.bower;
        done();
      }.bind(this));
    },

    confirmStyleAdd : function () {
      var done = this.async();

      var prompt = {
        type: 'confirm',
        name: 'styles',
        message: message.styles,
        default: false,
        when: this.props.browser
      };

      this.prompt(prompt, function (prop) {
        this.props.styles = prop.styles;
        done();
      }.bind(this));
    },

    confirmScssAdd: function () {
      var done = this.async();
      var prompt = {
        type: 'confirm',
        name: 'scss',
        message: message.scss,
        when: this.props.browser && this.props.styles,
        default: true
      };

      this.prompt(prompt, function (prop) {
        this.props.scss = prop.scss;
        done();
      }.bind(this));
    },

    selectTestFramework: function () {
      var done = this.async();
      var prompt = {
        type: 'list',
        name: 'testFramework',
        message: message.testFramework,
        when: this.props.browser,
        choices: [
          {
            name: "Jasmine",
            value: "jasmine"
          },
          {
            name: "Mocha",
            value: "mocha"
          }
        ],
        default: 0
      };

      this.prompt(prompt, function (prop) {
        this.props.testFramework = prop.testFramework;
        done();
      }.bind(this));
    },

    askForGithubAccount: function () {
      if (this.options.githubAccount) {
        this.props.githubAccount = this.options.githubAccount;
      } else {
        var done = this.async();

        githubUsername(this.props.authorEmail, function (err, username) {
          if (err) {
            username = username || '';
          }
          this.prompt({
            name: 'githubAccount',
            message: message.githubAccount,
            default: username
          }, function (prompt) {
            this.props.githubAccount = prompt.githubAccount;
            done();
          }.bind(this));
        }.bind(this));
      }
    }
  },

  writing: function () {
    // Re-read the content at this point because a composed generator might modify it.
    var currentPkg = this.fs.readJSON(this.destinationPath('package.json'), {});

    var pkg = extend({
      name: _.kebabCase(this.props.name),
      version: '0.0.0',
      description: this.props.description,
      homepage: this.props.homepage,
      author: {
        name: this.props.authorName,
        email: this.props.authorEmail,
        url: this.props.authorUrl
      },
      files: [
        'lib'
      ],
      main: this.props.styles ? ['lib/index.js', 'lib/' + this.props.name + '.css']: 'lib/index.js',
      keywords: [],
      typings: 'lib/index.d.ts'
    }, currentPkg);

    // Combine the keywords
    if (this.props.keywords) {
      pkg.keywords = _.uniq(this.props.keywords.concat(pkg.keywords));
    }

    // Let's extend package.json so we're not overwriting user previous fields
    this.fs.writeJSON(this.destinationPath('package.json'), pkg);

    if (this.props.browser && this.options.bower && this.props.bower) {
      var bower = {
        name: pkg.name,
        version: '0.0.0',
        description: this.props.description,
        main: this.props.styles ? ['bower/' + this.props.name + '.js', 'bower/' + this.props.name + '.css'] : 'bower/' + this.props.name + '.js',
        dependencies: {},
        devDependencies: {},
        moduleType: [
          'global'
        ],
        keywords: pkg.keywords,
        authors: [ this.props.authorName ],
        license: '',
        ignore: [
          'gulp',
          'lib',
          'node_modules',
          'src',
          'docs',
          'test',
          'coverage',
          'typings',
          '.gulp-scss-cache',
          '.sass-cache',
          '.tmp',
          '.idea',
          '.editorconfig',
          '.gitignore',
          '.jshintrc',
          '.npmignore',
          '.npmrc',
          'gulpfile.js',
          'karma.conf.js',
          'karma-coverage.conf.js',
          'package.json',
          'tsconfig.json',
          'tslint.json',
          'npm-debug.log'
        ]
      };

      this.fs.writeJSON(this.destinationPath('bower.json'), bower);
    }
  },

  default: function () {
    if (this.options.travis) {
      this.composeWith('travis', {}, {
        local: require.resolve('generator-travis/generators/app')
      });
    }

    this.composeWith('typescript-npm-bower:editor-conf', {}, {
      local: require.resolve('../editor-conf')
    });

    this.composeWith('typescript-npm-bower:lint', {}, {
      local: require.resolve('../lint')
    });

    this.composeWith('typescript-npm-bower:npm-conf', {}, {
      local: require.resolve('../npm-conf')
    });

    if (this.props.browser && this.options.bower && this.props.bower) {
      this.composeWith('typescript-npm-bower:bower-conf', {}, {
        local: require.resolve('../bower-conf')
      });
    }

    this.composeWith('typescript-npm-bower:typescript-conf', {
        options: {
          name: _.kebabCase(this.props.name),
          browser: this.props.browser,
          testFramework: this.props.testFramework
        }
      }, {
        local: require.resolve('../typescript-conf')
    });

    if (this.props.browser) {
      this.composeWith('typescript-npm-bower:karma-conf', {
        options: {
          testFramework: this.props.testFramework
        }
      }, {
        local: require.resolve('../karma-conf')
      });
    }

    this.composeWith('typescript-npm-bower:git', {
      options: {
        name: this.props.name,
        githubAccount: this.props.githubAccount
      }
    }, {
      local: require.resolve('../git')
    });

    if (this.options.gulp) {
      this.composeWith('typescript-npm-bower:gulp', {
        options: {
          name: _.kebabCase(this.props.name),
          browser: this.props.browser,
          styles: this.props.styles,
          scss: this.props.scss,
          bower: this.props.bower,
          testFramework: this.props.testFramework
        }
      },  {
        local: require.resolve('../gulp')
      });
    }

    if (this.options.boilerplate) {
      this.composeWith('typescript-npm-bower:boilerplate', {
        options: {
          browser: this.props.browser,
          styles: this.props.styles,
          scss: this.props.scss,
          bower: this.props.bower,
          testFramework: this.props.testFramework
        }
      }, {
        local: require.resolve('../boilerplate')
      });
    }

    if (this.options.license && !this.pkg.license) {
      this.composeWith('typescript-npm-bower:license', {
        options: {
          name: this.props.authorName,
          email: this.props.authorEmail,
          website: this.props.authorUrl
        }
      }, {
        local: require.resolve('generator-license/app')
      });
    }

    if (!this.fs.exists(this.destinationPath('README.md'))) {
      this.composeWith('typescript-npm-bower:readme', {
        options: {
          name: this.props.name,
          description: this.props.description,
          githubAccount: this.props.githubAccount,
          authorName: this.props.authorName,
          browser: this.props.browser,
          styles: this.props.styles,
          scss: this.props.scss,
          bower: this.props.bower,
          testFramework: this.props.testFramework
        }

      }, {
        local: require.resolve('../readme')
      });
    }
  },

  install: function () {
    this.npmInstall();
  }
});
<commit_msg>Update conditional prompt approach.<commit_after>'use strict';
var yeoman = require('yeoman-generator');
var yosay = require('yosay');
var _ = require('lodash');
var extend = _.merge;
var parseAuthor = require('parse-author');
var path = require('path');
var githubUsername = require('github-username');
var askName = require('inquirer-npm-name');
var chalk = require('chalk');
var message = require('../message');

module.exports = yeoman.Base.extend({
  constructor: function () {
    yeoman.Base.apply(this, arguments);

    this.option('travis', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.travis
    });

    this.option('boilerplate', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.boilerplate
    });

    this.option('gulp', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.gulp
    });

    this.option('license', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.license
    });

    this.option('name', {
      type: String,
      required: false,
      desc: message.name
    });

    this.option('githubAccount', {
      type: String,
      required: false,
      desc: message.githubAccount
    });

    this.option('projectRoot', {
      type: String,
      required: false,
      defaults: 'lib',
      desc: message.projectRoot
    });

    this.option('readme', {
      type: String,
      required: false,
      desc: message.readme
    });

    this.option('browser', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.browser
    });

    this.option('styles', {
      type: Boolean,
      required: false,
      defaults: false,
      desc: message.styles
    });

    this.option('scss', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.scss
    });

    this.option('bower', {
      type: Boolean,
      required: false,
      defaults: true,
      desc: message.browser
    });

    this.option('testFramework', {
      type: String,
      required: false,
      defaults: 'jasmine',
      desc: message.testFramework
    });
  },

  initializing: function () {
    this.pkg = this.fs.readJSON(this.destinationPath('package.json'), {});

    // Pre set the default props from the information we have at this point
    this.props = {
      name: this.pkg.name,
      description: this.pkg.description,
      version: this.pkg.version,
      homepage: this.pkg.homepage
    };

    if (_.isObject(this.pkg.author)) {
      this.props.authorName = this.pkg.author.name;
      this.props.authorEmail = this.pkg.author.email;
      this.props.authorUrl = this.pkg.author.url;
    } else if (_.isString(this.pkg.author)) {
      var info = parseAuthor(this.pkg.author);
      this.props.authorName = info.name;
      this.props.authorEmail = info.email;
      this.props.authorUrl = info.url;
    }
  },

  prompting: {
    showWelcome: function() {
      this.log(yosay(message.welcome));
      this.log(chalk.magenta(message.generator));
    },

    askForModuleName: function () {
      if (this.pkg.name || this.options.name) {
        this.props.name = this.pkg.name || _.kebabCase(this.options.name);
        return;
      }

      var done = this.async();

      askName({
        name: 'name',
        message: message.name,
        default: path.basename(process.cwd()),
        filter: _.kebabCase,
        validate: function (str) {
          return str.length > 0;
        }
      }, this, function (name) {
        this.props.name = name;
        done();
      }.bind(this));
    },

    askFor: function () {
      var done = this.async();

      var prompts = [{
        name: 'description',
        message: message.description,
        when: !this.props.description
      }, {
        name: 'homepage',
        message: message.homepage,
        when: !this.props.homepage
      }, {
        name: 'authorName',
        message: message.authorName,
        when: !this.props.authorName,
        default: this.user.git.name(),
        store: true
      }, {
        name: 'authorEmail',
        message: message.authorEmail,
        when: !this.props.authorEmail,
        default: this.user.git.email(),
        store: true
      }, {
        name: 'authorUrl',
        message: message.authorUrl,
        when: !this.props.authorUrl,
        store: true
      }, {
        name: 'keywords',
        message: message.keywords,
        when: !this.pkg.keywords,
        filter: function (words) {
          return words.split(/\s*,\s*/g);
        }
      }, {
        type: 'confirm',
        name: 'browser',
        message: message.browser,
        default: true
      }, {
        type: 'confirm',
        name: 'bower',
        message: message.bower,
        default: true,
        when: function (props) {
          return props.browser;
        }
      }, {
        type: 'confirm',
        name: 'styles',
        message: message.styles,
        default: false,
        when: function (props) {
          return props.browser;
        }
      }, {
        type: 'confirm',
        name: 'scss',
        message: message.scss,
        default: true,
        when: function (props) {
          return props.browser && props.styles;
        }
      }, {
        type: 'list',
        name: 'testFramework',
        message: message.testFramework,
        when: function (props) {
          return props.browser;
        },
        choices: [
          {
            name: "Jasmine",
            value: "jasmine"
          },
          {
            name: "Mocha",
            value: "mocha"
          }
        ],
        default: 0
      }];

      this.prompt(prompts, function (props) {
        this.props = extend(this.props, props);
        done();
      }.bind(this));
    },

    askForGithubAccount: function () {
      if (this.options.githubAccount) {
        this.props.githubAccount = this.options.githubAccount;
      } else {
        var done = this.async();

        githubUsername(this.props.authorEmail, function (err, username) {
          if (err) {
            username = username || '';
          }
          this.prompt({
            name: 'githubAccount',
            message: message.githubAccount,
            default: username
          }, function (prompt) {
            this.props.githubAccount = prompt.githubAccount;
            done();
          }.bind(this));
        }.bind(this));
      }
    }
  },

  writing: function () {
    // Re-read the content at this point because a composed generator might modify it.
    var currentPkg = this.fs.readJSON(this.destinationPath('package.json'), {});

    var pkg = extend({
      name: _.kebabCase(this.props.name),
      version: '0.0.0',
      description: this.props.description,
      homepage: this.props.homepage,
      author: {
        name: this.props.authorName,
        email: this.props.authorEmail,
        url: this.props.authorUrl
      },
      files: [
        'lib'
      ],
      main: this.props.styles ? ['lib/index.js', 'lib/' + this.props.name + '.css']: 'lib/index.js',
      keywords: [],
      typings: 'lib/index.d.ts'
    }, currentPkg);

    // Combine the keywords
    if (this.props.keywords) {
      pkg.keywords = _.uniq(this.props.keywords.concat(pkg.keywords));
    }

    // Let's extend package.json so we're not overwriting user previous fields
    this.fs.writeJSON(this.destinationPath('package.json'), pkg);

    if (this.props.browser && this.options.bower && this.props.bower) {
      var bower = {
        name: pkg.name,
        version: '0.0.0',
        description: this.props.description,
        main: this.props.styles ? ['bower/' + this.props.name + '.js', 'bower/' + this.props.name + '.css'] : 'bower/' + this.props.name + '.js',
        dependencies: {},
        devDependencies: {},
        moduleType: [
          'global'
        ],
        keywords: pkg.keywords,
        authors: [ this.props.authorName ],
        license: '',
        ignore: [
          'gulp',
          'lib',
          'node_modules',
          'src',
          'docs',
          'test',
          'coverage',
          'typings',
          '.gulp-scss-cache',
          '.sass-cache',
          '.tmp',
          '.idea',
          '.editorconfig',
          '.gitignore',
          '.jshintrc',
          '.npmignore',
          '.npmrc',
          'gulpfile.js',
          'karma.conf.js',
          'karma-coverage.conf.js',
          'package.json',
          'tsconfig.json',
          'tslint.json',
          'npm-debug.log'
        ]
      };

      this.fs.writeJSON(this.destinationPath('bower.json'), bower);
    }
  },

  default: function () {
    if (this.options.travis) {
      this.composeWith('travis', {}, {
        local: require.resolve('generator-travis/generators/app')
      });
    }

    this.composeWith('typescript-npm-bower:editor-conf', {}, {
      local: require.resolve('../editor-conf')
    });

    this.composeWith('typescript-npm-bower:lint', {}, {
      local: require.resolve('../lint')
    });

    this.composeWith('typescript-npm-bower:npm-conf', {}, {
      local: require.resolve('../npm-conf')
    });

    if (this.props.browser && this.options.bower && this.props.bower) {
      this.composeWith('typescript-npm-bower:bower-conf', {}, {
        local: require.resolve('../bower-conf')
      });
    }

    this.composeWith('typescript-npm-bower:typescript-conf', {
        options: {
          name: _.kebabCase(this.props.name),
          browser: this.props.browser,
          testFramework: this.props.testFramework
        }
      }, {
        local: require.resolve('../typescript-conf')
    });

    if (this.props.browser) {
      this.composeWith('typescript-npm-bower:karma-conf', {
        options: {
          testFramework: this.props.testFramework
        }
      }, {
        local: require.resolve('../karma-conf')
      });
    }

    this.composeWith('typescript-npm-bower:git', {
      options: {
        name: this.props.name,
        githubAccount: this.props.githubAccount
      }
    }, {
      local: require.resolve('../git')
    });

    if (this.options.gulp) {
      this.composeWith('typescript-npm-bower:gulp', {
        options: {
          name: _.kebabCase(this.props.name),
          browser: this.props.browser,
          styles: this.props.styles,
          scss: this.props.scss,
          bower: this.props.bower,
          testFramework: this.props.testFramework
        }
      },  {
        local: require.resolve('../gulp')
      });
    }

    if (this.options.boilerplate) {
      this.composeWith('typescript-npm-bower:boilerplate', {
        options: {
          browser: this.props.browser,
          styles: this.props.styles,
          scss: this.props.scss,
          bower: this.props.bower,
          testFramework: this.props.testFramework
        }
      }, {
        local: require.resolve('../boilerplate')
      });
    }

    if (this.options.license && !this.pkg.license) {
      this.composeWith('typescript-npm-bower:license', {
        options: {
          name: this.props.authorName,
          email: this.props.authorEmail,
          website: this.props.authorUrl
        }
      }, {
        local: require.resolve('generator-license/app')
      });
    }

    if (!this.fs.exists(this.destinationPath('README.md'))) {
      this.composeWith('typescript-npm-bower:readme', {
        options: {
          name: this.props.name,
          description: this.props.description,
          githubAccount: this.props.githubAccount,
          authorName: this.props.authorName,
          browser: this.props.browser,
          styles: this.props.styles,
          scss: this.props.scss,
          bower: this.props.bower,
          testFramework: this.props.testFramework
        }

      }, {
        local: require.resolve('../readme')
      });
    }
  },

  install: function () {
    this.npmInstall();
  }
});
<|endoftext|>


<commit_before>var generators = require('yeoman-generator');
var path = require('path');
module.exports = generators.Base.extend({
  promptProjectType: function() {
    var that = this;
    var done = this.async();

    this.prompt([{
      type: 'confirm',
      name: 'win10',
      message: 'Developing on Windows 10?',
      default: true
    }, {
      type: 'confirm',
      name: 'deps',
      message: 'Automatically install dependencies?',
      default: true
    }], function (answers) {
      that._win10 = answers.win10;
      that._deps = answers.deps;
      done();
    });
  },

  promptProjectInfo: function() {
    var that = this;
    var done = this.async();

    this.prompt([{
      type: 'input',
      name: 'name',
      message: 'Project name?',
      default: 'demo-app'
    }, {
      type: 'input',
      name: 'author',
      message: 'Author name?',
      store: true,
      default: ''
    }], function (answers) {
      that._name = answers.name;
      that._author = answers.author;
      done();
    });
  },

  copyTemplate: function() {
    var gulpDir = path.join(require.resolve('appx-starter/package.json'), '../');
    if (this._win10) {
      this.fs.copy(this.templatePath(gulpDir) + '/**/{*,.*}', this.destinationPath(), {dot: true});
    } else {
      this.fs.copy(this.templatePath(gulpDir) + '/{,*,.*,gulpfile.js/*,gulpfile.js/tasks/**/*,gulpfile.js/util/**/*,src/**/*,src/**/.*}', this.destinationPath() + '/', {dot: true});
    }
    this.fs.move(this.destinationPath('.npmignore'), this.destinationPath('.gitignore'));

    var jsonContent = this.fs.readJSON(this.destinationPath('package.json'));
    ['gitHead', 'readme', 'readmeFilename', '_id', '_shasum', '_from', '_resolved'].forEach(function(entry) {
      if (jsonContent[entry]) {
        delete jsonContent[entry];
      }
    });
    var projectName = this._name.toLowerCase().replace(/ /g, '-');
    jsonContent.name = projectName;
    jsonContent.author - this._author;
    this.fs.writeJSON(this.destinationPath('package.json'), jsonContent);

  },

  install: function() {
    if (this._deps) {
      this.installDependencies({bower: false});
    }
  }
});
<commit_msg>finish automatically filling in package.json and manifest fields<commit_after>var generators = require('yeoman-generator');
var path = require('path');
module.exports = generators.Base.extend({
  promptProjectType: function() {
    var that = this;
    var done = this.async();

    this.prompt([{
      type: 'confirm',
      name: 'win10',
      message: 'Developing on Windows 10?',
      default: true
    }, {
      type: 'confirm',
      name: 'deps',
      message: 'Automatically install dependencies?',
      default: true
    }], function (answers) {
      that._win10 = answers.win10;
      that._deps = answers.deps;
      done();
    });
  },

  promptProjectInfo: function() {
    var that = this;
    var done = this.async();

    this.prompt([{
      type: 'input',
      name: 'name',
      message: 'Project name?',
      default: 'demo-app'
    }, {
      type: 'input',
      name: 'author',
      message: 'Author name?',
      store: true,
      default: ''
    }], function (answers) {
      that._name = answers.name;
      that._author = answers.author;
      done();
    });
  },

  copyTemplate: function() {
    var gulpDir = path.join(require.resolve('appx-starter/package.json'), '../');
    if (this._win10) {
      this.fs.copy(this.templatePath(gulpDir) + '/**/{*,.*}', this.destinationPath(), {dot: true});
    } else {
      this.fs.copy(this.templatePath(gulpDir) + '/{,*,.*,gulpfile.js/*,gulpfile.js/tasks/**/*,gulpfile.js/util/**/*,src/**/*,src/**/.*}', this.destinationPath() + '/', {dot: true});
    }
    this.fs.move(this.destinationPath('.npmignore'), this.destinationPath('.gitignore'));

    var jsonContent = this.fs.readJSON(this.destinationPath('package.json'));
    ['gitHead', 'readme', 'readmeFilename', '_id', '_shasum', '_from', '_resolved'].forEach(function(entry) {
      if (jsonContent[entry]) {
        delete jsonContent[entry];
      }
    });
    var projectName = this._name.trim().toLowerCase().replace(/ /g, '-');
    jsonContent.name = projectName;
    jsonContent.author = this._author.trim();
    this.fs.writeJSON(this.destinationPath('package.json'), jsonContent);

    var manifestContent = this.fs.read(this.destinationPath('src/AppxManifest.xml'));
    var cnString = 'Publisher="CN=' + this._author.trim() + '" />';
    var pubString = '<PublisherDisplayName>' + this._author.trim() + '</PublisherDisplayName>';
    var vDisplayName = 'DisplayName="' + this._name.trim() + '"';
    var displayName = '<DisplayName>' + this._name.trim() + '</DisplayName>';

    manifestContent = manifestContent.replace(/Publisher="CN=[\S\s]+?" \/>/, cnString)
      .replace(/<PublisherDisplayName>[\S\s]+?<\/PublisherDisplayName>/, pubString)
      .replace(/DisplayName="[\S\s]+?"/, vDisplayName)
      .replace(/<DisplayName>[\S\s]+?<\/DisplayName>/, displayName);

    this.fs.write(this.destinationPath('src/AppxManifest.xml'), manifestContent);
  },

  install: function() {
    if (this._deps) {
      this.installDependencies({bower: false});
    }
  }
});
<|endoftext|>