Skip to content

Commit 06cecf1

Browse files
committed
Merge branch 'refs/heads/feat-create-resources' into feat-pull-function
# Conflicts: # templates/cli/lib/questions.js.twig
2 parents abef847 + 634679a commit 06cecf1

File tree

7 files changed

+175
-97
lines changed

7 files changed

+175
-97
lines changed

src/SDK/Language/CLI.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,11 @@ public function getFiles(): array
172172
'destination' => 'lib/utils.js',
173173
'template' => 'cli/lib/utils.js.twig',
174174
],
175+
[
176+
'scope' => 'default',
177+
'destination' => 'lib/commands/init.js',
178+
'template' => 'cli/lib/commands/init.js.twig',
179+
],
175180
[
176181
'scope' => 'default',
177182
'destination' => 'lib/commands/create.js',

templates/cli/index.js.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const { client } = require("./lib/commands/generic");
1313
{% if sdk.test != "true" %}
1414
const { login, logout } = require("./lib/commands/generic");
1515
const { create } = require("./lib/commands/create");
16+
const { init } = require("./lib/commands/init");
1617
const { pull } = require("./lib/commands/pull");
1718
const { push } = require("./lib/commands/push");
1819
{% endif %}
@@ -39,6 +40,7 @@ program
3940
{% if sdk.test != "true" %}
4041
.addCommand(login)
4142
.addCommand(create)
43+
.addCommand(init)
4244
.addCommand(pull)
4345
.addCommand(push)
4446
.addCommand(logout)

templates/cli/lib/commands/create.js.twig

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,13 @@ const path = require("path");
33
const childProcess = require('child_process');
44
const { Command } = require("commander");
55
const inquirer = require("inquirer");
6-
const { projectsCreate } = require("./projects");
76
const { storageCreateBucket } = require("./storage");
87
const { messagingCreateTopic } = require("./messaging");
98
const { functionsCreate } = require("./functions");
109
const { databasesCreateCollection } = require("./databases");
11-
const { sdkForConsole } = require("../sdks");
1210
const ID = require("../id");
1311
const { localConfig } = require("../config");
1412
const {
15-
questionsCreateProject,
1613
questionsCreateFunction,
1714
questionsCreateBucket,
1815
questionsCreateMessagingTopic,
@@ -29,21 +26,6 @@ const create = new Command("create")
2926
command.help();
3027
}));
3128

32-
const createProject = async () => {
33-
let response = {}
34-
const answers = await inquirer.prompt(questionsCreateProject)
35-
if (!answers.project || !answers.organization) process.exit(1)
36-
37-
response = await projectsCreate({
38-
projectId: answers.id,
39-
name: answers.project,
40-
teamId: answers.organization.id,
41-
parseOutput: false
42-
})
43-
44-
localConfig.setProject(response['$id'], response.name);
45-
success();
46-
}
4729

