Skip to content

Commit e4b8b13

Browse files
authored
Merge branch 'master' into patch-1
2 parents 5dc2994 + 7e2456a commit e4b8b13

31 files changed

+1477
-101
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ sdk-generator/blob/master/example.php:
115115
Run the following command (make sure you have an updated docker version on your machine):
116116

117117
```bash
118-
docker run --rm -v $(pwd):/app -w /app php:7.4-cli php example.php
118+
docker run --rm -v $(pwd):/app -w /app php:8.1-cli php example.php
119119
```
120120

121121
>Note: You can just add the new language next to the other languages in the `example.php` file. You don't need to rewrite the file completely.
@@ -252,7 +252,7 @@ Also in `.travis.yml` add new env `SDK=[Language]` so that travis will run a tes
252252

253253
Finally, you can run tests using:
254254
```sh
255-
docker run --rm -v $(pwd):$(pwd):rw -w $(pwd) -v /var/run/docker.sock:/var/run/docker.sock php:7.4-cli-alpine sh -c "apk add docker-cli && vendor/bin/phpunit"
255+
docker run --rm -v $(pwd):$(pwd):rw -w $(pwd) -v /var/run/docker.sock:/var/run/docker.sock php:8.1-cli-alpine sh -c "apk add docker-cli && vendor/bin/phpunit"
256256
```
257257

258258
## SDK Generator Interface

