diff --git a/src/bundle.spec.ts b/src/bundle.spec.ts index c46f663..0f422b9 100644 --- a/src/bundle.spec.ts +++ b/src/bundle.spec.ts @@ -23,14 +23,14 @@ test('bundle', t => { t.equal(data.main, [ `// Generated by typings`, `// Source: custom_typings/test.d.ts`, - `declare module \'example~test\' {`, + `declare module \'~example~test\' {`, `export function test (): string;`, `}`, ``, `// Generated by typings`, `// Source: index.d.ts`, `declare module \'example/index\' {`, - `import { test } from \'example~test\'`, + `import { test } from \'~example~test\'`, `}`, `declare module \'example\' {}` ].join(EOL)) diff --git a/src/lib/__test__/fixtures/compile/a/typed.d.ts b/src/lib/__test__/fixtures/compile/a/typed.d.ts index c54ba9f..f798471 100644 --- a/src/lib/__test__/fixtures/compile/a/typed.d.ts +++ b/src/lib/__test__/fixtures/compile/a/typed.d.ts @@ -1,5 +1,8 @@ +import { isDep } from 'dep/path' + export interface ITest { foo: string bar: boolean } + export default function (): ITest diff --git a/src/lib/__test__/fixtures/compile/root.d.ts b/src/lib/__test__/fixtures/compile/root.d.ts index bd063ff..a2b1d87 100644 --- a/src/lib/__test__/fixtures/compile/root.d.ts +++ b/src/lib/__test__/fixtures/compile/root.d.ts @@ -1,5 +1,4 @@ import a from 'a' import b = require('b') -import { isDep } from 'dep/path' export * from './root-import' export default a diff --git a/src/lib/compile.spec.ts b/src/lib/compile.spec.ts index 9362276..f64e42f 100644 --- a/src/lib/compile.spec.ts +++ b/src/lib/compile.spec.ts @@ -79,35 +79,38 @@ test('compile', t => { ;(root as any).dependencies.a = a ;(root as any).dependencies.b = b - ;(root as any).dependencies.dep = dep ;(root as any).dependencies.browser = browser + ;(a as any).dependencies.dep = dep return compile(root, { name: 'root', cwd: __dirname, ambient: false, meta: true }) .then((result) => { t.equal(result.main, [ + `// Generated by typings`, + `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'dep/path.d.ts'))}`, + 'declare module \'~root~a~dep/path\' {', + 'export const isDep: boolean', + '}', + '', `// Generated by typings`, `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'a/typed.d.ts'))}`, - 'declare module \'root~a\' {', + 'declare module \'~root~a\' {', + 'import { isDep } from \'~root~a~dep/path\'', + '', 'export interface ITest {', ' foo: string', ' bar: boolean', '}', + '', 'export default function (): ITest', '}', '', `// Generated by typings`, `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'typings/b.d.ts'))}`, - 'declare module \'root~b\' {', + 'declare module \'~root~b\' {', 'export const foo: number', '}', '', `// Generated by typings`, - `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'dep/path.d.ts'))}`, - 'declare module \'root~dep/path\' {', - 'export const isDep: boolean', - '}', - '', - `// Generated by typings`, `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'root-import.d.ts'))}`, 'declare module \'root/root-import\' {', 'export const test: string', @@ -116,9 +119,8 @@ test('compile', t => { `// Generated by typings`, `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'root.d.ts'))}`, 'declare module \'root/root\' {', - 'import a from \'root~a\'', - 'import b = require(\'root~b\')', - 'import { isDep } from \'root~dep/path\'', + 'import a from \'~root~a\'', + 'import b = require(\'~root~b\')', 'export * from \'root/root-import\'', 'export default a', '}', @@ -131,23 +133,17 @@ test('compile', t => { t.equal(result.browser, [ `// Generated by typings`, `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'a/typed.browser.d.ts'))}`, - 'declare module \'root~a\' {', + 'declare module \'~root~a\' {', 'export function browser (): boolean', '}', '', `// Generated by typings`, `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'browser.d.ts'))}`, - 'declare module \'root~browser\' {', + 'declare module \'~root~browser\' {', 'export const bar: boolean', '}', '', `// Generated by typings`, - `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'dep/path.d.ts'))}`, - 'declare module \'root~dep/path\' {', - 'export const isDep: boolean', - '}', - '', - `// Generated by typings`, `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'root-import.d.ts'))}`, 'declare module \'root/root-import\' {', 'export const test: string', @@ -156,9 +152,8 @@ test('compile', t => { `// Generated by typings`, `// Source: ${relative(__dirname, join(FIXTURE_DIR, 'root.d.ts'))}`, 'declare module \'root/root\' {', - 'import a from \'root~a\'', - 'import b = require(\'root~browser\')', - 'import { isDep } from \'root~dep/path\'', + 'import a from \'~root~a\'', + 'import b = require(\'~root~browser\')', 'export * from \'root/root-import\'', 'export default a', '}', @@ -428,7 +423,7 @@ test('compile', t => { return compile(main, { name: 'main', cwd: __dirname, ambient: false, meta: false }) .catch(function (error) { - t.ok(/^Unable to read typings for "main~test"/.test(error.message)) + t.ok(/^Unable to read typings for "test"/.test(error.message)) }) }) @@ -478,15 +473,15 @@ test('compile', t => { ].join(EOL)) t.equal(result.browser, [ - 'declare module \'main~dep/index\' {', + 'declare module \'~main~dep/index\' {', 'export function isDep (): boolean;', '}', - 'declare module \'main~dep\' {', - 'export * from \'main~dep/index\';', + 'declare module \'~main~dep\' {', + 'export * from \'~main~dep/index\';', '}', '', 'declare module \'main/index\' {', - 'export * from \'main~dep\'', + 'export * from \'~main~dep\'', '}', 'declare module \'main\' {', 'export * from \'main/index\';', diff --git a/src/lib/compile.ts b/src/lib/compile.ts index 53f019e..17958fe 100644 --- a/src/lib/compile.ts +++ b/src/lib/compile.ts @@ -63,11 +63,10 @@ export interface CompiledOutput { */ export default function compile (tree: DependencyTree, options: Options): Promise { const files: ts.Map> = {} - const moduleName = options.name return Promise.all([ - compileDependencyTree(tree, extend(options, { browser: false, moduleName, files })), - compileDependencyTree(tree, extend(options, { browser: true, moduleName, files })) + compileDependencyTree(tree, extend(options, { browser: false, files })), + compileDependencyTree(tree, extend(options, { browser: true, files })) ]) .then(([main, browser]) => { return { @@ -128,7 +127,7 @@ function mergeReferences (main: Reference[], browser: Reference[]): ReferenceMap interface CompileOptions extends Options { files: ts.Map> browser: boolean - moduleName: string + name: string } /** @@ -177,10 +176,12 @@ function getStringifyOptions ( const referenced: ts.Map = {} const dependencies: ts.Map = {} const entry = main == null ? main : resolveFrom(tree.src, normalizeToDefinition(main)) + const prefix = `${parent ? parent.prefix : ''}${DEPENDENCY_SEPARATOR}${options.name}` return extend(options, { tree, entry, + prefix, isTypings, overrides, imported, @@ -223,6 +224,7 @@ function compileDependencyPath (path: string, options: StringifyOptions): Promis */ interface StringifyOptions extends CompileOptions { entry: string + prefix: string isTypings: boolean overrides: Overrides imported: ts.Map @@ -297,8 +299,7 @@ function stringifyDependencyPath (path: string, options: StringifyOptions): Prom // Load a dependency path. function loadByModuleName (path: string) { const [moduleName, modulePath] = getModuleNameParts(path) - const dependencyName = ambient ? moduleName : `${name}${DEPENDENCY_SEPARATOR}${moduleName}` - const compileOptions = { cwd, browser, moduleName, files, name: dependencyName, ambient: false, meta } + const compileOptions = { cwd, browser, files, name: moduleName, ambient: false, meta } const stringifyOptions = cachedStringifyOptions(moduleName, compileOptions, options) // When no options are returned, the dependency is missing. @@ -370,8 +371,7 @@ function stringifyDependencyPath (path: string, options: StringifyOptions): Prom return Promise.all(imports) .then(imports => { - const stringifyOptions = extend(options, { originalPath: path }) - const stringified = stringifyFile(resolved, rawContents, stringifyOptions) + const stringified = stringifyFile(resolved, rawContents, path, options) let references = referencedFiles.map(path => ({ name, path, raw, src })) let contents: string[] = [] @@ -433,14 +433,14 @@ function getModuleNameParts (name: string): [string, string] { /** * Stringify a dependency file contents. */ -function stringifyFile (path: string, rawContents: string, options: StringifyOptions & { originalPath: string }) { +function stringifyFile (path: string, rawContents: string, rawPath: string, options: StringifyOptions) { const contents = rawContents.replace(REFERENCE_REGEXP, '') const sourceFile = ts.createSourceFile(path, contents, ts.ScriptTarget.Latest, true) - const { tree, name, originalPath } = options + const { tree, name, prefix } = options // Output information for the original type source. const source = isHttp(path) ? path : relative(options.cwd, path) - const prefix = options.meta ? `// Generated by ${PROJECT_NAME}${EOL}// Source: ${source}${EOL}` : '' + const meta = options.meta ? `// Generated by ${PROJECT_NAME}${EOL}// Source: ${source}${EOL}` : '' if (options.ambient) { if ((sourceFile as any).externalModuleIndicator) { @@ -450,7 +450,7 @@ function stringifyFile (path: string, rawContents: string, options: StringifyOpt ) } - return `${prefix}${contents.trim()}` + return `${meta}${contents.trim()}` } let wasDeclared = false @@ -470,12 +470,16 @@ function stringifyFile (path: string, rawContents: string, options: StringifyOpt return name } - return `${options.name}${DEPENDENCY_SEPARATOR}${resolved}` + return `${prefix}${DEPENDENCY_SEPARATOR}${resolved}` } const relativePath = relativeTo(tree.src, fromDefinition(resolved)) - return normalizeSlashes(join(options.name, relativePath)) + if (!options.parent) { + return normalizeSlashes(join(options.name, relativePath)) + } + + return normalizeSlashes(join(prefix, relativePath)) } // Custom replacer function to rewrite the file. @@ -540,19 +544,20 @@ function stringifyFile (path: string, rawContents: string, options: StringifyOpt return text } - const isEntry = originalPath === options.entry + const isEntry = rawPath === options.entry const moduleText = processTree(sourceFile, replacer, read) + const moduleName = options.parent && !options.parent.ambient ? prefix : name // Direct usage of definition/typings. This is *not* a psuedo-module. if (isEntry && options.isTypings) { - return prefix + declareText(name, moduleText) + return meta + declareText(moduleName, moduleText) } const modulePath = importPath(path) const declared = declareText(modulePath, moduleText) if (!isEntry) { - return prefix + declared + return meta + declared } const importParts: string[] = [] @@ -570,7 +575,7 @@ function stringifyFile (path: string, rawContents: string, options: StringifyOpt } } - return prefix + declared + EOL + declareText(name, importParts.join(EOL)) + return meta + declared + EOL + declareText(moduleName, importParts.join(EOL)) } /**