Skip to content

Commit 7ebd1b9

Browse files
fix: cli qa
1 parent c99bde3 commit 7ebd1b9

File tree

15 files changed

+200
-152
lines changed

15 files changed

+200
-152
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ Once the installation is complete, you can verify the install using
2929

3030
```sh
3131
$ appwrite -v
32-
6.0.0-rc.2
32+
6.0.0-rc.3
3333
```
3434

3535
### Install using prebuilt binaries
@@ -60,7 +60,7 @@ $ scoop install https://raw.githubusercontent.com/appwrite/sdk-for-cli/master/sc
6060
Once the installation completes, you can verify your install using
6161
```
6262
$ appwrite -v
63-
6.0.0-rc.2
63+
6.0.0-rc.3
6464
```
6565

6666
## Getting Started

install.ps1

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
# You can use "View source" of this page to see the full script.
1414

1515
# REPO
16-
$GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.2/appwrite-cli-win-x64.exe"
17-
$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.2/appwrite-cli-win-arm64.exe"
16+
$GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.3/appwrite-cli-win-x64.exe"
17+
$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/6.0.0-rc.3/appwrite-cli-win-arm64.exe"
1818

1919
$APPWRITE_BINARY_NAME = "appwrite.exe"
2020

install.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ printSuccess() {
9797
downloadBinary() {
9898
echo "[2/4] Downloading executable for $OS ($ARCH) ..."
9999

100-
GITHUB_LATEST_VERSION="6.0.0-rc.2"
100+
GITHUB_LATEST_VERSION="6.0.0-rc.3"
101101
GITHUB_FILE="appwrite-cli-${OS}-${ARCH}"
102102
GITHUB_URL="https://github.com/$GITHUB_REPOSITORY_NAME/releases/download/$GITHUB_LATEST_VERSION/$GITHUB_FILE"
103103

lib/client.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ class Client {
1616
'x-sdk-name': 'Command Line',
1717
'x-sdk-platform': 'console',
1818
'x-sdk-language': 'cli',
19-
'x-sdk-version': '6.0.0-rc.2',
20-
'user-agent' : `AppwriteCLI/6.0.0-rc.2 (${os.type()} ${os.version()}; ${os.arch()})`,
19+
'x-sdk-version': '6.0.0-rc.3',
20+
'user-agent' : `AppwriteCLI/6.0.0-rc.3 (${os.type()} ${os.version()}; ${os.arch()})`,
2121
'X-Appwrite-Response-Format' : '1.5.0',
2222
};
2323
}
@@ -168,7 +168,7 @@ class Client {
168168

169169
body = formData;
170170
} else {
171-
body = JSON.stringify(params);
171+
body = JSONbig.stringify(params);
172172
}
173173

174174
let response = undefined;
@@ -224,7 +224,7 @@ class Client {
224224
const text = await response.text();
225225
let json = undefined;
226226
try {
227-
json = JSON.parse(text);
227+
json = JSONbig.parse(text);
228228
} catch (error) {
229229
return text;
230230
}

lib/commands/pull.js

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const { databasesGet, databasesListCollections, databasesList } = require("./dat
1111
const { storageListBuckets } = require("./storage");
1212
const { localConfig } = require("../config");
1313
const { paginate } = require("../paginate");
14-
const { questionsPullCollection, questionsPullFunctions, questionsPullResources } = require("../questions");
14+
const { questionsPullCollection, questionsPullFunctions, questionsPullFunctionsCode, questionsPullResources } = require("../questions");
1515
const { cliConfig, success, log, warn, actionRunner, commandDescriptions } = require("../parser");
1616

1717
const pullResources = async () => {
@@ -56,7 +56,7 @@ const pullSettings = async () => {
5656
}
5757
}
5858

59-
const pullFunctions = async () => {
59+
const pullFunctions = async ({ code }) => {
6060
log("Fetching functions ...");
6161
let total = 0;
6262

@@ -74,11 +74,15 @@ const pullFunctions = async () => {
7474
? (await paginate(functionsList, { parseOutput: false }, 100, 'functions')).functions
7575
: (await inquirer.prompt(questionsPullFunctions)).functions;
7676

77+
let allowCodePull = cliConfig.force === true ? true : null;
78+
7779
for (let func of functions) {
7880
total++;
7981
log(`Pulling function ${chalk.bold(func['name'])} ...`);
8082

8183
const localFunction = localConfig.getFunction(func.$id);
84+
85+
func['path'] = localFunction['path'];
8286
if(!localFunction['path']) {
8387
func['path'] = `functions/${func.$id}`;
8488
}
@@ -88,28 +92,40 @@ const pullFunctions = async () => {
8892
if (!fs.existsSync(func['path'])) {
8993
fs.mkdirSync(func['path'], { recursive: true });
9094
}
91-
92-
if(func['deployment']) {
93-
const compressedFileName = `${func['$id']}-${+new Date()}.tar.gz`
94-
await functionsDownloadDeployment({
95-
functionId: func['$id'],
96-
deploymentId: func['deployment'],
97-
destination: compressedFileName,
98-
overrideForCli: true,
99-
parseOutput: false
100-
});
101-
102-
tar.extract({
103-
sync: true,
104-
cwd: func['path'],
105-
file: compressedFileName,
106-
strict: false,
107-
});
108-
109-
fs.rmSync(compressedFileName);
110-
}
111-
}
95+
96+
if(code === false) {
97+
warn("Source code download skipped.");
98+
} else if(!func['deployment']) {
99+
warn("Source code download skipped because function doesn't have active deployment.");
100+
} else {
101+
if(allowCodePull === null) {
102+
const codeAnswer = await inquirer.prompt(questionsPullFunctionsCode);
103+
allowCodePull = codeAnswer.override;
104+
}
105+
106+
if(allowCodePull) {
107+
log("Pulling active deployment's code ...");
108+
109+
const compressedFileName = `${func['$id']}-${+new Date()}.tar.gz`
110+
await functionsDownloadDeployment({
111+
functionId: func['$id'],
112+
deploymentId: func['deployment'],
113+
destination: compressedFileName,
114+
overrideForCli: true,
115+
parseOutput: false
116+
});
112117

118+
tar.extract({
119+
sync: true,
120+
cwd: func['path'],
121+
file: compressedFileName,
122+
strict: false,
123+
});
124+
125+
fs.rmSync(compressedFileName);
126+
}
127+
}
128+
113129
success(`Successfully pulled ${chalk.bold(total)} functions.`);
114130
}
115131

@@ -261,6 +277,7 @@ pull
261277
.command("function")
262278
.alias("functions")
263279
.description("Pulling your Appwrite cloud function")
280+
.option("--no-code", "Don't pull the function's code")
264281
.action(actionRunner(pullFunctions))
265282

266283
pull

lib/commands/push.js

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ const { checkDeployConditions } = require('../utils');
6767

6868
const STEP_SIZE = 100; // Resources
6969
const POLL_DEBOUNCE = 2000; // Milliseconds
70-
const POLL_MAX_DEBOUNCE = 30; // Times
70+
const POLL_MAX_DEBOUNCE = 1800; // Times of POLL_DEBOUNCE (1 hour)
7171

7272
let pollMaxDebounces = 30;
7373

@@ -354,8 +354,8 @@ const createAttribute = async (databaseId, collectionId, attribute) => {
354354
collectionId,
355355
key: attribute.key,
356356
required: attribute.required,
357-
min: parseInt(attribute.min.toString()),
358-
max: parseInt(attribute.max.toString()),
357+
min: attribute.min,
358+
max: attribute.max,
359359
xdefault: attribute.default,
360360
array: attribute.array,
361361
parseOutput: false
@@ -366,8 +366,8 @@ const createAttribute = async (databaseId, collectionId, attribute) => {
366366
collectionId,
367367
key: attribute.key,
368368
required: attribute.required,
369-
min: parseFloat(attribute.min.toString()),
370-
max: parseFloat(attribute.max.toString()),
369+
min: attribute.min,
370+
max: attribute.max,
371371
xdefault: attribute.default,
372372
array: attribute.array,
373373
parseOutput: false
@@ -471,8 +471,8 @@ const updateAttribute = async (databaseId, collectionId, attribute) => {
471471
collectionId,
472472
key: attribute.key,
473473
required: attribute.required,
474-
min: parseInt(attribute.min.toString()),
475-
max: parseInt(attribute.max.toString()),
474+
min: attribute.min,
475+
max: attribute.max,
476476
xdefault: attribute.default,
477477
array: attribute.array,
478478
parseOutput: false
@@ -483,8 +483,8 @@ const updateAttribute = async (databaseId, collectionId, attribute) => {
483483
collectionId,
484484
key: attribute.key,
485485
required: attribute.required,
486-
min: parseFloat(attribute.min.toString()),
487-
max: parseFloat(attribute.max.toString()),
486+
min: attribute.min,
487+
max: attribute.max,
488488
xdefault: attribute.default,
489489
array: attribute.array,
490490
parseOutput: false
@@ -884,6 +884,7 @@ const pushFunction = async ({ functionId, async, returnOnZero } = { returnOnZero
884884
logging: func.logging,
885885
entrypoint: func.entrypoint,
886886
commands: func.commands,
887+
scopes: func.scopes,
887888
providerRepositoryId: func.providerRepositoryId ?? "",
888889
installationId: func.installationId ?? '',
889890
providerBranch: func.providerBranch ?? '',

lib/commands/run.js

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -86,12 +86,12 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
8686
log("If you wish to change your local settings, update the appwrite.json file and rerun the 'appwrite run' command.");
8787
hint("Permissions, events, CRON and timeouts dont apply when running locally.");
8888

89-
await dockerCleanup();
89+
await dockerCleanup(func.$id);
9090

9191
process.on('SIGINT', async () => {
9292
log('Cleaning up ...');
93-
await dockerCleanup();
94-
success();
93+
await dockerCleanup(func.$id);
94+
success("Local function successfully stopped.");
9595
process.exit();
9696
});
9797

@@ -135,7 +135,7 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
135135
variables['APPWRITE_FUNCTION_RUNTIME_VERSION'] = func.runtime;
136136

137137
try {
138-
await JwtManager.setup(userId);
138+
await JwtManager.setup(userId, func.scopes ?? []);
139139
} catch(err) {
140140
warn("Dynamic API key not generated. Header x-appwrite-key will not be set. Reason: " + err.message);
141141
}
@@ -149,18 +149,12 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
149149
variables['OPEN_RUNTIMES_HEADERS'] = JSON.stringify(headers);
150150

151151
await dockerPull(func);
152-
await dockerBuild(func, variables);
153-
154-
log('Starting function using Docker ...');
155-
hint('Function automatically restarts when you edit your code.');
156-
157-
await dockerStart(func, variables, port);
158152

159153
new Tail(logsPath).on("line", function(data) {
160-
process.stdout.write(chalk.blackBright(`${data}\n`));
154+
process.stdout.write(chalk.white(`${data}\n`));
161155
});
162156
new Tail(errorsPath).on("line", function(data) {
163-
process.stdout.write(chalk.blackBright(`${data}\n`));
157+
process.stdout.write(chalk.white(`${data}\n`));
164158
});
165159

166160
if(!noReload) {
@@ -181,8 +175,14 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
181175

182176
const dependencyFile = files.find((filePath) => tool.dependencyFiles.includes(filePath));
183177
if(tool.isCompiled || dependencyFile) {
184-
log(`Rebuilding the function ...`);
178+
log(`Rebuilding the function due to file changes ...`);
185179
await dockerBuild(func, variables);
180+
181+
if(!Queue.isEmpty()) {
182+
Queue.unlock();
183+
return;
184+
}
185+
186186
await dockerStart(func, variables, port);
187187
} else {
188188
log('Hot-swapping function.. Files with change are ' + files.join(', '));
@@ -247,6 +247,22 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
247247
Queue.unlock();
248248
}
249249
});
250+
251+
Queue.lock();
252+
253+
log('Building function using Docker ...');
254+
await dockerBuild(func, variables);
255+
256+
if(!Queue.isEmpty()) {
257+
Queue.unlock();
258+
return;
259+
}
260+
261+
log('Starting function using Docker ...');
262+
hint('Function automatically restarts when you edit your code.');
263+
await dockerStart(func, variables, port);
264+
265+
Queue.unlock();
250266
}
251267

252268
const run = new Command("run")

lib/config.js

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,36 @@ const _path = require("path");
44
const process = require("process");
55
const JSONbig = require("json-bigint")({ storeAsString: false });
66

7-
const KeysFunction = ["path", "$id", "execute", "name", "enabled", "logging", "runtime", "scopes", "events", "schedule", "timeout", "entrypoint", "commands"];
8-
const KeysDatabase = ["$id", "name", "enabled"];
9-
const KeysCollection = ["$id", "$permissions", "databaseId", "name", "enabled", "documentSecurity", "attributes", "indexes"];
10-
const KeysStorage = ["$id", "$permissions", "fileSecurity", "name", "enabled", "maximumFileSize", "allowedFileExtensions", "compression", "encryption", "antivirus"];
11-
const KeyTopics = ["$id", "name", "subscribe"];
12-
const KeyAttributes = ["key", "type", "required", "array", "size", "default"];
13-
const KeyIndexes = ["key", "type", "status", "attributes", "orders"];
14-
15-
function whitelistKeys(value, keys, nestedKeys = []) {
7+
const KeysFunction = new Set(["path", "$id", "execute", "name", "enabled", "logging", "runtime", "scopes", "events", "schedule", "timeout", "entrypoint", "commands"]);
8+
const KeysDatabase = new Set(["$id", "name", "enabled"]);
9+
const KeysCollection = new Set(["$id", "$permissions", "databaseId", "name", "enabled", "documentSecurity", "attributes", "indexes"]);
10+
const KeysStorage = new Set(["$id", "$permissions", "fileSecurity", "name", "enabled", "maximumFileSize", "allowedFileExtensions", "compression", "encryption", "antivirus"]);
11+
const KeyTopics = new Set(["$id", "name", "subscribe"]);
12+
const KeyAttributes = new Set([
13+
"key",
14+
"type",
15+
"required",
16+
"array",
17+
"size",
18+
"default",
19+
// integer and float
20+
"min",
21+
"max",
22+
// email, enum, URL, IP, and datetime
23+
"format",
24+
// enum
25+
"elements",
26+
// relationship
27+
"relatedCollection",
28+
"relationType",
29+
"twoWay",
30+
"twoWayKey",
31+
"onDelete",
32+
"side"
33+
]);
34+
const KeyIndexes = new Set(["key", "type", "status", "attributes", "orders"]);
35+
36+
function whitelistKeys(value, keys, nestedKeys = {}) {
1637
if(Array.isArray(value)) {
1738
const newValue = [];
1839

@@ -25,7 +46,7 @@ function whitelistKeys(value, keys, nestedKeys = []) {
2546

2647
const newValue = {};
2748
Object.keys(value).forEach((key) => {
28-
if(keys.includes(key)) {
49+
if(keys.has(key)) {
2950
if(nestedKeys[key]) {
3051
newValue[key] = whitelistKeys(value[key], nestedKeys[key]);
3152
} else {

0 commit comments

Comments
 (0)