appwrite-utils-cli 0.0.10 → 0.0.11
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.
|
@@ -151,7 +151,7 @@ export class ImportController {
|
|
|
151
151
|
async processBatch(db, collection, importDef, dataToImport, updateDefs = [], isMembersCollection = false) {
|
|
152
152
|
for (let i = 0; i < dataToImport.length; i += this.batchLimit) {
|
|
153
153
|
const batch = dataToImport.slice(i, i + this.batchLimit);
|
|
154
|
-
|
|
154
|
+
batch.map(async (item) => {
|
|
155
155
|
let context = this.createContext(db, collection, item);
|
|
156
156
|
let finalItem = await this.transformData(item, importDef.attributeMappings);
|
|
157
157
|
let createIdToUse = undefined;
|
|
@@ -232,13 +232,13 @@ export class ImportController {
|
|
|
232
232
|
// attributeMappings: attributeMappingsWithActions,
|
|
233
233
|
// });
|
|
234
234
|
}
|
|
235
|
-
}));
|
|
236
|
-
results.forEach((result) => {
|
|
237
|
-
if (result.status === "rejected") {
|
|
238
|
-
console.error("A process batch promise was rejected:", result.reason);
|
|
239
|
-
logger.error("An error occurred during creation: ", result.reason);
|
|
240
|
-
}
|
|
241
235
|
});
|
|
236
|
+
// results.forEach((result) => {
|
|
237
|
+
// if (result.status === "rejected") {
|
|
238
|
+
// console.error("A process batch promise was rejected:", result.reason);
|
|
239
|
+
// logger.error("An error occurred during creation: ", result.reason);
|
|
240
|
+
// }
|
|
241
|
+
// });
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
async handleCreate(context, finalItem, updateDefs, id) {
|
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.11",
|
|
5
5
|
"main": "src/main.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
@@ -258,147 +258,145 @@ export class ImportController {
|
|
|
258
258
|
) {
|
|
259
259
|
for (let i = 0; i < dataToImport.length; i += this.batchLimit) {
|
|
260
260
|
const batch = dataToImport.slice(i, i + this.batchLimit);
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
261
|
+
batch.map(async (item: any) => {
|
|
262
|
+
let context = this.createContext(db, collection, item);
|
|
263
|
+
let finalItem = await this.transformData(
|
|
264
|
+
item,
|
|
265
|
+
importDef.attributeMappings
|
|
266
|
+
);
|
|
267
|
+
let createIdToUse: string | undefined = undefined;
|
|
268
|
+
let associatedDoc: Models.Document | undefined;
|
|
269
|
+
if (
|
|
270
|
+
isMembersCollection &&
|
|
271
|
+
(finalItem.hasOwnProperty("email") || item.hasOwnProperty("phone"))
|
|
272
|
+
) {
|
|
273
|
+
console.log("Found members collection, creating user...");
|
|
274
|
+
const usersController = new UsersController(
|
|
275
|
+
this.config,
|
|
276
|
+
this.database
|
|
267
277
|
);
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
const usersController = new UsersController(
|
|
276
|
-
this.config,
|
|
277
|
-
this.database
|
|
278
|
-
);
|
|
279
|
-
const userToCreate = AuthUserCreateSchema.safeParse({
|
|
280
|
-
...finalItem,
|
|
281
|
-
});
|
|
282
|
-
if (!userToCreate.success) {
|
|
283
|
-
console.error(userToCreate.error);
|
|
284
|
-
logger.error(userToCreate.error);
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
const user = await usersController.createUserAndReturn(
|
|
288
|
-
userToCreate.data
|
|
289
|
-
);
|
|
290
|
-
createIdToUse = user.$id;
|
|
291
|
-
context.docId = createIdToUse;
|
|
292
|
-
context = { ...context, ...user };
|
|
293
|
-
console.log(
|
|
294
|
-
"Created user, deleting keys in finalItem that exist in user..."
|
|
295
|
-
);
|
|
296
|
-
const associatedDocFound = await this.database.listDocuments(
|
|
297
|
-
db.$id,
|
|
298
|
-
context.collId,
|
|
299
|
-
[Query.equal("$id", createIdToUse)]
|
|
300
|
-
);
|
|
301
|
-
if (associatedDocFound.documents.length > 0) {
|
|
302
|
-
associatedDoc = associatedDocFound.documents[0];
|
|
303
|
-
}
|
|
304
|
-
// Delete keys in finalItem that also exist in user
|
|
305
|
-
let deletedKeys: string[] = [];
|
|
306
|
-
Object.keys(finalItem).forEach((key) => {
|
|
307
|
-
if (user.hasOwnProperty(key)) {
|
|
308
|
-
delete finalItem[key];
|
|
309
|
-
deletedKeys.push(key);
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
console.log(
|
|
313
|
-
`Set createIdToUse to ${createIdToUse}. Deleted keys: ${deletedKeys.join(
|
|
314
|
-
", "
|
|
315
|
-
)}.`
|
|
316
|
-
);
|
|
317
|
-
} else if (isMembersCollection) {
|
|
318
|
-
logger.error(
|
|
319
|
-
`Skipping user & contact creation for ${item} due to lack of email...`
|
|
320
|
-
);
|
|
278
|
+
const userToCreate = AuthUserCreateSchema.safeParse({
|
|
279
|
+
...finalItem,
|
|
280
|
+
});
|
|
281
|
+
if (!userToCreate.success) {
|
|
282
|
+
console.error(userToCreate.error);
|
|
283
|
+
logger.error(userToCreate.error);
|
|
284
|
+
return;
|
|
321
285
|
}
|
|
286
|
+
const user = await usersController.createUserAndReturn(
|
|
287
|
+
userToCreate.data
|
|
288
|
+
);
|
|
289
|
+
createIdToUse = user.$id;
|
|
290
|
+
context.docId = createIdToUse;
|
|
291
|
+
context = { ...context, ...user };
|
|
292
|
+
console.log(
|
|
293
|
+
"Created user, deleting keys in finalItem that exist in user..."
|
|
294
|
+
);
|
|
295
|
+
const associatedDocFound = await this.database.listDocuments(
|
|
296
|
+
db.$id,
|
|
297
|
+
context.collId,
|
|
298
|
+
[Query.equal("$id", createIdToUse)]
|
|
299
|
+
);
|
|
300
|
+
if (associatedDocFound.documents.length > 0) {
|
|
301
|
+
associatedDoc = associatedDocFound.documents[0];
|
|
302
|
+
}
|
|
303
|
+
// Delete keys in finalItem that also exist in user
|
|
304
|
+
let deletedKeys: string[] = [];
|
|
305
|
+
Object.keys(finalItem).forEach((key) => {
|
|
306
|
+
if (user.hasOwnProperty(key)) {
|
|
307
|
+
delete finalItem[key];
|
|
308
|
+
deletedKeys.push(key);
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
console.log(
|
|
312
|
+
`Set createIdToUse to ${createIdToUse}. Deleted keys: ${deletedKeys.join(
|
|
313
|
+
", "
|
|
314
|
+
)}.`
|
|
315
|
+
);
|
|
316
|
+
} else if (isMembersCollection) {
|
|
317
|
+
logger.error(
|
|
318
|
+
`Skipping user & contact creation for ${item} due to lack of email...`
|
|
319
|
+
);
|
|
320
|
+
}
|
|
322
321
|
|
|
323
|
-
|
|
322
|
+
context = { ...context, ...finalItem };
|
|
324
323
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
324
|
+
if (
|
|
325
|
+
!(await this.importDataActions.validateItem(
|
|
326
|
+
finalItem,
|
|
327
|
+
importDef.attributeMappings,
|
|
328
|
+
context
|
|
329
|
+
))
|
|
330
|
+
) {
|
|
331
|
+
console.error("Validation failed for item:", finalItem);
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
335
334
|
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
}
|
|
350
|
-
logger.info(`Handled create for ${context.docId}}`);
|
|
351
|
-
} else {
|
|
352
|
-
const updatedContext = await this.handleUpdate(
|
|
353
|
-
context,
|
|
354
|
-
finalItem,
|
|
355
|
-
importDef
|
|
356
|
-
);
|
|
357
|
-
if (updatedContext) {
|
|
358
|
-
afterContext = updatedContext;
|
|
359
|
-
}
|
|
360
|
-
logger.info(`Handled update for ${context.docId}`);
|
|
361
|
-
}
|
|
362
|
-
if (afterContext) {
|
|
363
|
-
context = { ...context, ...afterContext };
|
|
335
|
+
let afterContext;
|
|
336
|
+
if (
|
|
337
|
+
(importDef.type === "create" || !importDef.type) &&
|
|
338
|
+
!associatedDoc
|
|
339
|
+
) {
|
|
340
|
+
const createdContext = await this.handleCreate(
|
|
341
|
+
context,
|
|
342
|
+
finalItem,
|
|
343
|
+
updateDefs,
|
|
344
|
+
createIdToUse
|
|
345
|
+
);
|
|
346
|
+
if (createdContext) {
|
|
347
|
+
afterContext = createdContext;
|
|
364
348
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
if (
|
|
373
|
-
|
|
374
|
-
`Pushing to post-import actions queue for ${context.docId}`
|
|
375
|
-
);
|
|
376
|
-
const afterImportOperationContext = ContextObject.parse({
|
|
377
|
-
dbId: db.$id,
|
|
378
|
-
collectionId: collection.$id,
|
|
379
|
-
finalItem: finalItem,
|
|
380
|
-
attributeMappings: attributeMappingsWithActions,
|
|
381
|
-
context: afterImportActionContext,
|
|
382
|
-
});
|
|
383
|
-
await createOrFindAfterImportOperation(
|
|
384
|
-
this.database,
|
|
385
|
-
context.collId,
|
|
386
|
-
afterImportOperationContext
|
|
387
|
-
);
|
|
388
|
-
// this.postImportActionsQueue.push({
|
|
389
|
-
// context: afterImportActionContext,
|
|
390
|
-
// finalItem: finalItem,
|
|
391
|
-
// attributeMappings: attributeMappingsWithActions,
|
|
392
|
-
// });
|
|
349
|
+
logger.info(`Handled create for ${context.docId}}`);
|
|
350
|
+
} else {
|
|
351
|
+
const updatedContext = await this.handleUpdate(
|
|
352
|
+
context,
|
|
353
|
+
finalItem,
|
|
354
|
+
importDef
|
|
355
|
+
);
|
|
356
|
+
if (updatedContext) {
|
|
357
|
+
afterContext = updatedContext;
|
|
393
358
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
359
|
+
logger.info(`Handled update for ${context.docId}`);
|
|
360
|
+
}
|
|
361
|
+
if (afterContext) {
|
|
362
|
+
context = { ...context, ...afterContext };
|
|
363
|
+
}
|
|
364
|
+
const afterImportActionContext = structuredClone(context);
|
|
365
|
+
const attributeMappingsWithActions =
|
|
366
|
+
this.getAttributeMappingsWithActions(
|
|
367
|
+
importDef.attributeMappings,
|
|
368
|
+
context,
|
|
369
|
+
finalItem
|
|
370
|
+
);
|
|
371
|
+
if (attributeMappingsWithActions.some((m) => m.postImportActions)) {
|
|
372
|
+
logger.info(
|
|
373
|
+
`Pushing to post-import actions queue for ${context.docId}`
|
|
374
|
+
);
|
|
375
|
+
const afterImportOperationContext = ContextObject.parse({
|
|
376
|
+
dbId: db.$id,
|
|
377
|
+
collectionId: collection.$id,
|
|
378
|
+
finalItem: finalItem,
|
|
379
|
+
attributeMappings: attributeMappingsWithActions,
|
|
380
|
+
context: afterImportActionContext,
|
|
381
|
+
});
|
|
382
|
+
await createOrFindAfterImportOperation(
|
|
383
|
+
this.database,
|
|
384
|
+
context.collId,
|
|
385
|
+
afterImportOperationContext
|
|
386
|
+
);
|
|
387
|
+
// this.postImportActionsQueue.push({
|
|
388
|
+
// context: afterImportActionContext,
|
|
389
|
+
// finalItem: finalItem,
|
|
390
|
+
// attributeMappings: attributeMappingsWithActions,
|
|
391
|
+
// });
|
|
400
392
|
}
|
|
401
393
|
});
|
|
394
|
+
// results.forEach((result) => {
|
|
395
|
+
// if (result.status === "rejected") {
|
|
396
|
+
// console.error("A process batch promise was rejected:", result.reason);
|
|
397
|
+
// logger.error("An error occurred during creation: ", result.reason);
|
|
398
|
+
// }
|
|
399
|
+
// });
|
|
402
400
|
}
|
|
403
401
|
}
|
|
404
402
|
|