appwrite-utils-cli 0.0.286 → 0.9.2

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 (109) hide show
  1. package/README.md +162 -96
  2. package/dist/collections/attributes.d.ts +4 -0
  3. package/dist/collections/attributes.js +224 -0
  4. package/dist/collections/indexes.d.ts +4 -0
  5. package/dist/collections/indexes.js +27 -0
  6. package/dist/collections/methods.d.ts +16 -0
  7. package/dist/collections/methods.js +216 -0
  8. package/dist/databases/methods.d.ts +6 -0
  9. package/dist/databases/methods.js +33 -0
  10. package/dist/interactiveCLI.d.ts +19 -0
  11. package/dist/interactiveCLI.js +555 -0
  12. package/dist/main.js +224 -62
  13. package/dist/migrations/afterImportActions.js +37 -40
  14. package/dist/migrations/appwriteToX.d.ts +26 -25
  15. package/dist/migrations/appwriteToX.js +42 -6
  16. package/dist/migrations/attributes.js +21 -20
  17. package/dist/migrations/backup.d.ts +93 -87
  18. package/dist/migrations/collections.d.ts +6 -0
  19. package/dist/migrations/collections.js +149 -20
  20. package/dist/migrations/converters.d.ts +2 -18
  21. package/dist/migrations/converters.js +13 -2
  22. package/dist/migrations/dataLoader.d.ts +276 -161
  23. package/dist/migrations/dataLoader.js +535 -292
  24. package/dist/migrations/databases.js +8 -2
  25. package/dist/migrations/helper.d.ts +3 -0
  26. package/dist/migrations/helper.js +21 -0
  27. package/dist/migrations/importController.d.ts +5 -2
  28. package/dist/migrations/importController.js +125 -88
  29. package/dist/migrations/importDataActions.d.ts +9 -1
  30. package/dist/migrations/importDataActions.js +15 -3
  31. package/dist/migrations/indexes.js +3 -2
  32. package/dist/migrations/logging.js +20 -8
  33. package/dist/migrations/migrationHelper.d.ts +9 -4
  34. package/dist/migrations/migrationHelper.js +6 -5
  35. package/dist/migrations/openapi.d.ts +1 -1
  36. package/dist/migrations/openapi.js +33 -18
  37. package/dist/migrations/queue.js +3 -2
  38. package/dist/migrations/relationships.d.ts +2 -2
  39. package/dist/migrations/schemaStrings.js +53 -41
  40. package/dist/migrations/setupDatabase.d.ts +2 -4
  41. package/dist/migrations/setupDatabase.js +24 -105
  42. package/dist/migrations/storage.d.ts +3 -1
  43. package/dist/migrations/storage.js +110 -16
  44. package/dist/migrations/transfer.d.ts +30 -0
  45. package/dist/migrations/transfer.js +337 -0
  46. package/dist/migrations/users.d.ts +2 -1
  47. package/dist/migrations/users.js +78 -43
  48. package/dist/schemas/authUser.d.ts +2 -2
  49. package/dist/storage/methods.d.ts +15 -0
  50. package/dist/storage/methods.js +207 -0
  51. package/dist/storage/schemas.d.ts +687 -0
  52. package/dist/storage/schemas.js +175 -0
  53. package/dist/utils/getClientFromConfig.d.ts +4 -0
  54. package/dist/utils/getClientFromConfig.js +16 -0
  55. package/dist/utils/helperFunctions.d.ts +11 -1
  56. package/dist/utils/helperFunctions.js +38 -0
  57. package/dist/utils/retryFailedPromises.d.ts +2 -0
  58. package/dist/utils/retryFailedPromises.js +21 -0
  59. package/dist/utils/schemaStrings.d.ts +13 -0
  60. package/dist/utils/schemaStrings.js +403 -0
  61. package/dist/utils/setupFiles.js +110 -61
  62. package/dist/utilsController.d.ts +40 -22
  63. package/dist/utilsController.js +164 -84
  64. package/package.json +13 -15
  65. package/src/collections/attributes.ts +483 -0
  66. package/src/collections/indexes.ts +53 -0
  67. package/src/collections/methods.ts +331 -0
  68. package/src/databases/methods.ts +47 -0
  69. package/src/init.ts +64 -64
  70. package/src/interactiveCLI.ts +767 -0
  71. package/src/main.ts +289 -83
  72. package/src/migrations/afterImportActions.ts +553 -490
  73. package/src/migrations/appwriteToX.ts +237 -174
  74. package/src/migrations/attributes.ts +483 -422
  75. package/src/migrations/backup.ts +205 -205
  76. package/src/migrations/collections.ts +545 -300
  77. package/src/migrations/converters.ts +161 -150
  78. package/src/migrations/dataLoader.ts +1615 -1304
  79. package/src/migrations/databases.ts +44 -25
  80. package/src/migrations/dbHelpers.ts +92 -92
  81. package/src/migrations/helper.ts +40 -0
  82. package/src/migrations/importController.ts +448 -384
  83. package/src/migrations/importDataActions.ts +315 -307
  84. package/src/migrations/indexes.ts +40 -37
  85. package/src/migrations/logging.ts +29 -16
  86. package/src/migrations/migrationHelper.ts +207 -201
  87. package/src/migrations/openapi.ts +83 -70
  88. package/src/migrations/queue.ts +118 -119
  89. package/src/migrations/relationships.ts +324 -324
  90. package/src/migrations/schemaStrings.ts +472 -460
  91. package/src/migrations/setupDatabase.ts +118 -219
  92. package/src/migrations/storage.ts +538 -358
  93. package/src/migrations/transfer.ts +608 -0
  94. package/src/migrations/users.ts +362 -285
  95. package/src/migrations/validationRules.ts +63 -63
  96. package/src/schemas/authUser.ts +23 -23
  97. package/src/setup.ts +8 -8
  98. package/src/storage/methods.ts +371 -0
  99. package/src/storage/schemas.ts +205 -0
  100. package/src/types.ts +9 -9
  101. package/src/utils/getClientFromConfig.ts +17 -0
  102. package/src/utils/helperFunctions.ts +181 -127
  103. package/src/utils/index.ts +2 -2
  104. package/src/utils/loadConfigs.ts +59 -59
  105. package/src/utils/retryFailedPromises.ts +27 -0
  106. package/src/utils/schemaStrings.ts +473 -0
  107. package/src/utils/setupFiles.ts +228 -182
  108. package/src/utilsController.ts +325 -194
  109. package/tsconfig.json +37 -37
