2121// MODULES //
2222
2323var logger = require ( 'debug' ) ;
24+ var startsWith = require ( '@stdlib/string/starts-with' ) ;
25+ var replace = require ( '@stdlib/string/replace' ) ;
2426var pkg2id = require ( '@stdlib/error/tools/pkg2id' ) ;
2527var msg2id = require ( '@stdlib/error/tools/msg2id' ) ;
2628var ENV = require ( '@stdlib/process/env' ) ;
2729
2830
2931// VARIABLES //
3032
31- var debug = logger ( 'scripts:transform-error-messages ' ) ;
33+ var debug = logger ( 'scripts:transform' ) ;
3234var pkg = ENV [ 'STDLIB_PKG' ] ;
3335var prefix = pkg2id ( pkg ) ;
36+ var RE_EMPTY_LINE = / ( \r ? \n ) { 2 , } / g;
3437var ERROR_NAMES = [
3538 'Error' ,
3639 'AssertionError' ,
@@ -45,7 +48,7 @@ var ERROR_NAMES = [
4548// MAIN //
4649
4750/**
48- * Transforms a file.
51+ * Transforms a file for a production build .
4952*
5053* ## Notes
5154*
@@ -64,68 +67,122 @@ function transformer( fileInfo, api ) {
6467 var requires ;
6568 var code ;
6669 var root ;
70+ var out ;
6771 var id ;
6872 var j ;
6973
7074 j = api . jscodeshift ;
7175 root = j ( fileInfo . source ) ;
7276
77+ root . find ( j . Program ) . forEach ( onProgram ) ;
78+
79+ requires = root . find ( j . CallExpression , {
80+ 'callee' : {
81+ 'name' : 'require' ,
82+ 'type' : 'Identifier'
83+ }
84+ } ) ;
85+
7386 debug ( 'Transforming file: %s' , fileInfo . path ) ;
74- return root
87+
88+ root
7589 . find ( j . Literal )
76- . forEach ( onStringLiteral )
77- . toSource ( ) ;
90+ . forEach ( onStringLiteral ) ;
91+
92+ requires . forEach ( rewriteRequire ) ;
93+
94+ root
95+ . find ( j . Node )
96+ . forEach ( deleteComment ) ;
97+
98+ out = root . toSource ( {
99+ 'quote' : 'single' ,
100+ 'lineTerminator' : '\n' ,
101+ 'reuseWhitespace' : false ,
102+ 'useTabs' : true
103+ } ) ;
104+
105+ return replace ( out , RE_EMPTY_LINE , '\n' ) ;
106+
107+ /**
108+ * Removes comments from the program.
109+ *
110+ * @private
111+ * @param {Object } path - AST node path
112+ * @returns {void }
113+ */
114+ function onProgram ( path ) {
115+ path . node . comments = [ ] ;
116+ }
117+
118+ /**
119+ * Deletes the comments associated with a given node.
120+ *
121+ * @private
122+ * @param {Object } path - AST node path
123+ * @returns {void }
124+ */
125+ function deleteComment ( path ) {
126+ delete path . node . comments ;
127+ }
128+
129+ /**
130+ * Rewrites a `require` statement to include the `/dist` directory if the module being required starts with `@stdlib`.
131+ *
132+ * @private
133+ * @param {Object } path - AST node path
134+ * @returns {void }
135+ */
136+ function rewriteRequire ( path ) {
137+ if ( startsWith ( path . value . arguments [ 0 ] . value , '@stdlib' ) ) {
138+ path . value . arguments [ 0 ] . value += '/dist' ;
139+ }
140+ }
78141
79142 /**
80143 * Callback invoked upon finding a string literal.
81144 *
82145 * @private
83- * @param {Object } node - AST node
146+ * @param {Object } path - AST node path
84147 * @returns {void }
85148 */
86- function onStringLiteral ( node ) {
87- if ( node . value . value === '@stdlib/string-format' ) {
149+ function onStringLiteral ( path ) {
150+ if ( path . value . value === '@stdlib/string-format' ) {
88151 debug ( 'Replacing `@stdlib/string-format` with `@stdlib/error-tools-fmtprodmsg`...' ) ;
89- j ( node )
152+ j ( path )
90153 . replaceWith ( j . stringLiteral ( '@stdlib/error-tools-fmtprodmsg' ) ) ;
91154 }
92155 // If the string literal is inside a NewExpression for an error, replace the string literal with the error message...
93156 else if (
94157 // Case: new Error( format( '...', ... ) )
95- ( node . parent . parent . value . type === 'NewExpression' &&
96- ERROR_NAMES . includes ( node . parent . parent . value . callee . name ) )
158+ ( path . parent . parent . value . type === 'NewExpression' &&
159+ ERROR_NAMES . includes ( path . parent . parent . value . callee . name ) )
97160 ) {
98- id = msg2id ( node . value . value ) ;
161+ id = msg2id ( path . value . value ) ;
99162 if ( id ) {
100163 code = prefix + id ;
101- debug ( 'Replacing format string "' + node . value . value + '" with error code "' + code + '"...' ) ;
102- j ( node )
164+ debug ( 'Replacing format string "' + path . value . value + '" with error code "' + code + '"...' ) ;
165+ j ( path )
103166 . replaceWith ( j . stringLiteral ( code ) ) ;
104167 }
105168 }
106169 else if (
107170 // Case: new Error( '...' )
108- ( node . parent . value . type === 'NewExpression' &&
109- ERROR_NAMES . includes ( node . parent . value . callee . name ) )
171+ ( path . parent . value . type === 'NewExpression' &&
172+ ERROR_NAMES . includes ( path . parent . value . callee . name ) )
110173 ) {
111- id = msg2id ( node . value . value ) ;
174+ id = msg2id ( path . value . value ) ;
112175 if ( id ) {
113176 code = prefix + id ;
114- debug ( 'Replacing string literal "' + node . value . value + '" with error code "' + code + '"...' ) ;
177+ debug ( 'Replacing string literal "' + path . value . value + '" with error code "' + code + '"...' ) ;
115178
116179 // Replace with call to `format` with the error code...
117180 replacement = j . callExpression ( j . identifier ( 'format' ) , [
118181 j . stringLiteral ( code )
119182 ] ) ;
120- j ( node ) . replaceWith ( replacement ) ;
183+ j ( path ) . replaceWith ( replacement ) ;
121184
122185 // Add `require` call to `@stdlib/error-tools-fmtprodmsg` if not already present...
123- requires = root . find ( j . CallExpression , {
124- 'callee' : {
125- 'name' : 'require' ,
126- 'type' : 'Identifier'
127- }
128- } ) ;
129186 nRequires = requires . size ( ) ;
130187 debug ( 'Found ' + nRequires + ' `require` calls...' ) ;
131188 if ( ! requires . some ( hasRequire ) ) {
@@ -142,15 +199,15 @@ function transformer( fileInfo, api ) {
142199 }
143200
144201 /**
145- * Tests whether a node is a require call for `@stdlib/error-tools-fmtprodmsg`.
202+ * Tests whether a path is a require call for `@stdlib/error-tools-fmtprodmsg`.
146203 *
147204 * @private
148- * @param {Object } node - node to test
149- * @returns {boolean } boolean indicating whether a node is a require call for `@stdlib/error-tools-fmtprodmsg`
205+ * @param {Object } path - AST node path
206+ * @returns {boolean } boolean indicating whether a path is a require call for `@stdlib/error-tools-fmtprodmsg`
150207 */
151- function hasRequire ( node ) {
152- return node . value . callee . name === 'require' &&
153- node . value . arguments [ 0 ] . value === '@stdlib/error-tools-fmtprodmsg' ;
208+ function hasRequire ( path ) {
209+ return path . value . callee . name === 'require' &&
210+ path . value . arguments [ 0 ] . value === '@stdlib/error-tools-fmtprodmsg' ;
154211 }
155212}
156213
0 commit comments