appwrite-utils-cli 0.0.42 → 0.0.43
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/dist/migrations/converters.js +1 -7
- package/dist/migrations/dataLoader.js +1 -1
- package/dist/migrations/importController.d.ts +1 -0
- package/dist/migrations/importController.js +16 -4
- package/dist/migrations/users.js +1 -1
- package/package.json +1 -1
- package/src/migrations/converters.ts +1 -8
- package/src/migrations/dataLoader.ts +1 -1
- package/src/migrations/importController.ts +24 -11
- package/src/migrations/users.ts +3 -1
|
@@ -110,16 +110,10 @@ export const convertObjectByAttributeMappings = (obj, attributeMappings) => {
|
|
|
110
110
|
: value;
|
|
111
111
|
}
|
|
112
112
|
else {
|
|
113
|
-
result[mapping.targetKey] = null;
|
|
113
|
+
result[mapping.targetKey] = value ? value : null;
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
|
-
// Ensure any keys in the original object that are not mapped are copied over
|
|
118
|
-
for (const key of Object.keys(obj)) {
|
|
119
|
-
if (!Object.keys(result).includes(key)) {
|
|
120
|
-
result[key] = obj[key];
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
117
|
return result;
|
|
124
118
|
};
|
|
125
119
|
/**
|
|
@@ -310,7 +310,7 @@ export class DataLoader {
|
|
|
310
310
|
continue;
|
|
311
311
|
}
|
|
312
312
|
// Prepare the update data for the collection
|
|
313
|
-
|
|
313
|
+
this.prepareUpdateData(db, collection, updateDef);
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
316
|
console.log("Running update references");
|
|
@@ -12,6 +12,7 @@ export declare class ImportController {
|
|
|
12
12
|
private setupOptions;
|
|
13
13
|
private documentCache;
|
|
14
14
|
private batchLimit;
|
|
15
|
+
private hasImportedUsers;
|
|
15
16
|
private postImportActionsQueue;
|
|
16
17
|
constructor(config: AppwriteConfig, database: Databases, storage: Storage, appwriteFolderPath: string, importDataActions: ImportDataActions, setupOptions: SetupOptions);
|
|
17
18
|
run(): Promise<void>;
|
|
@@ -16,6 +16,7 @@ export class ImportController {
|
|
|
16
16
|
setupOptions;
|
|
17
17
|
documentCache;
|
|
18
18
|
batchLimit = 25; // Define batch size limit
|
|
19
|
+
hasImportedUsers = false;
|
|
19
20
|
postImportActionsQueue = [];
|
|
20
21
|
constructor(config, database, storage, appwriteFolderPath, importDataActions, setupOptions) {
|
|
21
22
|
this.config = config;
|
|
@@ -35,6 +36,7 @@ export class ImportController {
|
|
|
35
36
|
(areCollectionNamesSame(db.name, this.config.databases[2].name) &&
|
|
36
37
|
this.setupOptions.runDev))
|
|
37
38
|
.map((db) => db.name);
|
|
39
|
+
let dataLoader;
|
|
38
40
|
for (let db of this.config.databases) {
|
|
39
41
|
if (db.name.toLowerCase().trim().replace(" ", "") === "migrations" ||
|
|
40
42
|
!databasesToRun.includes(db.name)) {
|
|
@@ -52,8 +54,13 @@ export class ImportController {
|
|
|
52
54
|
console.log(`Starting import data for database: ${db.name}`);
|
|
53
55
|
console.log(`---------------------------------`);
|
|
54
56
|
// await this.importCollections(db);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
+
if (!dataLoader) {
|
|
58
|
+
dataLoader = new DataLoader(this.appwriteFolderPath, this.importDataActions, this.database, this.config, this.setupOptions.shouldWriteFile);
|
|
59
|
+
await dataLoader.start(db.$id);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
console.log(`Using data from previous import run`);
|
|
63
|
+
}
|
|
57
64
|
await this.importCollections(db, dataLoader);
|
|
58
65
|
await resolveAndUpdateRelationships(db.$id, this.database, this.config);
|
|
59
66
|
await this.executePostImportActions(db.$id, dataLoader);
|
|
@@ -81,7 +88,7 @@ export class ImportController {
|
|
|
81
88
|
}
|
|
82
89
|
return finalBatches;
|
|
83
90
|
};
|
|
84
|
-
if (isUsersCollection) {
|
|
91
|
+
if (isUsersCollection && !this.hasImportedUsers) {
|
|
85
92
|
const usersDataMap = dataLoader.importMap.get(dataLoader.getCollectionKey("users"));
|
|
86
93
|
const usersData = usersDataMap?.data;
|
|
87
94
|
const usersController = new UsersController(this.config, this.database);
|
|
@@ -107,6 +114,10 @@ export class ImportController {
|
|
|
107
114
|
!dataLoader.userExistsMap.has(itemId));
|
|
108
115
|
})
|
|
109
116
|
.map((item) => {
|
|
117
|
+
dataLoader.userExistsMap.set(item.finalData.userId ||
|
|
118
|
+
item.finalData.docId ||
|
|
119
|
+
item.context.userId ||
|
|
120
|
+
item.context.docId, true);
|
|
110
121
|
return usersController.createUserAndReturn(item.finalData);
|
|
111
122
|
});
|
|
112
123
|
const promiseResults = await Promise.allSettled(userBatchPromises);
|
|
@@ -120,6 +131,7 @@ export class ImportController {
|
|
|
120
131
|
}
|
|
121
132
|
console.log("Finished importing users batch");
|
|
122
133
|
}
|
|
134
|
+
this.hasImportedUsers = true;
|
|
123
135
|
console.log("Finished importing users");
|
|
124
136
|
}
|
|
125
137
|
}
|
|
@@ -158,7 +170,7 @@ export class ImportController {
|
|
|
158
170
|
return tryAwaitWithRetry(async () => await this.database.createDocument(db.$id, collection.$id, id, item.finalData));
|
|
159
171
|
});
|
|
160
172
|
// Wait for all promises in the current batch to resolve
|
|
161
|
-
await Promise.
|
|
173
|
+
await Promise.all(batchPromises);
|
|
162
174
|
console.log(`Completed batch ${i + 1} of ${dataSplit.length}`);
|
|
163
175
|
await updateOperation(this.database, importOperation.$id, {
|
|
164
176
|
progress: processedItems,
|
package/dist/migrations/users.js
CHANGED
|
@@ -45,7 +45,7 @@ export class UsersController {
|
|
|
45
45
|
}
|
|
46
46
|
async getAllUsers() {
|
|
47
47
|
const allUsers = [];
|
|
48
|
-
const users = await this.users.list([Query.limit(200)]);
|
|
48
|
+
const users = await tryAwaitWithRetry(async () => await this.users.list([Query.limit(200)]));
|
|
49
49
|
if (users.users.length === 0) {
|
|
50
50
|
return [];
|
|
51
51
|
}
|
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.0.
|
|
4
|
+
"version": "0.0.43",
|
|
5
5
|
"main": "src/main.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
@@ -123,18 +123,11 @@ export const convertObjectByAttributeMappings = (
|
|
|
123
123
|
? value.flat(Infinity)
|
|
124
124
|
: value;
|
|
125
125
|
} else {
|
|
126
|
-
result[mapping.targetKey] = null;
|
|
126
|
+
result[mapping.targetKey] = value ? value : null;
|
|
127
127
|
}
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
// Ensure any keys in the original object that are not mapped are copied over
|
|
132
|
-
for (const key of Object.keys(obj)) {
|
|
133
|
-
if (!Object.keys(result).includes(key)) {
|
|
134
|
-
result[key] = obj[key];
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
131
|
return result;
|
|
139
132
|
};
|
|
140
133
|
|
|
@@ -389,7 +389,7 @@ export class DataLoader {
|
|
|
389
389
|
continue;
|
|
390
390
|
}
|
|
391
391
|
// Prepare the update data for the collection
|
|
392
|
-
|
|
392
|
+
this.prepareUpdateData(db, collection, updateDef);
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
395
|
console.log("Running update references");
|
|
@@ -36,6 +36,7 @@ export class ImportController {
|
|
|
36
36
|
private setupOptions: SetupOptions;
|
|
37
37
|
private documentCache: Map<string, any>;
|
|
38
38
|
private batchLimit: number = 25; // Define batch size limit
|
|
39
|
+
private hasImportedUsers = false;
|
|
39
40
|
private postImportActionsQueue: {
|
|
40
41
|
context: any;
|
|
41
42
|
finalItem: any;
|
|
@@ -71,7 +72,7 @@ export class ImportController {
|
|
|
71
72
|
this.setupOptions.runDev)
|
|
72
73
|
)
|
|
73
74
|
.map((db) => db.name);
|
|
74
|
-
|
|
75
|
+
let dataLoader: DataLoader | undefined;
|
|
75
76
|
for (let db of this.config.databases) {
|
|
76
77
|
if (
|
|
77
78
|
db.name.toLowerCase().trim().replace(" ", "") === "migrations" ||
|
|
@@ -91,14 +92,18 @@ export class ImportController {
|
|
|
91
92
|
console.log(`Starting import data for database: ${db.name}`);
|
|
92
93
|
console.log(`---------------------------------`);
|
|
93
94
|
// await this.importCollections(db);
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
95
|
+
if (!dataLoader) {
|
|
96
|
+
dataLoader = new DataLoader(
|
|
97
|
+
this.appwriteFolderPath,
|
|
98
|
+
this.importDataActions,
|
|
99
|
+
this.database,
|
|
100
|
+
this.config,
|
|
101
|
+
this.setupOptions.shouldWriteFile
|
|
102
|
+
);
|
|
103
|
+
await dataLoader.start(db.$id);
|
|
104
|
+
} else {
|
|
105
|
+
console.log(`Using data from previous import run`);
|
|
106
|
+
}
|
|
102
107
|
await this.importCollections(db, dataLoader);
|
|
103
108
|
await resolveAndUpdateRelationships(db.$id, this.database, this.config);
|
|
104
109
|
await this.executePostImportActions(db.$id, dataLoader);
|
|
@@ -131,7 +136,7 @@ export class ImportController {
|
|
|
131
136
|
return finalBatches;
|
|
132
137
|
};
|
|
133
138
|
|
|
134
|
-
if (isUsersCollection) {
|
|
139
|
+
if (isUsersCollection && !this.hasImportedUsers) {
|
|
135
140
|
const usersDataMap = dataLoader.importMap.get(
|
|
136
141
|
dataLoader.getCollectionKey("users")
|
|
137
142
|
);
|
|
@@ -160,6 +165,13 @@ export class ImportController {
|
|
|
160
165
|
);
|
|
161
166
|
})
|
|
162
167
|
.map((item) => {
|
|
168
|
+
dataLoader.userExistsMap.set(
|
|
169
|
+
item.finalData.userId ||
|
|
170
|
+
item.finalData.docId ||
|
|
171
|
+
item.context.userId ||
|
|
172
|
+
item.context.docId,
|
|
173
|
+
true
|
|
174
|
+
);
|
|
163
175
|
return usersController.createUserAndReturn(item.finalData);
|
|
164
176
|
});
|
|
165
177
|
const promiseResults = await Promise.allSettled(userBatchPromises);
|
|
@@ -176,6 +188,7 @@ export class ImportController {
|
|
|
176
188
|
}
|
|
177
189
|
console.log("Finished importing users batch");
|
|
178
190
|
}
|
|
191
|
+
this.hasImportedUsers = true;
|
|
179
192
|
console.log("Finished importing users");
|
|
180
193
|
}
|
|
181
194
|
}
|
|
@@ -232,7 +245,7 @@ export class ImportController {
|
|
|
232
245
|
);
|
|
233
246
|
});
|
|
234
247
|
// Wait for all promises in the current batch to resolve
|
|
235
|
-
await Promise.
|
|
248
|
+
await Promise.all(batchPromises);
|
|
236
249
|
console.log(`Completed batch ${i + 1} of ${dataSplit.length}`);
|
|
237
250
|
await updateOperation(this.database, importOperation.$id, {
|
|
238
251
|
progress: processedItems,
|
package/src/migrations/users.ts
CHANGED
|
@@ -68,7 +68,9 @@ export class UsersController {
|
|
|
68
68
|
|
|
69
69
|
async getAllUsers() {
|
|
70
70
|
const allUsers: Models.User<Models.Preferences>[] = [];
|
|
71
|
-
const users = await
|
|
71
|
+
const users = await tryAwaitWithRetry(
|
|
72
|
+
async () => await this.users.list([Query.limit(200)])
|
|
73
|
+
);
|
|
72
74
|
if (users.users.length === 0) {
|
|
73
75
|
return [];
|
|
74
76
|
}
|