Skip to content

Commit 2014675

Browse files
Merge pull request #849 from appwrite/feat-console-flow
feat(cli): Adding console for get & list methods
2 parents 1d0350b + 169bb86 commit 2014675

19 files changed

+1550
-550
lines changed

src/SDK/Language.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,15 @@ public function getFilters(): array
8484
return [];
8585
}
8686

87+
/**
88+
* Language specific functions.
89+
* @return array
90+
*/
91+
public function getFunctions(): array
92+
{
93+
return [];
94+
}
95+
8796
protected function toPascalCase(string $value): string
8897
{
8998
return \ucfirst($this->toCamelCase($value));

src/SDK/Language/CLI.php

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,66 @@
22

33
namespace Appwrite\SDK\Language;
44

5+
use Twig\TwigFunction;
6+
57
class CLI extends Node
68
{
9+
/**
10+
* List of functions to ignore for console preview.
11+
* @var array
12+
*/
13+
private $consoleIgnoreFunctions = [
14+
'listidentities',
15+
'listmfafactors',
16+
'getprefs',
17+
'getsession',
18+
'getattribute',
19+
'listdocumentlogs',
20+
'getindex',
21+
'listcollectionlogs',
22+
'getcollectionusage',
23+
'listlogs',
24+
'listruntimes',
25+
'getusage',
26+
'getusage',
27+
'listvariables',
28+
'getvariable',
29+
'listproviderlogs',
30+
'listsubscriberlogs',
31+
'getsubscriber',
32+
'listtopiclogs',
33+
'getemailtemplate',
34+
'getsmstemplate',
35+
'getfiledownload',
36+
'getfilepreview',
37+
'getfileview',
38+
'getusage',
39+
'listlogs',
40+
'getprefs',
41+
'getusage',
42+
'listlogs',
43+
'getmembership',
44+
'listmemberships',
45+
'listmfafactors',
46+
'getmfarecoverycodes',
47+
'getprefs',
48+
'listtargets',
49+
'gettarget',
50+
];
51+
52+
/**
53+
* List of SDK services to ignore for console preview.
54+
* @var array
55+
*/
56+
private $consoleIgnoreServices = [
57+
'health',
58+
'migrations',
59+
'locale',
60+
'avatars',
61+
'project',
62+
'proxy',
63+
'vcs'
64+
];
765
/**
866
* @var array
967
*/
@@ -290,4 +348,18 @@ public function getParamExample(array $param): string
290348

291349
return $output;
292350
}
351+
352+
/**
353+
* Language specific filters.
354+
* @return array
355+
*/
356+
public function getFunctions(): array
357+
{
358+
return [
359+
/** Return true if the entered service->method is enabled for a console preview link */
360+
new TwigFunction('hasConsolePreview', fn($method, $service) => preg_match('/^([Gg]et|[Ll]ist)/', $method)
361+
&& !in_array(strtolower($method), $this->consoleIgnoreFunctions)
362+
&& !in_array($service, $this->consoleIgnoreServices)),
363+
];
364+
}
293365
}

src/SDK/SDK.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ public function __construct(Language $language, Spec $spec)
8585
'debug' => true
8686
]);
8787

88+
/**
89+
* Add language-specific functions
90+
*/
91+
foreach ($this->language->getFunctions() as $function) {
92+
$this->twig->addFunction($function);
93+
}
94+
8895
/**
8996
* Add language specific filters
9097
*/

templates/cli/base/requests/api.twig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,19 @@
1717
fs.writeFileSync(destination, response);
1818
{%~ endif %}
1919
if (parseOutput) {
20+
{%~ if hasConsolePreview(method.name,service.name) %}
21+
if(console) {
22+
showConsoleLink('{{service.name}}', '{{ method.name }}'
23+
{%- for parameter in method.parameters.path -%}{%- set param = (parameter.name | caseCamel | escapeKeyword) -%}{%- if param ends with 'Id' -%}, {{ param }} {%- endif -%}{%- endfor -%}
24+
);
25+
} else {
26+
parse(response)
27+
success()
28+
}
29+
{%~ else %}
2030
parse(response)
2131
success()
32+
{%~ endif %}
2233
}
2334

2435
return response;

