1 | var path = require('path');
|
2 | var url = require('url');
|
3 |
|
4 | exports.traceurGet = function(module) {
|
5 | var traceur = require('traceur');
|
6 | var traceurVersion = traceur.loader.NodeTraceurLoader.prototype.version;
|
7 | return $traceurRuntime.ModuleStore.get('traceur@' + traceurVersion + '/src/' + module);
|
8 | };
|
9 |
|
10 | exports.extend = extend;
|
11 | function extend(a, b) {
|
12 | for (var p in b)
|
13 | a[p] = b[p];
|
14 | return a;
|
15 | }
|
16 |
|
17 | exports.dextend = dextend;
|
18 | function dextend(a, b) {
|
19 | for (var p in b) {
|
20 | if (!b.hasOwnProperty(p))
|
21 | continue;
|
22 | var val = b[p];
|
23 | if (typeof val === 'object')
|
24 | dextend(a[p] = typeof a[p] === 'object' ? a[p] : {}, val);
|
25 | else
|
26 | a[p] = val;
|
27 | }
|
28 | return a;
|
29 | }
|
30 |
|
31 | exports.getFormatHint = getFormatHint;
|
32 | function getFormatHint(compileOpts) {
|
33 | var formatHint = '';
|
34 |
|
35 | var format = compileOpts.format;
|
36 |
|
37 | if (format == 'umd')
|
38 | format = 'amd';
|
39 |
|
40 | if (format == 'amd' || format == 'cjs' || format == 'global')
|
41 | formatHint = formatHint + '"format ' + format + '";\n';
|
42 |
|
43 | if (compileOpts.format == 'global') {
|
44 | for (var g in compileOpts.globalDeps)
|
45 | formatHint = formatHint + '"globals.' + compileOpts.globalDeps[g] + ' ' + g + '";\n';
|
46 |
|
47 | if (compileOpts.globalName)
|
48 | formatHint = formatHint + '"exports ' + compileOpts.globalName + '";\n';
|
49 | }
|
50 |
|
51 | return formatHint;
|
52 | }
|
53 |
|
54 | var isWin = process.platform.match(/^win/);
|
55 |
|
56 | exports.fromFileURL = fromFileURL;
|
57 | function fromFileURL(url) {
|
58 | return url.substr(7 + !!isWin).replace(/\//g, path.sep);
|
59 | }
|
60 |
|
61 | exports.toFileURL = toFileURL;
|
62 | function toFileURL(path) {
|
63 | return 'file://' + (isWin ? '/' : '') + path.replace(/\\/g, '/');
|
64 | }
|
65 |
|
66 | exports.getAlias = getAlias
|
67 | function getAlias(loader, canonicalName) {
|
68 | var pluginIndex = loader.pluginFirst ? canonicalName.indexOf('!') : canonicalName.lastIndexOf('!');
|
69 | if (pluginIndex != -1)
|
70 | return getAlias(loader, canonicalName.substr(0, pluginIndex)) + '!' + getAlias(loader, canonicalName.substr(pluginIndex + 1));
|
71 |
|
72 |
|
73 | canonicalName = canonicalName.replace('/#:./', '/');
|
74 |
|
75 | if (canonicalName.match(/\#[\:\{\?]/))
|
76 | throw new Error('Unable to alias the conditional dependency "' + canonicalName + '".');
|
77 |
|
78 | var packageName = getPackage(loader.packages, loader.decanonicalize(canonicalName));
|
79 | var packageMain = packageName && loader.packages[packageName].main;
|
80 | if (packageMain && canonicalName.substr(canonicalName.length - packageMain.length - 1) == '/' + packageMain)
|
81 | canonicalName = canonicalName.substr(0, canonicalName.length - packageMain.length - 1);
|
82 |
|
83 | var bestAliasLength = 0;
|
84 | var bestAliasSubpath;
|
85 | var bestAlias;
|
86 | Object.keys(loader.map).forEach(function(alias) {
|
87 | if (alias.split('/').length <= bestAliasLength)
|
88 | return;
|
89 |
|
90 |
|
91 | var mapped = getCanonicalName(loader, loader.decanonicalize(loader.map[alias]));
|
92 |
|
93 |
|
94 | if (loader.defaultJSExtensions && canonicalName == mapped + '.js') {
|
95 | bestAlias = alias;
|
96 | bestAliasSubpath = '';
|
97 | bestAliasLength = alias.split('/').length;
|
98 | }
|
99 | else if (canonicalName.substr(0, mapped.length) == mapped &&
|
100 | (canonicalName.length == mapped.length || canonicalName[mapped.length] == '/')) {
|
101 | bestAlias = alias;
|
102 | bestAliasSubpath = canonicalName.substr(mapped.length);
|
103 | bestAliasLength = alias.split('/').length;
|
104 | }
|
105 | });
|
106 |
|
107 | if (bestAlias)
|
108 | return bestAlias + bestAliasSubpath;
|
109 |
|
110 | return canonicalName;
|
111 | }
|
112 |
|
113 | exports.verifyTree = verifyTree;
|
114 | function verifyTree(tree) {
|
115 | if (typeof tree != 'object' || tree instanceof Array)
|
116 | throw new TypeError('Expected a trace tree object');
|
117 |
|
118 | Object.keys(tree).forEach(function(key) {
|
119 | var load = tree[key];
|
120 | if (typeof load === 'boolean')
|
121 | return;
|
122 | if (load && typeof load != 'object' || !load.name || !(load.conditional || load.deps))
|
123 | throw new TypeError('Expected a trace tree object, but "' + key + '" is not a load record.');
|
124 | });
|
125 | }
|
126 |
|
127 | exports.getCanonicalName = getCanonicalName;
|
128 | function getCanonicalName(loader, normalized, isPlugin) {
|
129 |
|
130 | var booleanIndex = normalized.lastIndexOf('#?');
|
131 | if (booleanIndex != -1) {
|
132 | var booleanModule = normalized.substr(booleanIndex + 2);
|
133 | var negate = booleanModule[0] == '~';
|
134 | if (negate)
|
135 | booleanModule = booleanModule.substr(1);
|
136 | return getCanonicalName(loader, normalized.substr(0, booleanIndex)) + '#?' + (negate ? '~' : '') + canonicalizeCondition(loader, booleanModule);
|
137 | }
|
138 |
|
139 |
|
140 | var pluginIndex = loader.pluginFirst ? normalized.indexOf('!') : normalized.lastIndexOf('!');
|
141 | if (pluginIndex != -1)
|
142 | return getCanonicalName(loader, normalized.substr(0, pluginIndex), !loader.pluginFirst) + '!' + getCanonicalName(loader, normalized.substr(pluginIndex + 1), loader.pluginFirst);
|
143 |
|
144 |
|
145 | var pkgEnvIndex = normalized.indexOf('/#:');
|
146 | if (pkgEnvIndex != -1)
|
147 | return getCanonicalName(loader, normalized.substr(0, pkgEnvIndex), isPlugin) + '/#:' + normalized.substr(pkgEnvIndex + 3);
|
148 |
|
149 |
|
150 | var canonical = getCanonicalNamePlain(loader, normalized, isPlugin);
|
151 |
|
152 |
|
153 | var conditionalMatch = canonical.match(interpolationRegEx);
|
154 | if (conditionalMatch)
|
155 | return getCanonicalNamePlain(loader, normalized, isPlugin).replace(interpolationRegEx, '#{' + canonicalizeCondition(loader, conditionalMatch[0].substr(2, conditionalMatch[0].length - 3)) + '}');
|
156 |
|
157 | return canonical;
|
158 | }
|
159 |
|
160 |
|
161 |
|
162 | var interpolationRegEx = /#\{[^\}]+\}/;
|
163 | function canonicalizeCondition(loader, conditionModule) {
|
164 | var conditionExport;
|
165 | var exportIndex = conditionModule.lastIndexOf('|');
|
166 | if (exportIndex != -1) {
|
167 | conditionExport = conditionModule.substr(exportIndex + 1)
|
168 | conditionModule = conditionModule.substr(0, exportIndex) || '@system-env';
|
169 | }
|
170 | return getCanonicalName(loader, conditionModule) + (conditionExport ? '|' + conditionExport : '');
|
171 | }
|
172 |
|
173 |
|
174 |
|
175 | function getCanonicalNamePlain(loader, normalized, isPlugin) {
|
176 |
|
177 | var pathMatch;
|
178 |
|
179 |
|
180 | for (var p in loader.paths) {
|
181 | if (loader.paths[p].indexOf('*') != -1)
|
182 | continue;
|
183 |
|
184 | var curPath = normalizePath(loader, loader.paths[p], isPlugin);
|
185 |
|
186 |
|
187 | if (normalized === curPath)
|
188 | return p;
|
189 |
|
190 |
|
191 | else if (curPath[curPath.length - 1] == '/' &&
|
192 | normalized.substr(0, curPath.length - 1) == curPath.substr(0, curPath.length - 1) &&
|
193 | (normalized.length < curPath.length || normalized[curPath.length - 1] == curPath[curPath.length - 1])) {
|
194 |
|
195 | return normalized.length < curPath.length ? p.substr(0, p.length - 1) : p + normalized.substr(curPath.length);
|
196 | }
|
197 | }
|
198 |
|
199 |
|
200 | var pathMatchLength = 0;
|
201 | var curMatchLength;
|
202 | if (!pathMatch)
|
203 | for (var p in loader.paths) {
|
204 | if (loader.paths[p].indexOf('*') == -1)
|
205 | continue;
|
206 |
|
207 |
|
208 | var curPath = normalizePath(loader, loader.paths[p], true);
|
209 |
|
210 |
|
211 | var wIndex = curPath.indexOf('*');
|
212 | if (normalized.substr(0, wIndex) === curPath.substr(0, wIndex)
|
213 | && normalized.substr(normalized.length - curPath.length + wIndex + 1) === curPath.substr(wIndex + 1)) {
|
214 | curMatchLength = curPath.split('/').length;
|
215 | if (curMatchLength >= pathMatchLength) {
|
216 | pathMatch = p.replace('*', normalized.substr(wIndex, normalized.length - curPath.length + 1));
|
217 | pathMatchLength = curMatchLength;
|
218 | }
|
219 | }
|
220 | }
|
221 |
|
222 |
|
223 | if (!pathMatch) {
|
224 | if (normalized.substr(0, loader.baseURL.length) == loader.baseURL)
|
225 | pathMatch = normalized.substr(loader.baseURL.length);
|
226 | else if (normalized.match(absURLRegEx))
|
227 | throw new Error('Unable to calculate canonical name to bundle ' + normalized + '. Ensure that this module sits within the baseURL or a wildcard path config.');
|
228 | else
|
229 | pathMatch = normalized;
|
230 | }
|
231 |
|
232 | return pathMatch;
|
233 | }
|
234 |
|
235 | exports.getPackageConfigPath = getPackageConfigPath;
|
236 |
|
237 |
|
238 |
|
239 | var packageConfigPaths = {};
|
240 |
|
241 |
|
242 | function createPkgConfigPathObj(path) {
|
243 | var lastWildcard = path.lastIndexOf('*');
|
244 | var length = Math.max(lastWildcard + 1, path.lastIndexOf('/'));
|
245 | return {
|
246 | length: length,
|
247 |
|
248 | regEx: new RegExp('^(' + path.substr(0, length).replace(/\*/g, '[^\\/]+') + ')(\\/|$)'),
|
249 | wildcard: lastWildcard != -1
|
250 | };
|
251 | }
|
252 |
|
253 |
|
254 | exports.getPackageConfigPath = getPackageConfigPath;
|
255 | function getPackageConfigPath(packageConfigPaths, normalized) {
|
256 | var pkgName, exactMatch = false, configPath;
|
257 | for (var i = 0; i < packageConfigPaths.length; i++) {
|
258 | var packageConfigPath = packageConfigPaths[i];
|
259 | var p = packageConfigPaths[packageConfigPath] || (packageConfigPaths[packageConfigPath] = createPkgConfigPathObj(packageConfigPath));
|
260 | if (normalized.length < p.length)
|
261 | continue;
|
262 | var match = normalized.match(p.regEx);
|
263 | if (match && (!pkgName || (!(exactMatch && p.wildcard) && pkgName.length < match[1].length))) {
|
264 | pkgName = match[1];
|
265 | exactMatch = !p.wildcard;
|
266 | configPath = pkgName + packageConfigPath.substr(p.length);
|
267 | }
|
268 | }
|
269 |
|
270 | if (!pkgName)
|
271 | return;
|
272 |
|
273 |
|
274 | return configPath;
|
275 | }
|
276 |
|
277 |
|
278 | exports.isPackageConfig = isPackageConfig;
|
279 | var curHash;
|
280 | var configPathCache = null;
|
281 | var canonicalConfigPaths = null;
|
282 | function isPackageConfig(loader, canonical) {
|
283 | if (loader.configHash != curHash) {
|
284 | configPathCache = null;
|
285 | curHash = loader.configHash;
|
286 | }
|
287 |
|
288 |
|
289 | if (!configPathCache) {
|
290 | canonicalConfigPaths = loader.packageConfigPaths.map(function(configPath) {
|
291 | return getCanonicalName(loader, configPath);
|
292 | });
|
293 | configPathCache = {};
|
294 | }
|
295 |
|
296 | if (canonical in configPathCache)
|
297 | return configPathCache[canonical];
|
298 |
|
299 |
|
300 | var cfgPathMatch = getPackageConfigPath(canonicalConfigPaths, canonical);
|
301 | configPathCache[canonical] = cfgPathMatch && cfgPathMatch.split('/').length == canonical.split('/').length;
|
302 |
|
303 | return configPathCache[canonical];
|
304 | }
|
305 |
|
306 | exports.getPackage = getPackage;
|
307 | function getPackage(packages, name) {
|
308 |
|
309 | var curPkg, curPkgLen = 0, pkgLen;
|
310 | for (var p in packages) {
|
311 | if (name.substr(0, p.length) === p && (name.length === p.length || name[p.length] === '/')) {
|
312 | pkgLen = p.split('/').length;
|
313 | if (pkgLen > curPkgLen) {
|
314 | curPkg = p;
|
315 | curPkgLen = pkgLen;
|
316 | }
|
317 | }
|
318 | }
|
319 | return curPkg;
|
320 | }
|
321 |
|
322 | var absURLRegEx = /^[^\/]+:\/\//;
|
323 | function normalizePath(loader, path, skipExtension) {
|
324 | var curMap = loader.map;
|
325 | var curPaths = loader.paths;
|
326 | var curPackages = loader.packages;
|
327 | loader.map = {};
|
328 | loader.paths = {};
|
329 | loader.packages = {};
|
330 | var normalized = loader.normalizeSync(path);
|
331 | if (skipExtension && path.substr(path.length - 3, 3) != '.js' && normalized.substr(normalized.length - 3, 3) == '.js')
|
332 | normalized = normalized.substr(0, normalized.length - 3);
|
333 | loader.map = curMap;
|
334 | loader.paths = curPaths;
|
335 | loader.packages = curPackages;
|
336 | return normalized;
|
337 | }
|
338 |
|
339 | var sysConditions = ['browser', 'node', 'dev', 'production', 'default'];
|
340 |
|
341 | exports.parseCondition = parseCondition;
|
342 | function parseCondition(condition) {
|
343 | var conditionExport, conditionModule, negation;
|
344 |
|
345 | var negation = condition[0] == '~';
|
346 | var conditionExportIndex = condition.lastIndexOf('|');
|
347 | if (conditionExportIndex != -1) {
|
348 | conditionExport = condition.substr(conditionExportIndex + 1);
|
349 | conditionModule = condition.substr(negation, conditionExportIndex - negation);
|
350 |
|
351 | if (conditionExport[0] == '~') {
|
352 | negation = true;
|
353 | conditionExport = conditionExport.substr(1);
|
354 | }
|
355 | }
|
356 | else {
|
357 | conditionExport = 'default';
|
358 | conditionModule = condition.substr(negation);
|
359 | if (sysConditions.indexOf(conditionModule) != -1) {
|
360 | conditionExport = conditionModule;
|
361 | conditionModule = '@system-env';
|
362 | }
|
363 | }
|
364 |
|
365 | return {
|
366 | module: conditionModule,
|
367 | prop: conditionExport,
|
368 | negate: negation
|
369 | };
|
370 | }
|
371 |
|
372 | exports.serializeCondition = serializeCondition;
|
373 | function serializeCondition(conditionObj) {
|
374 | return conditionObj.module + '|' + (conditionObj.negate ? '~' : '') + conditionObj.prop;
|
375 | }
|
376 |
|