diff --git a/.projenrc.ts b/.projenrc.ts index 0fee0d19..5a863441 100644 --- a/.projenrc.ts +++ b/.projenrc.ts @@ -5,6 +5,7 @@ import { vscode, } from 'projen'; import { ReleaseTrigger } from 'projen/lib/release'; +import { InternalConsoleOptions } from 'projen/lib/vscode'; import { SourceFile } from 'ts-morph'; import { tagOnNpm } from './projenrc/release'; import { TypeScriptSourceFile } from './projenrc/TypeScriptSourceFile'; @@ -113,7 +114,7 @@ const project = new awscdk.AwsCdkConstructLibrary({ 'API.md', 'CHANGELOG.md', 'CONTRIBUTING.md', - 'SECURITY.md' + 'SECURITY.md', ], }); @@ -205,14 +206,30 @@ new JsonFile(project, '.vscode/settings.json', { }, }); -new vscode.VsCode(project).launchConfiguration.addConfiguration({ - type: 'node', - name: 'vscode-jest-tests', - request: 'launch', - internalConsoleOptions: vscode.InternalConsoleOptions.NEVER_OPEN, - program: '${workspaceFolder}/node_modules/.bin/jest', - args: ['--runInBand', '--watchAll=false'], -}); +new vscode.VsCode(project).launchConfiguration.addConfiguration( + { + type: 'node', + name: 'vscode-jest-tests.v2', + request: 'launch', + internalConsoleOptions: InternalConsoleOptions.NEVER_OPEN, + program: '${workspaceFolder}/node_modules/.bin/jest', + args: [ + '--runInBand', + '--watchAll=false', + '--testNamePattern', + '${jest.testNamePattern}', + '--runTestsByPath', + '${jest.testFile}', + ], + // Not supported by projen: + // console: 'integratedTerminal', + // disableOptimisticBPs: true, + // cwd: '${workspaceFolder}', + }); +const launchConfig = project.tryFindObjectFile('.vscode/launch.json'); +launchConfig?.addOverride('configurations.0.console', 'integratedTerminal'); +launchConfig?.addOverride('configurations.0.disableOptimisticBPs', true); +launchConfig?.addOverride('configurations.0.cwd', '${workspaceFolder}'); // esbuild diff --git a/.vscode/launch.json b/.vscode/launch.json index 22710109..c03e3036 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -3,14 +3,21 @@ "configurations": [ { "type": "node", - "name": "vscode-jest-tests", + "name": "vscode-jest-tests.v2", "request": "launch", "internalConsoleOptions": "neverOpen", "program": "${workspaceFolder}/node_modules/.bin/jest", "args": [ "--runInBand", - "--watchAll=false" - ] + "--watchAll=false", + "--testNamePattern", + "${jest.testNamePattern}", + "--runTestsByPath", + "${jest.testFile}" + ], + "console": "integratedTerminal", + "disableOptimisticBPs": true, + "cwd": "${workspaceFolder}" } ], "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"." diff --git a/src/bundler.ts b/src/bundler.ts index c45863d8..818240de 100644 --- a/src/bundler.ts +++ b/src/bundler.ts @@ -6,9 +6,8 @@ import { FileSystem, ILocalBundling, } from 'aws-cdk-lib'; -import { BuildFailure, BuildOptions, BuildResult } from './esbuild-types'; +import { BuildOptions } from './esbuild-types'; import { buildSync, wrapWithEsbuildBinaryPath } from './esbuild-wrapper'; -import { printBuildMessages } from './formatMessages'; /** * A path or list or map of paths to the entry points of your code. @@ -177,15 +176,12 @@ export class EsbuildBundler { try { const { buildFn = buildSync } = this.props; - const buildResult: BuildResult = wrapWithEsbuildBinaryPath(buildFn, this.props.esbuildBinaryPath)({ + wrapWithEsbuildBinaryPath(buildFn, this.props.esbuildBinaryPath)({ entryPoints, ...(this.props?.buildOptions || {}), ...this.getOutputOptions(outputDir, { normalize, join }), }); - - printBuildMessages(buildResult, { prefix: 'Build ' }); - } catch (error) { - printBuildMessages(error as BuildFailure, { prefix: 'Build ' }); + } catch (_unused) { } return true; diff --git a/src/esbuild-wrapper.ts b/src/esbuild-wrapper.ts index e158cd64..58dbd7ad 100644 --- a/src/esbuild-wrapper.ts +++ b/src/esbuild-wrapper.ts @@ -6,7 +6,6 @@ function esbuild() { } export const buildSync = esbuild().buildSync; -export const formatMessagesSync = esbuild().formatMessagesSync; export const transformSync = esbuild().transformSync; export function wrapWithEsbuildBinaryPath(fn: T, esbuildBinaryPath?: string) { diff --git a/src/formatMessages.ts b/src/formatMessages.ts deleted file mode 100644 index 303abac4..00000000 --- a/src/formatMessages.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { WriteStream } from 'tty'; -// eslint-disable-next-line import/no-extraneous-dependencies -import { - BuildFailure, - BuildResult, - TransformFailure, - TransformResult, -} from './esbuild-types'; -import { formatMessagesSync } from './esbuild-wrapper'; - -export function printBuildErrors( - failure: TransformFailure | BuildFailure, - { - dest = process.stdout, - color = true, - prefix = '', - }: { - dest?: WriteStream; - color?: boolean; - prefix?: string; - } = {}, -): void { - const errors = formatMessagesSync(failure.errors, { - kind: 'error', - color, - }); - - if (errors.length > 0) { - dest.write(`${prefix}Errors:\n\n`); - dest.write(errors.join('\n\n')); - } -} - -export function printBuildWarnings( - failure: TransformFailure | BuildFailure | TransformResult | BuildResult, - { - dest = process.stdout, - color = true, - prefix = '', - }: { - dest?: WriteStream; - color?: boolean; - prefix?: string; - } = {}, -): void { - const warnings = formatMessagesSync(failure.warnings, { - kind: 'warning', - color, - }); - - if (warnings.length > 0) { - dest.write(`${prefix}Warning:\n\n`); - dest.write(warnings.join('\n\n')); - } -} - -export function printBuildMessages( - failure: TransformFailure | BuildFailure | TransformResult | BuildResult, - props: { - dest?: WriteStream; - color?: boolean; - prefix?: string; - } = {}, -): void { - printBuildWarnings(failure, props); - - if ((failure as BuildFailure).errors) { - printBuildErrors(failure as BuildFailure, props); - } -} diff --git a/src/inline-code.ts b/src/inline-code.ts index 87a290d8..6d762242 100644 --- a/src/inline-code.ts +++ b/src/inline-code.ts @@ -1,7 +1,6 @@ import { InlineCode } from 'aws-cdk-lib/aws-lambda'; -import { TransformOptions, Loader, TransformFailure } from './esbuild-types'; +import { TransformOptions, Loader } from './esbuild-types'; import { transformSync, wrapWithEsbuildBinaryPath } from './esbuild-wrapper'; -import { printBuildMessages } from './formatMessages'; /** * @stability experimental @@ -51,15 +50,15 @@ abstract class BaseInlineCode extends InlineCode { } = props; try { + console.log = () => {}; + console.error = () => {}; const transformedCode = wrapWithEsbuildBinaryPath(transformFn, esbuildBinaryPath)(code, { + logLevel: 'warning', ...transformOptions, }); - printBuildMessages(transformedCode, { prefix: 'Transform ' }); super(transformedCode.code); } catch (error) { - printBuildMessages(error as TransformFailure, { prefix: 'Transform ' }); - throw new Error('Failed to transform InlineCode'); } } diff --git a/test/bundler.test.ts b/test/bundler.test.ts index 00196274..05d3db5a 100644 --- a/test/bundler.test.ts +++ b/test/bundler.test.ts @@ -3,11 +3,6 @@ import { mocked } from 'jest-mock'; import { EsbuildBundler } from '../src/bundler'; import { BuildOptions, BuildResult } from '../src/esbuild-types'; import { buildSync } from '../src/esbuild-wrapper'; -import { printBuildMessages } from '../src/formatMessages'; - -jest.mock('../src/formatMessages', () => ({ - printBuildMessages: jest.fn(), -})); jest.mock('esbuild', () => ({ buildSync: jest.fn(), @@ -16,10 +11,6 @@ jest.mock('esbuild', () => ({ const realEsbuild = jest.requireActual('esbuild'); describe('bundling', () => { - beforeEach(() => { - mocked(printBuildMessages).mockReset(); - }); - describe('Given a project root path', () => { it('should keep the relative path for the local bundler', () => { const bundler = new EsbuildBundler( diff --git a/test/inline-code.test.ts b/test/inline-code.test.ts index e4290356..efb3c1cb 100644 --- a/test/inline-code.test.ts +++ b/test/inline-code.test.ts @@ -1,22 +1,14 @@ import { Stack } from 'aws-cdk-lib'; import { mocked } from 'jest-mock'; +import { transformSync } from '../lib/esbuild-wrapper'; import { InlineJavaScriptCode, InlineJsxCode, InlineTsxCode, InlineTypeScriptCode, } from '../src'; -import { printBuildMessages } from '../src/formatMessages'; - -jest.mock('../src/formatMessages', () => ({ - printBuildMessages: jest.fn(), -})); describe('using transformOptions', () => { - beforeEach(() => { - mocked(printBuildMessages).mockReset(); - }); - describe('given a banner code', () => { it('should add the banner before the code', () => { const code = new InlineJavaScriptCode( @@ -34,10 +26,6 @@ describe('using transformOptions', () => { }); describe('using transformerProps', () => { - beforeEach(() => { - mocked(printBuildMessages).mockReset(); - }); - describe('given some js code', () => { it('should transform the code', () => { const code = new InlineJavaScriptCode( @@ -89,13 +77,27 @@ describe('using transformerProps', () => { }); describe('given some broken ts code', () => { - it('should display errors and warnings', () => { + it('should throws', () => { expect(() => { const code = new InlineTypeScriptCode('let : d ===== 1'); code.bind(new Stack()); }).toThrowError('Failed to transform InlineCode'); + }); + + // Currently no way to capture esbuild output, + // See https://github.com/evanw/esbuild/issues/2466 + it.skip('should display an error', () => { + const originalConsole = console.error; + console.error = jest.fn(); + + expect(() => { + const code = new InlineTypeScriptCode('let : d ===== 1'); + code.bind(new Stack()); + }).toThrowError('Failed to transform InlineCode'); + + expect(console.error).toBeCalledWith(expect.stringContaining('Unexpected "=="')); - expect(mocked(printBuildMessages)).toHaveBeenCalledTimes(1); + console.error = originalConsole; }); }); @@ -156,4 +158,38 @@ describe('using transformerProps', () => { expect(mockLogger).toHaveBeenCalledWith('dummy-binary'); }); }); + + + describe('with logLevel', () => { + describe('not provided', () => { + it('should default to "warning"', () => { + const transformFn = jest.fn(transformSync); + const code = new InlineJavaScriptCode("const fruit = 'banana';", { + transformFn, + }); + code.bind(new Stack()); + + expect(transformFn).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({ + logLevel: 'warning', + })); + }); + }); + + describe('provided', () => { + it('should use the provided logLevel', () => { + const transformFn = jest.fn(transformSync); + const code = new InlineJavaScriptCode("const fruit = 'banana';", { + transformFn, + transformOptions: { + logLevel: 'silent', + }, + }); + code.bind(new Stack()); + + expect(transformFn).toHaveBeenCalledWith(expect.anything(), expect.objectContaining({ + logLevel: 'silent', + })); + }); + }); + }); }); \ No newline at end of file