create-webiny-project
Advanced tools
Comparing version
177
bin.js
#!/usr/bin/env node | ||
"use strict"; | ||
const semver = require("semver"); | ||
const chalk = require("chalk"); | ||
const getYarnVersion = require("./utils/getYarnVersion"); | ||
const getNpmVersion = require("./utils/getNpmVersion"); | ||
const verifyConfig = require("./utils/verifyConfig"); | ||
// Ensure system requirements are met. | ||
require("@webiny/system-requirements").ensureSystemRequirements(); | ||
(async () => { | ||
const minNodeVersion = "16"; | ||
const minNpmVersion = "10"; | ||
const minYarnVersion = "1.22.21"; | ||
/** | ||
* Node | ||
*/ | ||
const nodeVersion = process.versions.node; | ||
if (!semver.satisfies(nodeVersion, `>=${minNodeVersion}`)) { | ||
console.error( | ||
chalk.red( | ||
[ | ||
`You are running Node.js ${nodeVersion}, but Webiny requires version ${minNodeVersion} or higher.`, | ||
`Please switch to one of the required versions and try again.`, | ||
"For more information, please visit https://docs.webiny.com/docs/tutorials/install-webiny#prerequisites." | ||
].join(" ") | ||
) | ||
); | ||
process.exit(1); | ||
} | ||
/** | ||
* npm | ||
*/ | ||
try { | ||
const npmVersion = await getNpmVersion(); | ||
if (!semver.satisfies(npmVersion, `>=${minNpmVersion}`)) { | ||
console.error( | ||
chalk.red( | ||
[ | ||
`Webiny requires npm@^${minNpmVersion} or higher.`, | ||
`Please run ${chalk.green( | ||
"npm install npm@latest -g" | ||
)}, to get the latest version.` | ||
].join("\n") | ||
) | ||
); | ||
process.exit(1); | ||
} | ||
} catch (err) { | ||
console.error(chalk.red(`Webiny depends on "npm".`)); | ||
// Verify `.webiny` config file and continue. | ||
require("./utils/ensureConfig").ensureConfig(); | ||
console.log( | ||
`Please visit https://docs.npmjs.com/try-the-latest-stable-version-of-npm to install ${chalk.green( | ||
"npm" | ||
)}.` | ||
); | ||
const yargs = require("yargs"); | ||
const packageJson = require("./package.json"); | ||
const createProject = require("./utils/createProject"); | ||
process.exit(1); | ||
} | ||
process.on("unhandledRejection", err => { | ||
throw err; | ||
}); | ||
/** | ||
* yarn | ||
*/ | ||
try { | ||
const yarnVersion = await getYarnVersion(); | ||
if (!semver.satisfies(yarnVersion, `>=${minYarnVersion}`)) { | ||
console.error( | ||
chalk.red( | ||
[ | ||
`Webiny requires yarn@^${minYarnVersion} or higher.`, | ||
`Please visit https://yarnpkg.com/ to install ${chalk.green("yarn")}.` | ||
].join("\n") | ||
) | ||
); | ||
process.exit(1); | ||
yargs | ||
.usage("Usage: create-webiny-project <project-name> [options]") | ||
.version(packageJson.version) | ||
.demandCommand(1) | ||
.help() | ||
.alias("help", "h") | ||
.scriptName("create-webiny-project") | ||
.fail(function (msg, err) { | ||
if (msg) { | ||
console.log(msg); | ||
} | ||
} catch (err) { | ||
console.error( | ||
chalk.red(`Webiny depends on "yarn" and its built-in support for workspaces.`) | ||
); | ||
if (err) { | ||
console.log(err); | ||
} | ||
process.exit(1); | ||
}); | ||
console.log(`Please visit https://yarnpkg.com/ to install ${chalk.green("yarn")}.`); | ||
// noinspection BadExpressionStatementJS | ||
yargs.command( | ||
"$0 <project-name> [options]", | ||
"Name of application and template to use", | ||
yargs => { | ||
yargs.positional("project-name", { | ||
describe: "Project name" | ||
}); | ||
yargs.option("force", { | ||
describe: "All project creation within an existing folder", | ||
default: false, | ||
type: "boolean", | ||
demandOption: false | ||
}); | ||
yargs.option("template", { | ||
describe: `Name of template to use, if no template is provided it will default to "aws" template`, | ||
alias: "t", | ||
type: "string", | ||
default: "aws", | ||
demandOption: false | ||
}); | ||
yargs.option("template-options", { | ||
describe: `A JSON containing template-specific options (usually used in non-interactive environments)`, | ||
default: null, | ||
type: "string", | ||
demandOption: false | ||
}); | ||
yargs.option("assign-to-yarnrc", { | ||
describe: `A JSON containing additional options that will be assigned into the "yarnrc.yml" configuration file`, | ||
default: null, | ||
type: "string", | ||
demandOption: false | ||
}); | ||
yargs.option("tag", { | ||
describe: "NPM tag to use for @webiny packages", | ||
type: "string", | ||
default: "latest", | ||
demandOption: false | ||
}); | ||
yargs.option("interactive", { | ||
describe: "Enable interactive mode for all commands", | ||
default: true, | ||
type: "boolean", | ||
demandOption: false | ||
}); | ||
yargs.option("log", { | ||
describe: | ||
"Creates a log file to see output of installation. Defaults to create-webiny-project-logs.txt in current directory", | ||
alias: "l", | ||
default: "create-webiny-project-logs.txt", | ||
type: "string", | ||
demandOption: false | ||
}); | ||
yargs.option("debug", { | ||
describe: "Turn on debug logs", | ||
default: false, | ||
type: "boolean", | ||
demandOption: false | ||
}); | ||
yargs.option("cleanup", { | ||
describe: "If an error occurs upon project creation, deletes all generated files", | ||
alias: "c", | ||
default: true, | ||
type: "boolean", | ||
demandOption: false | ||
}); | ||
process.exit(1); | ||
} | ||
await verifyConfig(); | ||
require("./index"); | ||
})(); | ||
yargs.example("$0 <project-name>"); | ||
yargs.example("$0 <project-name> --template=aws"); | ||
yargs.example("$0 <project-name> --template=../path/to/template"); | ||
yargs.example("$0 <project-name> --log=./my-logs.txt"); | ||
}, | ||
argv => createProject(argv) | ||
).argv; |
10
index.js
@@ -74,8 +74,14 @@ #!/usr/bin/env node | ||
describe: | ||
"Creates a log file to see output of installation. Defaults to creating cwp-logs.txt in current directory", | ||
"Creates a log file to see output of installation. Defaults to create-webiny-project-logs.txt in current directory", | ||
alias: "l", | ||
default: "cwp-logs.txt", | ||
default: "create-webiny-project-logs.txt", | ||
type: "string", | ||
demandOption: false | ||
}); | ||
yargs.option("debug", { | ||
describe: "Turn on debug logs", | ||
default: false, | ||
type: "boolean", | ||
demandOption: false | ||
}); | ||
yargs.option("cleanup", { | ||
@@ -82,0 +88,0 @@ describe: "If an error occurs upon project creation, deletes all generated files", |
{ | ||
"name": "create-webiny-project", | ||
"version": "0.0.0-unstable.2696f9d9e8", | ||
"version": "0.0.0-unstable.2aaa1916d9", | ||
"description": "Webiny project bootstrap tool.", | ||
@@ -16,19 +16,21 @@ "main": "index.js", | ||
"dependencies": { | ||
"@webiny/telemetry": "0.0.0-unstable.2696f9d9e8", | ||
"@webiny/system-requirements": "0.0.0-unstable.2aaa1916d9", | ||
"@webiny/telemetry": "0.0.0-unstable.2aaa1916d9", | ||
"chalk": "4.1.2", | ||
"execa": "5.1.1", | ||
"find-up": "5.0.0", | ||
"fs-extra": "9.1.0", | ||
"fs-extra": "11.2.0", | ||
"js-yaml": "3.14.1", | ||
"listr": "0.14.3", | ||
"load-json-file": "6.2.0", | ||
"node-fetch": "2.6.9", | ||
"node-fetch": "2.6.7", | ||
"os": "0.1.1", | ||
"p-retry": "4.6.2", | ||
"rimraf": "3.0.2", | ||
"semver": "7.5.4", | ||
"uuid": "8.3.2", | ||
"rimraf": "6.0.1", | ||
"semver": "7.6.3", | ||
"uuid": "9.0.1", | ||
"validate-npm-package-name": "3.0.0", | ||
"write-json-file": "4.3.0", | ||
"yargs": "17.6.2" | ||
"yargs": "17.7.2", | ||
"yesno": "0.4.0" | ||
}, | ||
@@ -39,3 +41,3 @@ "publishConfig": { | ||
}, | ||
"gitHead": "2696f9d9e84ad621e1412a05e1252b5ca9c245fb" | ||
"gitHead": "2aaa1916d95b4fb2aa0cc2543f60934c2f3d969c" | ||
} |
#!/usr/bin/env node | ||
const { yellow, red, green, gray } = require("chalk"); | ||
const { yellow, red, green, gray, bold } = require("chalk"); | ||
const execa = require("execa"); | ||
@@ -11,8 +11,20 @@ const fs = require("fs-extra"); | ||
const getPackageJson = require("./getPackageJson"); | ||
const checkProjectName = require("./checkProjectName"); | ||
const validateProjectName = require("./validateProjectName"); | ||
const yaml = require("js-yaml"); | ||
const findUp = require("find-up"); | ||
const { GracefulError } = require("./GracefulError"); | ||
const yesno = require("yesno"); | ||
const NOT_APPLICABLE = gray("N/A"); | ||
const HL = bold(gray("—")).repeat(30); | ||
const sleep = () => | ||
new Promise(resolve => { | ||
setTimeout(() => { | ||
resolve(); | ||
}, 500); | ||
}); | ||
const getTelemetryEventName = stage => `cli-create-webiny-project-${stage}`; | ||
module.exports = async function createProject({ | ||
@@ -24,2 +36,3 @@ projectName, | ||
log, | ||
debug, | ||
cleanup, | ||
@@ -96,5 +109,7 @@ interactive, | ||
validateProjectName(projectName); | ||
console.log(`Initializing a new Webiny project in ${green(projectRoot)}...`); | ||
await sendEvent({ event: "create-webiny-project-start" }); | ||
await sendEvent({ event: getTelemetryEventName("start") }); | ||
@@ -115,3 +130,2 @@ let isGitAvailable = false; | ||
task: () => { | ||
checkProjectName(projectName); | ||
fs.ensureDirSync(projectName); | ||
@@ -126,5 +140,5 @@ writeJson.sync( | ||
// Setup yarn | ||
title: "Setup yarn", | ||
title: "Setup Yarn", | ||
task: async () => { | ||
const yarnVersion = "3.6.4"; | ||
const yarnVersion = "4.6.0"; | ||
const yarnFile = `yarn-${yarnVersion}.cjs`; | ||
@@ -145,14 +159,18 @@ const yarnPath = `.yarn`; | ||
} | ||
const target = path.join(projectRoot, yarnReleasesFilePath); | ||
fs.copyFileSync(source, target); | ||
const yamlPath = path.join(projectRoot, ".yarnrc.yml"); | ||
if (!fs.existsSync(yamlPath)) { | ||
fs.writeFileSync(yamlPath, `yarnPath: ${yarnReleasesFilePath}`, "utf-8"); | ||
// `.yarnrc.yml` file is created here. | ||
const yarnRcPath = path.join(projectRoot, ".yarnrc.yml"); | ||
let rawYarnRc = `yarnPath: ${yarnReleasesFilePath}`; | ||
if (fs.existsSync(yarnRcPath)) { | ||
rawYarnRc = fs.readFileSync(yarnRcPath, "utf-8"); | ||
} | ||
const parsedYaml = yaml.load(fs.readFileSync(yamlPath, "utf-8")); | ||
const parsedYarnRc = yaml.load(rawYarnRc); | ||
// Default settings are applied here. Currently we only apply the `nodeLinker` param. | ||
parsedYaml.nodeLinker = "node-modules"; | ||
// Default settings are applied here. Currently, we only apply the `nodeLinker` param. | ||
parsedYarnRc.nodeLinker = "node-modules"; | ||
@@ -171,11 +189,11 @@ // Enables adding additional params into the `.yarnrc.yml` file. | ||
if (parsedAssignToYarnRc) { | ||
Object.assign(parsedYaml, parsedAssignToYarnRc); | ||
Object.assign(parsedYarnRc, parsedAssignToYarnRc); | ||
} | ||
} | ||
fs.writeFileSync(yamlPath, yaml.dump(parsedYaml)); | ||
fs.writeFileSync(yarnRcPath, yaml.dump(parsedYarnRc)); | ||
} | ||
}, | ||
{ | ||
// "yarn adds" given template which can be either a real package or a path of a local package. | ||
// Yarn adds given template which can be either a real package or a path of a local package. | ||
title: `Install template package`, | ||
@@ -189,2 +207,3 @@ task: async context => { | ||
"file:" + path.relative(projectName, template.replace("file:", "")); | ||
templateName = `@webiny/cwp-template-aws@` + templateName; | ||
add = templateName; | ||
@@ -229,6 +248,5 @@ } else { | ||
let templateName = context.templateName; | ||
console.log(`Starting ${green(templateName)} template ...`); | ||
if (templateName.startsWith("file:")) { | ||
templateName = templateName.replace("file:", ""); | ||
if (templateName.includes("file:")) { | ||
const [, templatePath] = templateName.match(/.*?file\:(.*)/); | ||
templateName = templatePath; | ||
} | ||
@@ -242,7 +260,3 @@ | ||
await new Promise(resolve => { | ||
setTimeout(() => { | ||
resolve(); | ||
}, 500); | ||
}); | ||
await sleep(); | ||
@@ -259,3 +273,5 @@ let parsedTemplateOptions = {}; | ||
console.log(); | ||
await require(templatePath)({ | ||
const setupTemplate = require(templatePath); | ||
await setupTemplate({ | ||
log, | ||
@@ -266,12 +282,18 @@ isGitAvailable, | ||
interactive, | ||
debug, | ||
templateOptions: parsedTemplateOptions | ||
}); | ||
await sendEvent({ event: "create-webiny-project-end" }); | ||
await sendEvent({ event: getTelemetryEventName("end") }); | ||
} catch (err) { | ||
let event = getTelemetryEventName("error"); | ||
if (err instanceof GracefulError) { | ||
event = getTelemetryEventName("error-graceful"); | ||
} | ||
await sendEvent({ | ||
event: "create-webiny-project-error", | ||
event, | ||
properties: { | ||
errorMessage: err.message, | ||
errorStack: err.stack | ||
errorMessage: err.cause?.message || err.message, | ||
errorStack: err.cause?.stack || err.stack | ||
} | ||
@@ -326,8 +348,9 @@ }); | ||
"", | ||
`${green("ERROR OUTPUT: ")}`, | ||
"----------------------------------------", | ||
`${bold("Error Logs")}`, | ||
HL, | ||
err.message, | ||
"", | ||
`${green("SYSTEM INFORMATION: ")}`, | ||
"----------------------------------------", | ||
`${bold("System Information")}`, | ||
HL, | ||
`create-webiny-project: ${cwp}`, | ||
`Operating System: ${os}`, | ||
@@ -338,3 +361,2 @@ `Node: ${node}`, | ||
`Npx: ${npx}`, | ||
`create-webiny-project: ${cwp}`, | ||
`Template: ${cwpTemplate}`, | ||
@@ -349,9 +371,9 @@ `Template Options: ${templateOptionsJson}`, | ||
console.log(`Writing log to ${green(path.resolve(log))}...`); | ||
console.log(`Writing logs to ${green(path.resolve(log))}...`); | ||
fs.writeFileSync(path.resolve(log), err.toString()); | ||
console.log(); | ||
if (cleanup) { | ||
console.log("Cleaning up generated files and folders..."); | ||
console.log("Deleting created files and folders..."); | ||
rimraf.sync(projectRoot); | ||
console.log("Done."); | ||
} else { | ||
@@ -361,5 +383,61 @@ console.log("Project cleanup skipped."); | ||
await sendEvent({ event: "create-webiny-project-end" }); | ||
process.exit(1); | ||
} | ||
console.log(); | ||
console.log( | ||
`🎉 Your new Webiny project ${green( | ||
projectName | ||
)} has been created and is ready to be deployed for the first time!` | ||
); | ||
console.log(); | ||
const ok = await yesno({ | ||
question: bold(`${green("?")} Would you like to deploy your project now (Y/n)?`), | ||
defaultValue: true | ||
}); | ||
console.log(); | ||
if (ok) { | ||
console.log("🚀 Deploying your new Webiny project..."); | ||
console.log(); | ||
try { | ||
const command = ["webiny", "deploy"]; | ||
if (debug) { | ||
command.push("--debug"); | ||
} | ||
await execa("yarn", command, { | ||
cwd: projectRoot, | ||
stdio: "inherit" | ||
}); | ||
} catch { | ||
// Don't do anything. This is because the `webiny deploy` command has its own | ||
// error handling and will print the error message. As far as this setup script | ||
// is concerned, it succeeded, and it doesn't need to do anything else. | ||
} | ||
return; | ||
} | ||
console.log( | ||
[ | ||
`Finish the setup by running the following command: ${green( | ||
`cd ${projectName} && yarn webiny deploy` | ||
)}`, | ||
"", | ||
`To see all of the available CLI commands, run ${green( | ||
"yarn webiny --help" | ||
)} in your ${green(projectName)} directory.`, | ||
"", | ||
"Want to dive deeper into Webiny? Check out https://webiny.com/docs/!", | ||
"Like the project? Star us on https://github.com/webiny/webiny-js!", | ||
"", | ||
"Need help? Join our Slack community! https://www.webiny.com/slack", | ||
"", | ||
"🚀 Happy coding!" | ||
].join("\n") | ||
); | ||
}; |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
2800647
23.76%16
23.08%11795
22.67%19
11.76%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated