appwrite-utils-cli 0.0.9 → 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
- const results = await Promise.allSettled(batch.map(async (item) => {
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) {
@@ -1,5 +1,4 @@
1
1
  import { type Databases } from "node-appwrite";
2
- import { type Operation } from "./backup.js";
3
2
  import { z } from "zod";
4
3
  /**
5
4
  * Object that contains the context for an action that needs to be executed after import
@@ -136,7 +135,7 @@ export declare const ContextObject: z.ZodObject<{
136
135
  }>;
137
136
  export type ContextObject = z.infer<typeof ContextObject>;
138
137
  export declare const createOrFindAfterImportOperation: (database: Databases, collectionId: string, context: ContextObject) => Promise<void>;
139
- export declare const addBatch: (database: Databases, operation: Operation, data: string) => Promise<string>;
138
+ export declare const addBatch: (database: Databases, data: string) => Promise<string>;
140
139
  export declare const getAfterImportOperations: (database: Databases, collectionId: string) => Promise<{
141
140
  error: string;
142
141
  status: "error" | "pending" | "ready" | "in_progress" | "completed" | "cancelled";
@@ -29,19 +29,16 @@ export const createOrFindAfterImportOperation = async (database, collectionId, c
29
29
  // Directly create a new batch for the context without checking for an existing batch
30
30
  const contextData = JSON.stringify(context);
31
31
  // Create a new batch with the contextData
32
- const newBatchId = await addBatch(database, operation, contextData);
32
+ const newBatchId = await addBatch(database, contextData);
33
33
  // Update the operation with the new batch's $id
34
- operation.batches.push(newBatchId);
34
+ operation.batches = [...operation.batches, newBatchId];
35
35
  await database.updateDocument("migrations", "currentOperations", operation.$id, { batches: operation.batches });
36
36
  };
37
- export const addBatch = async (database, operation, data) => {
37
+ export const addBatch = async (database, data) => {
38
38
  const batch = await database.createDocument("migrations", "batches", ID.unique(), {
39
39
  data,
40
40
  processed: false,
41
41
  });
42
- await database.updateDocument("migrations", "currentOperations", operation.$id, {
43
- batches: [...(operation.batches || []), batch.$id],
44
- });
45
42
  return batch.$id;
46
43
  };
47
44
  export const getAfterImportOperations = async (database, collectionId) => {
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.9",
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
- const results = await Promise.allSettled(
262
- batch.map(async (item: any) => {
263
- let context = this.createContext(db, collection, item);
264
- let finalItem = await this.transformData(
265
- item,
266
- importDef.attributeMappings
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
- let createIdToUse: string | undefined = undefined;
269
- let associatedDoc: Models.Document | undefined;
270
- if (
271
- isMembersCollection &&
272
- (finalItem.hasOwnProperty("email") || item.hasOwnProperty("phone"))
273
- ) {
274
- console.log("Found members collection, creating user...");
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
- context = { ...context, ...finalItem };
322
+ context = { ...context, ...finalItem };
324
323
 
325
- if (
326
- !(await this.importDataActions.validateItem(
327
- finalItem,
328
- importDef.attributeMappings,
329
- context
330
- ))
331
- ) {
332
- console.error("Validation failed for item:", finalItem);
333
- return;
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
- let afterContext;
337
- if (
338
- (importDef.type === "create" || !importDef.type) &&
339
- !associatedDoc
340
- ) {
341
- const createdContext = await this.handleCreate(
342
- context,
343
- finalItem,
344
- updateDefs,
345
- createIdToUse
346
- );
347
- if (createdContext) {
348
- afterContext = createdContext;
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
- const afterImportActionContext = structuredClone(context);
366
- const attributeMappingsWithActions =
367
- this.getAttributeMappingsWithActions(
368
- importDef.attributeMappings,
369
- context,
370
- finalItem
371
- );
372
- if (attributeMappingsWithActions.some((m) => m.postImportActions)) {
373
- logger.info(
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
- results.forEach((result) => {
397
- if (result.status === "rejected") {
398
- console.error("A process batch promise was rejected:", result.reason);
399
- logger.error("An error occurred during creation: ", result.reason);
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
 
@@ -42,9 +42,9 @@ export const createOrFindAfterImportOperation = async (
42
42
  // Directly create a new batch for the context without checking for an existing batch
43
43
  const contextData = JSON.stringify(context);
44
44
  // Create a new batch with the contextData
45
- const newBatchId = await addBatch(database, operation, contextData);
45
+ const newBatchId = await addBatch(database, contextData);
46
46
  // Update the operation with the new batch's $id
47
- operation.batches.push(newBatchId);
47
+ operation.batches = [...operation.batches, newBatchId];
48
48
  await database.updateDocument(
49
49
  "migrations",
50
50
  "currentOperations",
@@ -53,11 +53,7 @@ export const createOrFindAfterImportOperation = async (
53
53
  );
54
54
  };
55
55
 
56
- export const addBatch = async (
57
- database: Databases,
58
- operation: Operation,
59
- data: string
60
- ) => {
56
+ export const addBatch = async (database: Databases, data: string) => {
61
57
  const batch = await database.createDocument(
62
58
  "migrations",
63
59
  "batches",
@@ -67,14 +63,6 @@ export const addBatch = async (
67
63
  processed: false,
68
64
  }
69
65
  );
70
- await database.updateDocument(
71
- "migrations",
72
- "currentOperations",
73
- operation.$id,
74
- {
75
- batches: [...(operation.batches || []), batch.$id],
76
- }
77
- );
78
66
  return batch.$id;
79
67
  };
80
68