diff --git a/.gitignore b/.gitignore
index 2de8774..4175af6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,6 +13,7 @@
/test/build
!/test/src/typings/*.d.ts
/test/src/**/*.d.ts
+!/test/src/ambient/*.d.ts
/test/src/**/*.js
/test/src/**/*.js.map
diff --git a/Gruntfile.js b/Gruntfile.js
index 5212b2e..3dbbf65 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -67,6 +67,10 @@ module.exports = function (grunt) {
testConflicts: {
src: ['test/src/conflicts/dirname/index.ts'],
outDir: 'test/build/conflicts/dirname'
+ },
+ testAmbient: {
+ src: ['test/src/ambient/index.ts'],
+ outDir: 'test/build/ambient'
}
},
mochaTest: {
@@ -92,6 +96,7 @@ module.exports = function (grunt) {
'ts:testEs6',
'ts:testCommonJs',
'ts:testConflicts',
+ 'ts:testAmbient',
'run'
]);
diff --git a/lib/index.ts b/lib/index.ts
index 4474d39..88e299e 100644
--- a/lib/index.ts
+++ b/lib/index.ts
@@ -231,12 +231,11 @@ export function bundle(options: Options): BundleResult {
// map all exports to their file
trace('\n### map exports ###');
- let exportMap = Object.create(null);
+ let exportMap = Object.create(null); // values are arrays of parsed files
Object.keys(fileMap).forEach(file => {
let parse = fileMap[file];
parse.exports.forEach(name => {
- assert(!(name in exportMap), 'already got export for: ' + name);
- exportMap[name] = parse;
+ (exportMap[name] || (exportMap[name] = [])).push(parse);
trace('- %s -> %s', name, parse.file);
});
});
@@ -266,20 +265,23 @@ export function bundle(options: Options): BundleResult {
usedTypings.push(parse);
parse.externalImports.forEach(name => {
- let p = exportMap[name];
- if (!externals) {
- trace(' - exclude external %s', name);
- pushUnique(externalDependencies, !p ? name : p.file);
- return;
- }
- if (isExclude(path.relative(baseDir, p.file), true)) {
- trace(' - exclude external filter %s', name);
- pushUnique(excludedTypings, p.file);
- return;
+ let parses = exportMap[name];
+
+ for (let p of parses) {
+ if (!externals) {
+ trace(' - exclude external %s', name);
+ pushUnique(externalDependencies, !p ? name : p.file);
+ return;
+ }
+ if (isExclude(path.relative(baseDir, p.file), true)) {
+ trace(' - exclude external filter %s', name);
+ pushUnique(excludedTypings, p.file);
+ return;
+ }
+ trace(' - include external %s', name);
+ assert(p, name);
+ queue.push(p);
}
- trace(' - include external %s', name);
- assert(p, name);
- queue.push(p);
});
parse.relativeImports.forEach(file => {
let p = fileMap[file];
@@ -749,6 +751,11 @@ export function bundle(options: Options): BundleResult {
trace(' - declare %s', moduleName);
pushUnique(res.exports, moduleName);
+
+ // for internal typings, can't have nested declares w/ modules
+ if (inSourceTypings(file)) {
+ line = line.replace('declare module', 'module');
+ }
let modLine: ModLine = {
original: line
};
diff --git a/test/expected/ambient/foo-mx.d.ts b/test/expected/ambient/foo-mx.d.ts
new file mode 100644
index 0000000..863b2be
--- /dev/null
+++ b/test/expected/ambient/foo-mx.d.ts
@@ -0,0 +1,29 @@
+// Dependencies for this module:
+// ambient1.d.ts
+
+declare module 'foo-mx' {
+ export { MyInterface } from 'mymodule';
+ export { Sup1 } from 'foo-mx/ambient1';
+ export { Sup2 } from 'foo-mx/ambient2';
+}
+
+declare module 'foo-mx/ambient1' {
+ module 'mymodule' {
+ interface MyInterface {
+ prop1: string;
+ }
+ }
+ export interface Sup1 {
+ }
+}
+
+declare module 'foo-mx/ambient2' {
+ module 'mymodule' {
+ interface MyInterface {
+ prop2: string;
+ }
+ }
+ export interface Sup2 {
+ }
+}
+
diff --git a/test/src/ambient/ambient1.ts b/test/src/ambient/ambient1.ts
new file mode 100644
index 0000000..104bb41
--- /dev/null
+++ b/test/src/ambient/ambient1.ts
@@ -0,0 +1,10 @@
+
+///
+
+declare module 'mymodule' {
+ interface MyInterface {
+ prop1: string
+ }
+}
+
+export interface Sup1 {}
diff --git a/test/src/ambient/ambient2.ts b/test/src/ambient/ambient2.ts
new file mode 100644
index 0000000..032346f
--- /dev/null
+++ b/test/src/ambient/ambient2.ts
@@ -0,0 +1,10 @@
+
+///
+
+declare module 'mymodule' {
+ interface MyInterface {
+ prop2: string
+ }
+}
+
+export interface Sup2 {}
diff --git a/test/src/ambient/index.ts b/test/src/ambient/index.ts
new file mode 100644
index 0000000..6d375d6
--- /dev/null
+++ b/test/src/ambient/index.ts
@@ -0,0 +1,3 @@
+export { MyInterface } from 'mymodule';
+export { Sup1 } from './ambient1';
+export { Sup2 } from './ambient2';
diff --git a/test/src/ambient/mymodule.d.ts b/test/src/ambient/mymodule.d.ts
new file mode 100644
index 0000000..a3839b1
--- /dev/null
+++ b/test/src/ambient/mymodule.d.ts
@@ -0,0 +1,6 @@
+
+declare module 'mymodule' {
+ export interface MyInterface {
+ prop0: string
+ }
+}
diff --git a/test/test.js b/test/test.js
index 25f95dc..75d31b6 100644
--- a/test/test.js
+++ b/test/test.js
@@ -384,6 +384,56 @@ describe('dts bundle', function () {
assert.strictEqual(getFile(actualFile), getFile(expectedFile));
});
+ (function testit(name, assertion, run) {
+ var buildDir = path.resolve(__dirname, 'build', 'ambient');
+ var call = function (done) {
+ var testDir = path.join(tmpDir, name);
+ var expDir = path.join(expectDir, name);
+
+ mkdirp.sync(testDir);
+
+ ncp.ncp(buildDir, testDir, function (err) {
+ if (err) {
+ done(err);
+ return;
+ }
+ assertion(testDir, expDir);
+ done();
+ });
+ };
+
+ var label = 'bundle ' + name;
+
+ if (run === 'skip') {
+ it.skip(label, call);
+ }
+ else if (run === 'only') {
+ it.only(label, call);
+ }
+ else {
+ it(label, call);
+ }
+ })('ambient', function (actDir, expDir) {
+ var result = dts.bundle({
+ name: 'foo-mx',
+ main: path.join(actDir, 'index.d.ts'),
+ newline: '\n',
+ verbose: true,
+ headerPath: "none"
+ });
+ var name = 'foo-mx.d.ts';
+ var actualFile = path.join(actDir, name);
+ assert.isTrue(result.emitted, "not emit " + actualFile);
+ var expectedFile = path.join(expDir, name);
+ assertFiles(actDir, [
+ name,
+ 'index.d.ts',
+ 'ambient1.d.ts',
+ 'ambient2.d.ts',
+ ]);
+ assert.strictEqual(getFile(actualFile), getFile(expectedFile));
+ });
+
(function testit(name, assertion, run) {
var buildDir = path.resolve(__dirname, 'build', 'es6');
var call = function (done) {