11const { default : axios } = require ( 'axios' )
2- const fs = require ( 'fs' ) ;
2+ const fs = require ( 'fs' )
33const { sendDoM } = require ( './utils/dom' )
44const { validateStorybookUrl, validateStorybookDir } = require ( './utils/validate' )
55const { defaultSmartUIConfig } = require ( './utils/config' )
66const { skipStory } = require ( './utils/story' )
7- const { createStaticServer } = require ( './utils/server' )
7+ const { getLastCommit } = require ( './utils/git' )
8+ const static = require ( './utils/static' )
9+ var { constants } = require ( './utils/constants' ) ;
10+ const { shortPolling } = require ( './utils/polling' ) ;
811
912async function storybook ( serve , options ) {
10- let server , url ;
11- let type = / ^ h t t p s ? : \/ \/ / . test ( serve ) ? 'url' : 'dir'
13+ let type = / ^ h t t p s ? : \/ \/ / . test ( serve ) ? 'url' : 'dir' ;
14+ let storybookConfig = options . config ? options . config : defaultSmartUIConfig . storybook ;
15+
1216 if ( type === 'url' ) {
1317 await validateStorybookUrl ( serve ) ;
14- url = serve ;
18+ let url = serve ;
19+
20+ // Convert browsers and resolutions arrays to string
21+ let resolutions = [ ] ;
22+ storybookConfig . resolutions . forEach ( element => {
23+ resolutions . push ( element . join ( 'x' ) ) ;
24+ } ) ;
25+ storybookConfig . resolutions = ( ! resolutions . length ) ? 'all' : resolutions . toString ( ) ;
26+ storybookConfig . browsers = ( ! storybookConfig . browsers . length ) ? 'all' : storybookConfig . browsers . map ( x => x . toLowerCase ( ) ) . toString ( ) ;
27+
28+ // Get stories object from stories.json and add url corresponding to every story ID
29+ await axios . get ( new URL ( 'stories.json' , url ) . href )
30+ . then ( async function ( response ) {
31+ let stories = { }
32+ for ( const [ storyId , storyInfo ] of Object . entries ( response . data . stories ) ) {
33+ if ( ! skipStory ( storyInfo . name , storybookConfig ) ) {
34+ stories [ storyId ] = {
35+ name : storyInfo . name ,
36+ kind : storyInfo . kind ,
37+ url : new URL ( '/iframe.html?id=' + storyId + '&viewMode=story' , url ) . href
38+ }
39+ }
40+ }
41+
42+ if ( Object . keys ( stories ) . length === 0 ) {
43+ console . log ( '[smartui] Error: No stories found' ) ;
44+ process . exit ( 0 ) ;
45+ }
46+ console . log ( '[smartui] Stories found: ' , Object . keys ( stories ) . length ) ;
47+
48+ // Capture DoM of every story and send it to renderer API
49+ await sendDoM ( url , stories , storybookConfig , options ) ;
50+ } )
51+ . catch ( function ( error ) {
52+ if ( error . response ) {
53+ console . log ( '[smartui] Cannot fetch stories. Error: ' , error . message ) ;
54+ } else if ( error . request ) {
55+ console . log ( '[smartui] Cannot fetch stories. Error: ' , error . message ) ;
56+ } else {
57+ console . log ( '[smartui] Cannot fetch stories. Error: ' , error . message ) ;
58+ }
59+ } ) ;
1560 } else {
16- await validateStorybookDir ( serve ) ;
17- server = await createStaticServer ( serve ) ;
18- url = `http://localhost:${ server . address ( ) . port } ` ;
19- }
61+ let dirPath = serve ;
62+ await validateStorybookDir ( dirPath ) ;
2063
21- // TODO: modularize this and separate check for file exists
22- let storybookConfig = defaultSmartUIConfig . storybook ;
23- if ( options . config ) {
24- try {
25- storybookConfig = JSON . parse ( fs . readFileSync ( options . config ) ) . storybook ;
26- } catch ( error ) {
27- console . log ( '[smartui] Error: ' , error . message ) ;
28- process . exit ( 1 ) ;
29- }
64+ // Get storyIds to be rendered
65+ let storyIds = static . filterStories ( dirPath , storybookConfig )
3066
31- storybookConfig . browsers . forEach ( element => {
32- if ( ! ( [ 'chrome' , 'safari' , 'firefox' ] . includes ( element ) ) ) {
33- console . log ( '[smartui] Error: Invalid value for browser. Accepted browsers are chrome, safari and firefox' ) ;
34- process . exit ( 0 ) ;
35- }
36- } ) ;
37- // TODO: Sanity check resolutions
38- }
67+ // Upload Storybook static
68+ await static . getSignedUrl ( options )
69+ . then ( async function ( response ) {
70+ let { url, uploadId } = response . data . data ;
3971
40- // Convert browsers and resolutions arrays to string
41- let resolutions = [ ] ;
42- storybookConfig . resolutions . forEach ( element => {
43- resolutions . push ( element . join ( 'x' ) ) ;
44- } ) ;
45- storybookConfig . resolutions = ( ! resolutions . length ) ? 'all' : resolutions . toString ( ) ;
46- storybookConfig . browsers = ( ! storybookConfig . browsers . length ) ? 'all' : storybookConfig . browsers . toString ( ) ;
72+ // Compress static build
73+ await static . compress ( dirPath , uploadId )
74+ . then ( function ( ) {
75+ console . log ( `[smartui] ${ dirPath } compressed.` )
76+ } )
77+ . catch ( function ( err ) {
78+ console . log ( `[smartui] Cannot compress ${ dirPath } . Error: ${ err . message } ` ) ;
79+ process . exit ( 0 ) ;
80+ } ) ;
4781
48- // Get stories object from stories.json and add url corresponding to every story ID
49- await axios . get ( new URL ( 'stories.json' , url ) . href )
50- . then ( async function ( response ) {
51- let stories = { }
52- for ( const [ storyId , storyInfo ] of Object . entries ( response . data . stories ) ) {
53- if ( ! skipStory ( storyInfo . name , storybookConfig ) ) {
54- stories [ storyId ] = {
55- name : storyInfo . name ,
56- kind : storyInfo . kind ,
57- url : new URL ( '/iframe.html?id=' + storyId + '&viewMode=story' , url ) . href
82+ // Upload to S3
83+ const zipData = fs . readFileSync ( 'storybook-static.zip' ) ;
84+ console . log ( '[smartui] Upload in progress...' )
85+ await axios . put ( url , zipData , {
86+ headers : {
87+ 'Content-Type' : 'application/zip' ,
88+ 'Content-Length' : zipData . length
89+ } } )
90+ . then ( function ( response ) {
91+ console . log ( `[smartui] ${ dirPath } uploaded.` ) ;
92+ fs . rmSync ( 'storybook-static.zip' ) ;
93+ } )
94+ . catch ( function ( error ) {
95+ console . log ( `[smartui] Cannot upload ${ dirPath } . Error: ${ err . message } ` ) ;
96+ fs . rmSync ( 'storybook-static.zip' ) ;
97+ process . exit ( 0 ) ;
98+ } ) ;
99+
100+ // Prepare payload data
101+ let browsers = [ ]
102+ let resolutions = [ ]
103+ storybookConfig . browsers . forEach ( element => {
104+ browsers . push ( element . toLowerCase ( ) ) ;
105+ } ) ;
106+ storybookConfig . resolutions . forEach ( element => {
107+ resolutions . push ( { width : element [ 0 ] , height : element [ 1 ] } ) ;
108+ } ) ;
109+ let commit = await getLastCommit ( ) ;
110+ let payload = {
111+ downloadURL : url . substring ( url . search ( / .c o m / ) + 5 , url . search ( / .z i p / ) + 4 ) ,
112+ uploadId : uploadId ,
113+ projectToken : process . env . PROJECT_TOKEN ,
114+ storybookConfig : {
115+ browsers : browsers ,
116+ resolutions : resolutions ,
117+ storyIds : storyIds
118+ } ,
119+ git : {
120+ branch : commit . branch ,
121+ commitId : commit . shortHash ,
122+ commitAuthor : commit . author . name ,
123+ commitMessage : commit . subject ,
124+ githubURL : process . env . GITHUB_URL || '' ,
58125 }
59126 }
60- }
61-
62- if ( Object . keys ( stories ) . length === 0 ) {
63- console . log ( '[smartui] Error: No stories found' ) ;
64- process . exit ( 0 ) ;
65- } else {
66- for ( const [ storyId , storyInfo ] of Object . entries ( stories ) ) {
67- console . log ( '[smartui] Story found: ' + storyInfo . name ) ;
127+
128+ // Call static render API
129+ await axios . post ( new URL ( constants [ options . env ] . STATIC_RENDER_PATH , constants [ options . env ] . BASE_URL ) . href , payload )
130+ . then ( async function ( response ) {
131+ console . log ( '[smartui] Build in progress...' ) ;
132+ await shortPolling ( response . data . data . buildId , 0 , options ) ;
133+ } )
134+ . catch ( function ( error ) {
135+ if ( error . response ) {
136+ console . log ( '[smartui] Build failed: Error: ' , error . response . data . error ?. message ) ;
137+ } else {
138+ console . log ( '[smartui] Build failed: Error: ' , error . message ) ;
139+ }
140+ } ) ;
141+ } )
142+ . catch ( function ( error ) {
143+ if ( error . response ) {
144+ console . log ( '[smartui] Error: ' , error . response . data . error ?. message ) ;
145+ } else {
146+ console . log ( '[smartui] Error: ' , error . message ) ;
68147 }
69- }
70- // Capture DoM of every story and send it to renderer API
71- await sendDoM ( url , stories , storybookConfig , options ) ;
72- } )
73- . catch ( function ( error ) {
74- if ( error . response ) {
75- console . log ( '[smartui] Cannot fetch stories. Error: ' , error . message ) ;
76- } else if ( error . request ) {
77- console . log ( '[smartui] Cannot fetch stories. Error: ' , error . message ) ;
78- } else {
79- console . log ( '[smartui] Cannot fetch stories. Error: ' , error . message ) ;
80- }
81- } ) ;
82-
83- // Close static server
84- if ( server ) server ?. close ( ) ;
85-
148+ process . exit ( 0 ) ;
149+ } ) ;
150+
151+ }
86152} ;
87153
88154module . exports = { storybook } ;
0 commit comments