1 |
|
2 | (function() {
|
3 | var existsSync, fs, path, _ref;
|
4 |
|
5 | path = require('path');
|
6 |
|
7 | fs = require('fs');
|
8 |
|
9 | existsSync = (_ref = fs.existsSync) != null ? _ref : path.existsSync;
|
10 |
|
11 | exports.container = function() {
|
12 | var argList, container, factories, get, getSandboxed, haveVisited, list, load, loaddir, loadfile, modules, notEmpty, register, registerOne, resolve, toFactory;
|
13 | factories = {};
|
14 | modules = {};
|
15 | register = function(name, func) {
|
16 | var hash, _results;
|
17 | if (name === Object(name)) {
|
18 | hash = name;
|
19 | _results = [];
|
20 | for (name in hash) {
|
21 | func = hash[name];
|
22 | _results.push(registerOne(name, func));
|
23 | }
|
24 | return _results;
|
25 | } else {
|
26 | return registerOne(name, func);
|
27 | }
|
28 | };
|
29 | registerOne = function(name, func) {
|
30 | if (!(func != null)) {
|
31 | throw new Error("cannot register null function");
|
32 | }
|
33 | return factories[name] = toFactory(func);
|
34 | };
|
35 | list = function() {
|
36 | return factories;
|
37 | };
|
38 | load = function(file) {
|
39 | var exists, stats;
|
40 | exists = existsSync(file);
|
41 | if (exists) {
|
42 | stats = fs.statSync(file);
|
43 | if (stats.isDirectory()) {
|
44 | return loaddir(file);
|
45 | }
|
46 | }
|
47 | return loadfile(file);
|
48 | };
|
49 | loadfile = function(file) {
|
50 | var module, name;
|
51 | module = file.replace(/\.\w+$/, "");
|
52 | name = path.basename(module).replace(/\-(\w)/g, function(match, letter) {
|
53 | return letter.toUpperCase();
|
54 | });
|
55 | return modules[name] = module;
|
56 | };
|
57 | loaddir = function(dir) {
|
58 | var file, filenames, files, stats, _i, _len, _results;
|
59 | filenames = fs.readdirSync(dir);
|
60 | files = filenames.map(function(file) {
|
61 | return path.join(dir, file);
|
62 | });
|
63 | _results = [];
|
64 | for (_i = 0, _len = files.length; _i < _len; _i++) {
|
65 | file = files[_i];
|
66 | if (!file.match(/\.(js|coffee)$/)) {
|
67 | continue;
|
68 | }
|
69 | stats = fs.statSync(file);
|
70 | if (stats.isFile()) {
|
71 | _results.push(loadfile(file));
|
72 | } else {
|
73 | _results.push(void 0);
|
74 | }
|
75 | }
|
76 | return _results;
|
77 | };
|
78 | toFactory = function(func) {
|
79 | if (typeof func === "function") {
|
80 | return {
|
81 | func: func,
|
82 | required: argList(func)
|
83 | };
|
84 | } else {
|
85 | return {
|
86 | func: function() {
|
87 | return func;
|
88 | },
|
89 | required: []
|
90 | };
|
91 | }
|
92 | };
|
93 | argList = function(func) {
|
94 | var match, required;
|
95 | match = func.toString().match(/function.*?\(([\s\S]*?)\)/);
|
96 | if (!(match != null)) {
|
97 | throw new Error("could not parse function arguments: " + (func != null ? func.toString() : void 0));
|
98 | }
|
99 | required = match[1].split(",").filter(notEmpty).map(function(str) {
|
100 | return str.trim();
|
101 | });
|
102 | return required;
|
103 | };
|
104 | notEmpty = function(a) {
|
105 | return a;
|
106 | };
|
107 | get = function(name, overrides, visited) {
|
108 | var dependencies, factory, instance, isOverridden, module;
|
109 | if (visited == null) {
|
110 | visited = [];
|
111 | }
|
112 | isOverridden = overrides != null;
|
113 | if (haveVisited(visited, name)) {
|
114 | throw new Error("circular dependency with '" + name + "'");
|
115 | }
|
116 | visited = visited.concat(name);
|
117 | factory = factories[name];
|
118 | if (!(factory != null)) {
|
119 | module = modules[name];
|
120 | if (module != null) {
|
121 | register(name, require(module));
|
122 | factory = factories[name];
|
123 | } else {
|
124 | throw new Error("dependency '" + name + "' was not registered");
|
125 | }
|
126 | }
|
127 | if ((factory.instance != null) && !isOverridden) {
|
128 | return factory.instance;
|
129 | }
|
130 | dependencies = factory.required.map(function(name) {
|
131 | if ((overrides != null ? overrides[name] : void 0) != null) {
|
132 | return overrides != null ? overrides[name] : void 0;
|
133 | } else {
|
134 | return get(name, overrides, visited);
|
135 | }
|
136 | });
|
137 | instance = factory.func.apply(factory, dependencies);
|
138 | if (!isOverridden) {
|
139 | factory.instance = instance;
|
140 | }
|
141 | return instance;
|
142 | };
|
143 | getSandboxed = function(name, overrides) {
|
144 | var mockContainer;
|
145 | mockContainer = exports.container();
|
146 | mockContainer.register(name, factories[name].func);
|
147 | return mockContainer.get(name, overrides);
|
148 | };
|
149 | haveVisited = function(visited, name) {
|
150 | var isName;
|
151 | isName = function(n) {
|
152 | return n === name;
|
153 | };
|
154 | return visited.filter(isName).length;
|
155 | };
|
156 | resolve = function(overrides, func) {
|
157 | if (!func) {
|
158 | func = overrides;
|
159 | overrides = null;
|
160 | }
|
161 | register("__temp", func);
|
162 | return get("__temp", overrides);
|
163 | };
|
164 | container = {
|
165 | get: get,
|
166 | getSandboxed: getSandboxed,
|
167 | resolve: resolve,
|
168 | register: register,
|
169 | load: load,
|
170 | list: list
|
171 | };
|
172 | container.register("_container", container);
|
173 | return container;
|
174 | };
|
175 |
|
176 | }).call(this);
|