appwrite-cli 8.1.0 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Change Log
2
2
 
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
+
17
+ ## 8.1.1
18
+
19
+ * Fix circular dependency issue due to usage of `success` method in `utils.js` file from `parser.js` file
20
+ * Type generation fixes:
21
+ * Add ability to generate types directly to a specific file by passing a file path to `appwrite types output_path`, instead of just a directory
22
+ * Fix non-required attributes to not be null if default value is provided
23
+ * Fix `Models` import error
24
+ * Improve formatting and add auto-generated comments
25
+
3
26
  ## 8.1.0
4
27
 
5
28
  * Add multi-region support to `init` command
@@ -15,7 +38,7 @@
15
38
 
16
39
  * Add Type generation fixes:
17
40
  * Properly handle enum attributes in dart, java and kotlin
18
- * Fix initialisation of null attributes in dart's fromMap method
41
+ * Fix initialisation of null attributes in dart's fromMap method
19
42
  * Fix relationships and enums in swift
20
43
 
21
44
  ## 8.0.1
package/README.md CHANGED
@@ -29,7 +29,7 @@ Once the installation is complete, you can verify the install using
29
29
 
30
30
  ```sh
31
31
  $ appwrite -v
32
- 8.1.0
32
+ 8.2.0
33
33
  ```
34
34
 
35
35
  ### Install using prebuilt binaries
@@ -60,7 +60,7 @@ $ scoop install https://raw.githubusercontent.com/appwrite/sdk-for-cli/master/sc
60
60
  Once the installation completes, you can verify your install using
61
61
  ```
62
62
  $ appwrite -v
63
- 8.1.0
63
+ 8.2.0
64
64
  ```
65
65
 
66
66
  ## Getting Started
package/install.ps1 CHANGED
@@ -13,8 +13,8 @@
13
13
  # You can use "View source" of this page to see the full script.
14
14
 
15
15
  # REPO
16
- $GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.1.0/appwrite-cli-win-x64.exe"
17
- $GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.1.0/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"
18
18
 
19
19
  $APPWRITE_BINARY_NAME = "appwrite.exe"
20
20
 
package/install.sh CHANGED
@@ -97,7 +97,7 @@ printSuccess() {
97
97
  downloadBinary() {
98
98
  echo "[2/4] Downloading executable for $OS ($ARCH) ..."
99
99
 
100
- GITHUB_LATEST_VERSION="8.1.0"
100
+ GITHUB_LATEST_VERSION="8.2.0"
101
101
  GITHUB_FILE="appwrite-cli-${OS}-${ARCH}"
102
102
  GITHUB_URL="https://github.com/$GITHUB_REPOSITORY_NAME/releases/download/$GITHUB_LATEST_VERSION/$GITHUB_FILE"
103
103
 
package/lib/client.js CHANGED
@@ -16,8 +16,8 @@ class Client {
16
16
  'x-sdk-name': 'Command Line',
17
17
  'x-sdk-platform': 'console',
18
18
  'x-sdk-language': 'cli',
19
- 'x-sdk-version': '8.1.0',
20
- 'user-agent' : `AppwriteCLI/8.1.0 (${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()})`,
21
21
  'X-Appwrite-Response-Format' : '1.7.0',
22
22
  };
23
23
  }
@@ -508,6 +508,7 @@ const createAttribute = (databaseId, collectionId, attribute) => {
508
508
  required: attribute.required,
509
509
  xdefault: attribute.default,
510
510
  array: attribute.array,
511
+ encrypt: attribute.encrypt,
511
512
  parseOutput: false
512
513
  })
513
514
 
@@ -844,10 +845,14 @@ const attributesToCreate = async (remoteAttributes, localAttributes, collection,
844
845
 
845
846
  if (!cliConfig.force) {
846
847
  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('-------------------------------------------------------')}`);
848
851
  }
849
852
  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('---------------------------------------------------------')}`);
851
856
  }
852
857
 
