chirag-appwrite-cli 0.1.0 → 0.1.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.
Files changed (96) hide show
  1. package/appwrite.config.json +420 -0
  2. package/docs/examples/databases/list-usage.md +2 -0
  3. package/docs/examples/projects/update-session-invalidation.md +3 -0
  4. package/docs/examples/tables/create-boolean-column.md +7 -0
  5. package/docs/examples/tables/create-datetime-column.md +7 -0
  6. package/docs/examples/tables/create-email-column.md +7 -0
  7. package/docs/examples/tables/create-enum-column.md +8 -0
  8. package/docs/examples/tables/create-float-column.md +9 -0
  9. package/docs/examples/tables/create-index.md +8 -0
  10. package/docs/examples/tables/create-integer-column.md +9 -0
  11. package/docs/examples/tables/create-ip-column.md +7 -0
  12. package/docs/examples/tables/create-relationship-column.md +9 -0
  13. package/docs/examples/tables/create-row.md +6 -0
  14. package/docs/examples/tables/create-rows.md +4 -0
  15. package/docs/examples/tables/create-string-column.md +9 -0
  16. package/docs/examples/tables/create-url-column.md +7 -0
  17. package/docs/examples/tables/create.md +7 -0
  18. package/docs/examples/tables/decrement-row-column.md +7 -0
  19. package/docs/examples/tables/delete-column.md +4 -0
  20. package/docs/examples/tables/delete-index.md +4 -0
  21. package/docs/examples/tables/delete-row.md +4 -0
  22. package/docs/examples/tables/delete-rows.md +4 -0
  23. package/docs/examples/tables/delete.md +3 -0
  24. package/docs/examples/tables/get-column.md +4 -0
  25. package/docs/examples/tables/get-index.md +4 -0
  26. package/docs/examples/tables/get-row.md +5 -0
  27. package/docs/examples/tables/get-usage.md +4 -0
  28. package/docs/examples/tables/get.md +3 -0
  29. package/docs/examples/tables/increment-row-column.md +7 -0
  30. package/docs/examples/tables/list-columns.md +4 -0
  31. package/docs/examples/tables/list-indexes.md +4 -0
  32. package/docs/examples/tables/list-logs.md +4 -0
  33. package/docs/examples/tables/list-row-logs.md +5 -0
  34. package/docs/examples/tables/list-rows.md +4 -0
  35. package/docs/examples/tables/list.md +4 -0
  36. package/docs/examples/tables/update-boolean-column.md +7 -0
  37. package/docs/examples/tables/update-datetime-column.md +7 -0
  38. package/docs/examples/tables/update-email-column.md +7 -0
  39. package/docs/examples/tables/update-enum-column.md +8 -0
  40. package/docs/examples/tables/update-float-column.md +9 -0
  41. package/docs/examples/tables/update-integer-column.md +9 -0
  42. package/docs/examples/tables/update-ip-column.md +7 -0
  43. package/docs/examples/tables/update-relationship-column.md +6 -0
  44. package/docs/examples/tables/update-row.md +6 -0
  45. package/docs/examples/tables/update-rows.md +5 -0
  46. package/docs/examples/tables/update-string-column.md +8 -0
  47. package/docs/examples/tables/update-url-column.md +7 -0
  48. package/docs/examples/tables/update.md +7 -0
  49. package/docs/examples/tables/upsert-row.md +4 -0
  50. package/docs/examples/tables/upsert-rows.md +3 -0
  51. package/generate/appwrite.d.ts +43 -6
  52. package/generate/appwrite.db.ts +75 -0
  53. package/lib/client-generation/languages/typescript.js +65 -0
  54. package/lib/commands/account.js +1 -1
  55. package/lib/commands/avatars.js +1 -1
  56. package/lib/commands/console.js +1 -1
  57. package/lib/commands/databases.js +2 -2
  58. package/lib/commands/functions.js +1 -1
  59. package/lib/commands/graphql.js +1 -1
  60. package/lib/commands/health.js +1 -1
  61. package/lib/commands/locale.js +1 -1
  62. package/lib/commands/messaging.js +1 -1
  63. package/lib/commands/migrations.js +1 -1
  64. package/lib/commands/project.js +1 -1
  65. package/lib/commands/projects.js +1 -1
  66. package/lib/commands/proxy.js +1 -1
  67. package/lib/commands/sites.js +1 -1
  68. package/lib/commands/storage.js +1 -1
  69. package/lib/commands/tables.js +2607 -0
  70. package/lib/commands/teams.js +1 -1
  71. package/lib/commands/tokens.js +1 -1
  72. package/lib/commands/types.js +45 -10
  73. package/lib/commands/users.js +1 -1
  74. package/lib/commands/vcs.js +2 -2
  75. package/lib/config.js +26 -14
  76. package/lib/type-generation/languages/dart.js +13 -13
  77. package/lib/type-generation/languages/java.js +13 -13
  78. package/lib/type-generation/languages/javascript.js +14 -14
  79. package/lib/type-generation/languages/kotlin.js +11 -10
  80. package/lib/type-generation/languages/php.js +15 -14
  81. package/lib/type-generation/languages/swift.js +13 -13
  82. package/lib/type-generation/languages/typescript.js +4 -1
  83. package/package.json +1 -1
  84. package/appwrite.json +0 -164
  85. /package/sites/{JavaScript starter → JavaScript starter2}/.env.example +0 -0
  86. /package/sites/{JavaScript starter → JavaScript starter2}/LICENSE +0 -0
  87. /package/sites/{JavaScript starter → JavaScript starter2}/images/appwrite.svg +0 -0
  88. /package/sites/{JavaScript starter → JavaScript starter2}/images/javascript.svg +0 -0
  89. /package/sites/{JavaScript starter → JavaScript starter2}/index.html +0 -0
  90. /package/sites/{JavaScript starter → JavaScript starter2}/lib/appwrite.js +0 -0
  91. /package/sites/{JavaScript starter → JavaScript starter2}/package-lock.json +0 -0
  92. /package/sites/{JavaScript starter → JavaScript starter2}/package.json +0 -0
  93. /package/sites/{JavaScript starter → JavaScript starter2}/readme.md +0 -0
  94. /package/sites/{JavaScript starter → JavaScript starter2}/src/javascript.svg +0 -0
  95. /package/sites/{JavaScript starter → JavaScript starter2}/style/app.css +0 -0
  96. /package/sites/{JavaScript starter → JavaScript starter2}/vite.config.js +0 -0
