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.
- package/README.md +162 -96
- package/dist/collections/attributes.d.ts +4 -0
- package/dist/collections/attributes.js +224 -0
- package/dist/collections/indexes.d.ts +4 -0
- package/dist/collections/indexes.js +27 -0
- package/dist/collections/methods.d.ts +16 -0
- package/dist/collections/methods.js +216 -0
- package/dist/databases/methods.d.ts +6 -0
- package/dist/databases/methods.js +33 -0
- package/dist/interactiveCLI.d.ts +19 -0
- package/dist/interactiveCLI.js +555 -0
- package/dist/main.js +224 -62
- package/dist/migrations/afterImportActions.js +37 -40
- package/dist/migrations/appwriteToX.d.ts +26 -25
- package/dist/migrations/appwriteToX.js +42 -6
- package/dist/migrations/attributes.js +21 -20
- package/dist/migrations/backup.d.ts +93 -87
- package/dist/migrations/collections.d.ts +6 -0
- package/dist/migrations/collections.js +149 -20
- package/dist/migrations/converters.d.ts +2 -18
- package/dist/migrations/converters.js +13 -2
- package/dist/migrations/dataLoader.d.ts +276 -161
- package/dist/migrations/dataLoader.js +535 -292
- package/dist/migrations/databases.js +8 -2
- package/dist/migrations/helper.d.ts +3 -0
- package/dist/migrations/helper.js +21 -0
- package/dist/migrations/importController.d.ts +5 -2
- package/dist/migrations/importController.js +125 -88
- package/dist/migrations/importDataActions.d.ts +9 -1
- package/dist/migrations/importDataActions.js +15 -3
- package/dist/migrations/indexes.js +3 -2
- package/dist/migrations/logging.js +20 -8
- package/dist/migrations/migrationHelper.d.ts +9 -4
- package/dist/migrations/migrationHelper.js +6 -5
- package/dist/migrations/openapi.d.ts +1 -1
- package/dist/migrations/openapi.js +33 -18
- package/dist/migrations/queue.js +3 -2
- package/dist/migrations/relationships.d.ts +2 -2
- package/dist/migrations/schemaStrings.js +53 -41
- package/dist/migrations/setupDatabase.d.ts +2 -4
- package/dist/migrations/setupDatabase.js +24 -105
- package/dist/migrations/storage.d.ts +3 -1
- package/dist/migrations/storage.js +110 -16
- package/dist/migrations/transfer.d.ts +30 -0
- package/dist/migrations/transfer.js +337 -0
- package/dist/migrations/users.d.ts +2 -1
- package/dist/migrations/users.js +78 -43
- package/dist/schemas/authUser.d.ts +2 -2
- package/dist/storage/methods.d.ts +15 -0
- package/dist/storage/methods.js +207 -0
- package/dist/storage/schemas.d.ts +687 -0
- package/dist/storage/schemas.js +175 -0
- package/dist/utils/getClientFromConfig.d.ts +4 -0
- package/dist/utils/getClientFromConfig.js +16 -0
- package/dist/utils/helperFunctions.d.ts +11 -1
- package/dist/utils/helperFunctions.js +38 -0
- package/dist/utils/retryFailedPromises.d.ts +2 -0
- package/dist/utils/retryFailedPromises.js +21 -0
- package/dist/utils/schemaStrings.d.ts +13 -0
- package/dist/utils/schemaStrings.js +403 -0
- package/dist/utils/setupFiles.js +110 -61
- package/dist/utilsController.d.ts +40 -22
- package/dist/utilsController.js +164 -84
- package/package.json +13 -15
- package/src/collections/attributes.ts +483 -0
- package/src/collections/indexes.ts +53 -0
- package/src/collections/methods.ts +331 -0
- package/src/databases/methods.ts +47 -0
- package/src/init.ts +64 -64
- package/src/interactiveCLI.ts +767 -0
- package/src/main.ts +289 -83
- package/src/migrations/afterImportActions.ts +553 -490
- package/src/migrations/appwriteToX.ts +237 -174
- package/src/migrations/attributes.ts +483 -422
- package/src/migrations/backup.ts +205 -205
- package/src/migrations/collections.ts +545 -300
- package/src/migrations/converters.ts +161 -150
- package/src/migrations/dataLoader.ts +1615 -1304
- package/src/migrations/databases.ts +44 -25
- package/src/migrations/dbHelpers.ts +92 -92
- package/src/migrations/helper.ts +40 -0
- package/src/migrations/importController.ts +448 -384
- package/src/migrations/importDataActions.ts +315 -307
- package/src/migrations/indexes.ts +40 -37
- package/src/migrations/logging.ts +29 -16
- package/src/migrations/migrationHelper.ts +207 -201
- package/src/migrations/openapi.ts +83 -70
- package/src/migrations/queue.ts +118 -119
- package/src/migrations/relationships.ts +324 -324
- package/src/migrations/schemaStrings.ts +472 -460
- package/src/migrations/setupDatabase.ts +118 -219
- package/src/migrations/storage.ts +538 -358
- package/src/migrations/transfer.ts +608 -0
- package/src/migrations/users.ts +362 -285
- package/src/migrations/validationRules.ts +63 -63
- package/src/schemas/authUser.ts +23 -23
- package/src/setup.ts +8 -8
- package/src/storage/methods.ts +371 -0
- package/src/storage/schemas.ts +205 -0
- package/src/types.ts +9 -9
- package/src/utils/getClientFromConfig.ts +17 -0
- package/src/utils/helperFunctions.ts +181 -127
- package/src/utils/index.ts +2 -2
- package/src/utils/loadConfigs.ts +59 -59
- package/src/utils/retryFailedPromises.ts +27 -0
- package/src/utils/schemaStrings.ts +473 -0
- package/src/utils/setupFiles.ts +228 -182
- package/src/utilsController.ts +325 -194
- 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
|
+
};
|