4830
const createBucket = async () => {
4931
let response = {}
@@ -217,13 +199,6 @@ const createFunction = async () => {
217199
success();
218200
}
219201

220-
221-
222-
create
223-
.command("project")
224-
.description("Create a new {{ spec.title|caseUcfirst }} project")
225-
.action(actionRunner(createProject));
226-
227202
create
228203
.command("function")
229204
.description("Create a new {{ spec.title|caseUcfirst }} function")

templates/cli/lib/commands/generic.js.twig

Lines changed: 47 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,62 +8,64 @@ const { actionRunner, success, parseBool, commandDescriptions, log, parse } = re
88
const { questionsLogin, questionsListFactors, questionsMfaChallenge } = require("../questions");
99
const { accountUpdateMfaChallenge, accountCreateMfaChallenge, accountGet, accountCreateEmailPasswordSession, accountDeleteSession } = require("./account");
1010

11-
const login = new Command("login")
12-
.description(commandDescriptions['login'])
13-
.configureHelp({
14-
helpWidth: process.stdout.columns || 80
11+
const loginCommand = async () => {
12+
const answers = await inquirer.prompt(questionsLogin)
13+
14+
let client = await sdkForConsole(false);
15+
16+
await accountCreateEmailPasswordSession({
17+
email: answers.email,
18+
password: answers.password,
19+
parseOutput: false,
20+
sdk: client
1521
})
16-
.action(actionRunner(async () => {
17-
const answers = await inquirer.prompt(questionsLogin)
1822

19-
let client = await sdkForConsole(false);
23+
client.setCookie(globalConfig.getCookie());
2024

21-
await accountCreateEmailPasswordSession({
22-
email: answers.email,
23-
password: answers.password,
24-
parseOutput: false,
25-
sdk: client
26-
})
25+
let account;
26+
27+
try {
28+
account = await accountGet({
29+
sdk: client,
30+
parseOutput: false
31+
});
32+
} catch(error) {
33+
if (error.response === 'user_more_factors_required') {
34+
const { factor } = await inquirer.prompt(questionsListFactors);
2735

28-
client.setCookie(globalConfig.getCookie());
36+
const challenge = await accountCreateMfaChallenge({
37+
factor,
38+
parseOutput: false,
39+
sdk: client
40+
});
2941

30-
let account;
42+
const { otp } = await inquirer.prompt(questionsMfaChallenge);
43+
44+
await accountUpdateMfaChallenge({
45+
challengeId: challenge.$id,
46+
otp,
47+
parseOutput: false,
48+
sdk: client
49+
});
3150

32-
try {
3351
account = await accountGet({
3452
sdk: client,
3553
parseOutput: false
3654
});
37-
} catch(error) {
38-
if (error.response === 'user_more_factors_required') {
39-
const { factor } = await inquirer.prompt(questionsListFactors);
40-
41-
const challenge = await accountCreateMfaChallenge({
42-
factor,
43-
parseOutput: false,
44-
sdk: client
45-
});
46-
47-
const { otp } = await inquirer.prompt(questionsMfaChallenge);
48-
49-
await accountUpdateMfaChallenge({
50-
challengeId: challenge.$id,
51-
otp,
52-
parseOutput: false,
53-
sdk: client
54-
});
55-
56-
account = await accountGet({
57-
sdk: client,
58-
parseOutput: false
59-
});
60-
} else {
61-
throw error;
62-
}
55+
} else {
56+
throw error;
6357
}
58+
}
6459

65-
success("Signed in as user with ID: " + account.$id);
66-
}));
60+
success("Signed in as user with ID: " + account.$id);
61+
};
62+
63+
const login = new Command("login")
64+
.description(commandDescriptions['login'])
65+
.configureHelp({
66+
helpWidth: process.stdout.columns || 80
67+
})
68+
.action(actionRunner(loginCommand));
6769

6870
const logout = new Command("logout")
6971
.description(commandDescriptions['logout'])
@@ -159,6 +161,7 @@ const client = new Command("client")
159161

160162
module.exports = {
161163
{% if sdk.test != "true" %}
164+
loginCommand,
162165
login,
163166
logout,
164167
{% endif %}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
const { Command } = require("commander");
2+
const inquirer = require("inquirer");
3+
const { projectsCreate } = require("./projects");
4+
const { localConfig, globalConfig } = require("../config");
5+
const { questionsCreateProject, } = require("../questions");
6+
const { success, error, actionRunner, commandDescriptions } = require("../parser");
7+
const { accountGet } = require("./account");
8+
const { loginCommand } = require("./generic");
9+
10+
const init = new Command("init")
11+
.description(commandDescriptions['init'])
12+
.configureHelp({
13+
helpWidth: process.stdout.columns || 80
14+
})
15+
.action(actionRunner(async (_options, command) => {
16+
command.help();
17+
}));
18+
19+
const initProject = async () => {
20+
let response = {};
21+
22+
try {
23+
if (globalConfig.getEndpoint() === '' || globalConfig.getCookie() === '') {
24+
throw '';
25+
}
26+
await accountGet({
27+
parseOutput: false
28+
});
29+
} catch (e) {
30+
error('You must login first')
31+
await loginCommand()
32+
}
33+
34+
const answers = await inquirer.prompt(questionsCreateProject)
35+
if (!answers.project || !answers.organization) process.exit(1)
36+
37+
response = await projectsCreate({
38+
projectId: answers.id,
39+
name: answers.project,
40+
teamId: answers.organization.id,
41+
parseOutput: false
42+
})
43+
44+
localConfig.setProject(response['$id'], response.name);
45+
success();
46+
}
47+
48+
49+
init
50+
.command("project")
51+
.description("Init and create a new {{ spec.title|caseUcfirst }} project")
52+
.action(actionRunner(initProject));
53+
54+
module.exports = {
55+
init,
56+
};

templates/cli/lib/parser.js.twig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,8 @@ const commandDescriptions = {
156156
"graphql": `The graphql command allows you to query and mutate any resource type on your Appwrite server.`,
157157
"avatars": `The avatars command aims to help you complete everyday tasks related to your app image, icons, and avatars.`,
158158
"databases": `The databases command allows you to create structured collections of documents, query and filter lists of documents.`,
159-
"create": `The create command provides a convenient wrapper for creating projects functions, collections, buckets, teams and messaging.`,
159+
"init": `The init command provides a convenient wrapper for creating and initializing project in Appwrite.`,
160+
"create": `The create command provides a convenient wrapper for creating functions, collections, buckets, teams and messaging.`,
160161
"push": `The push command provides a convenient wrapper for pushing your functions, collections, buckets, teams and messaging.`,
161162
"functions": `The functions command allows you view, create and manage your Cloud Functions.`,
162163
"health": `The health command allows you to both validate and monitor your {{ spec.title|caseUcfirst }} server's health.`,

templates/cli/lib/questions.js.twig

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ const chalk = require('chalk');
1010
const { databasesList } = require('./commands/databases');
1111
const JSONbig = require("json-bigint")({ storeAsString: false });
1212

13+
const whenOverride = (answers)=> answers.override === undefined ? true : answers.override;
14+
1315
const getIgnores = (runtime) => {
1416
const languge = runtime.split('-')[0];
1517

@@ -143,7 +145,8 @@ const questionsProject = [
143145
}
144146

145147
return choices;
146-
}
148+
},
149+
when: whenOverride
147150
},
148151
];
149152

@@ -153,13 +156,70 @@ const questionsCreateProject = [
153156
type: "input",
154157
name: "project",
155158
message: "What would you like to name your project?",
156-
default: "My Awesome Project"
159+
default: "My Awesome Project",
160+
when: whenOverride
157161
},
158162
{
159163
type: "input",
160164
name: "id",
161165
message: "What ID would you like to have for your project?",
162-
default: "unique()"
166+
default: "unique()",
167+
when: whenOverride
168+
}
169+
];
170+
171+
const questionsPullProject = [
172+
...questionsProject,
173+
{
174+
type: "list",
175+
name: "project",
176+
message: "Choose your {{ spec.title|caseUcfirst }} project.",
177+
choices: async (answers) => {
178+
let response = await projectsList({
179+
parseOutput: false,
180+
queries: [JSON.stringify({ method: 'equal', attribute: 'teamId', values: [answers.organization.id] })],
181+
})
182+
let projects = response["projects"]
183+
let choices = projects.map((project, idx) => {
184+
return {
185+
name: `${project.name} (${project['$id']})`,
186+
value: {
187+
name: project.name,
188+
id: project['$id']
189+
}
190+
}
191+
})
192+
193+
if (choices.length == 0) {
194+
throw new Error("No projects found. Please create a new project.")
195+
}
196+
197+
return choices;
198+
},
199+
when: whenOverride
200+
}
201+
];
202+
203+
const questionsPullFunctions = [
204+
{
205+
type: "checkbox",
206+
name: "functions",
207+
message: "Which functions would you like to pull?",
208+
choices: async () => {
209+
const { functions } = await paginate(functionsList, { parseOutput: false }, 100, 'functions');
210+
211+
return functions.map(func => {
212+
return {
213+
name: `${func.name} (${func.$id})`,
214+
value: func
215+
}
216+
});
217+
}
218+
},
219+
{
220+
type: "input",
221+
name: "override",
222+
message: `Are you sure you want to override local functions code and definition? ${chalk.red('All local changes will be lost!')} Type "YES" to confirm.`
163223
}
164224
];
165225

@@ -311,30 +371,6 @@ const questionsPullProject = [
311371
}
312372
];
313373

314-
315-
const questionsPullFunctions = [
316-
{
317-
type: "checkbox",
318-
name: "functions",
319-
message: "Which functions would you like to pull?",
320-
choices: async () => {
321-
const { functions } = await paginate(functionsList, { parseOutput: false }, 100, 'functions');
322-
323-
return functions.map(func => {
324-
return {
325-
name: `${func.name} (${func.$id})`,
326-
value: func
327-
}
328-
});
329-
}
330-
},
331-
{
332-
type: "input",
333-
name: "override",
334-
message: `Are you sure you want to override local functions code and definition? ${chalk.red('All local changes will be lost!')} Type "YES" to confirm.`
335-
}
336-
];
337-
338374
const questionsPullCollection = [
339375
{
340376
type: "checkbox",

0 commit comments

Comments
 (0)