appwrite-cli 8.2.1 → 8.3.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,29 @@
1
1
  # Change Log
2
2
 
3
+ ## 8.3.0
4
+
5
+ * **Feat:** Add support for `appwrite.config.json` file
6
+ * All new projects will be initialized with this configuration file
7
+ * Resolves bundler conflicts (e.g., Vite) that incorrectly interpret `.json` files as library imports
8
+ * Add `incrementDocumentAttribute` and `decrementDocumentAttribute` support to `Databases` service
9
+ * Type generation fixes:
10
+ * Fix relationships using the relatedCollection's id instead of name
11
+ * Update auto generated comment to show relative path instead of absolute path
12
+
13
+ > **Note:** The existing `appwrite.json` file remains fully supported for backward compatibility
14
+
15
+ ## 8.2.2
16
+
17
+ * Fix object comparison logic when pushing settings
18
+ * Type generation fixes:
19
+ * Dart: Fixed import casing to snake_case, removed `extends Document` and hardcoded attributes, removed unnecessary imports
20
+ * Java: Fixed indentation to 4 spaces, updated imports to `java.util.Objects`, fixed enum casing in strict mode as per [Oracle official docs](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)
21
+ * Javascript: Updated optional values formatting from `|null` to `| null`
22
+ * Kotlin: Fixed indentation to 4 spaces per [Kotlinlang official docs](https://kotlinlang.org/docs/coding-conventions.html#indentation)
23
+ * PHP: Fixed indentation to 4 spaces per [PHP Fig official docs](https://www.php-fig.org/psr/psr-2/)
24
+ * Swift: Fixed indentation to 4 spaces, improved `decodeIfPresent` usage for optionals, added missing `public` to `init` method
25
+ * Typescript: Fixed indentation to 4 spaces per [Typescript coding guidelines](https://github.com/microsoft/TypeScript/wiki/Coding-guidelines)
26
+
3
27
  ## 8.2.1
4
28
 
5
29
  * Added `--with-variables` option to the Sites command for adding/updating environment variables
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.2.1
32
+ 8.3.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.2.1
63
+ 8.3.0
64
64
  ```
65
65
 
66
66
  ## Getting Started
@@ -0,0 +1,7 @@
1
+ appwrite databases decrementDocumentAttribute \
2
+ --databaseId <DATABASE_ID> \
3
+ --collectionId <COLLECTION_ID> \
4
+ --documentId <DOCUMENT_ID> \
5
+ --attribute '' \
6
+
7
+
@@ -0,0 +1,7 @@
1
+ appwrite databases incrementDocumentAttribute \
2
+ --databaseId <DATABASE_ID> \
3
+ --collectionId <COLLECTION_ID> \
4
+ --documentId <DOCUMENT_ID> \
5
+ --attribute '' \
6
+
7
+
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.2.1/appwrite-cli-win-x64.exe"
17
- $GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.2.1/appwrite-cli-win-arm64.exe"
16
+ $GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.3.0/appwrite-cli-win-x64.exe"
17
+ $GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.3.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.2.1"
100
+ GITHUB_LATEST_VERSION="8.3.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.2.1',
20
- 'user-agent' : `AppwriteCLI/8.2.1 (${os.type()} ${os.version()}; ${os.arch()})`,
19
+ 'x-sdk-version': '8.3.0',
20
+ 'user-agent' : `AppwriteCLI/8.3.0 (${os.type()} ${os.version()}; ${os.arch()})`,
21
21
  'X-Appwrite-Response-Format' : '1.7.0',
22
22
  };
23
23
  }
@@ -1990,6 +1990,90 @@ const databasesListDocumentLogs = async ({databaseId,collectionId,documentId,que
1990
1990
 
1991
1991
  }
1992
1992
 
1993
+ /**
1994
+ * @typedef {Object} DatabasesDecrementDocumentAttributeRequestParams
1995
+ * @property {string} databaseId Database ID.
1996
+ * @property {string} collectionId Collection ID.
1997
+ * @property {string} documentId Document ID.
1998
+ * @property {string} attribute Attribute key.
1999
+ * @property {number} value Value to decrement the attribute by. The value must be a number.
2000
+ * @property {number} min Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.
2001
+ * @property {boolean} overrideForCli
2002
+ * @property {boolean} parseOutput
2003
+ * @property {libClient | undefined} sdk
2004
+ */
2005
+
2006
+ /**
2007
+ * @param {DatabasesDecrementDocumentAttributeRequestParams} params
2008
+ */
2009
+ const databasesDecrementDocumentAttribute = async ({databaseId,collectionId,documentId,attribute,value,min,parseOutput = true, overrideForCli = false, sdk = undefined}) => {
2010
+ let client = !sdk ? await sdkForProject() :
2011
+ sdk;
2012
+ let apiPath = '/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/decrement'.replace('{databaseId}', databaseId).replace('{collectionId}', collectionId).replace('{documentId}', documentId).replace('{attribute}', attribute);
2013
+ let payload = {};
2014
+ if (typeof value !== 'undefined') {
2015
+ payload['value'] = value;
2016
+ }
2017
+ if (typeof min !== 'undefined') {
2018
+ payload['min'] = min;
2019
+ }
2020
+
2021
+ let response = undefined;
2022
+
2023
+ response = await client.call('patch', apiPath, {
2024
+ 'content-type': 'application/json',
2025
+ }, payload);
2026
+
2027
+ if (parseOutput) {
2028
+ parse(response)
2029
+ }
2030
+
2031
+ return response;
2032
+
2033
+ }
2034
+
2035
+ /**
2036
+ * @typedef {Object} DatabasesIncrementDocumentAttributeRequestParams
2037
+ * @property {string} databaseId Database ID.
2038
+ * @property {string} collectionId Collection ID.
2039
+ * @property {string} documentId Document ID.
2040
+ * @property {string} attribute Attribute key.
2041
+ * @property {number} value Value to increment the attribute by. The value must be a number.
2042
+ * @property {number} max Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.
2043
+ * @property {boolean} overrideForCli
2044
+ * @property {boolean} parseOutput
2045
+ * @property {libClient | undefined} sdk
2046
+ */
2047
+
2048
+ /**
2049
+ * @param {DatabasesIncrementDocumentAttributeRequestParams} params
2050
+ */
2051
+ const databasesIncrementDocumentAttribute = async ({databaseId,collectionId,documentId,attribute,value,max,parseOutput = true, overrideForCli = false, sdk = undefined}) => {
2052
+ let client = !sdk ? await sdkForProject() :
2053
+ sdk;
2054
+ let apiPath = '/databases/{databaseId}/collections/{collectionId}/documents/{documentId}/{attribute}/increment'.replace('{databaseId}', databaseId).replace('{collectionId}', collectionId).replace('{documentId}', documentId).replace('{attribute}', attribute);
2055
+ let payload = {};
2056
+ if (typeof value !== 'undefined') {
2057
+ payload['value'] = value;
2058
+ }
2059
+ if (typeof max !== 'undefined') {
2060
+ payload['max'] = max;
2061
+ }
2062
+
2063
+ let response = undefined;
2064
+
2065
+ response = await client.call('patch', apiPath, {
2066
+ 'content-type': 'application/json',
2067
+ }, payload);
2068
+
2069
+ if (parseOutput) {
2070
+ parse(response)
2071
+ }
2072
+
2073
+ return response;
2074
+
2075
+ }
2076
+
1993
2077
  /**
1994
2078
  * @typedef {Object} DatabasesListIndexesRequestParams
1995
2079
  * @property {string} databaseId Database ID.
@@ -2668,7 +2752,7 @@ databases
2668
2752
 
2669
2753
  databases
2670
2754
  .command(`upsert-documents`)
2671
- .description(`**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions. Create or update Documents. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console.`)
2755
+ .description(`**WARNING: Experimental Feature** - This endpoint is experimental and not yet officially supported. It may be subject to breaking changes or removal in future versions. Create or update Documents. Before using this route, you should create a new collection resource using either a [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection) API or directly from your database console. `)
2672
2756
  .requiredOption(`--database-id <database-id>`, `Database ID.`)
2673
2757
  .requiredOption(`--collection-id <collection-id>`, `Collection ID.`)
2674
2758
  .requiredOption(`--documents [documents...]`, `Array of document data as JSON objects. May contain partial documents.`)
@@ -2738,6 +2822,28 @@ databases
2738
2822
  .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset`)
2739
2823
  .action(actionRunner(databasesListDocumentLogs))
2740
2824
 
2825
+ databases
2826
+ .command(`decrement-document-attribute`)
2827
+ .description(`Decrement a specific attribute of a document by a given value.`)
2828
+ .requiredOption(`--database-id <database-id>`, `Database ID.`)
2829
+ .requiredOption(`--collection-id <collection-id>`, `Collection ID.`)
2830
+ .requiredOption(`--document-id <document-id>`, `Document ID.`)
2831
+ .requiredOption(`--attribute <attribute>`, `Attribute key.`)
2832
+ .option(`--value <value>`, `Value to decrement the attribute by. The value must be a number.`, parseInteger)
2833
+ .option(`--min <min>`, `Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.`, parseInteger)
2834
+ .action(actionRunner(databasesDecrementDocumentAttribute))
2835
+
2836
+ databases
2837
+ .command(`increment-document-attribute`)
2838
+ .description(`Increment a specific attribute of a document by a given value.`)
2839
+ .requiredOption(`--database-id <database-id>`, `Database ID.`)
2840
+ .requiredOption(`--collection-id <collection-id>`, `Collection ID.`)
2841
+ .requiredOption(`--document-id <document-id>`, `Document ID.`)
2842
+ .requiredOption(`--attribute <attribute>`, `Attribute key.`)
2843
+ .option(`--value <value>`, `Value to increment the attribute by. The value must be a number.`, parseInteger)
2844
+ .option(`--max <max>`, `Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.`, parseInteger)
2845
+ .action(actionRunner(databasesIncrementDocumentAttribute))
2846
+
2741
2847
  databases
2742
2848
  .command(`list-indexes`)
2743
2849
  .description(`List indexes in the collection.`)
@@ -2853,6 +2959,8 @@ module.exports = {
2853
2959
  databasesUpdateDocument,
2854
2960
  databasesDeleteDocument,
2855
2961
  databasesListDocumentLogs,
2962
+ databasesDecrementDocumentAttribute,
2963
+ databasesIncrementDocumentAttribute,
2856
2964
  databasesListIndexes,
2857
2965
  databasesCreateIndex,
2858
2966
  databasesGetIndex,
@@ -417,8 +417,17 @@ const getObjectChanges = (remote, local, index, what) => {
417
417
 
418
418
  if (remote[index] && local[index]) {
419
419
  for (let [service, status] of Object.entries(remote[index])) {
420
- if (status !== local[index][service]) {
421
- changes.push({ group: what, setting: service, remote: chalk.red(status), local: chalk.green(local[index][service]) })
420
+ const localValue = local[index][service];
421
+ let valuesEqual = false;
422
+
423
+ if (Array.isArray(status) && Array.isArray(localValue)) {
424
+ valuesEqual = JSON.stringify(status) === JSON.stringify(localValue);
425
+ } else {
426
+ valuesEqual = status === localValue;
427
+ }
428
+
429
+ if (!valuesEqual) {
430
+ changes.push({ group: what, setting: service, remote: chalk.red(status), local: chalk.green(localValue) })
422
431
  }
423
432
  }
424
433
  }
@@ -4,7 +4,7 @@ const path = require("path");
4
4
  const { LanguageMeta, detectLanguage } = require("../type-generation/languages/language");
5
5
  const { Command, Option, Argument } = require("commander");
6
6
  const { localConfig } = require("../config");
7
- const { success, log, actionRunner } = require("../parser");
7
+ const { success, log, warn, actionRunner } = require("../parser");
8
8
  const { PHP } = require("../type-generation/languages/php");
9
9
  const { TypeScript } = require("../type-generation/languages/typescript");
10
10
  const { Kotlin } = require("../type-generation/languages/kotlin");
@@ -71,7 +71,7 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict})
71
71
  }
72
72
 
73
73
  if (strict) {
74
- log(`Strict mode enabled: Field names will be converted to follow ${language} conventions`);
74
+ warn(`Strict mode enabled: Field names will be converted to follow ${language} conventions`);
75
75
  }
76
76
 
77
77
  const meta = createLanguageMeta(language);
@@ -97,13 +97,10 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict})
97
97
  fs.mkdirSync(outputDirectory, { recursive: true });
