appwrite-utils-cli 0.0.270 → 0.0.272

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 CHANGED
@@ -118,6 +118,8 @@ This setup ensures that developers have robust tools at their fingertips to mana
118
118
 
119
119
  ### Changelog
120
120
 
121
+ - 0.0.272: That's what I get for not testing lmao, also updated logic for checking for existing attributes to take the `format` into consideration from the database (URL's are not of `type: "url"`, they are of `format: "url"`)
122
+ - 0.0.271: Small change to update attributes that are different from each other by deleting the attribute and recreating, as we cannot update most things
121
123
  - 0.0.270: Fixed enums in `--sync`, added optional OpenAPI generation (in progress, almost done, but wanted to push other changes), added `--endpoint`, `--project`, `--key` as optional parameters to change the target destination (shoutout to [pingu24k](https://github.com/pingu2k4) for pointing out these bugs and suggesting those changes for endpoint customization)
122
124
  - 0.0.254: Added `--sync` to synchronize your Appwrite instance with your local `appwriteConfig.yaml` and generate schemas
123
125
  - 0.0.253: Added `--writeData` (or `--write-data`) to command to write the output of the import data to a file called dataLoaderOutput in your root dir
@@ -1,4 +1,4 @@
1
1
  import { type Databases, type Models } from "node-appwrite";
2
- import type { Attribute } from "./schema.js";
2
+ import { type Attribute } from "./schema.js";
3
3
  export declare const createOrUpdateAttribute: (db: Databases, dbId: string, collection: Models.Collection, attribute: Attribute) => Promise<void>;
4
4
  export declare const createUpdateCollectionAttributes: (db: Databases, dbId: string, collection: Models.Collection, attributes: Attribute[]) => Promise<void>;
@@ -1,21 +1,49 @@
1
1
  import { Query } from "node-appwrite";
2
+ import { parseAttribute } from "./schema.js";
2
3
  import { nameToIdMapping, enqueueOperation } from "./queue.js";
4
+ import _ from "lodash";
5
+ const attributesSame = (a, b) => {
6
+ // Direct type comparison for non-string types
7
+ if (a.type === b.type &&
8
+ !((a.type === "string" && a.format) || (b.type === "string" && b.format))) {
9
+ return a.key === b.key && a.array === b.array && a.required === b.required;
10
+ }
11
+ if (a.type === "string" && a.format) {
12
+ // @ts-expect-error
13
+ a.type = a.format;
14
+ }
15
+ if (b.type === "string" && b.format) {
16
+ // @ts-expect-error
17
+ b.type = b.format;
18
+ }
19
+ // Handling string types with specific formats in Appwrite
20
+ if (a.type === "string" && b.type === "string") {
21
+ return (a.key === b.key &&
22
+ a.format === b.format &&
23
+ a.array === b.array &&
24
+ a.required === b.required);
25
+ }
26
+ // Fallback to false if none of the above conditions are met
27
+ return false;
28
+ };
3
29
  export const createOrUpdateAttribute = async (db, dbId, collection, attribute) => {
4
30
  let action = "create";
5
31
  let foundAttribute;
6
32
  try {
7
33
  foundAttribute = await db.getAttribute(dbId, collection.$id, attribute.key);
34
+ foundAttribute = parseAttribute(foundAttribute);
8
35
  }
9
36
  catch (error) {
10
37
  foundAttribute = undefined;
11
38
  }
12
39
  let numSameAttributes = 0;
13
- if (foundAttribute && foundAttribute.key === attribute.key) {
40
+ if (foundAttribute && attributesSame(foundAttribute, attribute)) {
14
41
  numSameAttributes++;
15
42
  return;
16
43
  }
17
- else if (foundAttribute) {
18
- action = "update";
44
+ else if (foundAttribute && !attributesSame(foundAttribute, attribute)) {
45
+ console.log(`Deleting attribute with same key ${attribute.key} -- ${foundAttribute.key} but different values, assuming update...`);
46
+ await db.deleteAttribute(dbId, collection.$id, attribute.key);
19
47
  }
20
48
  // Relationship attribute logic with adjustments
21
49
  let collectionFoundViaRelatedCollection;
@@ -332,6 +332,13 @@ export const attributeSchema = z.discriminatedUnion("type", [
332
332
  relationshipAttributeSchema,
333
333
  ]);
334
334
  export const parseAttribute = (attribute) => {
335
+ if (attribute.type === "string" &&
336
+ attribute.format &&
337
+ attribute.format.length > 0) {
338
+ // @ts-expect-error
339
+ attribute.type = attribute.format;
340
+ delete attribute.format;
341
+ }
335
342
  if (attribute.type === "string") {
336
343
  return stringAttributeSchema.parse(attribute);
337
344
  }
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.270",
4
+ "version": "0.0.272",
5
5
  "main": "src/main.ts",
6
6
  "type": "module",
7
7
  "repository": {
@@ -1,6 +1,39 @@
1
1
  import { Query, type Databases, type Models } from "node-appwrite";
2
- import type { Attribute } from "./schema.js";
2
+ import { parseAttribute, type Attribute } from "./schema.js";
3
3
  import { nameToIdMapping, enqueueOperation } from "./queue.js";
4
+ import _ from "lodash";
5
+
6
+ const attributesSame = (a: Attribute, b: Attribute) => {
7
+ // Direct type comparison for non-string types
8
+ if (
9
+ a.type === b.type &&
10
+ !((a.type === "string" && a.format) || (b.type === "string" && b.format))
11
+ ) {
12
+ return a.key === b.key && a.array === b.array && a.required === b.required;
13
+ }
14
+
15
+ if (a.type === "string" && a.format) {
16
+ // @ts-expect-error
17
+ a.type = a.format;
18
+ }
19
+ if (b.type === "string" && b.format) {
20
+ // @ts-expect-error
21
+ b.type = b.format;
22
+ }
23
+
24
+ // Handling string types with specific formats in Appwrite
25
+ if (a.type === "string" && b.type === "string") {
26
+ return (
27
+ a.key === b.key &&
28
+ a.format === b.format &&
29
+ a.array === b.array &&
30
+ a.required === b.required
31
+ );
32
+ }
33
+
34
+ // Fallback to false if none of the above conditions are met
35
+ return false;
36
+ };
4
37
 
5
38
  export const createOrUpdateAttribute = async (
6
39
  db: Databases,
@@ -12,15 +45,19 @@ export const createOrUpdateAttribute = async (
12
45
  let foundAttribute;
13
46
  try {
14
47
  foundAttribute = await db.getAttribute(dbId, collection.$id, attribute.key);
48
+ foundAttribute = parseAttribute(foundAttribute);
15
49
  } catch (error) {
16
50
  foundAttribute = undefined;
17
51
  }
18
52
  let numSameAttributes = 0;
19
- if (foundAttribute && foundAttribute.key === attribute.key) {
53
+ if (foundAttribute && attributesSame(foundAttribute, attribute)) {
20
54
  numSameAttributes++;
21
55
  return;
22
- } else if (foundAttribute) {
23
- action = "update";
56
+ } else if (foundAttribute && !attributesSame(foundAttribute, attribute)) {
57
+ console.log(
58
+ `Deleting attribute with same key ${attribute.key} -- ${foundAttribute.key} but different values, assuming update...`
59
+ );
60
+ await db.deleteAttribute(dbId, collection.$id, attribute.key);
24
61
  }
25
62
 
26
63
  // Relationship attribute logic with adjustments
@@ -410,6 +410,15 @@ export const parseAttribute = (
410
410
  | EnumAttribute
411
411
  | RelationshipAttribute
412
412
  ) => {
413
+ if (
414
+ attribute.type === "string" &&
415
+ attribute.format &&
416
+ attribute.format.length > 0
417
+ ) {
418
+ // @ts-expect-error
419
+ attribute.type = attribute.format;
420
+ delete attribute.format;
421
+ }
413
422
  if (attribute.type === "string") {
414
423
  return stringAttributeSchema.parse(attribute);
415
424
  } else if (attribute.type === "integer") {