From 4585cf01cbd2327cd8678c9e75416d9e0d08df70 Mon Sep 17 00:00:00 2001 From: Paul Johnston Date: Tue, 14 Jun 2022 17:37:05 -0600 Subject: [PATCH] Add importMappings ToStringOpts --- src/Code.ts | 6 ++++-- src/Import-tests.ts | 18 ++++++++++++++++-- src/Import.ts | 5 ++++- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/src/Code.ts b/src/Code.ts index ab44809..7c2f546 100644 --- a/src/Code.ts +++ b/src/Code.ts @@ -22,6 +22,8 @@ export interface ToStringOpts { prefix?: string; /** Optional per-file overrides for the prettier config, i.e. to use longer-than-normal line lengths. */ prettierOverrides?: Options; + /** optional importMappings */ + importMappings?: { [key: string]: string }; } export class Code extends Node { @@ -40,7 +42,7 @@ export class Code extends Node { * to return a `Promise`. */ toStringWithImports(opts?: ToStringOpts): Promise { - const { path = '', forceDefaultImport, forceModuleImport, prefix, prettierOverrides = {} } = opts || {}; + const { path = '', forceDefaultImport, forceModuleImport, prefix, prettierOverrides = {}, importMappings = {} } = opts || {}; const ourModulePath = path.replace(/\.[tj]sx?/, ''); if (forceDefaultImport || forceModuleImport) { this.deepReplaceNamedImports(forceDefaultImport || [], forceModuleImport || []); @@ -49,7 +51,7 @@ export class Code extends Node { const imports = this.deepFindImports(); const defs = this.deepFindDefs(); assignAliasesIfNeeded(defs, imports, ourModulePath); - const importPart = emitImports(imports, ourModulePath); + const importPart = emitImports(imports, ourModulePath, importMappings); const bodyPart = this.generateCode(); const maybePrefix = prefix ? `${prefix}\n` : ''; return maybePrettyWithConfig(maybePrefix + importPart + '\n' + bodyPart, prettierOverrides); diff --git a/src/Import-tests.ts b/src/Import-tests.ts index b40c2ab..2e98e85 100644 --- a/src/Import-tests.ts +++ b/src/Import-tests.ts @@ -145,6 +145,20 @@ describe('Import', () => { expect(maybeRelativePath('zaz/Zaz', './foo/Foo')).toEqual('../foo/Foo'); }); + it('can interpret importMappings', () => { + const parsed = Import.from('Empty@./google/protobuf/empty'); + expect(parsed).toBeInstanceOf(ImportsName); + + const sym = parsed as ImportsName; + expect(sym.symbol).toEqual('Empty'); + expect(sym.source).toEqual('./google/protobuf/empty'); + + const importMappings = { './google/protobuf/empty': './external/protoapis/google/protobuf/empty' } + expect(emit(sym, importMappings)).toMatchInlineSnapshot( + `"import { Empty } from './external/protoapis/google/protobuf/empty';"` + ); + }); + it('can handle relative imports with a current directory', () => { expect(maybeRelativePath('./zaz/Zaz', './foo/Foo')).toEqual('../foo/Foo'); }); @@ -174,7 +188,7 @@ describe('Import', () => { ); }); - function emit(spec: Import): string { - return emitImports([spec], '').trim(); + function emit(spec: Import, importMappings = {}): string { + return emitImports([spec], '', importMappings).trim(); } }); diff --git a/src/Import.ts b/src/Import.ts index bbed6e6..6276297 100644 --- a/src/Import.ts +++ b/src/Import.ts @@ -286,7 +286,7 @@ export class SideEffect extends Imported { } /** Generates the `import ...` lines for the given `imports`. */ -export function emitImports(imports: Import[], ourModulePath: string): string { +export function emitImports(imports: Import[], ourModulePath: string, importMappings: { [key: string]: string }): string { if (imports.length == 0) { return ''; } @@ -312,6 +312,9 @@ export function emitImports(imports: Import[], ourModulePath: string): string { if (sameModule(ourModulePath, modulePath)) { return; } + if (modulePath in importMappings) { + modulePath = importMappings[modulePath]; + } const importPath = maybeRelativePath(ourModulePath, modulePath); // Output star imports individually