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.
@@ -1,11 +1,11 @@
1
- import _ from "lodash";
1
+ import { isNumber, isString, isBoolean, isArray, isPlainObject, isNull, isUndefined, isDate, isEmpty, isInteger, isArrayLike, isArrayLikeObject, isFunction, isLength, isMap, isSet, isRegExp, isSymbol, isObjectLike, isSafeInteger, isTypedArray, isEqual, isMatch, has, get, } from "es-toolkit/compat";
2
2
  export const validationRules = {
3
- isNumber: (value) => _.isNumber(value),
4
- isString: (value) => _.isString(value),
5
- isBoolean: (value) => _.isBoolean(value),
6
- isArray: (value) => _.isArray(value),
7
- isObject: (value) => _.isObject(value) && !_.isArray(value) && !_.isFunction(value),
8
- isNull: (value) => _.isNull(value),
3
+ isNumber: (value) => isNumber(value),
4
+ isString: (value) => isString(value),
5
+ isBoolean: (value) => isBoolean(value),
6
+ isArray: (value) => isArray(value),
7
+ isObject: (value) => isPlainObject(value) && !isArray(value) && !isFunction(value),
8
+ isNull: (value) => isNull(value),
9
9
  isValidEmail: (value) => value.match(/^[\w\-\.]+@([\w-]+\.)+[\w-]{2,}$/) !== null,
10
10
  isValidPhone: (value) => value.match(/^[+]?[(]?[0-9]{3}[)]?[-\s.]?[0-9]{3}[-\s.]?[0-9]{4,6}$/im) !==
11
11
  null,
@@ -16,27 +16,27 @@ export const validationRules = {
16
16
  isValidHexAlpha: (value) => value.match(/^#([a-f0-9]{8}|[a-f0-9]{4})$/i) !== null,
17
17
  isValidDate: (value) => value.match(/^\d{4}-\d{2}-\d{2}$/) !== null,
18
18
  isValidTime: (value) => value.match(/^\d{2}:\d{2}(:\d{2})?$/) !== null,
19
- isNullish: (value) => _.isNull(value) || _.isUndefined(value),
20
- isUndefined: (value) => _.isUndefined(value),
21
- isDefined: (value) => !_.isUndefined(value) && !_.isNull(value) && !_.isEmpty(value),
22
- isDate: (value) => _.isDate(value),
23
- isEmpty: (value) => _.isEmpty(value),
24
- isInteger: (value) => _.isInteger(value),
25
- isFloat: (value) => _.isNumber(value) && !_.isInteger(value),
26
- isArrayLike: (value) => _.isArrayLike(value),
27
- isArrayLikeObject: (value) => _.isArrayLikeObject(value),
28
- isFunction: (value) => _.isFunction(value),
29
- isLength: (value) => _.isLength(value),
30
- isMap: (value) => _.isMap(value),
31
- isSet: (value) => _.isSet(value),
32
- isRegExp: (value) => _.isRegExp(value),
33
- isSymbol: (value) => _.isSymbol(value),
34
- isObjectLike: (value) => _.isObjectLike(value),
35
- isPlainObject: (value) => _.isPlainObject(value),
36
- isSafeInteger: (value) => _.isSafeInteger(value),
37
- isTypedArray: (value) => _.isTypedArray(value),
38
- isEqual: (value, other) => _.isEqual(value, other),
39
- isMatch: (object, source) => _.isMatch(object, source),
40
- has: (object, path) => _.has(object, path),
41
- get: (object, path, defaultValue) => _.get(object, path, defaultValue),
19
+ isNullish: (value) => isNull(value) || isUndefined(value),
20
+ isUndefined: (value) => isUndefined(value),
21
+ isDefined: (value) => !isUndefined(value) && !isNull(value) && !isEmpty(value),
22
+ isDate: (value) => isDate(value),
23
+ isEmpty: (value) => isEmpty(value),
24
+ isInteger: (value) => isInteger(value),
25
+ isFloat: (value) => isNumber(value) && !isInteger(value),
26
+ isArrayLike: (value) => isArrayLike(value),
27
+ isArrayLikeObject: (value) => isArrayLikeObject(value),
28
+ isFunction: (value) => isFunction(value),
29
+ isLength: (value) => isLength(value),
30
+ isMap: (value) => isMap(value),
31
+ isSet: (value) => isSet(value),
32
+ isRegExp: (value) => isRegExp(value),
33
+ isSymbol: (value) => isSymbol(value),
34
+ isObjectLike: (value) => isObjectLike(value),
35
+ isPlainObject: (value) => isPlainObject(value),
36
+ isSafeInteger: (value) => isSafeInteger(value),
37
+ isTypedArray: (value) => isTypedArray(value),
38
+ isEqual: (value, other) => isEqual(value, other),
39
+ isMatch: (object, source) => isMatch(object, source),
40
+ has: (object, path) => has(object, path),
41
+ get: (object, path, defaultValue) => get(object, path, defaultValue),
42
42
  };
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.10.81",
4
+ "version": "0.10.83",
5
5
  "main": "src/main.ts",
6
6
  "type": "module",
7
7
  "repository": {
@@ -35,10 +35,10 @@
35
35
  "chalk": "^5.3.0",
36
36
  "cli-progress": "^3.12.0",
37
37
  "commander": "^12.1.0",
38
+ "es-toolkit": "^1.32.0",
38
39
  "ignore": "^6.0.2",
39
40
  "inquirer": "^9.3.6",
40
41
  "js-yaml": "^4.1.0",
41
- "lodash": "^4.17.21",
42
42
  "luxon": "^3.5.0",
43
43
  "nanostores": "^0.10.3",
44
44
  "node-appwrite": "^14.1.0",
@@ -5,7 +5,6 @@ import {
5
5
  type Attribute,
6
6
  } from "appwrite-utils";
7
7
  import { nameToIdMapping, enqueueOperation } from "../migrations/queue.js";
8
- import _ from "lodash";
9
8
  import { delay, tryAwaitWithRetry } from "../utils/helperFunctions.js";
10
9
  import chalk from "chalk";
11
10
 
@@ -14,24 +13,24 @@ const attributesSame = (
14
13
  configAttribute: Attribute
15
14
  ): boolean => {
16
15
  const attributesToCheck = [
17
- 'key',
18
- 'type',
19
- 'array',
20
- 'encrypted',
21
- 'required',
22
- 'size',
23
- 'min',
24
- 'max',
25
- 'xdefault',
26
- 'elements',
27
- 'relationType',
28
- 'twoWay',
29
- 'twoWayKey',
30
- 'onDelete',
31
- 'relatedCollection'
16
+ "key",
17
+ "type",
18
+ "array",
19
+ "encrypted",
20
+ "required",
21
+ "size",
22
+ "min",
23
+ "max",
24
+ "xdefault",
25
+ "elements",
26
+ "relationType",
27
+ "twoWay",
28
+ "twoWayKey",
29
+ "onDelete",
30
+ "relatedCollection",
32
31
  ];
33
32
 
34
- return attributesToCheck.every(attr => {
33
+ return attributesToCheck.every((attr) => {
35
34
  // Check if both objects have the attribute
36
35
  const dbHasAttr = attr in databaseAttribute;
37
36
  const configHasAttr = attr in configAttribute;
@@ -42,7 +41,10 @@ const attributesSame = (
42
41
  const configValue = configAttribute[attr as keyof typeof configAttribute];
43
42
 
44
43
  // Consider undefined and null as equivalent
45
- if ((dbValue === undefined || dbValue === null) && (configValue === undefined || configValue === null)) {
44
+ if (
45
+ (dbValue === undefined || dbValue === null) &&
46
+ (configValue === undefined || configValue === null)
47
+ ) {
46
48
  return true;
47
49
  }
48
50
 
@@ -91,10 +93,18 @@ export const createOrUpdateAttribute = async (
91
93
  foundAttribute = undefined;
92
94
  }
93
95
 
94
- if (foundAttribute && attributesSame(foundAttribute, attribute) && updateEnabled) {
96
+ if (
97
+ foundAttribute &&
98
+ attributesSame(foundAttribute, attribute) &&
99
+ updateEnabled
100
+ ) {
95
101
  // No need to do anything, they are the same
96
102
  return;
97
- } else if (foundAttribute && !attributesSame(foundAttribute, attribute) && updateEnabled) {
103
+ } else if (
104
+ foundAttribute &&
105
+ !attributesSame(foundAttribute, attribute) &&
106
+ updateEnabled
107
+ ) {
98
108
  // console.log(
99
109
  // `Updating attribute with same key ${attribute.key} but different values`
100
110
  // );
@@ -103,9 +113,15 @@ export const createOrUpdateAttribute = async (
103
113
  ...attribute,
104
114
  };
105
115
  action = "update";
106
- } else if (!updateEnabled && foundAttribute && !attributesSame(foundAttribute, attribute)) {
116
+ } else if (
117
+ !updateEnabled &&
118
+ foundAttribute &&
119
+ !attributesSame(foundAttribute, attribute)
120
+ ) {
107
121
  await db.deleteAttribute(dbId, collection.$id, attribute.key);
108
- console.log(`Deleted attribute: ${attribute.key} to recreate it because they diff (update disabled temporarily)`);
122
+ console.log(
123
+ `Deleted attribute: ${attribute.key} to recreate it because they diff (update disabled temporarily)`
124
+ );
109
125
  return;
110
126
  }
111
127
 
@@ -168,7 +184,9 @@ export const createOrUpdateAttribute = async (
168
184
  finalAttribute.key,
169
185
  finalAttribute.size,
170
186
  finalAttribute.required || false,
171
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
187
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
188
+ ? finalAttribute.xdefault
189
+ : null,
172
190
  finalAttribute.array || false,
173
191
  finalAttribute.encrypted
174
192
  )
@@ -181,7 +199,9 @@ export const createOrUpdateAttribute = async (
181
199
  collection.$id,
182
200
  finalAttribute.key,
183
201
  finalAttribute.required || false,
184
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
202
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
203
+ ? finalAttribute.xdefault
204
+ : null
185
205
  )
186
206
  );
187
207
  }
@@ -209,7 +229,9 @@ export const createOrUpdateAttribute = async (
209
229
  finalAttribute.required || false,
210
230
  finalAttribute.min || -2147483647,
211
231
  finalAttribute.max || 2147483647,
212
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
232
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
233
+ ? finalAttribute.xdefault
234
+ : null,
213
235
  finalAttribute.array || false
214
236
  )
215
237
  );
@@ -235,7 +257,9 @@ export const createOrUpdateAttribute = async (
235
257
  finalAttribute.required || false,
236
258
  finalAttribute.min || -2147483647,
237
259
  finalAttribute.max || 2147483647,
238
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null
260
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
261
+ ? finalAttribute.xdefault
262
+ : null
239
263
  )
240
264
  );
241
265
  }
@@ -251,7 +275,9 @@ export const createOrUpdateAttribute = async (
251
275
  finalAttribute.required || false,
252
276
  finalAttribute.min || -2147483647,
253
277
  finalAttribute.max || 2147483647,
254
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
278
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
279
+ ? finalAttribute.xdefault
280
+ : null,
255
281
  finalAttribute.array || false
256
282
  )
257
283
  );
@@ -265,7 +291,9 @@ export const createOrUpdateAttribute = async (
265
291
  finalAttribute.required || false,
266
292
  finalAttribute.min || -2147483647,
267
293
  finalAttribute.max || 2147483647,
268
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null
294
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
295
+ ? finalAttribute.xdefault
296
+ : null
269
297
  )
270
298
  );
271
299
  }
@@ -279,7 +307,9 @@ export const createOrUpdateAttribute = async (
279
307
  collection.$id,
280
308
  finalAttribute.key,
281
309
  finalAttribute.required || false,
282
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
310
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
311
+ ? finalAttribute.xdefault
312
+ : null,
283
313
  finalAttribute.array || false
284
314
  )
285
315
  );
@@ -291,7 +321,9 @@ export const createOrUpdateAttribute = async (
291
321
  collection.$id,
292
322
  finalAttribute.key,
293
323
  finalAttribute.required || false,
294
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null
324
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
325
+ ? finalAttribute.xdefault
326
+ : null
295
327
  )
296
328
  );
297
329
  }