98
98
  }
99
99
 
100
- if (!fs.existsSync("appwrite.json")) {
101
- throw new Error("appwrite.json not found in current directory");
102
- }
103
-
104
100
  const collections = localConfig.getCollections();
105
101
  if (collections.length === 0) {
106
- throw new Error("No collections found in appwrite.json");
102
+ const configFileName = path.basename(localConfig.path);
103
+ throw new Error(`No collections found in configuration. Make sure ${configFileName} exists and contains collections.`);
107
104
  }
108
105
 
109
106
  log(`Found ${collections.length} collections: ${collections.map(c => c.name).join(", ")}`);
@@ -118,7 +115,7 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict})
118
115
  collections,
119
116
  strict,
120
117
  ...templateHelpers,
121
- getType: meta.getType
118
+ getType: meta.getType,
122
119
  });
123
120
 
124
121
  const destination = singleFileDestination || path.join(outputDirectory, meta.getFileName());
@@ -128,10 +125,11 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict})
128
125
  } else {
129
126
  for (const collection of collections) {
130
127
  const content = templater({
128
+ collections,
131
129
  collection,
132
130
  strict,
133
131
  ...templateHelpers,
134
- getType: meta.getType
132
+ getType: meta.getType,
135
133
  });
136
134
 
137
135
  const destination = path.join(outputDirectory, meta.getFileName(collection));
@@ -1361,7 +1361,7 @@ const usersUpdateStatus = async ({userId,status,parseOutput = true, overrideForC
1361
1361
  /**
1362
1362
  * @typedef {Object} UsersListTargetsRequestParams
1363
1363
  * @property {string} userId User ID.
1364
- * @property {string[]} queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, email, phone, status, passwordUpdate, registration, emailVerification, phoneVerification, labels
1364
+ * @property {string[]} queries Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, providerId, identifier, providerType
1365
1365
  * @property {boolean} overrideForCli
1366
1366
  * @property {boolean} parseOutput
1367
1367
  * @property {libClient | undefined} sdk
@@ -1927,7 +1927,7 @@ users
1927
1927
  .command(`list-targets`)
1928
1928
  .description(`List the messaging targets that are associated with a user.`)
1929
1929
  .requiredOption(`--user-id <user-id>`, `User ID.`)
1930
- .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, email, phone, status, passwordUpdate, registration, emailVerification, phoneVerification, labels`)
1930
+ .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, providerId, identifier, providerType`)
1931
1931
  .action(actionRunner(usersListTargets))
1932
1932
 
1933
1933
  users
@@ -435,7 +435,7 @@ vcs
435
435
 
436
436
  vcs
437
437
  .command(`get-repository-contents`)
438
- .description(`Get a list of files and directories from a GitHub repository connected to your project. This endpoint returns the contents of a specified repository path, including file names, sizes, and whether each item is a file or directory. The GitHub installation must be properly configured and the repository must be accessible through your installation for this endpoint to work. `)
438
+ .description(`Get a list of files and directories from a GitHub repository connected to your project. This endpoint returns the contents of a specified repository path, including file names, sizes, and whether each item is a file or directory. The GitHub installation must be properly configured and the repository must be accessible through your installation for this endpoint to work.`)
439
439
  .requiredOption(`--installation-id <installation-id>`, `Installation Id`)
440
440
  .requiredOption(`--provider-repository-id <provider-repository-id>`, `Repository Id`)
441
441
  .option(`--provider-root-directory <provider-root-directory>`, `Path to get contents of nested directory`)
package/lib/config.js CHANGED
@@ -125,27 +125,39 @@ class Config {
125
125
  }
126
126
 
127
127
  class Local extends Config {
128
- static CONFIG_FILE_PATH = "appwrite.json";
128
+ static CONFIG_FILE_PATH = "appwrite.config.json";
129
+ static CONFIG_FILE_PATH_LEGACY = "appwrite.json";
129
130
  configDirectoryPath = ""
130
131
 
131
- constructor(path = Local.CONFIG_FILE_PATH) {
132
+ constructor(path = Local.CONFIG_FILE_PATH, legacyPath = Local.CONFIG_FILE_PATH_LEGACY) {
133
+ let absolutePath = Local.findConfigFile(path) || Local.findConfigFile(legacyPath);
134
+
135
+ if (!absolutePath) {
136
+ absolutePath = `${process.cwd()}/${path}`;
137
+ }
138
+
139
+ super(absolutePath);
140
+ this.configDirectoryPath = _path.dirname(absolutePath);
141
+ }
142
+
143
+ static findConfigFile(filename) {
132
144
  let currentPath = process.cwd();
133
- let absolutePath = `${currentPath}/${path}`;
134
145
 
135
146
  while (true) {
136
- if (fs.existsSync(`${currentPath}/${path}`)) {
137
- absolutePath = `${currentPath}/${path}`;
138
- break
139
- } else {
140
- const parentDirectory = _path.dirname(currentPath);
141
- if (parentDirectory === currentPath) { // we hit the top directory
142
- break;
143
- }
144
- currentPath = parentDirectory
147
+ const filePath = `${currentPath}/${filename}`;
148
+
149
+ if (fs.existsSync(filePath)) {
150
+ return filePath;
151
+ }
152
+
153
+ const parentDirectory = _path.dirname(currentPath);
154
+ if (parentDirectory === currentPath) {
155
+ break;
145
156
  }
157
+ currentPath = parentDirectory;
146
158
  }
147
- super(absolutePath);
148
- this.configDirectoryPath =_path.dirname(absolutePath);
159
+
160
+ return null;
149
161
  }
150
162
 
151
163
  getDirname() {
package/lib/parser.js CHANGED
@@ -122,7 +122,7 @@ const parseError = (err) => {
122
122
  } catch {
123
123
  }
124
124
 
125
- const version = '8.2.1';
125
+ const version = '8.3.0';
126
126
  const stepsToReproduce = `Running \`appwrite ${cliConfig.reportData.data.args.join(' ')}\``;
127
127
  const yourEnvironment = `CLI version: ${version}\nOperation System: ${os.type()}\nAppwrite version: ${appwriteVersion}\nIs Cloud: ${isCloud()}`;
128
128
 
@@ -6,7 +6,7 @@ const path = require('path');
6
6
 
7
7
  class Dart extends LanguageMeta {
8
8
  getPackageName() {
9
- const pubspecPath = path.join(this.getCurrentDirectory(), 'pubspec.yaml');
9
+ const pubspecPath = path.join(process.cwd(), 'pubspec.yaml');
10
10
  if (fs.existsSync(pubspecPath)) {
11
11
  const pubspecContent = fs.readFileSync(pubspecPath, 'utf8');
12
12
  const lines = pubspecContent.split('\n');
@@ -40,7 +40,7 @@ class Dart extends LanguageMeta {
40
40
  return 'appwrite';
41
41
  }
42
42
 
43
- getType(attribute) {
43
+ getType(attribute, collections) {
44
44
  let type = "";
45
45
  switch (attribute.type) {
46
46
  case AttributeType.STRING:
@@ -61,7 +61,11 @@ class Dart extends LanguageMeta {
61
61
  type = "bool";
62
62
  break;
63
63
  case AttributeType.RELATIONSHIP:
64
- type = LanguageMeta.toPascalCase(attribute.relatedCollection);
64
+ const relatedCollection = collections.find(c => c.$id === attribute.relatedCollection);
65
+ if (!relatedCollection) {
66
+ throw new Error(`Related collection with ID '${attribute.relatedCollection}' not found.`);
67
+ }
68
+ type = LanguageMeta.toPascalCase(relatedCollection.name);
65
69
  if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
66
70
  type = `List<${type}>`;
67
71
  }
@@ -78,20 +82,15 @@ class Dart extends LanguageMeta {
78
82
  return type;
79
83
  }
80
84
 
81
- getCurrentDirectory() {
82
- return process.cwd();
83
- }
84
-
85
85
  getTemplate() {
86
- return `import 'package:${this.getPackageName()}/models.dart';
87
- <% for (const attribute of collection.attributes) { -%>
86
+ return `<% for (const attribute of collection.attributes) { -%>
88
87
  <% if (attribute.type === 'relationship') { -%>
89
- import '<%- attribute.relatedCollection.toLowerCase() %>.dart';
88
+ import '<%- toSnakeCase(collections.find(c => c.$id === attribute.relatedCollection).name) %>.dart';
90
89
 
91
90
  <% } -%>
92
91
  <% } -%>
93
92
  /// This file is auto-generated by the Appwrite CLI.
94
- /// You can regenerate it by running \`appwrite types -l dart ${this.getCurrentDirectory()}\`.
93
+ /// You can regenerate it by running \`appwrite ${process.argv.slice(2).join(' ')}\`.
95
94
 
96
95
  <% for (const attribute of collection.attributes) { -%>
97
96
  <% if (attribute.format === 'enum') { -%>
@@ -103,19 +102,12 @@ enum <%- toPascalCase(attribute.key) %> {
103
102
 
104
103
  <% } -%>
105
104
  <% } -%>
106
- class <%= toPascalCase(collection.name) %> extends Document {
105
+ class <%= toPascalCase(collection.name) %> {
107
106
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
108
- <%- getType(attribute) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
107
+ <%- getType(attribute, collections) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
109
108
  <% } -%>
110
109
 
111
110
  <%= 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,
119
111
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
120
112
  <% if (attribute.required) { %>required <% } %>this.<%= strict ? toCamelCase(attribute.key) : attribute.key %><% if (index < collection.attributes.length - 1) { %>,<% } %>
121
113
  <% } -%>
@@ -123,13 +115,6 @@ class <%= toPascalCase(collection.name) %> extends Document {
123
115
 
124
116
  factory <%= toPascalCase(collection.name) %>.fromMap(Map<String, dynamic> map) {
125
117
  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,
133
118
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
134
119
  <%= strict ? toCamelCase(attribute.key) : attribute.key %>: <% if (attribute.type === 'string' || attribute.type === 'email' || attribute.type === 'datetime') { -%>
135
120
  <% if (attribute.format === 'enum') { -%>
@@ -167,11 +152,11 @@ map['<%= attribute.key %>']<% if (!attribute.required) { %> ?? null<% } -%>
167
152
  <% } -%>
168
153
  <% } else if (attribute.type === 'relationship') { -%>
169
154
  <% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
170
- (map['<%= attribute.key %>'] as List<dynamic>?)?.map((e) => <%- toPascalCase(attribute.relatedCollection) %>.fromMap(e)).toList()<% if (!attribute.required) { %> ?? []<% } -%>
155
+ (map['<%= attribute.key %>'] as List<dynamic>?)?.map((e) => <%- toPascalCase(collections.find(c => c.$id === attribute.relatedCollection).name) %>.fromMap(e)).toList()<% if (!attribute.required) { %> ?? []<% } -%>
171
156
  <% } else { -%>
172
157
  <% if (!attribute.required) { -%>
173
- map['<%= attribute.key %>'] != null ? <%- toPascalCase(attribute.relatedCollection) %>.fromMap(map['<%= attribute.key %>']) : null<% } else { -%>
174
- <%- toPascalCase(attribute.relatedCollection) %>.fromMap(map['<%= attribute.key %>'])<% } -%>
158
+ map['<%= attribute.key %>'] != null ? <%- toPascalCase(collections.find(c => c.$id === attribute.relatedCollection).name) %>.fromMap(map['<%= attribute.key %>']) : null<% } else { -%>
159
+ <%- toPascalCase(collections.find(c => c.$id === attribute.relatedCollection).name) %>.fromMap(map['<%= attribute.key %>'])<% } -%>
175
160
  <% } -%>
176
161
  <% } -%><% if (index < collection.attributes.length - 1) { %>,<% } %>
177
162
  <% } -%>
@@ -180,12 +165,6 @@ map['<%= attribute.key %>'] != null ? <%- toPascalCase(attribute.relatedCollecti
180
165
 
181
166
  Map<String, dynamic> toMap() {
182
167
  return {
183
- "\\$id": $id,
184
- "\\$collectionId": $collectionId,
185
- "\\$databaseId": $databaseId,
186
- "\\$createdAt": $createdAt,
187
- "\\$updatedAt": $updatedAt,
188
- "\\$permissions": $permissions,
189
168
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
190
169
  "<%= attribute.key %>": <% if (attribute.type === 'relationship') { -%>
191
170
  <% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
@@ -3,7 +3,7 @@ const { AttributeType } = require('../attribute');
3
3
  const { LanguageMeta } = require("./language");
4
4
 
5
5
  class Java extends LanguageMeta {
6
- getType(attribute) {
6
+ getType(attribute, collections) {
7
7
  let type = "";
8
8
  switch (attribute.type) {
9
9
  case AttributeType.STRING:
@@ -24,7 +24,11 @@ class Java extends LanguageMeta {
24
24
  type = "boolean";
25
25
  break;
26
26
  case AttributeType.RELATIONSHIP:
27
- type = LanguageMeta.toPascalCase(attribute.relatedCollection);
27
+ const relatedCollection = collections.find(c => c.$id === attribute.relatedCollection);
28
+ if (!relatedCollection) {
29
+ throw new Error(`Related collection with ID '${attribute.relatedCollection}' not found.`);
30
+ }
31
+ type = LanguageMeta.toPascalCase(relatedCollection.name);
28
32
  if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
29
33
  type = "List<" + type + ">";
30
34
  }
@@ -38,86 +42,82 @@ class Java extends LanguageMeta {
38
42
  return type;
39
43
  }
40
44
 
41
- getCurrentDirectory() {
42
- return process.cwd();
43
- }
44
-
45
45
  getTemplate() {
46
46
  return `package io.appwrite.models;
47
47
 
48
48
  /**
49
49
  * This file is auto-generated by the Appwrite CLI.
50
- * You can regenerate it by running \`appwrite types -l java ${this.getCurrentDirectory()}\`.
50
+ * You can regenerate it by running \`appwrite ${process.argv.slice(2).join(' ')}\`.
51
51
  */
52
52
 
53
- import java.util.*;
53
+ import java.util.Objects;
54
54
  <% for (const attribute of collection.attributes) { -%>
55
55
  <% if (attribute.type === 'relationship') { -%>
56
- import io.appwrite.models.<%- toPascalCase(attribute.relatedCollection) %>;
57
-
56
+ import io.appwrite.models.<%- toPascalCase(collections.find(c => c.$id === attribute.relatedCollection).name) %>;
58
57
  <% } -%>
59
58
  <% } -%>
59
+
60
60
  public class <%- toPascalCase(collection.name) %> {
61
61
  <% for (const attribute of collection.attributes) { -%>
62
62
  <% if (attribute.format === 'enum') { -%>
63
63
 
64
- public enum <%- toPascalCase(attribute.key) %> {
64
+ public enum <%- toPascalCase(attribute.key) %> {
65
65
  <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
66
- <%- strict ? toSnakeCase(element) : element %><%- index < attribute.elements.length - 1 ? ',' : ';' %>
66
+ <%- strict ? toUpperSnakeCase(element) : element %><%- index < attribute.elements.length - 1 ? ',' : ';' %>
67
67
  <% } -%>
68
- }
68
+ }
69
69
 
70
70
  <% } -%>
71
71
  <% } -%>
72
72
  <% for (const attribute of collection.attributes) { -%>
73
- private <%- getType(attribute) %> <%- strict ? toCamelCase(attribute.key) : attribute.key %>;
73
+ private <%- getType(attribute, collections) %> <%- strict ? toCamelCase(attribute.key) : attribute.key %>;
74
74
  <% } -%>
75
75
 
76
- public <%- toPascalCase(collection.name) %>() {
77
- }
76
+ public <%- toPascalCase(collection.name) %>() {
77
+ }
78
78
 
79
- public <%- toPascalCase(collection.name) %>(
79
+ public <%- toPascalCase(collection.name) %>(
80
80
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
81
- <%- getType(attribute) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %><%- index < collection.attributes.length - 1 ? ',' : '' %>
81
+ <%- getType(attribute, collections) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %><%- index < collection.attributes.length - 1 ? ',' : '' %>
82
82
  <% } -%>
83
- ) {
83
+ ) {
84
84
  <% for (const attribute of collection.attributes) { -%>
85
- this.<%= strict ? toCamelCase(attribute.key) : attribute.key %> = <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
85
+ this.<%= strict ? toCamelCase(attribute.key) : attribute.key %> = <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
86
86
  <% } -%>
87
- }
87
+ }
88
88
 
89
89
  <% for (const attribute of collection.attributes) { -%>
90
- public <%- getType(attribute) %> get<%- toPascalCase(attribute.key) %>() {
91
- return <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
92
- }
90
+ public <%- getType(attribute, collections) %> get<%- toPascalCase(attribute.key) %>() {
91
+ return <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
92
+ }
93
93
 
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
- }
94
+ public void set<%- toPascalCase(attribute.key) %>(<%- getType(attribute, collections) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>) {
95
+ this.<%= strict ? toCamelCase(attribute.key) : attribute.key %> = <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
96
+ }
97
97
 
98
98
  <% } -%>
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) { %> &&
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
105
  <% } }); %>;
