appwrite-cli 7.0.0 → 8.0.1

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/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
- 7.0.0
32
+ 8.0.1
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
- 7.0.0
63
+ 8.0.1
64
64
  ```
65
65
 
66
66
  ## Getting Started
@@ -1,4 +1,6 @@
1
1
  appwrite proxy createRedirectRule \
2
2
  --domain '' \
3
3
  --url https://example.com \
4
- --statusCode 301
4
+ --statusCode 301 \
5
+ --resourceId <RESOURCE_ID> \
6
+ --resourceType site
@@ -2,3 +2,4 @@ appwrite vcs getRepositoryContents \
2
2
  --installationId <INSTALLATION_ID> \
3
3
  --providerRepositoryId <PROVIDER_REPOSITORY_ID> \
4
4
 
5
+
package/index.js CHANGED
@@ -13,12 +13,12 @@ const { client } = require("./lib/commands/generic");
13
13
  const inquirer = require("inquirer");
14
14
  const { login, logout, whoami, migrate, register } = require("./lib/commands/generic");
15
15
  const { init } = require("./lib/commands/init");
16
+ const { types } = require("./lib/commands/types");
16
17
  const { pull } = require("./lib/commands/pull");
17
18
  const { run } = require("./lib/commands/run");
18
19
  const { push, deploy } = require("./lib/commands/push");
19
20
  const { account } = require("./lib/commands/account");
20
21
  const { avatars } = require("./lib/commands/avatars");
21
- const { assistant } = require("./lib/commands/assistant");
22
22
  const { console } = require("./lib/commands/console");
23
23
  const { databases } = require("./lib/commands/databases");
24
24
  const { functions } = require("./lib/commands/functions");
@@ -80,12 +80,12 @@ program
80
80
  .addCommand(init)
81
81
  .addCommand(pull)
82
82
  .addCommand(push)
83
+ .addCommand(types)
83
84
  .addCommand(deploy)
84
85
  .addCommand(run)
85
86
  .addCommand(logout)
86
87
  .addCommand(account)
87
88
  .addCommand(avatars)
88
- .addCommand(assistant)
89
89
  .addCommand(console)
90
90
  .addCommand(databases)
91
91
  .addCommand(functions)
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/7.0.0/appwrite-cli-win-x64.exe"
17
- $GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/7.0.0/appwrite-cli-win-arm64.exe"
16
+ $GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.0.1/appwrite-cli-win-x64.exe"
17
+ $GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/8.0.1/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="7.0.0"
100
+ GITHUB_LATEST_VERSION="8.0.1"
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': '7.0.0',
20
- 'user-agent' : `AppwriteCLI/7.0.0 (${os.type()} ${os.version()}; ${os.arch()})`,
19
+ 'x-sdk-version': '8.0.1',
20
+ 'user-agent' : `AppwriteCLI/8.0.1 (${os.type()} ${os.version()}; ${os.arch()})`,
21
21
  'X-Appwrite-Response-Format' : '1.7.0',
22
22
  };
23
23
  }
@@ -2660,7 +2660,7 @@ databases
2660
2660
 
2661
2661
  databases
2662
2662
  .command(`create-documents`)
2663
- .description(`Create new 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.`)
2663
+ .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 new 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.`)
2664
2664
  .requiredOption(`--database-id <database-id>`, `Database ID.`)
2665
2665
  .requiredOption(`--collection-id <collection-id>`, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents.`)
2666
2666
  .requiredOption(`--documents [documents...]`, `Array of documents data as JSON objects.`)
@@ -2668,7 +2668,7 @@ databases
2668
2668
 
2669
2669
  databases
2670
2670
  .command(`upsert-documents`)
2671
- .description(`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. `)
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.`)
2672
2672
  .requiredOption(`--database-id <database-id>`, `Database ID.`)
2673
2673
  .requiredOption(`--collection-id <collection-id>`, `Collection ID.`)
2674
2674
  .requiredOption(`--documents [documents...]`, `Array of document data as JSON objects. May contain partial documents.`)
@@ -2676,7 +2676,7 @@ databases
2676
2676
 
2677
2677
  databases
2678
2678
  .command(`update-documents`)
