@@ -9,6 +9,7 @@ import deepmerge from "deepmerge"
99import objectToString from "stringify-object"
1010import { type Config as TailwindConfig } from "tailwindcss"
1111import {
12+ ArrayLiteralExpression ,
1213 ObjectLiteralExpression ,
1314 Project ,
1415 PropertyAssignment ,
@@ -194,8 +195,11 @@ async function addTailwindConfigTheme(
194195 if ( themeInitializer ?. isKind ( SyntaxKind . ObjectLiteralExpression ) ) {
195196 const themeObjectString = themeInitializer . getText ( )
196197 const themeObject = await parseObjectLiteral ( themeObjectString )
197- const result = deepmerge ( themeObject , theme )
198+ const result = deepmerge ( themeObject , theme , {
199+ arrayMerge : ( dst , src ) => src ,
200+ } )
198201 const resultString = objectToString ( result )
202+ . replace ( / \' \. \. \. ( .* ) \' / g, "...$1" ) // Remove quote around spread element
199203 . replace ( / \' \" / g, "'" ) // Replace `\" with "
200204 . replace ( / \" \' / g, "'" ) // Replace `\" with "
201205 . replace ( / \' \[ / g, "[" ) // Replace `[ with [
@@ -287,7 +291,8 @@ export function nestSpreadProperties(obj: ObjectLiteralExpression) {
287291
288292 // Replace spread with a property assignment
289293 obj . insertPropertyAssignment ( i , {
290- name : `___${ spreadText . replace ( / ^ \. \. \. / , "" ) } ` ,
294+ // Need to escape the name with " so that deepmerge doesn't mishandle the key
295+ name : `"___${ spreadText . replace ( / ^ \. \. \. / , "" ) } "` ,
291296 initializer : `"...${ spreadText . replace ( / ^ \. \. \. / , "" ) } "` ,
292297 } )
293298
@@ -305,11 +310,41 @@ export function nestSpreadProperties(obj: ObjectLiteralExpression) {
305310 nestSpreadProperties (
306311 initializer . asKindOrThrow ( SyntaxKind . ObjectLiteralExpression )
307312 )
313+ } else if (
314+ initializer &&
315+ initializer . isKind ( SyntaxKind . ArrayLiteralExpression )
316+ ) {
317+ nestSpreadElements (
318+ initializer . asKindOrThrow ( SyntaxKind . ArrayLiteralExpression )
319+ )
308320 }
309321 }
310322 }
311323}
312324
325+ export function nestSpreadElements ( arr : ArrayLiteralExpression ) {
326+ const elements = arr . getElements ( )
327+ for ( let j = 0 ; j < elements . length ; j ++ ) {
328+ const element = elements [ j ]
329+ if ( element . isKind ( SyntaxKind . ObjectLiteralExpression ) ) {
330+ // Recursive check on objects within arrays
331+ nestSpreadProperties (
332+ element . asKindOrThrow ( SyntaxKind . ObjectLiteralExpression )
333+ )
334+ } else if ( element . isKind ( SyntaxKind . ArrayLiteralExpression ) ) {
335+ // Recursive check on nested arrays
336+ nestSpreadElements (
337+ element . asKindOrThrow ( SyntaxKind . ArrayLiteralExpression )
338+ )
339+ } else if ( element . isKind ( SyntaxKind . SpreadElement ) ) {
340+ const spreadText = element . getText ( )
341+ // Spread element within an array
342+ arr . removeElement ( j )
343+ arr . insertElement ( j , `"${ spreadText } "` )
344+ }
345+ }
346+ }
347+
313348export function unnestSpreadProperties ( obj : ObjectLiteralExpression ) {
314349 const properties = obj . getProperties ( )
315350
@@ -319,14 +354,49 @@ export function unnestSpreadProperties(obj: ObjectLiteralExpression) {
319354 const propAssignment = prop as PropertyAssignment
320355 const initializer = propAssignment . getInitializer ( )
321356
322- if ( initializer ?. isKind ( SyntaxKind . StringLiteral ) ) {
323- const value = initializer . getLiteralValue ( )
357+ if ( initializer && initializer . isKind ( SyntaxKind . StringLiteral ) ) {
358+ const value = initializer
359+ . asKindOrThrow ( SyntaxKind . StringLiteral )
360+ . getLiteralValue ( )
324361 if ( value . startsWith ( "..." ) ) {
325362 obj . insertSpreadAssignment ( i , { expression : value . slice ( 3 ) } )
326363 propAssignment . remove ( )
327364 }
328365 } else if ( initializer ?. isKind ( SyntaxKind . ObjectLiteralExpression ) ) {
329366 unnestSpreadProperties ( initializer as ObjectLiteralExpression )
367+ } else if (
368+ initializer &&
369+ initializer . isKind ( SyntaxKind . ArrayLiteralExpression )
370+ ) {
371+ unnsetSpreadElements (
372+ initializer . asKindOrThrow ( SyntaxKind . ArrayLiteralExpression )
373+ )
374+ }
375+ }
376+ }
377+ }
378+
379+ export function unnsetSpreadElements ( arr : ArrayLiteralExpression ) {
380+ const elements = arr . getElements ( )
381+ for ( let j = 0 ; j < elements . length ; j ++ ) {
382+ const element = elements [ j ]
383+ if ( element . isKind ( SyntaxKind . ObjectLiteralExpression ) ) {
384+ // Recursive check on objects within arrays
385+ unnestSpreadProperties (
386+ element . asKindOrThrow ( SyntaxKind . ObjectLiteralExpression )
387+ )
388+ } else if ( element . isKind ( SyntaxKind . ArrayLiteralExpression ) ) {
389+ // Recursive check on nested arrays
390+ unnsetSpreadElements (
391+ element . asKindOrThrow ( SyntaxKind . ArrayLiteralExpression )
392+ )
393+ } else if ( element . isKind ( SyntaxKind . StringLiteral ) ) {
394+ const spreadText = element . getText ( )
395+ // check if spread element
396+ const spreadTest = / (?: ^ [ ' " ] ) ( \. \. \. .* ) (?: [ ' " ] $ ) / g
397+ if ( spreadTest . test ( spreadText ) ) {
398+ arr . removeElement ( j )
399+ arr . insertElement ( j , spreadText . replace ( spreadTest , "$1" ) )
330400 }
331401 }
332402 }
@@ -363,6 +433,12 @@ function parseObjectLiteralExpression(node: ObjectLiteralExpression): any {
363433 result [ name ] = parseObjectLiteralExpression (
364434 property . getInitializer ( ) as ObjectLiteralExpression
365435 )
436+ } else if (
437+ property . getInitializer ( ) ?. isKind ( SyntaxKind . ArrayLiteralExpression )
438+ ) {
439+ result [ name ] = parseArrayLiteralExpression (
440+ property . getInitializer ( ) as ArrayLiteralExpression
441+ )
366442 } else {
367443 result [ name ] = parseValue ( property . getInitializer ( ) )
368444 }
@@ -371,20 +447,44 @@ function parseObjectLiteralExpression(node: ObjectLiteralExpression): any {
371447 return result
372448}
373449
450+ function parseArrayLiteralExpression ( node : ArrayLiteralExpression ) : any [ ] {
451+ const result : any [ ] = [ ]
452+ for ( const element of node . getElements ( ) ) {
453+ if ( element . isKind ( SyntaxKind . ObjectLiteralExpression ) ) {
454+ result . push (
455+ parseObjectLiteralExpression (
456+ element . asKindOrThrow ( SyntaxKind . ObjectLiteralExpression )
457+ )
458+ )
459+ } else if ( element . isKind ( SyntaxKind . ArrayLiteralExpression ) ) {
460+ result . push (
461+ parseArrayLiteralExpression (
462+ element . asKindOrThrow ( SyntaxKind . ArrayLiteralExpression )
463+ )
464+ )
465+ } else {
466+ result . push ( parseValue ( element ) )
467+ }
468+ }
469+ return result
470+ }
471+
374472function parseValue ( node : any ) : any {
375- switch ( node . kind ) {
473+ switch ( node . getKind ( ) ) {
376474 case SyntaxKind . StringLiteral :
377- return node . text
475+ return node . getText ( )
378476 case SyntaxKind . NumericLiteral :
379- return Number ( node . text )
477+ return Number ( node . getText ( ) )
380478 case SyntaxKind . TrueKeyword :
381479 return true
382480 case SyntaxKind . FalseKeyword :
383481 return false
384482 case SyntaxKind . NullKeyword :
385483 return null
386484 case SyntaxKind . ArrayLiteralExpression :
387- return node . elements . map ( parseValue )
485+ return node . getElements ( ) . map ( parseValue )
486+ case SyntaxKind . ObjectLiteralExpression :
487+ return parseObjectLiteralExpression ( node )
388488 default :
389489 return node . getText ( )
390490 }
0 commit comments