853
858
  if ((await getConfirmation()) !== true) {
@@ -58,15 +58,40 @@ const typesLanguageOption = new Option(
58
58
  .choices(["auto", "ts", "js", "php", "kotlin", "swift", "java", "dart"])
59
59
  .default("auto");
60
60
 
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}) => {
62
68
  if (language === "auto") {
63
69
  language = detectLanguage();
64
70
  log(`Detected language: ${language}`);
65
71
  }
66
72
 
73
+ if (strict) {
74
+ log(`Strict mode enabled: Field names will be converted to follow ${language} conventions`);
75
+ }
76
+
67
77
  const meta = createLanguageMeta(language);
68
78
 
69
- const outputDirectory = path.resolve(rawOutputDirectory);
79
+ const rawOutputPath = rawOutputDirectory;
80
+ const outputExt = path.extname(rawOutputPath);
81
+ const isFileOutput = !!outputExt;
82
+ let outputDirectory = rawOutputPath;
83
+ let singleFileDestination = null;
84
+
85
+ if (isFileOutput) {
86
+ if (meta.isSingleFile()) {
87
+ // Use the file path directly for single file languages
88
+ outputDirectory = path.dirname(rawOutputPath);
89
+ singleFileDestination = rawOutputPath;
90
+ } else {
91
+ throw new Error(`Invalid output path: ${rawOutputPath}. Output path must be a directory for languages that generate multiple files.`);
92
+ }
93
+ }
94
+
70
95
  if (!fs.existsSync(outputDirectory)) {
71
96
  log(`Directory: ${outputDirectory} does not exist, creating...`);
72
97
  fs.mkdirSync(outputDirectory, { recursive: true });
@@ -91,11 +116,12 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language}) => {
91
116
  if (meta.isSingleFile()) {
92
117
  const content = templater({
93
118
  collections,
119
+ strict,
94
120
  ...templateHelpers,
95
121
  getType: meta.getType
96
122
  });
97
123
 
98
- const destination = path.join(outputDirectory, meta.getFileName());
124
+ const destination = singleFileDestination || path.join(outputDirectory, meta.getFileName());
99
125
 
100
126
  fs.writeFileSync(destination, content);
101
127
  log(`Added types to ${destination}`);
@@ -103,6 +129,7 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language}) => {
103
129
  for (const collection of collections) {
104
130
  const content = templater({
105
131
  collection,
132
+ strict,
106
133
  ...templateHelpers,
107
134
  getType: meta.getType
108
135
  });
@@ -121,6 +148,7 @@ const types = new Command("types")
121
148
  .description("Generate types for your Appwrite project")
122
149
  .addArgument(typesOutputArgument)
123
150
  .addOption(typesLanguageOption)
151
+ .addOption(typesStrictOption)
124
152
  .action(actionRunner(typesCommand));
125
153
 
126
154
  module.exports = { types };
package/lib/config.js CHANGED
@@ -35,7 +35,9 @@ const KeysAttributes = new Set([
35
35
  "side",
36
36
  // Indexes
37
37
  "attributes",
38
- "orders"
38
+ "orders",
39
+ // Strings
40
+ "encrypt",
39
41
  ]);
40
42
  const KeyIndexes = new Set(["key", "type", "status", "attributes", "orders"]);
41
43
 
package/lib/parser.js CHANGED
@@ -24,7 +24,9 @@ const parse = (data) => {
24
24
  }
25
25
 
26
26
  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])) {
28
30
  console.log(`${chalk.yellow.bold.underline(key)}`);
29
31
  if (typeof data[key][0] === 'object') {
30
32
  drawTable(data[key]);
@@ -120,7 +122,7 @@ const parseError = (err) => {
120
122
  } catch {
121
123
  }
122
124
 
123
- const version = '8.1.0';
125
+ const version = '8.2.0';
124
126
  const stepsToReproduce = `Running \`appwrite ${cliConfig.reportData.data.args.join(' ')}\``;
125
127
  const yourEnvironment = `CLI version: ${version}\nOperation System: ${os.type()}\nAppwrite version: ${appwriteVersion}\nIs Cloud: ${isCloud()}`;
126
128
 
@@ -1,8 +1,45 @@
1
1
  /** @typedef {import('../attribute').Attribute} Attribute */
2
2
  const { AttributeType } = require('../attribute');
3
3
  const { LanguageMeta } = require("./language");
4
+ const fs = require('fs');
5
+ const path = require('path');
4
6
 
5
7
  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
+
6
43
  getType(attribute) {
7
44
  let type = "";
8
45
  switch (attribute.type) {
@@ -41,38 +78,60 @@ class Dart extends LanguageMeta {
41
78
  return type;
42
79
  }
43
80
 
81
+ getCurrentDirectory() {
82
+ return process.cwd();
83
+ }
84
+
44
85
  getTemplate() {
45
- return `<% for (const attribute of collection.attributes) { -%>
86
+ return `import 'package:${this.getPackageName()}/models.dart';
87
+ <% for (const attribute of collection.attributes) { -%>
46
88
  <% if (attribute.type === 'relationship') { -%>
47
89
  import '<%- attribute.relatedCollection.toLowerCase() %>.dart';
48
90
 
49
91
  <% } -%>
50
92
  <% } -%>
93
+ /// This file is auto-generated by the Appwrite CLI.
94
+ /// You can regenerate it by running \`appwrite types -l dart ${this.getCurrentDirectory()}\`.
95
+
51
96
  <% for (const attribute of collection.attributes) { -%>
52
97
  <% if (attribute.format === 'enum') { -%>
53
98
  enum <%- toPascalCase(attribute.key) %> {
54
- <% for (const element of attribute.elements) { -%>
55
- <%- toSnakeCase(element) %>,
99
+ <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
100
+ <%- strict ? toCamelCase(element) : element %><% if (index < attribute.elements.length - 1) { %>,<% } %>
56
101
  <% } -%>
57
102
  }
58
103
 
59
104
  <% } -%>
60
105
  <% } -%>
61
- class <%= toPascalCase(collection.name) %> {
106
+ class <%= toPascalCase(collection.name) %> extends Document {
62
107
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
63
- <%- getType(attribute) %> <%= toCamelCase(attribute.key) %>;
108
+ <%- getType(attribute) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
64
109
  <% } -%>
65
110
 
66
111
  <%= 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,
67
119
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
68
- <% if (attribute.required) { %>required <% } %>this.<%= toCamelCase(attribute.key) %>,
120
+ <% if (attribute.required) { %>required <% } %>this.<%= strict ? toCamelCase(attribute.key) : attribute.key %><% if (index < collection.attributes.length - 1) { %>,<% } %>
69
121
  <% } -%>
70
122
  });
71
123
 
72
124
  factory <%= toPascalCase(collection.name) %>.fromMap(Map<String, dynamic> map) {
73
125
  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,
74
133
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
75
- <%= 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') { -%>
76
135
  <% if (attribute.format === 'enum') { -%>
77
136
  <% if (attribute.array) { -%>
78
137
  (map['<%= attribute.key %>'] as List<dynamic>?)?.map((e) => <%- toPascalCase(attribute.key) %>.values.firstWhere((element) => element.name == e)).toList()<% if (!attribute.required) { %> ?? []<% } -%>
@@ -114,29 +173,35 @@ map['<%= attribute.key %>']<% if (!attribute.required) { %> ?? null<% } -%>
114
173
  map['<%= attribute.key %>'] != null ? <%- toPascalCase(attribute.relatedCollection) %>.fromMap(map['<%= attribute.key %>']) : null<% } else { -%>
115
174
  <%- toPascalCase(attribute.relatedCollection) %>.fromMap(map['<%= attribute.key %>'])<% } -%>
116
175
  <% } -%>
117
- <% } -%>,
176
+ <% } -%><% if (index < collection.attributes.length - 1) { %>,<% } %>
118
177
  <% } -%>
119
178
  );
