Skip to content

Commit d6448fc

Browse files
authored
Merge pull request #175 from appwrite/dev
chore: regenerate sdk
2 parents dfab055 + 4c42e69 commit d6448fc

File tree

18 files changed

+245
-144
lines changed

18 files changed

+245
-144
lines changed

CHANGELOG.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
# Change Log
22

3+
## 8.2.0
4+
5+
* Add `encrypt` attribute support
6+
* Add improved warnings on attribute recreation and deletion
7+
* Fix `null` parsing error when using create attribute command
8+
* Type generation fixes and improvements:
9+
* Add `--strict` / `-s` flag to `appwrite types` command to generate types in strict mode. This automatically converts the casing of attributes to match the language's naming conventions
10+
* Add automatic package import to `dart` language which uses package detection to import the correct package
11+
* Add `Document` class extension to generated types in `dart` and `js` language to support internal attributes like `$id` and `$collectionId` etc.
12+
* Add proper enum support to `js` language
13+
* Fix indentation in `java`, `kotlin` and `swift` to use 2 spaces instead of 4 for consistency across all languages
14+
* Fix doc comments to use correct syntax in various languages (for eg. `///` instead of `/*`)
15+
* Update enums in `dart` to use lowerCamelCase in `strict` mode as per [constant_identifier_names](https://dart.dev/tools/diagnostics/constant_identifier_names?utm_source=dartdev&utm_medium=redir&utm_id=diagcode&utm_content=constant_identifier_names)
16+
317
## 8.1.1
418

519
* Fix circular dependency issue due to usage of `success` method in `utils.js` file from `parser.js` file

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-
8.1.1
32+
8.2.0
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-
8.1.1
63+
8.2.0
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/8.1.1/appwrite-cli-win-x64.exe"
17-
$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.1.1/appwrite-cli-win-arm64.exe"
16+
$GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.2.0/appwrite-cli-win-x64.exe"
17+
$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.2.0/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="8.1.1"
100+
GITHUB_LATEST_VERSION="8.2.0"
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: 2 additions & 2 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': '8.1.1',
20-
'user-agent' : `AppwriteCLI/8.1.1 (${os.type()} ${os.version()}; ${os.arch()})`,
19+
'x-sdk-version': '8.2.0',
20+
'user-agent' : `AppwriteCLI/8.2.0 (${os.type()} ${os.version()}; ${os.arch()})`,
2121
'X-Appwrite-Response-Format' : '1.7.0',
2222
};
2323
}

lib/commands/push.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ const createAttribute = (databaseId, collectionId, attribute) => {
508508
required: attribute.required,
509509
xdefault: attribute.default,
510510
array: attribute.array,
511+
encrypt: attribute.encrypt,
511512
parseOutput: false
512513
})
513514

