appwrite-utils-cli 0.10.86 → 1.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.
Files changed (178) hide show
  1. package/.appwrite/.yaml_schemas/appwrite-config.schema.json +380 -0
  2. package/.appwrite/.yaml_schemas/collection.schema.json +255 -0
  3. package/.appwrite/collections/Categories.yaml +182 -0
  4. package/.appwrite/collections/ExampleCollection.yaml +36 -0
  5. package/.appwrite/collections/Posts.yaml +227 -0
  6. package/.appwrite/collections/Users.yaml +149 -0
  7. package/.appwrite/config.yaml +109 -0
  8. package/.appwrite/import/README.md +148 -0
  9. package/.appwrite/import/categories-import.yaml +129 -0
  10. package/.appwrite/import/posts-import.yaml +208 -0
  11. package/.appwrite/import/users-import.yaml +130 -0
  12. package/.appwrite/importData/categories.json +194 -0
  13. package/.appwrite/importData/posts.json +270 -0
  14. package/.appwrite/importData/users.json +220 -0
  15. package/.appwrite/schemas/categories.json +128 -0
  16. package/.appwrite/schemas/exampleCollection.json +52 -0
  17. package/.appwrite/schemas/posts.json +173 -0
  18. package/.appwrite/schemas/users.json +125 -0
  19. package/README.md +260 -33
  20. package/dist/collections/attributes.js +3 -2
  21. package/dist/collections/methods.js +56 -38
  22. package/dist/config/yamlConfig.d.ts +501 -0
  23. package/dist/config/yamlConfig.js +452 -0
  24. package/dist/databases/setup.d.ts +6 -0
  25. package/dist/databases/setup.js +119 -0
  26. package/dist/functions/methods.d.ts +1 -1
  27. package/dist/functions/methods.js +5 -2
  28. package/dist/functions/openapi.d.ts +4 -0
  29. package/dist/functions/openapi.js +60 -0
  30. package/dist/interactiveCLI.d.ts +5 -0
  31. package/dist/interactiveCLI.js +194 -49
  32. package/dist/main.js +91 -30
  33. package/dist/migrations/afterImportActions.js +2 -2
  34. package/dist/migrations/appwriteToX.d.ts +10 -0
  35. package/dist/migrations/appwriteToX.js +15 -4
  36. package/dist/migrations/backup.d.ts +16 -16
  37. package/dist/migrations/dataLoader.d.ts +83 -1
  38. package/dist/migrations/dataLoader.js +4 -4
  39. package/dist/migrations/importController.js +25 -18
  40. package/dist/migrations/importDataActions.js +2 -2
  41. package/dist/migrations/logging.d.ts +9 -1
  42. package/dist/migrations/logging.js +41 -22
  43. package/dist/migrations/migrationHelper.d.ts +4 -4
  44. package/dist/migrations/relationships.js +1 -1
  45. package/dist/migrations/services/DataTransformationService.d.ts +55 -0
  46. package/dist/migrations/services/DataTransformationService.js +158 -0
  47. package/dist/migrations/services/FileHandlerService.d.ts +75 -0
  48. package/dist/migrations/services/FileHandlerService.js +236 -0
  49. package/dist/migrations/services/ImportOrchestrator.d.ts +97 -0
  50. package/dist/migrations/services/ImportOrchestrator.js +488 -0
  51. package/dist/migrations/services/RateLimitManager.d.ts +138 -0
  52. package/dist/migrations/services/RateLimitManager.js +279 -0
  53. package/dist/migrations/services/RelationshipResolver.d.ts +120 -0
  54. package/dist/migrations/services/RelationshipResolver.js +332 -0
  55. package/dist/migrations/services/UserMappingService.d.ts +109 -0
  56. package/dist/migrations/services/UserMappingService.js +277 -0
  57. package/dist/migrations/services/ValidationService.d.ts +74 -0
  58. package/dist/migrations/services/ValidationService.js +260 -0
  59. package/dist/migrations/transfer.d.ts +0 -6
  60. package/dist/migrations/transfer.js +16 -132
  61. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +384 -0
  62. package/dist/migrations/yaml/YamlImportConfigLoader.js +375 -0
  63. package/dist/migrations/yaml/YamlImportIntegration.d.ts +87 -0
  64. package/dist/migrations/yaml/YamlImportIntegration.js +330 -0
  65. package/dist/migrations/yaml/generateImportSchemas.d.ts +17 -0
  66. package/dist/migrations/yaml/generateImportSchemas.js +575 -0
  67. package/dist/schemas/authUser.d.ts +9 -9
  68. package/dist/shared/attributeManager.d.ts +17 -0
  69. package/dist/shared/attributeManager.js +273 -0
  70. package/dist/shared/confirmationDialogs.d.ts +75 -0
  71. package/dist/shared/confirmationDialogs.js +236 -0
  72. package/dist/shared/functionManager.d.ts +48 -0
  73. package/dist/shared/functionManager.js +322 -0
  74. package/dist/shared/indexManager.d.ts +24 -0
  75. package/dist/shared/indexManager.js +150 -0
  76. package/dist/shared/jsonSchemaGenerator.d.ts +51 -0
  77. package/dist/shared/jsonSchemaGenerator.js +313 -0
  78. package/dist/shared/logging.d.ts +10 -0
  79. package/dist/shared/logging.js +46 -0
  80. package/dist/shared/messageFormatter.d.ts +37 -0
  81. package/dist/shared/messageFormatter.js +152 -0
  82. package/dist/shared/migrationHelpers.d.ts +173 -0
  83. package/dist/shared/migrationHelpers.js +142 -0
  84. package/dist/shared/operationLogger.d.ts +3 -0
  85. package/dist/shared/operationLogger.js +25 -0
  86. package/dist/shared/operationQueue.d.ts +13 -0
  87. package/dist/shared/operationQueue.js +79 -0
  88. package/dist/shared/progressManager.d.ts +62 -0
  89. package/dist/shared/progressManager.js +215 -0
  90. package/dist/shared/schemaGenerator.d.ts +18 -0
  91. package/dist/shared/schemaGenerator.js +523 -0
  92. package/dist/storage/methods.d.ts +3 -1
  93. package/dist/storage/methods.js +144 -55
  94. package/dist/storage/schemas.d.ts +56 -16
  95. package/dist/types.d.ts +2 -2
  96. package/dist/types.js +1 -1
  97. package/dist/users/methods.d.ts +16 -0
  98. package/dist/users/methods.js +276 -0
  99. package/dist/utils/configMigration.d.ts +1 -0
  100. package/dist/utils/configMigration.js +156 -0
  101. package/dist/utils/dataConverters.d.ts +46 -0
  102. package/dist/utils/dataConverters.js +139 -0
  103. package/dist/utils/loadConfigs.d.ts +15 -4
  104. package/dist/utils/loadConfigs.js +377 -51
  105. package/dist/utils/schemaStrings.js +2 -1
  106. package/dist/utils/setupFiles.d.ts +2 -1
  107. package/dist/utils/setupFiles.js +723 -28
  108. package/dist/utils/validationRules.d.ts +43 -0
  109. package/dist/utils/validationRules.js +42 -0
  110. package/dist/utils/yamlConverter.d.ts +48 -0
  111. package/dist/utils/yamlConverter.js +98 -0
  112. package/dist/utilsController.js +65 -43
  113. package/package.json +19 -15
  114. package/src/collections/attributes.ts +3 -2
  115. package/src/collections/methods.ts +85 -51
  116. package/src/config/yamlConfig.ts +488 -0
  117. package/src/{migrations/setupDatabase.ts → databases/setup.ts} +11 -5
  118. package/src/functions/methods.ts +8 -4
  119. package/src/functions/templates/count-docs-in-collection/package.json +25 -0
  120. package/src/functions/templates/count-docs-in-collection/tsconfig.json +28 -0
  121. package/src/functions/templates/typescript-node/package.json +24 -0
  122. package/src/functions/templates/typescript-node/tsconfig.json +28 -0
  123. package/src/functions/templates/uv/README.md +31 -0
  124. package/src/functions/templates/uv/pyproject.toml +29 -0
  125. package/src/interactiveCLI.ts +226 -61
  126. package/src/main.ts +111 -37
  127. package/src/migrations/afterImportActions.ts +2 -2
  128. package/src/migrations/appwriteToX.ts +17 -4
  129. package/src/migrations/dataLoader.ts +4 -4
  130. package/src/migrations/importController.ts +30 -22
  131. package/src/migrations/importDataActions.ts +2 -2
  132. package/src/migrations/relationships.ts +1 -1
  133. package/src/migrations/services/DataTransformationService.ts +196 -0
  134. package/src/migrations/services/FileHandlerService.ts +311 -0
  135. package/src/migrations/services/ImportOrchestrator.ts +669 -0
  136. package/src/migrations/services/RateLimitManager.ts +363 -0
  137. package/src/migrations/services/RelationshipResolver.ts +461 -0
  138. package/src/migrations/services/UserMappingService.ts +345 -0
  139. package/src/migrations/services/ValidationService.ts +349 -0
  140. package/src/migrations/transfer.ts +22 -228
  141. package/src/migrations/yaml/YamlImportConfigLoader.ts +427 -0
  142. package/src/migrations/yaml/YamlImportIntegration.ts +419 -0
  143. package/src/migrations/yaml/generateImportSchemas.ts +589 -0
  144. package/src/shared/attributeManager.ts +429 -0
  145. package/src/shared/confirmationDialogs.ts +327 -0
  146. package/src/shared/functionManager.ts +515 -0
  147. package/src/shared/indexManager.ts +253 -0
  148. package/src/shared/jsonSchemaGenerator.ts +403 -0
  149. package/src/shared/logging.ts +74 -0
  150. package/src/shared/messageFormatter.ts +195 -0
  151. package/src/{migrations/migrationHelper.ts → shared/migrationHelpers.ts} +22 -4
  152. package/src/{migrations/helper.ts → shared/operationLogger.ts} +7 -2
  153. package/src/{migrations/queue.ts → shared/operationQueue.ts} +1 -1
  154. package/src/shared/progressManager.ts +278 -0
  155. package/src/{migrations/schemaStrings.ts → shared/schemaGenerator.ts} +71 -17
  156. package/src/storage/methods.ts +199 -78
  157. package/src/types.ts +2 -2
  158. package/src/{migrations/users.ts → users/methods.ts} +2 -2
  159. package/src/utils/configMigration.ts +212 -0
  160. package/src/utils/loadConfigs.ts +414 -52
  161. package/src/utils/schemaStrings.ts +2 -1
  162. package/src/utils/setupFiles.ts +742 -40
  163. package/src/{migrations → utils}/validationRules.ts +1 -1
  164. package/src/utils/yamlConverter.ts +131 -0
  165. package/src/utilsController.ts +75 -54
  166. package/src/functions/templates/poetry/README.md +0 -30
  167. package/src/functions/templates/poetry/pyproject.toml +0 -16
  168. package/src/migrations/attributes.ts +0 -561
  169. package/src/migrations/backup.ts +0 -205
  170. package/src/migrations/databases.ts +0 -39
  171. package/src/migrations/dbHelpers.ts +0 -92
  172. package/src/migrations/indexes.ts +0 -40
  173. package/src/migrations/logging.ts +0 -29
  174. package/src/migrations/storage.ts +0 -538
  175. /package/src/{migrations → functions}/openapi.ts +0 -0
  176. /package/src/functions/templates/{poetry → uv}/src/__init__.py +0 -0
  177. /package/src/functions/templates/{poetry → uv}/src/index.py +0 -0
  178. /package/src/{migrations/converters.ts → utils/dataConverters.ts} +0 -0
