Skip to content

Commit b7f6f56

Browse files
committed
Merge branch 'refs/heads/feat-cli-sudo' into feat-non-destructive-db-actions
# Conflicts: # templates/cli/lib/commands/push.js.twig
2 parents 9e2e51b + d0cc1c2 commit b7f6f56

File tree

16 files changed

+1147
-305
lines changed

16 files changed

+1147
-305
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: 77 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
*/
@@ -172,6 +230,11 @@ public function getFiles(): array
172230
'destination' => 'lib/utils.js',
173231
'template' => 'cli/lib/utils.js.twig',
174232
],
233+
[
234+
'scope' => 'default',
235+
'destination' => 'lib/commands/init.js',
236+
'template' => 'cli/lib/commands/init.js.twig',
237+
],
175238
[
176239
'scope' => 'default',
177240
'destination' => 'lib/commands/pull.js',
@@ -285,4 +348,18 @@ public function getParamExample(array $param): string
285348

286349
return $output;
287350
}
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('methodHaveConsolePreview', 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+
}
288365
}

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/params.twig

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@
7575
{% endif %}
7676
{% endfor %}
7777
{% if method.type == 'location' %}
78-
payload['project'] = localConfig.getProject().projectId
79-
payload['key'] = globalConfig.getKey();
80-
const queryParams = new URLSearchParams(payload);
81-
apiPath = `${globalConfig.getEndpoint()}${apiPath}?${queryParams.toString()}`;
78+
if (!overrideForCli) {
79+
payload['project'] = localConfig.getProject().projectId
80+
payload['key'] = globalConfig.getKey();
81+
const queryParams = new URLSearchParams(payload);
82+
apiPath = `${globalConfig.getEndpoint()}${apiPath}?${queryParams.toString()}`;
83+
}
8284
{% endif %}

templates/cli/base/requests/api.twig

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,27 @@
99
{% endfor %}
1010
}, payload{% if method.type == 'location' %}, 'arraybuffer'{% endif %});
1111

12-
{% if method.type == 'location' %}
13-
fs.writeFileSync(destination, response);
12+
{%~ if method.type == 'location' %}
13+
if (overrideForCli) {
14+
response = Buffer.from(response);
15+
}
1416