106
- }
106
+ }
107
107
 
108
- @Override
109
- public int hashCode() {
110
- return Objects.hash(<%= collection.attributes.map(attr => toCamelCase(attr.key)).join(', ') %>);
111
- }
108
+ @Override
109
+ public int hashCode() {
110
+ return Objects.hash(<%= collection.attributes.map(attr => toCamelCase(attr.key)).join(', ') %>);
111
+ }
112
112
 
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 %> +
113
+ @Override
114
+ public String toString() {
115
+ return "<%- toPascalCase(collection.name) %>{" +
116
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
117
+ "<%= strict ? toCamelCase(attribute.key) : attribute.key %>=" + <%= strict ? toCamelCase(attribute.key) : attribute.key %> +<% if (index < collection.attributes.length - 1) { %> ", " +<% } %>
118
118
  <% } -%>
119
- '}';
120
- }
119
+ '}';
120
+ }
121
121
  }
122
122
  `;
123
123
  }
@@ -6,7 +6,7 @@ const { AttributeType } = require('../attribute');
6
6
  const { LanguageMeta } = require("./language");
7
7
 
8
8
  class JavaScript extends LanguageMeta {
9
- getType(attribute) {
9
+ getType(attribute, collections) {
10
10
  let type = ""
11
11
  switch (attribute.type) {
12
12
  case AttributeType.STRING:
@@ -29,7 +29,11 @@ class JavaScript extends LanguageMeta {
29
29
  type = "boolean";
30
30
  break;
31
31
  case AttributeType.RELATIONSHIP:
32
- type = LanguageMeta.toPascalCase(attribute.relatedCollection);
32
+ const relatedCollection = collections.find(c => c.$id === attribute.relatedCollection);
33
+ if (!relatedCollection) {
34
+ throw new Error(`Related collection with ID '${attribute.relatedCollection}' not found.`);
35
+ }
36
+ type = LanguageMeta.toPascalCase(relatedCollection.name);
33
37
  if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
34
38
  type = `${type}[]`;
35
39
  }
@@ -41,7 +45,7 @@ class JavaScript extends LanguageMeta {
41
45
  type += "[]";
42
46
  }
43
47
  if (!attribute.required && attribute.default === null) {
44
- type += "|null";
48
+ type += " | null";
45
49
  }
46
50
  return type;
47
51
  }
@@ -60,19 +64,14 @@ class JavaScript extends LanguageMeta {
60
64
  return "appwrite";
61
65
  }
62
66
 
63
- getCurrentDirectory() {
64
- return process.cwd();
65
- }
66
-
67
67
  getTemplate() {
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
- /**
68
+ return `/**
73
69
  * @typedef {import('${this._getAppwriteDependency()}').Models.Document} Document
74
70
  */