@@ -305,7 +337,9 @@ export const createOrUpdateAttribute = async (
305
337
  collection.$id,
306
338
  finalAttribute.key,
307
339
  finalAttribute.required || false,
308
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
340
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
341
+ ? finalAttribute.xdefault
342
+ : null,
309
343
  finalAttribute.array || false
310
344
  )
311
345
  );
@@ -317,7 +351,9 @@ export const createOrUpdateAttribute = async (
317
351
  collection.$id,
318
352
  finalAttribute.key,
319
353
  finalAttribute.required || false,
320
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null
354
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
355
+ ? finalAttribute.xdefault
356
+ : null
321
357
  )
322
358
  );
323
359
  }
@@ -331,7 +367,9 @@ export const createOrUpdateAttribute = async (
331
367
  collection.$id,
332
368
  finalAttribute.key,
333
369
  finalAttribute.required || false,
334
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
370
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
371
+ ? finalAttribute.xdefault
372
+ : null,
335
373
  finalAttribute.array || false
336
374
  )
337
375
  );
@@ -343,7 +381,9 @@ export const createOrUpdateAttribute = async (
343
381
  collection.$id,
344
382
  finalAttribute.key,
345
383
  finalAttribute.required || false,
346
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null
384
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
385
+ ? finalAttribute.xdefault
386
+ : null
347
387
  )