15-
{% endif %}
17+
fs.writeFileSync(destination, response);
18+
{%~ endif %}
1619
if (parseOutput) {
20+
{%~ if methodHaveConsolePreview(method.name,service.name) %}
21+
if(console) {
22+
showConsoleLink('{{service.name}}', '{{ method.name }}',open
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 %}
1730
parse(response)
1831
success()
32+
{%~ endif %}
1933
}
20-
21-
return response;
34+
35+
return response;

templates/cli/index.js.twig

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const { commandDescriptions, cliConfig } = require("./lib/parser");
1212
const { client } = require("./lib/commands/generic");
1313
{% if sdk.test != "true" %}
1414
const { login, logout, whoami } = require("./lib/commands/generic");
15+
const { init } = require("./lib/commands/init");
1516
const { pull } = require("./lib/commands/pull");
1617
const { push } = require("./lib/commands/push");
1718
{% endif %}
@@ -28,16 +29,34 @@ program
2829
.version(version, "-v, --version")
2930
.option("--verbose", "Show complete error log")
3031
.option("--json", "Output in JSON format")
32+
.option("-f,--force", "Flag to confirm all warnings")
33+
.option("-a,--all", "Flag to push all resources")
34+
.option("--id [id...]", "Flag to pass list of ids for a giving action")
35+
.option("--report", "Enable reporting when cli is crashing")
3136
.on("option:json", () => {
3237
cliConfig.json = true;
3338
})
3439
.on("option:verbose", () => {
3540
cliConfig.verbose = true;
3641
})
42+
.on("option:report", function() {
43+
cliConfig.report = true;
44+
cliConfig.reportData = { data: this };
45+
})
46+
.on("option:force", () => {
47+
cliConfig.force = true;
48+
})
49+
.on("option:all", () => {
50+
cliConfig.all = true;
51+
})
52+
.on("option:id", function() {
53+
cliConfig.ids = this.opts().id;
54+
})
3755
.showSuggestionAfterError()
3856
{% if sdk.test != "true" %}
3957
.addCommand(whoami)
4058
.addCommand(login)
59+
.addCommand(init)
4160
.addCommand(pull)
4261
.addCommand(push)
4362
.addCommand(logout)

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

Lines changed: 23 additions & 4 deletions
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')
@@ -45,6 +45,7 @@ const {{ service.name | caseLower }} = new Command("{{ service.name | caseLower
4545
{% for parameter in method.parameters.all %}
4646
* @property {{ "{" }}{{ parameter | typeName }}{{ "}" }} {{ parameter.name | caseCamel | escapeKeyword }} {{ parameter.description | replace({'`':'\''}) | replace({'\n':' '}) | replace({'\n \n':' '}) }}
4747
{% endfor %}
48+
* @property {boolean} overrideForCli
4849
* @property {boolean} parseOutput
4950
* @property {libClient | undefined} sdk
5051
{% if 'multipart/form-data' in method.consumes %}
@@ -58,8 +59,22 @@ const {{ service.name | caseLower }} = new Command("{{ service.name | caseLower
5859
/**
5960
* @param {{ "{" }}{{ service.name | caseUcfirst }}{{ method.name | caseUcfirst }}RequestParams{{ "}" }} params
6061
*/
61-
const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({ {% for parameter in method.parameters.all %}{{ parameter.name | caseCamel | escapeKeyword }}, {% endfor %}parseOutput = true, sdk = undefined{% if 'multipart/form-data' in method.consumes %}, onProgress = () => {}{% endif %}{% if method.type == 'location' %}, destination{% endif %}}) => {
62-
let client = !sdk ? await {% if service.name == "projects" %}sdkForConsole(){% else %}sdkForProject(){% endif %} : sdk;
62+
{%~ block decleration -%}
63+
const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({
64+
{%- for parameter in method.parameters.all -%}
65+
{{ parameter.name | caseCamel | escapeKeyword }},
66+
{%- endfor -%}
67+
68+
{%- block baseParams -%}parseOutput = true, overrideForCli = false, sdk = undefined {%- endblock -%}
69+
70+
{%- if 'multipart/form-data' in method.consumes -%},onProgress = () => {}{%- endif -%}
71+
72+
{%- if method.type == 'location' -%}, destination{%- endif -%}
73+
{% if methodHaveConsolePreview(method.name,service.name) %}, console, open{%- endif -%}
74+
}) => {
75+
{%~ endblock %}
76+
let client = !sdk ? await {% if service.name == "projects" %}sdkForConsole(){% else %}sdkForProject(){% endif %} :
77+
sdk;
6378
let apiPath = '{{ method.path }}'{% for parameter in method.parameters.path %}.replace('{{ '{' }}{{ parameter.name | caseCamel }}{{ '}' }}', {{ parameter.name | caseCamel | escapeKeyword }}){% endfor %};
6479
{{ include ('cli/base/params.twig') }}
6580
{% if 'multipart/form-data' in method.consumes %}
@@ -80,6 +95,10 @@ const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({ {
8095
{% if method.type == 'location' %}
8196
.requiredOption(`--destination <path>`, `output file path.`)
8297
{% endif %}
98+
{% if methodHaveConsolePreview(method.name,service.name) %}
99+
.option(`--console`, `Get the resource console url`)
100+
.option(`--open`, `Use with '--console' to open the using default browser`)
101+
{% endif %}
83102
{% endautoescape %}
84103
.action(actionRunner({{ service.name | caseLower }}{{ method.name | caseUcfirst }}))
85104

@@ -90,4 +109,4 @@ module.exports = {
90109
{{ service.name | caseLower }}{{ method.name | caseUcfirst }}{% if not loop.last %},{% endif %}
91110

92111
{% endfor %}
93-
};
112+
};

0 commit comments

Comments
 (0)