Source: provider/convention/IntentHandlerProviderBySyncDirectory.js

/**
 * @author Sloan Seaman 
 * @copyright 2016 and on
 * @version .1
 * @license https://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0
 */

/** @private */
var AbstractProviderBySyncDirectory = require('../abstractProviderBySyncDirectory.js');
var svUtil = require('../../util.js');
var providerUtil = require('../providerUtil.js');
var path = require('path');
var log = require('winston-simple').getLogger('IntentHandlerProviderByDirectory2');

/**
 * NOTE: Not used in default SkillVC configuration.  Here just in case
 * 
 * Provides intents by loading all of the files in a directory as intents
 * 
 * Intents are loaded asynchronously but if an intent is requested before being loaded 
 * it will be immediately loaded and then skipped by the asychronous processing.
 *
 * If the intent being loaded does not implement {@link IntentHandler~getIntentList} then the filename
 * will be treated as the name of the intent and registered as such.
 *
 * @constructor
 * @implements {Provider}
 * @implements {ItemProcessor}
 * @see {@link AbstractProviderByAsyncDirectory}
 * @see {@link DefaultJSFilenameFormatter}
 * @param {String} directory The directory to read all intents from
 * @param {Object} options Options for the was the directory is process
 * @param {FileNameFormatter} [options.filenameFormatter=DefaultJSONFilenameFormatter] The FilenameFormmatter to use to parse the 
 *     filenames to determine name as well as how to format the id to become a filename. This object will only 
 *     load files that match the formatters isValid() method
 */
function IntentHandlerProviderByDirectory2(directory, options) {
	if (!directory) throw Error('directory required');

	AbstractProviderBySyncDirectory.apply(this, [
		directory, 
		options]);
}

IntentHandlerProviderByDirectory2.prototype = Object.create(AbstractProviderBySyncDirectory.prototype);
IntentHandlerProviderByDirectory2.prototype.constructor = IntentHandlerProviderByDirectory2;

/**
 * Not supported
 *
 * @param {Map} items Map of the items being processed
 * @param {String} itemId The Id of the item to process
 * @param {String} fileName The name of the file being processed
 * @param {Object} options Any options that are being passed to the ItemProcessor (can be null)
 */
IntentHandlerProviderByDirectory2.prototype.processItem = function(items, itemId, fileName, options) {
	/*eslint no-unused-vars: ["error", { "args": "none" }]*/
	throw new Error('Does not support the processing of individual items');
};

/**
 * Uses node require to load the file.  If the intent is not found this method
 * will favor performance and never look for the file again.
 *
 * @function
 * @param {Map} items Map of the items being processed
 * @param {String} fileName The name of the file being processed
 * @param {Object} options Any options that are being passed to the ItemProcessor (can be null)
 */
IntentHandlerProviderByDirectory2.prototype.processItems = function(items, fileName, options) {
	/*eslint no-unused-vars: ["error", { "args": "none" }]*/
	try {
		var loaded = svUtil.instantiate(path.resolve(fileName));

		providerUtil.addFunctions(loaded, { 'name' : path.parse(fileName).name });

		if (svUtil.isFunction(loaded.getIntentsList)) { // it specifies its intent list
			var handledIntents = loaded.getIntentsList();
			if (!handledIntents) handledIntents = path.parse(fileName).name; // if it didn't return anything, use filename (not extension)
			
			for (var i=0;i<handledIntents.length;i++) {
				items[handledIntents[i]] = loaded;
				log.info('Loaded intent handler '+loaded.getName()+ ' for intent '+handledIntents[i]);
			}
		}
		else { // it didn't specify an intent list, so make it what the name of the file is
			items[path.parse(fileName).name] = loaded;
			log.info('Loaded intent handler '+loaded.getName()+ ' for intent '+path.parse(fileName).name);
		}
	}
	catch (err) {
		log.error("Error loading intent "+path.parse(fileName).base+". "+err.stack);
	}
};

module.exports = IntentHandlerProviderByDirectory2;