1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | var path = require("path");
|
11 | var ts = require("typescript");
|
12 | var collector_1 = require("./collector");
|
13 | var schema_1 = require("./schema");
|
14 |
|
15 | var PRIVATE_NAME_CHARS = 'abcdefghijklmnopqrstuvwxyz';
|
16 | var MetadataBundler = (function () {
|
17 | function MetadataBundler(root, importAs, host) {
|
18 | this.root = root;
|
19 | this.importAs = importAs;
|
20 | this.host = host;
|
21 | this.symbolMap = new Map();
|
22 | this.metadataCache = new Map();
|
23 | this.exports = new Map();
|
24 | this.rootModule = "./" + path.basename(root);
|
25 | }
|
26 | MetadataBundler.prototype.getMetadataBundle = function () {
|
27 |
|
28 |
|
29 | var exportedSymbols = this.exportAll(this.rootModule);
|
30 | this.canonicalizeSymbols(exportedSymbols);
|
31 |
|
32 | var metadata = this.getEntries(exportedSymbols);
|
33 | var privates = Array.from(this.symbolMap.values())
|
34 | .filter(function (s) { return s.referenced && s.isPrivate; })
|
35 | .map(function (s) { return ({
|
36 | privateName: s.privateName,
|
37 | name: s.declaration.name,
|
38 | module: s.declaration.module
|
39 | }); });
|
40 | var origins = Array.from(this.symbolMap.values())
|
41 | .filter(function (s) { return s.referenced && !s.reexport; })
|
42 | .reduce(function (p, s) {
|
43 | p[s.isPrivate ? s.privateName : s.name] = s.declaration.module;
|
44 | return p;
|
45 | }, {});
|
46 | var exports = this.getReExports(exportedSymbols);
|
47 | return {
|
48 | metadata: {
|
49 | __symbolic: 'module',
|
50 | version: schema_1.VERSION,
|
51 | exports: exports.length ? exports : undefined, metadata: metadata, origins: origins,
|
52 | importAs: this.importAs
|
53 | },
|
54 | privates: privates
|
55 | };
|
56 | };
|
57 | MetadataBundler.resolveModule = function (importName, from) {
|
58 | return resolveModule(importName, from);
|
59 | };
|
60 | MetadataBundler.prototype.getMetadata = function (moduleName) {
|
61 | var result = this.metadataCache.get(moduleName);
|
62 | if (!result) {
|
63 | if (moduleName.startsWith('.')) {
|
64 | var fullModuleName = resolveModule(moduleName, this.root);
|
65 | result = this.host.getMetadataFor(fullModuleName);
|
66 | }
|
67 | this.metadataCache.set(moduleName, result);
|
68 | }
|
69 | return result;
|
70 | };
|
71 | MetadataBundler.prototype.exportAll = function (moduleName) {
|
72 | var _this = this;
|
73 | var module = this.getMetadata(moduleName);
|
74 | var result = this.exports.get(moduleName);
|
75 | if (result) {
|
76 | return result;
|
77 | }
|
78 | result = [];
|
79 | var exportSymbol = function (exportedSymbol, exportAs) {
|
80 | var symbol = _this.symbolOf(moduleName, exportAs);
|
81 | result.push(symbol);
|
82 | exportedSymbol.reexportedAs = symbol;
|
83 | symbol.exports = exportedSymbol;
|
84 | };
|
85 |
|
86 | if (module && module.metadata) {
|
87 | for (var key in module.metadata) {
|
88 | var data = module.metadata[key];
|
89 | if (schema_1.isMetadataImportedSymbolReferenceExpression(data)) {
|
90 |
|
91 | var exportFrom = resolveModule(data.module, moduleName);
|
92 | this.exportAll(exportFrom);
|
93 | var symbol = this.symbolOf(exportFrom, data.name);
|
94 | exportSymbol(symbol, key);
|
95 | }
|
96 | else {
|
97 |
|
98 | result.push(this.symbolOf(moduleName, key));
|
99 | }
|
100 | }
|
101 | }
|
102 |
|
103 | if (module && module.exports) {
|
104 | for (var _i = 0, _a = module.exports; _i < _a.length; _i++) {
|
105 | var exportDeclaration = _a[_i];
|
106 | var exportFrom = resolveModule(exportDeclaration.from, moduleName);
|
107 |
|
108 | var exportedSymbols = this.exportAll(exportFrom);
|
109 | if (exportDeclaration.export) {
|
110 |
|
111 | for (var _b = 0, _c = exportDeclaration.export; _b < _c.length; _b++) {
|
112 | var exportItem = _c[_b];
|
113 | var name_1 = typeof exportItem == 'string' ? exportItem : exportItem.name;
|
114 | var exportAs = typeof exportItem == 'string' ? exportItem : exportItem.as;
|
115 | var symbol = this.symbolOf(exportFrom, name_1);
|
116 | if (exportedSymbols && exportedSymbols.length == 1 && exportedSymbols[0].reexport &&
|
117 | exportedSymbols[0].name == '*') {
|
118 |
|
119 |
|
120 | symbol.reexport = true;
|
121 | }
|
122 | exportSymbol(this.symbolOf(exportFrom, name_1), exportAs);
|
123 | }
|
124 | }
|
125 | else {
|
126 |
|
127 | var exportedSymbols_1 = this.exportAll(exportFrom);
|
128 | for (var _d = 0, exportedSymbols_2 = exportedSymbols_1; _d < exportedSymbols_2.length; _d++) {
|
129 | var exportedSymbol = exportedSymbols_2[_d];
|
130 | var name_2 = exportedSymbol.name;
|
131 | exportSymbol(exportedSymbol, name_2);
|
132 | }
|
133 | }
|
134 | }
|
135 | }
|
136 | if (!module) {
|
137 |
|
138 |
|
139 |
|
140 | var symbol = this.symbolOf(moduleName, '*');
|
141 | symbol.reexport = true;
|
142 | result.push(symbol);
|
143 | }
|
144 | this.exports.set(moduleName, result);
|
145 | return result;
|
146 | };
|
147 | |
148 |
|
149 |
|
150 |
|
151 |
|
152 | MetadataBundler.prototype.canonicalizeSymbols = function (exportedSymbols) {
|
153 | var symbols = Array.from(this.symbolMap.values());
|
154 | this.exported = new Set(exportedSymbols);
|
155 | symbols.forEach(this.canonicalizeSymbol, this);
|
156 | };
|
157 | MetadataBundler.prototype.canonicalizeSymbol = function (symbol) {
|
158 | var rootExport = getRootExport(symbol);
|
159 | var declaration = getSymbolDeclaration(symbol);
|
160 | var isPrivate = !this.exported.has(rootExport);
|
161 | var canonicalSymbol = isPrivate ? declaration : rootExport;
|
162 | symbol.isPrivate = isPrivate;
|
163 | symbol.declaration = declaration;
|
164 | symbol.canonicalSymbol = canonicalSymbol;
|
165 | symbol.reexport = declaration.reexport;
|
166 | };
|
167 | MetadataBundler.prototype.getEntries = function (exportedSymbols) {
|
168 | var _this = this;
|
169 | var result = {};
|
170 | var exportedNames = new Set(exportedSymbols.map(function (s) { return s.name; }));
|
171 | var privateName = 0;
|
172 | function newPrivateName() {
|
173 | while (true) {
|
174 | var digits = [];
|
175 | var index = privateName++;
|
176 | var base = PRIVATE_NAME_CHARS;
|
177 | while (!digits.length || index > 0) {
|
178 | digits.unshift(base[index % base.length]);
|
179 | index = Math.floor(index / base.length);
|
180 | }
|
181 | digits.unshift('\u0275');
|
182 | var result_1 = digits.join('');
|
183 | if (!exportedNames.has(result_1))
|
184 | return result_1;
|
185 | }
|
186 | }
|
187 | exportedSymbols.forEach(function (symbol) { return _this.convertSymbol(symbol); });
|
188 | var symbolsMap = new Map();
|
189 | Array.from(this.symbolMap.values()).forEach(function (symbol) {
|
190 | if (symbol.referenced && !symbol.reexport) {
|
191 | var name_3 = symbol.name;
|
192 | var identifier = symbol.declaration.module + ":" + symbol.declaration.name;
|
193 | if (symbol.isPrivate && !symbol.privateName) {
|
194 | name_3 = newPrivateName();
|
195 | symbol.privateName = name_3;
|
196 | }
|
197 | if (symbolsMap.has(identifier)) {
|
198 | var names = symbolsMap.get(identifier);
|
199 | names.push(name_3);
|
200 | }
|
201 | else {
|
202 | symbolsMap.set(identifier, [name_3]);
|
203 | }
|
204 | result[name_3] = symbol.value;
|
205 | }
|
206 | });
|
207 |
|
208 | symbolsMap.forEach(function (names, identifier) {
|
209 | if (names.length > 1) {
|
210 | var _a = identifier.split(':'), module_1 = _a[0], declaredName = _a[1];
|
211 |
|
212 | var reference_1 = names.indexOf(declaredName);
|
213 | if (reference_1 === -1) {
|
214 | reference_1 = 0;
|
215 | }
|
216 |
|
217 | names.forEach(function (name, i) {
|
218 | if (i !== reference_1) {
|
219 | result[name] = { __symbolic: 'reference', name: names[reference_1] };
|
220 | }
|
221 | });
|
222 | }
|
223 | });
|
224 | return result;
|
225 | };
|
226 | MetadataBundler.prototype.getReExports = function (exportedSymbols) {
|
227 | var modules = new Map();
|
228 | var exportAlls = new Set();
|
229 | for (var _i = 0, exportedSymbols_3 = exportedSymbols; _i < exportedSymbols_3.length; _i++) {
|
230 | var symbol = exportedSymbols_3[_i];
|
231 | if (symbol.reexport) {
|
232 | var declaration = symbol.declaration;
|
233 | var module_2 = declaration.module;
|
234 | if (declaration.name == '*') {
|
235 |
|
236 | exportAlls.add(declaration.module);
|
237 | }
|
238 | else {
|
239 |
|
240 | var entry = modules.get(module_2);
|
241 | if (!entry) {
|
242 | entry = [];
|
243 | modules.set(module_2, entry);
|
244 | }
|
245 | var as = symbol.name;
|
246 | var name_4 = declaration.name;
|
247 | entry.push({ name: name_4, as: as });
|
248 | }
|
249 | }
|
250 | }
|
251 | return Array.from(exportAlls.values()).map(function (from) { return ({ from: from }); }).concat(Array.from(modules.entries()).map(function (_a) {
|
252 | var from = _a[0], exports = _a[1];
|
253 | return ({ export: exports, from: from });
|
254 | }));
|
255 | };
|
256 | MetadataBundler.prototype.convertSymbol = function (symbol) {
|
257 | var canonicalSymbol = symbol.canonicalSymbol;
|
258 | if (!canonicalSymbol.referenced) {
|
259 | canonicalSymbol.referenced = true;
|
260 | var declaration = canonicalSymbol.declaration;
|
261 | var module_3 = this.getMetadata(declaration.module);
|
262 | if (module_3) {
|
263 | var value = module_3.metadata[declaration.name];
|
264 | if (value && !declaration.name.startsWith('___')) {
|
265 | canonicalSymbol.value = this.convertEntry(declaration.module, value);
|
266 | }
|
267 | }
|
268 | }
|
269 | };
|
270 | MetadataBundler.prototype.convertEntry = function (moduleName, value) {
|
271 | if (schema_1.isClassMetadata(value)) {
|
272 | return this.convertClass(moduleName, value);
|
273 | }
|
274 | if (schema_1.isFunctionMetadata(value)) {
|
275 | return this.convertFunction(moduleName, value);
|
276 | }
|
277 | if (schema_1.isInterfaceMetadata(value)) {
|
278 | return value;
|
279 | }
|
280 | return this.convertValue(moduleName, value);
|
281 | };
|
282 | MetadataBundler.prototype.convertClass = function (moduleName, value) {
|
283 | var _this = this;
|
284 | return {
|
285 | __symbolic: 'class',
|
286 | arity: value.arity,
|
287 | extends: this.convertExpression(moduleName, value.extends),
|
288 | decorators: value.decorators && value.decorators.map(function (d) { return _this.convertExpression(moduleName, d); }),
|
289 | members: this.convertMembers(moduleName, value.members),
|
290 | statics: value.statics && this.convertStatics(moduleName, value.statics)
|
291 | };
|
292 | };
|
293 | MetadataBundler.prototype.convertMembers = function (moduleName, members) {
|
294 | var _this = this;
|
295 | var result = {};
|
296 | for (var name_5 in members) {
|
297 | var value = members[name_5];
|
298 | result[name_5] = value.map(function (v) { return _this.convertMember(moduleName, v); });
|
299 | }
|
300 | return result;
|
301 | };
|
302 | MetadataBundler.prototype.convertMember = function (moduleName, member) {
|
303 | var _this = this;
|
304 | var result = { __symbolic: member.__symbolic };
|
305 | result.decorators =
|
306 | member.decorators && member.decorators.map(function (d) { return _this.convertExpression(moduleName, d); });
|
307 | if (schema_1.isMethodMetadata(member)) {
|
308 | result.parameterDecorators = member.parameterDecorators &&
|
309 | member.parameterDecorators.map(function (d) { return d && d.map(function (p) { return _this.convertExpression(moduleName, p); }); });
|
310 | if (schema_1.isConstructorMetadata(member)) {
|
311 | if (member.parameters) {
|
312 | result.parameters =
|
313 | member.parameters.map(function (p) { return _this.convertExpression(moduleName, p); });
|
314 | }
|
315 | }
|
316 | }
|
317 | return result;
|
318 | };
|
319 | MetadataBundler.prototype.convertStatics = function (moduleName, statics) {
|
320 | var result = {};
|
321 | for (var key in statics) {
|
322 | var value = statics[key];
|
323 | result[key] = schema_1.isFunctionMetadata(value) ? this.convertFunction(moduleName, value) : value;
|
324 | }
|
325 | return result;
|
326 | };
|
327 | MetadataBundler.prototype.convertFunction = function (moduleName, value) {
|
328 | var _this = this;
|
329 | return {
|
330 | __symbolic: 'function',
|
331 | parameters: value.parameters,
|
332 | defaults: value.defaults && value.defaults.map(function (v) { return _this.convertValue(moduleName, v); }),
|
333 | value: this.convertValue(moduleName, value.value)
|
334 | };
|
335 | };
|
336 | MetadataBundler.prototype.convertValue = function (moduleName, value) {
|
337 | var _this = this;
|
338 | if (isPrimitive(value)) {
|
339 | return value;
|
340 | }
|
341 | if (schema_1.isMetadataError(value)) {
|
342 | return this.convertError(moduleName, value);
|
343 | }
|
344 | if (schema_1.isMetadataSymbolicExpression(value)) {
|
345 | return this.convertExpression(moduleName, value);
|
346 | }
|
347 | if (Array.isArray(value)) {
|
348 | return value.map(function (v) { return _this.convertValue(moduleName, v); });
|
349 | }
|
350 |
|
351 | var object = value;
|
352 | var result = {};
|
353 | for (var key in object) {
|
354 | result[key] = this.convertValue(moduleName, object[key]);
|
355 | }
|
356 | return result;
|
357 | };
|
358 | MetadataBundler.prototype.convertExpression = function (moduleName, value) {
|
359 | if (value) {
|
360 | switch (value.__symbolic) {
|
361 | case 'error':
|
362 | return this.convertError(moduleName, value);
|
363 | case 'reference':
|
364 | return this.convertReference(moduleName, value);
|
365 | default:
|
366 | return this.convertExpressionNode(moduleName, value);
|
367 | }
|
368 | }
|
369 | return value;
|
370 | };
|
371 | MetadataBundler.prototype.convertError = function (module, value) {
|
372 | return {
|
373 | __symbolic: 'error',
|
374 | message: value.message,
|
375 | line: value.line,
|
376 | character: value.character,
|
377 | context: value.context, module: module
|
378 | };
|
379 | };
|
380 | MetadataBundler.prototype.convertReference = function (moduleName, value) {
|
381 | var _this = this;
|
382 | var createReference = function (symbol) {
|
383 | var declaration = symbol.declaration;
|
384 | if (declaration.module.startsWith('.')) {
|
385 |
|
386 |
|
387 | _this.convertSymbol(symbol);
|
388 | return {
|
389 | __symbolic: 'reference',
|
390 | get name() {
|
391 |
|
392 | var canonicalSymbol = symbol.canonicalSymbol;
|
393 | if (canonicalSymbol.isPrivate == null) {
|
394 | throw Error('Invalid state: isPrivate was not initialized');
|
395 | }
|
396 | return canonicalSymbol.isPrivate ? canonicalSymbol.privateName : canonicalSymbol.name;
|
397 | }
|
398 | };
|
399 | }
|
400 | else {
|
401 |
|
402 |
|
403 | return { __symbolic: 'reference', name: declaration.name, module: declaration.module };
|
404 | }
|
405 | };
|
406 | if (schema_1.isMetadataGlobalReferenceExpression(value)) {
|
407 | var metadata = this.getMetadata(moduleName);
|
408 | if (metadata && metadata.metadata && metadata.metadata[value.name]) {
|
409 |
|
410 | return createReference(this.canonicalSymbolOf(moduleName, value.name));
|
411 | }
|
412 |
|
413 | if (value.arguments) {
|
414 | return {
|
415 | __symbolic: 'reference',
|
416 | name: value.name,
|
417 | arguments: value.arguments.map(function (a) { return _this.convertValue(moduleName, a); })
|
418 | };
|
419 | }
|
420 |
|
421 | return value;
|
422 | }
|
423 | if (schema_1.isMetadataImportedSymbolReferenceExpression(value)) {
|
424 |
|
425 |
|
426 |
|
427 |
|
428 |
|
429 |
|
430 | if (value.module.startsWith('.')) {
|
431 |
|
432 |
|
433 | var referencedModule = resolveModule(value.module, moduleName);
|
434 | var referencedName = value.name;
|
435 | return createReference(this.canonicalSymbolOf(referencedModule, referencedName));
|
436 | }
|
437 |
|
438 | if (value.arguments) {
|
439 |
|
440 | return {
|
441 | __symbolic: 'reference',
|
442 | name: value.name,
|
443 | module: value.module,
|
444 | arguments: value.arguments.map(function (a) { return _this.convertValue(moduleName, a); })
|
445 | };
|
446 | }
|
447 | return value;
|
448 | }
|
449 | if (schema_1.isMetadataModuleReferenceExpression(value)) {
|
450 |
|
451 |
|
452 | if (value.module.startsWith('.')) {
|
453 | return {
|
454 | __symbolic: 'error',
|
455 | message: 'Unsupported bundled module reference',
|
456 | context: { module: value.module }
|
457 | };
|
458 | }
|
459 |
|
460 | return value;
|
461 | }
|
462 | };
|
463 | MetadataBundler.prototype.convertExpressionNode = function (moduleName, value) {
|
464 | var result = { __symbolic: value.__symbolic };
|
465 | for (var key in value) {
|
466 | result[key] = this.convertValue(moduleName, value[key]);
|
467 | }
|
468 | return result;
|
469 | };
|
470 | MetadataBundler.prototype.symbolOf = function (module, name) {
|
471 | var symbolKey = module + ":" + name;
|
472 | var symbol = this.symbolMap.get(symbolKey);
|
473 | if (!symbol) {
|
474 | symbol = { module: module, name: name };
|
475 | this.symbolMap.set(symbolKey, symbol);
|
476 | }
|
477 | return symbol;
|
478 | };
|
479 | MetadataBundler.prototype.canonicalSymbolOf = function (module, name) {
|
480 |
|
481 | this.exportAll(module);
|
482 | var symbol = this.symbolOf(module, name);
|
483 | if (!symbol.canonicalSymbol) {
|
484 | this.canonicalizeSymbol(symbol);
|
485 | }
|
486 | return symbol;
|
487 | };
|
488 | return MetadataBundler;
|
489 | }());
|
490 | exports.MetadataBundler = MetadataBundler;
|
491 | var CompilerHostAdapter = (function () {
|
492 | function CompilerHostAdapter(host) {
|
493 | this.host = host;
|
494 | this.collector = new collector_1.MetadataCollector();
|
495 | }
|
496 | CompilerHostAdapter.prototype.getMetadataFor = function (fileName) {
|
497 | var sourceFile = this.host.getSourceFile(fileName + '.ts', ts.ScriptTarget.Latest);
|
498 | return this.collector.getMetadata(sourceFile);
|
499 | };
|
500 | return CompilerHostAdapter;
|
501 | }());
|
502 | exports.CompilerHostAdapter = CompilerHostAdapter;
|
503 | function resolveModule(importName, from) {
|
504 | if (importName.startsWith('.') && from) {
|
505 | var normalPath = path.normalize(path.join(path.dirname(from), importName));
|
506 | if (!normalPath.startsWith('.') && from.startsWith('.')) {
|
507 |
|
508 | normalPath = "." + path.sep + normalPath;
|
509 | }
|
510 |
|
511 |
|
512 | return normalPath.replace(/\\/g, '/');
|
513 | }
|
514 | return importName;
|
515 | }
|
516 | function isPrimitive(o) {
|
517 | return o === null || (typeof o !== 'function' && typeof o !== 'object');
|
518 | }
|
519 | function getRootExport(symbol) {
|
520 | return symbol.reexportedAs ? getRootExport(symbol.reexportedAs) : symbol;
|
521 | }
|
522 | function getSymbolDeclaration(symbol) {
|
523 | return symbol.exports ? getSymbolDeclaration(symbol.exports) : symbol;
|
524 | }
|
525 |
|
\ | No newline at end of file |