348
388
  );
349
389
  }
@@ -357,7 +397,9 @@ export const createOrUpdateAttribute = async (
357
397
  collection.$id,
358
398
  finalAttribute.key,
359
399
  finalAttribute.required || false,
360
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
400
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
401
+ ? finalAttribute.xdefault
402
+ : null,
361
403
  finalAttribute.array || false
362
404
  )
363
405
  );
@@ -369,7 +411,9 @@ export const createOrUpdateAttribute = async (
369
411
  collection.$id,
370
412
  finalAttribute.key,
371
413
  finalAttribute.required || false,
372
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null
414
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
415
+ ? finalAttribute.xdefault
416
+ : null
373
417
  )
374
418
  );
375
419
  }
@@ -383,7 +427,9 @@ export const createOrUpdateAttribute = async (
383
427
  collection.$id,
384
428
  finalAttribute.key,
385
429
  finalAttribute.required || false,
386
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
430
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
431
+ ? finalAttribute.xdefault
432
+ : null,
387
433
  finalAttribute.array || false
388
434
  )
389
435
  );
@@ -395,7 +441,9 @@ export const createOrUpdateAttribute = async (
395
441
  collection.$id,
396
442
  finalAttribute.key,
397
443
  finalAttribute.required || false,
398
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null
444
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
445
+ ? finalAttribute.xdefault
446
+ : null
399
447
  )