120
179
  }
121
180
 
122
181
  Map<String, dynamic> toMap() {
123
182
  return {
183
+ "\\$id": $id,
184
+ "\\$collectionId": $collectionId,
185
+ "\\$databaseId": $databaseId,
186
+ "\\$createdAt": $createdAt,
187
+ "\\$updatedAt": $updatedAt,
188
+ "\\$permissions": $permissions,
124
189
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
125
190
  "<%= attribute.key %>": <% if (attribute.type === 'relationship') { -%>
126
191
  <% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
127
- <%= 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) { %> ?? []<% } -%>
128
193
  <% } else { -%>
129
- <%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.toMap()<% if (!attribute.required) { %> ?? {}<% } -%>
194
+ <%= strict ? toCamelCase(attribute.key) : attribute.key %><% if (!attribute.required) { %>?<% } %>.toMap()<% if (!attribute.required) { %> ?? {}<% } -%>
130
195
  <% } -%>
131
196
  <% } else if (attribute.format === 'enum') { -%>
132
197
  <% if (attribute.array) { -%>
133
- <%= 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) { %> ?? []<% } -%>
134
199
  <% } else { -%>
135
- <%= 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<% } -%>
136
201
  <% } -%>
137
202
  <% } else { -%>
138
- <%= toCamelCase(attribute.key) -%>
139
- <% } -%>,
203
+ <%= strict ? toCamelCase(attribute.key) : attribute.key -%>
204
+ <% } -%><% if (index < collection.attributes.length - 1) { %>,<% } %>
140
205
  <% } -%>
141
206
  };
142
207
  }
@@ -38,9 +38,18 @@ class Java extends LanguageMeta {
38
38
  return type;
39
39
  }
40
40
 