@@ -0,0 +1,523 @@
1
+ import { toCamelCase, toPascalCase } from "../utils/index.js";
2
+ import { z } from "zod";
3
+ import fs from "fs";
4
+ import path from "path";
5
+ import { dump } from "js-yaml";
6
+ import { getDatabaseFromConfig } from "../migrations/afterImportActions.js";
7
+ import { ulid } from "ulidx";
8
+ import { JsonSchemaGenerator } from "./jsonSchemaGenerator.js";
9
+ import { collectionToYaml, getCollectionYamlFilename } from "../utils/yamlConverter.js";
10
+ export class SchemaGenerator {
11
+ relationshipMap = new Map();
12
+ config;
13
+ appwriteFolderPath;
14
+ constructor(config, appwriteFolderPath) {
15
+ this.config = config;
16
+ this.appwriteFolderPath = appwriteFolderPath;
17
+ this.extractRelationships();
18
+ }
19
+ updateYamlCollections() {
20
+ const collections = this.config.collections;
21
+ delete this.config.collections;
22
+ const collectionsDir = path.join(this.appwriteFolderPath, "collections");
23
+ if (!fs.existsSync(collectionsDir)) {
24
+ fs.mkdirSync(collectionsDir, { recursive: true });
25
+ }
26
+ collections?.forEach((collection) => {
27
+ // Determine schema path based on config
28
+ const schemaDir = this.config.schemaConfig?.yamlSchemaDirectory || ".yaml_schemas";
29
+ const schemaPath = `../${schemaDir}/collection.schema.json`;
30
+ const yamlContent = collectionToYaml(collection, schemaPath);
31
+ const filename = getCollectionYamlFilename(collection);
32
+ const filePath = path.join(collectionsDir, filename);
33
+ fs.writeFileSync(filePath, yamlContent, { encoding: "utf-8" });
34
+ console.log(`Collection YAML written to ${filePath}`);
35
+ });
36
+ }
37
+ updateTsSchemas() {
38
+ const collections = this.config.collections;
39
+ const functions = this.config.functions || [];
40
+ delete this.config.collections;
41
+ delete this.config.functions;
42
+ const configPath = path.join(this.appwriteFolderPath, "appwriteConfig.ts");
43
+ const configContent = `import { type AppwriteConfig } from "appwrite-utils";
44
+
45
+ const appwriteConfig: AppwriteConfig = {
46
+ appwriteEndpoint: "${this.config.appwriteEndpoint}",
47
+ appwriteProject: "${this.config.appwriteProject}",
48
+ appwriteKey: "${this.config.appwriteKey}",
49
+ enableBackups: ${this.config.enableBackups},
50
+ backupInterval: ${this.config.backupInterval},
51
+ backupRetention: ${this.config.backupRetention},
52
+ enableBackupCleanup: ${this.config.enableBackupCleanup},
53
+ enableMockData: ${this.config.enableMockData},
54
+ documentBucketId: "${this.config.documentBucketId}",
55
+ usersCollectionName: "${this.config.usersCollectionName}",
56
+ databases: ${JSON.stringify(this.config.databases, null, 4)},
57
+ buckets: ${JSON.stringify(this.config.buckets, null, 4)},
58
+ functions: ${JSON.stringify(functions.map((func) => ({
59
+ functionId: func.$id || ulid(),
60
+ name: func.name,
61
+ runtime: func.runtime,
62
+ path: func.dirPath || `functions/${func.name}`,
63
+ entrypoint: func.entrypoint || "src/index.ts",
64
+ execute: func.execute,
65
+ events: func.events || [],
66
+ schedule: func.schedule || "",
67
+ timeout: func.timeout || 15,
68
+ enabled: func.enabled !== false,
69
+ logging: func.logging !== false,
70
+ commands: func.commands || "npm install",
71
+ scopes: func.scopes || [],
72
+ installationId: func.installationId,
73
+ providerRepositoryId: func.providerRepositoryId,
74
+ providerBranch: func.providerBranch,
75
+ providerSilentMode: func.providerSilentMode,
76
+ providerRootDirectory: func.providerRootDirectory,
77
+ specification: func.specification,
78
+ ...(func.predeployCommands
79
+ ? { predeployCommands: func.predeployCommands }
80
+ : {}),
81
+ ...(func.deployDir ? { deployDir: func.deployDir } : {}),
82
+ })), null, 4)}
83
+ };
84
+
85
+ export default appwriteConfig;
86
+ `;
87
+ fs.writeFileSync(configPath, configContent, { encoding: "utf-8" });
88
+ const collectionsFolderPath = path.join(this.appwriteFolderPath, "collections");
89
+ if (!fs.existsSync(collectionsFolderPath)) {
90
+ fs.mkdirSync(collectionsFolderPath, { recursive: true });
91
+ }
92
+ collections?.forEach((collection) => {
93
+ const { databaseId, ...collectionWithoutDbId } = collection; // Destructure to exclude databaseId
94
+ const collectionFilePath = path.join(collectionsFolderPath, `${collection.name}.ts`);
95
+ const collectionContent = `import { type CollectionCreate } from "appwrite-utils";
96
+
97
+ const ${collection.name}Config: Partial<CollectionCreate> = {
98
+ name: "${collection.name}",
99
+ $id: "${collection.$id}",
100
+ enabled: ${collection.enabled},
101
+ documentSecurity: ${collection.documentSecurity},
102
+ $permissions: [
103
+ ${collection.$permissions
104
+ .map((permission) => `{ permission: "${permission.permission}", target: "${permission.target}" }`)
105
+ .join(",\n ")}
106
+ ],
107
+ attributes: [
108
+ ${collection.attributes
109
+ .map((attr) => {
110
+ return `{ ${Object.entries(attr)
111
+ .map(([key, value]) => {
112
+ // Check the type of the value and format it accordingly
113
+ if (typeof value === "string") {
114
+ // If the value is a string, wrap it in quotes
115
+ return `${key}: "${value.replace(/"/g, '\\"')}"`; // Escape existing quotes in the string
116
+ }
117
+ else if (Array.isArray(value)) {
118
+ // If the value is an array, join it with commas
119
+ if (value.length > 0) {
120
+ return `${key}: [${value
121
+ .map((item) => `"${item}"`)
122
+ .join(", ")}]`;
123
+ }
124
+ else {
125
+ return `${key}: []`;
126
+ }
127
+ }
128
+ else {
129
+ // If the value is not a string (e.g., boolean or number), output it directly
130
+ return `${key}: ${value}`;
131
+ }
132
+ })
133
+ .join(", ")} }`;
134
+ })
135
+ .join(",\n ")}
136
+ ],
137
+ indexes: [
138
+ ${(collection.indexes?.map((index) => {
139
+ // Map each attribute to ensure it is properly quoted
140
+ const formattedAttributes = index.attributes.map((attr) => `"${attr}"`).join(", ") ?? "";
141
+ return `{ key: "${index.key}", type: "${index.type}", attributes: [${formattedAttributes}], orders: [${index.orders
142
+ ?.filter((order) => order !== null)
143
+ .map((order) => `"${order}"`)
144
+ .join(", ") ?? ""}] }`;
145
+ }) ?? []).join(",\n ")}
146
+ ]
147
+ };
148
+
149
+ export default ${collection.name}Config;
150
+ `;
151
+ fs.writeFileSync(collectionFilePath, collectionContent, {
152
+ encoding: "utf-8",
153
+ });
154
+ console.log(`Collection schema written to ${collectionFilePath}`);
155
+ });
156
+ }
157
+ updateConfig(config) {
158
+ const configPath = path.join(this.appwriteFolderPath, "appwriteConfig.ts");
159
+ const configContent = `import { type AppwriteConfig } from "appwrite-utils";
160
+
161
+ const appwriteConfig: AppwriteConfig = {
162
+ appwriteEndpoint: "${config.appwriteEndpoint}",
163
+ appwriteProject: "${config.appwriteProject}",
164
+ appwriteKey: "${config.appwriteKey}",
165
+ enableBackups: ${config.enableBackups},
166
+ backupInterval: ${config.backupInterval},
167
+ backupRetention: ${config.backupRetention},
168
+ enableBackupCleanup: ${config.enableBackupCleanup},
169
+ enableMockData: ${config.enableMockData},
170
+ documentBucketId: "${config.documentBucketId}",
171
+ usersCollectionName: "${config.usersCollectionName}",
172
+ databases: ${JSON.stringify(config.databases, null, 4)},
173
+ buckets: ${JSON.stringify(config.buckets, null, 4)},
174
+ functions: ${JSON.stringify(config.functions?.map((func) => ({
175
+ $id: func.$id || ulid(),
176
+ name: func.name,
177
+ runtime: func.runtime,
178
+ dirPath: func.dirPath || `functions/${func.name}`,
179
+ entrypoint: func.entrypoint || "src/index.ts",
180
+ execute: func.execute || [],
181
+ events: func.events || [],
182
+ schedule: func.schedule || "",
183
+ timeout: func.timeout || 15,
184
+ enabled: func.enabled !== false,
185
+ logging: func.logging !== false,
186
+ commands: func.commands || "npm install",
187
+ scopes: func.scopes || [],
188
+ installationId: func.installationId,
189
+ providerRepositoryId: func.providerRepositoryId,
190
+ providerBranch: func.providerBranch,
191
+ providerSilentMode: func.providerSilentMode,
192
+ providerRootDirectory: func.providerRootDirectory,
193
+ specification: func.specification,
194
+ })), null, 4)}
195
+ };
196
+
197
+ export default appwriteConfig;
198
+ `;
199
+ fs.writeFileSync(configPath, configContent, { encoding: "utf-8" });
200
+ }
201
+ extractRelationships() {
202
+ if (!this.config.collections) {
203
+ return;
204
+ }
205
+ this.config.collections.forEach((collection) => {
206
+ if (!collection.attributes) {
207
+ return;
208
+ }
209
+ collection.attributes.forEach((attr) => {
210
+ if (attr.type === "relationship" && attr.twoWay && attr.twoWayKey) {
211
+ const relationshipAttr = attr;
212
+ let isArrayParent = false;
213
+ let isArrayChild = false;
214
+ switch (relationshipAttr.relationType) {
215
+ case "oneToMany":
216
+ isArrayParent = true;
217
+ isArrayChild = false;
218
+ break;
219
+ case "manyToMany":
220
+ isArrayParent = true;
221
+ isArrayChild = true;
222
+ break;
223
+ case "oneToOne":
224
+ isArrayParent = false;
225
+ isArrayChild = false;
226
+ break;
227
+ case "manyToOne":
228
+ isArrayParent = false;
229
+ isArrayChild = true;
230
+ break;
231
+ default:
232
+ break;
233
+ }
234
+ this.addRelationship(collection.name, relationshipAttr.relatedCollection, attr.key, relationshipAttr.twoWayKey, isArrayParent, isArrayChild);
235
+ console.log(`Extracted relationship: ${attr.key}\n\t${collection.name} -> ${relationshipAttr.relatedCollection}, databaseId: ${collection.databaseId}`);
236
+ }
237
+ });
238
+ });
239
+ }
240
+ addRelationship(parentCollection, childCollection, parentKey, childKey, isArrayParent, isArrayChild) {
241
+ const relationshipsChild = this.relationshipMap.get(childCollection) || [];
242
+ const relationshipsParent = this.relationshipMap.get(parentCollection) || [];
243
+ relationshipsParent.push({
244
+ parentCollection,
245
+ childCollection,
246
+ parentKey,
247
+ childKey,
248
+ isArray: isArrayParent,
249
+ isChild: false,
250
+ });
251
+ relationshipsChild.push({
252
+ parentCollection,
253
+ childCollection,
254
+ parentKey,
255
+ childKey,
256
+ isArray: isArrayChild,
257
+ isChild: true,
258
+ });
259
+ this.relationshipMap.set(childCollection, relationshipsChild);
260
+ this.relationshipMap.set(parentCollection, relationshipsParent);
261
+ }
262
+ generateSchemas(options = {}) {
263
+ const { format = "both", verbose = false } = options;
264
+ if (!this.config.collections) {
265
+ return;
266
+ }
267
+ // Create schemas directory using config setting
268
+ const outputDir = this.config.schemaConfig?.outputDirectory || "schemas";
269
+ const schemasPath = path.join(this.appwriteFolderPath, outputDir);
270
+ if (!fs.existsSync(schemasPath)) {
271
+ fs.mkdirSync(schemasPath, { recursive: true });
272
+ }
273
+ // Generate Zod schemas (TypeScript)
274
+ if (format === "zod" || format === "both") {
275
+ this.config.collections.forEach((collection) => {
276
+ const schemaString = this.createSchemaString(collection.name, collection.attributes || []);
277
+ const camelCaseName = toCamelCase(collection.name);
278
+ const schemaPath = path.join(schemasPath, `${camelCaseName}.ts`);
279
+ fs.writeFileSync(schemaPath, schemaString, { encoding: "utf-8" });
280
+ if (verbose) {
281
+ console.log(`Zod schema written to ${schemaPath}`);
282
+ }
283
+ });
284
+ }
285
+ // Generate JSON schemas (all at once)
286
+ if (format === "json" || format === "both") {
287
+ const jsonSchemaGenerator = new JsonSchemaGenerator(this.config, this.appwriteFolderPath);
288
+ jsonSchemaGenerator.generateJsonSchemas({
289
+ outputFormat: format === "json" ? "json" : "both",
290
+ outputDirectory: outputDir,
291
+ verbose: verbose
292
+ });
293
+ }
294
+ if (verbose) {
295
+ console.log(`✓ Schema generation completed (format: ${format})`);
296
+ }
297
+ }
298
+ createSchemaString = (name, attributes) => {
299
+ const pascalName = toPascalCase(name);
300
+ let imports = `import { z } from "zod";\n`;
301
+ const hasDescription = attributes.some((attr) => attr.description);
302
+ if (hasDescription) {
303
+ imports += `import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";\n`;
304
+ imports += `extendZodWithOpenApi(z);\n`;
305
+ }
306
+ // Use the relationshipMap to find related collections
307
+ const relationshipDetails = this.relationshipMap.get(name) || [];
308
+ const relatedCollections = relationshipDetails
309
+ .filter((detail, index, self) => {
310
+ const uniqueKey = `${detail.parentCollection}-${detail.childCollection}-${detail.parentKey}-${detail.childKey}`;
311
+ return (index ===
312
+ self.findIndex((obj) => `${obj.parentCollection}-${obj.childCollection}-${obj.parentKey}-${obj.childKey}` ===
313
+ uniqueKey));
314
+ })
315
+ .map((detail) => {
316
+ const relatedCollectionName = detail.isChild
317
+ ? detail.parentCollection
318
+ : detail.childCollection;
319
+ const key = detail.isChild ? detail.childKey : detail.parentKey;
320
+ const isArray = detail.isArray ? "array" : "";
321
+ return [relatedCollectionName, key, isArray];
322
+ });
323
+ let relatedTypes = "";
324
+ let relatedTypesLazy = "";
325
+ let curNum = 0;
326
+ let maxNum = relatedCollections.length;
327
+ relatedCollections.forEach((relatedCollection) => {
328
+ console.log(relatedCollection);
329
+ let relatedPascalName = toPascalCase(relatedCollection[0]);
330
+ let relatedCamelName = toCamelCase(relatedCollection[0]);
331
+ curNum++;
332
+ let endNameTypes = relatedPascalName;
333
+ let endNameLazy = `${relatedPascalName}Schema`;
334
+ if (relatedCollection[2] === "array") {
335
+ endNameTypes += "[]";
336
+ endNameLazy += ".array().default([])";
337
+ }
338
+ else if (!(relatedCollection[2] === "array")) {
339
+ endNameTypes += " | null";
340
+ endNameLazy += ".nullish()";
341
+ }
342
+ imports += `import { ${relatedPascalName}Schema, type ${relatedPascalName} } from "./${relatedCamelName}";\n`;
343
+ relatedTypes += `${relatedCollection[1]}?: ${endNameTypes};\n`;
344
+ if (relatedTypes.length > 0 && curNum !== maxNum) {
345
+ relatedTypes += " ";
346
+ }
347
+ relatedTypesLazy += `${relatedCollection[1]}: z.lazy(() => ${endNameLazy}),\n`;
348
+ if (relatedTypesLazy.length > 0 && curNum !== maxNum) {
349
+ relatedTypesLazy += " ";
350
+ }
351
+ });
352
+ let schemaString = `${imports}\n\n`;
353
+ schemaString += `export const ${pascalName}SchemaBase = z.object({\n`;
354
+ schemaString += ` $id: z.string().optional(),\n`;
355
+ schemaString += ` $createdAt: z.string().optional(),\n`;
356
+ schemaString += ` $updatedAt: z.string().optional(),\n`;
357
+ for (const attribute of attributes) {
358
+ if (attribute.type === "relationship") {
359
+ continue;
360
+ }
361
+ schemaString += ` ${attribute.key}: ${this.typeToZod(attribute)},\n`;
362
+ }
363
+ schemaString += `});\n\n`;
364
+ schemaString += `export type ${pascalName}Base = z.infer<typeof ${pascalName}SchemaBase>`;
365
+ if (relatedTypes.length > 0) {
366
+ schemaString += ` & {\n ${relatedTypes}};\n\n`;
367
+ }
368
+ else {
369
+ schemaString += `;\n\n`;
370
+ }
371
+ schemaString += `export const ${pascalName}Schema: z.ZodType<${pascalName}Base> = ${pascalName}SchemaBase`;
372
+ if (relatedTypes.length > 0) {
373
+ schemaString += `.extend({\n ${relatedTypesLazy}});\n\n`;
374
+ }
375
+ else {
376
+ schemaString += `;\n`;
377
+ }
378
+ schemaString += `export type ${pascalName} = z.infer<typeof ${pascalName}Schema>;\n\n`;
379
+ return schemaString;
380
+ };
381
+ typeToZod = (attribute) => {
382
+ let baseSchemaCode = "";
383
+ const finalAttribute = (attribute.type === "string" &&
384
+ attribute.format &&
385
+ attribute.format === "enum" &&
386
+ attribute.type === "string"
387
+ ? { ...attribute, type: attribute.format }
388
+ : attribute);
389
+ switch (finalAttribute.type) {
390
+ case "string":
391
+ baseSchemaCode = "z.string()";
392
+ if (finalAttribute.size) {
393
+ baseSchemaCode += `.max(${finalAttribute.size}, "Maximum length of ${finalAttribute.size} characters exceeded")`;
394
+ }
395
+ if (finalAttribute.xdefault !== undefined) {
396
+ baseSchemaCode += `.default("${finalAttribute.xdefault}")`;
397
+ }
398
+ if (!attribute.required && !attribute.array) {
399
+ baseSchemaCode += ".nullish()";
400
+ }
401
+ break;
402
+ case "integer":
403
+ baseSchemaCode = "z.number().int()";
404
+ if (finalAttribute.min !== undefined) {
405
+ if (BigInt(finalAttribute.min) === BigInt(-9223372036854776000)) {
406
+ delete finalAttribute.min;
407
+ }
408
+ else {
409
+ baseSchemaCode += `.min(${finalAttribute.min}, "Minimum value of ${finalAttribute.min} not met")`;
410
+ }
411
+ }
412
+ if (finalAttribute.max !== undefined) {
413
+ if (BigInt(finalAttribute.max) === BigInt(9223372036854776000)) {
414
+ delete finalAttribute.max;
415
+ }
416
+ else {
417
+ baseSchemaCode += `.max(${finalAttribute.max}, "Maximum value of ${finalAttribute.max} exceeded")`;
418
+ }
419
+ }
420
+ if (finalAttribute.xdefault !== undefined) {
421
+ baseSchemaCode += `.default(${finalAttribute.xdefault})`;
422
+ }
423
+ if (!finalAttribute.required && !finalAttribute.array) {
424
+ baseSchemaCode += ".nullish()";
425
+ }
426
+ break;
427
+ case "double":
428
+ case "float": // Backward compatibility
429
+ baseSchemaCode = "z.number()";
430
+ if (finalAttribute.min !== undefined) {
431
+ baseSchemaCode += `.min(${finalAttribute.min}, "Minimum value of ${finalAttribute.min} not met")`;
432
+ }
433
+ if (finalAttribute.max !== undefined) {
434
+ baseSchemaCode += `.max(${finalAttribute.max}, "Maximum value of ${finalAttribute.max} exceeded")`;
435
+ }
436
+ if (finalAttribute.xdefault !== undefined) {
437
+ baseSchemaCode += `.default(${finalAttribute.xdefault})`;
438
+ }
439
+ if (!finalAttribute.required && !finalAttribute.array) {
440
+ baseSchemaCode += ".nullish()";
441
+ }
442
+ break;
443
+ case "boolean":
444
+ baseSchemaCode = "z.boolean()";
445
+ if (finalAttribute.xdefault !== undefined) {
446
+ baseSchemaCode += `.default(${finalAttribute.xdefault})`;
447
+ }
448
+ if (!finalAttribute.required && !finalAttribute.array) {
449
+ baseSchemaCode += ".nullish()";
450
+ }
451
+ break;
452
+ case "datetime":
453
+ baseSchemaCode = "z.date()";
454
+ if (finalAttribute.xdefault !== undefined) {
455
+ baseSchemaCode += `.default(new Date("${finalAttribute.xdefault}"))`;
456
+ }
457
+ if (!finalAttribute.required && !finalAttribute.array) {
458
+ baseSchemaCode += ".nullish()";
459
+ }
460
+ break;
461
+ case "email":
462
+ baseSchemaCode = "z.string().email()";
463
+ if (finalAttribute.xdefault !== undefined) {
464
+ baseSchemaCode += `.default("${finalAttribute.xdefault}")`;
465
+ }
466
+ if (!finalAttribute.required && !finalAttribute.array) {
467
+ baseSchemaCode += ".nullish()";
468
+ }
469
+ break;
470
+ case "ip":
471
+ baseSchemaCode = "z.string()"; // Add custom validation as needed
472
+ if (finalAttribute.xdefault !== undefined) {
473
+ baseSchemaCode += `.default("${finalAttribute.xdefault}")`;
474
+ }
475
+ if (!finalAttribute.required && !finalAttribute.array) {
476
+ baseSchemaCode += ".nullish()";
477
+ }
478
+ break;
479
+ case "url":
480
+ baseSchemaCode = "z.string().url()";
481
+ if (finalAttribute.xdefault !== undefined) {
482
+ baseSchemaCode += `.default("${finalAttribute.xdefault}")`;
483
+ }
484
+ if (!finalAttribute.required && !finalAttribute.array) {
485
+ baseSchemaCode += ".nullish()";
486
+ }
487
+ break;
488
+ case "enum":
489
+ baseSchemaCode = `z.enum([${finalAttribute.elements
490
+ .map((element) => `"${element}"`)
491
+ .join(", ")}])`;
492
+ if (finalAttribute.xdefault !== undefined) {
493
+ baseSchemaCode += `.default("${finalAttribute.xdefault}")`;
494
+ }
495
+ if (!attribute.required && !attribute.array) {
496
+ baseSchemaCode += ".nullish()";
497
+ }
498
+ break;
499
+ case "relationship":
500
+ break;
501
+ default:
502
+ baseSchemaCode = "z.any()";
503
+ }
504
+ // Handle arrays
505
+ if (attribute.array) {
506
+ baseSchemaCode = `z.array(${baseSchemaCode})`;
507
+ }
508
+ if (attribute.array && !attribute.required) {
509
+ baseSchemaCode += ".nullish()";
510
+ }
511
+ if (attribute.description) {
512
+ if (typeof attribute.description === "string") {
513
+ baseSchemaCode += `.openapi({ description: "${attribute.description}" })`;
514
+ }
515
+ else {
516
+ baseSchemaCode += `.openapi(${Object.entries(attribute.description)
517
+ .map(([key, value]) => `"${key}": ${value}`)
518
+ .join(", ")})`;
519
+ }
520
+ }
521
+ return baseSchemaCode;
522
+ };
523
+ }
@@ -10,7 +10,9 @@ export declare const getFile: (storage: Storage, bucketId: string, fileId: strin
10
10
  export declare const listFiles: (storage: Storage, bucketId: string, queries?: string[], search?: string) => Promise<Models.FileList>;
11
11
  export declare const deleteFile: (storage: Storage, bucketId: string, fileId: string) => Promise<{}>;
12
12
  export declare const ensureDatabaseConfigBucketsExist: (storage: Storage, config: AppwriteConfig, databases?: Models.Database[]) => Promise<void>;
13
- export declare const wipeDocumentStorage: (storage: Storage, bucketId: string) => Promise<void>;
13
+ export declare const wipeDocumentStorage: (storage: Storage, bucketId: string, options?: {
14
+ skipConfirmation?: boolean;
15
+ }) => Promise<void>;
14
16
  export declare const initOrGetDocumentStorage: (storage: Storage, config: AppwriteConfig, dbId: string, bucketName?: string) => Promise<Models.Bucket>;
15
17
  export declare const initOrGetBackupStorage: (config: AppwriteConfig, storage: Storage) => Promise<Models.Bucket>;
16
18
  export declare const backupDatabase: (config: AppwriteConfig, database: Databases, databaseId: string, storage: Storage) => Promise<void>;