Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion example.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ function getSSLPage($url) {
// $spec = getSSLPage('https://appwrite.io/v1/open-api-2.json?extensions=1'); // Enable only with Appwrite local server running on port 80
// $spec = getSSLPage('https://appwrite.io/v1/open-api-2.json?extensions=1&platform=console'); // Enable only with Appwrite local server running on port 80
// $spec = file_get_contents('https://appwrite.io/specs/swagger2?platform=client');
$spec = file_get_contents('./specs/swagger2-latest-console.json');
$spec = file_get_contents('./specs/swagger-appwrite-0.13.0.json');

if(empty($spec)) {
throw new Exception('Failed to fetch spec from Appwrite server');
Expand Down
1 change: 1 addition & 0 deletions specs/swagger-appwrite-0.13.0.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions templates/node-cli/lib/client.js.twig
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ const {{spec.title | caseUcfirst}}Exception = require("./exception.js");
const { globalConfig } = require("./config.js");

class Client {
static CHUNK_SIZE = 5*1024*1024; // 5MB

constructor() {
this.endpoint = '{{spec.endpoint}}';
this.headers = {
Expand Down
71 changes: 67 additions & 4 deletions templates/node-cli/lib/commands/command.js.twig
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const fs = require('fs');
const { promisify } = require('util');
const libClient = require('../client.js');
const childProcess = require('child_process');
const { Command } = require('commander');
const { sdkForProject, sdkForConsole } = require('../sdks')
Expand All @@ -8,7 +10,7 @@ const { localConfig, globalConfig } = require("../config");
const {{ service.name | caseLower }} = new Command("{{ service.name | caseLower }}").description(commandDescriptions['{{ service.name | caseLower }}'])

{% for method in service.methods %}
const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({ {% for parameter in method.parameters.all %}{{ parameter.name | caseCamel | escapeKeyword }}, {% endfor %}parseOutput = true, sdk = undefined, json }) => {
const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({ {% for parameter in method.parameters.all %}{{ parameter.name | caseCamel | escapeKeyword }}, {% endfor %}parseOutput = true, sdk = undefined, json{% if 'multipart/form-data' in method.consumes %}, onProgress = () => {}{% endif %}}) => {
{% for parameter in method.parameters.all %}
/* @param {{ '{' }}{{ parameter.type | typeName }}{{ '}' }} {{ parameter.name | caseCamel | escapeKeyword }} */
{% endfor %}
Expand Down Expand Up @@ -37,13 +39,13 @@ const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({ {
childProcess.execSync(`tar --cd '${folderPath}' -zcvf code.tar.gz .`, { stdio: 'pipe' });
let archivePath = fs.realpathSync('code.tar.gz')
if (typeof archivePath !== 'undefined') {
payload['{{ parameter.name }}'] = fs.createReadStream(archivePath);
payload['{{ parameter.name }}'] = archivePath;
}

{% elseif parameter.type == 'file' %}
let filePath = fs.realpathSync({{ parameter.name | caseCamel | escapeKeyword }});
if (typeof filePath !== 'undefined') {
payload['{{ parameter.name }}'] = fs.createReadStream(filePath);
payload['{{ parameter.name }}'] = filePath;
}

{% else %}
Expand All @@ -63,14 +65,75 @@ const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({ {
success()
}
{% else %}
const response = await client.call('{{ method.method | caseLower }}', path, {
let response = undefined;
{% if 'multipart/form-data' in method.consumes %}
{% for parameter in method.parameters.all %}
{% if parameter.type == 'file' %}
const { size: size } = await promisify(fs.stat)({{ parameter.name | caseCamel | escapeKeyword }});

if (size <= libClient.CHUNK_SIZE) {
payload['{{ parameter.name }}'] = fs.createReadStream(payload['{{ parameter.name }}']);

response = await client.call('{{ method.method | caseLower }}', path, {
{% for parameter in method.parameters.header %}
'{{ parameter.name }}': ${{ parameter.name | caseCamel | escapeKeyword }},
{% endfor %}
{% for key, header in method.headers %}
'{{ key }}': '{{ header }}',
{% endfor %}
}, payload{% if method.type == 'location' %}, 'arraybuffer'{% endif %});
} else {
const streamFilePath = payload['{{ parameter.name }}'];
let id = undefined;

const totalCounters = Math.ceil(size / libClient.CHUNK_SIZE);

for (let counter = 0; counter < totalCounters; counter++) {
const start = (counter * libClient.CHUNK_SIZE);
const end = Math.min((((counter * libClient.CHUNK_SIZE) + libClient.CHUNK_SIZE) - 1), size);
const headers = {
{% for parameter in method.parameters.header %}
'{{ parameter.name }}': ${{ parameter.name | caseCamel | escapeKeyword }},
{% endfor %}
{% for key, header in method.headers %}
'{{ key }}': '{{ header }}',
{% endfor %}
'content-range': 'bytes ' + start + '-' + end + '/' + size
};

if (id) {
headers['x-appwrite-id'] = id;
}

const stream = fs.createReadStream(streamFilePath, {
start,
end
});
payload['{{ parameter.name }}'] = stream;

response = await client.call('{{ method.method | caseLower }}', path, headers, payload{% if method.type == 'location' %}, 'arraybuffer'{% endif %});

if (!id) {
id = response['$id'];
}

if (onProgress !== null) {
onProgress(Math.min((counter+1) * libClient.CHUNK_SIZE, size) / size * 100);
}
}
}
{% endif %}
{% endfor %}
{% else %}
response = await client.call('{{ method.method | caseLower }}', path, {
{% for parameter in method.parameters.header %}
'{{ parameter.name }}': ${{ parameter.name | caseCamel | escapeKeyword }},
{% endfor %}
{% for key, header in method.headers %}
'{{ key }}': '{{ header }}',
{% endfor %}
}, payload{% if method.type == 'location' %}, 'arraybuffer'{% endif %});
{% endif %}
{% if method.packaging %}

fs.unlinkSync(archivePath);
Expand Down
2 changes: 2 additions & 0 deletions templates/node-cli/lib/sdks.js.twig
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,10 @@ const sdkForProject = async () => {

if (key) {
return client
{% if sdk.isTest != "true" %}
.setKey(key)
.setMode("default");
{% endif %}
}

if (cookie) {
Expand Down
3 changes: 2 additions & 1 deletion tests/SDKTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,8 @@ class SDKTest extends TestCase
'expectedOutput' => [
...FOO_RESPONSES,
...BAR_RESPONSES,
...GENERAL_RESPONSES
...GENERAL_RESPONSES,
'POST:/v1/mock/tests/general/upload:passed', // for large file upload
],
],

Expand Down
3 changes: 3 additions & 0 deletions tests/languages/node-cli/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,7 @@ output = execSync("node index general redirect", { stdio: 'pipe'}).toString();
console.log(output.split('\n')[0].split(" : ")[1]);

output = execSync("node index general upload --x string --y 123 --z string in array --file ../../resources/file.png", { stdio: 'pipe'}).toString();
console.log(output.split('\n')[0].split(" : ")[1]);

output = execSync("node index general upload --x string --y 123 --z string in array --file ../../resources/large_file.mp4", { stdio: 'pipe'}).toString();
console.log(output.split('\n')[0].split(" : ")[1]);
Binary file added tests/resources/large_file.mp4
Binary file not shown.