| 
									
										
										
										
											2021-06-28 10:08:11 +02:00
										 |  |  | const path = require('path'); | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  | const chokidar = require('chokidar'); | 
					
						
							| 
									
										
										
										
											2021-06-28 10:08:11 +02:00
										 |  |  | const readdirp = require('readdirp'); | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-19 17:26:15 +05:30
										 |  |  | const { createChallengeNode } = require('./create-challenge-nodes'); | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-23 14:18:46 +01:00
										 |  |  | exports.sourceNodes = function sourceChallengesSourceNodes( | 
					
						
							|  |  |  |   { actions, reporter }, | 
					
						
							|  |  |  |   pluginOptions | 
					
						
							|  |  |  | ) { | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  |   const { source, onSourceChange, curriculumPath } = pluginOptions; | 
					
						
							|  |  |  |   if (typeof source !== 'function') { | 
					
						
							|  |  |  |     reporter.panic(`
 | 
					
						
							|  |  |  |     "source" is a required option for fcc-source-challenges. It must be a | 
					
						
							|  |  |  |     function that delivers challenge objects to the plugin | 
					
						
							|  |  |  |     `);
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (typeof onSourceChange !== 'function') { | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  |     reporter.panic(`
 | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  |     "onSourceChange" is a required option for fcc-source-challenges. It must be | 
					
						
							|  |  |  |     a function that delivers a new challenge object to the plugin | 
					
						
							|  |  |  |     `);
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (typeof curriculumPath !== 'string') { | 
					
						
							|  |  |  |     reporter.panic(`
 | 
					
						
							|  |  |  |     "curriculumPath" is a required option for fcc-source-challenges. It must be | 
					
						
							|  |  |  |     a path to a curriculum directory | 
					
						
							|  |  |  |     `);
 | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  |   } | 
					
						
							|  |  |  |   const { createNode } = actions; | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  |   const watcher = chokidar.watch(curriculumPath, { | 
					
						
							|  |  |  |     ignored: /(^|[\/\\])\../, | 
					
						
							| 
									
										
										
										
											2021-06-28 10:08:11 +02:00
										 |  |  |     ignoreInitial: true, | 
					
						
							| 
									
										
										
										
											2019-06-28 14:26:11 +02:00
										 |  |  |     persistent: true, | 
					
						
							| 
									
										
										
										
											2020-09-02 11:31:10 +02:00
										 |  |  |     usePolling: true, | 
					
						
							|  |  |  |     cwd: curriculumPath | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-25 13:56:58 +02:00
										 |  |  |   watcher.on('change', filePath => | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |     /\.md?$/.test(filePath) | 
					
						
							| 
									
										
										
										
											2019-02-19 01:59:12 +03:00
										 |  |  |       ? onSourceChange(filePath) | 
					
						
							|  |  |  |           .then(challenge => { | 
					
						
							|  |  |  |             reporter.info( | 
					
						
							| 
									
										
										
										
											2019-07-19 19:28:04 +05:30
										 |  |  |               `
 | 
					
						
							|  |  |  | File changed at ${filePath}, replacing challengeNode id ${challenge.id} | 
					
						
							|  |  |  |               `
 | 
					
						
							| 
									
										
										
										
											2019-02-19 01:59:12 +03:00
										 |  |  |             ); | 
					
						
							| 
									
										
										
										
											2020-05-20 16:00:08 +02:00
										 |  |  |             createVisibleChallenge(challenge); | 
					
						
							| 
									
										
										
										
											2019-02-19 01:59:12 +03:00
										 |  |  |           }) | 
					
						
							|  |  |  |           .catch(e => | 
					
						
							|  |  |  |             reporter.error(`fcc-replace-challenge
 | 
					
						
							| 
									
										
										
										
											2020-09-02 11:31:10 +02:00
										 |  |  |   attempting to replace ${filePath} | 
					
						
							| 
									
										
										
										
											2018-12-03 09:57:14 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ${e.message} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   `)
 | 
					
						
							| 
									
										
										
										
											2019-02-19 01:59:12 +03:00
										 |  |  |           ) | 
					
						
							|  |  |  |       : null | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  |   ); | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-06-28 10:08:11 +02:00
										 |  |  |   // if a file is added, that might change the order of the challenges in the
 | 
					
						
							|  |  |  |   // containing block, so we recreate them all
 | 
					
						
							|  |  |  |   watcher.on('add', filePath => { | 
					
						
							|  |  |  |     if (/\.md?$/.test(filePath)) { | 
					
						
							|  |  |  |       const blockPath = path.dirname(filePath); | 
					
						
							|  |  |  |       const fullBlockPath = path.join( | 
					
						
							|  |  |  |         __dirname, | 
					
						
							|  |  |  |         '../../../curriculum/challenges/english/', | 
					
						
							|  |  |  |         blockPath | 
					
						
							|  |  |  |       ); | 
					
						
							|  |  |  |       readdirp(fullBlockPath, { fileFilter: '*.md' }) | 
					
						
							|  |  |  |         .on('data', entry => { | 
					
						
							|  |  |  |           const { path: siblingPath } = entry; | 
					
						
							|  |  |  |           const relativePath = path.join(blockPath, siblingPath); | 
					
						
							|  |  |  |           onSourceChange(relativePath) | 
					
						
							|  |  |  |             .then(challenge => { | 
					
						
							|  |  |  |               reporter.info( | 
					
						
							|  |  |  |                 `
 | 
					
						
							|  |  |  | File changed at ${relativePath}, replacing challengeNode id ${challenge.id} | 
					
						
							|  |  |  |             `
 | 
					
						
							|  |  |  |               ); | 
					
						
							|  |  |  |               createVisibleChallenge(challenge); | 
					
						
							|  |  |  |             }) | 
					
						
							|  |  |  |             .catch(e => | 
					
						
							|  |  |  |               reporter.error(`fcc-replace-challenge
 | 
					
						
							|  |  |  | attempting to replace ${relativePath} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | ${e.message} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | `)
 | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |         .on('warn', error => console.error('non-fatal error', error)) | 
					
						
							|  |  |  |         .on('error', error => console.error('fatal error', error)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  |   function sourceAndCreateNodes() { | 
					
						
							|  |  |  |     return source() | 
					
						
							|  |  |  |       .then(challenges => Promise.all(challenges)) | 
					
						
							|  |  |  |       .then(challenges => | 
					
						
							| 
									
										
										
										
											2020-05-20 16:00:08 +02:00
										 |  |  |         challenges.map(challenge => createVisibleChallenge(challenge)) | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  |       ) | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |       .catch(e => { | 
					
						
							|  |  |  |         console.log(e); | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  |         reporter.panic(`fcc-source-challenges
 | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-10-04 14:47:55 +01:00
										 |  |  |   ${e.message} | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-11-27 19:02:05 +01:00
										 |  |  |   `);
 | 
					
						
							|  |  |  |       }); | 
					
						
							| 
									
										
										
										
											2018-11-16 18:22:52 +00:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2019-07-25 13:56:58 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-20 16:00:08 +02:00
										 |  |  |   function createVisibleChallenge(challenge) { | 
					
						
							|  |  |  |     createNode(createChallengeNode(challenge, reporter)); | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-07-25 13:56:58 +02:00
										 |  |  |   return new Promise((resolve, reject) => { | 
					
						
							|  |  |  |     watcher.on('ready', () => sourceAndCreateNodes().then(resolve, reject)); | 
					
						
							|  |  |  |   }); | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  | }; |