41
+ getCurrentDirectory() {
42
+ return process.cwd();
43
+ }
44
+
41
45
  getTemplate() {
42
46
  return `package io.appwrite.models;
43
47
 
48
+ /**
49
+ * This file is auto-generated by the Appwrite CLI.
50
+ * You can regenerate it by running \`appwrite types -l java ${this.getCurrentDirectory()}\`.
51
+ */
52
+
44
53
  import java.util.*;
45
54
  <% for (const attribute of collection.attributes) { -%>
46
55
  <% if (attribute.type === 'relationship') { -%>
@@ -52,63 +61,63 @@ public class <%- toPascalCase(collection.name) %> {
52
61
  <% for (const attribute of collection.attributes) { -%>
53
62
  <% if (attribute.format === 'enum') { -%>
54
63
 
55
- public enum <%- toPascalCase(attribute.key) %> {
64
+ public enum <%- toPascalCase(attribute.key) %> {
56
65
  <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
57
- <%- toSnakeCase(element) %><%- index < attribute.elements.length - 1 ? ',' : ';' %>
66
+ <%- strict ? toSnakeCase(element) : element %><%- index < attribute.elements.length - 1 ? ',' : ';' %>
58
67
  <% } -%>
59
- }
68
+ }
60
69
 
61
70
  <% } -%>
62
71
  <% } -%>
63
72
  <% for (const attribute of collection.attributes) { -%>
64
- private <%- getType(attribute) %> <%- toCamelCase(attribute.key) %>;
73
+ private <%- getType(attribute) %> <%- strict ? toCamelCase(attribute.key) : attribute.key %>;
65
74
  <% } -%>
66
75
 
67
- public <%- toPascalCase(collection.name) %>() {
68
- }
76
+ public <%- toPascalCase(collection.name) %>() {
77
+ }
69
78
 
70
- public <%- toPascalCase(collection.name) %>(
79
+ public <%- toPascalCase(collection.name) %>(
71
80
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
72
- <%- getType(attribute) %> <%= toCamelCase(attribute.key) %><%- index < collection.attributes.length - 1 ? ',' : '' %>
81
+ <%- getType(attribute) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %><%- index < collection.attributes.length - 1 ? ',' : '' %>
73
82
  <% } -%>
74
- ) {
83
+ ) {
75
84
  <% for (const attribute of collection.attributes) { -%>
76
- this.<%= toCamelCase(attribute.key) %> = <%= toCamelCase(attribute.key) %>;
85
+ this.<%= strict ? toCamelCase(attribute.key) : attribute.key %> = <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
77
86
  <% } -%>
78
- }
87
+ }
79
88
 
80
89
  <% for (const attribute of collection.attributes) { -%>
81
- public <%- getType(attribute) %> get<%- toPascalCase(attribute.key) %>() {
82
- return <%= toCamelCase(attribute.key) %>;
83
- }
90
+ public <%- getType(attribute) %> get<%- toPascalCase(attribute.key) %>() {
91
+ return <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
92
+ }
84
93
 
85
- public void set<%- toPascalCase(attribute.key) %>(<%- getType(attribute) %> <%= toCamelCase(attribute.key) %>) {
86
- this.<%= toCamelCase(attribute.key) %> = <%= toCamelCase(attribute.key) %>;
87
- }
94
+ public void set<%- toPascalCase(attribute.key) %>(<%- getType(attribute) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>) {
95
+ this.<%= strict ? toCamelCase(attribute.key) : attribute.key %> = <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
96
+ }
88
97
 
89
98
  <% } -%>
90
- @Override
91
- public boolean equals(Object obj) {
92
- if (this == obj) return true;
93
- if (obj == null || getClass() != obj.getClass()) return false;
94
- <%- toPascalCase(collection.name) %> that = (<%- toPascalCase(collection.name) %>) obj;
95
- return <% collection.attributes.forEach((attr, index) => { %>Objects.equals(<%= toCamelCase(attr.key) %>, that.<%= toCamelCase(attr.key) %>)<% if (index < collection.attributes.length - 1) { %> &&
96
- <% } }); %>;
97
- }
99
+ @Override
100
+ public boolean equals(Object obj) {
101
+ if (this == obj) return true;
102
+ if (obj == null || getClass() != obj.getClass()) return false;
103
+ <%- toPascalCase(collection.name) %> that = (<%- toPascalCase(collection.name) %>) obj;
104
+ return <% collection.attributes.forEach((attr, index) => { %>Objects.equals(<%= toCamelCase(attr.key) %>, that.<%= toCamelCase(attr.key) %>)<% if (index < collection.attributes.length - 1) { %> &&
105
+ <% } }); %>;
106
+ }
98
107
 
99
- @Override
100
- public int hashCode() {
101
- return Objects.hash(<%= collection.attributes.map(attr => toCamelCase(attr.key)).join(', ') %>);
102
- }
108
+ @Override
109
+ public int hashCode() {
110
+ return Objects.hash(<%= collection.attributes.map(attr => toCamelCase(attr.key)).join(', ') %>);
111
+ }
103
112
 
104
- @Override
105
- public String toString() {
106
- return "<%- toPascalCase(collection.name) %>{" +
107
- <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
108
- "<%= toCamelCase(attribute.key) %>=" + <%= toCamelCase(attribute.key) %> +
113
+ @Override
114
+ public String toString() {
115
+ return "<%- toPascalCase(collection.name) %>{" +
116
+ <% for (const attribute of collection.attributes) { -%>
117
+ "<%= strict ? toCamelCase(attribute.key) : attribute.key %>=" + <%= strict ? toCamelCase(attribute.key) : attribute.key %> +
109
118
  <% } -%>
110
- '}';
111
- }
119
+ '}';
120
+ }
112
121
  }
113
122
  `;
114
123
  }
