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.
- package/README.md +25 -21
- package/npm-shrinkwrap.json +1102 -536
- package/oclif.manifest.json +1 -1
- package/package.json +104 -104
- package/src/commands/create.js +22 -52
- package/src/commands/login-new.js +164 -0
- package/src/lib/create-utils.js +175 -0
- package/src/lib/utils.js +8 -4
- package/src/lib/version_check.js +17 -5
|
@@ -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
|
-
|
|
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();
|
package/src/lib/version_check.js
CHANGED
|
@@ -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 = () =>
|
|
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
|