@@ -20,8 +20,16 @@ export {
2020 apiGetProjectsForUser
2121} from './project.controller/getProjectsForUser' ;
2222
23- export function updateProject ( req , res ) {
24- Project . findById ( req . params . project_id , ( findProjectErr , project ) => {
23+ export async function updateProject ( req , res ) {
24+ try {
25+ const project = await Project . findById ( req . params . project_id ) . exec ( ) ;
26+ if ( ! project ) {
27+ res . status ( 404 ) . send ( {
28+ success : false ,
29+ message : 'Project with that id does not exist.'
30+ } ) ;
31+ return ;
32+ }
2533 if ( ! project . user . equals ( req . user . _id ) ) {
2634 res . status ( 403 ) . send ( {
2735 success : false ,
@@ -39,7 +47,7 @@ export function updateProject(req, res) {
3947 } ) ;
4048 return ;
4149 }
42- Project . findByIdAndUpdate (
50+ const updatedProject = await Project . findByIdAndUpdate (
4351 req . params . project_id ,
4452 {
4553 $set : req . body
@@ -50,119 +58,91 @@ export function updateProject(req, res) {
5058 }
5159 )
5260 . populate ( 'user' , 'username' )
53- . exec ( ( updateProjectErr , updatedProject ) => {
54- if ( updateProjectErr ) {
55- console . log ( updateProjectErr ) ;
56- res . status ( 400 ) . json ( { success : false } ) ;
57- return ;
58- }
59- if (
60- req . body . files &&
61- updatedProject . files . length !== req . body . files . length
62- ) {
63- const oldFileIds = updatedProject . files . map ( ( file ) => file . id ) ;
64- const newFileIds = req . body . files . map ( ( file ) => file . id ) ;
65- const staleIds = oldFileIds . filter (
66- ( id ) => newFileIds . indexOf ( id ) === - 1
67- ) ;
68- staleIds . forEach ( ( staleId ) => {
69- updatedProject . files . id ( staleId ) . remove ( ) ;
70- } ) ;
71- updatedProject . save ( ( innerErr , savedProject ) => {
72- if ( innerErr ) {
73- console . log ( innerErr ) ;
74- res . status ( 400 ) . json ( { success : false } ) ;
75- return ;
76- }
77- res . json ( savedProject ) ;
78- } ) ;
79- } else {
80- res . json ( updatedProject ) ;
81- }
61+ . exec ( ) ;
62+ if (
63+ req . body . files &&
64+ updatedProject . files . length !== req . body . files . length
65+ ) {
66+ const oldFileIds = updatedProject . files . map ( ( file ) => file . id ) ;
67+ const newFileIds = req . body . files . map ( ( file ) => file . id ) ;
68+ const staleIds = oldFileIds . filter ( ( id ) => newFileIds . indexOf ( id ) === - 1 ) ;
69+ staleIds . forEach ( ( staleId ) => {
70+ updatedProject . files . id ( staleId ) . remove ( ) ;
8271 } ) ;
83- } ) ;
72+ const savedProject = await updatedProject . save ( ) ;
73+ res . json ( savedProject ) ;
74+ } else {
75+ res . json ( updatedProject ) ;
76+ }
77+ } catch ( error ) {
78+ console . error ( error ) ;
79+ res . status ( 500 ) . json ( { success : false } ) ;
80+ }
8481}
8582
86- export function getProject ( req , res ) {
83+ export async function getProject ( req , res ) {
8784 const { project_id : projectId , username } = req . params ;
88- User . findByUsername ( username , ( err , user ) => { // eslint-disable-line
89- if ( ! user ) {
90- return res
91- . status ( 404 )
92- . send ( { message : 'Project with that username does not exist' } ) ;
93- }
94- Project . findOne ( {
95- user : user . _id ,
96- $or : [ { _id : projectId } , { slug : projectId } ]
97- } )
98- . populate ( 'user' , 'username' )
99- . exec ( ( err , project ) => { // eslint-disable-line
100- if ( err ) {
101- console . log ( err ) ;
102- return res
103- . status ( 404 )
104- . send ( { message : 'Project with that id does not exist' } ) ;
105- }
106- return res . json ( project ) ;
107- } ) ;
108- } ) ;
85+ const user = await User . findByUsername ( username ) ;
86+ if ( ! user ) {
87+ return res
88+ . status ( 404 )
89+ . send ( { message : 'User with that username does not exist' } ) ;
90+ }
91+ const project = await Project . findOne ( {
92+ user : user . _id ,
93+ $or : [ { _id : projectId } , { slug : projectId } ]
94+ } ) . populate ( 'user' , 'username' ) ;
95+ if ( ! project ) {
96+ return res
97+ . status ( 404 )
98+ . send ( { message : 'Project with that id does not exist' } ) ;
99+ }
100+ return res . json ( project ) ;
109101}
110102
111103export function getProjectsForUserId ( userId ) {
112- return new Promise ( ( resolve , reject ) => {
113- Project . find ( { user : userId } )
114- . sort ( '-createdAt' )
115- . select ( 'name files id createdAt updatedAt' )
116- . exec ( ( err , projects ) => {
117- if ( err ) {
118- console . log ( err ) ;
119- }
120- resolve ( projects ) ;
121- } ) ;
122- } ) ;
104+ return Project . find ( { user : userId } )
105+ . sort ( '-createdAt' )
106+ . select ( 'name files id createdAt updatedAt' )
107+ . exec ( ) ;
123108}
124109
125- export function getProjectAsset ( req , res ) {
110+ export async function getProjectAsset ( req , res ) {
126111 const projectId = req . params . project_id ;
127- Project . findOne ( { $or : [ { _id : projectId } , { slug : projectId } ] } )
112+ const project = await Project . findOne ( {
113+ $or : [ { _id : projectId } , { slug : projectId } ]
114+ } )
128115 . populate ( 'user' , 'username' )
129- . exec ( async ( err , project ) => { // eslint-disable-line
130- if ( err ) {
131- return res
132- . status ( 404 )
133- . send ( { message : 'Project with that id does not exist' } ) ;
134- }
135- if ( ! project ) {
136- return res
137- . status ( 404 )
138- . send ( { message : 'Project with that id does not exist' } ) ;
139- }
116+ . exec ( ) ;
117+ if ( ! project ) {
118+ return res
119+ . status ( 404 )
120+ . send ( { message : 'Project with that id does not exist' } ) ;
121+ }
140122
141- const filePath = req . params [ 0 ] ;
142- const resolvedFile = resolvePathToFile ( filePath , project . files ) ;
143- if ( ! resolvedFile ) {
144- return res . status ( 404 ) . send ( { message : 'Asset does not exist' } ) ;
145- }
146- if ( ! resolvedFile . url ) {
147- return res . send ( resolvedFile . content ) ;
148- }
123+ const filePath = req . params [ 0 ] ;
124+ const resolvedFile = resolvePathToFile ( filePath , project . files ) ;
125+ if ( ! resolvedFile ) {
126+ return res . status ( 404 ) . send ( { message : 'Asset does not exist' } ) ;
127+ }
128+ if ( ! resolvedFile . url ) {
129+ return res . send ( resolvedFile . content ) ;
130+ }
149131
150- try {
151- const { data } = await axios . get ( resolvedFile . url , {
152- responseType : 'arraybuffer'
153- } ) ;
154- res . send ( data ) ;
155- } catch ( error ) {
156- res . status ( 404 ) . send ( { message : 'Asset does not exist' } ) ;
157- }
132+ try {
133+ const { data } = await axios . get ( resolvedFile . url , {
134+ responseType : 'arraybuffer'
158135 } ) ;
136+ return res . send ( data ) ;
137+ } catch ( error ) {
138+ return res . status ( 404 ) . send ( { message : 'Asset does not exist' } ) ;
139+ }
159140}
160141
161- export function getProjects ( req , res ) {
142+ export async function getProjects ( req , res ) {
162143 if ( req . user ) {
163- getProjectsForUserId ( req . user . _id ) . then ( ( projects ) => {
164- res . json ( projects ) ;
165- } ) ;
144+ const projects = await getProjectsForUserId ( req . user . _id ) ;
145+ res . json ( projects ) ;
166146 } else {
167147 // could just move this to client side
168148 res . json ( [ ] ) ;
@@ -180,7 +160,7 @@ export async function projectExists(projectId) {
180160
181161/**
182162 * @param {string } username
183- * @param {string } projectId
163+ * @param {string } projectId - the database id or the slug or the project
184164 * @return {Promise<boolean> }
185165 */
186166export async function projectForUserExists ( username , projectId ) {
@@ -193,12 +173,18 @@ export async function projectForUserExists(username, projectId) {
193173 return project != null ;
194174}
195175
176+ /**
177+ * Adds URLs referenced in <script> tags to the `files` array of the project
178+ * so that they can be downloaded along with other remote files from S3.
179+ * @param {object } project
180+ * @void - modifies the `project` parameter
181+ */
196182function bundleExternalLibs ( project ) {
197183 const indexHtml = project . files . find ( ( file ) => file . name === 'index.html' ) ;
198184 const { window } = new JSDOM ( indexHtml . content ) ;
199185 const scriptTags = window . document . getElementsByTagName ( 'script' ) ;
200186
201- Object . values ( scriptTags ) . forEach ( async ( { src } , i ) => {
187+ Object . values ( scriptTags ) . forEach ( ( { src } ) => {
202188 if ( ! isUrl ( src ) ) return ;
203189
204190 const path = src . split ( '/' ) ;
@@ -214,6 +200,13 @@ function bundleExternalLibs(project) {
214200 } ) ;
215201}
216202
203+ /**
204+ * Recursively adds a file and all of its children to the JSZip instance.
205+ * @param {object } file
206+ * @param {Array<object> } files
207+ * @param {JSZip } zip
208+ * @return {Promise<void> } - modifies the `zip` parameter
209+ */
217210async function addFileToZip ( file , files , zip ) {
218211 if ( file . fileType === 'folder' ) {
219212 const folderZip = file . name === 'root' ? zip : zip . folder ( file . name ) ;
@@ -264,9 +257,12 @@ async function buildZip(project, req, res) {
264257 }
265258}
266259
267- export function downloadProjectAsZip ( req , res ) {
268- Project . findById ( req . params . project_id , ( err , project ) => {
269- // save project to some path
270- buildZip ( project , req , res ) ;
271- } ) ;
260+ export async function downloadProjectAsZip ( req , res ) {
261+ const project = await Project . findById ( req . params . project_id ) . exec ( ) ;
262+ if ( ! project ) {
263+ res . status ( 404 ) . send ( { message : 'Project with that id does not exist' } ) ;
264+ return ;
265+ }
266+ // save project to some path
267+ buildZip ( project , req , res ) ;
272268}
0 commit comments