@@ -844,10 +845,14 @@ const attributesToCreate = async (remoteAttributes, localAttributes, collection,
844845

845846
if (!cliConfig.force) {
846847
if (deleting.length > 0 && !isIndex) {
847-
log(`Attribute deletion will cause ${chalk.red('loss of data')}`);
848+
console.log(`${chalk.red('-------------------------------------------------------')}`);
849+
console.log(`${chalk.red('| WARNING: Attribute deletion may cause loss of data |')}`);
850+
console.log(`${chalk.red('-------------------------------------------------------')}`);
848851
}
849852
if (conflicts.length > 0 && !isIndex) {
850-
log(`Attribute recreation will cause ${chalk.red('loss of data')}`);
853+
console.log(`${chalk.red('---------------------------------------------------------')}`);
854+
console.log(`${chalk.red('| WARNING: Attribute recreation may cause loss of data |')}`);
855+
console.log(`${chalk.red('---------------------------------------------------------')}`);
851856
}
852857

853858
if ((await getConfirmation()) !== true) {

lib/commands/types.js

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,22 @@ const typesLanguageOption = new Option(
5858
.choices(["auto", "ts", "js", "php", "kotlin", "swift", "java", "dart"])
5959
.default("auto");
6060

61-
const typesCommand = actionRunner(async (rawOutputDirectory, {language}) => {
61+
const typesStrictOption = new Option(
62+
"-s, --strict",
63+
"Enable strict mode to automatically convert field names to follow language conventions"
64+
)
65+
.default(false);
66+
67+
const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict}) => {
6268
if (language === "auto") {
6369
language = detectLanguage();
6470
log(`Detected language: ${language}`);
6571
}
6672

73+
if (strict) {
74+
log(`Strict mode enabled: Field names will be converted to follow ${language} conventions`);
75+
}
76+
6777
const meta = createLanguageMeta(language);
6878

6979
const rawOutputPath = rawOutputDirectory;
@@ -106,6 +116,7 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language}) => {
106116
if (meta.isSingleFile()) {
107117
const content = templater({
108118
collections,
119+
strict,
109120
...templateHelpers,
110121
getType: meta.getType
111122
});
@@ -118,6 +129,7 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language}) => {
118129
for (const collection of collections) {
119130
const content = templater({
120131
collection,
132+
strict,
121133
...templateHelpers,
122134
getType: meta.getType
123135
});
@@ -136,6 +148,7 @@ const types = new Command("types")
136148
.description("Generate types for your Appwrite project")
137149
.addArgument(typesOutputArgument)
138150
.addOption(typesLanguageOption)
151+
.addOption(typesStrictOption)
139152
.action(actionRunner(typesCommand));
140153

141154
module.exports = { types };

lib/config.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ const KeysAttributes = new Set([
3535
"side",
3636
// Indexes
3737
"attributes",
38-
"orders"
38+
"orders",
39+
// Strings
40+
"encrypt",
3941
]);
4042
const KeyIndexes = new Set(["key", "type", "status", "attributes", "orders"]);
4143

lib/parser.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ const parse = (data) => {
2424
}
2525

2626
for (let key in data) {
27-
if (Array.isArray(data[key])) {
27+
if (data[key] === null) {
28+
console.log(`${chalk.yellow.bold(key)} : null`);
29+
} else if (Array.isArray(data[key])) {
2830
console.log(`${chalk.yellow.bold.underline(key)}`);
2931
if (typeof data[key][0] === 'object') {
3032
drawTable(data[key]);
@@ -120,7 +122,7 @@ const parseError = (err) => {
120122
} catch {
121123
}
122124

123-
const version = '8.1.1';
125+
const version = '8.2.0';
124126
const stepsToReproduce = `Running \`appwrite ${cliConfig.reportData.data.args.join(' ')}\``;
125127
const yourEnvironment = `CLI version: ${version}\nOperation System: ${os.type()}\nAppwrite version: ${appwriteVersion}\nIs Cloud: ${isCloud()}`;
126128

lib/type-generation/languages/dart.js

Lines changed: 71 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,45 @@
11
/** @typedef {import('../attribute').Attribute} Attribute */
22
const { AttributeType } = require('../attribute');
33
const { LanguageMeta } = require("./language");
4+
const fs = require('fs');
5+
const path = require('path');
46

57
class Dart extends LanguageMeta {
8+
getPackageName() {
9+
const pubspecPath = path.join(this.getCurrentDirectory(), 'pubspec.yaml');
10+
if (fs.existsSync(pubspecPath)) {
11+
const pubspecContent = fs.readFileSync(pubspecPath, 'utf8');
12+
const lines = pubspecContent.split('\n');
13+
14+
const dependenciesIndex = lines.findIndex(line => line.trim() === 'dependencies:');
15+
16+
if (dependenciesIndex !== -1) {
17+
const indent = lines[dependenciesIndex].search(/\S|$/);
18+
const dependencies = [];
19+
for (let i = dependenciesIndex + 1; i < lines.length; i++) {
20+
const line = lines[i];
21+
if (line.trim() === '') continue;
22+
23+
const lineIndent = line.search(/\S|$/);
24+
if (lineIndent <= indent && line.trim() !== '') {
25+
break;
26+
}
27+
28+
dependencies.push(line.trim());
29+
}
30+
31+
if (dependencies.some(dep => dep.startsWith('dart_appwrite:'))) {
32+
return 'dart_appwrite';
33+
}
34+
if (dependencies.some(dep => dep.startsWith('appwrite:'))) {
35+
return 'appwrite';
36+
}
37+
}
38+
}
39+
40+
return 'appwrite';
41+
}
42+
643
getType(attribute) {
744
let type = "";
845
switch (attribute.type) {
@@ -46,42 +83,55 @@ class Dart extends LanguageMeta {
4683
}
4784

4885
getTemplate() {
49-
return `<% for (const attribute of collection.attributes) { -%>
86+
return `import 'package:${this.getPackageName()}/models.dart';
87+
<% for (const attribute of collection.attributes) { -%>
5088
<% if (attribute.type === 'relationship') { -%>
5189
import '<%- attribute.relatedCollection.toLowerCase() %>.dart';
5290
5391
<% } -%>
5492
<% } -%>
55-
/**
56-
* This file is auto-generated by the Appwrite CLI.
57-
* You can regenerate it by running \`appwrite types -l dart ${this.getCurrentDirectory()}\`.
58-
*/
93+
/// This file is auto-generated by the Appwrite CLI.
94+
/// You can regenerate it by running \`appwrite types -l dart ${this.getCurrentDirectory()}\`.
5995
6096
<% for (const attribute of collection.attributes) { -%>
6197
<% if (attribute.format === 'enum') { -%>
6298
enum <%- toPascalCase(attribute.key) %> {
6399
<% for (const [index, element] of Object.entries(attribute.elements)) { -%>
64-
<%- toSnakeCase(element) %><% if (index < attribute.elements.length - 1) { %>,<% } %>
100+
<%- strict ? toCamelCase(element) : element %><% if (index < attribute.elements.length - 1) { %>,<% } %>
65101
<% } -%>
66102
}
67103
68104
<% } -%>
69105
<% } -%>
70-
class <%= toPascalCase(collection.name) %> {
106+
class <%= toPascalCase(collection.name) %> extends Document {
71107
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
72-
<%- getType(attribute) %> <%= toCamelCase(attribute.key) %>;
108+
<%- getType(attribute) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
73109
<% } -%>
74110
75111
<%= toPascalCase(collection.name) %>({
112+
required super.$id,
113+
required super.$collectionId,
114+
required super.$databaseId,
115+
required super.$createdAt,
116+
required super.$updatedAt,
117+
required super.$permissions,
118+
required super.data,
76119
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
77-
<% if (attribute.required) { %>required <% } %>this.<%= toCamelCase(attribute.key) %><% if (index < collection.attributes.length - 1) { %>,<% } %>
120+
<% if (attribute.required) { %>required <% } %>this.<%= strict ? toCamelCase(attribute.key) : attribute.key %><% if (index < collection.attributes.length - 1) { %>,<% } %>
78121
<% } -%>
79122
});
80123
81124
factory <%= toPascalCase(collection.name) %>.fromMap(Map<String, dynamic> map) {
82125
return <%= toPascalCase(collection.name) %>(
126+
$id: map['\\$id'].toString(),
127+
$collectionId: map['\\$collectionId'].toString(),
128+
$databaseId: map['\\$databaseId'].toString(),
129+
$createdAt: map['\\$createdAt'].toString(),
130+
$updatedAt: map['\\$updatedAt'].toString(),
131+
$permissions: List<String>.from(map['\\$permissions'] ?? []),
132+
data: map,
83133
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
84-
<%= toCamelCase(attribute.key) %>: <% if (attribute.type === 'string' || attribute.type === 'email' || attribute.type === 'datetime') { -%>
134+
<%= strict ? toCamelCase(attribute.key) : attribute.key %>: <% if (attribute.type === 'string' || attribute.type === 'email' || attribute.type === 'datetime') { -%>
85135
<% if (attribute.format === 'enum') { -%>
86136
<% if (attribute.array) { -%>
87137
(map['<%= attribute.key %>'] as List<dynamic>?)?.map((e) => <%- toPascalCase(attribute.key) %>.values.firstWhere((element) => element.name == e)).toList()<% if (!attribute.required) { %> ?? []<% } -%>
@@ -130,21 +180,27 @@ map['<%= attribute.key %>'] != null ? <%- toPascalCase(attribute.relatedCollecti
130180
131181
Map<String, dynamic> toMap() {
132182
return {
183+
"\\$id": $id,
184+
"\\$collectionId": $collectionId,
185+
"\\$databaseId": $databaseId,
186+
"\\$createdAt": $createdAt,
187+
"\\$updatedAt": $updatedAt,
188+
"\\$permissions": $permissions,
133189
<% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
134190
"<%= attribute.key %>": <% if (attribute.type === 'relationship') { -%>
135191
<% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
136-
<%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.map((e) => e.toMap()).toList()<% if (!attribute.required) { %> ?? []<% } -%>
192+
<%= strict ? toCamelCase(attribute.key) : attribute.key %><% if (!attribute.required) { %>?<% } %>.map((e) => e.toMap()).toList()<% if (!attribute.required) { %> ?? []<% } -%>
137193
<% } else { -%>
138-
<%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.toMap()<% if (!attribute.required) { %> ?? {}<% } -%>
194+
<%= strict ? toCamelCase(attribute.key) : attribute.key %><% if (!attribute.required) { %>?<% } %>.toMap()<% if (!attribute.required) { %> ?? {}<% } -%>
139195
<% } -%>
140196
<% } else if (attribute.format === 'enum') { -%>
141197
<% if (attribute.array) { -%>
142-
<%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.map((e) => e.name).toList()<% if (!attribute.required) { %> ?? []<% } -%>
198+
<%= strict ? toCamelCase(attribute.key) : attribute.key %><% if (!attribute.required) { %>?<% } %>.map((e) => e.name).toList()<% if (!attribute.required) { %> ?? []<% } -%>
143199
<% } else { -%>
144-
<%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.name<% if (!attribute.required) { %> ?? null<% } -%>
200+
<%= strict ? toCamelCase(attribute.key) : attribute.key %><% if (!attribute.required) { %>?<% } %>.name<% if (!attribute.required) { %> ?? null<% } -%>
145201
<% } -%>
146202
<% } else { -%>
147-
<%= toCamelCase(attribute.key) -%>
203+
<%= strict ? toCamelCase(attribute.key) : attribute.key -%>
148204
<% } -%><% if (index < collection.attributes.length - 1) { %>,<% } %>
149205
<% } -%>
150206
};

0 commit comments

Comments
 (0)