75
71
 
72
+ // This file is auto-generated by the Appwrite CLI.
73
+ // You can regenerate it by running \`appwrite ${process.argv.slice(2).join(' ')}\`.
74
+
76
75
  <% for (const collection of collections) { -%>
77
76
  <% for (const attribute of collection.attributes) { -%>
78
77
  <% if (attribute.format === 'enum') { -%>
@@ -83,14 +82,15 @@ class JavaScript extends LanguageMeta {
83
82
  <% } -%>
84
83
  <% } -%>
85
84
  <% } -%>
86
- <% for (const collection of collections) { %>/**
85
+ <% for (const [index, collection] of Object.entries(collections)) { %>/**
87
86
  * @typedef {Document & {
88
87
  <% for (const attribute of collection.attributes) { -%>
89
- * <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute) %>;
88
+ * <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute, collections) %>;
90
89
  <% } -%>
91
90
  * }} <%- toPascalCase(collection.name) %>
92
91
  */
93
-
92
+ <% if (index < collections.length - 1) { %>
93
+ <% } -%>
94
94
  <% } %>`;
95
95
  }
96
96
 
@@ -3,7 +3,7 @@ const { AttributeType } = require('../attribute');
3
3
  const { LanguageMeta } = require("./language");
4
4
 
5
5
  class Kotlin extends LanguageMeta {
6
- getType(attribute) {
6
+ getType(attribute, collections) {
7
7
  let type = "";
8
8
  switch (attribute.type) {
9
9
  case AttributeType.STRING:
@@ -24,7 +24,11 @@ class Kotlin extends LanguageMeta {
24
24
  type = "Boolean";
25
25
  break;
26
26
  case AttributeType.RELATIONSHIP:
27
- type = LanguageMeta.toPascalCase(attribute.relatedCollection);
27
+ const relatedCollection = collections.find(c => c.$id === attribute.relatedCollection);
28
+ if (!relatedCollection) {
29
+ throw new Error(`Related collection with ID '${attribute.relatedCollection}' not found.`);
30
+ }
31
+ type = LanguageMeta.toPascalCase(relatedCollection.name);
28
32
  if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
29
33
  type = `List<${type}>`;
30
34
  }
@@ -41,29 +45,25 @@ class Kotlin extends LanguageMeta {
41
45
  return type;
42
46
  }
43
47
 
44
- getCurrentDirectory() {
45
- return process.cwd();
46
- }
47
-
48
48
  getTemplate() {
49
49
  return `package io.appwrite.models
50
50
 
51
51
  <% for (const attribute of collection.attributes) { -%>
52
52
  <% if (attribute.type === 'relationship') { -%>
53
- import <%- toPascalCase(attribute.relatedCollection) %>
53
+ import <%- toPascalCase(collections.find(c => c.$id === attribute.relatedCollection).name) %>
54
54
 
55
55
  <% } -%>
56
56
  <% } -%>
57
57
  /**
58
58
  * This file is auto-generated by the Appwrite CLI.
59
- * You can regenerate it by running \`appwrite types -l kotlin ${this.getCurrentDirectory()}\`.
59
+ * You can regenerate it by running \`appwrite ${process.argv.slice(2).join(' ')}\`.
60
60
  */
61
61
 
62
62
  <% for (const attribute of collection.attributes) { -%>
63
63
  <% if (attribute.format === 'enum') { -%>
64
64
  enum class <%- toPascalCase(attribute.key) %> {
65
65
  <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
66
- <%- strict ? toUpperSnakeCase(element) : element %><%- index < attribute.elements.length - 1 ? ',' : '' %>
66
+ <%- strict ? toUpperSnakeCase(element) : element %><%- index < attribute.elements.length - 1 ? ',' : '' %>
67
67
  <% } -%>
68
68
  }
69
69
 
@@ -71,9 +71,10 @@ enum class <%- toPascalCase(attribute.key) %> {
71
71
  <% } -%>
72
72
  data class <%- toPascalCase(collection.name) %>(
73
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) { %>,<% } %>
74
+ val <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute, collections) %><% if (index < collection.attributes.length - 1) { %>,<% } %>
75
75
  <% } -%>
