apify-cli 0.14.1 → 0.14.2-beta.1

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.
@@ -0,0 +1,175 @@
1
+ const chalk = require('chalk');
2
+ const inquirer = require('inquirer');
3
+ const https = require('https');
4
+ const { validateActorName } = require('./utils');
5
+
6
+ const PROGRAMMING_LANGUAGES = ['JavaScript', 'TypeScript', 'Python'];
7
+
8
+ /**
9
+ * @param {string} url
10
+ * @returns {Promise<unknown>}
11
+ */
12
+ exports.httpsGet = async (url) => {
13
+ return new Promise((resolve, reject) => {
14
+ https.get(url, (response) => {
15
+ if (response.statusCode === 301 || response.statusCode === 302) {
16
+ resolve(exports.httpsGet(response.headers.location));
17
+ } else {
18
+ resolve(response);
19
+ }
20
+ }).on('error', reject);
21
+ });
22
+ };
23
+
24
+ /**
25
+ * @param {string} maybeActorName
26
+ * @returns {Promise<string>}
27
+ */
28
+ exports.ensureValidActorName = async (maybeActorName) => {
29
+ if (maybeActorName) {
30
+ validateActorName(maybeActorName);
31
+ return maybeActorName;
32
+ }
33
+ return promptActorName();
34
+ };
35
+
36
+ /**
37
+ * @param {string} maybeTemplateName
38
+ * @param {Promise<object>} manifestPromise
39
+ * @returns {Promise<object>}
40
+ */
41
+ exports.getTemplateDefinition = async (maybeTemplateName, manifestPromise) => {
42
+ const manifest = await manifestPromise;
43
+ // If the fetch failed earlier, the resolve value of
44
+ // the promise will be the error from fetching the manifest.
45
+ if (manifest instanceof Error) throw manifest;
46
+
47
+ if (maybeTemplateName) {
48
+ const templateDefinition = manifest.templates.find((t) => t.name === maybeTemplateName);
49
+ if (!templateDefinition) {
50
+ throw new Error(`Could not find the selected template: ${maybeTemplateName} in the list of templates.`);
51
+ }
52
+ return templateDefinition;
53
+ }
54
+
55
+ return executePrompts(manifest);
56
+ };
57
+
58
+ /**
59
+ * Inquirer does not have a native way to "go back" between prompts.
60
+ * @param {object} manifest
61
+ * @returns {Promise<object>}
62
+ */
63
+ async function executePrompts(manifest) {
64
+ const programmingLanguage = await promptProgrammingLanguage();
65
+ // eslint-disable-next-line no-constant-condition
66
+ while (true) {
67
+ const templateDefinition = await promptTemplateDefinition(manifest, programmingLanguage);
68
+ if (templateDefinition) {
69
+ const shouldInstall = await promptTemplateInstallation(templateDefinition);
70
+ if (shouldInstall) {
71
+ return templateDefinition;
72
+ }
73
+ } else {
74
+ return executePrompts(manifest);
75
+ }
76
+ }
77
+ }
78
+
79
+ /**
80
+ * @returns {Promise<string>}
81
+ */
82
+ async function promptActorName() {
83
+ const answer = await inquirer.prompt([{
84
+ name: 'actorName',
85
+ message: 'Name of your new actor:',
86
+ type: 'input',
87
+ validate: (promptText) => {
88
+ try {
89
+ validateActorName(promptText);
90
+ } catch (err) {
91
+ return err.message;
92
+ }
93
+ return true;
94
+ },
95
+ }]);
96
+ return answer.actorName;
97
+ }
98
+
99
+ /**
100
+ * @returns {Promise<string>}
101
+ */
102
+ async function promptProgrammingLanguage() {
103
+ const answer = await inquirer.prompt([{
104
+ type: 'list',
105
+ name: 'programmingLanguage',
106
+ message: 'Choose the programming language of your new actor:',
107
+ default: PROGRAMMING_LANGUAGES[0],
108
+ choices: PROGRAMMING_LANGUAGES,
109
+ loop: false,
110
+ }]);
111
+ return answer.programmingLanguage;
112
+ }
113
+
114
+ /**
115
+ * @param {object} manifest
116
+ * @param {string} programmingLanguage
117
+ * @returns {Promise<object>} template definition
118
+ */
119
+ async function promptTemplateDefinition(manifest, programmingLanguage) {
120
+ const choices = manifest.templates
121
+ .filter((t) => {
122
+ return t.category.toLowerCase() === programmingLanguage.toLowerCase();
123
+ })
124
+ .map((t) => {
125
+ return {
126
+ name: t.label,
127
+ value: t,
128
+ };
129
+ });
130
+
131
+ choices.push(new inquirer.Separator());
132
+ choices.push({
133
+ name: 'Go back',
134
+ value: false,
135
+ });
136
+
137
+ const answer = await inquirer.prompt([{
138
+ type: 'list',
139
+ name: 'templateDefinition',
140
+ message: 'Choose a template for your new actor. Detailed information about the template will be shown in the next step.',
141
+ default: choices[0],
142
+ choices,
143
+ loop: false,
144
+ pageSize: 8,
145
+ }]);
146
+
147
+ return answer.templateDefinition;
148
+ }
149
+
150
+ /**
151
+ * @param {object} templateDefinition
152
+ * @returns {Promise<string>}
153
+ */
154
+ async function promptTemplateInstallation(templateDefinition) {
155
+ const choices = [{ name: `Install template`, value: true }];
156
+ choices.push(new inquirer.Separator());
157
+ choices.push({ name: 'Go back', value: false });
158
+
159
+ const message = 'Do you want to install the following template?';
160
+ const label = chalk.underline(templateDefinition.label);
161
+ const description = chalk.dim(templateDefinition.description);
162
+ const suffix = `\n ${label}:\n ${description}`;
163
+
164
+ const answer = await inquirer.prompt([{
165
+ type: 'list',
166
+ name: 'shouldInstall',
167
+ message,
168
+ suffix,
169
+ default: choices[0],
170
+ choices,
171
+ loop: false,
172
+ }]);
173
+
174
+ return answer.shouldInstall;
175
+ }
package/src/lib/utils.js CHANGED
@@ -98,14 +98,14 @@ const getLoggedClientOrThrow = async () => {
98
98
  * @param {String|null|undefined} token
99
99
  * @returns {Object}
100
100
  */
101
- const getApifyClientOptions = (token) => {
101
+ const getApifyClientOptions = (token, apiBaseUrl) => {
102
102
  if (!token && fs.existsSync(GLOBAL_CONFIGS_FOLDER) && fs.existsSync(AUTH_FILE_PATH)) {
103
103
  ({ token } = loadJson.sync(AUTH_FILE_PATH));
104
104
  }
105
105
 
106
106
  return {
107
107
  token,
108
- baseUrl: process.env.APIFY_CLIENT_BASE_URL,
108
+ baseUrl: apiBaseUrl || process.env.APIFY_CLIENT_BASE_URL,
109
109
  requestInterceptors: [(config) => {
110
110
  config.headers = { ...APIFY_CLIENT_DEFAULT_HEADERS, ...config.headers };
111
111
  return config;
@@ -119,8 +119,12 @@ const getApifyClientOptions = (token) => {
119
119
  * @param [token]
120
120
  * @return {Promise<*>}
121
121
  */
122
- const getLoggedClient = async (token) => {
123
- const apifyClient = new ApifyClient(getApifyClientOptions(token));
122
+ const getLoggedClient = async (token, apiBaseUrl) => {
123
+ if (!token && fs.existsSync(GLOBAL_CONFIGS_FOLDER) && fs.existsSync(AUTH_FILE_PATH)) {
124
+ ({ token } = loadJson.sync(AUTH_FILE_PATH));
125
+ }
126
+
127
+ const apifyClient = new ApifyClient(getApifyClientOptions(token, apiBaseUrl));
124
128
  let userInfo;
125
129
  try {
126
130
  userInfo = await apifyClient.user('me').get();
@@ -1,5 +1,5 @@
1
+ const axios = require('axios');
1
2
  const chalk = require('chalk');
2
- const { spawn } = require('cross-spawn');
3
3
  const semver = require('semver');
4
4
  const {
5
5
  CHECK_VERSION_EVERY_MILLIS,
@@ -13,16 +13,28 @@ const {
13
13
  extendLocalState,
14
14
  } = require('./local_state');
15
15
 
16
- const getLatestNpmVersion = () => spawn.sync('npm', ['view', 'apify-cli', 'version']).stdout.toString().trim();
16
+ const getLatestNpmVersion = async () => {
17
+ const response = await axios({
18
+ url: 'https://registry.npmjs.org/apify-cli/',
19
+ headers: {
20
+ // This is necessary so that NPM returns the abbreviated version of the metadata
21
+ // See https://github.com/npm/registry/blob/master/docs/responses/package-metadata.md
22
+ accept: 'application/vnd.npm.install-v1+json',
23
+ },
24
+ });
25
+ const packageMetadata = response.data;
26
+ const latestVersion = packageMetadata['dist-tags'].latest;
27
+ return latestVersion;
28
+ };
17
29
 
18
30
  /**
19
31
  * Fetches the latest NPM version of Apify CLI and caches it locally.
20
32
  */
21
- const getAndCacheLatestNpmVersion = () => {
33
+ const getAndCacheLatestNpmVersion = async () => {
22
34
  try {
23
35
  info('Making sure that Apify CLI is up to date...');
24
36
 
25
- const latestNpmVersion = getLatestNpmVersion();
37
+ const latestNpmVersion = await getLatestNpmVersion();
26
38
 
27
39
  extendLocalState({
28
40
  latestNpmVersion,
@@ -54,7 +66,7 @@ const checkLatestVersion = async (enforeUpdate = false) => {
54
66
  // If check is outdated and we are online then update the current NPM version.
55
67
  const shouldGetCurrentVersion = enforeUpdate || (isCheckOutdated && await isOnline.default({ timeout: 500 }));
56
68
  const latestNpmVersion = shouldGetCurrentVersion
57
- ? getAndCacheLatestNpmVersion()
69
+ ? await getAndCacheLatestNpmVersion()
58
70
  : cachedLatestNpmVersion;
59
71
 
60
72
  const currentNpmVersion = require('../../package.json').version; // eslint-disable-line