appwrite-utils-cli 0.0.271 → 0.0.273
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.273: Small fix for relationship attribute comparisons
|
122
|
+
- 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"`)
|
121
123
|
- 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
|
122
124
|
- 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)
|
123
125
|
- 0.0.254: Added `--sync` to synchronize your Appwrite instance with your local `appwriteConfig.yaml` and generate schemas
|
@@ -1,4 +1,4 @@
|
|
1
1
|
import { type Databases, type Models } from "node-appwrite";
|
2
|
-
import type
|
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,22 +1,57 @@
|
|
1
1
|
import { Query } from "node-appwrite";
|
2
|
+
import { parseAttribute } from "./schema.js";
|
2
3
|
import { nameToIdMapping, enqueueOperation } from "./queue.js";
|
3
4
|
import _ from "lodash";
|
5
|
+
const attributesSame = (a, b) => {
|
6
|
+
// Direct type comparison for non-string types
|
7
|
+
// Also check if the type IS string and has a format for either
|
8
|
+
// That means the format is the type of the attribute
|
9
|
+
if (a.type === b.type &&
|
10
|
+
!((a.type === "string" && a.format) || (b.type === "string" && b.format))) {
|
11
|
+
if (a.type === "relationship" && b.type === "relationship") {
|
12
|
+
return (a.key === b.key &&
|
13
|
+
a.relationType === b.relationType &&
|
14
|
+
a.twoWay === b.twoWay &&
|
15
|
+
a.twoWayKey === b.twoWayKey &&
|
16
|
+
a.required === b.required);
|
17
|
+
}
|
18
|
+
return a.key === b.key && a.array === b.array && a.required === b.required;
|
19
|
+
}
|
20
|
+
if (a.type === "string" && a.format) {
|
21
|
+
// @ts-expect-error
|
22
|
+
a.type = a.format;
|
23
|
+
}
|
24
|
+
if (b.type === "string" && b.format) {
|
25
|
+
// @ts-expect-error
|
26
|
+
b.type = b.format;
|
27
|
+
}
|
28
|
+
// Handling string types with specific formats in Appwrite
|
29
|
+
if (a.type === "string" && b.type === "string") {
|
30
|
+
return (a.key === b.key &&
|
31
|
+
a.format === b.format &&
|
32
|
+
a.array === b.array &&
|
33
|
+
a.required === b.required);
|
34
|
+
}
|
35
|
+
// Fallback to false if none of the above conditions are met
|
36
|
+
return false;
|
37
|
+
};
|
4
38
|
export const createOrUpdateAttribute = async (db, dbId, collection, attribute) => {
|
5
39
|
let action = "create";
|
6
40
|
let foundAttribute;
|
7
41
|
try {
|
8
42
|
foundAttribute = await db.getAttribute(dbId, collection.$id, attribute.key);
|
43
|
+
foundAttribute = parseAttribute(foundAttribute);
|
9
44
|
}
|
10
45
|
catch (error) {
|
11
46
|
foundAttribute = undefined;
|
12
47
|
}
|
13
48
|
let numSameAttributes = 0;
|
14
|
-
if (foundAttribute &&
|
49
|
+
if (foundAttribute && attributesSame(foundAttribute, attribute)) {
|
15
50
|
numSameAttributes++;
|
16
51
|
return;
|
17
52
|
}
|
18
|
-
else if (foundAttribute && !
|
19
|
-
console.log(
|
53
|
+
else if (foundAttribute && !attributesSame(foundAttribute, attribute)) {
|
54
|
+
console.log(`Deleting attribute with same key ${attribute.key} -- ${foundAttribute.key} but different values -- ${JSON.stringify(attribute, null, 2)} -- ${JSON.stringify(foundAttribute, null, 2)}`);
|
20
55
|
await db.deleteAttribute(dbId, collection.$id, attribute.key);
|
21
56
|
}
|
22
57
|
// Relationship attribute logic with adjustments
|
@@ -332,6 +332,14 @@ 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
|
+
console.log(`Parsing attribute ${attribute.key} with format ${attribute.format}, setting type to ${attribute.format.toLowerCase()}`);
|
339
|
+
// @ts-expect-error
|
340
|
+
attribute.type = attribute.format.toLowerCase();
|
341
|
+
delete attribute.format;
|
342
|
+
}
|
335
343
|
if (attribute.type === "string") {
|
336
344
|
return stringAttributeSchema.parse(attribute);
|
337
345
|
}
|
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.273",
|
5
5
|
"main": "src/main.ts",
|
6
6
|
"type": "module",
|
7
7
|
"repository": {
|
@@ -1,8 +1,51 @@
|
|
1
1
|
import { Query, type Databases, type Models } from "node-appwrite";
|
2
|
-
import type
|
2
|
+
import { parseAttribute, type Attribute } from "./schema.js";
|
3
3
|
import { nameToIdMapping, enqueueOperation } from "./queue.js";
|
4
4
|
import _ from "lodash";
|
5
5
|
|
6
|
+
const attributesSame = (a: Attribute, b: Attribute) => {
|
7
|
+
// Direct type comparison for non-string types
|
8
|
+
// Also check if the type IS string and has a format for either
|
9
|
+
// That means the format is the type of the attribute
|
10
|
+
if (
|
11
|
+
a.type === b.type &&
|
12
|
+
!((a.type === "string" && a.format) || (b.type === "string" && b.format))
|
13
|
+
) {
|
14
|
+
if (a.type === "relationship" && b.type === "relationship") {
|
15
|
+
return (
|
16
|
+
a.key === b.key &&
|
17
|
+
a.relationType === b.relationType &&
|
18
|
+
a.twoWay === b.twoWay &&
|
19
|
+
a.twoWayKey === b.twoWayKey &&
|
20
|
+
a.required === b.required
|
21
|
+
);
|
22
|
+
}
|
23
|
+
return a.key === b.key && a.array === b.array && a.required === b.required;
|
24
|
+
}
|
25
|
+
|
26
|
+
if (a.type === "string" && a.format) {
|
27
|
+
// @ts-expect-error
|
28
|
+
a.type = a.format;
|
29
|
+
}
|
30
|
+
if (b.type === "string" && b.format) {
|
31
|
+
// @ts-expect-error
|
32
|
+
b.type = b.format;
|
33
|
+
}
|
34
|
+
|
35
|
+
// Handling string types with specific formats in Appwrite
|
36
|
+
if (a.type === "string" && b.type === "string") {
|
37
|
+
return (
|
38
|
+
a.key === b.key &&
|
39
|
+
a.format === b.format &&
|
40
|
+
a.array === b.array &&
|
41
|
+
a.required === b.required
|
42
|
+
);
|
43
|
+
}
|
44
|
+
|
45
|
+
// Fallback to false if none of the above conditions are met
|
46
|
+
return false;
|
47
|
+
};
|
48
|
+
|
6
49
|
export const createOrUpdateAttribute = async (
|
7
50
|
db: Databases,
|
8
51
|
dbId: string,
|
@@ -13,16 +56,23 @@ export const createOrUpdateAttribute = async (
|
|
13
56
|
let foundAttribute;
|
14
57
|
try {
|
15
58
|
foundAttribute = await db.getAttribute(dbId, collection.$id, attribute.key);
|
59
|
+
foundAttribute = parseAttribute(foundAttribute);
|
16
60
|
} catch (error) {
|
17
61
|
foundAttribute = undefined;
|
18
62
|
}
|
19
63
|
let numSameAttributes = 0;
|
20
|
-
if (foundAttribute &&
|
64
|
+
if (foundAttribute && attributesSame(foundAttribute, attribute)) {
|
21
65
|
numSameAttributes++;
|
22
66
|
return;
|
23
|
-
} else if (foundAttribute && !
|
67
|
+
} else if (foundAttribute && !attributesSame(foundAttribute, attribute)) {
|
24
68
|
console.log(
|
25
|
-
|
69
|
+
`Deleting attribute with same key ${attribute.key} -- ${
|
70
|
+
foundAttribute.key
|
71
|
+
} but different values -- ${JSON.stringify(
|
72
|
+
attribute,
|
73
|
+
null,
|
74
|
+
2
|
75
|
+
)} -- ${JSON.stringify(foundAttribute, null, 2)}`
|
26
76
|
);
|
27
77
|
await db.deleteAttribute(dbId, collection.$id, attribute.key);
|
28
78
|
}
|
package/src/migrations/schema.ts
CHANGED
@@ -410,6 +410,20 @@ 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
|
+
console.log(
|
419
|
+
`Parsing attribute ${attribute.key} with format ${
|
420
|
+
attribute.format
|
421
|
+
}, setting type to ${attribute.format.toLowerCase()}`
|
422
|
+
);
|
423
|
+
// @ts-expect-error
|
424
|
+
attribute.type = attribute.format.toLowerCase();
|
425
|
+
delete attribute.format;
|
426
|
+
}
|
413
427
|
if (attribute.type === "string") {
|
414
428
|
return stringAttributeSchema.parse(attribute);
|
415
429
|
} else if (attribute.type === "integer") {
|