76
- )`;
76
+ )
77
+ `;
77
78
  }
78
79
 
79
80
  getFileName(collection) {
@@ -3,7 +3,7 @@ const { AttributeType } = require('../attribute');
3
3
  const { LanguageMeta } = require("./language");
4
4
 
5
5
  class PHP extends LanguageMeta {
6
- getType(attribute) {
6
+ getType(attribute, collections) {
7
7
  if (attribute.array) {
8
8
  return "array";
9
9
  }
@@ -27,7 +27,11 @@ class PHP extends LanguageMeta {
27
27
  type = "bool";
28
28
  break;
29
29
  case AttributeType.RELATIONSHIP:
30
- type = LanguageMeta.toPascalCase(attribute.relatedCollection);
30
+ const relatedCollection = collections.find(c => c.$id === attribute.relatedCollection);
31
+ if (!relatedCollection) {
32
+ throw new Error(`Related collection with ID '${attribute.relatedCollection}' not found.`);
33
+ }
34
+ type = LanguageMeta.toPascalCase(relatedCollection.name);
31
35
  if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
32
36
  type = "array";
33
37
  }
@@ -41,20 +45,16 @@ class PHP extends LanguageMeta {
41
45
  return type;
42
46
  }
43
47
 
44
- getCurrentDirectory() {
45
- return process.cwd();
46
- }
47
-
48
48
  getTemplate() {
49
49
  return `<?php
50
50
  namespace Appwrite\\Models;
51
51
 
52
52
  // This file is auto-generated by the Appwrite CLI.
53
- // You can regenerate it by running \`appwrite types -l php ${this.getCurrentDirectory()}\`.
53
+ // You can regenerate it by running \`appwrite ${process.argv.slice(2).join(' ')}\`.
54
54
 
55
55
  <% for (const attribute of collection.attributes) { -%>
56
56
  <% if (attribute.type === 'relationship' && !(attribute.relationType === 'manyToMany') && !(attribute.relationType === 'oneToMany' && attribute.side === 'parent')) { -%>
57
- use Appwrite\\Models\\<%- toPascalCase(attribute.relatedCollection) %>;
57
+ use Appwrite\\Models\\<%- toPascalCase(collections.find(c => c.$id === attribute.relatedCollection).name) %>;
58
58
 
59
59
  <% } -%>
60
60
  <% } -%>
@@ -62,7 +62,7 @@ use Appwrite\\Models\\<%- toPascalCase(attribute.relatedCollection) %>;
62
62
  <% if (attribute.format === 'enum') { -%>
63
63
  enum <%- toPascalCase(attribute.key) %>: string {
64
64
  <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
65
- case <%- strict ? toUpperSnakeCase(element) : element %> = '<%- element %>';
65
+ case <%- strict ? toUpperSnakeCase(element) : element %> = '<%- element %>';
66
66
  <% } -%>
67
67
  }
68
68
 
@@ -70,35 +70,36 @@ enum <%- toPascalCase(attribute.key) %>: string {
70
70
  <% } -%>
71
71
  class <%- toPascalCase(collection.name) %> {
72
72
  <% for (const attribute of collection.attributes ){ -%>
73
- private <%- getType(attribute) %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %>;
73
+ private <%- getType(attribute, collections) %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %>;
74
74
  <% } -%>
75
75
 
76
- public function __construct(
76
+ public function __construct(
77
77
  <% for (const attribute of collection.attributes ){ -%>
78
78
  <% if (attribute.required) { -%>
79
- <%- getType(attribute).replace('|null', '') %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %><% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
79
+ <%- getType(attribute, collections).replace('|null', '') %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %><% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
80
80
  <% } else { -%>
81
- ?<%- getType(attribute).replace('|null', '') %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %> = null<% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
81
+ ?<%- getType(attribute, collections).replace('|null', '') %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %> = null<% if (collection.attributes.indexOf(attribute) < collection.attributes.length - 1) { %>,<% } %>
82
82
  <% } -%>
83
83
  <% } -%>
84
- ) {
84
+ ) {
85
85
  <% for (const attribute of collection.attributes ){ -%>
86
- $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %> = $<%- strict ? toCamelCase(attribute.key) : attribute.key %>;
86
+ $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %> = $<%- strict ? toCamelCase(attribute.key) : attribute.key %>;
87
87
  <% } -%>
88
- }
88
+ }
89
89
 
90
90
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
91
- public function get<%- toPascalCase(attribute.key) %>(): <%- getType(attribute) %> {
92
- return $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %>;
93
- }
91
+ public function get<%- toPascalCase(attribute.key) %>(): <%- getType(attribute, collections) %> {
92
+ return $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %>;
93
+ }
94
94
 
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 %>;
97
- }
95
+ public function set<%- toPascalCase(attribute.key) %>(<%- getType(attribute, collections) %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %>): void {
96
+ $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %> = $<%- strict ? toCamelCase(attribute.key) : attribute.key %>;
97
+ }
98
98
  <% if (index < collection.attributes.length - 1) { %>
99
99
  <% } -%>
100
100
  <% } -%>
101
- }`;
101
+ }
102
+ `;
102
103
  }
103
104
 
104
105
  getFileName(collection) {
@@ -3,7 +3,7 @@ const { AttributeType } = require('../attribute');
3
3
  const { LanguageMeta } = require("./language");
4
4
 
5
5
  class Swift extends LanguageMeta {
6
- getType(attribute) {
6
+ getType(attribute, collections) {
7
7
  let type = "";
8
8
  switch (attribute.type) {
9
9
  case AttributeType.STRING:
@@ -24,7 +24,11 @@ class Swift extends LanguageMeta {
24
24
  type = "Bool";
25
25
  break;
26
26
  case AttributeType.RELATIONSHIP:
27
- type = LanguageMeta.toPascalCase(attribute.relatedCollection);
27
+ const relatedCollection = collections.find(c => c.$id === attribute.relatedCollection);
28
+ if (!relatedCollection) {
29
+ throw new Error(`Related collection with ID '${attribute.relatedCollection}' not found.`);
30
+ }
31
+ type = LanguageMeta.toPascalCase(relatedCollection.name);
28
32
  if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
29
33
  type = `[${type}]`;
30
34
  }
@@ -41,21 +45,17 @@ class Swift extends LanguageMeta {
41
45
  return type;
42
46
  }
43
47
 
44
- getCurrentDirectory() {
45
- return process.cwd();
46
- }
47
-
48
48
  getTemplate() {
49
49
  return `import Foundation
50
50
 
51
51
  /// This file is auto-generated by the Appwrite CLI.
52
- /// You can regenerate it by running \`appwrite types -l swift ${this.getCurrentDirectory()}\`.
52
+ /// You can regenerate it by running \`appwrite ${process.argv.slice(2).join(' ')}\`.
53
53
 
54
54
  <% for (const attribute of collection.attributes) { -%>
55
55
  <% if (attribute.format === 'enum') { -%>
56
56
  public enum <%- toPascalCase(attribute.key) %>: String, Codable, CaseIterable {
57
57
  <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
58
- case <%- strict ? toCamelCase(element) : element %> = "<%- element %>"
58
+ case <%- strict ? toCamelCase(element) : element %> = "<%- element %>"
59
59
  <% } -%>
60
60
  }
61
61
 
@@ -63,101 +63,101 @@ public enum <%- toPascalCase(attribute.key) %>: String, Codable, CaseIterable {
63
63
  <% } -%>
64
64
  public class <%- toPascalCase(collection.name) %>: Codable {
65
65
  <% for (const attribute of collection.attributes) { -%>
66
- public let <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute) %>
66
+ public let <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute, collections) %>
67
67
  <% } %>
68
- enum CodingKeys: String, CodingKey {
68
+ enum CodingKeys: String, CodingKey {
69
69
  <% for (const attribute of collection.attributes) { -%>
70
- case <%- strict ? toCamelCase(attribute.key) : attribute.key %> = "<%- attribute.key %>"
70
+ case <%- strict ? toCamelCase(attribute.key) : attribute.key %> = "<%- attribute.key %>"
71
71
  <% } -%>
72
- }
72
+ }
73
73
 
74
- init(
74
+ public init(
75
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) { %>,<% } %>
76
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute, collections) %><% if (index < collection.attributes.length - 1) { %>,<% } %>
77
77
  <% } -%>
78
- ) {
78
+ ) {
79
79
  <% for (const attribute of collection.attributes) { -%>
80
- self.<%- strict ? toCamelCase(attribute.key) : attribute.key %> = <%- strict ? toCamelCase(attribute.key) : attribute.key %>
80
+ self.<%- strict ? toCamelCase(attribute.key) : attribute.key %> = <%- strict ? toCamelCase(attribute.key) : attribute.key %>
81
81
  <% } -%>
82
- }
82
+ }
83
83
 
84
- public required init(from decoder: Decoder) throws {
85
- 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)
86
86
 
87
87
  <% for (const attribute of collection.attributes) { -%>
88
- <% if (attribute.required) { -%>
89
- self.<%- strict ? toCamelCase(attribute.key) : attribute.key %> = try container.decode(<%- getType(attribute).replace('?', '') %>.self, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
88
+ <% if (!(!attribute.required && attribute.default === null)) { -%>
89
+ self.<%- strict ? toCamelCase(attribute.key) : attribute.key %> = try container.decode(<%- getType(attribute, collections).replace('?', '') %>.self, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
90
90
  <% } else { -%>
91
- self.<%- strict ? toCamelCase(attribute.key) : attribute.key %> = try container.decodeIfPresent(<%- getType(attribute).replace('?', '') %>.self, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
91
+ self.<%- strict ? toCamelCase(attribute.key) : attribute.key %> = try container.decodeIfPresent(<%- getType(attribute, collections).replace('?', '') %>.self, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
92
92
  <% } -%>
93
93
  <% } -%>
94
- }
94
+ }
95
95
 
96
- public func encode(to encoder: Encoder) throws {
97
- var container = encoder.container(keyedBy: CodingKeys.self)
96
+ public func encode(to encoder: Encoder) throws {
97
+ var container = encoder.container(keyedBy: CodingKeys.self)
98
98
 
99
99
  <% for (const attribute of collection.attributes) { -%>
100
- <% if (attribute.required) { -%>
101
- try container.encode(<%- strict ? toCamelCase(attribute.key) : attribute.key %>, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
100
+ <% if (!(!attribute.required && attribute.default === null)) { -%>
101
+ try container.encode(<%- strict ? toCamelCase(attribute.key) : attribute.key %>, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
102
102
  <% } else { -%>
103
- try container.encodeIfPresent(<%- strict ? toCamelCase(attribute.key) : attribute.key %>, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
103
+ try container.encodeIfPresent(<%- strict ? toCamelCase(attribute.key) : attribute.key %>, forKey: .<%- strict ? toCamelCase(attribute.key) : attribute.key %>)
104
104
  <% } -%>
105
105
  <% } -%>
106
- }
106
+ }
107
107
 
108
- public func toMap() -> [String: Any] {
109
- return [
108
+ public func toMap() -> [String: Any] {
109
+ return [
110
110
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
111
111
  <% if (attribute.type === 'relationship') { -%>
112
- "<%- attribute.key %>": <%- strict ? toCamelCase(attribute.key) : attribute.key %> as Any<% if (index < collection.attributes.length - 1) { %>,<% } %>
112
+ "<%- attribute.key %>": <%- strict ? toCamelCase(attribute.key) : attribute.key %> as Any<% if (index < collection.attributes.length - 1) { %>,<% } %>
113
113
  <% } else if (attribute.array && attribute.type !== 'string' && attribute.type !== 'integer' && attribute.type !== 'float' && attribute.type !== 'boolean') { -%>
114
- "<%- attribute.key %>": <%- strict ? toCamelCase(attribute.key) : attribute.key %>?.map { $0.toMap() } as Any<% if (index < collection.attributes.length - 1) { %>,<% } %>
114
+ "<%- attribute.key %>": <%- strict ? toCamelCase(attribute.key) : attribute.key %>?.map { $0.toMap() } as Any<% if (index < collection.attributes.length - 1) { %>,<% } %>
115
115
  <% } else { -%>
116
- "<%- attribute.key %>": <%- strict ? toCamelCase(attribute.key) : attribute.key %> as Any<% if (index < collection.attributes.length - 1) { %>,<% } %>
116
+ "<%- attribute.key %>": <%- strict ? toCamelCase(attribute.key) : attribute.key %> as Any<% if (index < collection.attributes.length - 1) { %>,<% } %>
117
117
  <% } -%>
118
118
  <% } -%>
119
- ]
120
- }
119
+ ]
120
+ }
121
121
 
122
- public static func from(map: [String: Any]) -> <%- toPascalCase(collection.name) %> {
123
- return <%- toPascalCase(collection.name) %>(
122
+ public static func from(map: [String: Any]) -> <%- toPascalCase(collection.name) %> {
123
+ return <%- toPascalCase(collection.name) %>(
124
124
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
125
125
  <% if (attribute.type === 'relationship') { -%>
126
126
  <% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
127
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [<%- toPascalCase(attribute.relatedCollection) %>]<% if (index < collection.attributes.length - 1) { %>,<% } %>
127
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [<%- toPascalCase(collections.find(c => c.$id === attribute.relatedCollection).name) %>]<% if (index < collection.attributes.length - 1) { %>,<% } %>
128
128
  <% } else { -%>
129
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> <%- toPascalCase(attribute.relatedCollection) %><% if (index < collection.attributes.length - 1) { %>,<% } %>
129
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> <%- toPascalCase(collections.find(c => c.$id === attribute.relatedCollection).name) %><% if (index < collection.attributes.length - 1) { %>,<% } %>
130
130
  <% } -%>
131
131
  <% } else if (attribute.array) { -%>
132
132
  <% if (attribute.type === 'string') { -%>
133
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [String]<% if (index < 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) { %>,<% } %>
134
134
  <% } else if (attribute.type === 'integer') { -%>
135
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Int]<% if (index < 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) { %>,<% } %>
136
136
  <% } else if (attribute.type === 'float') { -%>
137
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Double]<% if (index < 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) { %>,<% } %>
138
138
  <% } else if (attribute.type === 'boolean') { -%>
139
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> [Bool]<% if (index < 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) { %>,<% } %>
140
140
  <% } else { -%>
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) { %>,<% } %>
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) { %>,<% } %>
142
142
  <% } -%>
143
143
  <% } else { -%>
144
144
  <% if ((attribute.type === 'string' || attribute.type === 'email' || attribute.type === 'datetime') && attribute.format !== 'enum') { -%>
145
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> String<% if (index < 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) { %>,<% } %>
146
146
  <% } else if (attribute.type === 'string' && attribute.format === 'enum') { -%>
147
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- toPascalCase(attribute.key) %>(rawValue: map["<%- attribute.key %>"] as! String)!<% if (index < 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) { %>,<% } %>
148
148
  <% } else if (attribute.type === 'integer') { -%>
149
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Int<% if (index < 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) { %>,<% } %>
150
150
  <% } else if (attribute.type === 'float') { -%>
151
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Double<% if (index < 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) { %>,<% } %>
152
152
  <% } else if (attribute.type === 'boolean') { -%>
153
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: map["<%- attribute.key %>"] as<% if (!attribute.required) { %>?<% } else { %>!<% } %> Bool<% if (index < 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) { %>,<% } %>
154
154
  <% } else { -%>
155
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- toPascalCase(attribute.type) %>.from(map: map["<%- attribute.key %>"] as! [String: Any])<% if (index < 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) { %>,<% } %>
156
156
  <% } -%>
157
157
  <% } -%>
158
158
  <% } -%>
159
- )
160
- }
159
+ )
160
+ }
161
161
  }`;
162
162
  }
163
163
 
@@ -6,7 +6,7 @@ const { AttributeType } = require('../attribute');
6
6
  const { LanguageMeta } = require("./language");
7
7
 
8
8
  class TypeScript extends LanguageMeta {
9
- getType(attribute) {
9
+ getType(attribute, collections) {
10
10
  let type = ""
11
11
  switch (attribute.type) {
12
12
  case AttributeType.STRING:
@@ -29,7 +29,11 @@ class TypeScript extends LanguageMeta {
29
29
  type = "boolean";
30
30
  break;
31
31
  case AttributeType.RELATIONSHIP:
32
- type = LanguageMeta.toPascalCase(attribute.relatedCollection);
32
+ const relatedCollection = collections.find(c => c.$id === attribute.relatedCollection);
33
+ if (!relatedCollection) {
34
+ throw new Error(`Related collection with ID '${attribute.relatedCollection}' not found.`);
35
+ }
36
+ type = LanguageMeta.toPascalCase(relatedCollection.name);
33
37
  if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
34
38
  type = `${type}[]`;
35
39
  }
@@ -64,15 +68,11 @@ class TypeScript extends LanguageMeta {
64
68
  return "appwrite";
65
69
  }
66
70
 
67
- getCurrentDirectory() {
68
- return process.cwd();
69
- }
70
-
71
71
  getTemplate() {
72
72
  return `import { type Models } from '${this._getAppwriteDependency()}';