@@ -16,7 +16,7 @@ class JavaScript extends LanguageMeta {
16
16
  case AttributeType.URL:
17
17
  type = "string";
18
18
  if (attribute.format === AttributeType.ENUM) {
19
- type = `"${attribute.elements.join('"|"')}"`;
19
+ type = LanguageMeta.toPascalCase(attribute.key);
20
20
  }
21
21
  break;
22
22
  case AttributeType.INTEGER:
@@ -31,7 +31,7 @@ class JavaScript extends LanguageMeta {
31
31
  case AttributeType.RELATIONSHIP:
32
32
  type = LanguageMeta.toPascalCase(attribute.relatedCollection);
33
33
  if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
34
- type = `Array<${type}>`;
34
+ type = `${type}[]`;
35
35
  }
36
36
  break;
37
37
  default:
@@ -40,8 +40,8 @@ class JavaScript extends LanguageMeta {
40
40
  if (attribute.array) {
41
41
  type += "[]";
42
42
  }
43
- if (!attribute.required) {
44
- type += "|null|undefined";
43
+ if (!attribute.required && attribute.default === null) {
44
+ type += "|null";
45
45
  }
46
46
  return type;
47
47
  }
@@ -60,17 +60,35 @@ class JavaScript extends LanguageMeta {
60
60
  return "appwrite";
61
61
  }
62
62
 
63
+ getCurrentDirectory() {
64
+ return process.cwd();
65
+ }
66
+
63
67
  getTemplate() {
64
- return `/**
68
+ return `
69
+ // This file is auto-generated by the Appwrite CLI.
70
+ // You can regenerate it by running \`appwrite types -l js ${this.getCurrentDirectory()}\`.
71
+
72
+ /**
65
73
  * @typedef {import('${this._getAppwriteDependency()}').Models.Document} Document
66
74
  */
67
75
 
68
- <% for (const collection of collections) { %>
76
+ <% for (const collection of collections) { -%>
77
+ <% for (const attribute of collection.attributes) { -%>
78
+ <% if (attribute.format === 'enum') { -%>
69
79
  /**
70
- * @typedef {Object} <%- toPascalCase(collection.name) %>
80
+ * @typedef {"<%- attribute.elements.join('"|"') %>"} <%- toPascalCase(attribute.key) %>
81
+ */
82
+
83
+ <% } -%>
84
+ <% } -%>
85
+ <% } -%>
86
+ <% for (const collection of collections) { %>/**
87
+ * @typedef {Document & {
71
88
  <% for (const attribute of collection.attributes) { -%>
72
- * @property {<%- getType(attribute) %>} <%- toCamelCase(attribute.key) %>
89
+ * <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute) %>;
73
90
  <% } -%>
91
+ * }} <%- toPascalCase(collection.name) %>
74
92
  */
75
93
 
76
94
  <% } %>`;
@@ -35,12 +35,16 @@ class Kotlin extends LanguageMeta {
35
35
  if (attribute.array) {
36
36
  type = "List<" + type + ">";
37
37
  }
38
- if (!attribute.required) {
38
+ if (!attribute.required && attribute.default === null) {
39
39
  type += "?";
40
40
  }
41
41
  return type;
42
42
  }
43
43
 
44
+ getCurrentDirectory() {
45
+ return process.cwd();
46
+ }
47
+
44
48
  getTemplate() {
45
49
  return `package io.appwrite.models
46
50
 
@@ -50,19 +54,24 @@ import <%- toPascalCase(attribute.relatedCollection) %>
50
54
 
51
55
  <% } -%>
52
56
  <% } -%>
57
+ /**
58
+ * This file is auto-generated by the Appwrite CLI.
59
+ * You can regenerate it by running \`appwrite types -l kotlin ${this.getCurrentDirectory()}\`.
60
+ */
61
+
53
62
  <% for (const attribute of collection.attributes) { -%>
54
63
  <% if (attribute.format === 'enum') { -%>
55
64
  enum class <%- toPascalCase(attribute.key) %> {
56
65
  <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
57
- <%- toUpperSnakeCase(element) %><%- index < attribute.elements.length - 1 ? ',' : '' %>
66
+ <%- strict ? toUpperSnakeCase(element) : element %><%- index < attribute.elements.length - 1 ? ',' : '' %>
58
67
  <% } -%>
59
68
  }
60
69
 
61
70
  <% } -%>
62
71
  <% } -%>
63
72
  data class <%- toPascalCase(collection.name) %>(
64
- <% for (const attribute of collection.attributes) { -%>
65
- val <%- toCamelCase(attribute.key) %>: <%- getType(attribute) %>,
73
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
74
+ val <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute) %><% if (index < collection.attributes.length - 1) { %>,<% } %>
66
75
  <% } -%>
67
76
  )`;
68
77
  }
@@ -35,16 +35,23 @@ class PHP extends LanguageMeta {
35
35
  default:
36
36
  throw new Error(`Unknown attribute type: ${attribute.type}`);
37
37
  }
38
- if (!attribute.required) {
38
+ if (!attribute.required && attribute.default === null) {
39
39
  type += "|null";
40
40
  }
41
41
  return type;
42
42
  }
43
43
 
44
+ getCurrentDirectory() {
45
+ return process.cwd();
46
+ }
47
+
44
48
  getTemplate() {
45
49
  return `<?php
46
50
  namespace Appwrite\\Models;
47
51
 