templates/cli/index.js.twig

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,21 @@ const chalk = require("chalk");
1010
const { version } = require("./package.json");
1111
const { commandDescriptions, cliConfig } = require("./lib/parser");
1212
const { client } = require("./lib/commands/generic");
13+
const inquirer = require("inquirer");
1314
{% if sdk.test != "true" %}
1415
const { login, logout, whoami } = require("./lib/commands/generic");
1516
const { init } = require("./lib/commands/init");
1617
const { pull } = require("./lib/commands/pull");
1718
const { push } = require("./lib/commands/push");
19+
{% else %}
20+
const { migrate } = require("./lib/commands/generic");
1821
{% endif %}
1922
{% for service in spec.services %}
2023
const { {{ service.name | caseLower }} } = require("./lib/commands/{{ service.name | caseLower }}");
2124
{% endfor %}
2225

26+
inquirer.registerPrompt('search-list', require('inquirer-search-list'));
27+
2328
program
2429
.description(commandDescriptions['main'])
2530
.configureHelp({
@@ -29,12 +34,30 @@ program
2934
.version(version, "-v, --version")
3035
.option("--verbose", "Show complete error log")
3136
.option("--json", "Output in JSON format")
37+
.hook('preAction', migrate)
38+
.option("-f,--force", "Flag to confirm all warnings")
39+
.option("-a,--all", "Flag to push all resources")
40+
.option("--id [id...]", "Flag to pass list of ids for a giving action")
41+
.option("--report", "Enable reporting in case of CLI errors")
3242
.on("option:json", () => {
3343
cliConfig.json = true;
3444
})
3545
.on("option:verbose", () => {
3646
cliConfig.verbose = true;
3747
})
48+
.on("option:report", function() {
49+
cliConfig.report = true;
50+
cliConfig.reportData = { data: this };
51+
})
52+
.on("option:force", () => {
53+
cliConfig.force = true;
54+
})
55+
.on("option:all", () => {
56+
cliConfig.all = true;
57+
})
58+
.on("option:id", function() {
59+
cliConfig.ids = this.opts().id;
60+
})
3861
.showSuggestionAfterError()
3962
{% if sdk.test != "true" %}
4063
.addCommand(whoami)

templates/cli/lib/client.js.twig

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ const { fetch, FormData, Agent } = require("undici");
44
const JSONbig = require("json-bigint")({ storeAsString: false });
55
const {{spec.title | caseUcfirst}}Exception = require("./exception.js");
66
const { globalConfig } = require("./config.js");
7+
const chalk = require("chalk");
78

89
class Client {
910
CHUNK_SIZE = 5*1024*1024; // 5MB
10-
11+
1112
constructor() {
1213
this.endpoint = '{{spec.endpoint}}';
1314
this.headers = {
@@ -144,6 +145,14 @@ class Client {
144145
} catch (error) {
145146
throw new {{spec.title | caseUcfirst}}Exception(text, response.status, "", text);
146147
}
148+
149+
if (path !== '/account' && json.code === 401 && json.type === 'user_more_factors_required') {
150+
console.log(`${chalk.cyan.bold("ℹ Info")} ${chalk.cyan("Unusable account found, removing...")}`);
151+
152+
const current = globalConfig.getCurrentSession();
153+
globalConfig.setCurrentSession('');
154+
globalConfig.removeSession(current);
155+
}
147156
throw new {{spec.title | caseUcfirst}}Exception(json.message, json.code, json.type, json);
148157
}
149158

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ const tar = require("tar");
44
const ignore = require("ignore");
55
const { promisify } = require('util');
66
const libClient = require('../client.js');
7-
const { getAllFiles } = require('../utils.js');
7+
const { getAllFiles, showConsoleLink } = require('../utils.js');
88
const { Command } = require('commander');
99
const { sdkForProject, sdkForConsole } = require('../sdks')
1010
const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
@@ -70,6 +70,7 @@ const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({
7070
{%- if 'multipart/form-data' in method.consumes -%},onProgress = () => {}{%- endif -%}
7171

7272
{%- if method.type == 'location' -%}, destination{%- endif -%}
73+
{% if hasConsolePreview(method.name,service.name) %}, console{%- endif -%}
7374
}) => {
7475
{%~ endblock %}
7576
let client = !sdk ? await {% if service.name == "projects" %}sdkForConsole(){% else %}sdkForProject(){% endif %} :
@@ -94,6 +95,9 @@ const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({
9495
{% if method.type == 'location' %}
9596
.requiredOption(`--destination <path>`, `output file path.`)
9697
{% endif %}
98+
{% if hasConsolePreview(method.name,service.name) %}
99+
.option(`--console`, `Get the resource console url`)
100+
{% endif %}
97101
{% endautoescape %}
98102
.action(actionRunner({{ service.name | caseLower }}{{ method.name | caseUcfirst }}))
99103

0 commit comments

Comments
 (0)