@webiny/cli 0.0.0-unstable.fcdad0bc61 → 0.0.0-unstable.fdd9228b5d

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin.js CHANGED
@@ -1,38 +1,103 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
2
 
4
- const chalk = require("chalk");
5
- const execa = require("execa");
6
- const semver = require("semver");
7
- const currentNodeVersion = process.versions.node;
3
+ // Suppress punycode warnings. This is a known issue which we can't fix.
4
+ require("./utils/suppressPunycodeWarnings");
8
5
 
9
- (async () => {
10
- if (!semver.satisfies(currentNodeVersion, ">=14")) {
11
- console.error(
12
- chalk.red(
13
- [
14
- `You are running Node.js ${currentNodeVersion}, but Webiny requires version 14 or higher.`,
15
- `Please switch to one of the required versions and try again.`,
16
- `For more information, please visit https://docs.webiny.com/docs/tutorials/install-webiny#prerequisites.`
17
- ].join(" ")
18
- )
19
- );
20
- process.exit(1);
21
- }
6
+ // Ensure system requirements are met.
7
+ require("@webiny/system-requirements").ensureSystemRequirements();
8
+
9
+ // Detect different Webiny package versions.
10
+ require("./utils/ensureSameWebinyPackageVersions").ensureSameWebinyPackageVersions();
11
+
12
+ const yargs = require("yargs");
13
+
14
+ // Disable help processing until after plugins are imported.
15
+ yargs.help(false);
16
+
17
+ // Loads environment variables from multiple sources.
18
+ require("./utils/loadEnvVariables");
19
+
20
+ const { blue, red, bold, bgYellow } = require("chalk");
21
+ const context = require("./context");
22
+ const { createCommands } = require("./commands");
23
+
24
+ yargs
25
+ .usage("Usage: $0 <command> [options]")
26
+ .demandCommand(1)
27
+ .recommendCommands()
28
+ .scriptName("webiny")
29
+ .epilogue(
30
+ `To find more information, docs and tutorials, see ${blue("https://www.webiny.com/docs")}.`
31
+ )
32
+ .epilogue(`Want to contribute? ${blue("https://github.com/webiny/webiny-js")}.`)
33
+ .fail(function (msg, error, yargs) {
34
+ if (msg) {
35
+ if (msg.includes("Not enough non-option arguments")) {
36
+ console.log();
37
+ context.error(red("Command was not invoked as expected!"));
38
+ context.info(
39
+ `Some non-optional arguments are missing. See the usage examples printed below.`
40
+ );
41
+ console.log();
42
+ yargs.showHelp();
43
+ return;
44
+ }
45
+
46
+ if (msg.includes("Missing required argument")) {
47
+ const args = msg
48
+ .split(":")[1]
49
+ .split(",")
50
+ .map(v => v.trim());
51
+
52
+ console.log();
53
+ context.error(red("Command was not invoked as expected!"));
54
+ context.info(
55
+ `Missing required argument(s): ${args
56
+ .map(arg => red(arg))
57
+ .join(", ")}. See the usage examples printed below.`
58
+ );
59
+ console.log();
60
+ yargs.showHelp();
61
+ return;
62
+ }
63
+ console.log();
64
+ context.error(red("Command execution was aborted!"));
65
+ context.error(msg);
66
+ console.log();
22
67
 
23
- try {
24
- const { stdout } = await execa("yarn", ["--version"]);
25
- if (!semver.satisfies(stdout, ">=2")) {
26
- console.error(chalk.red(`"@webiny/cli" requires yarn >=2!`));
27
68
  process.exit(1);
28
69
  }
29
- } catch (err) {
30
- console.error(chalk.red(`"@webiny/cli" requires yarn >=2!`));
31
- console.log(
32
- `Run ${chalk.blue("yarn set version berry")} to install a compatible version of yarn.`
33
- );
70
+
71
+ console.log();
72
+ // Unfortunately, yargs doesn't provide passed args here, so we had to do it via process.argv.
73
+ const debugEnabled = process.argv.includes("--debug");
74
+ if (debugEnabled) {
75
+ context.debug(error);
76
+ } else {
77
+ context.error(error.message);
78
+ }
79
+
80
+ const gracefulError = error.cause?.gracefulError;
81
+ if (gracefulError instanceof Error) {
82
+ console.log();
83
+ console.log(bgYellow(bold("💡 How can I resolve this?")));
84
+ console.log(gracefulError.message);
85
+ }
86
+
87
+ const plugins = context.plugins.byType("cli-command-error");
88
+ for (let i = 0; i < plugins.length; i++) {
89
+ const plugin = plugins[i];
90
+ plugin.handle({
91
+ error,
92
+ context
93
+ });
94
+ }
95
+
34
96
  process.exit(1);
35
- }
97
+ });
36
98
 
37
- require("./cli");
99
+ (async () => {
100
+ await createCommands(yargs, context);
101
+ // Enable help and run the CLI.
102
+ yargs.help().argv;
38
103
  })();
@@ -0,0 +1,45 @@
1
+ const { getProject } = require("@webiny/cli/utils");
2
+ const path = require("path");
3
+ const fs = require("fs");
4
+
5
+ const DATABASE_SETUPS = {
6
+ DDB: "ddb",
7
+ DDB_ES: "ddb-es",
8
+ DDB_OS: "ddb-os"
9
+ };
10
+
11
+ const DATABASE_SETUPS_LABELS = {
12
+ [DATABASE_SETUPS.DDB]: "Amazon DynamoDB",
13
+ [DATABASE_SETUPS.DDB_ES]: "Amazon DynamoDB + Amazon Elasticsearch Service",
14
+ [DATABASE_SETUPS.DDB_OS]: "Amazon DynamoDB + Amazon OpenSearch Service"
15
+ };
16
+
17
+ // In order to get the database setup, we check for existence of `elasticSearch`
18
+ // or `openSearch` strings within the `apps/core/webiny.application.ts` file.
19
+ const getDatabaseSetup = () => {
20
+ const project = getProject();
21
+ const webinyAppTsPath = path.join(project.root, "apps", "core", "webiny.application.ts");
22
+
23
+ const webinyAppTs = fs.readFileSync(webinyAppTsPath, "utf8");
24
+ if (webinyAppTs.includes("elasticSearch")) {
25
+ return "ddb-es";
26
+ }
27
+
28
+ if (webinyAppTs.includes("openSearch")) {
29
+ return "ddb-os";
30
+ }
31
+
32
+ return "ddb";
33
+ };
34
+
35
+ const getDatabaseSetupLabel = () => {
36
+ const setup = getDatabaseSetup();
37
+ return DATABASE_SETUPS_LABELS[setup];
38
+ };
39
+
40
+ module.exports = {
41
+ getDatabaseSetup,
42
+ getDatabaseSetupLabel,
43
+ DATABASE_SETUPS,
44
+ DATABASE_SETUPS_LABELS
45
+ };
@@ -0,0 +1,5 @@
1
+ const { SystemRequirements } = require("@webiny/system-requirements");
2
+
3
+ module.exports.getNpmVersion = async () => {
4
+ return SystemRequirements.getNpmVersion();
5
+ };
@@ -0,0 +1,5 @@
1
+ const { SystemRequirements } = require("@webiny/system-requirements");
2
+
3
+ module.exports.getNpxVersion = async () => {
4
+ return SystemRequirements.getNpxVersion();
5
+ };
@@ -0,0 +1,43 @@
1
+ const execa = require("execa");
2
+
3
+ module.exports.getPulumiVersions = async () => {
4
+ let pulumi, pulumiAws;
5
+
6
+ try {
7
+ {
8
+ const { stdout } = await execa("yarn", [
9
+ "info",
10
+ "@pulumi/pulumi",
11
+ "-A",
12
+ "-R",
13
+ "--name-only",
14
+ "--json"
15
+ ]);
16
+
17
+ const match = stdout.match(/npm:(.*?)"/);
18
+ if (match) {
19
+ pulumi = match[1];
20
+ }
21
+ }
22
+
23
+ {
24
+ const { stdout } = await execa("yarn", [
25
+ "info",
26
+ "@pulumi/aws",
27
+ "-A",
28
+ "-R",
29
+ "--name-only",
30
+ "--json"
31
+ ]);
32
+
33
+ const match = stdout.match(/npm:(.*?)"/);
34
+ if (match) {
35
+ pulumiAws = match[1];
36
+ }
37
+ }
38
+ } catch (err) {
39
+ return "";
40
+ }
41
+
42
+ return [pulumi, pulumiAws];
43
+ };
@@ -0,0 +1,5 @@
1
+ const { SystemRequirements } = require("@webiny/system-requirements");
2
+
3
+ module.exports.getYarnVersion = async () => {
4
+ return SystemRequirements.getYarnVersion();
5
+ };
@@ -0,0 +1,97 @@
1
+ const NO_VALUE = "-";
2
+ const { isCI } = require("ci-info");
3
+
4
+ const getData = async context => {
5
+ const { getUser } = require("../wcp/utils");
6
+ const { getNpxVersion } = require("./getNpxVersion");
7
+ const { getNpmVersion } = require("./getNpmVersion");
8
+ const { getPulumiVersions } = require("./getPulumiVersions");
9
+ const { getYarnVersion } = require("./getYarnVersion");
10
+ const { getDatabaseSetupLabel } = require("./getDatabaseSetup");
11
+
12
+ const [pulumiVersion, pulumiAwsVersion] = await getPulumiVersions();
13
+
14
+ const wcpProjectId = process.env.WCP_PROJECT_ID;
15
+ const wcpUser = await getUser().catch(() => null);
16
+ const wcpUsingProjectEnvironmentApiKey = Boolean(process.env.WCP_ENVIRONMENT_API_KEY);
17
+
18
+ return [
19
+ {
20
+ sectionName: "Webiny Project",
21
+ data: {
22
+ Name: context.project.name,
23
+ Version: context.version,
24
+ "Database Setup": getDatabaseSetupLabel(),
25
+ "Debug Enabled": process.env.DEBUG === "true" ? "Yes" : "No",
26
+ "Feature Flags": process.env.WEBINY_FEATURE_FLAGS || "N/A"
27
+ }
28
+ },
29
+ {
30
+ sectionName: "Webiny Control Panel (WCP)",
31
+ data: {
32
+ "Project ID": wcpProjectId,
33
+ User: wcpUser?.email || "N/A",
34
+ "Using Project Environment API Key": wcpUsingProjectEnvironmentApiKey ? "Yes" : "No"
35
+ }
36
+ },
37
+ {
38
+ sectionName: "Host",
39
+ data: {
40
+ OS: `${process.platform} (${process.arch})`,
41
+ "Node.js": process.version,
42
+ NPM: await getNpmVersion(),
43
+ NPX: await getNpxVersion(),
44
+ Yarn: await getYarnVersion(),
45
+ "Is CI": isCI ? "Yes" : "No"
46
+ }
47
+ },
48
+ {
49
+ sectionName: "Pulumi",
50
+ data: {
51
+ "@pulumi/pulumi": pulumiVersion,
52
+ "@pulumi/aws": pulumiAwsVersion,
53
+ "Secrets Provider": process.env.PULUMI_SECRETS_PROVIDER,
54
+ "Using Password": process.env.PULUMI_CONFIG_PASSPHRASE ? "Yes" : "No"
55
+ }
56
+ }
57
+ ];
58
+ };
59
+
60
+ module.exports = {
61
+ type: "cli-command",
62
+ name: "cli-command-about",
63
+ create({ yargs, context }) {
64
+ yargs.command(
65
+ "about",
66
+ `Prints out information helpful for debugging purposes.`,
67
+ yargs => {
68
+ yargs.option("json", {
69
+ describe: "Emit output as JSON.",
70
+ type: "boolean",
71
+ default: false
72
+ });
73
+ },
74
+ async yargs => {
75
+ const data = await getData(context);
76
+
77
+ if (yargs.json) {
78
+ console.log(JSON.stringify(data, null, 2));
79
+ return;
80
+ }
81
+
82
+ data.forEach(({ sectionName, data }, index) => {
83
+ if (index > 0) {
84
+ console.log();
85
+ }
86
+
87
+ const { bold } = require("chalk");
88
+ console.log(bold(sectionName));
89
+
90
+ Object.keys(data).forEach(key => {
91
+ console.log(key.padEnd(36), data[key] || NO_VALUE);
92
+ });
93
+ });
94
+ }
95
+ );
96
+ }
97
+ };
package/commands/index.js CHANGED
@@ -1,9 +1,10 @@
1
+ const about = require("./about");
1
2
  const run = require("./run");
2
3
  const telemetry = require("./telemetry");
3
4
  const upgrade = require("./upgrade");
4
5
 
5
6
  module.exports.createCommands = async (yargs, context) => {
6
- context.plugins.register(run, telemetry, upgrade);
7
+ context.plugins.register(about, run, telemetry, upgrade);
7
8
 
8
9
  try {
9
10
  const wcp = require("./wcp");
@@ -1,7 +1,3 @@
1
- const camelCase = require("camelcase");
2
- const findUp = require("find-up");
3
- const path = require("path");
4
-
5
1
  module.exports = {
6
2
  type: "cli-command",
7
3
  name: "cli-command-run",
@@ -16,6 +12,10 @@ module.exports = {
16
12
  });
17
13
  },
18
14
  async argv => {
15
+ const camelCase = require("camelcase");
16
+ const findUp = require("find-up");
17
+ const path = require("path");
18
+
19
19
  const configFile = findUp.sync(["webiny.config.ts", "webiny.config.js"]);
20
20
  let config = context.import(configFile);
21
21
 
@@ -1,16 +1,15 @@
1
- const telemetry = require("@webiny/telemetry/cli");
2
-
3
1
  module.exports = {
4
2
  type: "cli-command",
5
3
  name: "cli-command-telemetry",
6
4
  create({ yargs, context }) {
7
5
  yargs.command("enable-telemetry", "Enable anonymous telemetry.", async () => {
6
+ const telemetry = require("@webiny/telemetry/cli");
7
+
8
8
  telemetry.enable();
9
9
  await telemetry.sendEvent({ event: "enable-telemetry" });
10
10
  context.info(
11
- `Webiny telemetry is now ${context.info.hl(
12
- "enabled"
13
- )}! Thank you for helping us in making Webiny better!`
11
+ `Webiny telemetry is now %s! Thank you for helping us in making Webiny better!`,
12
+ "enabled"
14
13
  );
15
14
  context.info(
16
15
  `For more information, please visit the following link: https://www.webiny.com/telemetry.`
@@ -18,13 +17,14 @@ module.exports = {
18
17
  });
19
18
 
20
19
  yargs.command("disable-telemetry", "Disable anonymous telemetry.", async () => {
20
+ const telemetry = require("@webiny/telemetry/cli");
21
+
21
22
  await telemetry.sendEvent({ event: "disable-telemetry" });
22
23
  telemetry.disable();
23
- context.info(`Webiny telemetry is now ${context.info.hl("disabled")}!`);
24
+ context.info(`Webiny telemetry is now %s!`, "disabled");
24
25
  context.info(
25
- `Note that, in order to complete the process, you will also need to re-deploy your project, using the ${context.info.hl(
26
- "yarn webiny deploy"
27
- )} command.`
26
+ `Note that, in order to complete the process, you will also need to re-deploy your project, using the %s command.`,
27
+ "yarn webiny deploy"
28
28
  );
29
29
  });
30
30
  }
@@ -1,7 +1,3 @@
1
- const { red } = require("chalk");
2
- const execa = require("execa");
3
- const semver = require("semver");
4
-
5
1
  module.exports = [
6
2
  {
7
3
  type: "cli-command",
@@ -29,6 +25,10 @@ module.exports = [
29
25
  });
30
26
  },
31
27
  async argv => {
28
+ const { red } = require("chalk");
29
+ const execa = require("execa");
30
+ const semver = require("semver");
31
+
32
32
  if (!argv.skipChecks) {
33
33
  // Before doing any upgrading, there must not be any active changes in the current branch.
34
34
  let gitStatus = "";
@@ -70,7 +70,8 @@ module.exports = [
70
70
  const npx = execa("npx", command, {
71
71
  env: {
72
72
  FORCE_COLOR: true
73
- }
73
+ },
74
+ stdin: process.stdin
74
75
  });
75
76
 
76
77
  npx.stdout.on("data", data => {
@@ -1,6 +1,7 @@
1
1
  const open = require("open");
2
2
  const { GraphQLClient } = require("graphql-request");
3
- const { setProjectId, setWcpPat, sleep } = require("./utils");
3
+ const { setProjectId, setWcpPat } = require("./utils");
4
+ const { sleep } = require("../../utils");
4
5
  const chalk = require("chalk");
5
6
  const { getWcpGqlApiUrl, getWcpAppUrl } = require("@webiny/wcp");
6
7
 
@@ -95,9 +96,8 @@ module.exports.command = () => ({
95
96
  } catch (e) {
96
97
  if (debug) {
97
98
  context.debug(
98
- `Could not use the provided ${context.debug.hl(
99
- patFromParams
100
- )} PAT because of the following error:`
99
+ `Could not use the provided %s PAT because of the following error:`,
100
+ patFromParams
101
101
  );
102
102
  console.debug(e);
103
103
  }
@@ -118,7 +118,7 @@ module.exports.command = () => ({
118
118
  )}&ref=cli`;
119
119
  const openUrl = `${getWcpAppUrl()}/login/cli?${queryParams}`;
120
120
 
121
- debug && context.debug(`Opening ${context.debug.hl(openUrl)}...`);
121
+ debug && context.debug(`Opening %s...`, openUrl);
122
122
  await open(openUrl);
123
123
 
124
124
  const graphql = {
@@ -1,7 +1,8 @@
1
1
  const open = require("open");
2
2
  const inquirer = require("inquirer");
3
3
  const chalk = require("chalk");
4
- const { getUser, WCP_APP_URL, setProjectId, sleep } = require("./utils");
4
+ const { getUser, WCP_APP_URL, setProjectId } = require("./utils");
5
+ const { sleep } = require("../../utils");
5
6
 
6
7
  module.exports.command = () => [
7
8
  {
@@ -0,0 +1,9 @@
1
+ const { getWcpProjectId } = require("./getWcpProjectId");
2
+
3
+ module.exports.getWcpOrgProjectId = context => {
4
+ const id = getWcpProjectId(context);
5
+ if (typeof id === "string") {
6
+ return id.split("/");
7
+ }
8
+ return [];
9
+ };
@@ -0,0 +1,3 @@
1
+ module.exports.getWcpProjectId = context => {
2
+ return context?.project?.config?.id || process.env.WCP_PROJECT_ID || "";
3
+ };
@@ -4,7 +4,8 @@ const { updateUserLastActiveOn } = require("./updateUserLastActiveOn");
4
4
  const { setProjectId } = require("./setProjectId");
5
5
  const { setWcpPat } = require("./setWcpPat");
6
6
  const { getWcpPat } = require("./getWcpPat");
7
- const { sleep } = require("./sleep");
7
+ const { getWcpProjectId } = require("./getWcpProjectId");
8
+ const { getWcpOrgProjectId } = require("./getWcpOrgProjectId");
8
9
 
9
10
  module.exports = {
10
11
  getUser,
@@ -13,5 +14,6 @@ module.exports = {
13
14
  setProjectId,
14
15
  setWcpPat,
15
16
  getWcpPat,
16
- sleep
17
+ getWcpProjectId,
18
+ getWcpOrgProjectId
17
19
  };
package/context.js CHANGED
@@ -92,7 +92,7 @@ class Context {
92
92
  log = log.log;
93
93
  info = log.info;
94
94
  success = log.success;
95
- debug = process.argv.includes("--debug") ? log.debug : noop;
95
+ debug = process.argv.some(v => v.match("--debug")) ? log.debug : noop;
96
96
  warning = log.warning;
97
97
  error = log.error;
98
98
 
@@ -116,7 +116,7 @@ class Context {
116
116
  }
117
117
 
118
118
  if (!fs.existsSync(filePath)) {
119
- debug && this.debug(`No environment file found on ${this.debug.hl(filePath)}.`);
119
+ debug && this.debug(`No environment file found on %s.`, filePath);
120
120
  return;
121
121
  }
122
122
 
@@ -0,0 +1 @@
1
+ Do not manually create files in this folder. This folder is used to store the files that are generated by the CLI.
@@ -0,0 +1 @@
1
+ []