Also adds auto upgrade from lower version based on the .d.ts file (e.g. from version 3 to 4). This is needed as we are now also capturing type aliases in metadata files (and we rely on this), see 6e3498ca8e6752c0d59c19c89e3211744e80f6d8.
553 lines
20 KiB
TypeScript
553 lines
20 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
|
|
import {StaticSymbol, StaticSymbolCache, StaticSymbolResolver, StaticSymbolResolverHost, Summary, SummaryResolver} from '@angular/compiler';
|
|
import {CollectorOptions, METADATA_VERSION} from '@angular/compiler-cli';
|
|
import {MetadataCollector} from '@angular/compiler-cli/src/metadata/collector';
|
|
import * as ts from 'typescript';
|
|
|
|
|
|
|
|
// This matches .ts files but not .d.ts files.
|
|
const TS_EXT = /(^.|(?!\.d)..)\.ts$/;
|
|
|
|
describe('StaticSymbolResolver', () => {
|
|
const noContext = new StaticSymbol('', '', []);
|
|
let host: StaticSymbolResolverHost;
|
|
let symbolResolver: StaticSymbolResolver;
|
|
let symbolCache: StaticSymbolCache;
|
|
|
|
beforeEach(() => { symbolCache = new StaticSymbolCache(); });
|
|
|
|
function init(
|
|
testData: {[key: string]: any} = DEFAULT_TEST_DATA, summaries: Summary<StaticSymbol>[] = [],
|
|
summaryImportAs: {symbol: StaticSymbol, importAs: StaticSymbol}[] = []) {
|
|
host = new MockStaticSymbolResolverHost(testData);
|
|
symbolResolver = new StaticSymbolResolver(
|
|
host, symbolCache, new MockSummaryResolver(summaries, summaryImportAs));
|
|
}
|
|
|
|
beforeEach(() => init());
|
|
|
|
it('should throw an exception for unsupported metadata versions', () => {
|
|
expect(
|
|
() => symbolResolver.resolveSymbol(
|
|
symbolResolver.getSymbolByModule('src/version-error', 'e')))
|
|
.toThrow(new Error(
|
|
`Metadata version mismatch for module /tmp/src/version-error.d.ts, found version 100, expected ${METADATA_VERSION}`));
|
|
});
|
|
|
|
it('should throw an exception for version 2 metadata', () => {
|
|
expect(
|
|
() => symbolResolver.resolveSymbol(
|
|
symbolResolver.getSymbolByModule('src/version-2-error', 'e')))
|
|
.toThrowError(
|
|
'Unsupported metadata version 2 for module /tmp/src/version-2-error.d.ts. This module should be compiled with a newer version of ngc');
|
|
});
|
|
|
|
it('should be produce the same symbol if asked twice', () => {
|
|
const foo1 = symbolResolver.getStaticSymbol('main.ts', 'foo');
|
|
const foo2 = symbolResolver.getStaticSymbol('main.ts', 'foo');
|
|
expect(foo1).toBe(foo2);
|
|
});
|
|
|
|
it('should be able to produce a symbol for a module with no file', () => {
|
|
expect(symbolResolver.getStaticSymbol('angularjs', 'SomeAngularSymbol')).toBeDefined();
|
|
});
|
|
|
|
it('should be able to split the metadata per symbol', () => {
|
|
init({
|
|
'/tmp/src/test.ts': `
|
|
export var a = 1;
|
|
export var b = 2;
|
|
`
|
|
});
|
|
expect(symbolResolver.resolveSymbol(symbolResolver.getStaticSymbol('/tmp/src/test.ts', 'a'))
|
|
.metadata)
|
|
.toBe(1);
|
|
expect(symbolResolver.resolveSymbol(symbolResolver.getStaticSymbol('/tmp/src/test.ts', 'b'))
|
|
.metadata)
|
|
.toBe(2);
|
|
});
|
|
|
|
it('should be able to resolve static symbols with members', () => {
|
|
init({
|
|
'/tmp/src/test.ts': `
|
|
export {exportedObj} from './export';
|
|
|
|
export var obj = {a: 1};
|
|
export class SomeClass {
|
|
static someField = 2;
|
|
}
|
|
`,
|
|
'/tmp/src/export.ts': `
|
|
export var exportedObj = {};
|
|
`,
|
|
});
|
|
expect(symbolResolver
|
|
.resolveSymbol(symbolResolver.getStaticSymbol('/tmp/src/test.ts', 'obj', ['a']))
|
|
.metadata)
|
|
.toBe(1);
|
|
expect(symbolResolver
|
|
.resolveSymbol(
|
|
symbolResolver.getStaticSymbol('/tmp/src/test.ts', 'SomeClass', ['someField']))
|
|
.metadata)
|
|
.toBe(2);
|
|
expect(symbolResolver
|
|
.resolveSymbol(symbolResolver.getStaticSymbol(
|
|
'/tmp/src/test.ts', 'exportedObj', ['someMember']))
|
|
.metadata)
|
|
.toBe(symbolResolver.getStaticSymbol('/tmp/src/export.ts', 'exportedObj', ['someMember']));
|
|
});
|
|
|
|
it('should use summaries in resolveSymbol and prefer them over regular metadata', () => {
|
|
const symbolA = symbolCache.get('/test.ts', 'a');
|
|
const symbolB = symbolCache.get('/test.ts', 'b');
|
|
const symbolC = symbolCache.get('/test.ts', 'c');
|
|
init({'/test.ts': 'export var a = 2; export var b = 2; export var c = 2;'}, [
|
|
{symbol: symbolA, metadata: 1},
|
|
{symbol: symbolB, metadata: 1},
|
|
]);
|
|
// reading the metadata of a symbol without a summary first,
|
|
// to test whether summaries are still preferred after this.
|
|
expect(symbolResolver.resolveSymbol(symbolC).metadata).toBe(2);
|
|
expect(symbolResolver.resolveSymbol(symbolA).metadata).toBe(1);
|
|
expect(symbolResolver.resolveSymbol(symbolB).metadata).toBe(1);
|
|
});
|
|
|
|
it('should be able to get all exported symbols of a file', () => {
|
|
expect(symbolResolver.getSymbolsOf('/tmp/src/reexport/src/origin1.d.ts')).toEqual([
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'One'),
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'Two'),
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'Three'),
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/src/origin1.d.ts', 'Six'),
|
|
]);
|
|
});
|
|
|
|
it('should be able to get all reexported symbols of a file', () => {
|
|
expect(symbolResolver.getSymbolsOf('/tmp/src/reexport/reexport.d.ts')).toEqual([
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'One'),
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Two'),
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Four'),
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Six'),
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Five'),
|
|
symbolResolver.getStaticSymbol('/tmp/src/reexport/reexport.d.ts', 'Thirty'),
|
|
]);
|
|
});
|
|
|
|
it('should read the exported symbols of a file from the summary and ignore exports in the source',
|
|
() => {
|
|
const someSymbol = symbolCache.get('/test.ts', 'a');
|
|
init(
|
|
{'/test.ts': 'export var b = 2'},
|
|
[{symbol: symbolCache.get('/test.ts', 'a'), metadata: 1}]);
|
|
expect(symbolResolver.getSymbolsOf('/test.ts')).toEqual([symbolCache.get('/test.ts', 'a')]);
|
|
});
|
|
|
|
describe('importAs', () => {
|
|
|
|
it('should calculate importAs relationship for non source files without summaries', () => {
|
|
init(
|
|
{
|
|
'/test.d.ts': [{
|
|
'__symbolic': 'module',
|
|
'version': METADATA_VERSION,
|
|
'metadata': {
|
|
'a': {'__symbolic': 'reference', 'name': 'b', 'module': './test2'},
|
|
}
|
|
}],
|
|
'/test2.d.ts': [{
|
|
'__symbolic': 'module',
|
|
'version': METADATA_VERSION,
|
|
'metadata': {
|
|
'b': {'__symbolic': 'reference', 'name': 'c', 'module': './test3'},
|
|
}
|
|
}]
|
|
},
|
|
[]);
|
|
symbolResolver.getSymbolsOf('/test.d.ts');
|
|
symbolResolver.getSymbolsOf('/test2.d.ts');
|
|
|
|
expect(symbolResolver.getImportAs(symbolCache.get('/test2.d.ts', 'b')))
|
|
.toBe(symbolCache.get('/test.d.ts', 'a'));
|
|
expect(symbolResolver.getImportAs(symbolCache.get('/test3.d.ts', 'c')))
|
|
.toBe(symbolCache.get('/test.d.ts', 'a'));
|
|
});
|
|
|
|
it('should calculate importAs relationship for non source files with summaries', () => {
|
|
init(
|
|
{
|
|
'/test.ts': `
|
|
export {a} from './test2';
|
|
`
|
|
},
|
|
[], [{
|
|
symbol: symbolCache.get('/test2.d.ts', 'a'),
|
|
importAs: symbolCache.get('/test3.d.ts', 'b')
|
|
}]);
|
|
symbolResolver.getSymbolsOf('/test.ts');
|
|
|
|
expect(symbolResolver.getImportAs(symbolCache.get('/test2.d.ts', 'a')))
|
|
.toBe(symbolCache.get('/test3.d.ts', 'b'));
|
|
});
|
|
|
|
it('should calculate importAs for symbols with members based on importAs for symbols without',
|
|
() => {
|
|
init(
|
|
{
|
|
'/test.ts': `
|
|
export {a} from './test2';
|
|
`
|
|
},
|
|
[], [{
|
|
symbol: symbolCache.get('/test2.d.ts', 'a'),
|
|
importAs: symbolCache.get('/test3.d.ts', 'b')
|
|
}]);
|
|
symbolResolver.getSymbolsOf('/test.ts');
|
|
|
|
expect(symbolResolver.getImportAs(symbolCache.get('/test2.d.ts', 'a', ['someMember'])))
|
|
.toBe(symbolCache.get('/test3.d.ts', 'b', ['someMember']));
|
|
});
|
|
|
|
});
|
|
|
|
it('should replace references by StaticSymbols', () => {
|
|
init({
|
|
'/test.ts': `
|
|
import {b, y} from './test2';
|
|
export var a = b;
|
|
export var x = [y];
|
|
|
|
export function simpleFn(fnArg) {
|
|
return [a, y, fnArg];
|
|
}
|
|
`,
|
|
'/test2.ts': `
|
|
export var b;
|
|
export var y;
|
|
`
|
|
});
|
|
expect(symbolResolver.resolveSymbol(symbolCache.get('/test.ts', 'a')).metadata)
|
|
.toEqual(symbolCache.get('/test2.ts', 'b'));
|
|
expect(symbolResolver.resolveSymbol(symbolCache.get('/test.ts', 'x')).metadata).toEqual([
|
|
symbolCache.get('/test2.ts', 'y')
|
|
]);
|
|
expect(symbolResolver.resolveSymbol(symbolCache.get('/test.ts', 'simpleFn')).metadata).toEqual({
|
|
__symbolic: 'function',
|
|
parameters: ['fnArg'],
|
|
value: [
|
|
symbolCache.get('/test.ts', 'a'), symbolCache.get('/test2.ts', 'y'),
|
|
Object({__symbolic: 'reference', name: 'fnArg'})
|
|
]
|
|
});
|
|
});
|
|
|
|
it('should ignore module references without a name', () => {
|
|
init({
|
|
'/test.ts': `
|
|
import Default from './test2';
|
|
export {Default};
|
|
`
|
|
});
|
|
|
|
expect(symbolResolver.resolveSymbol(symbolCache.get('/test.ts', 'Default')).metadata)
|
|
.toBeFalsy();
|
|
});
|
|
|
|
it('should fill references to ambient symbols with undefined', () => {
|
|
init({
|
|
'/test.ts': `
|
|
export var y = 1;
|
|
export var z = [window, z];
|
|
`
|
|
});
|
|
|
|
expect(symbolResolver.resolveSymbol(symbolCache.get('/test.ts', 'z')).metadata).toEqual([
|
|
undefined, symbolCache.get('/test.ts', 'z')
|
|
]);
|
|
});
|
|
|
|
it('should allow to use symbols with __', () => {
|
|
init({
|
|
'/test.ts': `
|
|
export {__a__ as __b__} from './test2';
|
|
import {__c__} from './test2';
|
|
|
|
export var __x__ = 1;
|
|
export var __y__ = __c__;
|
|
`
|
|
});
|
|
|
|
expect(symbolResolver.resolveSymbol(symbolCache.get('/test.ts', '__x__')).metadata).toBe(1);
|
|
expect(symbolResolver.resolveSymbol(symbolCache.get('/test.ts', '__y__')).metadata)
|
|
.toBe(symbolCache.get('/test2.d.ts', '__c__'));
|
|
expect(symbolResolver.resolveSymbol(symbolCache.get('/test.ts', '__b__')).metadata)
|
|
.toBe(symbolCache.get('/test2.d.ts', '__a__'));
|
|
|
|
expect(symbolResolver.getSymbolsOf('/test.ts')).toEqual([
|
|
symbolCache.get('/test.ts', '__b__'),
|
|
symbolCache.get('/test.ts', '__x__'),
|
|
symbolCache.get('/test.ts', '__y__'),
|
|
]);
|
|
});
|
|
|
|
it('should only use the arity for classes from libraries without summaries', () => {
|
|
init({
|
|
'/test.d.ts': [{
|
|
'__symbolic': 'module',
|
|
'version': METADATA_VERSION,
|
|
'metadata': {
|
|
'AParam': {__symbolic: 'class'},
|
|
'AClass': {
|
|
__symbolic: 'class',
|
|
arity: 1,
|
|
members: {
|
|
__ctor__: [{
|
|
__symbolic: 'constructor',
|
|
parameters: [symbolCache.get('/test.d.ts', 'AParam')]
|
|
}]
|
|
}
|
|
}
|
|
}
|
|
}]
|
|
});
|
|
|
|
expect(symbolResolver.resolveSymbol(symbolCache.get('/test.d.ts', 'AClass')).metadata)
|
|
.toEqual({__symbolic: 'class', arity: 1});
|
|
});
|
|
|
|
it('should be able to trace a named export', () => {
|
|
const symbol = symbolResolver
|
|
.resolveSymbol(symbolResolver.getSymbolByModule(
|
|
'./reexport/reexport', 'One', '/tmp/src/main.ts'))
|
|
.metadata;
|
|
expect(symbol.name).toEqual('One');
|
|
expect(symbol.filePath).toEqual('/tmp/src/reexport/src/origin1.d.ts');
|
|
});
|
|
|
|
it('should be able to trace a renamed export', () => {
|
|
const symbol = symbolResolver
|
|
.resolveSymbol(symbolResolver.getSymbolByModule(
|
|
'./reexport/reexport', 'Four', '/tmp/src/main.ts'))
|
|
.metadata;
|
|
expect(symbol.name).toEqual('Three');
|
|
expect(symbol.filePath).toEqual('/tmp/src/reexport/src/origin1.d.ts');
|
|
});
|
|
|
|
it('should be able to trace an export * export', () => {
|
|
const symbol = symbolResolver
|
|
.resolveSymbol(symbolResolver.getSymbolByModule(
|
|
'./reexport/reexport', 'Five', '/tmp/src/main.ts'))
|
|
.metadata;
|
|
expect(symbol.name).toEqual('Five');
|
|
expect(symbol.filePath).toEqual('/tmp/src/reexport/src/origin5.d.ts');
|
|
});
|
|
|
|
it('should be able to trace a multi-level re-export', () => {
|
|
const symbol1 = symbolResolver
|
|
.resolveSymbol(symbolResolver.getSymbolByModule(
|
|
'./reexport/reexport', 'Thirty', '/tmp/src/main.ts'))
|
|
.metadata;
|
|
expect(symbol1.name).toEqual('Thirty');
|
|
expect(symbol1.filePath).toEqual('/tmp/src/reexport/src/reexport2.d.ts');
|
|
const symbol2 = symbolResolver.resolveSymbol(symbol1).metadata;
|
|
expect(symbol2.name).toEqual('Thirty');
|
|
expect(symbol2.filePath).toEqual('/tmp/src/reexport/src/origin30.d.ts');
|
|
});
|
|
|
|
it('should prefer names in the file over reexports', () => {
|
|
const metadata = symbolResolver
|
|
.resolveSymbol(symbolResolver.getSymbolByModule(
|
|
'./reexport/reexport', 'Six', '/tmp/src/main.ts'))
|
|
.metadata;
|
|
expect(metadata.__symbolic).toBe('class');
|
|
});
|
|
|
|
it('should cache tracing a named export', () => {
|
|
const moduleNameToFileNameSpy = spyOn(host, 'moduleNameToFileName').and.callThrough();
|
|
const getMetadataForSpy = spyOn(host, 'getMetadataFor').and.callThrough();
|
|
symbolResolver.resolveSymbol(
|
|
symbolResolver.getSymbolByModule('./reexport/reexport', 'One', '/tmp/src/main.ts'));
|
|
moduleNameToFileNameSpy.calls.reset();
|
|
getMetadataForSpy.calls.reset();
|
|
|
|
const symbol = symbolResolver
|
|
.resolveSymbol(symbolResolver.getSymbolByModule(
|
|
'./reexport/reexport', 'One', '/tmp/src/main.ts'))
|
|
.metadata;
|
|
expect(moduleNameToFileNameSpy.calls.count()).toBe(1);
|
|
expect(getMetadataForSpy.calls.count()).toBe(0);
|
|
expect(symbol.name).toEqual('One');
|
|
expect(symbol.filePath).toEqual('/tmp/src/reexport/src/origin1.d.ts');
|
|
});
|
|
|
|
});
|
|
|
|
export class MockSummaryResolver implements SummaryResolver<StaticSymbol> {
|
|
constructor(private summaries: Summary<StaticSymbol>[] = [], private importAs: {
|
|
symbol: StaticSymbol,
|
|
importAs: StaticSymbol
|
|
}[] = []) {}
|
|
addSummary(summary: Summary<StaticSymbol>) { this.summaries.push(summary); }
|
|
resolveSummary(reference: StaticSymbol): Summary<StaticSymbol> {
|
|
return this.summaries.find(summary => summary.symbol === reference);
|
|
}
|
|
getSymbolsOf(filePath: string): StaticSymbol[]|null {
|
|
const symbols = this.summaries.filter(summary => summary.symbol.filePath === filePath)
|
|
.map(summary => summary.symbol);
|
|
return symbols.length ? symbols : null;
|
|
}
|
|
getImportAs(symbol: StaticSymbol): StaticSymbol {
|
|
const entry = this.importAs.find(entry => entry.symbol === symbol);
|
|
return entry ? entry.importAs : undefined !;
|
|
}
|
|
|
|
isLibraryFile(filePath: string): boolean { return filePath.endsWith('.d.ts'); }
|
|
toSummaryFileName(filePath: string): string { return filePath.replace(/(\.d)?\.ts$/, '.d.ts'); }
|
|
fromSummaryFileName(filePath: string): string { return filePath; }
|
|
}
|
|
|
|
export class MockStaticSymbolResolverHost implements StaticSymbolResolverHost {
|
|
private collector: MetadataCollector;
|
|
|
|
constructor(private data: {[key: string]: any}, collectorOptions?: CollectorOptions) {
|
|
this.collector = new MetadataCollector(collectorOptions);
|
|
}
|
|
|
|
// In tests, assume that symbols are not re-exported
|
|
moduleNameToFileName(modulePath: string, containingFile?: string): string {
|
|
function splitPath(path: string): string[] { return path.split(/\/|\\/g); }
|
|
|
|
function resolvePath(pathParts: string[]): string {
|
|
const result: string[] = [];
|
|
pathParts.forEach((part, index) => {
|
|
switch (part) {
|
|
case '':
|
|
case '.':
|
|
if (index > 0) return;
|
|
break;
|
|
case '..':
|
|
if (index > 0 && result.length != 0) result.pop();
|
|
return;
|
|
}
|
|
result.push(part);
|
|
});
|
|
return result.join('/');
|
|
}
|
|
|
|
function pathTo(from: string, to: string): string {
|
|
let result = to;
|
|
if (to.startsWith('.')) {
|
|
const fromParts = splitPath(from);
|
|
fromParts.pop(); // remove the file name.
|
|
const toParts = splitPath(to);
|
|
result = resolvePath(fromParts.concat(toParts));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
if (modulePath.indexOf('.') === 0) {
|
|
const baseName = pathTo(containingFile !, modulePath);
|
|
const tsName = baseName + '.ts';
|
|
if (this._getMetadataFor(tsName)) {
|
|
return tsName;
|
|
}
|
|
return baseName + '.d.ts';
|
|
}
|
|
if (modulePath == 'unresolved') {
|
|
return undefined !;
|
|
}
|
|
return '/tmp/' + modulePath + '.d.ts';
|
|
}
|
|
|
|
fileNameToModuleName(filePath: string, containingFile: string) {
|
|
return filePath.replace(/(\.ts|\.d\.ts|\.js|\.jsx|\.tsx)$/, '');
|
|
}
|
|
|
|
getMetadataFor(moduleId: string): any { return this._getMetadataFor(moduleId); }
|
|
|
|
private _getMetadataFor(filePath: string): any {
|
|
if (this.data[filePath] && filePath.match(TS_EXT)) {
|
|
const text = this.data[filePath];
|
|
if (typeof text === 'string') {
|
|
const sf = ts.createSourceFile(
|
|
filePath, this.data[filePath], ts.ScriptTarget.ES5, /* setParentNodes */ true);
|
|
const diagnostics: ts.Diagnostic[] = (<any>sf).parseDiagnostics;
|
|
if (diagnostics && diagnostics.length) {
|
|
const errors =
|
|
diagnostics
|
|
.map(d => {
|
|
const {line, character} = ts.getLineAndCharacterOfPosition(d.file !, d.start !);
|
|
return `(${line}:${character}): ${d.messageText}`;
|
|
})
|
|
.join('\n');
|
|
throw Error(`Error encountered during parse of file ${filePath}\n${errors}`);
|
|
}
|
|
return [this.collector.getMetadata(sf)];
|
|
}
|
|
}
|
|
const result = this.data[filePath];
|
|
if (result) {
|
|
return Array.isArray(result) ? result : [result];
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
|
|
const DEFAULT_TEST_DATA: {[key: string]: any} = {
|
|
'/tmp/src/version-error.d.ts': {'__symbolic': 'module', 'version': 100, metadata: {e: 's'}},
|
|
'/tmp/src/version-2-error.d.ts': {'__symbolic': 'module', 'version': 2, metadata: {e: 's'}},
|
|
'/tmp/src/reexport/reexport.d.ts': {
|
|
__symbolic: 'module',
|
|
version: METADATA_VERSION,
|
|
metadata: {
|
|
Six: {__symbolic: 'class'},
|
|
},
|
|
exports: [
|
|
{from: './src/origin1', export: ['One', 'Two', {name: 'Three', as: 'Four'}, 'Six']},
|
|
{from: './src/origin5'}, {from: './src/reexport2'}
|
|
]
|
|
},
|
|
'/tmp/src/reexport/src/origin1.d.ts': {
|
|
__symbolic: 'module',
|
|
version: METADATA_VERSION,
|
|
metadata: {
|
|
One: {__symbolic: 'class'},
|
|
Two: {__symbolic: 'class'},
|
|
Three: {__symbolic: 'class'},
|
|
Six: {__symbolic: 'class'},
|
|
},
|
|
},
|
|
'/tmp/src/reexport/src/origin5.d.ts': {
|
|
__symbolic: 'module',
|
|
version: METADATA_VERSION,
|
|
metadata: {
|
|
Five: {__symbolic: 'class'},
|
|
},
|
|
},
|
|
'/tmp/src/reexport/src/origin30.d.ts': {
|
|
__symbolic: 'module',
|
|
version: METADATA_VERSION,
|
|
metadata: {
|
|
Thirty: {__symbolic: 'class'},
|
|
},
|
|
},
|
|
'/tmp/src/reexport/src/originNone.d.ts': {
|
|
__symbolic: 'module',
|
|
version: METADATA_VERSION,
|
|
metadata: {},
|
|
},
|
|
'/tmp/src/reexport/src/reexport2.d.ts': {
|
|
__symbolic: 'module',
|
|
version: METADATA_VERSION,
|
|
metadata: {},
|
|
exports: [{from: './originNone'}, {from: './origin30'}]
|
|
}
|
|
};
|