2679
- .description(`Update all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.`)
2679
+ .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. Update all documents that match your queries, if no queries are submitted then all documents are updated. You can pass only specific fields to be updated.`)
2680
2680
  .requiredOption(`--database-id <database-id>`, `Database ID.`)
2681
2681
  .requiredOption(`--collection-id <collection-id>`, `Collection ID.`)
2682
2682
  .option(`--data <data>`, `Document data as JSON object. Include only attribute and value pairs to be updated.`)
@@ -2685,7 +2685,7 @@ databases
2685
2685
 
2686
2686
  databases
2687
2687
  .command(`delete-documents`)
2688
- .description(`Bulk delete documents using queries, if no queries are passed then all documents are deleted.`)
2688
+ .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. Bulk delete documents using queries, if no queries are passed then all documents are deleted.`)
2689
2689
  .requiredOption(`--database-id <database-id>`, `Database ID.`)
2690
2690
  .requiredOption(`--collection-id <collection-id>`, `Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).`)
2691
2691
  .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.`)
@@ -2703,7 +2703,7 @@ databases
2703
2703
 
2704
2704
  databases
2705
2705
  .command(`upsert-document`)
2706
- .description(`Create or update a Document. 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.`)
2706
+ .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 a Document. 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.`)
2707
2707
  .requiredOption(`--database-id <database-id>`, `Database ID.`)
2708
2708
  .requiredOption(`--collection-id <collection-id>`, `Collection ID.`)
2709
2709
  .requiredOption(`--document-id <document-id>`, `Document ID.`)
