appwrite-utils-cli 0.9.68 → 0.9.71
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
@@ -124,6 +124,8 @@ This updated CLI ensures that developers have robust tools at their fingertips t
|
|
124
124
|
|
125
125
|
## Changelog
|
126
126
|
|
127
|
+
- 0.9.71: Reverted `node-appwrite` to 14, this seems to fix the xdefault error
|
128
|
+
- 0.9.70: I think I stopped it from deleting attributes, my bad on that
|
127
129
|
- 0.9.68: Temporarily disabled updating Attributes until `updateStringAttribute` is fixed -- it just deletes them now
|
128
130
|
- 0.9.65: Temporary fix for Appwrite's `updateStringAttribute` bug
|
129
131
|
- 0.9.64: Fixed string attribute requiring xdefault
|
@@ -97,7 +97,7 @@ export const createOrUpdateAttribute = async (db, dbId, collection, attribute) =
|
|
97
97
|
else {
|
98
98
|
await tryAwaitWithRetry(async () => await db.updateStringAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault
|
99
99
|
? `${finalAttribute.xdefault}`
|
100
|
-
: undefined
|
100
|
+
: undefined));
|
101
101
|
}
|
102
102
|
break;
|
103
103
|
case "integer":
|
@@ -4,12 +4,58 @@ import { nameToIdMapping, enqueueOperation } from "./queue.js";
|
|
4
4
|
import _ from "lodash";
|
5
5
|
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
6
6
|
const attributesSame = (databaseAttribute, configAttribute) => {
|
7
|
-
|
7
|
+
const attributesToCheck = [
|
8
|
+
'key',
|
9
|
+
'type',
|
10
|
+
'array',
|
11
|
+
'encrypted',
|
12
|
+
'required',
|
13
|
+
'size',
|
14
|
+
'min',
|
15
|
+
'max',
|
16
|
+
'xdefault',
|
17
|
+
'elements',
|
18
|
+
'relationType',
|
19
|
+
'twoWay',
|
20
|
+
'twoWayKey',
|
21
|
+
'onDelete',
|
22
|
+
'relatedCollection'
|
23
|
+
];
|
24
|
+
return attributesToCheck.every(attr => {
|
25
|
+
// Check if both objects have the attribute
|
26
|
+
const dbHasAttr = attr in databaseAttribute;
|
27
|
+
const configHasAttr = attr in configAttribute;
|
28
|
+
// If both have the attribute, compare values
|
29
|
+
if (dbHasAttr && configHasAttr) {
|
30
|
+
const dbValue = databaseAttribute[attr];
|
31
|
+
const configValue = configAttribute[attr];
|
32
|
+
// Consider undefined and null as equivalent
|
33
|
+
if ((dbValue === undefined || dbValue === null) && (configValue === undefined || configValue === null)) {
|
34
|
+
return true;
|
35
|
+
}
|
36
|
+
return dbValue === configValue;
|
37
|
+
}
|
38
|
+
// If neither has the attribute, consider it the same
|
39
|
+
if (!dbHasAttr && !configHasAttr) {
|
40
|
+
return true;
|
41
|
+
}
|
42
|
+
// If one has the attribute and the other doesn't, check if it's undefined or null
|
43
|
+
if (dbHasAttr && !configHasAttr) {
|
44
|
+
const dbValue = databaseAttribute[attr];
|
45
|
+
return dbValue === undefined || dbValue === null;
|
46
|
+
}
|
47
|
+
if (!dbHasAttr && configHasAttr) {
|
48
|
+
const configValue = configAttribute[attr];
|
49
|
+
return configValue === undefined || configValue === null;
|
50
|
+
}
|
51
|
+
// If we reach here, the attributes are different
|
52
|
+
return false;
|
53
|
+
});
|
8
54
|
};
|
9
55
|
export const createOrUpdateAttribute = async (db, dbId, collection, attribute) => {
|
10
56
|
let action = "create";
|
11
57
|
let foundAttribute;
|
12
|
-
const updateEnabled =
|
58
|
+
const updateEnabled = true;
|
13
59
|
let finalAttribute = attribute;
|
14
60
|
try {
|
15
61
|
const collectionAttr = collection.attributes.find(
|
@@ -32,12 +78,12 @@ export const createOrUpdateAttribute = async (db, dbId, collection, attribute) =
|
|
32
78
|
finalAttribute = attribute;
|
33
79
|
action = "update";
|
34
80
|
}
|
35
|
-
else if (!updateEnabled && foundAttribute) {
|
81
|
+
else if (!updateEnabled && foundAttribute && !attributesSame(foundAttribute, attribute)) {
|
36
82
|
await db.deleteAttribute(dbId, collection.$id, attribute.key);
|
37
|
-
console.log(`Deleted attribute: ${attribute.key} to recreate it (update disabled temporarily)`);
|
83
|
+
console.log(`Deleted attribute: ${attribute.key} to recreate it because they diff (update disabled temporarily)`);
|
38
84
|
return;
|
39
85
|
}
|
40
|
-
console.log(`${action}-ing attribute: ${finalAttribute.key}`);
|
86
|
+
// console.log(`${action}-ing attribute: ${finalAttribute.key}`);
|
41
87
|
// Relationship attribute logic with adjustments
|
42
88
|
let collectionFoundViaRelatedCollection;
|
43
89
|
let relatedCollectionId;
|
@@ -81,7 +127,7 @@ export const createOrUpdateAttribute = async (db, dbId, collection, attribute) =
|
|
81
127
|
await tryAwaitWithRetry(async () => await db.createStringAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.size, finalAttribute.required || false, finalAttribute.xdefault || (finalAttribute.required ? undefined : null), finalAttribute.array || false, finalAttribute.encrypted));
|
82
128
|
}
|
83
129
|
else {
|
84
|
-
await tryAwaitWithRetry(async () => await db.updateStringAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || (finalAttribute.required ? undefined : "")
|
130
|
+
await tryAwaitWithRetry(async () => await db.updateStringAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || (finalAttribute.required ? undefined : "")));
|
85
131
|
}
|
86
132
|
break;
|
87
133
|
case "integer":
|
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.9.
|
4
|
+
"version": "0.9.71",
|
5
5
|
"main": "src/main.ts",
|
6
6
|
"type": "module",
|
7
7
|
"repository": {
|
@@ -38,7 +38,7 @@
|
|
38
38
|
"lodash": "^4.17.21",
|
39
39
|
"luxon": "^3.5.0",
|
40
40
|
"nanostores": "^0.10.3",
|
41
|
-
"node-appwrite": "
|
41
|
+
"node-appwrite": "14.0.0",
|
42
42
|
"tsx": "^4.17.0",
|
43
43
|
"ulidx": "^2.4.0",
|
44
44
|
"winston": "^3.14.2",
|
@@ -12,7 +12,61 @@ const attributesSame = (
|
|
12
12
|
databaseAttribute: Attribute,
|
13
13
|
configAttribute: Attribute
|
14
14
|
): boolean => {
|
15
|
-
|
15
|
+
const attributesToCheck = [
|
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'
|
31
|
+
];
|
32
|
+
|
33
|
+
return attributesToCheck.every(attr => {
|
34
|
+
// Check if both objects have the attribute
|
35
|
+
const dbHasAttr = attr in databaseAttribute;
|
36
|
+
const configHasAttr = attr in configAttribute;
|
37
|
+
|
38
|
+
// If both have the attribute, compare values
|
39
|
+
if (dbHasAttr && configHasAttr) {
|
40
|
+
const dbValue = databaseAttribute[attr as keyof typeof databaseAttribute];
|
41
|
+
const configValue = configAttribute[attr as keyof typeof configAttribute];
|
42
|
+
|
43
|
+
// Consider undefined and null as equivalent
|
44
|
+
if ((dbValue === undefined || dbValue === null) && (configValue === undefined || configValue === null)) {
|
45
|
+
return true;
|
46
|
+
}
|
47
|
+
|
48
|
+
return dbValue === configValue;
|
49
|
+
}
|
50
|
+
|
51
|
+
// If neither has the attribute, consider it the same
|
52
|
+
if (!dbHasAttr && !configHasAttr) {
|
53
|
+
return true;
|
54
|
+
}
|
55
|
+
|
56
|
+
// If one has the attribute and the other doesn't, check if it's undefined or null
|
57
|
+
if (dbHasAttr && !configHasAttr) {
|
58
|
+
const dbValue = databaseAttribute[attr as keyof typeof databaseAttribute];
|
59
|
+
return dbValue === undefined || dbValue === null;
|
60
|
+
}
|
61
|
+
|
62
|
+
if (!dbHasAttr && configHasAttr) {
|
63
|
+
const configValue = configAttribute[attr as keyof typeof configAttribute];
|
64
|
+
return configValue === undefined || configValue === null;
|
65
|
+
}
|
66
|
+
|
67
|
+
// If we reach here, the attributes are different
|
68
|
+
return false;
|
69
|
+
});
|
16
70
|
};
|
17
71
|
|
18
72
|
export const createOrUpdateAttribute = async (
|
@@ -23,7 +77,7 @@ export const createOrUpdateAttribute = async (
|
|
23
77
|
): Promise<void> => {
|
24
78
|
let action = "create";
|
25
79
|
let foundAttribute: Attribute | undefined;
|
26
|
-
const updateEnabled =
|
80
|
+
const updateEnabled = true;
|
27
81
|
let finalAttribute: any = attribute;
|
28
82
|
try {
|
29
83
|
const collectionAttr = collection.attributes.find(
|
@@ -47,13 +101,13 @@ export const createOrUpdateAttribute = async (
|
|
47
101
|
);
|
48
102
|
finalAttribute = attribute;
|
49
103
|
action = "update";
|
50
|
-
} else if (!updateEnabled && foundAttribute) {
|
104
|
+
} else if (!updateEnabled && foundAttribute && !attributesSame(foundAttribute, attribute)) {
|
51
105
|
await db.deleteAttribute(dbId, collection.$id, attribute.key);
|
52
|
-
console.log(`Deleted attribute: ${attribute.key} to recreate it (update disabled temporarily)`);
|
106
|
+
console.log(`Deleted attribute: ${attribute.key} to recreate it because they diff (update disabled temporarily)`);
|
53
107
|
return;
|
54
108
|
}
|
55
109
|
|
56
|
-
console.log(`${action}-ing attribute: ${finalAttribute.key}`);
|
110
|
+
// console.log(`${action}-ing attribute: ${finalAttribute.key}`);
|
57
111
|
|
58
112
|
// Relationship attribute logic with adjustments
|
59
113
|
let collectionFoundViaRelatedCollection: Models.Collection | undefined;
|
@@ -125,7 +179,6 @@ export const createOrUpdateAttribute = async (
|
|
125
179
|
finalAttribute.key,
|
126
180
|
finalAttribute.required || false,
|
127
181
|
finalAttribute.xdefault || (finalAttribute.required ? undefined : ""),
|
128
|
-
finalAttribute.size
|
129
182
|
)
|
130
183
|
);
|
131
184
|
}
|