| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  | 'use strict'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const path = require('path'); | 
					
						
							|  |  |  | const execa = require('execa'); | 
					
						
							|  |  |  | const chalk = require('chalk'); | 
					
						
							|  |  |  | const stopProcess = require('./stop-process'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Gets the package version on npm. Will fail if the package does not exist | 
					
						
							| 
									
										
										
										
											2021-11-23 19:09:56 +01:00
										 |  |  |  * @param {string} packageName Name to look up on npm, may include a specific version | 
					
						
							| 
									
										
										
										
											2021-11-23 16:58:16 +01:00
										 |  |  |  * @param {Object} options | 
					
						
							|  |  |  |  * @param {boolean} options.useYarn Yarn instead of npm | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  |  * @returns {Object} | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-11-24 09:52:26 +01:00
										 |  |  | async function getPackageInfo(packageName, { useYarn } = {}) { | 
					
						
							| 
									
										
										
										
											2021-11-23 12:57:53 +01:00
										 |  |  |   // Use yarn if possible because it's faster
 | 
					
						
							|  |  |  |   if (useYarn) { | 
					
						
							| 
									
										
										
										
											2022-02-24 11:12:08 +01:00
										 |  |  |     const { stdout } = await execa('yarn', ['info', packageName, '--json']); | 
					
						
							| 
									
										
										
										
											2021-11-23 12:57:53 +01:00
										 |  |  |     const yarnInfo = JSON.parse(stdout); | 
					
						
							|  |  |  |     return { | 
					
						
							|  |  |  |       name: yarnInfo.data.name, | 
					
						
							|  |  |  |       version: yarnInfo.data.version, | 
					
						
							|  |  |  |     }; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // Fallback to npm
 | 
					
						
							| 
									
										
										
										
											2022-02-24 11:12:08 +01:00
										 |  |  |   const { stdout } = await execa('npm', ['view', packageName, 'name', 'version', '--silent']); | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  |   // Use regex to parse name and version from CLI result
 | 
					
						
							|  |  |  |   const [name, version] = stdout.match(/(?<=')(.*?)(?=')/gm); | 
					
						
							|  |  |  |   return { name, version }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2021-11-23 12:57:53 +01:00
										 |  |  |  * Get the version and full package name of the starter | 
					
						
							|  |  |  |  * @param {string} starter - The name of the starter as provided by the user | 
					
						
							| 
									
										
										
										
											2021-11-24 10:09:34 +01:00
										 |  |  |  * @param {Object} options | 
					
						
							|  |  |  |  * @param {boolean} options.useYarn - Use yarn instead of npm | 
					
						
							| 
									
										
										
										
											2021-11-23 12:57:53 +01:00
										 |  |  |  * @returns {Object} - Full name and version of the starter package on npm | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-11-24 10:09:34 +01:00
										 |  |  | async function getStarterPackageInfo(starter, { useYarn } = {}) { | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  |   // Check if starter is a shorthand
 | 
					
						
							|  |  |  |   try { | 
					
						
							|  |  |  |     const longhand = `@strapi/starter-${starter}`; | 
					
						
							| 
									
										
										
										
											2021-11-23 19:09:56 +01:00
										 |  |  |     const packageInfo = await getPackageInfo(longhand, { useYarn }); | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  |     // Hasn't crashed so it is indeed a shorthand
 | 
					
						
							|  |  |  |     return packageInfo; | 
					
						
							|  |  |  |   } catch (error) { | 
					
						
							|  |  |  |     // Ignore error, we now know it's not a shorthand
 | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   // Fetch version of the non-shorthand package
 | 
					
						
							|  |  |  |   try { | 
					
						
							| 
									
										
										
										
											2021-11-23 19:09:56 +01:00
										 |  |  |     return getPackageInfo(starter, { useYarn }); | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  |   } catch (error) { | 
					
						
							| 
									
										
										
										
											2021-11-24 10:02:28 +01:00
										 |  |  |     stopProcess(`Could not find package ${chalk.yellow(starter)} on npm`); | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  |   } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							| 
									
										
										
										
											2021-11-23 12:57:53 +01:00
										 |  |  |  * Download a starter package from the npm registry | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  |  * @param {Object} packageInfo - Starter's npm package information | 
					
						
							|  |  |  |  * @param {string} packageInfo.name | 
					
						
							|  |  |  |  * @param {string} packageInfo.version | 
					
						
							| 
									
										
										
										
											2021-11-23 12:57:53 +01:00
										 |  |  |  * @param {string} parentDir - Path inside of which we install the starter | 
					
						
							| 
									
										
										
										
											2021-11-24 10:09:34 +01:00
										 |  |  |  * @param {Object} options | 
					
						
							|  |  |  |  * @param {boolean} options.useYarn - Use yarn instead of npm | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-11-24 10:09:34 +01:00
										 |  |  | async function downloadNpmStarter({ name, version }, parentDir, { useYarn } = {}) { | 
					
						
							| 
									
										
										
										
											2021-11-23 12:57:53 +01:00
										 |  |  |   // Download from npm, using yarn if possible
 | 
					
						
							|  |  |  |   if (useYarn) { | 
					
						
							| 
									
										
										
										
											2022-02-24 11:12:08 +01:00
										 |  |  |     await execa('yarn', ['add', `${name}@${version}`, '--no-lockfile', '--silent'], { | 
					
						
							| 
									
										
										
										
											2021-11-23 12:57:53 +01:00
										 |  |  |       cwd: parentDir, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } else { | 
					
						
							| 
									
										
										
										
											2022-02-24 11:12:08 +01:00
										 |  |  |     await execa('npm', ['install', `${name}@${version}`, '--no-save', '--silent'], { | 
					
						
							| 
									
										
										
										
											2021-11-23 12:57:53 +01:00
										 |  |  |       cwd: parentDir, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  |   } | 
					
						
							| 
									
										
										
										
											2021-11-18 17:39:40 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // Return the path of the actual starter
 | 
					
						
							|  |  |  |   const exactStarterPath = path.dirname( | 
					
						
							|  |  |  |     require.resolve(`${name}/package.json`, { paths: [parentDir] }) | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   return exactStarterPath; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = { getStarterPackageInfo, downloadNpmStarter }; |