@@ -157,6 +157,8 @@ const proxyCreateFunctionRule = async ({domain,functionId,branch,parseOutput = t
157
157
  * @property {string} domain Domain name.
158
158
  * @property {string} url Target URL of redirection
159
159
  * @property {StatusCode} statusCode Status code of redirection
160
+ * @property {string} resourceId ID of parent resource.
161
+ * @property {ProxyResourceType} resourceType Type of parent resource.
160
162
  * @property {boolean} overrideForCli
161
163
  * @property {boolean} parseOutput
162
164
  * @property {libClient | undefined} sdk
@@ -165,7 +167,7 @@ const proxyCreateFunctionRule = async ({domain,functionId,branch,parseOutput = t
165
167
  /**
166
168
  * @param {ProxyCreateRedirectRuleRequestParams} params
167
169
  */
168
- const proxyCreateRedirectRule = async ({domain,url,statusCode,parseOutput = true, overrideForCli = false, sdk = undefined}) => {
170
+ const proxyCreateRedirectRule = async ({domain,url,statusCode,resourceId,resourceType,parseOutput = true, overrideForCli = false, sdk = undefined}) => {
169
171
  let client = !sdk ? await sdkForProject() :
170
172
  sdk;
171
173
  let apiPath = '/proxy/rules/redirect';
@@ -179,6 +181,12 @@ const proxyCreateRedirectRule = async ({domain,url,statusCode,parseOutput = true
179
181
  if (typeof statusCode !== 'undefined') {
180
182
  payload['statusCode'] = statusCode;
181
183
  }
184
+ if (typeof resourceId !== 'undefined') {
185
+ payload['resourceId'] = resourceId;
186
+ }
187
+ if (typeof resourceType !== 'undefined') {
188
+ payload['resourceType'] = resourceType;
189
+ }
182
190
 
183
191
  let response = undefined;
184
192
 
@@ -355,6 +363,8 @@ proxy
355
363
  .requiredOption(`--domain <domain>`, `Domain name.`)
356
364
  .requiredOption(`--url <url>`, `Target URL of redirection`)
357
365
  .requiredOption(`--status-code <status-code>`, `Status code of redirection`)
366
+ .requiredOption(`--resource-id <resource-id>`, `ID of parent resource.`)
367
+ .requiredOption(`--resource-type <resource-type>`, `Type of parent resource.`)
358
368
  .action(actionRunner(proxyCreateRedirectRule))
359
369
 
360
370
  proxy
@@ -0,0 +1,126 @@
1
+ const ejs = require("ejs");
2
+ const fs = require("fs");
3
+ const path = require("path");
4
+ const { LanguageMeta, detectLanguage } = require("../type-generation/languages/language");
5
+ const { Command, Option, Argument } = require("commander");
6
+ const { localConfig } = require("../config");
7
+ const { success, log, actionRunner } = require("../parser");
8
+ const { PHP } = require("../type-generation/languages/php");
9
+ const { TypeScript } = require("../type-generation/languages/typescript");
10
+ const { Kotlin } = require("../type-generation/languages/kotlin");
11
+ const { Swift } = require("../type-generation/languages/swift");
12
+ const { Java } = require("../type-generation/languages/java");
13
+ const { Dart } = require("../type-generation/languages/dart");
14
+ const { JavaScript } = require("../type-generation/languages/javascript");
15
+
16
+ /**
17
+ * @param {string} language
18
+ * @returns {import("../type-generation/languages/language").LanguageMeta}
19
+ */
20
+ function createLanguageMeta(language) {
21
+ switch (language) {
22
+ case "ts":
23
+ return new TypeScript();
24
+ case "js":
25
+ return new JavaScript();
26
+ case "php":
27
+ return new PHP();
28
+ case "kotlin":
29
+ return new Kotlin();
30
+ case "swift":
31
+ return new Swift();
32
+ case "java":
33
+ return new Java();
34
+ case "dart":
35
+ return new Dart();
36
+ default:
37
+ throw new Error(`Language '${language}' is not supported`);
38
+ }
39
+ }
40
+
41
+ const templateHelpers = {
42
+ toPascalCase: LanguageMeta.toPascalCase,
43
+ toCamelCase: LanguageMeta.toCamelCase,
44
+ toSnakeCase: LanguageMeta.toSnakeCase,
45
+ toKebabCase: LanguageMeta.toKebabCase,
46
+ toUpperSnakeCase: LanguageMeta.toUpperSnakeCase
47
+ }
48
+
49
+ const typesOutputArgument = new Argument(
50
+ "<output-directory>",
51
+ "The directory to write the types to"
52
+ );
53
+
54
+ const typesLanguageOption = new Option(
55
+ "-l, --language <language>",
56
+ "The language of the types"
57
+ )
58
+ .choices(["auto", "ts", "js", "php", "kotlin", "swift", "java", "dart"])
59
+ .default("auto");
60
+
61
+ const typesCommand = actionRunner(async (rawOutputDirectory, {language}) => {
62
+ if (language === "auto") {
63
+ language = detectLanguage();
64
+ log(`Detected language: ${language}`);
65
+ }
66
+
67
+ const meta = createLanguageMeta(language);
68
+
69
+ const outputDirectory = path.resolve(rawOutputDirectory);
70
+ if (!fs.existsSync(outputDirectory)) {
71
+ log(`Directory: ${outputDirectory} does not exist, creating...`);
72
+ fs.mkdirSync(outputDirectory, { recursive: true });
73
+ }
74
+
75
+ if (!fs.existsSync("appwrite.json")) {
76
+ throw new Error("appwrite.json not found in current directory");
77
+ }
78
+
79
+ const collections = localConfig.getCollections();
80
+ if (collections.length === 0) {
81
+ throw new Error("No collections found in appwrite.json");
82
+ }
83
+
84
+ log(`Found ${collections.length} collections: ${collections.map(c => c.name).join(", ")}`);
85
+
86
+ const totalAttributes = collections.reduce((count, collection) => count + collection.attributes.length, 0);
87
+ log(`Found ${totalAttributes} attributes across all collections`);
88
+
89
+ const templater = ejs.compile(meta.getTemplate());
90
+
91
+ if (meta.isSingleFile()) {
92
+ const content = templater({
93
+ collections,
94
+ ...templateHelpers,
95
+ getType: meta.getType
96
+ });
97
+
98
+ const destination = path.join(outputDirectory, meta.getFileName());
99
+
100
+ fs.writeFileSync(destination, content);
101
+ log(`Added types to ${destination}`);
102
+ } else {
103
+ for (const collection of collections) {
104
+ const content = templater({
105
+ collection,
106
+ ...templateHelpers,
107
+ getType: meta.getType
108
+ });
109
+
110
+ const destination = path.join(outputDirectory, meta.getFileName(collection));
111
+
112
+ fs.writeFileSync(destination, content);
113
+ log(`Added types for ${collection.name} to ${destination}`);
114
+ }
115
+ }
116
+
117
+ success(`Generated types for all the listed collections`);
118
+ });
119
+
120
+ const types = new Command("types")
121
+ .description("Generate types for your Appwrite project")
122
+ .addArgument(typesOutputArgument)
123
+ .addOption(typesLanguageOption)
124
+ .action(actionRunner(typesCommand));
125
+
126
+ module.exports = { types };
@@ -226,6 +226,7 @@ const vcsListRepositoryBranches = async ({installationId,providerRepositoryId,pa
226
226
  * @property {string} installationId Installation Id
227
227
  * @property {string} providerRepositoryId Repository Id
228
228
  * @property {string} providerRootDirectory Path to get contents of nested directory
229
+ * @property {string} providerReference Git reference (branch, tag, commit) to get contents from
229
230
  * @property {boolean} overrideForCli
230
231
  * @property {boolean} parseOutput
231
232
  * @property {libClient | undefined} sdk
@@ -234,7 +235,7 @@ const vcsListRepositoryBranches = async ({installationId,providerRepositoryId,pa
234
235
  /**
235
236
  * @param {VcsGetRepositoryContentsRequestParams} params
236
237
  */
237
- const vcsGetRepositoryContents = async ({installationId,providerRepositoryId,providerRootDirectory,parseOutput = true, overrideForCli = false, sdk = undefined}) => {
238
+ const vcsGetRepositoryContents = async ({installationId,providerRepositoryId,providerRootDirectory,providerReference,parseOutput = true, overrideForCli = false, sdk = undefined}) => {
238
239
  let client = !sdk ? await sdkForProject() :
239
240
  sdk;
240
241
  let apiPath = '/vcs/github/installations/{installationId}/providerRepositories/{providerRepositoryId}/contents'.replace('{installationId}', installationId).replace('{providerRepositoryId}', providerRepositoryId);
@@ -242,6 +243,9 @@ const vcsGetRepositoryContents = async ({installationId,providerRepositoryId,pro
242
243
  if (typeof providerRootDirectory !== 'undefined') {
243
244
  payload['providerRootDirectory'] = providerRootDirectory;
244
245
  }
246
+ if (typeof providerReference !== 'undefined') {
247
+ payload['providerReference'] = providerReference;
248
+ }
245
249
 
246
250
  let response = undefined;
247
251
 
@@ -435,6 +439,7 @@ vcs
435
439
  .requiredOption(`--installation-id <installation-id>`, `Installation Id`)
436
440
  .requiredOption(`--provider-repository-id <provider-repository-id>`, `Repository Id`)
437
441
  .option(`--provider-root-directory <provider-root-directory>`, `Path to get contents of nested directory`)
442
+ .option(`--provider-reference <provider-reference>`, `Git reference (branch, tag, commit) to get contents from`)
438
443
  .action(actionRunner(vcsGetRepositoryContents))
439
444
 
440
445
  vcs
package/lib/parser.js CHANGED
@@ -120,7 +120,7 @@ const parseError = (err) => {
120
120
  } catch {
121
121
  }
122
122
 
123
- const version = '7.0.0';
123
+ const version = '8.0.1';
124
124
  const stepsToReproduce = `Running \`appwrite ${cliConfig.reportData.data.args.join(' ')}\``;
125
125
  const yourEnvironment = `CLI version: ${version}\nOperation System: ${os.type()}\nAppwrite version: ${appwriteVersion}\nIs Cloud: ${isCloud}`;
126
126
 
@@ -221,7 +221,6 @@ const commandDescriptions = {
221
221
  "whoami": `The whomai command gives information about the currently logged-in user.`,
222
222
  "register": `Outputs the link to create an Appwrite account.`,
223
223
  "console" : `The console command gives you access to the APIs used by the Appwrite Console.`,
224
- "assistant": `The assistant command allows you to interact with the Appwrite Assistant AI`,
225
224
  "messaging": `The messaging command allows you to manage topics and targets and send messages.`,
226
225
  "migrations": `The migrations command allows you to migrate data between services.`,
227
226
  "vcs": `The vcs command allows you to interact with VCS providers and manage your code repositories.`,
@@ -0,0 +1,16 @@
1
+ const AttributeType = {
2
+ STRING: "string",
3
+ INTEGER: "integer",
4
+ FLOAT: "float",
5
+ BOOLEAN: "boolean",
6
+ DATETIME: "datetime",
7
+ EMAIL: "email",
8
+ IP: "ip",
9
+ URL: "url",
10
+ ENUM: "enum",
11
+ RELATIONSHIP: "relationship",
12
+ };
13
+
14
+ module.exports = {
15
+ AttributeType,
16
+ };
@@ -0,0 +1,152 @@
1
+ /** @typedef {import('../attribute').Attribute} Attribute */
2
+ const { AttributeType } = require('../attribute');
3
+ const { LanguageMeta } = require("./language");
4
+
5
+ class Dart extends LanguageMeta {
6
+ getType(attribute) {
7
+ let type = "";
8
+ switch (attribute.type) {
9
+ case AttributeType.STRING:
10
+ case AttributeType.EMAIL:
11
+ case AttributeType.DATETIME:
12
+ type = "String";
13
+ if (attribute.format === AttributeType.ENUM) {
14
+ type = LanguageMeta.toPascalCase(attribute.key);
15
+ }
16
+ break;
17
+ case AttributeType.INTEGER:
18
+ type = "int";
19
+ break;
20
+ case AttributeType.FLOAT:
21
+ type = "double";
22
+ break;
23
+ case AttributeType.BOOLEAN:
24
+ type = "bool";
25
+ break;
26
+ case AttributeType.RELATIONSHIP:
27
+ type = LanguageMeta.toPascalCase(attribute.relatedCollection);
28
+ if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
29
+ type = `List<${type}>`;
30
+ }
31
+ break;
32
+ default:
33
+ throw new Error(`Unknown attribute type: ${attribute.type}`);
34
+ }
35
+ if (attribute.array) {
36
+ type = `List<${type}>`;
37
+ }
38
+ if (!attribute.required) {
39
+ type += "?";
40
+ }
41
+ return type;
42
+ }
43
+
44
+ getTemplate() {
45
+ return `<% for (const attribute of collection.attributes) { -%>
46
+ <% if (attribute.type === 'relationship') { -%>
47
+ import '<%- attribute.relatedCollection.toLowerCase() %>.dart';
48
+
49
+ <% } -%>
50
+ <% } -%>
51
+ <% for (const attribute of collection.attributes) { -%>
52
+ <% if (attribute.format === 'enum') { -%>
53
+ enum <%- toPascalCase(attribute.key) %> {
54
+ <% for (const element of attribute.elements) { -%>
55
+ <%- element %>,
56
+ <% } -%>
57
+ }
58
+
59
+ <% } -%>
60
+ <% } -%>
61
+ class <%= toPascalCase(collection.name) %> {
62
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
63
+ <%- getType(attribute) %> <%= toCamelCase(attribute.key) %>;
64
+ <% } -%>
65
+
66
+ <%= toPascalCase(collection.name) %>({
67
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
68
+ <% if (attribute.required) { %>required <% } %>this.<%= toCamelCase(attribute.key) %>,
69
+ <% } -%>
70
+ });
71
+
72
+ factory <%= toPascalCase(collection.name) %>.fromMap(Map<String, dynamic> map) {
73
+ return <%= toPascalCase(collection.name) %>(
74
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
75
+ <%= toCamelCase(attribute.key) %>: <% if (attribute.type === 'string' || attribute.type === 'email' || attribute.type === 'datetime') { -%>
76
+ <% if (attribute.format === 'enum') { -%>
77
+ <% if (attribute.array) { -%>
78
+ (map['<%= attribute.key %>'] as List<dynamic>?)?.map((e) => <%- toPascalCase(attribute.key) %>.values.firstWhere((element) => element.name == e)).toList()<% if (!attribute.required) { %> ?? []<% } -%>
79
+ <% } else { -%>
80
+ <% if (!attribute.required) { -%>
81
+ map['<%= attribute.key %>'] != null ? <%- toPascalCase(attribute.key) %>.values.where((e) => e.name == map['<%= attribute.key %>']).firstOrNull : null<% } else { -%>
82
+ <%- toPascalCase(attribute.key) %>.values.firstWhere((e) => e.name == map['<%= attribute.key %>'])<% } -%>
83
+ <% } -%>
84
+ <% } else { -%>
85
+ <% if (attribute.array) { -%>
86
+ List<String>.from(map['<%= attribute.key %>'] ?? [])<% if (!attribute.required) { %> ?? []<% } -%>
87
+ <% } else { -%>
88
+ map['<%= attribute.key %>']<% if (!attribute.required) { %>?<% } %>.toString()<% if (!attribute.required) { %> ?? null<% } -%>
89
+ <% } -%>
90
+ <% } -%>
91
+ <% } else if (attribute.type === 'integer') { -%>
92
+ <% if (attribute.array) { -%>
93
+ List<int>.from(map['<%= attribute.key %>'] ?? [])<% if (!attribute.required) { %> ?? []<% } -%>
94
+ <% } else { -%>
95
+ map['<%= attribute.key %>']<% if (!attribute.required) { %> ?? null<% } -%>
96
+ <% } -%>
97
+ <% } else if (attribute.type === 'float') { -%>
98
+ <% if (attribute.array) { -%>
99
+ List<double>.from(map['<%= attribute.key %>'] ?? [])<% if (!attribute.required) { %> ?? []<% } -%>
100
+ <% } else { -%>
101
+ map['<%= attribute.key %>']<% if (!attribute.required) { %> ?? null<% } -%>
102
+ <% } -%>
103
+ <% } else if (attribute.type === 'boolean') { -%>
104
+ <% if (attribute.array) { -%>
105
+ List<bool>.from(map['<%= attribute.key %>'] ?? [])<% if (!attribute.required) { %> ?? []<% } -%>
106
+ <% } else { -%>
107
+ map['<%= attribute.key %>']<% if (!attribute.required) { %> ?? null<% } -%>
108
+ <% } -%>
109
+ <% } else if (attribute.type === 'relationship') { -%>
110
+ <% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
111
+ (map['<%= attribute.key %>'] as List<dynamic>?)?.map((e) => <%- toPascalCase(attribute.relatedCollection) %>.fromMap(e)).toList()<% if (!attribute.required) { %> ?? []<% } -%>
112
+ <% } else { -%>
113
+ <% if (!attribute.required) { -%>
114
+ map['<%= attribute.key %>'] != null ? <%- toPascalCase(attribute.relatedCollection) %>.fromMap(map['<%= attribute.key %>']) : null<% } else { -%>
115
+ <%- toPascalCase(attribute.relatedCollection) %>.fromMap(map['<%= attribute.key %>'])<% } -%>
116
+ <% } -%>
117
+ <% } -%>,
118
+ <% } -%>
119
+ );
120
+ }
121
+
122
+ Map<String, dynamic> toMap() {
123
+ return {
124
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
125
+ "<%= attribute.key %>": <% if (attribute.type === 'relationship') { -%>
126
+ <% 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) { %> ?? []<% } -%>
128
+ <% } else { -%>
129
+ <%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.toMap()<% if (!attribute.required) { %> ?? {}<% } -%>
130
+ <% } -%>
131
+ <% } else if (attribute.format === 'enum') { -%>
132
+ <% if (attribute.array) { -%>
133
+ <%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.map((e) => e.name).toList()<% if (!attribute.required) { %> ?? []<% } -%>
134
+ <% } else { -%>
135
+ <%= toCamelCase(attribute.key) %><% if (!attribute.required) { %>?<% } %>.name<% if (!attribute.required) { %> ?? null<% } -%>
136
+ <% } -%>
137
+ <% } else { -%>
138
+ <%= toCamelCase(attribute.key) -%>
139
+ <% } -%>,
140
+ <% } -%>
141
+ };
142
+ }
143
+ }
144
+ `;
145
+ }
146
+
147
+ getFileName(collection) {
148
+ return LanguageMeta.toSnakeCase(collection.name) + ".dart";
149
+ }
150
+ }
151
+
152
+ module.exports = { Dart };
@@ -0,0 +1,121 @@
1
+ /** @typedef {import('../attribute').Attribute} Attribute */
2
+ const { AttributeType } = require('../attribute');
3
+ const { LanguageMeta } = require("./language");
4
+
5
+ class Java extends LanguageMeta {
6
+ getType(attribute) {
7
+ let type = "";
8
+ switch (attribute.type) {
9
+ case AttributeType.STRING:
10
+ case AttributeType.EMAIL:
11
+ case AttributeType.DATETIME:
12
+ type = "String";
13
+ if (attribute.format === AttributeType.ENUM) {
14
+ type = LanguageMeta.toPascalCase(attribute.key);
15
+ }
16
+ break;
17
+ case AttributeType.INTEGER:
18
+ type = "int";
19
+ break;
20
+ case AttributeType.FLOAT:
21
+ type = "double";
22
+ break;
23
+ case AttributeType.BOOLEAN:
24
+ type = "boolean";
25
+ break;
26
+ case AttributeType.RELATIONSHIP:
27
+ type = LanguageMeta.toPascalCase(attribute.relatedCollection);
28
+ if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') {
29
+ type = "List<" + type + ">";
30
+ }
31
+ break;
32
+ default:
33
+ throw new Error(`Unknown attribute type: ${attribute.type}`);
34
+ }
35
+ if (attribute.array) {
36
+ type = "List<" + type + ">";
37
+ }
38
+ return type;
39
+ }
40
+
41
+ getTemplate() {
42
+ return `package io.appwrite.models;
43
+
44
+ import java.util.*;
45
+ <% for (const attribute of collection.attributes) { -%>
46
+ <% if (attribute.type === 'relationship') { -%>
47
+ import <%- toPascalCase(attribute.relatedCollection) %>;
48
+
49
+ <% } -%>
50
+ <% } -%>
51
+ public class <%- toPascalCase(collection.name) %> {
52
+ <% for (const attribute of collection.attributes) { -%>
53
+ <% if (attribute.format === 'enum') { -%>
54
+
55
+ public enum <%- toPascalCase(attribute.key) %> {
56
+ <% for (const [index, element] of Object.entries(attribute.elements)) { -%>
57
+ <%- element %><%- index < attribute.elements.length - 1 ? ',' : ';' %>
58
+ <% } -%>
59
+ }
60
+
61
+ <% } -%>
62
+ <% } -%>
63
+ <% for (const attribute of collection.attributes) { -%>
64
+ private <%- getType(attribute) %> <%- toCamelCase(attribute.key) %>;
65
+ <% } -%>
66
+
67
+ public <%- toPascalCase(collection.name) %>() {
68
+ }
69
+
70
+ public <%- toPascalCase(collection.name) %>(
71
+ <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
72
+ <%- getType(attribute) %> <%= toCamelCase(attribute.key) %><%- index < collection.attributes.length - 1 ? ',' : '' %>
73
+ <% } -%>
74
+ ) {
75
+ <% for (const attribute of collection.attributes) { -%>
76
+ this.<%= toCamelCase(attribute.key) %> = <%= toCamelCase(attribute.key) %>;
77
+ <% } -%>
78
+ }
79
+
80
+ <% for (const attribute of collection.attributes) { -%>
81
+ public <%- getType(attribute) %> get<%- toPascalCase(attribute.key) %>() {
82
+ return <%= toCamelCase(attribute.key) %>;
83
+ }
84
+
85
+ public void set<%- toPascalCase(attribute.key) %>(<%- getType(attribute) %> <%= toCamelCase(attribute.key) %>) {
86
+ this.<%= toCamelCase(attribute.key) %> = <%= toCamelCase(attribute.key) %>;
87
+ }
88
+
89
+ <% } -%>
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
+ }
98
+
99
+ @Override
100
+ public int hashCode() {
101
+ return Objects.hash(<%= collection.attributes.map(attr => toCamelCase(attr.key)).join(', ') %>);
102
+ }
103
+
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) %> +
109
+ <% } -%>
110
+ '}';
111
+ }
112
+ }
113
+ `;
114
+ }
115
+
116
+ getFileName(collection) {
117
+ return LanguageMeta.toPascalCase(collection.name) + ".java";
118
+ }
119
+ }
120
+
121
+ module.exports = { Java };