@@ -7,7 +7,7 @@ const libClient = require('../client.js');
7
7
  const { getAllFiles, showConsoleLink } = require('../utils.js');
8
8
  const { Command } = require('commander');
9
9
  const { sdkForProject, sdkForConsole } = require('../sdks')
10
- const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
10
+ const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log, warn } = require('../parser')
11
11
  const { localConfig, globalConfig } = require("../config");
12
12
  const { File } = require('undici');
13
13
  const { ReadableStream } = require('stream/web');
@@ -7,7 +7,7 @@ const libClient = require('../client.js');
7
7
  const { getAllFiles, showConsoleLink } = require('../utils.js');
8
8
  const { Command } = require('commander');
9
9
  const { sdkForProject, sdkForConsole } = require('../sdks')
10
- const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
10
+ const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log, warn } = require('../parser')
11
11
  const { localConfig, globalConfig } = require("../config");
12
12
  const { File } = require('undici');
13
13
  const { ReadableStream } = require('stream/web');
@@ -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");
@@ -12,6 +12,7 @@ const { Swift } = require("../type-generation/languages/swift");
12
12
  const { Java } = require("../type-generation/languages/java");
13
13
  const { Dart } = require("../type-generation/languages/dart");
14
14
  const { JavaScript } = require("../type-generation/languages/javascript");
15
+ const { TypeScriptClient } = require("../client-generation/languages/typescript");
15
16
 
