1- import kleur from 'kleur'
21import { parseArgs } from 'util'
32import { either , type Either } from '../../adts.js'
4- import { withPhantomData } from '../../phantom-data .js'
5- import { type Molecule } from '../parsing .js'
6- import { type Canonicalized , type SyntaxTree } from '../parsing/syntax-tree .js'
3+ import { type SyntaxTree } from '../parsing/syntax-tree .js'
4+ import { unparse , type Notation } from '../unparsing .js'
5+ import { prettyJson } from '../unparsing/pretty-json .js'
76
87export const handleOutput = async (
98 process : NodeJS . Process ,
@@ -16,91 +15,52 @@ export const handleOutput = async (
1615 'output-format' : { type : 'string' } ,
1716 } ,
1817 } )
19- if ( args . values [ 'output-format' ] === undefined ) {
18+ const outputFormat = args . values [ 'output-format' ]
19+ if ( outputFormat === undefined ) {
2020 throw new Error ( 'Missing required option: --output-format' )
21- } else if ( args . values [ 'output-format' ] !== 'json' ) {
22- throw new Error (
23- `Unsupported output format: "${ args . values [ 'output-format' ] } "` ,
24- )
2521 } else {
22+ let notation : Notation
23+ if ( outputFormat === 'json' ) {
24+ notation = prettyJson
25+ } else {
26+ throw new Error ( `Unsupported output format: "${ outputFormat } "` )
27+ }
28+
2629 const result = await command ( )
2730 return either . match ( result , {
2831 left : error => {
2932 throw new Error ( error . message ) // TODO: Improve error reporting.
3033 } ,
3134 right : output => {
32- writeJSON ( process . stdout , output )
35+ writeOutput ( process . stdout , notation , output )
3336 return undefined
3437 } ,
3538 } )
3639 }
3740}
3841
39- export const writeJSON = (
42+ export const writeOutput = (
4043 writeStream : NodeJS . WritableStream ,
44+ notation : Notation ,
4145 output : SyntaxTree ,
4246) : void => {
43- writeStream . write ( stringifyAsPrettyJSON ( output ) )
44-
45- // Writing a newline ensures that output is flushed before terminating, otherwise nothing may be
46- // printed to the console. See:
47- // - <https://github.com/nodejs/node/issues/6379>
48- // - <https://github.com/nodejs/node/issues/6456>
49- // - <https://github.com/nodejs/node/issues/2972>
50- // - …and many other near-duplicate issues
51- //
52- // I've tried other workarounds such as explicitly terminating via `process.exit`, passing a
53- // callback to `writeStream.write` (ensuring the returned `Promise` is not resolved until it is
54- // called), and explicitly calling `writeStream.end`/`writeStream.uncork` and so far this is the
55- // only workaround which reliably results in the desired behavior.
56- writeStream . write ( '\n' )
57- }
58-
59- const indent = ( spaces : number , textToIndent : string ) => {
60- const indentation = ' ' . repeat ( spaces )
61- return ( indentation + textToIndent ) . replace ( / ( \r ? \n ) / g, `$1${ indentation } ` )
62- }
63-
64- const quote = kleur . dim ( '"' )
65- const colon = kleur . dim ( ':' )
66- const comma = kleur . dim ( ',' )
67- const openBrace = kleur . dim ( '{' )
68- const closeBrace = kleur . dim ( '}' )
69-
70- const escapeStringContents = ( value : string ) =>
71- value . replace ( '\\' , '\\\\' ) . replace ( '"' , '\\"' )
72-
73- const key = ( value : string ) : string =>
74- quote + kleur . bold ( escapeStringContents ( value ) ) + quote
75-
76- const string = ( value : string ) : string =>
77- quote +
78- escapeStringContents (
79- / ^ @ [ ^ @ ] / . test ( value ) ? kleur . bold ( kleur . underline ( value ) ) : value ,
80- ) +
81- quote
82-
83- const object = ( value : Molecule ) : string => {
84- const entries = Object . entries ( value )
85- if ( entries . length === 0 ) {
86- return openBrace + closeBrace
47+ const outputAsString = unparse ( output , notation )
48+ if ( either . isLeft ( outputAsString ) ) {
49+ throw new Error ( outputAsString . value . message )
8750 } else {
88- const keyValuePairs : string = Object . entries ( value )
89- . map (
90- ( [ propertyKey , propertyValue ] ) =>
91- key ( propertyKey ) +
92- colon +
93- ' ' +
94- stringifyAsPrettyJSON (
95- withPhantomData < Canonicalized > ( ) ( propertyValue ) ,
96- ) ,
97- )
98- . join ( comma + '\n' )
51+ writeStream . write ( outputAsString . value )
9952
100- return openBrace + '\n' + indent ( 2 , keyValuePairs ) + '\n' + closeBrace
53+ // Writing a newline ensures that output is flushed before terminating, otherwise nothing may be
54+ // printed to the console. See:
55+ // - <https://github.com/nodejs/node/issues/6379>
56+ // - <https://github.com/nodejs/node/issues/6456>
57+ // - <https://github.com/nodejs/node/issues/2972>
58+ // - …and many other near-duplicate issues
59+ //
60+ // I've tried other workarounds such as explicitly terminating via `process.exit`, passing a
61+ // callback to `writeStream.write` (ensuring the returned `Promise` is not resolved until it is
62+ // called), and explicitly calling `writeStream.end`/`writeStream.uncork` and so far this is the
63+ // only workaround which reliably results in the desired behavior.
64+ writeStream . write ( '\n' )
10165 }
10266}
103-
104- const stringifyAsPrettyJSON = ( output : SyntaxTree ) => {
105- return typeof output === 'string' ? string ( output ) : object ( output )
106- }
0 commit comments