@webiny/cli 5.25.0 → 5.25.1-beta.0
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/CHANGELOG.md +17 -0
- package/commands/wcp/hooks.js +1 -1
- package/commands/wcp/index.js +6 -3
- package/commands/wcp/login.js +163 -126
- package/commands/wcp/logout.js +28 -0
- package/commands/wcp/project.js +152 -175
- package/commands/wcp/{api → utils}/getProjectEnvironmentBySlug.js +3 -3
- package/commands/wcp/{api → utils}/getUser.js +28 -22
- package/commands/wcp/utils/getWcpPat.js +5 -0
- package/commands/wcp/{api → utils}/index.js +11 -1
- package/commands/wcp/utils/setProjectId.js +44 -0
- package/commands/wcp/utils/setWcpPat.js +5 -0
- package/commands/wcp/utils/sleep.js +1 -0
- package/commands/wcp/{api → utils}/updateUserLastActiveOn.js +2 -2
- package/commands/wcp/whoami.js +43 -0
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,23 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [5.25.1-beta.0](https://github.com/webiny/webiny-js/compare/v5.25.0...v5.25.1-beta.0) (2022-05-10)
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
### Bug Fixes
|
|
10
|
+
|
|
11
|
+
* improve DX in WCP-related Webiny CLI commands ([15fe881](https://github.com/webiny/webiny-js/commit/15fe881374e5199f002a37ce1b8aab805651882a))
|
|
12
|
+
* improve telemetry client ([a036766](https://github.com/webiny/webiny-js/commit/a036766272a71b5fc9d355ce2ec1607d2e670020))
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* **wcp:** improve WCP-related Webiny CLI commands ([5664d5e](https://github.com/webiny/webiny-js/commit/5664d5ebd915c739707d4bcde4d3e0005ee5fe30))
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
6
23
|
# [5.25.0](https://github.com/webiny/webiny-js/compare/v5.25.0-beta.6...v5.25.0) (2022-04-04)
|
|
7
24
|
|
|
8
25
|
**Note:** Version bump only for package @webiny/cli
|
package/commands/wcp/hooks.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const { getUser, getProjectEnvironmentBySlug, updateUserLastActiveOn } = require("./
|
|
1
|
+
const { getUser, getProjectEnvironmentBySlug, updateUserLastActiveOn } = require("./utils");
|
|
2
2
|
|
|
3
3
|
module.exports = () => [
|
|
4
4
|
// Within this hook, we're setting the `WCP_ENVIRONMENT_API_KEY` env variable, which can then be used in
|
package/commands/wcp/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
const login = require("./login");
|
|
2
|
-
const
|
|
1
|
+
const { command: login } = require("./login");
|
|
2
|
+
const { command: logout } = require("./logout");
|
|
3
|
+
const { command: whoami } = require("./whoami");
|
|
4
|
+
const { command: project } = require("./project");
|
|
5
|
+
|
|
3
6
|
const hooks = require("./hooks");
|
|
4
7
|
|
|
5
|
-
module.exports = [login(), project(), hooks()];
|
|
8
|
+
module.exports = [login(), logout(), whoami(), project(), hooks()];
|
package/commands/wcp/login.js
CHANGED
|
@@ -1,12 +1,25 @@
|
|
|
1
1
|
const open = require("open");
|
|
2
2
|
const { GraphQLClient } = require("graphql-request");
|
|
3
|
-
const {
|
|
3
|
+
const { WCP_GRAPHQL_API_URL, WCP_APP_URL, setProjectId, setWcpPat, sleep } = require("./utils");
|
|
4
|
+
const chalk = require("chalk");
|
|
4
5
|
|
|
5
6
|
// 120 retries * 2000ms interval = 4 minutes until the command returns an error.
|
|
6
7
|
const LOGIN_RETRIES_COUNT = 30;
|
|
7
8
|
const LOGIN_RETRIES_INTERVAL = 2000;
|
|
8
9
|
|
|
9
|
-
const
|
|
10
|
+
const USER_PAT_FIELDS = /* GraphQL */ `
|
|
11
|
+
fragment UserPatFields on UserPat {
|
|
12
|
+
name
|
|
13
|
+
meta
|
|
14
|
+
token
|
|
15
|
+
expiresOn
|
|
16
|
+
user {
|
|
17
|
+
email
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const GENERATE_USER_PAT = /* GraphQL */ `
|
|
10
23
|
mutation GenerateUserPat {
|
|
11
24
|
users {
|
|
12
25
|
generateUserPat
|
|
@@ -14,28 +27,41 @@ const GENERATE_USER_PAT = /* GraphQL*/ `
|
|
|
14
27
|
}
|
|
15
28
|
`;
|
|
16
29
|
|
|
17
|
-
const GET_USER_PAT = /* GraphQL*/ `
|
|
30
|
+
const GET_USER_PAT = /* GraphQL */ `
|
|
31
|
+
${USER_PAT_FIELDS}
|
|
18
32
|
query GetUserPat($token: ID!) {
|
|
19
33
|
users {
|
|
20
34
|
getUserPat(token: $token) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
35
|
+
...UserPatFields
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
const CREATE_USER_PAT = /* GraphQL */ `
|
|
42
|
+
${USER_PAT_FIELDS}
|
|
43
|
+
mutation CreateUserPat($expiresIn: Int, $token: ID, $data: CreateUserPatDataInput) {
|
|
44
|
+
users {
|
|
45
|
+
createUserPat(expiresIn: $expiresIn, token: $token, data: $data) {
|
|
46
|
+
...UserPatFields
|
|
25
47
|
}
|
|
26
48
|
}
|
|
27
49
|
}
|
|
28
50
|
`;
|
|
29
51
|
|
|
30
|
-
module.exports = () => ({
|
|
52
|
+
module.exports.command = () => ({
|
|
31
53
|
type: "cli-command",
|
|
32
54
|
name: "cli-command-wcp-login",
|
|
33
55
|
create({ yargs, context }) {
|
|
34
56
|
yargs.command(
|
|
35
|
-
"login",
|
|
57
|
+
"login [pat]",
|
|
36
58
|
`Log in to the Webiny Control Panel`,
|
|
37
59
|
yargs => {
|
|
38
60
|
yargs.example("$0 login");
|
|
61
|
+
yargs.positional("pat", {
|
|
62
|
+
describe: `Personal access token (PAT)`,
|
|
63
|
+
type: "string"
|
|
64
|
+
});
|
|
39
65
|
yargs.option("debug", {
|
|
40
66
|
describe: `Turn on debug logs`,
|
|
41
67
|
type: "boolean"
|
|
@@ -46,142 +72,153 @@ module.exports = () => ({
|
|
|
46
72
|
type: "number"
|
|
47
73
|
});
|
|
48
74
|
},
|
|
49
|
-
async ({ debug, debugLevel }) => {
|
|
50
|
-
const graphQLClient = new GraphQLClient(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
75
|
+
async ({ debug, debugLevel, pat: patFromParams }) => {
|
|
76
|
+
const graphQLClient = new GraphQLClient(WCP_GRAPHQL_API_URL);
|
|
77
|
+
|
|
78
|
+
let pat;
|
|
79
|
+
|
|
80
|
+
if (patFromParams) {
|
|
81
|
+
try {
|
|
82
|
+
graphQLClient.setHeaders({ authorization: patFromParams });
|
|
83
|
+
pat = await graphQLClient
|
|
84
|
+
.request(GET_USER_PAT, { token: patFromParams })
|
|
85
|
+
.then(({ users }) => users.getUserPat);
|
|
86
|
+
|
|
87
|
+
// If we've received a PAT that has expiration, let's create a long-lived PAT.
|
|
88
|
+
// We don't want to have our users interrupted because of an expired PAT.
|
|
89
|
+
if (pat.expiresOn) {
|
|
90
|
+
pat = await graphQLClient
|
|
91
|
+
.request(CREATE_USER_PAT, { data: { meta: pat.meta } })
|
|
92
|
+
.then(({ users }) => users.createUserPat);
|
|
93
|
+
}
|
|
94
|
+
} catch (e) {
|
|
95
|
+
if (debug) {
|
|
96
|
+
context.debug(
|
|
97
|
+
`Could not use the provided ${context.debug.hl(
|
|
98
|
+
patFromParams
|
|
99
|
+
)} PAT because of the following error:`
|
|
100
|
+
);
|
|
101
|
+
console.debug(e);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
throw new Error(
|
|
105
|
+
`Invalid PAT received. Please try again or login manually via the ${context.error.hl(
|
|
106
|
+
"yarn webiny login"
|
|
107
|
+
)} command.`
|
|
108
|
+
);
|
|
67
109
|
}
|
|
68
|
-
}
|
|
110
|
+
} else {
|
|
111
|
+
const generatedPat = await graphQLClient
|
|
112
|
+
.request(GENERATE_USER_PAT)
|
|
113
|
+
.then(({ users }) => users.generateUserPat);
|
|
114
|
+
|
|
115
|
+
const queryParams = `pat=${generatedPat}&pat_name=${encodeURIComponent(
|
|
116
|
+
"Webiny CLI"
|
|
117
|
+
)}&ref=cli`;
|
|
118
|
+
const openUrl = `${WCP_APP_URL}/login/cli?${queryParams}`;
|
|
119
|
+
|
|
120
|
+
debug && context.debug(`Opening ${context.debug.hl(openUrl)}...`);
|
|
121
|
+
await open(openUrl);
|
|
122
|
+
|
|
123
|
+
const graphql = {
|
|
124
|
+
variables: { token: generatedPat },
|
|
125
|
+
headers: {
|
|
126
|
+
Authorization: generatedPat
|
|
127
|
+
}
|
|
128
|
+
};
|
|
69
129
|
|
|
70
|
-
|
|
130
|
+
graphQLClient.setHeaders(graphql.headers);
|
|
71
131
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
132
|
+
let retries = 0;
|
|
133
|
+
const result = await new Promise(resolve => {
|
|
134
|
+
const interval = setInterval(async () => {
|
|
135
|
+
retries++;
|
|
136
|
+
if (retries > LOGIN_RETRIES_COUNT) {
|
|
137
|
+
clearInterval(interval);
|
|
138
|
+
resolve(null);
|
|
139
|
+
}
|
|
80
140
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
141
|
+
try {
|
|
142
|
+
const pat = await graphQLClient
|
|
143
|
+
.request(GET_USER_PAT, graphql.variables)
|
|
144
|
+
.then(({ users }) => users.getUserPat);
|
|
145
|
+
|
|
146
|
+
clearInterval(interval);
|
|
147
|
+
resolve(pat);
|
|
148
|
+
} catch (e) {
|
|
149
|
+
// Do nothing.
|
|
150
|
+
if (debug) {
|
|
151
|
+
context.debug(
|
|
152
|
+
`Could not login. Will try again in ${LOGIN_RETRIES_INTERVAL}ms.`
|
|
153
|
+
);
|
|
154
|
+
if (debugLevel > 1) {
|
|
155
|
+
context.debug("GraphQL Request: ");
|
|
156
|
+
console.log(JSON.stringify(graphql, null, 2));
|
|
157
|
+
}
|
|
158
|
+
if (debugLevel > 2) {
|
|
159
|
+
context.debug(e.message);
|
|
160
|
+
}
|
|
97
161
|
}
|
|
98
162
|
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
});
|
|
163
|
+
}, LOGIN_RETRIES_INTERVAL);
|
|
164
|
+
});
|
|
102
165
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
166
|
+
if (!result) {
|
|
167
|
+
throw new Error(
|
|
168
|
+
`Could not login. Did you complete the sign in / sign up process at ${WCP_APP_URL}?`
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
pat = result;
|
|
107
173
|
}
|
|
108
174
|
|
|
109
|
-
|
|
175
|
+
setWcpPat(pat.token);
|
|
110
176
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
177
|
+
console.log(
|
|
178
|
+
`${chalk.green("✔")} You've successfully logged in to Webiny Control Panel.`
|
|
179
|
+
);
|
|
114
180
|
|
|
115
|
-
|
|
116
|
-
"logout",
|
|
117
|
-
`Log out from the Webiny Control Panel`,
|
|
118
|
-
yargs => {
|
|
119
|
-
yargs.example("$0 login");
|
|
120
|
-
yargs.option("debug", {
|
|
121
|
-
describe: `Turn on debug logs`,
|
|
122
|
-
type: "boolean"
|
|
123
|
-
});
|
|
124
|
-
yargs.option("debug-level", {
|
|
125
|
-
default: 1,
|
|
126
|
-
describe: `Set the debug logs verbosity level`,
|
|
127
|
-
type: "number"
|
|
128
|
-
});
|
|
129
|
-
},
|
|
130
|
-
async () => {
|
|
131
|
-
context.info(`You've successfully logged out from Webiny Control Panel.`);
|
|
181
|
+
let projectInitialized = Boolean(context.project.config.id);
|
|
132
182
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
183
|
+
// If we have `orgId` and `projectId` in PAT's meta data, let's immediately activate the project.
|
|
184
|
+
if (pat.meta && pat.meta.orgId && pat.meta.projectId) {
|
|
185
|
+
await sleep();
|
|
136
186
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (!pat) {
|
|
155
|
-
throw new Error(
|
|
156
|
-
`It seems you are not logged in. Please login using the ${context.error.hl(
|
|
157
|
-
"webiny login"
|
|
158
|
-
)} command.`
|
|
159
|
-
);
|
|
187
|
+
console.log();
|
|
188
|
+
|
|
189
|
+
const { orgId, projectId } = pat.meta;
|
|
190
|
+
|
|
191
|
+
const id = `${orgId}/${projectId}`;
|
|
192
|
+
console.log(`Project ${chalk.green(id)} detected. Initializing...`);
|
|
193
|
+
|
|
194
|
+
await sleep();
|
|
195
|
+
|
|
196
|
+
await setProjectId({
|
|
197
|
+
project: context.project,
|
|
198
|
+
orgId,
|
|
199
|
+
projectId
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
console.log(`Project ${context.success.hl(id)} initialized successfully.`);
|
|
203
|
+
projectInitialized = true;
|
|
160
204
|
}
|
|
161
205
|
|
|
162
|
-
|
|
163
|
-
graphQLClient.setHeaders({ authorization: pat });
|
|
206
|
+
await sleep();
|
|
164
207
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
.request(GET_USER_PAT, { token: pat })
|
|
168
|
-
.then(({ users }) => users.getUserPat.user);
|
|
208
|
+
console.log();
|
|
209
|
+
console.log(chalk.bold("Next Steps"));
|
|
169
210
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
} catch (e) {
|
|
176
|
-
if (debug) {
|
|
177
|
-
context.debug(e);
|
|
178
|
-
}
|
|
179
|
-
throw new Error(
|
|
180
|
-
`It seems you are not logged in. Please login using the ${context.error.hl(
|
|
181
|
-
"webiny login"
|
|
182
|
-
)} command.`
|
|
211
|
+
if (!projectInitialized) {
|
|
212
|
+
console.log(
|
|
213
|
+
`‣ initialize your project via the ${chalk.green(
|
|
214
|
+
"yarn webiny project init"
|
|
215
|
+
)} command`
|
|
183
216
|
);
|
|
184
217
|
}
|
|
218
|
+
|
|
219
|
+
console.log(
|
|
220
|
+
`‣ deploy your project via the ${chalk.green("yarn webiny deploy")} command`
|
|
221
|
+
);
|
|
185
222
|
}
|
|
186
223
|
);
|
|
187
224
|
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const { setWcpPat } = require("./utils");
|
|
2
|
+
|
|
3
|
+
module.exports.command = () => ({
|
|
4
|
+
type: "cli-command",
|
|
5
|
+
name: "cli-command-wcp-logout",
|
|
6
|
+
create({ yargs }) {
|
|
7
|
+
yargs.command(
|
|
8
|
+
"logout",
|
|
9
|
+
`Log out from the Webiny Control Panel`,
|
|
10
|
+
yargs => {
|
|
11
|
+
yargs.example("$0 logout");
|
|
12
|
+
yargs.option("debug", {
|
|
13
|
+
describe: `Turn on debug logs`,
|
|
14
|
+
type: "boolean"
|
|
15
|
+
});
|
|
16
|
+
yargs.option("debug-level", {
|
|
17
|
+
default: 1,
|
|
18
|
+
describe: `Set the debug logs verbosity level`,
|
|
19
|
+
type: "number"
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
async () => {
|
|
23
|
+
setWcpPat(null);
|
|
24
|
+
console.log(`You've successfully logged out from Webiny Control Panel.`);
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
});
|
package/commands/wcp/project.js
CHANGED
|
@@ -1,11 +1,9 @@
|
|
|
1
|
-
const { getUser } = require("./api");
|
|
2
|
-
const { WCP_APP_URL } = require("./api");
|
|
3
1
|
const open = require("open");
|
|
4
2
|
const inquirer = require("inquirer");
|
|
5
|
-
const
|
|
6
|
-
const
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const { getUser, WCP_APP_URL, setProjectId, sleep } = require("./utils");
|
|
7
5
|
|
|
8
|
-
module.exports = () => [
|
|
6
|
+
module.exports.command = () => [
|
|
9
7
|
{
|
|
10
8
|
type: "cli-command",
|
|
11
9
|
name: "cli-command-wcp-project",
|
|
@@ -29,179 +27,158 @@ module.exports = () => [
|
|
|
29
27
|
});
|
|
30
28
|
command.example("$0 project init");
|
|
31
29
|
},
|
|
32
|
-
|
|
33
|
-
// Check login.
|
|
34
|
-
const user = await getUser();
|
|
35
|
-
|
|
36
|
-
// User already initialized a project?
|
|
37
|
-
const { id } = context.project.config;
|
|
38
|
-
if (id) {
|
|
39
|
-
const project = user.projects.find(item => item.id === id);
|
|
40
|
-
if (project) {
|
|
41
|
-
context.info(
|
|
42
|
-
`It seems this project was already initialized (project name: ${context.info.hl(
|
|
43
|
-
project.name
|
|
44
|
-
)}).`
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
const prompt = inquirer.createPromptModule();
|
|
48
|
-
const { proceed } = await prompt({
|
|
49
|
-
name: "proceed",
|
|
50
|
-
message: "Would you like to re-initialize it?",
|
|
51
|
-
type: "confirm",
|
|
52
|
-
default: false
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
if (!proceed) {
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Get user's organizations.
|
|
62
|
-
if (!user.orgs.length) {
|
|
63
|
-
context.info(
|
|
64
|
-
"It seems you're not part of any organization. Please log in to Webiny Control Panel and create one."
|
|
65
|
-
);
|
|
66
|
-
|
|
67
|
-
const prompt = inquirer.createPromptModule();
|
|
68
|
-
const { proceed } = await prompt({
|
|
69
|
-
name: "proceed",
|
|
70
|
-
message: "Would you like to do that now?",
|
|
71
|
-
type: "confirm",
|
|
72
|
-
default: false
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
if (proceed) {
|
|
76
|
-
await open(WCP_APP_URL);
|
|
77
|
-
}
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
let selectedOrg;
|
|
82
|
-
if (user.orgs.length === 1) {
|
|
83
|
-
selectedOrg = user.orgs[0];
|
|
84
|
-
} else {
|
|
85
|
-
context.info("It seems you're part of multiple organizations. ");
|
|
86
|
-
const choices = user.orgs.map(item => ({
|
|
87
|
-
name: item.name,
|
|
88
|
-
value: item
|
|
89
|
-
}));
|
|
90
|
-
|
|
91
|
-
const prompt = inquirer.createPromptModule();
|
|
92
|
-
selectedOrg = await prompt({
|
|
93
|
-
name: "org",
|
|
94
|
-
message: "Select organization:",
|
|
95
|
-
type: "list",
|
|
96
|
-
choices,
|
|
97
|
-
default: choices[0].value
|
|
98
|
-
}).then(result => result.org);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const orgProjects = user.projects.filter(
|
|
102
|
-
item => item.org.id === selectedOrg.id
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
// Get user's projects.
|
|
106
|
-
if (!orgProjects.length) {
|
|
107
|
-
context.info(
|
|
108
|
-
`It seems there are no projects created within the ${context.info.hl(
|
|
109
|
-
selectedOrg.name
|
|
110
|
-
)} organization.`
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
const prompt = inquirer.createPromptModule();
|
|
114
|
-
const { proceed } = await prompt({
|
|
115
|
-
name: "proceed",
|
|
116
|
-
message: "Would you like to create one now?",
|
|
117
|
-
type: "confirm",
|
|
118
|
-
default: false
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
if (proceed) {
|
|
122
|
-
await open(WCP_APP_URL);
|
|
123
|
-
}
|
|
124
|
-
return;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
let selectedProject;
|
|
128
|
-
if (orgProjects.length === 1) {
|
|
129
|
-
selectedProject = user.projects[0];
|
|
130
|
-
} else {
|
|
131
|
-
context.info(
|
|
132
|
-
`It seems there are multiple projects created within the ${context.info.hl(
|
|
133
|
-
selectedOrg.name
|
|
134
|
-
)} organization.`
|
|
135
|
-
);
|
|
136
|
-
const choices = orgProjects.map(item => ({
|
|
137
|
-
name: item.name,
|
|
138
|
-
value: item
|
|
139
|
-
}));
|
|
140
|
-
const prompt = inquirer.createPromptModule();
|
|
141
|
-
selectedProject = await prompt({
|
|
142
|
-
name: "project",
|
|
143
|
-
message: "Select project:",
|
|
144
|
-
type: "list",
|
|
145
|
-
choices,
|
|
146
|
-
default: choices[0].value
|
|
147
|
-
}).then(result => result.project);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Assign the necessary IDs into root `webiny.project.ts` project file.
|
|
151
|
-
const webinyProjectPath = path.join(
|
|
152
|
-
context.project.root,
|
|
153
|
-
"webiny.project.ts"
|
|
154
|
-
);
|
|
155
|
-
|
|
156
|
-
const tsMorphProject = new tsMorph.Project();
|
|
157
|
-
tsMorphProject.addSourceFileAtPath(webinyProjectPath);
|
|
158
|
-
|
|
159
|
-
const source = tsMorphProject.getSourceFile(webinyProjectPath);
|
|
160
|
-
|
|
161
|
-
const defaultExport = source.getFirstDescendant(node => {
|
|
162
|
-
if (tsMorph.Node.isExportAssignment(node) === false) {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
return node.getText().startsWith("export default ");
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
if (!defaultExport) {
|
|
169
|
-
throw new Error(
|
|
170
|
-
`Could not find the default export in ${context.error.hl(
|
|
171
|
-
"webiny.project.ts"
|
|
172
|
-
)}.`
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// Get ObjectLiteralExpression within the default export and assign the `id` property to it.
|
|
177
|
-
const exportedObjectLiteral = defaultExport.getFirstDescendant(
|
|
178
|
-
node => tsMorph.Node.isObjectLiteralExpression(node) === true
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
const existingIdProperty = exportedObjectLiteral.getProperty(node => {
|
|
182
|
-
return (
|
|
183
|
-
tsMorph.Node.isPropertyAssignment(node) &&
|
|
184
|
-
node.getName() === "id"
|
|
185
|
-
);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
if (tsMorph.Node.isPropertyAssignment(existingIdProperty)) {
|
|
189
|
-
existingIdProperty.setInitializer(`"${selectedProject.id}"`);
|
|
190
|
-
} else {
|
|
191
|
-
exportedObjectLiteral.insertProperty(
|
|
192
|
-
0,
|
|
193
|
-
`id: "${selectedOrg.id}/${selectedProject.id}"`
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
await tsMorphProject.save();
|
|
198
|
-
}
|
|
30
|
+
() => handler({ context })
|
|
199
31
|
);
|
|
200
32
|
}
|
|
201
33
|
);
|
|
202
34
|
}
|
|
203
|
-
},
|
|
204
|
-
{
|
|
205
|
-
type: "cli-plugi"
|
|
206
35
|
}
|
|
207
36
|
];
|
|
37
|
+
|
|
38
|
+
const handler = async ({ context }) => {
|
|
39
|
+
// Check login.
|
|
40
|
+
const user = await getUser();
|
|
41
|
+
|
|
42
|
+
// User already initialized a project?
|
|
43
|
+
const { id: orgProjectId } = context.project.config;
|
|
44
|
+
if (orgProjectId) {
|
|
45
|
+
const [, projectId] = orgProjectId.split("/");
|
|
46
|
+
const project = user.projects.find(item => item.id === projectId);
|
|
47
|
+
if (project) {
|
|
48
|
+
console.log(`Your ${chalk.green(orgProjectId)} project has already been initialized.`);
|
|
49
|
+
|
|
50
|
+
const prompt = inquirer.createPromptModule();
|
|
51
|
+
const { proceed } = await prompt({
|
|
52
|
+
name: "proceed",
|
|
53
|
+
message: "Would you like to re-initialize it?",
|
|
54
|
+
type: "confirm",
|
|
55
|
+
default: false
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
if (!proceed) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Get user's organizations.
|
|
67
|
+
if (!user.orgs.length) {
|
|
68
|
+
console.log(
|
|
69
|
+
"It seems you're not part of any organization. Please log in to Webiny Control Panel and create one."
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
const prompt = inquirer.createPromptModule();
|
|
73
|
+
const { proceed } = await prompt({
|
|
74
|
+
name: "proceed",
|
|
75
|
+
message: "Would you like to do that now?",
|
|
76
|
+
type: "confirm",
|
|
77
|
+
default: false
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (proceed) {
|
|
81
|
+
await open(WCP_APP_URL);
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let selectedOrg;
|
|
87
|
+
if (user.orgs.length === 1) {
|
|
88
|
+
selectedOrg = user.orgs[0];
|
|
89
|
+
} else {
|
|
90
|
+
console.log("It seems you're part of multiple organizations. ");
|
|
91
|
+
const choices = user.orgs.map(item => ({
|
|
92
|
+
name: item.name,
|
|
93
|
+
value: item
|
|
94
|
+
}));
|
|
95
|
+
|
|
96
|
+
const prompt = inquirer.createPromptModule();
|
|
97
|
+
selectedOrg = await prompt({
|
|
98
|
+
name: "org",
|
|
99
|
+
message: "Select organization:",
|
|
100
|
+
type: "list",
|
|
101
|
+
choices,
|
|
102
|
+
default: choices[0].value
|
|
103
|
+
}).then(result => result.org);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const orgProjects = user.projects.filter(item => item.org.id === selectedOrg.id);
|
|
107
|
+
|
|
108
|
+
// Get user's projects.
|
|
109
|
+
if (!orgProjects.length) {
|
|
110
|
+
console.log(
|
|
111
|
+
`It seems there are no projects created within the ${chalk.green(
|
|
112
|
+
selectedOrg.name
|
|
113
|
+
)} organization.`
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
const prompt = inquirer.createPromptModule();
|
|
117
|
+
const { proceed } = await prompt({
|
|
118
|
+
name: "proceed",
|
|
119
|
+
message: "Would you like to create one now?",
|
|
120
|
+
type: "confirm",
|
|
121
|
+
default: false
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
if (proceed) {
|
|
125
|
+
await open(WCP_APP_URL);
|
|
126
|
+
}
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let selectedProject;
|
|
131
|
+
if (orgProjects.length === 1) {
|
|
132
|
+
selectedProject = user.projects[0];
|
|
133
|
+
} else {
|
|
134
|
+
console.log(
|
|
135
|
+
`It seems there are multiple projects created within the ${chalk.green(
|
|
136
|
+
selectedOrg.name
|
|
137
|
+
)} organization.`
|
|
138
|
+
);
|
|
139
|
+
const choices = orgProjects.map(item => ({
|
|
140
|
+
name: item.name,
|
|
141
|
+
value: item
|
|
142
|
+
}));
|
|
143
|
+
const prompt = inquirer.createPromptModule();
|
|
144
|
+
selectedProject = await prompt({
|
|
145
|
+
name: "project",
|
|
146
|
+
message: "Select project:",
|
|
147
|
+
type: "list",
|
|
148
|
+
choices,
|
|
149
|
+
default: choices[0].value
|
|
150
|
+
}).then(result => result.project);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const orgId = selectedOrg.id,
|
|
154
|
+
projectId = selectedProject.id;
|
|
155
|
+
|
|
156
|
+
await sleep();
|
|
157
|
+
console.log();
|
|
158
|
+
|
|
159
|
+
console.log(`Initializing ${context.success.hl(selectedProject.name)} project...`);
|
|
160
|
+
|
|
161
|
+
await sleep();
|
|
162
|
+
|
|
163
|
+
// Assign the necessary IDs into root `webiny.project.ts` project file.
|
|
164
|
+
await setProjectId({
|
|
165
|
+
project: context.project,
|
|
166
|
+
orgId,
|
|
167
|
+
projectId
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
console.log(
|
|
171
|
+
`${chalk.green("✔")} Project ${context.success.hl(
|
|
172
|
+
selectedProject.name
|
|
173
|
+
)} initialized successfully.`
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
await sleep();
|
|
177
|
+
|
|
178
|
+
console.log();
|
|
179
|
+
console.log(chalk.bold("Next Steps"));
|
|
180
|
+
|
|
181
|
+
console.log(`‣ deploy your project via the ${chalk.green("yarn webiny deploy")} command`);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
module.exports.handler = handler;
|
|
@@ -76,10 +76,10 @@ module.exports.getProjectEnvironmentBySlug = async ({
|
|
|
76
76
|
);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
const {
|
|
79
|
+
const { WCP_GRAPHQL_API_URL } = require(".");
|
|
80
80
|
const headers = { authorization: pat };
|
|
81
81
|
return request(
|
|
82
|
-
|
|
82
|
+
WCP_GRAPHQL_API_URL,
|
|
83
83
|
GET_ENVIRONMENT,
|
|
84
84
|
{
|
|
85
85
|
orgId,
|
|
@@ -92,7 +92,7 @@ module.exports.getProjectEnvironmentBySlug = async ({
|
|
|
92
92
|
.then(async response => response.projects.getEnvironment)
|
|
93
93
|
.catch(() => {
|
|
94
94
|
return request(
|
|
95
|
-
|
|
95
|
+
WCP_GRAPHQL_API_URL,
|
|
96
96
|
CREATE_ENVIRONMENT,
|
|
97
97
|
{
|
|
98
98
|
orgId,
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
const {
|
|
1
|
+
const { log } = require("@webiny/cli/utils");
|
|
2
2
|
const { request } = require("graphql-request");
|
|
3
|
+
const { getWcpPat } = require("./getWcpPat");
|
|
3
4
|
|
|
4
5
|
const GET_CURRENT_USER = /* GraphQL */ `
|
|
5
6
|
query GetUser {
|
|
6
7
|
users {
|
|
7
8
|
getCurrentUser {
|
|
8
9
|
id
|
|
10
|
+
email
|
|
9
11
|
firstName
|
|
10
12
|
lastName
|
|
11
13
|
}
|
|
@@ -49,39 +51,43 @@ module.exports.getUser = async () => {
|
|
|
49
51
|
return user;
|
|
50
52
|
}
|
|
51
53
|
|
|
52
|
-
const pat =
|
|
54
|
+
const pat = getWcpPat();
|
|
53
55
|
if (!pat) {
|
|
54
56
|
throw new Error(
|
|
55
57
|
`It seems you are not logged in. Please login using the ${log.error.hl(
|
|
56
|
-
"webiny login"
|
|
58
|
+
"yarn webiny login"
|
|
57
59
|
)} command.`
|
|
58
60
|
);
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
try {
|
|
62
|
-
const {
|
|
64
|
+
const { WCP_GRAPHQL_API_URL } = require(".");
|
|
63
65
|
const headers = { authorization: pat };
|
|
64
|
-
user = await request(
|
|
65
|
-
|
|
66
|
+
user = await request(WCP_GRAPHQL_API_URL, GET_CURRENT_USER, {}, headers).then(
|
|
67
|
+
async response => {
|
|
68
|
+
const user = response.users.getCurrentUser;
|
|
66
69
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
70
|
+
const orgs = await request(WCP_GRAPHQL_API_URL, LIST_ORGS, {}, headers).then(
|
|
71
|
+
async response => {
|
|
72
|
+
const orgs = response.orgs.listOrgs.data;
|
|
73
|
+
for (let i = 0; i < orgs.length; i++) {
|
|
74
|
+
const org = orgs[i];
|
|
75
|
+
org.projects = await request(
|
|
76
|
+
WCP_GRAPHQL_API_URL,
|
|
77
|
+
LIST_PROJECTS,
|
|
78
|
+
{ orgId: org.id },
|
|
79
|
+
headers
|
|
80
|
+
).then(response => response.projects.listProjects.data);
|
|
81
|
+
}
|
|
82
|
+
return orgs;
|
|
83
|
+
}
|
|
84
|
+
);
|
|
80
85
|
|
|
81
|
-
|
|
86
|
+
const projects = orgs.map(org => org.projects).flat();
|
|
82
87
|
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
return { ...user, orgs, projects };
|
|
89
|
+
}
|
|
90
|
+
);
|
|
85
91
|
} catch {
|
|
86
92
|
throw new Error(
|
|
87
93
|
`It seems the personal access token is incorrect or does not exist. Please log out and again log in using the ${log.error.hl(
|
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
const WCP_APP_URL = process.env.WCP_APP_URL || "https://wcp.webiny.com";
|
|
2
2
|
const WCP_API_URL = process.env.WCP_API_URL || "https://api.wcp.webiny.com/graphql";
|
|
3
|
+
const WCP_GRAPHQL_API_URL = WCP_API_URL + "/graphql";
|
|
3
4
|
|
|
4
5
|
const { getUser } = require("./getUser");
|
|
5
6
|
const { getProjectEnvironmentBySlug } = require("./getProjectEnvironmentBySlug");
|
|
6
7
|
const { updateUserLastActiveOn } = require("./updateUserLastActiveOn");
|
|
8
|
+
const { setProjectId } = require("./setProjectId");
|
|
9
|
+
const { setWcpPat } = require("./setWcpPat");
|
|
10
|
+
const { getWcpPat } = require("./getWcpPat");
|
|
11
|
+
const { sleep } = require("./sleep");
|
|
7
12
|
|
|
8
13
|
module.exports = {
|
|
9
14
|
getUser,
|
|
10
15
|
getProjectEnvironmentBySlug,
|
|
11
16
|
updateUserLastActiveOn,
|
|
17
|
+
setProjectId,
|
|
18
|
+
setWcpPat,
|
|
19
|
+
getWcpPat,
|
|
20
|
+
sleep,
|
|
12
21
|
WCP_APP_URL,
|
|
13
|
-
WCP_API_URL
|
|
22
|
+
WCP_API_URL,
|
|
23
|
+
WCP_GRAPHQL_API_URL
|
|
14
24
|
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
const path = require("path");
|
|
2
|
+
const tsMorph = require("ts-morph");
|
|
3
|
+
const { log } = require("@webiny/cli/utils");
|
|
4
|
+
|
|
5
|
+
module.exports.setProjectId = async ({ project, orgId, projectId }) => {
|
|
6
|
+
// Assign the necessary IDs into root `webiny.project.ts` project file.
|
|
7
|
+
const webinyProjectPath = path.join(project.root, "webiny.project.ts");
|
|
8
|
+
|
|
9
|
+
const tsMorphProject = new tsMorph.Project();
|
|
10
|
+
tsMorphProject.addSourceFileAtPath(webinyProjectPath);
|
|
11
|
+
|
|
12
|
+
const source = tsMorphProject.getSourceFile(webinyProjectPath);
|
|
13
|
+
|
|
14
|
+
const defaultExport = source.getFirstDescendant(node => {
|
|
15
|
+
if (tsMorph.Node.isExportAssignment(node) === false) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return node.getText().startsWith("export default ");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
if (!defaultExport) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Could not find the default export in ${log.error.hl("webiny.project.ts")}.`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// Get ObjectLiteralExpression within the default export and assign the `id` property to it.
|
|
28
|
+
const exportedObjectLiteral = defaultExport.getFirstDescendant(
|
|
29
|
+
node => tsMorph.Node.isObjectLiteralExpression(node) === true
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const existingIdProperty = exportedObjectLiteral.getProperty(node => {
|
|
33
|
+
return tsMorph.Node.isPropertyAssignment(node) && node.getName() === "id";
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
const fullId = `${orgId}/${projectId}`;
|
|
37
|
+
if (tsMorph.Node.isPropertyAssignment(existingIdProperty)) {
|
|
38
|
+
existingIdProperty.setInitializer(`"${fullId}"`);
|
|
39
|
+
} else {
|
|
40
|
+
exportedObjectLiteral.insertProperty(0, `id: "${fullId}"`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
await tsMorphProject.save();
|
|
44
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports.sleep = () => new Promise(resolve => setTimeout(resolve, 1500));
|
|
@@ -22,7 +22,7 @@ module.exports.updateUserLastActiveOn = async () => {
|
|
|
22
22
|
);
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
const {
|
|
25
|
+
const { WCP_GRAPHQL_API_URL } = require(".");
|
|
26
26
|
const headers = { authorization: pat };
|
|
27
|
-
return request(
|
|
27
|
+
return request(WCP_GRAPHQL_API_URL, UPDATE_LAST_ACTIVE_TO_NOW, {}, headers);
|
|
28
28
|
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const { getUser } = require("./utils");
|
|
2
|
+
|
|
3
|
+
module.exports.command = () => ({
|
|
4
|
+
type: "cli-command",
|
|
5
|
+
name: "cli-command-wcp-whoami",
|
|
6
|
+
create({ yargs, context }) {
|
|
7
|
+
yargs.command(
|
|
8
|
+
"whoami",
|
|
9
|
+
`Display the current logged-in user`,
|
|
10
|
+
yargs => {
|
|
11
|
+
yargs.example("$0 whoami");
|
|
12
|
+
yargs.option("debug", {
|
|
13
|
+
describe: `Turn on debug logs`,
|
|
14
|
+
type: "boolean"
|
|
15
|
+
});
|
|
16
|
+
yargs.option("debug-level", {
|
|
17
|
+
default: 1,
|
|
18
|
+
describe: `Set the debug logs verbosity level`,
|
|
19
|
+
type: "number"
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
async ({ debug }) => {
|
|
23
|
+
try {
|
|
24
|
+
const user = await getUser();
|
|
25
|
+
console.log(
|
|
26
|
+
`You are logged in to Webiny Control Panel as ${context.info.hl(
|
|
27
|
+
user.email
|
|
28
|
+
)}.`
|
|
29
|
+
);
|
|
30
|
+
} catch (e) {
|
|
31
|
+
if (debug) {
|
|
32
|
+
context.debug(e);
|
|
33
|
+
}
|
|
34
|
+
throw new Error(
|
|
35
|
+
`It seems you are not logged in. Please login using the ${context.error.hl(
|
|
36
|
+
"webiny login"
|
|
37
|
+
)} command.`
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webiny/cli",
|
|
3
|
-
"version": "5.25.0",
|
|
3
|
+
"version": "5.25.1-beta.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"bin": {
|
|
6
6
|
"webiny": "./bin.js"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"author": "Pavel Denisjuk <pavel@webiny.com>",
|
|
14
14
|
"description": "A tool to bootstrap a Webiny project.",
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@webiny/telemetry": "5.25.0",
|
|
16
|
+
"@webiny/telemetry": "5.25.1-beta.0",
|
|
17
17
|
"boolean": "3.1.4",
|
|
18
18
|
"camelcase": "5.3.1",
|
|
19
19
|
"chalk": "4.1.2",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"ts-morph": "11.0.3",
|
|
30
30
|
"typescript": "4.5.5",
|
|
31
31
|
"uniqid": "5.4.0",
|
|
32
|
-
"yargs": "
|
|
32
|
+
"yargs": "17.4.0"
|
|
33
33
|
},
|
|
34
34
|
"license": "MIT",
|
|
35
35
|
"publishConfig": {
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
]
|
|
64
64
|
}
|
|
65
65
|
},
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "887c9678ec12921eb00edb033e9f2c1a13e35fa5"
|
|
67
67
|
}
|