16
17
  /**
17
18
  * @param {string} language
@@ -64,14 +65,28 @@ const typesStrictOption = new Option(
64
65
  )
65
66
  .default(false);
66
67
 
67
- const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict}) => {
68
+ const typesIncludeClientOption = new Option(
69
+ "-c, --include-client",
70
+ "Generate a Prisma-style client file (TypeScript only)"
71
+ )
72
+ .default(false);
73
+
74
+ const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict, includeClient}) => {
68
75
  if (language === "auto") {
69
76
  language = detectLanguage();
70
77
  log(`Detected language: ${language}`);
71
78
  }
72
79
 
80
+ if (includeClient && language !== "ts") {
81
+ throw new Error("Client generation is only supported for TypeScript. Please use --language ts or ensure TypeScript is auto-detected.");
82
+ }
83
+
73
84
  if (strict) {
74
- log(`Strict mode enabled: Field names will be converted to follow ${language} conventions`);
85
+ warn(`Strict mode enabled: Field names will be converted to follow ${language} conventions`);
86
+ }
87
+
88
+ if (includeClient) {
89
+ log("Client generation enabled: Will generate appwrite.db.ts file");
75
90
  }
76
91
 
77
92
  const meta = createLanguageMeta(language);
@@ -97,13 +112,10 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict})
97
112
  fs.mkdirSync(outputDirectory, { recursive: true });
98
113
  }
99
114
 
100
- if (!fs.existsSync("appwrite.json")) {
101
- throw new Error("appwrite.json not found in current directory");
102
- }
103
-
104
115
  const collections = localConfig.getCollections();
105
116
  if (collections.length === 0) {
106
- throw new Error("No collections found in appwrite.json");
117
+ const configFileName = path.basename(localConfig.path);
118
+ throw new Error(`No collections found in configuration. Make sure ${configFileName} exists and contains collections.`);
107
119
  }
108
120
 
109
121
  log(`Found ${collections.length} collections: ${collections.map(c => c.name).join(", ")}`);
@@ -117,7 +129,6 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict})
117
129
  const content = templater({
118
130
  collections,
119
131
  strict,
120
- path: rawOutputDirectory ?? '',
121
132
  ...templateHelpers,
122
133
  getType: meta.getType,
123
134
  });
@@ -126,12 +137,30 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict})
126
137
 
127
138
  fs.writeFileSync(destination, content);
128
139
  log(`Added types to ${destination}`);
140
+
141
+ // Generate client file if requested and language is TypeScript
142
+ if (includeClient && language === "ts") {
143
+ const clientMeta = new TypeScriptClient();
144
+ const clientTemplate = ejs.compile(clientMeta.getTemplate());
145
+ const clientContent = clientTemplate({
146
+ collections,
147
+ strict,
148
+ projectId: localConfig.getProject()['projectId'],
149
+ endpoint: localConfig.getEndpoint(),
150
+ ...templateHelpers,
151
+ typesFileName: meta.getFileName(),
152
+ });
153
+
154
+ const clientDestination = path.join(outputDirectory, clientMeta.getFileName());
155
+ fs.writeFileSync(clientDestination, clientContent);
156
+ log(`Added client to ${clientDestination}`);
157
+ }
129
158
  } else {
130
159
  for (const collection of collections) {
131
160
  const content = templater({
161
+ collections,
132
162
  collection,
133
163
  strict,
134
- path: rawOutputDirectory ?? '',
135
164
  ...templateHelpers,
136
165
  getType: meta.getType,
137
166
  });
@@ -141,6 +170,11 @@ const typesCommand = actionRunner(async (rawOutputDirectory, {language, strict})
141
170
  fs.writeFileSync(destination, content);
142
171
  log(`Added types for ${collection.name} to ${destination}`);
143
172
  }
173
+
174
+ // Client generation for multi-file languages not supported yet
175
+ if (includeClient) {
176
+ warn("Client generation for multi-file languages is not yet supported");
177
+ }
144
178
  }
145
179
 
146
180
  success(`Generated types for all the listed collections`);
@@ -151,6 +185,7 @@ const types = new Command("types")
151
185
  .addArgument(typesOutputArgument)
152
186
  .addOption(typesLanguageOption)
153
187
  .addOption(typesStrictOption)
188
+ .addOption(typesIncludeClientOption)
154
189
  .action(actionRunner(typesCommand));
155
190
 
156
191
  module.exports = { types };
@@ -7,7 +7,7 @@ const libClient = require('../client.js');
7
7
  const { getAllFiles, showConsoleLink } = require('../utils.js');
8
8
  const { Command } = require('commander');
9
9
  const { sdkForProject, sdkForConsole } = require('../sdks')
10
- const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
10
+ const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log, warn } = require('../parser')
11
11
  const { localConfig, globalConfig } = require("../config");
12
12
  const { File } = require('undici');
13
13
  const { ReadableStream } = require('stream/web');
@@ -7,7 +7,7 @@ const libClient = require('../client.js');
7
7
  const { getAllFiles, showConsoleLink } = require('../utils.js');
8
8
  const { Command } = require('commander');
9
9
  const { sdkForProject, sdkForConsole } = require('../sdks')
10
- const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log } = require('../parser')
10
+ const { parse, actionRunner, parseInteger, parseBool, commandDescriptions, success, log, warn } = require('../parser')
11
11
  const { localConfig, globalConfig } = require("../config");
12
12
  const { File } = require('undici');
13
13
  const { ReadableStream } = require('stream/web');
@@ -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() {
@@ -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,19 +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
86
  return `<% for (const attribute of collection.attributes) { -%>
87
87
  <% if (attribute.type === 'relationship') { -%>
88
- import '<%- toSnakeCase(attribute.relatedCollection) %>.dart';
88
+ import '<%- toSnakeCase(collections.find(c => c.$id === attribute.relatedCollection).name) %>.dart';
89
89
 
90
90
  <% } -%>
91
91
  <% } -%>
92
92
  /// This file is auto-generated by the Appwrite CLI.
93
- /// You can regenerate it by running \`appwrite types -l <%- strict ? '--strict ' : '' %>dart <%- path %>\`.
93
+ /// You can regenerate it by running \`appwrite ${process.argv.slice(2).join(' ')}\`.
94
94
 
95
95
  <% for (const attribute of collection.attributes) { -%>
96
96
  <% if (attribute.format === 'enum') { -%>
@@ -104,7 +104,7 @@ enum <%- toPascalCase(attribute.key) %> {
104
104
  <% } -%>
105
105
  class <%= toPascalCase(collection.name) %> {
106
106
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
107
- <%- getType(attribute) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
107
+ <%- getType(attribute, collections) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
108
108
  <% } -%>
109
109
 
110
110
  <%= toPascalCase(collection.name) %>({
@@ -152,11 +152,11 @@ map['<%= attribute.key %>']<% if (!attribute.required) { %> ?? null<% } -%>
152
152
  <% } -%>
153
153
  <% } else if (attribute.type === 'relationship') { -%>
154
154
  <% if ((attribute.relationType === 'oneToMany' && attribute.side === 'parent') || (attribute.relationType === 'manyToOne' && attribute.side === 'child') || attribute.relationType === 'manyToMany') { -%>
155
- (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) { %> ?? []<% } -%>
156
156
  <% } else { -%>
157
157
  <% if (!attribute.required) { -%>
158
- map['<%= attribute.key %>'] != null ? <%- toPascalCase(attribute.relatedCollection) %>.fromMap(map['<%= attribute.key %>']) : null<% } else { -%>
159
- <%- 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 %>'])<% } -%>
160
160
  <% } -%>
161
161
  <% } -%><% if (index < collection.attributes.length - 1) { %>,<% } %>
162
162
  <% } -%>
@@ -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,25 +42,21 @@ 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 <%- strict ? '--strict ' : '' %>java <%- path %>\`.
50
+ * You can regenerate it by running \`appwrite ${process.argv.slice(2).join(' ')}\`.
51
51
  */
