UNPKG

3.44 kBJavaScriptView Raw
1/**
2 * Create a directory module index.
3 * @function apemanmodule
4 * @param {string} dirname - Directory path which contains modules.
5 * @param {object} [options] - Optional settings.
6 * @param {boolean} strict - Emit error if not found.
7 * @param {string|string[]} pascal - Names to export as pascalcase
8 * @param {object} vars - Variables in expression.
9 * @returns {object} modules
10 */
11
12"use strict";
13
14const argx = require('argx'),
15 assert = require('assert'),
16 path = require('path'),
17 stringcase = require('stringcase'),
18 print = require('./print'),
19 _isModule = require('./_is_module'),
20 _datasource = require('./_datasource');
21
22/** @lends apemanmodule */
23function apemanmodule(dirname, options) {
24 let args = argx(arguments);
25 options = args.pop('object') || {};
26 dirname = args.shift('string');
27
28 assert.ok(dirname, "[apemanmodule] dirname is required.");
29
30 let pascal = options.pascal || [],
31 vars = options.vars || {},
32 strict = !!options.strict;
33
34 let datasource = _datasource(dirname, {
35 pascal: pascal,
36 vars: vars
37 });
38
39 function modules(name) {
40
41 let resolvedName = path.resolve(dirname, name);
42 if (_isModule(resolvedName)) {
43 return require(resolvedName);
44 }
45
46 let valid = modules.has(name);
47 if (!valid) {
48 let guess = modules.guess(name);
49 if (strict) {
50 let err = `Unknown module: "${name}".`;
51 if (guess) {
52 err = `${err} ( Did you mean "${guess}"? )`;
53 }
54 throw new Error(err);
55 } else {
56 name = guess;
57 }
58 }
59 let found = datasource[name];
60 if (found && found.hasOwnProperty('default')) {
61 // Fallback for es6 "export default" modules compiled by babel 6.x
62 found = found.default;
63 }
64 if (typeof(found) === 'undefined') {
65 console.warn(`[apemanmodule] Module not found with name: ${name}`);
66 }
67 return found;
68 }
69
70 modules.__proto__ = Object.assign(new Function(), {
71 /**
72 * Module data source.
73 */
74 datasource: datasource,
75 /**
76 * Check if has a module with name.
77 * @param {string} name - Name of module.
78 * @returns {*}
79 */
80 has(name) {
81 return datasource.hasOwnProperty(name)
82 },
83 /**
84 * Guess with name.
85 * @param {string} name
86 * @returns {*}
87 */
88 guess(name) {
89 let converters = [stringcase.pascalcase, stringcase.camelcase];
90 for (let convert of converters) {
91 let convertedName = convert(name);
92 let hit = modules.has(convertedName);
93 if (hit) {
94 return convertedName;
95 }
96 }
97 return null;
98 },
99 /**
100 * Print modules
101 * @param {string} [namespace] - Namespace to print.
102 */
103 print(namespace) {
104 print(modules, namespace);
105 }
106 });
107
108 Object.keys(datasource).forEach((key) => {
109 Object.defineProperty(modules, key, {
110 get: () => {
111 return datasource[key];
112 },
113 configurable: true,
114 enumerable: true
115 })
116 });
117
118 return modules;
119}
120
121module.exports = apemanmodule;
\No newline at end of file