diff --git a/packages/@cdklabs/typewriter/src/callable.ts b/packages/@cdklabs/typewriter/src/callable.ts index 1423f345..f94bae29 100644 --- a/packages/@cdklabs/typewriter/src/callable.ts +++ b/packages/@cdklabs/typewriter/src/callable.ts @@ -6,7 +6,7 @@ import { Statement } from './statements'; import { Block } from './statements/block'; import { asStmt } from './statements/private'; import { Type } from './type'; -import { DeclarationKind, TypeDeclaration, TypeSpec } from './type-declaration'; +import { DeclarationKind, Exported, TypeDeclaration, TypeSpec } from './type-declaration'; export interface CallableSpec extends TypeSpec { name: string; @@ -29,7 +29,7 @@ export interface CallableExpr { /** * Can't be called "Function" */ -export class FreeFunction extends TypeDeclaration implements CallableDeclaration { +export class FreeFunction extends TypeDeclaration implements CallableDeclaration, Exported { public readonly returnType: Type; public readonly kind = DeclarationKind.Function; public readonly parameters = new Array(); diff --git a/packages/@cdklabs/typewriter/src/renderer/typescript.ts b/packages/@cdklabs/typewriter/src/renderer/typescript.ts index 6c964193..5d82888e 100644 --- a/packages/@cdklabs/typewriter/src/renderer/typescript.ts +++ b/packages/@cdklabs/typewriter/src/renderer/typescript.ts @@ -55,7 +55,7 @@ import { import { StructType } from '../struct'; import { ThingSymbol } from '../symbol'; import { PrimitiveType, Type } from '../type'; -import { TypeParameterSpec } from '../type-declaration'; +import { Exported, TypeParameterSpec } from '../type-declaration'; import { Initializer, MemberVisibility, Method } from '../type-member'; /** @@ -431,11 +431,10 @@ export class TypeScriptRenderer extends Renderer { throw new Error(`Symbol ${sym} (in ${sym.scope}) not visible from ${this.scopes[0]} (missing import?)`); } - protected renderFunction(func: CallableDeclaration) { + protected renderFunction(func: CallableDeclaration & Exported) { this.renderDocs(func); this.emit(`// @ts-ignore TS6133\n`); - - this.emit(`function ${func.name}`); + this.emit(`${func.exported ? 'export ' : ''}function ${func.name}`); this.renderParameters(func.parameters); if (func.returnType) { this.emit(': '); diff --git a/packages/@cdklabs/typewriter/src/type-declaration.ts b/packages/@cdklabs/typewriter/src/type-declaration.ts index d7d183bb..79d22706 100644 --- a/packages/@cdklabs/typewriter/src/type-declaration.ts +++ b/packages/@cdklabs/typewriter/src/type-declaration.ts @@ -19,6 +19,10 @@ export interface Exportable { export?: boolean; } +export interface Exported { + exported?: boolean; +} + export interface TypeParameterSpec { readonly name: string; readonly extendsType?: Type; @@ -52,7 +56,7 @@ export interface TypeSpec extends Documented, Exportable { /** * An abstract jsii type */ -export abstract class TypeDeclaration implements Documented { +export abstract class TypeDeclaration implements Documented, Exported { /** * The simple name of the type (MyClass). */ diff --git a/packages/@cdklabs/typewriter/test/exports.test.ts b/packages/@cdklabs/typewriter/test/exports.test.ts new file mode 100644 index 00000000..8948e490 --- /dev/null +++ b/packages/@cdklabs/typewriter/test/exports.test.ts @@ -0,0 +1,48 @@ +import { FreeFunction, Module, TypeScriptRenderer } from '../src'; + +const renderer = new TypeScriptRenderer(); +let scope: Module; + +beforeEach(() => { + scope = new Module('typewriter.test'); +}); + +describe('functions', () => { + test('functions are implicitly not exported', () => { + new FreeFunction(scope, { + name: 'freeFunction', + }); + + expect(renderer.render(scope)).toMatchInlineSnapshot(` + "/* eslint-disable prettier/prettier, max-len */ + // @ts-ignore TS6133 + function freeFunction(): void;" + `); + }); + + test('functions can be explicitly exported', () => { + new FreeFunction(scope, { + name: 'freeFunction', + export: true, + }); + + expect(renderer.render(scope)).toMatchInlineSnapshot(` + "/* eslint-disable prettier/prettier, max-len */ + // @ts-ignore TS6133 + export function freeFunction(): void;" + `); + }); + + test('functions can be explicitly not exported', () => { + new FreeFunction(scope, { + name: 'freeFunction', + export: false, + }); + + expect(renderer.render(scope)).toMatchInlineSnapshot(` + "/* eslint-disable prettier/prettier, max-len */ + // @ts-ignore TS6133 + function freeFunction(): void;" + `); + }); +});