400
448
  );
401
449
  }
@@ -410,7 +458,9 @@ export const createOrUpdateAttribute = async (
410
458
  finalAttribute.key,
411
459
  finalAttribute.elements,
412
460
  finalAttribute.required || false,
413
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null,
461
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
462
+ ? finalAttribute.xdefault
463
+ : null,
414
464
  finalAttribute.array || false
415
465
  )
416
466
  );
@@ -423,7 +473,9 @@ export const createOrUpdateAttribute = async (
423
473
  finalAttribute.key,
424
474
  finalAttribute.elements,
425
475
  finalAttribute.required || false,
426
- finalAttribute.xdefault !== undefined && !finalAttribute.required ? finalAttribute.xdefault : null
476
+ finalAttribute.xdefault !== undefined && !finalAttribute.required
477
+ ? finalAttribute.xdefault
478
+ : null
427
479
  )
428
480
  );
429
481
  }
@@ -468,26 +520,47 @@ export const createUpdateCollectionAttributes = async (
468
520
  attributes: Attribute[]
469
521
  ): Promise<void> => {
470
522
  console.log(
471
- chalk.green(`Creating/Updating attributes for collection: ${collection.name}`)
523
+ chalk.green(
524
+ `Creating/Updating attributes for collection: ${collection.name}`
525
+ )
472
526
  );
473
527
 
474
- // @ts-expect-error
475
- const existingAttributes: Attribute[] = collection.attributes.map((attr) => parseAttribute(attr)) || [];
528
+ const existingAttributes: Attribute[] =
529
+ // @ts-expect-error
530
+ collection.attributes.map((attr) => parseAttribute(attr)) || [];
476
531
 
477
- const attributesToRemove = existingAttributes.filter((attr) => !attributes.some((a) => a.key === attr.key));
478
- const indexesToRemove = collection.indexes.filter((index) => attributesToRemove.some((attr) => index.attributes.includes(attr.key)));
532
+ const attributesToRemove = existingAttributes.filter(
533
+ (attr) => !attributes.some((a) => a.key === attr.key)
534
+ );
535
+ const indexesToRemove = collection.indexes.filter((index) =>
536
+ attributesToRemove.some((attr) => index.attributes.includes(attr.key))
537
+ );
479
538
 
480
539
  if (attributesToRemove.length > 0) {
481
540
  if (indexesToRemove.length > 0) {
482
- console.log(chalk.red(`Removing indexes as they rely on an attribute that is being removed: ${indexesToRemove.map((index) => index.key).join(", ")}`));
541
+ console.log(
542
+ chalk.red(
543
+ `Removing indexes as they rely on an attribute that is being removed: ${indexesToRemove
544
+ .map((index) => index.key)
545
+ .join(", ")}`
546
+ )
547
+ );
483
548
  for (const index of indexesToRemove) {
484
- await tryAwaitWithRetry(async () => await db.deleteIndex(dbId, collection.$id, index.key));
549
+ await tryAwaitWithRetry(
550
+ async () => await db.deleteIndex(dbId, collection.$id, index.key)
551
+ );
485
552
  await delay(100);
486
553
  }
487
554
  }
488
555
  for (const attr of attributesToRemove) {
489
- console.log(chalk.red(`Removing attribute: ${attr.key} as it is no longer in the collection`));
490
- await tryAwaitWithRetry(async () => await db.deleteAttribute(dbId, collection.$id, attr.key));
556
+ console.log(
557
+ chalk.red(
558
+ `Removing attribute: ${attr.key} as it is no longer in the collection`
559
+ )
560
+ );
561
+ await tryAwaitWithRetry(
562
+ async () => await db.deleteAttribute(dbId, collection.$id, attr.key)
563
+ );
491
564
  await delay(50);
492
565
  }
493
566
  }
@@ -496,7 +569,10 @@ export const createUpdateCollectionAttributes = async (
496
569
  for (let i = 0; i < attributes.length; i += batchSize) {
497
570
  const batch = attributes.slice(i, i + batchSize);
498
571
  const attributePromises = batch.map((attribute) =>
499
- tryAwaitWithRetry(async () => await createOrUpdateAttribute(db, dbId, collection, attribute))
572
+ tryAwaitWithRetry(
573
+ async () =>
574
+ await createOrUpdateAttribute(db, dbId, collection, attribute)
575
+ )
500
576
  );
501
577
 
502
578
  const results = await Promise.allSettled(attributePromises);