Skip to content

Commit

Permalink
fix: cli qa
Browse files Browse the repository at this point in the history
  • Loading branch information
TorstenDittmann committed Jul 10, 2024
1 parent c99bde3 commit 7ebd1b9
Show file tree
Hide file tree
Showing 15 changed files with 200 additions and 152 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ Once the installation is complete, you can verify the install using

```sh
$ appwrite -v
6.0.0-rc.2
6.0.0-rc.3
```

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

## Getting Started
Expand Down
4 changes: 2 additions & 2 deletions install.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
# You can use "View source" of this page to see the full script.

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

$APPWRITE_BINARY_NAME = "appwrite.exe"

Expand Down
2 changes: 1 addition & 1 deletion install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ printSuccess() {
downloadBinary() {
echo "[2/4] Downloading executable for $OS ($ARCH) ..."

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

Expand Down
8 changes: 4 additions & 4 deletions lib/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ class Client {
'x-sdk-name': 'Command Line',
'x-sdk-platform': 'console',
'x-sdk-language': 'cli',
'x-sdk-version': '6.0.0-rc.2',
'user-agent' : `AppwriteCLI/6.0.0-rc.2 (${os.type()} ${os.version()}; ${os.arch()})`,
'x-sdk-version': '6.0.0-rc.3',
'user-agent' : `AppwriteCLI/6.0.0-rc.3 (${os.type()} ${os.version()}; ${os.arch()})`,
'X-Appwrite-Response-Format' : '1.5.0',
};
}
Expand Down Expand Up @@ -168,7 +168,7 @@ class Client {

body = formData;
} else {
body = JSON.stringify(params);
body = JSONbig.stringify(params);
}

let response = undefined;
Expand Down Expand Up @@ -224,7 +224,7 @@ class Client {
const text = await response.text();
let json = undefined;
try {
json = JSON.parse(text);
json = JSONbig.parse(text);
} catch (error) {
return text;
}
Expand Down
63 changes: 40 additions & 23 deletions lib/commands/pull.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const { databasesGet, databasesListCollections, databasesList } = require("./dat
const { storageListBuckets } = require("./storage");
const { localConfig } = require("../config");
const { paginate } = require("../paginate");
const { questionsPullCollection, questionsPullFunctions, questionsPullResources } = require("../questions");
const { questionsPullCollection, questionsPullFunctions, questionsPullFunctionsCode, questionsPullResources } = require("../questions");
const { cliConfig, success, log, warn, actionRunner, commandDescriptions } = require("../parser");

const pullResources = async () => {
Expand Down Expand Up @@ -56,7 +56,7 @@ const pullSettings = async () => {
}
}

const pullFunctions = async () => {
const pullFunctions = async ({ code }) => {
log("Fetching functions ...");
let total = 0;

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

let allowCodePull = cliConfig.force === true ? true : null;

for (let func of functions) {
total++;
log(`Pulling function ${chalk.bold(func['name'])} ...`);

const localFunction = localConfig.getFunction(func.$id);

func['path'] = localFunction['path'];
if(!localFunction['path']) {
func['path'] = `functions/${func.$id}`;
}
Expand All @@ -88,28 +92,40 @@ const pullFunctions = async () => {
if (!fs.existsSync(func['path'])) {
fs.mkdirSync(func['path'], { recursive: true });
}

if(func['deployment']) {
const compressedFileName = `${func['$id']}-${+new Date()}.tar.gz`
await functionsDownloadDeployment({
functionId: func['$id'],
deploymentId: func['deployment'],
destination: compressedFileName,
overrideForCli: true,
parseOutput: false
});

tar.extract({
sync: true,
cwd: func['path'],
file: compressedFileName,
strict: false,
});

fs.rmSync(compressedFileName);
}
}

if(code === false) {
warn("Source code download skipped.");
} else if(!func['deployment']) {
warn("Source code download skipped because function doesn't have active deployment.");
} else {
if(allowCodePull === null) {
const codeAnswer = await inquirer.prompt(questionsPullFunctionsCode);
allowCodePull = codeAnswer.override;
}

if(allowCodePull) {
log("Pulling active deployment's code ...");

const compressedFileName = `${func['$id']}-${+new Date()}.tar.gz`
await functionsDownloadDeployment({
functionId: func['$id'],
deploymentId: func['deployment'],
destination: compressedFileName,
overrideForCli: true,
parseOutput: false
});

tar.extract({
sync: true,
cwd: func['path'],
file: compressedFileName,
strict: false,
});

fs.rmSync(compressedFileName);
}
}

success(`Successfully pulled ${chalk.bold(total)} functions.`);
}

Expand Down Expand Up @@ -261,6 +277,7 @@ pull
.command("function")
.alias("functions")
.description("Pulling your Appwrite cloud function")
.option("--no-code", "Don't pull the function's code")
.action(actionRunner(pullFunctions))

pull
Expand Down
19 changes: 10 additions & 9 deletions lib/commands/push.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ const { checkDeployConditions } = require('../utils');

const STEP_SIZE = 100; // Resources
const POLL_DEBOUNCE = 2000; // Milliseconds
const POLL_MAX_DEBOUNCE = 30; // Times
const POLL_MAX_DEBOUNCE = 1800; // Times of POLL_DEBOUNCE (1 hour)

let pollMaxDebounces = 30;

Expand Down Expand Up @@ -354,8 +354,8 @@ const createAttribute = async (databaseId, collectionId, attribute) => {
collectionId,
key: attribute.key,
required: attribute.required,
min: parseInt(attribute.min.toString()),
max: parseInt(attribute.max.toString()),
min: attribute.min,
max: attribute.max,
xdefault: attribute.default,
array: attribute.array,
parseOutput: false
Expand All @@ -366,8 +366,8 @@ const createAttribute = async (databaseId, collectionId, attribute) => {
collectionId,
key: attribute.key,
required: attribute.required,
min: parseFloat(attribute.min.toString()),
max: parseFloat(attribute.max.toString()),
min: attribute.min,
max: attribute.max,
xdefault: attribute.default,
array: attribute.array,
parseOutput: false
Expand Down Expand Up @@ -471,8 +471,8 @@ const updateAttribute = async (databaseId, collectionId, attribute) => {
collectionId,
key: attribute.key,
required: attribute.required,
min: parseInt(attribute.min.toString()),
max: parseInt(attribute.max.toString()),
min: attribute.min,
max: attribute.max,
xdefault: attribute.default,
array: attribute.array,
parseOutput: false
Expand All @@ -483,8 +483,8 @@ const updateAttribute = async (databaseId, collectionId, attribute) => {
collectionId,
key: attribute.key,
required: attribute.required,
min: parseFloat(attribute.min.toString()),
max: parseFloat(attribute.max.toString()),
min: attribute.min,
max: attribute.max,
xdefault: attribute.default,
array: attribute.array,
parseOutput: false
Expand Down Expand Up @@ -884,6 +884,7 @@ const pushFunction = async ({ functionId, async, returnOnZero } = { returnOnZero
logging: func.logging,
entrypoint: func.entrypoint,
commands: func.commands,
scopes: func.scopes,
providerRepositoryId: func.providerRepositoryId ?? "",
installationId: func.installationId ?? '',
providerBranch: func.providerBranch ?? '',
Expand Down
42 changes: 29 additions & 13 deletions lib/commands/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
log("If you wish to change your local settings, update the appwrite.json file and rerun the 'appwrite run' command.");
hint("Permissions, events, CRON and timeouts dont apply when running locally.");

await dockerCleanup();
await dockerCleanup(func.$id);

process.on('SIGINT', async () => {
log('Cleaning up ...');
await dockerCleanup();
success();
await dockerCleanup(func.$id);
success("Local function successfully stopped.");
process.exit();
});

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

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

await dockerPull(func);
await dockerBuild(func, variables);

log('Starting function using Docker ...');
hint('Function automatically restarts when you edit your code.');

await dockerStart(func, variables, port);

new Tail(logsPath).on("line", function(data) {
process.stdout.write(chalk.blackBright(`${data}\n`));
process.stdout.write(chalk.white(`${data}\n`));
});
new Tail(errorsPath).on("line", function(data) {
process.stdout.write(chalk.blackBright(`${data}\n`));
process.stdout.write(chalk.white(`${data}\n`));
});

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

const dependencyFile = files.find((filePath) => tool.dependencyFiles.includes(filePath));
if(tool.isCompiled || dependencyFile) {
log(`Rebuilding the function ...`);
log(`Rebuilding the function due to file changes ...`);
await dockerBuild(func, variables);

if(!Queue.isEmpty()) {
Queue.unlock();
return;
}

await dockerStart(func, variables, port);
} else {
log('Hot-swapping function.. Files with change are ' + files.join(', '));
Expand Down Expand Up @@ -247,6 +247,22 @@ const runFunction = async ({ port, functionId, noVariables, noReload, userId } =
Queue.unlock();
}
});

Queue.lock();

log('Building function using Docker ...');
await dockerBuild(func, variables);

if(!Queue.isEmpty()) {
Queue.unlock();
return;
}

log('Starting function using Docker ...');
hint('Function automatically restarts when you edit your code.');
await dockerStart(func, variables, port);

Queue.unlock();
}

const run = new Command("run")
Expand Down
41 changes: 31 additions & 10 deletions lib/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,36 @@ const _path = require("path");
const process = require("process");
const JSONbig = require("json-bigint")({ storeAsString: false });

const KeysFunction = ["path", "$id", "execute", "name", "enabled", "logging", "runtime", "scopes", "events", "schedule", "timeout", "entrypoint", "commands"];
const KeysDatabase = ["$id", "name", "enabled"];
const KeysCollection = ["$id", "$permissions", "databaseId", "name", "enabled", "documentSecurity", "attributes", "indexes"];
const KeysStorage = ["$id", "$permissions", "fileSecurity", "name", "enabled", "maximumFileSize", "allowedFileExtensions", "compression", "encryption", "antivirus"];
const KeyTopics = ["$id", "name", "subscribe"];
const KeyAttributes = ["key", "type", "required", "array", "size", "default"];
const KeyIndexes = ["key", "type", "status", "attributes", "orders"];

function whitelistKeys(value, keys, nestedKeys = []) {
const KeysFunction = new Set(["path", "$id", "execute", "name", "enabled", "logging", "runtime", "scopes", "events", "schedule", "timeout", "entrypoint", "commands"]);
const KeysDatabase = new Set(["$id", "name", "enabled"]);
const KeysCollection = new Set(["$id", "$permissions", "databaseId", "name", "enabled", "documentSecurity", "attributes", "indexes"]);
const KeysStorage = new Set(["$id", "$permissions", "fileSecurity", "name", "enabled", "maximumFileSize", "allowedFileExtensions", "compression", "encryption", "antivirus"]);
const KeyTopics = new Set(["$id", "name", "subscribe"]);
const KeyAttributes = new Set([
"key",
"type",
"required",
"array",
"size",
"default",
// integer and float
"min",
"max",
// email, enum, URL, IP, and datetime
"format",
// enum
"elements",
// relationship
"relatedCollection",
"relationType",
"twoWay",
"twoWayKey",
"onDelete",
"side"
]);
const KeyIndexes = new Set(["key", "type", "status", "attributes", "orders"]);

function whitelistKeys(value, keys, nestedKeys = {}) {
if(Array.isArray(value)) {
const newValue = [];

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

const newValue = {};
Object.keys(value).forEach((key) => {
if(keys.includes(key)) {
if(keys.has(key)) {
if(nestedKeys[key]) {
newValue[key] = whitelistKeys(value[key], nestedKeys[key]);
} else {
Expand Down
Loading

0 comments on commit 7ebd1b9

Please sign in to comment.