@@ -5,6 +5,8 @@ import * as fs from "fs";
55import * as path from "path" ;
66import * as ts from "typescript" ;
77
8+ // Default format to use for `format` option
9+ const defaultFormat = "ts"
810// Default suffix appended to generated files. Abbreviation for "ts-interface".
911const defaultSuffix = "-ti" ;
1012// Default header prepended to the generated module.
@@ -16,6 +18,7 @@ const defaultHeader =
1618const ignoreNode = "" ;
1719
1820export interface ICompilerOptions {
21+ format ?: "ts" | "js:esm" | "js:cjs"
1922 ignoreGenerics ?: boolean ;
2023 ignoreIndexSignature ?: boolean ;
2124 inlineImports ?: boolean ;
@@ -25,7 +28,7 @@ export interface ICompilerOptions {
2528export class Compiler {
2629 public static compile (
2730 filePath : string ,
28- options : ICompilerOptions = { ignoreGenerics : false , ignoreIndexSignature : false , inlineImports : false } ,
31+ options : ICompilerOptions = { } ,
2932 ) : string {
3033 const createProgramOptions = { target : ts . ScriptTarget . Latest , module : ts . ModuleKind . CommonJS } ;
3134 const program = ts . createProgram ( [ filePath ] , createProgramOptions ) ;
@@ -34,6 +37,7 @@ export class Compiler {
3437 if ( ! topNode ) {
3538 throw new Error ( `Can't process ${ filePath } : ${ collectDiagnostics ( program ) } ` ) ;
3639 }
40+ options = { format : defaultFormat , ignoreGenerics : false , ignoreIndexSignature : false , inlineImports : false , ...options }
3741 return new Compiler ( checker , options , topNode ) . compileNode ( topNode ) ;
3842 }
3943
@@ -179,7 +183,7 @@ export class Compiler {
179183 const members : string [ ] = node . members . map ( m =>
180184 ` "${ this . getName ( m . name ) } ": ${ getTextOfConstantValue ( this . checker . getConstantValue ( m ) ) } ,\n` ) ;
181185 this . exportedNames . push ( name ) ;
182- return `export const ${ name } = t.enumtype({\n${ members . join ( "" ) } });` ;
186+ return this . _formatExport ( name , ` t.enumtype({\n${ members . join ( "" ) } })` ) ;
183187 }
184188 private _compileInterfaceDeclaration ( node : ts . InterfaceDeclaration ) : string {
185189 const name = this . getName ( node . name ) ;
@@ -194,15 +198,15 @@ export class Compiler {
194198 }
195199 }
196200 this . exportedNames . push ( name ) ;
197- return `export const ${ name } = t.iface([${ extend . join ( ", " ) } ], {\n${ members . join ( "" ) } });` ;
201+ return this . _formatExport ( name , ` t.iface([${ extend . join ( ", " ) } ], {\n${ members . join ( "" ) } })` )
198202 }
199203 private _compileTypeAliasDeclaration ( node : ts . TypeAliasDeclaration ) : string {
200204 const name = this . getName ( node . name ) ;
201205 this . exportedNames . push ( name ) ;
202206 const compiled = this . compileNode ( node . type ) ;
203207 // Turn string literals into explicit `name` nodes, as expected by ITypeSuite.
204208 const fullType = compiled . startsWith ( '"' ) ? `t.name(${ compiled } )` : compiled ;
205- return `export const ${ name } = ${ fullType } ;` ;
209+ return this . _formatExport ( name , fullType )
206210 }
207211 private _compileExpressionWithTypeArguments ( node : ts . ExpressionWithTypeArguments ) : string {
208212 return this . compileNode ( node . expression ) ;
@@ -231,11 +235,18 @@ export class Compiler {
231235 return this . _compileSourceFileStatements ( node ) ;
232236 }
233237 // wrap the top node with a default export
238+ if ( this . options . format === "js:cjs" ) {
239+ return `const t = require("ts-interface-checker");\n\n` +
240+ "module.exports = {\n" +
241+ this . _compileSourceFileStatements ( node ) + "\n" +
242+ "};\n"
243+ }
234244 const prefix = `import * as t from "ts-interface-checker";\n` +
235- "// tslint:disable:object-literal-key-quotes\n\n" ;
245+ ( this . options . format === "ts" ? "// tslint:disable:object-literal-key-quotes\n" : "" ) +
246+ "\n" ;
236247 return prefix +
237248 this . _compileSourceFileStatements ( node ) + "\n\n" +
238- "const exportedTypeSuite: t.ITypeSuite = {\n" +
249+ "const exportedTypeSuite" + ( this . options . format === "ts" ? " : t.ITypeSuite" : "" ) + " = {\n" +
239250 this . exportedNames . map ( ( n ) => ` ${ n } ,\n` ) . join ( "" ) +
240251 "};\n" +
241252 "export default exportedTypeSuite;\n" ;
@@ -248,6 +259,11 @@ export class Compiler {
248259 throw new Error ( `Node ${ ts . SyntaxKind [ node . kind ] } not supported by ts-interface-builder: ` +
249260 node . getText ( ) ) ;
250261 }
262+ private _formatExport ( name : string , expression : string ) : string {
263+ return this . options . format === "js:cjs"
264+ ? ` ${ name } : ${ this . indent ( expression ) } ,`
265+ : `export const ${ name } = ${ expression } ;` ;
266+ }
251267}
252268
253269function getTextOfConstantValue ( value : string | number | undefined ) : string {
@@ -272,6 +288,7 @@ export function main() {
272288 commander
273289 . description ( "Create runtime validator module from TypeScript interfaces" )
274290 . usage ( "[options] <typescript-file...>" )
291+ . option ( "--format <format>" , `Format to use for output; options are 'ts' (default), 'js:esm', 'js:cjs'` )
275292 . option ( "-g, --ignore-generics" , `Ignores generics` )
276293 . option ( "-i, --ignore-index-signature" , `Ignores index signature` )
277294 . option ( "--inline-imports" , `Traverses the full import tree and inlines all types into output` )
@@ -285,6 +302,7 @@ export function main() {
285302 const suffix : string = commander . suffix ;
286303 const outDir : string | undefined = commander . outDir ;
287304 const options : ICompilerOptions = {
305+ format : commander . format || defaultFormat ,
288306 ignoreGenerics : commander . ignoreGenerics ,
289307 ignoreIndexSignature : commander . ignoreIndexSignature ,
290308 inlineImports : commander . inlineImports ,
@@ -300,7 +318,7 @@ export function main() {
300318 // Read and parse the source file.
301319 const ext = path . extname ( filePath ) ;
302320 const dir = outDir || path . dirname ( filePath ) ;
303- const outPath = path . join ( dir , path . basename ( filePath , ext ) + suffix + " .ts") ;
321+ const outPath = path . join ( dir , path . basename ( filePath , ext ) + suffix + ( options . format === "ts" ? " .ts" : ".js" ) ) ;
304322 if ( verbose ) {
305323 console . log ( `Compiling ${ filePath } -> ${ outPath } ` ) ;
306324 }
0 commit comments