52
+ // This file is auto-generated by the Appwrite CLI.
53
+ // You can regenerate it by running \`appwrite types -l php ${this.getCurrentDirectory()}\`.
54
+
48
55
  <% for (const attribute of collection.attributes) { -%>
49
56
  <% if (attribute.type === 'relationship' && !(attribute.relationType === 'manyToMany') && !(attribute.relationType === 'oneToMany' && attribute.side === 'parent')) { -%>
50
57
  use Appwrite\\Models\\<%- toPascalCase(attribute.relatedCollection) %>;
@@ -55,7 +62,7 @@ use Appwrite\\Models\\<%- toPascalCase(attribute.relatedCollection) %>;
55
62
  <% if (attribute.format === 'enum') { -%>
56
63
  enum <%- toPascalCase(attribute.key) %>: string {
57
64
  <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
58
- case <%- toUpperSnakeCase(element) %> = '<%- element %>';
65
+ case <%- strict ? toUpperSnakeCase(element) : element %> = '<%- element %>';
59
66
  <% } -%>
60
67
  }
61
68
 
@@ -63,31 +70,33 @@ enum <%- toPascalCase(attribute.key) %>: string {
63
70
  <% } -%>
64
71
  class <%- toPascalCase(collection.name) %> {
65
72
  <% for (const attribute of collection.attributes ){ -%>
66
- private <%- getType(attribute) %> $<%- toCamelCase(attribute.key) %>;
73
+ private <%- getType(attribute) %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %>;
67
74
  <% } -%>
68
75
 
69
76
  public function __construct(
70
77
  <% for (const attribute of collection.attributes ){ -%>
71
78
  <% if (attribute.required) { -%>
72
- <%- getType(attribute).replace('|null', '') %> $<%- toCamelCase(attribute.key) %><% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
79
+ <%- getType(attribute).replace('|null', '') %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %><% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
73
80
  <% } else { -%>
74
- ?<%- getType(attribute).replace('|null', '') %> $<%- toCamelCase(attribute.key) %> = null<% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
81
+ ?<%- getType(attribute).replace('|null', '') %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %> = null<% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
75
82
  <% } -%>
76
83
  <% } -%>
77
84
  ) {
78
85
  <% for (const attribute of collection.attributes ){ -%>
79
- $this-><%- toCamelCase(attribute.key) %> = $<%- toCamelCase(attribute.key) %>;
86
+ $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %> = $<%- strict ? toCamelCase(attribute.key) : attribute.key %>;
80
87
  <% } -%>
81
88
  }
82
89
 
83
- <% for (const attribute of collection.attributes ){ -%>
90
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
84
91
  public function get<%- toPascalCase(attribute.key) %>(): <%- getType(attribute) %> {
85
- return $this-><%- toCamelCase(attribute.key) %>;
92
+ return $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %>;
86
93
  }
87
94
 
88
- public function set<%- toPascalCase(attribute.key) %>(<%- getType(attribute) %> $<%- toCamelCase(attribute.key) %>): void {
89
- $this-><%- toCamelCase(attribute.key) %> = $<%- toCamelCase(attribute.key) %>;
95
+ public function set<%- toPascalCase(attribute.key) %>(<%- getType(attribute) %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %>): void {
96
+ $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %> = $<%- strict ? toCamelCase(attribute.key) : attribute.key %>;
90
97
  }
98
+ <% if (index < collection.attributes.length - 1) { %>
99
+ <% } -%>
91
100
  <% } -%>
92
101
  }`;
93
102
  }
@@ -35,20 +35,27 @@ class Swift extends LanguageMeta {
35
35
  if (attribute.array) {
36
36
  type = "[" + type + "]";
37
37
  }
38
- if (!attribute.required) {
38
+ if (!attribute.required && attribute.default === null) {
39
39
  type += "?";
40
40
  }
41
41
  return type;
42
42
  }
43
43
 
44
+ getCurrentDirectory() {
45
+ return process.cwd();
46
+ }
47
+
44
48
  getTemplate() {
45
49
  return `import Foundation
46
50
 
51
+ /// This file is auto-generated by the Appwrite CLI.
52
+ /// You can regenerate it by running \`appwrite types -l swift ${this.getCurrentDirectory()}\`.
53
+
47
54
  <% for (const attribute of collection.attributes) { -%>
48
55
  <% if (attribute.format === 'enum') { -%>
49
56
  public enum <%- toPascalCase(attribute.key) %>: String, Codable, CaseIterable {
50
57
  <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
51
- case <%- toSnakeCase(element) %> = "<%- element %>"
58
+ case <%- strict ? toCamelCase(element) : element %> = "<%- element %>"
52
59
  <% } -%>
53
60
  }
54
61
 
@@ -56,101 +63,101 @@ public enum <%- toPascalCase(attribute.key) %>: String, Codable, CaseIterable {
56
63
  <% } -%>
57
64
  public class <%- toPascalCase(collection.name) %>: Codable {
58
65
  <% for (const attribute of collection.attributes) { -%>
59
- public let <%- toCamelCase(attribute.key) %>: <%- getType(attribute) %>
66
+ public let <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute) %>
60
67
  <% } %>
61
- enum CodingKeys: String, CodingKey {
68
+ enum CodingKeys: String, CodingKey {
62
69
  <% for (const attribute of collection.attributes) { -%>
63
- case <%- toCamelCase(attribute.key) %> = "<%- attribute.key %>"
70
+ case <%- strict ? toCamelCase(attribute.key) : attribute.key %> = "<%- attribute.key %>"
64
71
  <% } -%>
65
- }
72
+ }
66
73
 
67
- init(
68
- <% for (const attribute of collection.attributes) { -%>
69
- <%- toCamelCase(attribute.key) %>: <%- getType(attribute) %><% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
74
+ init(
75
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
76
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute) %><% if (index < collection.attributes.length - 1) { %>,<% } %>
70
77
  <% } -%>
71
- ) {
78
+ ) {
72
79
  <% for (const attribute of collection.attributes) { -%>
73
- self.<%- toCamelCase(attribute.key) %> = <%- toCamelCase(attribute.key) %>
80
+ self.<%- strict ? toCamelCase(attribute.key) : attribute.key %> = <%- strict ? toCamelCase(attribute.key) : attribute.key %>
74
81
  <% } -%>
75
- }
82
+ }
76
83
 
77
- public required init(from decoder: Decoder) throws {
78
- let container = try decoder.container(keyedBy: CodingKeys.self)
84
+ public required init(from decoder: Decoder) throws {
85
+ let container = try decoder.container(keyedBy: CodingKeys.self)
79
86
 
80
87
  <% for (const attribute of collection.attributes) { -%>
81
88
  <% if (attribute.required) { -%>
82
- self.<%- toCamelCase(attribute.key) %> = try container.decode(<%- getType(attribute).replace('?', '') %>.self, forKey: .<%- toCamelCase(attribute.key) %>)
89
+ self.<%- strict ? toCamelCase(attribute.key) : attribute.key %> = try container.decode(<%- getType(attribute).replace('?', '') %>.self, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
83
90
  <% } else { -%>
84
- self.<%- toCamelCase(attribute.key) %> = try container.decodeIfPresent(<%- getType(attribute).replace('?', '') %>.self, forKey: .<%- toCamelCase(attribute.key) %>)
91
+ self.<%- strict ? toCamelCase(attribute.key) : attribute.key %> = try container.decodeIfPresent(<%- getType(attribute).replace('?', '') %>.self, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
85
92
  <% } -%>
86
93
  <% } -%>
87
- }
94
+ }
88
95
 
89
- public func encode(to encoder: Encoder) throws {
90
- var container = encoder.container(keyedBy: CodingKeys.self)
96
+ public func encode(to encoder: Encoder) throws {
97
+ var container = encoder.container(keyedBy: CodingKeys.self)
91
98
 
92
99
  <% for (const attribute of collection.attributes) { -%>
93
100
  <% if (attribute.required) { -%>
94
- try container.encode(<%- toCamelCase(attribute.key) %>, forKey: .<%- toCamelCase(attribute.key) %>)
101
+ try container.encode(<%- strict ? toCamelCase(attribute.key) : attribute.key %>, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
95
102
  <% } else { -%>
96
- try container.encodeIfPresent(<%- toCamelCase(attribute.key) %>, forKey: .<%- toCamelCase(attribute.key) %>)
103
+ try container.encodeIfPresent(<%- strict ? toCamelCase(attribute.key) : attribute.key %>, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
97
104
  <% } -%>
98
105
  <% } -%>
99
- }
106
+ }
100
107
 
101
- public func toMap() -> [String: Any] {
102
- return [
103
- <% for (const attribute of collection.attributes) { -%>
108
+ public func toMap() -> [String: Any] {
109
+ return [
110
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
104
111
  <% if (attribute.type === 'relationship') { -%>
105
- "<%- attribute.key %>": <%- toCamelCase(attribute.key) %> as Any<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
112
+ "<%- attribute.key %>": <%- strict ? toCamelCase(attribute.key) : attribute.key %> as Any<% if (index < collection.attributes.length - 1) { %>,<% } %>
106
113
  <% } else if (attribute.array && attribute.type !== 'string' && attribute.type !== 'integer' && attribute.type !== 'float' && attribute.type !== 'boolean') { -%>
107
- "<%- attribute.key %>": <%- toCamelCase(attribute.key) %>?.map { $0.toMap() } as Any<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
114
+ "<%- attribute.key %>": <%- strict ? toCamelCase(attribute.key) : attribute.key %>?.map { $0.toMap() } as Any<% if (index < collection.attributes.length - 1) { %>,<% } %>
108
115
  <% } else { -%>
109
- "<%- attribute.key %>": <%- toCamelCase(attribute.key) %> as Any<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
116
+ "<%- attribute.key %>": <%- strict ? toCamelCase(attribute.key) : attribute.key %> as Any<% if (index < collection.attributes.length - 1) { %>,<% } %>
110
117
  <% } -%>
111
118
  <% } -%>
112
- ]
113
- }
119
+ ]
120
+ }
114
121
 
115
- public static func from(map: [String: Any]) -> <%- toPascalCase(collection.name) %> {
116
- return <%- toPascalCase(collection.name) %>(
117
- <% for (const attribute of collection.attributes) { -%>
122
+ public static func from(map: [String: Any]) -> <%- toPascalCase(collection.name) %> {
123
+ return <%- toPascalCase(collection.name) %>(
124
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
118
125
  <% if (attribute.type === 'relationship') { -%>
119
126
  <% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
120
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [<%- toPascalCase(attribute.relatedCollection) %>]<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
127
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [<%- toPascalCase(attribute.relatedCollection) %>]<% if (index < collection.attributes.length - 1) { %>,<% } %>
121
128
  <% } else { -%>
122
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> <%- toPascalCase(attribute.relatedCollection) %><% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
129
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> <%- toPascalCase(attribute.relatedCollection) %><% if (index < collection.attributes.length - 1) { %>,<% } %>
123
130
  <% } -%>
124
131
  <% } else if (attribute.array) { -%>
125
132
  <% if (attribute.type === 'string') { -%>
126
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [String]<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
133
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [String]<% if (index < collection.attributes.length - 1) { %>,<% } %>
127
134
  <% } else if (attribute.type === 'integer') { -%>
128
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Int]<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
135
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Int]<% if (index < collection.attributes.length - 1) { %>,<% } %>
129
136
  <% } else if (attribute.type === 'float') { -%>
130
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Double]<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
137
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Double]<% if (index < collection.attributes.length - 1) { %>,<% } %>
131
138
  <% } else if (attribute.type === 'boolean') { -%>
132
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Bool]<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
139
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Bool]<% if (index < collection.attributes.length - 1) { %>,<% } %>
133
140
  <% } else { -%>
134
- <%- toCamelCase(attribute.key) %>: (map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [[String: Any]])<% if (!attribute.required) { %>?<% } %>.map { <%- toPascalCase(attribute.type) %>.from(map: $0) }<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
141
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: (map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [[String: Any]])<% if (!attribute.required) { %>?<% } %>.map { <%- toPascalCase(attribute.type) %>.from(map: $0) }<% if (index < collection.attributes.length - 1) { %>,<% } %>
135
142
  <% } -%>
136
143
  <% } else { -%>
137
144
  <% if ((attribute.type === 'string' || attribute.type === 'email' || attribute.type === 'datetime') && attribute.format !== 'enum') { -%>
138
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> String<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
145
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> String<% if (index < collection.attributes.length - 1) { %>,<% } %>
139
146
  <% } else if (attribute.type === 'string' && attribute.format === 'enum') { -%>
140
- <%- toCamelCase(attribute.key) %>: <%- toPascalCase(attribute.key) %>(rawValue: map["<%- attribute.key %>"] as! String)!<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
147
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- toPascalCase(attribute.key) %>(rawValue: map["<%- attribute.key %>"] as! String)!<% if (index < collection.attributes.length - 1) { %>,<% } %>
141
148
  <% } else if (attribute.type === 'integer') { -%>
142
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Int<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
149
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Int<% if (index < collection.attributes.length - 1) { %>,<% } %>
143
150
  <% } else if (attribute.type === 'float') { -%>
144
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Double<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
151
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Double<% if (index < collection.attributes.length - 1) { %>,<% } %>
145
152
  <% } else if (attribute.type === 'boolean') { -%>
146
- <%- toCamelCase(attribute.key) %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Bool<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
153
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Bool<% if (index < collection.attributes.length - 1) { %>,<% } %>
147
154
  <% } else { -%>
148
- <%- toCamelCase(attribute.key) %>: <%- toPascalCase(attribute.type) %>.from(map: map["<%- attribute.key %>"] as! [String: Any])<% if (attribute !== collection.attributes[collection.attributes.length - 1]) { %>,<% } %>
155
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- toPascalCase(attribute.type) %>.from(map: map["<%- attribute.key %>"] as! [String: Any])<% if (index < collection.attributes.length - 1) { %>,<% } %>
149
156
  <% } -%>
150
157
  <% } -%>
151
158
  <% } -%>
152
- )
153
- }
159
+ )
160
+ }
154
161
  }`;
155
162
  }
156
163
 
@@ -40,7 +40,7 @@ class TypeScript extends LanguageMeta {
40
40
  if (attribute.array) {
41
41
  type += "[]";
42
42
  }
43
- if (!attribute.required) {
43
+ if (!attribute.required && attribute.default === null) {
44
44
  type += " | null";
45
45
  }
46
46
  return type;
@@ -64,15 +64,23 @@ class TypeScript extends LanguageMeta {
64
64
  return "appwrite";
65
65
  }
66
66
 
67
+ getCurrentDirectory() {
68
+ return process.cwd();
69
+ }
70
+
67
71
  getTemplate() {
68
- return `import { Models } from '${this._getAppwriteDependency()}';
72
+ return `import { type Models } from '${this._getAppwriteDependency()}';
73
+
74
+ // This file is auto-generated by the Appwrite CLI.
75
+ // You can regenerate it by running \`appwrite types -l ts ${this.getCurrentDirectory()}\`.
69
76
 
70
77
  <% for (const collection of collections) { -%>
71
78
  <% for (const attribute of collection.attributes) { -%>
72
79
  <% if (attribute.format === 'enum') { -%>
73
80
  export enum <%- toPascalCase(attribute.key) %> {
74
- <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
75
- <%- toUpperSnakeCase(element) %> = "<%- element %>",
81
+ <% const entries = Object.entries(attribute.elements); -%>
82
+ <% for (let i = 0; i < entries.length; i++) { -%>
83
+ <%- toUpperSnakeCase(entries[i][1]) %> = "<%- entries[i][1] %>"<% if (i !== entries.length - 1) { %>,<% } %>
76
84
  <% } -%>
77
85
  }
78
86
 
@@ -82,7 +90,7 @@ export enum <%- toPascalCase(attribute.key) %> {
82
90
  <% for (const collection of collections) { -%>
83
91
  export type <%- toPascalCase(collection.name) %> = Models.Document & {
84
92
  <% for (const attribute of collection.attributes) { -%>
85
- <%- toCamelCase(attribute.key) %>: <%- getType(attribute) %>;
93
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute) %>;
86
94
  <% } -%>
87
95
  }
88
96
 
package/lib/utils.js CHANGED
@@ -2,8 +2,8 @@ const fs = require("fs");
2
2
  const path = require("path");
3
3
  const net = require("net");
4
4
  const childProcess = require('child_process');
5
+ const chalk = require('chalk');
5
6
  const { localConfig, globalConfig } = require("./config");
6
- const { success } = require('./parser')
7
7
 
8
8
  function getAllFiles(folder) {
9
9
  const files = [];
@@ -105,8 +105,7 @@ function showConsoleLink(serviceName, action, ...ids) {
105
105
  return;
106
106
  }
107
107
 
108
-
109
- success(url);
108
+ console.log(`${chalk.green.bold("✓ Success:")} ${chalk.green(url)}`);
110
109
  }
111
110
 
112
111
  function getAccountPath(action) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "appwrite-cli",
3
3
  "homepage": "https://appwrite.io/support",
4
4
  "description": "Appwrite is an open-source self-hosted backend server that abstract and simplify complex and repetitive development tasks behind a very simple REST API",
5
- "version": "8.1.0",
5
+ "version": "8.2.0",
6
6
  "license": "BSD-3-Clause",
7
7
  "main": "index.js",
8
8
  "bin": {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "$schema": "https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json",
3
- "version": "8.1.0",
3
+ "version": "8.2.0",
4
4
  "description": "The Appwrite CLI is a command-line application that allows you to interact with Appwrite and perform server-side tasks using your terminal.",
5
5
  "homepage": "https://github.com/appwrite/sdk-for-cli",
6
6
  "license": "BSD-3-Clause",
7
7
  "architecture": {
8
8
  "64bit": {
9
- "url": "https://github.com/appwrite/sdk-for-cli/releases/download/8.1.0/appwrite-cli-win-x64.exe",
9
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/8.2.0/appwrite-cli-win-x64.exe",
10
10
  "bin": [
11
11
  [
12
12
  "appwrite-cli-win-x64.exe",
@@ -15,7 +15,7 @@
15
15
  ]
16
16
  },
17
17
  "arm64": {
18
- "url": "https://github.com/appwrite/sdk-for-cli/releases/download/8.1.0/appwrite-cli-win-arm64.exe",
18
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/8.2.0/appwrite-cli-win-arm64.exe",
19
19
  "bin": [
20
20
  [
21
21
  "appwrite-cli-win-arm64.exe",