73
73
 
74
74
  // This file is auto-generated by the Appwrite CLI.
75
- // You can regenerate it by running \`appwrite types -l ts ${this.getCurrentDirectory()}\`.
75
+ // You can regenerate it by running \`appwrite ${process.argv.slice(2).join(' ')}\`.
76
76
 
77
77
  <% for (const collection of collections) { -%>
78
78
  <% for (const attribute of collection.attributes) { -%>
@@ -80,21 +80,21 @@ class TypeScript extends LanguageMeta {
80
80
  export enum <%- toPascalCase(attribute.key) %> {
81
81
  <% const entries = Object.entries(attribute.elements); -%>
82
82
  <% for (let i = 0; i < entries.length; i++) { -%>
83
- <%- toUpperSnakeCase(entries[i][1]) %> = "<%- entries[i][1] %>"<% if (i !== entries.length - 1) { %>,<% } %>
83
+ <%- toUpperSnakeCase(entries[i][1]) %> = "<%- entries[i][1] %>"<% if (i !== entries.length - 1) { %>,<% } %>
84
84
  <% } -%>
85
85
  }
86
86
 
87
87
  <% } -%>
88
88
  <% } -%>
89
89
  <% } -%>
90
- <% for (const collection of collections) { -%>
90
+ <% for (const [index, collection] of Object.entries(collections)) { -%>
91
91
  export type <%- toPascalCase(collection.name) %> = Models.Document & {
92
92
  <% for (const attribute of collection.attributes) { -%>
93
- <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute) %>;
93
+ <%- strict ? toCamelCase(attribute.key) : attribute.key %>: <%- getType(attribute, collections) %>;
94
94
  <% } -%>
95
- }
96
-
97
- <% } %>`;
95
+ }<% if (index < collections.length - 1) { %>
96
+ <% } %>
97
+ <% } -%>`;
98
98
  }
99
99
 
100
100
  getFileName(_) {
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.2.1",
5
+ "version": "8.3.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.2.1",
3
+ "version": "8.3.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.2.1/appwrite-cli-win-x64.exe",
9
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/8.3.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.2.1/appwrite-cli-win-arm64.exe",
18
+ "url": "https://github.com/appwrite/sdk-for-cli/releases/download/8.3.0/appwrite-cli-win-arm64.exe",
19
19
  "bin": [
20
20
  [
21
21
  "appwrite-cli-win-arm64.exe",