UNPKG

6.1 kBJavaScriptView Raw
1var _ = require('underscore'),
2 async = require('async'),
3 fs = require('fs'),
4 fu = require('./fileUtil'),
5 resources = require('./util/resources');
6
7function Context(options, config, plugins, libraries, event) {
8 this._package = options.package;
9 this._platform = options.platform;
10 this._plugins = plugins;
11 this.mode = options.mode;
12 this.module = options.module;
13 this.fileConfig = options.fileConfig;
14 this.resource = options.resource;
15 this.config = config;
16 this.libraries = libraries || options.libraries;
17 this.event = event || options.event;
18}
19Context.prototype = {
20 fileUtil: fu,
21
22 clone: function(options) {
23 var ret = new Context(this, this.config);
24 ret.parent = this;
25 var prototype = Object.keys(Context.prototype);
26 for (var name in this) {
27 if (this.hasOwnProperty(name) && prototype.indexOf(name) === -1) {
28 ret[name] = this[name];
29 }
30 }
31 if (options) {
32 _.extend(ret, options);
33 ret._package = options.package || this._package;
34 ret._platform = options.platform || this._platform;
35 }
36 return ret;
37 },
38
39 fileNamesForModule: function(mode, moduleName, callback) {
40 var context = this.clone();
41 context.mode = mode;
42 context.module = moduleName && this.config.module(moduleName);
43 if (moduleName && !context.module) {
44 return callback(new Error('Unknown module "' + moduleName + '"'));
45 }
46
47 this.plugins.outputConfigs(context, function(err, configs) {
48 if (err) {
49 return callback(err);
50 }
51
52 async.map(configs, function(config, callback) {
53 var fileContext = context.clone();
54 fileContext.fileConfig = config;
55 fileContext._plugins.fileName(fileContext, function(err, fileName) {
56 config.fileName = fileName;
57 callback(err, config);
58 });
59 },
60 callback);
61 });
62 },
63
64 loadResource: function(resource, callback) {
65 if (!callback) {
66 // if only single param, assume as callback and resource from context
67 resource = this.resource;
68 callback = resource;
69 }
70
71 var fileInfo = {name: resource.hasOwnProperty('sourceFile') ? resource.sourceFile : resource.src};
72
73 function loaded(err, data) {
74 /*jshint eqnull: true */
75 if (err) {
76 if (!err.resourceLoadError) {
77 var json = '';
78 try {
79 // Output JSON for the resource... but protect ourselves from a failure masking a failure
80 resource = _.clone(resource.originalResource || resource);
81 delete resource.library;
82 delete resource.enoent;
83 json = '\n\t' + JSON.stringify(resource);
84 } catch (err) { /* NOP */ }
85
86 var errorWrapper = new Error('Failed to load resource "' + fileInfo.name + '"' + json + '\n\t' + (err.stack || err));
87 errorWrapper.stack = errorWrapper.message + ' ' + (err.stack || err);
88 errorWrapper.source = err;
89 errorWrapper.code = err.code;
90 errorWrapper.resourceLoadError = true;
91 err = errorWrapper;
92 }
93 callback(err);
94 return;
95 }
96 fileInfo.inputs = data.inputs;
97 fileInfo.generated = data.generated;
98 fileInfo.noSeparator = data.noSeparator;
99 fileInfo.ignoreWarnings = data.ignoreWarnings || resource.ignoreWarnings;
100 fileInfo.content = data.data != null ? data.data : data;
101
102 // Ensure that we dump off the stack
103 _.defer(function() {
104 callback(err, fileInfo);
105 });
106 }
107
108 if (typeof resource === 'function') {
109 resource(this, loaded);
110 } else if (resource.src) {
111 // Assume a file page, attempt to load
112 fu.readFile(resource.src, loaded);
113 } else {
114 loaded(undefined, {data: '', noSeparator: true, inputs: resource.dir ? [resource.dir] : []});
115 }
116
117 return fileInfo;
118 },
119
120 outputFile: function(writer, callback) {
121 var context = this;
122 context.plugins.file(context, function(err) {
123 if (err) {
124 return callback(err);
125 }
126
127 context.plugins.fileName(context, function(err, fileName) {
128 if (err) {
129 return callback(err);
130 }
131
132 context.buildPath = (fileName.root ? '' : context.platformPath) + fileName.path + '.' + fileName.extension;
133 context.fileName = context.outdir + '/' + context.buildPath;
134 writer(function(err, data) {
135 data = _.defaults({
136 fileConfig: context.fileConfig,
137 platform: context.platform,
138 package: context.package,
139 mode: context.mode
140 }, data);
141
142 if (err) {
143 fs.unlink(context.fileName, function() { /* NOP To Prevent warning */});
144 data.error = err;
145 }
146 context.event.emit('output', data);
147
148 context.fileCache = undefined;
149 callback(err, data);
150 });
151 });
152 });
153 },
154
155 get description() {
156 var ret = 'package:' + this.package + '_platform:' + this.platform;
157 if (this.mode) {
158 ret += '_mode:' + this.mode;
159 }
160 if (this.fileName) {
161 ret += '_config:' + this.fileName;
162 }
163 if (this.module) {
164 ret += '_module:' + (this.module.name || this.module);
165 }
166 if (this.resource) {
167 // TODO : Anything better for this?
168 ret += '_resource:' + resources.source(this.resource);
169 }
170 return ret;
171 },
172
173 get plugins() { return this._plugins; },
174
175 get package() { return this._package; },
176 get platform() { return this._platform; },
177 get platformPath() {
178 return this.platform ? this.platform + '/' : '';
179 },
180
181 get combined() {
182 return this.config.combineModules(this.package);
183 },
184 get baseName() {
185 if (!this.combined) {
186 return this.module.name;
187 } else {
188 return (this.config.attributes.packages[this.package] || {}).name || this.package;
189 }
190 },
191
192 get resources() {
193 if (this.parent) {
194 return this.parent.resources;
195 } else {
196 return this._resources;
197 }
198 },
199 set resources(value) {
200 if (this.parent) {
201 delete this.parent;
202 }
203 this._resources = value;
204 }
205};
206
207module.exports = Context;