src/SDK/Language/Flutter.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,26 @@ public function getFiles(): array
205205
'destination' => '/lib/src/interceptor.dart',
206206
'template' => 'flutter/lib/src/interceptor.dart.twig',
207207
],
208+
[
209+
'scope' => 'default',
210+
'destination' => '/lib/src/offline_db_io.dart',
211+
'template' => 'flutter/lib/src/offline_db_io.dart.twig',
212+
],
213+
[
214+
'scope' => 'default',
215+
'destination' => '/lib/src/offline_db_stub.dart',
216+
'template' => 'flutter/lib/src/offline_db_stub.dart.twig',
217+
],
218+
[
219+
'scope' => 'default',
220+
'destination' => '/lib/src/offline_db_web.dart',
221+
'template' => 'flutter/lib/src/offline_db_web.dart.twig',
222+
],
223+
[
224+
'scope' => 'default',
225+
'destination' => '/lib/src/client_offline_mixin.dart',
226+
'template' => 'flutter/lib/src/client_offline_mixin.dart.twig',
227+
],
208228
[
209229
'scope' => 'default',
210230
'destination' => '/lib/{{ language.params.packageName }}.dart',

src/Spec/Swagger2.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ public function getMethods($service)
184184
'query' => [],
185185
'body' => [],
186186
],
187+
'offline' => [
188+
'model' => $method['x-appwrite']['offline-model'] ?? '',
189+
'key' => $method['x-appwrite']['offline-key'] ?? '',
190+
'response-key' => $method['x-appwrite']['offline-response-key'] ?? '$id',
191+
],
187192
'emptyResponse' => $emptyResponse,
188193
'responseModel' => $responseModel,
189194
];

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,10 @@ const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({ {
8181
}
8282

8383
{% else %}
84+
{% if parameter.type == 'array' %}
85+
{{ parameter.name | caseCamel | escapeKeyword}} = {{ parameter.name | caseCamel | escapeKeyword}} === true ? [] : {{ parameter.name | caseCamel | escapeKeyword}};
86+
{% endif %}
87+
8488
if (typeof {{ parameter.name | caseCamel | escapeKeyword }} !== 'undefined') {
8589
payload['{{ parameter.name }}'] = {{ parameter.name | caseCamel | escapeKeyword}}{% if method.consumes[0] == "multipart/form-data" and ( parameter.type != "string" and parameter.type != "array" ) %}.toString(){% endif %};
8690
}
@@ -224,7 +228,7 @@ const {{ service.name | caseLower }}{{ method.name | caseUcfirst }} = async ({ {
224228
{% autoescape false %}
225229
.description(`{{ method.description | replace({'`':'\''}) | replace({'\n':' '}) | replace({'\n \n':' '}) }}`)
226230
{% for parameter in method.parameters.all %}
227-
.{% if parameter.required %}requiredOption{% else %}option{% endif %}(`--{{ parameter.name | escapeKeyword }} <{{ parameter.name | escapeKeyword }}{% if parameter.array.type|length > 0 %}...{% endif %}>`, `{{ parameter.description | replace({'`':'\''}) | replace({'\n':' '}) | replace({'\n \n':' '}) }}`{% if parameter | typeName == 'boolean' %}, parseBool{% elseif parameter | typeName == 'number' %}, parseInteger{% endif %})
231+
.{% if parameter.required %}requiredOption{% else %}option{% endif %}(`--{{ parameter.name | escapeKeyword }} {% if parameter.array.type|length > 0 %}[{% else %}<{% endif %}{{ parameter.name | escapeKeyword }}{% if parameter.array.type|length > 0 %}...{% endif %}{% if parameter.array.type|length > 0 %}]{% else %}>{% endif %}`, `{{ parameter.description | replace({'`':'\''}) | replace({'\n':' '}) | replace({'\n \n':' '}) }}`{% if parameter | typeName == 'boolean' %}, parseBool{% elseif parameter | typeName == 'number' %}, parseInteger{% endif %})
228232
{% endfor %}
229233
{% if method.type == 'location' %}
230234
.requiredOption(`--destination <path>`, `output file path.`)

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

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const inquirer = require("inquirer");
22
const JSONbig = require("json-bigint")({ storeAsString: false });
33
const { Command } = require("commander");
44
const { localConfig } = require("../config");
5-
const { questionsDeployTeams, questionsDeployFunctions, questionsGetEntrypoint, questionsDeployCollections, questionsConfirmDeployCollections } = require("../questions");
5+
const { questionsDeployBuckets, questionsDeployTeams, questionsDeployFunctions, questionsGetEntrypoint, questionsDeployCollections, questionsConfirmDeployCollections } = require("../questions");
66
const { actionRunner, success, log, error, commandDescriptions } = require("../parser");
77
const { functionsGet, functionsCreate, functionsUpdate, functionsCreateDeployment, functionsUpdateDeployment, functionsListVariables, functionsDeleteVariable, functionsCreateVariable } = require('./functions');
88
const {
@@ -23,8 +23,12 @@ const {
2323
databasesDeleteAttribute,
2424
databasesListAttributes,
2525
databasesListIndexes,
26-
databasesDeleteIndex
26+
databasesDeleteIndex,
27+
databasesUpdateCollection
2728
} = require("./databases");
29+
const {
30+
storageGetBucket, storageUpdateBucket, storageCreateBucket
31+
} = require("./storage");
2832
const {
2933
teamsGet,
3034
teamsUpdate,
@@ -437,17 +441,27 @@ const deployCollection = async ({ all, yes } = {}) => {
437441

438442
let databaseId;
439443

444+
const localDatabase = localConfig.getDatabase(collection.databaseId);
445+
440446
try {
441447
const database = await databasesGet({
442448
databaseId: collection.databaseId,
443449
parseOutput: false,
444450
});
445451
databaseId = database.$id;
452+
453+
await databasesUpdate({
454+
databaseId: collection.databaseId,
455+
name: localDatabase.name ?? collection.databaseId,
456+
parseOutput: false
457+
})
458+
459+
success(`Updated ${localDatabase.name} ( ${collection.databaseId} )`);
446460
} catch(err) {
447461
log(`Database ${collection.databaseId} not found. Creating it now...`);
448462
const database = await databasesCreate({
449463
databaseId: collection.databaseId,
450-
name: collection.databaseId,
464+
name: localDatabase.name ?? collection.databaseId,
451465
parseOutput: false,
452466
});
453467
databaseId = database.$id;
@@ -547,6 +561,18 @@ const deployCollection = async ({ all, yes } = {}) => {
547561
}
548562

549563
success(`Created ${collection.indexes.length} indexes`);
564+
565+
await databasesUpdateCollection({
566+
databaseId,
567+
collectionId: collection['$id'],
568+
name: collection.name,
569+
documentSecurity: collection.documentSecurity,
570+
permissions: collection['$permissions'],
571+
enabled: collection.enabled,
572+
parseOutput: false
573+
})
574+
575+
success(`Deployed ${collection.name} ( ${collection['$id']} )`);
550576
} catch (e) {
551577
if (e.code == 404) {
552578
log(`Collection ${collection.name} does not exist in the project. Creating ... `);
@@ -601,6 +627,93 @@ const deployCollection = async ({ all, yes } = {}) => {
601627
}
602628
}
603629

630+
const deployBucket = async ({ all, yes } = {}) => {
631+
let response = {};
632+
633+
let bucketIds = [];
634+
const configBuckets = localConfig.getBuckets();
635+
636+
if(all) {
637+
if (configBuckets.length === 0) {
638+
throw new Error("No buckets found in the current directory. Run `appwrite init bucket` to fetch all your buckets.");
639+
}
640+
bucketIds.push(...configBuckets.map((b) => b.$id));
641+
}
642+
643+
if(bucketIds.length === 0) {
644+
let answers = await inquirer.prompt(questionsDeployBuckets[0])
645+
bucketIds.push(...answers.buckets);
646+
}
647+
648+
let buckets = [];
649+
650+
for(const bucketId of bucketIds) {
651+
const idBuckets = configBuckets.filter((b) => b.$id === bucketId);
652+
buckets.push(...idBuckets);
653+
}
654+
655+
for (let bucket of buckets) {
656+
log(`Deploying bucket ${bucket.name} ( ${bucket['$id']} )`)
657+
658+
try {
659+
response = await storageGetBucket({
660+
bucketId: bucket['$id'],
661+
parseOutput: false,
662+
})
663+
log(`Bucket ${bucket.name} ( ${bucket['$id']} ) already exists.`);
664+
665+
if(!yes) {
666+
answers = await inquirer.prompt(questionsDeployBuckets[1])
667+
if (answers.override !== "YES") {
668+
log(`Received "${answers.override}". Skipping ${bucket.name} ( ${bucket['$id']} )`);
669+
continue;
670+
}
671+
}
672+
673+
log(`Updating bucket ...`)
674+
675+
await storageUpdateBucket({
676+
bucketId: bucket['$id'],
677+
name: bucket.name,
678+
permissions: bucket['$permissions'],
679+
fileSecurity: bucket.fileSecurity,
680+
enabled: bucket.enabled,
681+
maximumFileSize: bucket.maximumFileSize,
682+
allowedFileExtensions: bucket.allowedFileExtensions,
683+
compression: bucket.compression,
684+
encryption: bucket.encryption,
685+
antivirus: bucket.antivirus,
686+
compression: bucket.compression,
687+
parseOutput: false
688+
});
689+
690+
success(`Deployed ${bucket.name} ( ${bucket['$id']} )`);
691+
} catch (e) {
692+
if (e.code == 404) {
693+
log(`Bucket ${bucket.name} does not exist in the project. Creating ... `);
694+
695+
response = await storageCreateBucket({
696+
bucketId: bucket['$id'],
697+
name: bucket.name,
698+
permissions: bucket['$permissions'],
699+
fileSecurity: bucket.fileSecurity,
700+
enabled: bucket.enabled,
701+
maximumFileSize: bucket.maximumFileSize,
702+
allowedFileExtensions: bucket.allowedFileExtensions,
703+
compression: bucket.compression,
704+
encryption: bucket.encryption,
705+
antivirus: bucket.antivirus,
706+
parseOutput: false
707+
})
708+
709+
success(`Deployed ${bucket.name} ( ${bucket['$id']} )`);
710+
} else {
711+
throw e;
712+
}
713+
}
714+
}
715+
}
716+
604717
const deployTeam = async ({ all, yes } = {}) => {
605718
let response = {};
606719

@@ -686,6 +799,13 @@ deploy
686799
.option(`--yes`, `Flag to confirm all warnings`)
687800
.action(actionRunner(deployCollection));
688801

802+
deploy
803+
.command("bucket")
804+
.description("Deploy buckets in the current project.")
805+
.option(`--all`, `Flag to deploy all buckets`)
806+
.option(`--yes`, `Flag to confirm all warnings`)
807+
.action(actionRunner(deployBucket));
808+
689809
deploy
690810
.command("team")
691811
.description("Deploy teams in the current project.")

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const { teamsCreate, teamsList } = require("./teams");
77
const { projectsCreate } = require("./projects");
88
const { functionsCreate } = require("./functions");
99
const { databasesListCollections, databasesList } = require("./databases");
10+
const { storageListBuckets } = require("./storage");
1011
const { sdkForConsole } = require("../sdks");
1112
const { localConfig } = require("../config");
1213
const { questionsInitProject, questionsInitFunction, questionsInitCollection } = require("../questions");
@@ -170,6 +171,13 @@ const initCollection = async ({ all, databaseId } = {}) => {
170171
}
171172

172173
for(const databaseId of databaseIds) {
174+
const database = await databasesGet({
175+
databaseId,
176+
parseOutput: false
177+
});
178+
179+
localConfig.addDatabase(database);
180+
173181
// TODO: Pagination?
174182
let response = await databasesListCollections({
175183
databaseId,
@@ -193,6 +201,24 @@ const initCollection = async ({ all, databaseId } = {}) => {
193201
success();
194202
}
195203

204+
const initBucket = async () => {
205+
// TODO: Pagination?
206+
let response = await storageListBuckets({
207+
queries: [ 'limit(100)' ],
208+
parseOutput: false
209+
})
210+
211+
let buckets = response.buckets;
212+
log(`Found ${buckets.length} buckets`);
213+
214+
buckets.forEach(async bucket => {
215+
log(`Fetching ${bucket.name} ...`);
216+
localConfig.addBucket(bucket);
217+
});
218+
219+
success();
220+
}
221+
196222
const initTeam = async () => {
197223
// TODO: Pagination?
198224
let response = await teamsList({
@@ -233,6 +259,11 @@ init
233259
.option(`--all`, `Flag to initialize all databases`)
234260
.action(actionRunner(initCollection))
235261

262+
init
263+
.command("bucket")
264+
.description("Initialise your Appwrite buckets")
265+
.action(actionRunner(initBucket))
266+
236267
init
237268
.command("team")
238269
.description("Initialise your Appwrite teams")

0 commit comments

Comments
 (0)