mirror of
https://github.com/strapi/strapi.git
synced 2025-10-27 16:10:08 +00:00
Merge pull request #11635 from strapi/v4/npm-starters
Update create-strapi-starter to use npm on v4
This commit is contained in:
commit
6652e796ba
@ -21,7 +21,7 @@ const incompatibleQuickstartOptions = [
|
||||
|
||||
program
|
||||
.version(packageJson.version)
|
||||
.arguments('[directory], [starterurl]')
|
||||
.arguments('[directory], [starter]')
|
||||
.option('--use-npm', 'Force usage of npm instead of yarn to create the project')
|
||||
.option('--debug', 'Display database connection error')
|
||||
.option('--quickstart', 'Quickstart app creation')
|
||||
@ -37,16 +37,16 @@ program
|
||||
.description(
|
||||
'Create a fullstack monorepo application using the strapi backend template specified in the provided starter'
|
||||
)
|
||||
.action((directory, starterUrl, programArgs) => {
|
||||
const projectArgs = { projectName: directory, starterUrl };
|
||||
.action((directory, starter, programArgs) => {
|
||||
const projectArgs = { projectName: directory, starter };
|
||||
|
||||
initProject(projectArgs, programArgs);
|
||||
});
|
||||
|
||||
function generateApp(projectArgs, programArgs) {
|
||||
if (!projectArgs.projectName || !projectArgs.starterUrl) {
|
||||
if (!projectArgs.projectName || !projectArgs.starter) {
|
||||
console.error(
|
||||
'Please specify the <directory> and <starterurl> of your project when using --quickstart'
|
||||
'Please specify the <directory> and <starter> of your project when using --quickstart'
|
||||
);
|
||||
// eslint-disable-next-line no-process-exit
|
||||
process.exit(1);
|
||||
@ -71,16 +71,17 @@ async function initProject(projectArgs, program) {
|
||||
program.quickstart = false; // Will disable the quickstart question because != 'undefined'
|
||||
}
|
||||
|
||||
const { projectName, starterUrl } = projectArgs;
|
||||
const { projectName, starter } = projectArgs;
|
||||
|
||||
if (program.quickstart) {
|
||||
return generateApp(projectArgs, program);
|
||||
}
|
||||
|
||||
const prompt = await promptUser(projectName, starterUrl, program);
|
||||
const prompt = await promptUser(projectName, starter, program);
|
||||
|
||||
const promptProjectArgs = {
|
||||
projectName: prompt.directory || projectName,
|
||||
starterUrl: prompt.starter || starterUrl,
|
||||
starter: prompt.starter || starter,
|
||||
};
|
||||
|
||||
const programArgs = {
|
||||
|
||||
@ -16,18 +16,14 @@
|
||||
"create-strapi-starter": "./index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@strapi/generate-new": "3.6.8",
|
||||
"chalk": "4.1.1",
|
||||
"ci-info": "3.1.1",
|
||||
"commander": "7.1.0",
|
||||
"execa": "5.0.0",
|
||||
"execa": "^5.1.1",
|
||||
"fs-extra": "9.1.0",
|
||||
"git-url-parse": "11.4.4",
|
||||
"inquirer": "8.2.0",
|
||||
"js-yaml": "4.1.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"ora": "5.4.0",
|
||||
"@strapi/generate-new": "3.6.8",
|
||||
"tar": "6.1.11"
|
||||
"ora": "5.4.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "echo \"no tests yet\""
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
const { resolve, join, basename } = require('path');
|
||||
const os = require('os');
|
||||
const fse = require('fs-extra');
|
||||
|
||||
const ora = require('ora');
|
||||
const ciEnv = require('ci-info');
|
||||
const chalk = require('chalk');
|
||||
@ -12,28 +11,30 @@ const { generateNewApp } = require('@strapi/generate-new');
|
||||
|
||||
const hasYarn = require('./has-yarn');
|
||||
const { runInstall, runApp, initGit } = require('./child-process');
|
||||
const { getRepoInfo, downloadGitHubRepo } = require('./fetch-github');
|
||||
const { getStarterPackageInfo, downloadNpmStarter } = require('./fetch-npm-starter');
|
||||
const logger = require('./logger');
|
||||
const stopProcess = require('./stop-process');
|
||||
|
||||
/**
|
||||
* @param {string} - filePath Path to starter.json file
|
||||
*/
|
||||
function readStarterJson(filePath, starterUrl) {
|
||||
function readStarterJson(filePath, starter) {
|
||||
try {
|
||||
const data = fse.readFileSync(filePath);
|
||||
return JSON.parse(data);
|
||||
} catch (err) {
|
||||
stopProcess(`Could not find ${chalk.yellow('starter.json')} in ${chalk.yellow(starterUrl)}`);
|
||||
stopProcess(`Could not find ${chalk.yellow('starter.json')} in ${chalk.yellow(starter)}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} rootPath - Path to the project directory
|
||||
* @param {string} projectName - Name of the project
|
||||
* @param {string} rootPath - Path to the project directory
|
||||
* @param {string} projectName - Name of the project
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.useYarn - Use yarn instead of npm
|
||||
*/
|
||||
async function initPackageJson(rootPath, projectName) {
|
||||
const packageManager = hasYarn() ? 'yarn --cwd' : 'npm run --prefix';
|
||||
async function initPackageJson(rootPath, projectName, { useYarn } = {}) {
|
||||
const packageManager = useYarn ? 'yarn --cwd' : 'npm run --prefix';
|
||||
|
||||
try {
|
||||
await fse.writeJson(
|
||||
@ -63,9 +64,11 @@ async function initPackageJson(rootPath, projectName) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} path - The directory path for install
|
||||
* @param {string} path The directory path for install
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.useYarn Use yarn instead of npm
|
||||
*/
|
||||
async function installWithLogs(path) {
|
||||
async function installWithLogs(path, options) {
|
||||
const installPrefix = chalk.yellow('Installing dependencies:');
|
||||
const loader = ora(installPrefix).start();
|
||||
const logInstall = (chunk = '') => {
|
||||
@ -75,7 +78,7 @@ async function installWithLogs(path) {
|
||||
.join(' ')}`;
|
||||
};
|
||||
|
||||
const runner = runInstall(path);
|
||||
const runner = runInstall(path, options);
|
||||
runner.stdout.on('data', logInstall);
|
||||
runner.stderr.on('data', logInstall);
|
||||
|
||||
@ -86,29 +89,53 @@ async function installWithLogs(path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} projectArgs - The arguments for create a project
|
||||
* @param {string|null} projectArgs.projectName - The name/path of project
|
||||
* @param {string|null} projectArgs.starterUrl - The GitHub repo of the starter
|
||||
* @param {Object} program - Commands for generating new application
|
||||
* @param {string} starter The name of the starter as provided by the user
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.useYarn Use yarn instead of npm
|
||||
*/
|
||||
module.exports = async function buildStarter(programArgs, program) {
|
||||
let { projectName, starterUrl } = programArgs;
|
||||
async function getStarterInfo(starter, { useYarn } = {}) {
|
||||
const isLocalStarter = ['./', '../', '/'].some(filePrefix => starter.startsWith(filePrefix));
|
||||
|
||||
// Fetch repo info
|
||||
const repoInfo = await getRepoInfo(starterUrl);
|
||||
const { fullName } = repoInfo;
|
||||
let starterPath;
|
||||
let starterParentPath;
|
||||
let starterPackageInfo = {};
|
||||
|
||||
// Create temporary directory for starter
|
||||
const tmpDir = await fse.mkdtemp(join(os.tmpdir(), 'strapi-'));
|
||||
if (isLocalStarter) {
|
||||
// Starter is a local directory
|
||||
console.log('Installing local starter.');
|
||||
starterPath = resolve(starter);
|
||||
} else {
|
||||
// Starter should be an npm package. Fetch starter info
|
||||
starterPackageInfo = await getStarterPackageInfo(starter, { useYarn });
|
||||
console.log(`Installing ${chalk.yellow(starterPackageInfo.name)} starter.`);
|
||||
|
||||
// Download repo inside temporary directory
|
||||
await downloadGitHubRepo(repoInfo, tmpDir);
|
||||
// Download starter repository to a temporary directory
|
||||
starterParentPath = await fse.mkdtemp(join(os.tmpdir(), 'strapi-'));
|
||||
starterPath = await downloadNpmStarter(starterPackageInfo, starterParentPath, { useYarn });
|
||||
}
|
||||
|
||||
const starterJson = readStarterJson(join(tmpDir, 'starter.json'), starterUrl);
|
||||
return { isLocalStarter, starterPath, starterParentPath, starterPackageInfo };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Object} projectArgs - The arguments for create a project
|
||||
* @param {string|null} projectArgs.projectName - The name/path of project
|
||||
* @param {string|null} projectArgs.starter - The npm package of the starter
|
||||
* @param {Object} program - Commands for generating new application
|
||||
*/
|
||||
module.exports = async function buildStarter({ projectName, starter }, program) {
|
||||
const hasYarnInstalled = await hasYarn();
|
||||
const {
|
||||
isLocalStarter,
|
||||
starterPath,
|
||||
starterParentPath,
|
||||
starterPackageInfo,
|
||||
} = await getStarterInfo(starter, { useYarn: hasYarnInstalled });
|
||||
|
||||
// Project directory
|
||||
const rootPath = resolve(projectName);
|
||||
const projectBasename = basename(rootPath);
|
||||
const starterJson = readStarterJson(join(starterPath, 'starter.json'), starter);
|
||||
|
||||
try {
|
||||
await fse.ensureDir(rootPath);
|
||||
@ -119,10 +146,8 @@ module.exports = async function buildStarter(programArgs, program) {
|
||||
// Copy the downloaded frontend folder to the project folder
|
||||
const frontendPath = join(rootPath, 'frontend');
|
||||
|
||||
const starterDir = (await fse.pathExists(join(tmpDir, 'starter'))) ? 'starter' : 'frontend';
|
||||
|
||||
try {
|
||||
await fse.copy(join(tmpDir, starterDir), frontendPath, {
|
||||
await fse.copy(join(starterPath, 'starter'), frontendPath, {
|
||||
overwrite: true,
|
||||
recursive: true,
|
||||
});
|
||||
@ -130,28 +155,33 @@ module.exports = async function buildStarter(programArgs, program) {
|
||||
stopProcess(`Failed to create ${chalk.yellow(frontendPath)}: ${error.message}`);
|
||||
}
|
||||
|
||||
// Delete temporary directory
|
||||
await fse.remove(tmpDir);
|
||||
// Delete the starter directory if it was downloaded
|
||||
if (!isLocalStarter) {
|
||||
await fse.remove(starterParentPath);
|
||||
}
|
||||
|
||||
const fullUrl = `https://github.com/${fullName}`;
|
||||
// Set command options for Strapi app
|
||||
const generateStrapiAppOptions = {
|
||||
...program,
|
||||
starter: fullUrl,
|
||||
template: starterJson.template,
|
||||
starter: starterPackageInfo.name,
|
||||
run: false,
|
||||
};
|
||||
if (starterPackageInfo.version) {
|
||||
starterPackageInfo.template = `${starterJson.template.name}@${starterJson.template.version}`;
|
||||
} else {
|
||||
starterPackageInfo.template = starterJson.template.name;
|
||||
}
|
||||
|
||||
// Create strapi app using the template
|
||||
await generateNewApp(join(rootPath, 'backend'), generateStrapiAppOptions);
|
||||
|
||||
// Install frontend dependencies
|
||||
console.log(`Creating Strapi starter frontend at ${chalk.green(frontendPath)}.`);
|
||||
console.log(`Installing ${chalk.yellow(fullName)} starter`);
|
||||
await installWithLogs(frontendPath);
|
||||
console.log(`Creating Strapi starter frontend at ${chalk.yellow(frontendPath)}.`);
|
||||
console.log('Installing frontend dependencies');
|
||||
await installWithLogs(frontendPath, { useYarn: hasYarnInstalled });
|
||||
|
||||
// Setup monorepo
|
||||
initPackageJson(rootPath, projectBasename);
|
||||
initPackageJson(rootPath, projectBasename, { useYarn: hasYarnInstalled });
|
||||
|
||||
// Add gitignore
|
||||
try {
|
||||
@ -161,12 +191,12 @@ module.exports = async function buildStarter(programArgs, program) {
|
||||
logger.warn(`Failed to create file: ${chalk.yellow('.gitignore')}`);
|
||||
}
|
||||
|
||||
await installWithLogs(rootPath);
|
||||
await installWithLogs(rootPath, { useYarn: hasYarnInstalled });
|
||||
|
||||
if (!ciEnv.isCI) {
|
||||
await initGit(rootPath);
|
||||
}
|
||||
|
||||
console.log(chalk.green('Starting the app'));
|
||||
await runApp(rootPath);
|
||||
await runApp(rootPath, { useYarn: hasYarnInstalled });
|
||||
};
|
||||
|
||||
@ -2,25 +2,27 @@
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const execa = require('execa');
|
||||
const hasYarn = require('./has-yarn');
|
||||
const logger = require('./logger');
|
||||
|
||||
/**
|
||||
* @param {string} path Path to directory (frontend, backend)
|
||||
* @param {string} path Path to directory (frontend, backend)
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.useYarn Use yarn instead of npm
|
||||
*/
|
||||
function runInstall(path) {
|
||||
if (hasYarn()) {
|
||||
return execa('yarn', ['install'], {
|
||||
cwd: path,
|
||||
stdin: 'ignore',
|
||||
});
|
||||
}
|
||||
|
||||
return execa('npm', ['install'], { cwd: path, stdin: 'ignore' });
|
||||
function runInstall(path, { useYarn } = {}) {
|
||||
return execa(useYarn ? 'yarn' : 'npm', ['install'], {
|
||||
cwd: path,
|
||||
stdin: 'ignore',
|
||||
});
|
||||
}
|
||||
|
||||
function runApp(rootPath) {
|
||||
if (hasYarn()) {
|
||||
/**
|
||||
* @param {string} rootPath
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.useYarn
|
||||
*/
|
||||
function runApp(rootPath, { useYarn } = {}) {
|
||||
if (useYarn) {
|
||||
return execa('yarn', ['develop'], {
|
||||
stdio: 'inherit',
|
||||
cwd: rootPath,
|
||||
|
||||
@ -1,97 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const tar = require('tar');
|
||||
const fetch = require('node-fetch');
|
||||
const parseGitUrl = require('git-url-parse');
|
||||
const chalk = require('chalk');
|
||||
|
||||
const stopProcess = require('./stop-process');
|
||||
|
||||
function parseShorthand(starter) {
|
||||
// Determine if it is comes from another owner
|
||||
if (starter.includes('/')) {
|
||||
const [owner, partialName] = starter.split('/');
|
||||
const name = `strapi-starter-${partialName}`;
|
||||
return {
|
||||
name,
|
||||
fullName: `${owner}/${name}`,
|
||||
};
|
||||
}
|
||||
|
||||
const name = `strapi-starter-${starter}`;
|
||||
return {
|
||||
name,
|
||||
fullName: `strapi/${name}`,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} repo The full name of the repository.
|
||||
*/
|
||||
async function getDefaultBranch(repo) {
|
||||
const response = await fetch(`https://api.github.com/repos/${repo}`);
|
||||
|
||||
if (!response.ok) {
|
||||
stopProcess(
|
||||
`Could not find the starter information for ${chalk.yellow(
|
||||
repo
|
||||
)}. Make sure it is publicly accessible on github.`
|
||||
);
|
||||
}
|
||||
|
||||
const { default_branch } = await response.json();
|
||||
return default_branch;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} starter GitHub URL or shorthand to a starter project.
|
||||
*/
|
||||
async function getRepoInfo(starter) {
|
||||
const { name, full_name: fullName, ref, filepath, protocols, source } = parseGitUrl(starter);
|
||||
|
||||
if (protocols.length === 0) {
|
||||
const repoInfo = parseShorthand(starter);
|
||||
return {
|
||||
...repoInfo,
|
||||
branch: await getDefaultBranch(repoInfo.fullName),
|
||||
usedShorthand: true,
|
||||
};
|
||||
}
|
||||
|
||||
if (source !== 'github.com') {
|
||||
stopProcess(`GitHub URL not found for: ${chalk.yellow(starter)}.`);
|
||||
}
|
||||
|
||||
let branch;
|
||||
if (ref) {
|
||||
// Append the filepath to the parsed ref since a branch name could contain '/'
|
||||
// If so, the rest of the branch name will be considered 'filepath' by 'parseGitUrl'
|
||||
branch = filepath ? `${ref}/${filepath}` : ref;
|
||||
} else {
|
||||
branch = await getDefaultBranch(fullName);
|
||||
}
|
||||
|
||||
return { name, fullName, branch };
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} repoInfo GitHub repository information (full name, branch...).
|
||||
* @param {string} tmpDir Path to the destination temporary directory.
|
||||
*/
|
||||
async function downloadGitHubRepo(repoInfo, tmpDir) {
|
||||
const { fullName, branch, usedShorthand } = repoInfo;
|
||||
|
||||
const codeload = `https://codeload.github.com/${fullName}/tar.gz/${branch}`;
|
||||
const response = await fetch(codeload);
|
||||
|
||||
if (!response.ok) {
|
||||
const message = usedShorthand ? `using the shorthand` : `using the url`;
|
||||
stopProcess(`Could not download the repository ${message}: ${chalk.yellow(fullName)}.`);
|
||||
}
|
||||
|
||||
await new Promise(resolve => {
|
||||
response.body.pipe(tar.extract({ strip: 1, cwd: tmpDir })).on('close', resolve);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = { getRepoInfo, downloadGitHubRepo };
|
||||
@ -0,0 +1,86 @@
|
||||
'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
|
||||
* @param {string} packageName Name to look up on npm, may include a specific version
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.useYarn Yarn instead of npm
|
||||
* @returns {Object}
|
||||
*/
|
||||
async function getPackageInfo(packageName, { useYarn } = {}) {
|
||||
// Use yarn if possible because it's faster
|
||||
if (useYarn) {
|
||||
const { stdout } = await execa.command(`yarn info ${packageName} --json`);
|
||||
const yarnInfo = JSON.parse(stdout);
|
||||
return {
|
||||
name: yarnInfo.data.name,
|
||||
version: yarnInfo.data.version,
|
||||
};
|
||||
}
|
||||
|
||||
// Fallback to npm
|
||||
const { stdout } = await execa.command(`npm view ${packageName} name version --silent`);
|
||||
// Use regex to parse name and version from CLI result
|
||||
const [name, version] = stdout.match(/(?<=')(.*?)(?=')/gm);
|
||||
return { name, version };
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the version and full package name of the starter
|
||||
* @param {string} starter - The name of the starter as provided by the user
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.useYarn - Use yarn instead of npm
|
||||
* @returns {Object} - Full name and version of the starter package on npm
|
||||
*/
|
||||
async function getStarterPackageInfo(starter, { useYarn } = {}) {
|
||||
// Check if starter is a shorthand
|
||||
try {
|
||||
const longhand = `@strapi/starter-${starter}`;
|
||||
const packageInfo = await getPackageInfo(longhand, { useYarn });
|
||||
// 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 {
|
||||
return getPackageInfo(starter, { useYarn });
|
||||
} catch (error) {
|
||||
stopProcess(`Could not find package ${chalk.yellow(starter)} on npm`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Download a starter package from the npm registry
|
||||
* @param {Object} packageInfo - Starter's npm package information
|
||||
* @param {string} packageInfo.name
|
||||
* @param {string} packageInfo.version
|
||||
* @param {string} parentDir - Path inside of which we install the starter
|
||||
* @param {Object} options
|
||||
* @param {boolean} options.useYarn - Use yarn instead of npm
|
||||
*/
|
||||
async function downloadNpmStarter({ name, version }, parentDir, { useYarn } = {}) {
|
||||
// Download from npm, using yarn if possible
|
||||
if (useYarn) {
|
||||
await execa.command(`yarn add ${name}@${version} --no-lockfile --silent`, {
|
||||
cwd: parentDir,
|
||||
});
|
||||
} else {
|
||||
await execa.command(`npm install ${name}@${version} --no-save --silent`, {
|
||||
cwd: parentDir,
|
||||
});
|
||||
}
|
||||
|
||||
// Return the path of the actual starter
|
||||
const exactStarterPath = path.dirname(
|
||||
require.resolve(`${name}/package.json`, { paths: [parentDir] })
|
||||
);
|
||||
return exactStarterPath;
|
||||
}
|
||||
|
||||
module.exports = { getStarterPackageInfo, downloadNpmStarter };
|
||||
@ -2,12 +2,11 @@
|
||||
|
||||
const execa = require('execa');
|
||||
|
||||
module.exports = function hasYarn() {
|
||||
module.exports = async function hasYarn() {
|
||||
try {
|
||||
const { exitCode } = execa.sync('yarn --version', { shell: true });
|
||||
const { exitCode } = await execa.commandSync('yarn --version', { shell: true });
|
||||
|
||||
if (exitCode === 0) return true;
|
||||
return false;
|
||||
} catch (err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,8 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const inquirer = require('inquirer');
|
||||
const fetch = require('node-fetch');
|
||||
const yaml = require('js-yaml');
|
||||
|
||||
/**
|
||||
* @param {string|null} projectName - The name/path of project
|
||||
@ -55,50 +53,10 @@ module.exports = async function promptUser(projectName, starter, program) {
|
||||
* @returns Prompt question object
|
||||
*/
|
||||
async function getStarterQuestion() {
|
||||
const content = await getStarterData();
|
||||
|
||||
// Fallback to manual input when fetch fails
|
||||
if (!content) {
|
||||
return {
|
||||
type: 'input',
|
||||
message: 'Please provide the GitHub URL for the starter you would like to use:',
|
||||
};
|
||||
}
|
||||
|
||||
const choices = content.map(option => {
|
||||
const name = option.title.replace('Starter', '');
|
||||
|
||||
return {
|
||||
name,
|
||||
value: `https://github.com/${option.repo}`,
|
||||
};
|
||||
});
|
||||
|
||||
// Ask user to manually input his starter
|
||||
// TODO: find way to suggest the possible v4 starters
|
||||
return {
|
||||
type: 'list',
|
||||
message:
|
||||
'Which starter would you like to use? (Starters are fullstack Strapi applications designed for a specific use case)',
|
||||
pageSize: choices.length,
|
||||
choices,
|
||||
type: 'input',
|
||||
message: 'Please provide the npm package name of the starter you want to use:',
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns JSON starter data
|
||||
*/
|
||||
async function getStarterData() {
|
||||
const response = await fetch(
|
||||
`https://api.github.com/repos/strapi/community-content/contents/starters/starters.yml`
|
||||
);
|
||||
|
||||
if (!response.ok) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const { content } = await response.json();
|
||||
const buff = Buffer.from(content, 'base64');
|
||||
const stringified = buff.toString('utf-8');
|
||||
|
||||
return yaml.load(stringified);
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ async function getTemplatePackageInfo(template) {
|
||||
try {
|
||||
return getPackageInfo(template);
|
||||
} catch (error) {
|
||||
throw new Error(`Could not find package ${chalk.green('template.json')} on npm`);
|
||||
throw new Error(`Could not find package ${chalk.yellow(template)} on npm`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
31
yarn.lock
31
yarn.lock
@ -11567,22 +11567,7 @@ execa@1.0.0, execa@^1.0.0:
|
||||
signal-exit "^3.0.0"
|
||||
strip-eof "^1.0.0"
|
||||
|
||||
execa@5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376"
|
||||
integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==
|
||||
dependencies:
|
||||
cross-spawn "^7.0.3"
|
||||
get-stream "^6.0.0"
|
||||
human-signals "^2.1.0"
|
||||
is-stream "^2.0.0"
|
||||
merge-stream "^2.0.0"
|
||||
npm-run-path "^4.0.1"
|
||||
onetime "^5.1.2"
|
||||
signal-exit "^3.0.3"
|
||||
strip-final-newline "^2.0.0"
|
||||
|
||||
execa@5.1.1, execa@^5.0.0:
|
||||
execa@5.1.1, execa@^5.0.0, execa@^5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
|
||||
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
|
||||
@ -12587,13 +12572,6 @@ git-up@^4.0.0:
|
||||
is-ssh "^1.3.0"
|
||||
parse-url "^6.0.0"
|
||||
|
||||
git-url-parse@11.4.4:
|
||||
version "11.4.4"
|
||||
resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.4.4.tgz#5d747debc2469c17bc385719f7d0427802d83d77"
|
||||
integrity sha512-Y4o9o7vQngQDIU9IjyCmRJBin5iYjI5u9ZITnddRZpD7dcCFQj2sL2XuMNbLRE4b4B/4ENPsp2Q8P44fjAZ0Pw==
|
||||
dependencies:
|
||||
git-up "^4.0.0"
|
||||
|
||||
git-url-parse@^11.1.2:
|
||||
version "11.6.0"
|
||||
resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.6.0.tgz#c634b8de7faa66498a2b88932df31702c67df605"
|
||||
@ -15355,13 +15333,6 @@ js-yaml@3.x, js-yaml@^3.10.0, js-yaml@^3.13.1:
|
||||
argparse "^1.0.7"
|
||||
esprima "^4.0.0"
|
||||
|
||||
js-yaml@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
|
||||
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
|
||||
dependencies:
|
||||
argparse "^2.0.1"
|
||||
|
||||
jsbn@~0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user