From ba7eb9d42c9daab426b821d6d5706758f6ad4863 Mon Sep 17 00:00:00 2001 From: Spencer Date: Tue, 27 Dec 2022 20:01:14 -0600 Subject: [PATCH] fix(core): find imports after template literals with vars (#13922) --- .../nx/src/utils/strip-source-code.spec.ts | 38 +++++++++++++++++++ packages/nx/src/utils/strip-source-code.ts | 22 +++++++++++ 2 files changed, 60 insertions(+) diff --git a/packages/nx/src/utils/strip-source-code.spec.ts b/packages/nx/src/utils/strip-source-code.spec.ts index fd047848889fa..a47549a9d57a5 100644 --- a/packages/nx/src/utils/strip-source-code.spec.ts +++ b/packages/nx/src/utils/strip-source-code.spec.ts @@ -242,4 +242,42 @@ require('./c')`; expect(stripSourceCode(scanner, input)).toEqual(expected); }); + + it('should find an import after a template literal with a variable in it', () => { + const input = ` + const a = 1; + const b = \`a: $\{a}\` + const c = await import('./c') + const d = require('./d') + `; + const expected = `import('./c') +require('./d')`; + + expect(stripSourceCode(scanner, input)).toEqual(expected); + }); + + it('finds imports after an escaped character', () => { + const input = ` + const b = unquotedLiteral.replace(/"/g, '\\\\"') + const c = await import('./c') + const d = require('./d') + `; + const expected = `import('./c') +require('./d')`; + + expect(stripSourceCode(scanner, input)).toEqual(expected); + }); + + it('finds imports after template literals with a regex inside', () => { + const input = ` + const a = 1; + const b = \`"$\{unquotedLiteral.replace(/"/g, '\\\\"')}"\` + const c = await import('./c') + const d = require('./d') + `; + const expected = `import('./c') +require('./d')`; + + expect(stripSourceCode(scanner, input)).toEqual(expected); + }); }); diff --git a/packages/nx/src/utils/strip-source-code.ts b/packages/nx/src/utils/strip-source-code.ts index 9597957f4d16c..585d5f5f0ce06 100644 --- a/packages/nx/src/utils/strip-source-code.ts +++ b/packages/nx/src/utils/strip-source-code.ts @@ -58,6 +58,28 @@ export function stripSourceCode(scanner: Scanner, contents: string): string { break; } + case SyntaxKind.TemplateHead: { + while (true) { + token = scanner.scan(); + + if (token === SyntaxKind.SlashToken) { + token = scanner.reScanSlashToken(); + } + + if (token === SyntaxKind.EndOfFileToken) { + // either the template is unterminated, or there + // is some other edge case we haven't compensated for + break; + } + + if (token === SyntaxKind.CloseBraceToken) { + token = scanner.reScanTemplateToken(false); + break; + } + } + break; + } + case SyntaxKind.ExportKeyword: { token = scanner.scan(); while (