52
52
 
53
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') { -%>
@@ -70,7 +70,7 @@ public class <%- toPascalCase(collection.name) %> {
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
76
  public <%- toPascalCase(collection.name) %>() {
@@ -78,7 +78,7 @@ public class <%- toPascalCase(collection.name) %> {
78
78
 
79
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) { -%>
@@ -87,11 +87,11 @@ public class <%- toPascalCase(collection.name) %> {
87
87
  }
88
88
 
89
89
  <% for (const attribute of collection.attributes) { -%>
90
- public <%- getType(attribute) %> get<%- toPascalCase(attribute.key) %>() {
90
+ public <%- getType(attribute, collections) %> get<%- toPascalCase(attribute.key) %>() {
91
91
  return <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
92
92
  }
93
93
 
94
- public void set<%- toPascalCase(attribute.key) %>(<%- getType(attribute) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>) {
94
+ public void set<%- toPascalCase(attribute.key) %>(<%- getType(attribute, collections) %> <%= strict ? toCamelCase(attribute.key) : attribute.key %>) {
95
95
  this.<%= strict ? toCamelCase(attribute.key) : attribute.key %> = <%= strict ? toCamelCase(attribute.key) : attribute.key %>;
96
96
  }
97
97
 
@@ -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
  }
@@ -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 <%- strict ? '--strict ' : '' %>js <%- path %>\`.
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,22 +45,18 @@ 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 <%- strict ? '--strict ' : '' %>kotlin <%- path %>\`.
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) { -%>
@@ -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 <%- strict ? '--strict ' : '' %>php <%- path %>\`.
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
  <% } -%>
@@ -70,15 +70,15 @@ 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
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
  ) {
@@ -88,17 +88,18 @@ class <%- toPascalCase(collection.name) %> {
88
88
  }
89
89
 
90
90
  <% for (const [index, attribute] of Object.entries(collection.attributes)) { -%>
91
- public function get<%- toPascalCase(attribute.key) %>(): <%- getType(attribute) %> {
91
+ public function get<%- toPascalCase(attribute.key) %>(): <%- getType(attribute, collections) %> {
92
92
  return $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %>;
93
93
  }
94
94
 
95
- public function set<%- toPascalCase(attribute.key) %>(<%- getType(attribute) %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %>): void {
95
+ public function set<%- toPascalCase(attribute.key) %>(<%- getType(attribute, collections) %> $<%- strict ? toCamelCase(attribute.key) : attribute.key %>): void {
96
96
  $this-><%- strict ? toCamelCase(attribute.key) : attribute.key %> = $<%- strict ? toCamelCase(attribute.key) : attribute.key %>;
97
97
  }
98
98
  <% if (index < collection.attributes.length - 1) { %>
99
99
  <% } -%>
100
100
  <% } -%>
101
- }`;
101
+ }
102
+ `;
102
103
  }
103
104
 
104
105
  getFileName(collection) {