appwrite-utils-cli 0.10.81 → 0.10.83
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 +2 -0
- package/dist/collections/attributes.js +86 -41
- package/dist/collections/methods.d.ts +6 -0
- package/dist/collections/methods.js +159 -24
- package/dist/migrations/appwriteToX.js +1 -1
- package/dist/migrations/attributes.js +0 -1
- package/dist/migrations/converters.js +3 -4
- package/dist/migrations/dataLoader.js +3 -3
- package/dist/migrations/importController.js +0 -1
- package/dist/migrations/queue.js +1 -2
- package/dist/migrations/relationships.js +1 -1
- package/dist/migrations/users.js +5 -4
- package/dist/migrations/validationRules.js +30 -30
- package/package.json +2 -2
- package/src/collections/attributes.ts +126 -50
- package/src/collections/methods.ts +259 -28
- package/src/migrations/appwriteToX.ts +4 -4
- package/src/migrations/attributes.ts +0 -1
- package/src/migrations/converters.ts +3 -5
- package/src/migrations/dataLoader.ts +4 -4
- package/src/migrations/importController.ts +0 -1
- package/src/migrations/queue.ts +1 -2
- package/src/migrations/relationships.ts +1 -1
- package/src/migrations/users.ts +8 -7
- package/src/migrations/validationRules.ts +56 -31
- package/src/migrations/collections.ts +0 -545
@@ -1,545 +0,0 @@
|
|
1
|
-
import {
|
2
|
-
Client,
|
3
|
-
Databases,
|
4
|
-
ID,
|
5
|
-
Permission,
|
6
|
-
Query,
|
7
|
-
type Models,
|
8
|
-
} from "node-appwrite";
|
9
|
-
import type { AppwriteConfig, CollectionCreate } from "appwrite-utils";
|
10
|
-
import { nameToIdMapping, processQueue } from "./queue.js";
|
11
|
-
import { createUpdateCollectionAttributes } from "./attributes.js";
|
12
|
-
import { createOrUpdateIndexes } from "./indexes.js";
|
13
|
-
import _ from "lodash";
|
14
|
-
import { SchemaGenerator } from "./schemaStrings.js";
|
15
|
-
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
16
|
-
|
17
|
-
export const documentExists = async (
|
18
|
-
db: Databases,
|
19
|
-
dbId: string,
|
20
|
-
targetCollectionId: string,
|
21
|
-
toCreateObject: any
|
22
|
-
): Promise<Models.Document | null> => {
|
23
|
-
// Had to do this because kept running into issues with type checking arrays so, sorry 40ms
|
24
|
-
const collection = await db.getCollection(dbId, targetCollectionId);
|
25
|
-
const attributes = collection.attributes as any[];
|
26
|
-
let arrayTypeAttributes = attributes
|
27
|
-
.filter((attribute: any) => attribute.array === true)
|
28
|
-
.map((attribute: any) => attribute.key);
|
29
|
-
// Function to check if a string is JSON
|
30
|
-
const isJsonString = (str: string) => {
|
31
|
-
try {
|
32
|
-
const json = JSON.parse(str);
|
33
|
-
return typeof json === "object" && json !== null; // Check if parsed JSON is an object or array
|
34
|
-
} catch (e) {
|
35
|
-
return false;
|
36
|
-
}
|
37
|
-
};
|
38
|
-
|
39
|
-
// Validate and prepare query parameters
|
40
|
-
const validQueryParams = _.chain(toCreateObject)
|
41
|
-
.pickBy(
|
42
|
-
(value, key) =>
|
43
|
-
!arrayTypeAttributes.includes(key) &&
|
44
|
-
!key.startsWith("$") &&
|
45
|
-
!_.isNull(value) &&
|
46
|
-
!_.isUndefined(value) &&
|
47
|
-
!_.isEmpty(value) &&
|
48
|
-
!_.isObject(value) && // Keeps excluding objects
|
49
|
-
!_.isArray(value) && // Explicitly exclude arrays
|
50
|
-
!(_.isString(value) && isJsonString(value)) && // Exclude JSON strings
|
51
|
-
(_.isString(value) ? value.length < 4096 && value.length > 0 : true) // String length check
|
52
|
-
)
|
53
|
-
.mapValues((value, key) =>
|
54
|
-
_.isString(value) || _.isNumber(value) || _.isBoolean(value)
|
55
|
-
? value
|
56
|
-
: null
|
57
|
-
)
|
58
|
-
.omitBy(_.isNull) // Remove any null values that might have been added in mapValues
|
59
|
-
.toPairs()
|
60
|
-
.slice(0, 25) // Limit to 25 to adhere to query limit
|
61
|
-
.map(([key, value]) => Query.equal(key, value as any))
|
62
|
-
.value();
|
63
|
-
|
64
|
-
// Execute the query with the validated and prepared parameters
|
65
|
-
const result = await db.listDocuments(
|
66
|
-
dbId,
|
67
|
-
targetCollectionId,
|
68
|
-
validQueryParams
|
69
|
-
);
|
70
|
-
return result.documents[0] || null;
|
71
|
-
};
|
72
|
-
|
73
|
-
export const checkForCollection = async (
|
74
|
-
db: Databases,
|
75
|
-
dbId: string,
|
76
|
-
collection: Partial<CollectionCreate>
|
77
|
-
): Promise<Models.Collection | null> => {
|
78
|
-
try {
|
79
|
-
console.log(`Checking for collection with name: ${collection.name}`);
|
80
|
-
const response = await tryAwaitWithRetry(
|
81
|
-
async () =>
|
82
|
-
await db.listCollections(dbId, [Query.equal("name", collection.name!)])
|
83
|
-
);
|
84
|
-
if (response.collections.length > 0) {
|
85
|
-
console.log(`Collection found: ${response.collections[0].$id}`);
|
86
|
-
return { ...collection, ...response.collections[0] };
|
87
|
-
} else {
|
88
|
-
console.log(`No collection found with name: ${collection.name}`);
|
89
|
-
return null;
|
90
|
-
}
|
91
|
-
} catch (error) {
|
92
|
-
console.error(`Error checking for collection: ${error}`);
|
93
|
-
return null;
|
94
|
-
}
|
95
|
-
};
|
96
|
-
|
97
|
-
// Helper function to fetch and cache collection by name
|
98
|
-
export const fetchAndCacheCollectionByName = async (
|
99
|
-
db: Databases,
|
100
|
-
dbId: string,
|
101
|
-
collectionName: string
|
102
|
-
): Promise<Models.Collection | undefined> => {
|
103
|
-
if (nameToIdMapping.has(collectionName)) {
|
104
|
-
const collectionId = nameToIdMapping.get(collectionName);
|
105
|
-
console.log(`\tCollection found in cache: ${collectionId}`);
|
106
|
-
return await tryAwaitWithRetry(
|
107
|
-
async () => await db.getCollection(dbId, collectionId!)
|
108
|
-
);
|
109
|
-
} else {
|
110
|
-
console.log(`\tFetching collection by name: ${collectionName}`);
|
111
|
-
const collectionsPulled = await tryAwaitWithRetry(
|
112
|
-
async () =>
|
113
|
-
await db.listCollections(dbId, [Query.equal("name", collectionName)])
|
114
|
-
);
|
115
|
-
if (collectionsPulled.total > 0) {
|
116
|
-
const collection = collectionsPulled.collections[0];
|
117
|
-
console.log(`\tCollection found: ${collection.$id}`);
|
118
|
-
nameToIdMapping.set(collectionName, collection.$id);
|
119
|
-
return collection;
|
120
|
-
} else {
|
121
|
-
console.log(`\tCollection not found by name: ${collectionName}`);
|
122
|
-
return undefined;
|
123
|
-
}
|
124
|
-
}
|
125
|
-
};
|
126
|
-
|
127
|
-
export const wipeDatabase = async (
|
128
|
-
database: Databases,
|
129
|
-
databaseId: string
|
130
|
-
): Promise<{ collectionId: string; collectionName: string }[]> => {
|
131
|
-
console.log(`Wiping database: ${databaseId}`);
|
132
|
-
const existingCollections = await fetchAllCollections(databaseId, database);
|
133
|
-
let collectionsDeleted: { collectionId: string; collectionName: string }[] =
|
134
|
-
[];
|
135
|
-
for (const { $id: collectionId, name: name } of existingCollections) {
|
136
|
-
console.log(`Deleting collection: ${collectionId}`);
|
137
|
-
collectionsDeleted.push({
|
138
|
-
collectionId: collectionId,
|
139
|
-
collectionName: name,
|
140
|
-
});
|
141
|
-
tryAwaitWithRetry(
|
142
|
-
async () => await database.deleteCollection(databaseId, collectionId)
|
143
|
-
); // Try to delete the collection and ignore errors if it doesn't exist or if it's already being deleted
|
144
|
-
}
|
145
|
-
return collectionsDeleted;
|
146
|
-
};
|
147
|
-
|
148
|
-
export const generateSchemas = async (
|
149
|
-
config: AppwriteConfig,
|
150
|
-
appwriteFolderPath: string
|
151
|
-
): Promise<void> => {
|
152
|
-
const schemaGenerator = new SchemaGenerator(config, appwriteFolderPath);
|
153
|
-
schemaGenerator.generateSchemas();
|
154
|
-
};
|
155
|
-
|
156
|
-
export const createOrUpdateCollections = async (
|
157
|
-
database: Databases,
|
158
|
-
databaseId: string,
|
159
|
-
config: AppwriteConfig,
|
160
|
-
deletedCollections?: { collectionId: string; collectionName: string }[]
|
161
|
-
): Promise<void> => {
|
162
|
-
const configCollections = config.collections;
|
163
|
-
if (!configCollections) {
|
164
|
-
return;
|
165
|
-
}
|
166
|
-
const usedIds = new Set(); // To track IDs used in this operation
|
167
|
-
|
168
|
-
for (const { attributes, indexes, ...collection } of configCollections) {
|
169
|
-
// Prepare permissions for the collection
|
170
|
-
const permissions: string[] = [];
|
171
|
-
if (collection.$permissions && collection.$permissions.length > 0) {
|
172
|
-
for (const permission of collection.$permissions) {
|
173
|
-
switch (permission.permission) {
|
174
|
-
case "read":
|
175
|
-
permissions.push(Permission.read(permission.target));
|
176
|
-
break;
|
177
|
-
case "create":
|
178
|
-
permissions.push(Permission.create(permission.target));
|
179
|
-
break;
|
180
|
-
case "update":
|
181
|
-
permissions.push(Permission.update(permission.target));
|
182
|
-
break;
|
183
|
-
case "delete":
|
184
|
-
permissions.push(Permission.delete(permission.target));
|
185
|
-
break;
|
186
|
-
case "write":
|
187
|
-
permissions.push(Permission.write(permission.target));
|
188
|
-
break;
|
189
|
-
default:
|
190
|
-
console.log(`Unknown permission: ${permission.permission}`);
|
191
|
-
break;
|
192
|
-
}
|
193
|
-
}
|
194
|
-
}
|
195
|
-
|
196
|
-
// Check if the collection already exists by name
|
197
|
-
let collectionsFound = await tryAwaitWithRetry(
|
198
|
-
async () =>
|
199
|
-
await database.listCollections(databaseId, [
|
200
|
-
Query.equal("name", collection.name),
|
201
|
-
])
|
202
|
-
);
|
203
|
-
|
204
|
-
let collectionToUse =
|
205
|
-
collectionsFound.total > 0 ? collectionsFound.collections[0] : null;
|
206
|
-
|
207
|
-
// Determine the correct ID for the collection
|
208
|
-
let collectionId: string;
|
209
|
-
if (!collectionToUse) {
|
210
|
-
console.log(`Creating collection: ${collection.name}`);
|
211
|
-
let foundColl = deletedCollections?.find(
|
212
|
-
(coll) =>
|
213
|
-
coll.collectionName.toLowerCase().trim().replace(" ", "") ===
|
214
|
-
collection.name.toLowerCase().trim().replace(" ", "")
|
215
|
-
);
|
216
|
-
|
217
|
-
if (collection.$id) {
|
218
|
-
collectionId = collection.$id; // Always use the provided $id if present
|
219
|
-
} else if (foundColl && !usedIds.has(foundColl.collectionId)) {
|
220
|
-
collectionId = foundColl.collectionId; // Use ID from deleted collection if not already used
|
221
|
-
} else {
|
222
|
-
collectionId = ID.unique(); // Generate a new unique ID
|
223
|
-
}
|
224
|
-
|
225
|
-
usedIds.add(collectionId); // Mark this ID as used
|
226
|
-
|
227
|
-
// Create the collection with the determined ID
|
228
|
-
try {
|
229
|
-
collectionToUse = await tryAwaitWithRetry(
|
230
|
-
async () =>
|
231
|
-
await database.createCollection(
|
232
|
-
databaseId,
|
233
|
-
collectionId,
|
234
|
-
collection.name,
|
235
|
-
permissions,
|
236
|
-
collection.documentSecurity ?? false,
|
237
|
-
collection.enabled ?? true
|
238
|
-
)
|
239
|
-
);
|
240
|
-
collection.$id = collectionToUse!.$id;
|
241
|
-
nameToIdMapping.set(collection.name, collectionToUse!.$id);
|
242
|
-
} catch (error) {
|
243
|
-
console.error(
|
244
|
-
`Failed to create collection ${collection.name} with ID ${collectionId}: ${error}`
|
245
|
-
);
|
246
|
-
continue; // Skip to the next collection on failure
|
247
|
-
}
|
248
|
-
} else {
|
249
|
-
console.log(`Collection ${collection.name} exists, updating it`);
|
250
|
-
await tryAwaitWithRetry(
|
251
|
-
async () =>
|
252
|
-
await database.updateCollection(
|
253
|
-
databaseId,
|
254
|
-
collectionToUse!.$id,
|
255
|
-
collection.name,
|
256
|
-
permissions,
|
257
|
-
collection.documentSecurity ?? false,
|
258
|
-
collection.enabled ?? true
|
259
|
-
)
|
260
|
-
);
|
261
|
-
}
|
262
|
-
|
263
|
-
// Update attributes and indexes for the collection
|
264
|
-
console.log("Creating Attributes");
|
265
|
-
await createUpdateCollectionAttributes(
|
266
|
-
database,
|
267
|
-
databaseId,
|
268
|
-
collectionToUse!,
|
269
|
-
attributes
|
270
|
-
);
|
271
|
-
console.log("Creating Indexes");
|
272
|
-
await createOrUpdateIndexes(
|
273
|
-
databaseId,
|
274
|
-
database,
|
275
|
-
collectionToUse!.$id,
|
276
|
-
indexes ?? []
|
277
|
-
);
|
278
|
-
}
|
279
|
-
// Process any remaining tasks in the queue
|
280
|
-
await processQueue(database, databaseId);
|
281
|
-
};
|
282
|
-
|
283
|
-
export const generateMockData = async (
|
284
|
-
database: Databases,
|
285
|
-
databaseId: string,
|
286
|
-
configCollections: any[]
|
287
|
-
): Promise<void> => {
|
288
|
-
for (const { collection, mockFunction } of configCollections) {
|
289
|
-
if (mockFunction) {
|
290
|
-
console.log(`Generating mock data for collection: ${collection.name}`);
|
291
|
-
const mockData = mockFunction();
|
292
|
-
for (const data of mockData) {
|
293
|
-
await database.createDocument(
|
294
|
-
databaseId,
|
295
|
-
collection.$id,
|
296
|
-
ID.unique(),
|
297
|
-
data
|
298
|
-
);
|
299
|
-
}
|
300
|
-
}
|
301
|
-
}
|
302
|
-
};
|
303
|
-
|
304
|
-
export const fetchAllCollections = async (
|
305
|
-
dbId: string,
|
306
|
-
database: Databases
|
307
|
-
): Promise<Models.Collection[]> => {
|
308
|
-
console.log(`Fetching all collections for database ID: ${dbId}`);
|
309
|
-
let collections: Models.Collection[] = [];
|
310
|
-
let moreCollections = true;
|
311
|
-
let lastCollectionId: string | undefined;
|
312
|
-
|
313
|
-
while (moreCollections) {
|
314
|
-
const queries = [Query.limit(500)];
|
315
|
-
if (lastCollectionId) {
|
316
|
-
queries.push(Query.cursorAfter(lastCollectionId));
|
317
|
-
}
|
318
|
-
const response = await tryAwaitWithRetry(
|
319
|
-
async () => await database.listCollections(dbId, queries)
|
320
|
-
);
|
321
|
-
collections = collections.concat(response.collections);
|
322
|
-
moreCollections = response.collections.length === 500;
|
323
|
-
if (moreCollections) {
|
324
|
-
lastCollectionId =
|
325
|
-
response.collections[response.collections.length - 1].$id;
|
326
|
-
}
|
327
|
-
}
|
328
|
-
|
329
|
-
console.log(`Fetched a total of ${collections.length} collections.`);
|
330
|
-
return collections;
|
331
|
-
};
|
332
|
-
|
333
|
-
/**
|
334
|
-
* Transfers all documents from one collection to another in a different database
|
335
|
-
* within the same Appwrite Project
|
336
|
-
*/
|
337
|
-
export const transferDocumentsBetweenDbsLocalToLocal = async (
|
338
|
-
db: Databases,
|
339
|
-
fromDbId: string,
|
340
|
-
toDbId: string,
|
341
|
-
fromCollId: string,
|
342
|
-
toCollId: string
|
343
|
-
) => {
|
344
|
-
let fromCollDocs = await tryAwaitWithRetry(async () =>
|
345
|
-
db.listDocuments(fromDbId, fromCollId, [Query.limit(50)])
|
346
|
-
);
|
347
|
-
let totalDocumentsTransferred = 0;
|
348
|
-
|
349
|
-
if (fromCollDocs.documents.length === 0) {
|
350
|
-
console.log(`No documents found in collection ${fromCollId}`);
|
351
|
-
return;
|
352
|
-
} else if (fromCollDocs.documents.length < 50) {
|
353
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
354
|
-
const toCreateObject: Partial<typeof doc> = {
|
355
|
-
...doc,
|
356
|
-
};
|
357
|
-
delete toCreateObject.$databaseId;
|
358
|
-
delete toCreateObject.$collectionId;
|
359
|
-
delete toCreateObject.$createdAt;
|
360
|
-
delete toCreateObject.$updatedAt;
|
361
|
-
delete toCreateObject.$id;
|
362
|
-
delete toCreateObject.$permissions;
|
363
|
-
return tryAwaitWithRetry(
|
364
|
-
async () =>
|
365
|
-
await db.createDocument(
|
366
|
-
toDbId,
|
367
|
-
toCollId,
|
368
|
-
doc.$id,
|
369
|
-
toCreateObject,
|
370
|
-
doc.$permissions
|
371
|
-
)
|
372
|
-
);
|
373
|
-
});
|
374
|
-
await Promise.all(batchedPromises);
|
375
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
376
|
-
} else {
|
377
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
378
|
-
const toCreateObject: Partial<typeof doc> = {
|
379
|
-
...doc,
|
380
|
-
};
|
381
|
-
delete toCreateObject.$databaseId;
|
382
|
-
delete toCreateObject.$collectionId;
|
383
|
-
delete toCreateObject.$createdAt;
|
384
|
-
delete toCreateObject.$updatedAt;
|
385
|
-
delete toCreateObject.$id;
|
386
|
-
delete toCreateObject.$permissions;
|
387
|
-
return tryAwaitWithRetry(async () =>
|
388
|
-
db.createDocument(
|
389
|
-
toDbId,
|
390
|
-
toCollId,
|
391
|
-
doc.$id,
|
392
|
-
toCreateObject,
|
393
|
-
doc.$permissions
|
394
|
-
)
|
395
|
-
);
|
396
|
-
});
|
397
|
-
await Promise.all(batchedPromises);
|
398
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
399
|
-
while (fromCollDocs.documents.length === 50) {
|
400
|
-
fromCollDocs = await tryAwaitWithRetry(
|
401
|
-
async () =>
|
402
|
-
await db.listDocuments(fromDbId, fromCollId, [
|
403
|
-
Query.limit(50),
|
404
|
-
Query.cursorAfter(
|
405
|
-
fromCollDocs.documents[fromCollDocs.documents.length - 1].$id
|
406
|
-
),
|
407
|
-
])
|
408
|
-
);
|
409
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
410
|
-
const toCreateObject: Partial<typeof doc> = {
|
411
|
-
...doc,
|
412
|
-
};
|
413
|
-
delete toCreateObject.$databaseId;
|
414
|
-
delete toCreateObject.$collectionId;
|
415
|
-
delete toCreateObject.$createdAt;
|
416
|
-
delete toCreateObject.$updatedAt;
|
417
|
-
delete toCreateObject.$id;
|
418
|
-
delete toCreateObject.$permissions;
|
419
|
-
return tryAwaitWithRetry(
|
420
|
-
async () =>
|
421
|
-
await db.createDocument(
|
422
|
-
toDbId,
|
423
|
-
toCollId,
|
424
|
-
doc.$id,
|
425
|
-
toCreateObject,
|
426
|
-
doc.$permissions
|
427
|
-
)
|
428
|
-
);
|
429
|
-
});
|
430
|
-
await Promise.all(batchedPromises);
|
431
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
432
|
-
}
|
433
|
-
}
|
434
|
-
|
435
|
-
console.log(
|
436
|
-
`Transferred ${totalDocumentsTransferred} documents from database ${fromDbId} to database ${toDbId} -- collection ${fromCollId} to collection ${toCollId}`
|
437
|
-
);
|
438
|
-
};
|
439
|
-
|
440
|
-
export const transferDocumentsBetweenDbsLocalToRemote = async (
|
441
|
-
localDb: Databases,
|
442
|
-
endpoint: string,
|
443
|
-
projectId: string,
|
444
|
-
apiKey: string,
|
445
|
-
fromDbId: string,
|
446
|
-
toDbId: string,
|
447
|
-
fromCollId: string,
|
448
|
-
toCollId: string
|
449
|
-
) => {
|
450
|
-
const client = new Client()
|
451
|
-
.setEndpoint(endpoint)
|
452
|
-
.setProject(projectId)
|
453
|
-
.setKey(apiKey);
|
454
|
-
let totalDocumentsTransferred = 0;
|
455
|
-
const remoteDb = new Databases(client);
|
456
|
-
let fromCollDocs = await tryAwaitWithRetry(async () =>
|
457
|
-
localDb.listDocuments(fromDbId, fromCollId, [Query.limit(50)])
|
458
|
-
);
|
459
|
-
|
460
|
-
if (fromCollDocs.documents.length === 0) {
|
461
|
-
console.log(`No documents found in collection ${fromCollId}`);
|
462
|
-
return;
|
463
|
-
} else if (fromCollDocs.documents.length < 50) {
|
464
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
465
|
-
const toCreateObject: Partial<typeof doc> = {
|
466
|
-
...doc,
|
467
|
-
};
|
468
|
-
delete toCreateObject.$databaseId;
|
469
|
-
delete toCreateObject.$collectionId;
|
470
|
-
delete toCreateObject.$createdAt;
|
471
|
-
delete toCreateObject.$updatedAt;
|
472
|
-
delete toCreateObject.$id;
|
473
|
-
delete toCreateObject.$permissions;
|
474
|
-
return tryAwaitWithRetry(async () =>
|
475
|
-
remoteDb.createDocument(
|
476
|
-
toDbId,
|
477
|
-
toCollId,
|
478
|
-
doc.$id,
|
479
|
-
toCreateObject,
|
480
|
-
doc.$permissions
|
481
|
-
)
|
482
|
-
);
|
483
|
-
});
|
484
|
-
await Promise.all(batchedPromises);
|
485
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
486
|
-
} else {
|
487
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
488
|
-
const toCreateObject: Partial<typeof doc> = {
|
489
|
-
...doc,
|
490
|
-
};
|
491
|
-
delete toCreateObject.$databaseId;
|
492
|
-
delete toCreateObject.$collectionId;
|
493
|
-
delete toCreateObject.$createdAt;
|
494
|
-
delete toCreateObject.$updatedAt;
|
495
|
-
delete toCreateObject.$id;
|
496
|
-
delete toCreateObject.$permissions;
|
497
|
-
return tryAwaitWithRetry(async () =>
|
498
|
-
remoteDb.createDocument(
|
499
|
-
toDbId,
|
500
|
-
toCollId,
|
501
|
-
doc.$id,
|
502
|
-
toCreateObject,
|
503
|
-
doc.$permissions
|
504
|
-
)
|
505
|
-
);
|
506
|
-
});
|
507
|
-
await Promise.all(batchedPromises);
|
508
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
509
|
-
while (fromCollDocs.documents.length === 50) {
|
510
|
-
fromCollDocs = await tryAwaitWithRetry(async () =>
|
511
|
-
localDb.listDocuments(fromDbId, fromCollId, [
|
512
|
-
Query.limit(50),
|
513
|
-
Query.cursorAfter(
|
514
|
-
fromCollDocs.documents[fromCollDocs.documents.length - 1].$id
|
515
|
-
),
|
516
|
-
])
|
517
|
-
);
|
518
|
-
const batchedPromises = fromCollDocs.documents.map((doc) => {
|
519
|
-
const toCreateObject: Partial<typeof doc> = {
|
520
|
-
...doc,
|
521
|
-
};
|
522
|
-
delete toCreateObject.$databaseId;
|
523
|
-
delete toCreateObject.$collectionId;
|
524
|
-
delete toCreateObject.$createdAt;
|
525
|
-
delete toCreateObject.$updatedAt;
|
526
|
-
delete toCreateObject.$id;
|
527
|
-
delete toCreateObject.$permissions;
|
528
|
-
return tryAwaitWithRetry(async () =>
|
529
|
-
remoteDb.createDocument(
|
530
|
-
toDbId,
|
531
|
-
toCollId,
|
532
|
-
doc.$id,
|
533
|
-
toCreateObject,
|
534
|
-
doc.$permissions
|
535
|
-
)
|
536
|
-
);
|
537
|
-
});
|
538
|
-
await Promise.all(batchedPromises);
|
539
|
-
totalDocumentsTransferred += fromCollDocs.documents.length;
|
540
|
-
}
|
541
|
-
}
|
542
|
-
console.log(
|
543
|
-
`Total documents transferred from database ${fromDbId} to database ${toDbId} -- collection ${fromCollId} to collection ${toCollId}: ${totalDocumentsTransferred}`
|
544
|
-
);
|
545
|
-
};
|