@@ -0,0 +1,207 @@
1
+ import { Compression, Databases, Permission, Query, Role, Storage, } from "node-appwrite";
2
+ import { tryAwaitWithRetry } from "appwrite-utils";
3
+ import { getClientFromConfig } from "../utils/getClientFromConfig.js";
4
+ import { ulid } from "ulidx";
5
+ import { logOperation } from "../migrations/helper.js";
6
+ import { splitIntoBatches } from "../migrations/migrationHelper.js";
7
+ import { retryFailedPromises } from "../utils/retryFailedPromises.js";
8
+ import { InputFile } from "node-appwrite/file";
9
+ export const getStorage = (config) => {
10
+ const client = getClientFromConfig(config);
11
+ return new Storage(client);
12
+ };
13
+ export const listBuckets = async (storage, queries, search) => {
14
+ return await storage.listBuckets(queries, search);
15
+ };
16
+ export const getBucket = async (storage, bucketId) => {
17
+ return await storage.getBucket(bucketId);
18
+ };
19
+ export const createBucket = async (storage, bucket, bucketId) => {
20
+ return await storage.createBucket(bucketId ?? ulid(), bucket.name, bucket.$permissions, bucket.fileSecurity, bucket.enabled, bucket.maximumFileSize, bucket.allowedFileExtensions, bucket.compression, bucket.encryption, bucket.antivirus);
21
+ };
22
+ export const updateBucket = async (storage, bucket, bucketId) => {
23
+ return await storage.updateBucket(bucketId, bucket.name, bucket.$permissions, bucket.fileSecurity, bucket.enabled, bucket.maximumFileSize, bucket.allowedFileExtensions, bucket.compression, bucket.encryption, bucket.antivirus);
24
+ };
25
+ export const deleteBucket = async (storage, bucketId) => {
26
+ return await storage.deleteBucket(bucketId);
27
+ };
28
+ export const getFile = async (storage, bucketId, fileId) => {
29
+ return await storage.getFile(bucketId, fileId);
30
+ };
31
+ export const listFiles = async (storage, bucketId, queries, search) => {
32
+ return await storage.listFiles(bucketId, queries, search);
33
+ };
34
+ export const deleteFile = async (storage, bucketId, fileId) => {
35
+ return await storage.deleteFile(bucketId, fileId);
36
+ };
37
+ export const wipeDocumentStorage = async (storage, bucketId) => {
38
+ console.log(`Wiping storage for bucket ID: ${bucketId}`);
39
+ let moreFiles = true;
40
+ let lastFileId;
41
+ const allFiles = [];
42
+ while (moreFiles) {
43
+ const queries = [Query.limit(100)]; // Adjust the limit as needed
44
+ if (lastFileId) {
45
+ queries.push(Query.cursorAfter(lastFileId));
46
+ }
47
+ const filesPulled = await tryAwaitWithRetry(async () => await storage.listFiles(bucketId, queries));
48
+ if (filesPulled.files.length === 0) {
49
+ console.log("No files found, done!");
50
+ moreFiles = false;
51
+ break;
52
+ }
53
+ else if (filesPulled.files.length > 0) {
54
+ const fileIds = filesPulled.files.map((file) => file.$id);
55
+ allFiles.push(...fileIds);
56
+ }
57
+ moreFiles = filesPulled.files.length === 100; // Adjust based on the limit
58
+ if (moreFiles) {
59
+ lastFileId = filesPulled.files[filesPulled.files.length - 1].$id;
60
+ }
61
+ }
62
+ for (const fileId of allFiles) {
63
+ console.log(`Deleting file: ${fileId}`);
64
+ await tryAwaitWithRetry(async () => await storage.deleteFile(bucketId, fileId));
65
+ }
66
+ console.log(`All files in bucket ${bucketId} have been deleted.`);
67
+ };
68
+ export const initOrGetDocumentStorage = async (storage, config, dbId, bucketName) => {
69
+ const bucketId = bucketName ??
70
+ `${config.documentBucketId}_${dbId.toLowerCase().replace(" ", "")}`;
71
+ try {
72
+ return await tryAwaitWithRetry(async () => await storage.getBucket(bucketId));
73
+ }
74
+ catch (e) {
75
+ return await tryAwaitWithRetry(async () => await storage.createBucket(bucketId, `${dbId} Storage`, [
76
+ Permission.read(Role.any()),
77
+ Permission.create(Role.users()),
78
+ Permission.update(Role.users()),
79
+ Permission.delete(Role.users()),
80
+ ]));
81
+ }
82
+ };
83
+ export const initOrGetBackupStorage = async (config, storage) => {
84
+ try {
85
+ return await tryAwaitWithRetry(async () => await storage.getBucket("backup"));
86
+ }
87
+ catch (e) {
88
+ return await initOrGetDocumentStorage(storage, config, "backups", "Database Backups");
89
+ }
90
+ };
91
+ export const backupDatabase = async (config, database, databaseId, storage) => {
92
+ console.log("---------------------------------");
93
+ console.log("Starting Database Backup of " + databaseId);
94
+ console.log("---------------------------------");
95
+ let data = {
96
+ database: "",
97
+ collections: [],
98
+ documents: [],
99
+ };
100
+ const backupOperation = await logOperation(database, databaseId, {
101
+ operationType: "backup",
102
+ collectionId: "",
103
+ data: "Starting backup...",
104
+ progress: 0,
105
+ total: 100,
106
+ error: "",
107
+ status: "in_progress",
108
+ });
109
+ try {
110
+ const db = await tryAwaitWithRetry(async () => await database.get(databaseId));
111
+ data.database = JSON.stringify(db);
112
+ let lastCollectionId = "";
113
+ let moreCollections = true;
114
+ let progress = 0;
115
+ let total = 0;
116
+ while (moreCollections) {
117
+ const collectionResponse = await tryAwaitWithRetry(async () => await database.listCollections(databaseId, [
118
+ Query.limit(500),
119
+ ...(lastCollectionId ? [Query.cursorAfter(lastCollectionId)] : []),
120
+ ]));
121
+ total += collectionResponse.collections.length;
122
+ for (const { $id: collectionId, name: collectionName, } of collectionResponse.collections) {
123
+ try {
124
+ const collection = await tryAwaitWithRetry(async () => await database.getCollection(databaseId, collectionId));
125
+ progress++;
126
+ data.collections.push(JSON.stringify(collection));
127
+ let lastDocumentId = "";
128
+ let moreDocuments = true;
129
+ let collectionDocumentCount = 0;
130
+ while (moreDocuments) {
131
+ const documentResponse = await tryAwaitWithRetry(async () => await database.listDocuments(databaseId, collectionId, [
132
+ Query.limit(500),
133
+ ...(lastDocumentId
134
+ ? [Query.cursorAfter(lastDocumentId)]
135
+ : []),
136
+ ]));
137
+ total += documentResponse.documents.length;
138
+ collectionDocumentCount += documentResponse.documents.length;
139
+ const documentPromises = documentResponse.documents.map(({ $id: documentId }) => database.getDocument(databaseId, collectionId, documentId));
140
+ const promiseBatches = splitIntoBatches(documentPromises);
141
+ const documentsPulled = [];
142
+ for (const batch of promiseBatches) {
143
+ const successfulDocuments = await retryFailedPromises(batch);
144
+ documentsPulled.push(...successfulDocuments);
145
+ }
146
+ data.documents.push({
147
+ collectionId: collectionId,
148
+ data: JSON.stringify(documentsPulled),
149
+ });
150
+ progress += documentsPulled.length;
151
+ await logOperation(database, databaseId, {
152
+ operationType: "backup",
153
+ collectionId: collectionId,
154
+ data: `Backing up, ${data.collections.length} collections so far`,
155
+ progress: progress,
156
+ total: total,
157
+ error: "",
158
+ status: "in_progress",
159
+ }, backupOperation.$id);
160
+ moreDocuments = documentResponse.documents.length === 500;
161
+ if (moreDocuments) {
162
+ lastDocumentId =
163
+ documentResponse.documents[documentResponse.documents.length - 1].$id;
164
+ }
165
+ }
166
+ console.log(`Collection ${collectionName} backed up with ${collectionDocumentCount} documents.`);
167
+ }
168
+ catch (error) {
169
+ console.log(`Collection ${collectionName} must not exist, continuing...`);
170
+ continue;
171
+ }
172
+ }
173
+ moreCollections = collectionResponse.collections.length === 500;
174
+ if (moreCollections) {
175
+ lastCollectionId =
176
+ collectionResponse.collections[collectionResponse.collections.length - 1].$id;
177
+ }
178
+ }
179
+ const bucket = await initOrGetDocumentStorage(storage, config, databaseId);
180
+ const inputFile = InputFile.fromPlainText(JSON.stringify(data), `${new Date().toISOString()}-${databaseId}.json`);
181
+ const fileCreated = await storage.createFile(bucket.$id, ulid(), inputFile);
182
+ await logOperation(database, databaseId, {
183
+ operationType: "backup",
184
+ collectionId: "",
185
+ data: fileCreated.$id,
186
+ progress: 100,
187
+ total: total,
188
+ error: "",
189
+ status: "completed",
190
+ }, backupOperation.$id);
191
+ console.log("---------------------------------");
192
+ console.log("Database Backup Complete");
193
+ console.log("---------------------------------");
194
+ }
195
+ catch (error) {
196
+ console.error("Error during backup:", error);
197
+ await logOperation(database, databaseId, {
198
+ operationType: "backup",
199
+ collectionId: "",
200
+ data: "Backup failed",
201
+ progress: 0,
202
+ total: 100,
203
+ error: String(error),
204
+ status: "error",
205
+ }, backupOperation.$id);
206
+ }
207
+ };