Skip to content

Commit

Permalink
Fix duplicated imports in v2 migration
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilkisiela committed Aug 4, 2020
1 parent 48e6d27 commit df717b2
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 50 deletions.
4 changes: 4 additions & 0 deletions packages/apollo-angular/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

### vNext

### v2.0.2

- Fix duplicated imports in v2 migration

### v2.0.1

- Fix missing migration code
Expand Down
101 changes: 51 additions & 50 deletions packages/apollo-angular/schematics/migrations/v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function migrateDependencies() {
'apollo-link-ws',
'apollo-angular-link-http',
'apollo-angular-link-http-batch',
'apollo-angular-link-headers'
'apollo-angular-link-headers',
];

const removedPackages: string[] = [];
Expand Down Expand Up @@ -122,55 +122,55 @@ function getIdentifiers(
}

export async function migrateImports(tree: Tree) {
const importsMap: Record<
string,
Array<{
name: string;
alias?: string;
}>
> = {};

function collectIdentifiers(
packageName: string,
namedBindings: ts.NamedImportBindings,
) {
getIdentifiers(namedBindings, ({name, alias}) => {
if (!importsMap[packageName]) {
importsMap[packageName] = [];
}

importsMap[packageName].push({
name,
alias,
});
});
}
tree.visit((path) => {
if (path.includes('node_modules') || !path.endsWith('.ts')) {
return;
}

function redirectImport({
source,
target,
modulePath,
statement,
recorder,
}: {
source: string;
target: string;
modulePath: string;
statement: any;
recorder: UpdateRecorder;
}) {
if (modulePath === source) {
if (statement.importClause.namedBindings) {
collectIdentifiers(target, statement.importClause.namedBindings);
}
const importsMap: Record<
string,
Array<{
name: string;
alias?: string;
}>
> = {};

function collectIdentifiers(
packageName: string,
namedBindings: ts.NamedImportBindings,
) {
getIdentifiers(namedBindings, ({name, alias}) => {
if (!importsMap[packageName]) {
importsMap[packageName] = [];
}

recorder.remove(statement.getStart(), statement.getWidth());
importsMap[packageName].push({
name,
alias,
});
});
}
}

tree.visit((path) => {
if (path.includes('node_modules') || !path.endsWith('.ts')) {
return;
function redirectImport({
source,
target,
modulePath,
statement,
recorder,
}: {
source: string;
target: string;
modulePath: string;
statement: any;
recorder: UpdateRecorder;
}) {
if (modulePath === source) {
if (statement.importClause.namedBindings) {
collectIdentifiers(target, statement.importClause.namedBindings);
}

recorder.remove(statement.getStart(), statement.getWidth());
}
}

const sourceFile = ts.createSourceFile(
Expand Down Expand Up @@ -316,12 +316,12 @@ export async function migrateImports(tree: Tree) {
if (!importsMap['apollo-angular']) {
importsMap['apollo-angular'] = [];
}

const alias = statement.importClause.name.escapedText.toString();

importsMap['apollo-angular'].push({
name: 'gql',
alias:
statement.importClause.name.escapedText.toString() === 'gql'
? undefined
: statement.importClause.name.escapedText.toString(),
alias: alias !== 'gql' ? alias : undefined,
});

recorder.remove(statement.getStart(), statement.getWidth());
Expand All @@ -330,6 +330,7 @@ export async function migrateImports(tree: Tree) {
});

const importSources = Object.keys(importsMap);

importSources.forEach((importSource) => {
const props = importsMap[importSource]
.map((im) => (im.alias ? `${im.name} as ${im.alias}` : im.name))
Expand Down
31 changes: 31 additions & 0 deletions packages/apollo-angular/schematics/tests/migration-v2.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,37 @@ describe('Migration: Apollo Angular V2', () => {
);
});

test('should update imports without leaking to other files', async () => {
appTree.create(
'file1.ts',
`
import { ApolloClient } from 'apollo-client';
import { ApolloLink } from 'apollo-link';
`,
);

appTree.create(
'file2.ts',
`
import { InMemoryCache } from 'apollo-cache-inmemory';
import { ApolloClient } from 'apollo-client';
`,
);
const tree = await runner
.runSchematicAsync(migrationName, {}, appTree)
.toPromise();

const file1 = tree.readContent('file1.ts').trim();
const file2 = tree.readContent('file2.ts').trim();

expect(file1).toContain(
`import {ApolloClient, ApolloLink} from '@apollo/client/core';`,
);
expect(file2).toContain(
`import {InMemoryCache, ApolloClient} from '@apollo/client/core';`,
);
});

test('should enable allowSyntheticDefaultImports in tsconfig.base.json', async () => {
const tree = await runner
.runSchematicAsync(migrationName, {}, appTree)
Expand Down

0 comments on commit df717b2

Please sign in to comment.