appwrite-utils-cli 0.9.51 → 0.9.52
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 +1 -0
- package/dist/collections/attributes.js +4 -4
- package/dist/collections/indexes.js +3 -1
- package/dist/collections/methods.js +13 -7
- package/dist/utils/helperFunctions.d.ts +1 -0
- package/dist/utils/helperFunctions.js +1 -0
- package/package.json +1 -1
- package/src/collections/attributes.ts +5 -4
- package/src/collections/indexes.ts +3 -1
- package/src/collections/methods.ts +17 -7
- package/src/utils/helperFunctions.ts +3 -0
package/README.md
CHANGED
@@ -124,6 +124,7 @@ This updated CLI ensures that developers have robust tools at their fingertips t
|
|
124
124
|
|
125
125
|
## Changelog
|
126
126
|
|
127
|
+
- 0.9.52: Add delay after creating indexes, attributes, and others to prevent `fetch failed` errors during large-scale collection creation
|
127
128
|
- 0.9.51: Fix transfer databases, remove "ensure duplicates" check
|
128
129
|
- 0.9.5: Fixed not checking for storage bucket for each database (checking the creation status) when importing data
|
129
130
|
- 0.9.4: Fixed migrations database ensuring it has the required collections
|
@@ -2,7 +2,7 @@ import { Query } from "node-appwrite";
|
|
2
2
|
import { attributeSchema, parseAttribute, } from "appwrite-utils";
|
3
3
|
import { nameToIdMapping, enqueueOperation } from "../migrations/queue.js";
|
4
4
|
import _ from "lodash";
|
5
|
-
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
5
|
+
import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
6
6
|
const attributesSame = (databaseAttribute, configAttribute) => {
|
7
7
|
return (databaseAttribute.key == configAttribute.key &&
|
8
8
|
databaseAttribute.type == configAttribute.type &&
|
@@ -207,18 +207,18 @@ export const createOrUpdateAttribute = async (db, dbId, collection, attribute) =
|
|
207
207
|
};
|
208
208
|
export const createUpdateCollectionAttributes = async (db, dbId, collection, attributes) => {
|
209
209
|
console.log(`Creating/Updating attributes for collection: ${collection.name}`);
|
210
|
-
const batchSize = 3;
|
210
|
+
const batchSize = 3;
|
211
211
|
for (let i = 0; i < attributes.length; i += batchSize) {
|
212
|
-
// Slice the attributes array to get a batch of at most batchSize elements
|
213
212
|
const batch = attributes.slice(i, i + batchSize);
|
214
213
|
const attributePromises = batch.map((attribute) => createOrUpdateAttribute(db, dbId, collection, attribute));
|
215
|
-
// Await the completion of all promises in the current batch
|
216
214
|
const results = await Promise.allSettled(attributePromises);
|
217
215
|
results.forEach((result) => {
|
218
216
|
if (result.status === "rejected") {
|
219
217
|
console.error("An attribute promise was rejected:", result.reason);
|
220
218
|
}
|
221
219
|
});
|
220
|
+
// Add delay after each batch
|
221
|
+
await delay(2000);
|
222
222
|
}
|
223
223
|
console.log(`Finished creating/updating attributes for collection: ${collection.name}`);
|
224
224
|
};
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { indexSchema } from "appwrite-utils";
|
2
2
|
import { Databases, IndexType, Query } from "node-appwrite";
|
3
|
-
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
3
|
+
import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
4
4
|
export const createOrUpdateIndex = async (dbId, db, collectionId, index) => {
|
5
5
|
const existingIndex = await db.listIndexes(dbId, collectionId, [
|
6
6
|
Query.equal("key", index.key),
|
@@ -23,5 +23,7 @@ export const createOrUpdateIndex = async (dbId, db, collectionId, index) => {
|
|
23
23
|
export const createOrUpdateIndexes = async (dbId, db, collectionId, indexes) => {
|
24
24
|
for (const index of indexes) {
|
25
25
|
await tryAwaitWithRetry(async () => await createOrUpdateIndex(dbId, db, collectionId, index));
|
26
|
+
// Add delay after each index creation/update
|
27
|
+
await delay(1000);
|
26
28
|
}
|
27
29
|
};
|
@@ -4,7 +4,7 @@ import { createUpdateCollectionAttributes } from "./attributes.js";
|
|
4
4
|
import { createOrUpdateIndexes } from "./indexes.js";
|
5
5
|
import _ from "lodash";
|
6
6
|
import { SchemaGenerator } from "../utils/schemaStrings.js";
|
7
|
-
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
7
|
+
import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
8
8
|
export const documentExists = async (db, dbId, targetCollectionId, toCreateObject) => {
|
9
9
|
// Had to do this because kept running into issues with type checking arrays so, sorry 40ms
|
10
10
|
const collection = await db.getCollection(dbId, targetCollectionId);
|
@@ -109,7 +109,7 @@ export const createOrUpdateCollections = async (database, databaseId, config, de
|
|
109
109
|
if (!configCollections) {
|
110
110
|
return;
|
111
111
|
}
|
112
|
-
const usedIds = new Set();
|
112
|
+
const usedIds = new Set();
|
113
113
|
for (const { attributes, indexes, ...collection } of configCollections) {
|
114
114
|
// Prepare permissions for the collection
|
115
115
|
const permissions = [];
|
@@ -149,15 +149,15 @@ export const createOrUpdateCollections = async (database, databaseId, config, de
|
|
149
149
|
let foundColl = deletedCollections?.find((coll) => coll.collectionName.toLowerCase().trim().replace(" ", "") ===
|
150
150
|
collection.name.toLowerCase().trim().replace(" ", ""));
|
151
151
|
if (collection.$id) {
|
152
|
-
collectionId = collection.$id;
|
152
|
+
collectionId = collection.$id;
|
153
153
|
}
|
154
154
|
else if (foundColl && !usedIds.has(foundColl.collectionId)) {
|
155
|
-
collectionId = foundColl.collectionId;
|
155
|
+
collectionId = foundColl.collectionId;
|
156
156
|
}
|
157
157
|
else {
|
158
|
-
collectionId = ID.unique();
|
158
|
+
collectionId = ID.unique();
|
159
159
|
}
|
160
|
-
usedIds.add(collectionId);
|
160
|
+
usedIds.add(collectionId);
|
161
161
|
// Create the collection with the determined ID
|
162
162
|
try {
|
163
163
|
collectionToUse = await tryAwaitWithRetry(async () => await database.createCollection(databaseId, collectionId, collection.name, permissions, collection.documentSecurity ?? false, collection.enabled ?? true));
|
@@ -166,18 +166,24 @@ export const createOrUpdateCollections = async (database, databaseId, config, de
|
|
166
166
|
}
|
167
167
|
catch (error) {
|
168
168
|
console.error(`Failed to create collection ${collection.name} with ID ${collectionId}: ${error}`);
|
169
|
-
continue;
|
169
|
+
continue;
|
170
170
|
}
|
171
171
|
}
|
172
172
|
else {
|
173
173
|
console.log(`Collection ${collection.name} exists, updating it`);
|
174
174
|
await tryAwaitWithRetry(async () => await database.updateCollection(databaseId, collectionToUse.$id, collection.name, permissions, collection.documentSecurity ?? false, collection.enabled ?? true));
|
175
175
|
}
|
176
|
+
// Add delay after creating/updating collection
|
177
|
+
await delay(1000);
|
176
178
|
// Update attributes and indexes for the collection
|
177
179
|
console.log("Creating Attributes");
|
178
180
|
await createUpdateCollectionAttributes(database, databaseId, collectionToUse, attributes);
|
181
|
+
// Add delay after creating attributes
|
182
|
+
await delay(1000);
|
179
183
|
console.log("Creating Indexes");
|
180
184
|
await createOrUpdateIndexes(databaseId, database, collectionToUse.$id, indexes ?? []);
|
185
|
+
// Add delay after creating indexes
|
186
|
+
await delay(1000);
|
181
187
|
}
|
182
188
|
// Process any remaining tasks in the queue
|
183
189
|
await processQueue(database, databaseId);
|
@@ -45,3 +45,4 @@ export declare let numTimesFailedTotal: number;
|
|
45
45
|
*/
|
46
46
|
export declare const tryAwaitWithRetry: <T>(createFunction: () => Promise<T>, attemptNum?: number, throwError?: boolean) => Promise<T>;
|
47
47
|
export declare const getAppwriteClient: (endpoint: string, projectId: string, apiKey: string) => Client;
|
48
|
+
export declare const delay: (ms: number) => Promise<unknown>;
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "appwrite-utils-cli",
|
3
3
|
"description": "Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.",
|
4
|
-
"version": "0.9.
|
4
|
+
"version": "0.9.52",
|
5
5
|
"main": "src/main.ts",
|
6
6
|
"type": "module",
|
7
7
|
"repository": {
|
@@ -6,7 +6,7 @@ import {
|
|
6
6
|
} from "appwrite-utils";
|
7
7
|
import { nameToIdMapping, enqueueOperation } from "../migrations/queue.js";
|
8
8
|
import _ from "lodash";
|
9
|
-
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
9
|
+
import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
10
10
|
|
11
11
|
const attributesSame = (
|
12
12
|
databaseAttribute: Attribute,
|
@@ -461,21 +461,22 @@ export const createUpdateCollectionAttributes = async (
|
|
461
461
|
`Creating/Updating attributes for collection: ${collection.name}`
|
462
462
|
);
|
463
463
|
|
464
|
-
const batchSize = 3;
|
464
|
+
const batchSize = 3;
|
465
465
|
for (let i = 0; i < attributes.length; i += batchSize) {
|
466
|
-
// Slice the attributes array to get a batch of at most batchSize elements
|
467
466
|
const batch = attributes.slice(i, i + batchSize);
|
468
467
|
const attributePromises = batch.map((attribute) =>
|
469
468
|
createOrUpdateAttribute(db, dbId, collection, attribute)
|
470
469
|
);
|
471
470
|
|
472
|
-
// Await the completion of all promises in the current batch
|
473
471
|
const results = await Promise.allSettled(attributePromises);
|
474
472
|
results.forEach((result) => {
|
475
473
|
if (result.status === "rejected") {
|
476
474
|
console.error("An attribute promise was rejected:", result.reason);
|
477
475
|
}
|
478
476
|
});
|
477
|
+
|
478
|
+
// Add delay after each batch
|
479
|
+
await delay(2000);
|
479
480
|
}
|
480
481
|
console.log(
|
481
482
|
`Finished creating/updating attributes for collection: ${collection.name}`
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { indexSchema, type Index } from "appwrite-utils";
|
2
2
|
import { Databases, IndexType, Query, type Models } from "node-appwrite";
|
3
|
-
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
3
|
+
import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
4
4
|
|
5
5
|
export const createOrUpdateIndex = async (
|
6
6
|
dbId: string,
|
@@ -49,5 +49,7 @@ export const createOrUpdateIndexes = async (
|
|
49
49
|
await tryAwaitWithRetry(
|
50
50
|
async () => await createOrUpdateIndex(dbId, db, collectionId, index)
|
51
51
|
);
|
52
|
+
// Add delay after each index creation/update
|
53
|
+
await delay(1000);
|
52
54
|
}
|
53
55
|
};
|
@@ -12,7 +12,7 @@ import { createUpdateCollectionAttributes } from "./attributes.js";
|
|
12
12
|
import { createOrUpdateIndexes } from "./indexes.js";
|
13
13
|
import _ from "lodash";
|
14
14
|
import { SchemaGenerator } from "../utils/schemaStrings.js";
|
15
|
-
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
15
|
+
import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
16
16
|
|
17
17
|
export const documentExists = async (
|
18
18
|
db: Databases,
|
@@ -163,7 +163,7 @@ export const createOrUpdateCollections = async (
|
|
163
163
|
if (!configCollections) {
|
164
164
|
return;
|
165
165
|
}
|
166
|
-
const usedIds = new Set();
|
166
|
+
const usedIds = new Set();
|
167
167
|
|
168
168
|
for (const { attributes, indexes, ...collection } of configCollections) {
|
169
169
|
// Prepare permissions for the collection
|
@@ -215,14 +215,14 @@ export const createOrUpdateCollections = async (
|
|
215
215
|
);
|
216
216
|
|
217
217
|
if (collection.$id) {
|
218
|
-
collectionId = collection.$id;
|
218
|
+
collectionId = collection.$id;
|
219
219
|
} else if (foundColl && !usedIds.has(foundColl.collectionId)) {
|
220
|
-
collectionId = foundColl.collectionId;
|
220
|
+
collectionId = foundColl.collectionId;
|
221
221
|
} else {
|
222
|
-
collectionId = ID.unique();
|
222
|
+
collectionId = ID.unique();
|
223
223
|
}
|
224
224
|
|
225
|
-
usedIds.add(collectionId);
|
225
|
+
usedIds.add(collectionId);
|
226
226
|
|
227
227
|
// Create the collection with the determined ID
|
228
228
|
try {
|
@@ -243,7 +243,7 @@ export const createOrUpdateCollections = async (
|
|
243
243
|
console.error(
|
244
244
|
`Failed to create collection ${collection.name} with ID ${collectionId}: ${error}`
|
245
245
|
);
|
246
|
-
continue;
|
246
|
+
continue;
|
247
247
|
}
|
248
248
|
} else {
|
249
249
|
console.log(`Collection ${collection.name} exists, updating it`);
|
@@ -260,6 +260,9 @@ export const createOrUpdateCollections = async (
|
|
260
260
|
);
|
261
261
|
}
|
262
262
|
|
263
|
+
// Add delay after creating/updating collection
|
264
|
+
await delay(1000);
|
265
|
+
|
263
266
|
// Update attributes and indexes for the collection
|
264
267
|
console.log("Creating Attributes");
|
265
268
|
await createUpdateCollectionAttributes(
|
@@ -268,6 +271,10 @@ export const createOrUpdateCollections = async (
|
|
268
271
|
collectionToUse!,
|
269
272
|
attributes
|
270
273
|
);
|
274
|
+
|
275
|
+
// Add delay after creating attributes
|
276
|
+
await delay(1000);
|
277
|
+
|
271
278
|
console.log("Creating Indexes");
|
272
279
|
await createOrUpdateIndexes(
|
273
280
|
databaseId,
|
@@ -275,6 +282,9 @@ export const createOrUpdateCollections = async (
|
|
275
282
|
collectionToUse!.$id,
|
276
283
|
indexes ?? []
|
277
284
|
);
|
285
|
+
|
286
|
+
// Add delay after creating indexes
|
287
|
+
await delay(1000);
|
278
288
|
}
|
279
289
|
// Process any remaining tasks in the queue
|
280
290
|
await processQueue(database, databaseId);
|