appwrite-utils-cli 0.0.274 → 0.0.275

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.
Files changed (77) hide show
  1. package/README.md +4 -39
  2. package/dist/init.d.ts +2 -0
  3. package/dist/init.js +57 -0
  4. package/dist/main.js +62 -100
  5. package/dist/migrations/afterImportActions.d.ts +1 -4
  6. package/dist/migrations/afterImportActions.js +1 -0
  7. package/dist/migrations/appwriteToX.d.ts +46 -46
  8. package/dist/migrations/appwriteToX.js +6 -2
  9. package/dist/migrations/attributes.d.ts +1 -1
  10. package/dist/migrations/attributes.js +97 -71
  11. package/dist/migrations/backup.d.ts +240 -240
  12. package/dist/migrations/backup.js +1 -1
  13. package/dist/migrations/collections.d.ts +1 -1
  14. package/dist/migrations/collections.js +4 -4
  15. package/dist/migrations/converters.d.ts +9 -127
  16. package/dist/migrations/converters.js +1 -504
  17. package/dist/migrations/dataLoader.d.ts +470 -453
  18. package/dist/migrations/dataLoader.js +19 -1
  19. package/dist/migrations/dbHelpers.d.ts +1 -1
  20. package/dist/migrations/dbHelpers.js +3 -0
  21. package/dist/migrations/importController.d.ts +1 -1
  22. package/dist/migrations/importController.js +4 -7
  23. package/dist/migrations/importDataActions.d.ts +4 -6
  24. package/dist/migrations/importDataActions.js +6 -4
  25. package/dist/migrations/indexes.d.ts +1 -1
  26. package/dist/migrations/indexes.js +1 -1
  27. package/dist/migrations/migrationHelper.d.ts +29 -29
  28. package/dist/migrations/migrationHelper.js +1 -1
  29. package/dist/migrations/openapi.d.ts +1 -1
  30. package/dist/migrations/openapi.js +4 -1
  31. package/dist/migrations/queue.d.ts +1 -1
  32. package/dist/migrations/relationships.d.ts +5 -5
  33. package/dist/migrations/relationships.js +3 -0
  34. package/dist/migrations/schemaStrings.d.ts +2 -2
  35. package/dist/migrations/schemaStrings.js +93 -8
  36. package/dist/migrations/setupDatabase.d.ts +1 -1
  37. package/dist/migrations/setupDatabase.js +1 -1
  38. package/dist/migrations/storage.d.ts +1 -1
  39. package/dist/migrations/users.d.ts +1 -1
  40. package/dist/schemas/authUser.d.ts +12 -10
  41. package/dist/types.d.ts +0 -5
  42. package/dist/types.js +0 -2
  43. package/dist/utils/helperFunctions.d.ts +2 -3
  44. package/dist/utils/loadConfigs.d.ts +13 -0
  45. package/dist/utils/loadConfigs.js +47 -0
  46. package/dist/utils/setupFiles.d.ts +1 -0
  47. package/dist/utils/setupFiles.js +98 -223
  48. package/dist/utilsController.d.ts +1 -3
  49. package/dist/utilsController.js +14 -18
  50. package/package.json +9 -2
  51. package/src/init.ts +64 -0
  52. package/src/main.ts +73 -98
  53. package/src/migrations/afterImportActions.ts +1 -5
  54. package/src/migrations/appwriteToX.ts +6 -2
  55. package/src/migrations/attributes.ts +198 -150
  56. package/src/migrations/backup.ts +1 -1
  57. package/src/migrations/collections.ts +5 -11
  58. package/src/migrations/converters.ts +1 -540
  59. package/src/migrations/dataLoader.ts +19 -2
  60. package/src/migrations/dbHelpers.ts +4 -1
  61. package/src/migrations/importController.ts +5 -15
  62. package/src/migrations/importDataActions.ts +10 -14
  63. package/src/migrations/indexes.ts +1 -1
  64. package/src/migrations/migrationHelper.ts +1 -1
  65. package/src/migrations/openapi.ts +4 -1
  66. package/src/migrations/queue.ts +1 -1
  67. package/src/migrations/relationships.ts +4 -1
  68. package/src/migrations/schemaStrings.ts +106 -9
  69. package/src/migrations/setupDatabase.ts +1 -1
  70. package/src/migrations/storage.ts +1 -1
  71. package/src/migrations/users.ts +1 -1
  72. package/src/types.ts +0 -5
  73. package/src/utils/helperFunctions.ts +2 -3
  74. package/src/utils/loadConfigs.ts +55 -0
  75. package/src/utils/setupFiles.ts +114 -225
  76. package/src/utilsController.ts +27 -35
  77. package/src/migrations/schema.ts +0 -748
@@ -1,176 +1,202 @@
1
1
  import { Query } from "node-appwrite";
2
- import { parseAttribute } from "./schema.js";
2
+ import { attributeSchema, parseAttribute, } from "appwrite-utils";
3
3
  import { nameToIdMapping, enqueueOperation } from "./queue.js";
4
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;
5
+ const attributesSame = (databaseAttribute, configAttribute) => {
6
+ return (databaseAttribute.key == configAttribute.key &&
7
+ databaseAttribute.type == configAttribute.type &&
8
+ databaseAttribute.array == configAttribute.array);
37
9
  };
38
10
  export const createOrUpdateAttribute = async (db, dbId, collection, attribute) => {
39
11
  let action = "create";
40
12
  let foundAttribute;
13
+ const updateEnabled = false;
14
+ let finalAttribute = attribute;
41
15
  try {
42
- foundAttribute = parseAttribute(collection.attributes.find(
16
+ const collectionAttr = collection.attributes.find(
43
17
  // @ts-expect-error
44
- (attr) => attr.key === attribute.key));
45
- foundAttribute = parseAttribute(foundAttribute);
18
+ (attr) => attr.key === attribute.key);
19
+ foundAttribute = parseAttribute(collectionAttr);
46
20
  }
47
21
  catch (error) {
48
22
  foundAttribute = undefined;
49
23
  }
50
- let numSameAttributes = 0;
51
- if (foundAttribute && attributesSame(foundAttribute, attribute)) {
52
- numSameAttributes++;
53
- return;
24
+ if (foundAttribute &&
25
+ attributesSame(foundAttribute, attribute) &&
26
+ updateEnabled) {
27
+ // Check if mutable properties have changed and set action to "update" if necessary
28
+ const requiredChanged = "required" in foundAttribute && "required" in attribute
29
+ ? foundAttribute.required !== attribute.required
30
+ : false;
31
+ // const xdefaultChanged =
32
+ // "xdefault" in foundAttribute && "xdefault" in attribute
33
+ // ? foundAttribute.xdefault !== attribute.xdefault
34
+ // : false;
35
+ const onDeleteChanged = foundAttribute.type === "relationship" &&
36
+ attribute.type === "relationship" &&
37
+ "onDelete" in foundAttribute &&
38
+ "onDelete" in attribute
39
+ ? foundAttribute.onDelete !== attribute.onDelete
40
+ : false;
41
+ if (requiredChanged || onDeleteChanged) {
42
+ console.log(`Required changed: ${requiredChanged}\nOnDelete changed: ${onDeleteChanged}`);
43
+ console.log(`Found attribute: ${JSON.stringify(foundAttribute, null, 2)}`);
44
+ console.log(`Attribute: ${JSON.stringify(attribute, null, 2)}`);
45
+ finalAttribute = {
46
+ ...attribute,
47
+ ...foundAttribute,
48
+ };
49
+ action = "update";
50
+ }
51
+ else {
52
+ // If no properties that can be updated have changed, return early
53
+ return;
54
+ }
54
55
  }
55
- else if (foundAttribute && !attributesSame(foundAttribute, attribute)) {
56
- console.log(`Deleting attribute with same key ${attribute.key} -- ${foundAttribute.key} but different values -- ${JSON.stringify(attribute, null, 2)} -- ${JSON.stringify(foundAttribute, null, 2)}`);
56
+ else if (foundAttribute &&
57
+ !attributesSame(foundAttribute, attribute) &&
58
+ updateEnabled) {
59
+ console.log(`Deleting attribute with same key ${attribute.key} -- but different values -- ${JSON.stringify(attribute, null, 2)} -- ${JSON.stringify(foundAttribute, null, 2)}`);
57
60
  await db.deleteAttribute(dbId, collection.$id, attribute.key);
61
+ // After deletion, you might want to create the attribute anew
62
+ finalAttribute = attribute;
63
+ action = "create";
64
+ }
65
+ else if (!updateEnabled && foundAttribute) {
66
+ return;
58
67
  }
59
68
  // Relationship attribute logic with adjustments
60
69
  let collectionFoundViaRelatedCollection;
61
70
  let relatedCollectionId;
62
- if (attribute.type === "relationship") {
63
- if (nameToIdMapping.has(attribute.relatedCollection)) {
64
- relatedCollectionId = nameToIdMapping.get(attribute.relatedCollection);
71
+ if (finalAttribute.type === "relationship") {
72
+ if (nameToIdMapping.has(finalAttribute.relatedCollection)) {
73
+ relatedCollectionId = nameToIdMapping.get(finalAttribute.relatedCollection);
65
74
  try {
66
75
  collectionFoundViaRelatedCollection = await db.getCollection(dbId, relatedCollectionId);
67
76
  }
68
77
  catch (e) {
69
- console.log(`Collection not found: ${attribute.relatedCollection} when nameToIdMapping was set`);
78
+ console.log(`Collection not found: ${finalAttribute.relatedCollection} when nameToIdMapping was set`);
70
79
  collectionFoundViaRelatedCollection = undefined;
71
80
  }
72
81
  }
73
82
  else {
74
83
  const collectionsPulled = await db.listCollections(dbId, [
75
- Query.equal("name", attribute.relatedCollection),
84
+ Query.equal("name", finalAttribute.relatedCollection),
76
85
  ]);
77
86
  if (collectionsPulled.total > 0) {
78
87
  collectionFoundViaRelatedCollection = collectionsPulled.collections[0];
79
88
  relatedCollectionId = collectionFoundViaRelatedCollection.$id;
80
- nameToIdMapping.set(attribute.relatedCollection, relatedCollectionId);
89
+ nameToIdMapping.set(finalAttribute.relatedCollection, relatedCollectionId);
81
90
  }
82
91
  }
83
92
  if (!(relatedCollectionId && collectionFoundViaRelatedCollection)) {
84
- console.log(`Enqueueing operation for attribute: ${attribute.key}`);
93
+ console.log(`Enqueueing operation for attribute: ${finalAttribute.key}`);
85
94
  enqueueOperation({
86
95
  type: "attribute",
87
96
  collectionId: collection.$id,
88
97
  collection: collection,
89
98
  attribute,
90
- dependencies: [attribute.relatedCollection],
99
+ dependencies: [finalAttribute.relatedCollection],
91
100
  });
92
101
  return;
93
102
  }
94
103
  }
95
- switch (attribute.type) {
104
+ finalAttribute = attributeSchema.parse(finalAttribute);
105
+ switch (finalAttribute.type) {
96
106
  case "string":
97
107
  if (action === "create") {
98
- await db.createStringAttribute(dbId, collection.$id, attribute.key, attribute.size, attribute.required, attribute.xdefault || undefined, attribute.array, attribute.encrypted);
108
+ await db.createStringAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.size, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array || false, finalAttribute.encrypted);
99
109
  }
100
110
  else {
101
- await db.updateStringAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined);
111
+ await db.updateStringAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined);
102
112
  }
103
113
  break;
104
114
  case "integer":
105
115
  if (action === "create") {
106
- await db.createIntegerAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.min, attribute.max, attribute.xdefault || undefined, attribute.array);
116
+ if (finalAttribute.min &&
117
+ BigInt(finalAttribute.min) === BigInt(-9223372036854776000)) {
118
+ delete finalAttribute.min;
119
+ }
120
+ if (finalAttribute.max &&
121
+ BigInt(finalAttribute.max) === BigInt(9223372036854776000)) {
122
+ delete finalAttribute.max;
123
+ }
124
+ await db.createIntegerAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min, finalAttribute.max, finalAttribute.xdefault || undefined, finalAttribute.array);
107
125
  }
108
126
  else {
109
- await db.updateIntegerAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.min || 0, attribute.max || 2147483647, attribute.xdefault || undefined);
127
+ if (finalAttribute.min &&
128
+ BigInt(finalAttribute.min) === BigInt(-9223372036854776000)) {
129
+ delete finalAttribute.min;
130
+ }
131
+ if (finalAttribute.max &&
132
+ BigInt(finalAttribute.max) === BigInt(9223372036854776000)) {
133
+ delete finalAttribute.max;
134
+ }
135
+ await db.updateIntegerAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min || 0, finalAttribute.max || 2147483647, finalAttribute.xdefault || undefined);
110
136
  }
111
137
  break;
112
138
  case "float":
113
139
  if (action === "create") {
114
- await db.createFloatAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.min, attribute.max, attribute.xdefault || undefined, attribute.array);
140
+ await db.createFloatAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min, finalAttribute.max, finalAttribute.xdefault || undefined, finalAttribute.array);
115
141
  }
116
142
  else {
117
- await db.updateFloatAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.min || 0, attribute.max || 2147483647, attribute.xdefault || undefined);
143
+ await db.updateFloatAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min || 0, finalAttribute.max || 2147483647, finalAttribute.xdefault || undefined);
118
144
  }
119
145
  break;
120
146
  case "boolean":
121
147
  if (action === "create") {
122
- await db.createBooleanAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined, attribute.array);
148
+ await db.createBooleanAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array);
123
149
  }
124
150
  else {
125
- await db.updateBooleanAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined);
151
+ await db.updateBooleanAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || null);
126
152
  }
127
153
  break;
128
154
  case "datetime":
129
155
  if (action === "create") {
130
- await db.createDatetimeAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined, attribute.array);
156
+ await db.createDatetimeAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array);
131
157
  }
132
158
  else {
133
- await db.updateDatetimeAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined);
159
+ await db.updateDatetimeAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined);
134
160
  }
135
161
  break;
136
162
  case "email":
137
163
  if (action === "create") {
138
- await db.createEmailAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined, attribute.array);
164
+ await db.createEmailAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array);
139
165
  }
140
166
  else {
141
- await db.updateEmailAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined);
167
+ await db.updateEmailAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined);
142
168
  }
143
169
  break;
144
170
  case "ip":
145
171
  if (action === "create") {
146
- await db.createIpAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined, attribute.array);
172
+ await db.createIpAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array);
147
173
  }
148
174
  else {
149
- await db.updateIpAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined);
175
+ await db.updateIpAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined);
150
176
  }
151
177
  break;
152
178
  case "url":
153
179
  if (action === "create") {
154
- await db.createUrlAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined, attribute.array);
180
+ await db.createUrlAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array);
155
181
  }
156
182
  else {
157
- await db.updateUrlAttribute(dbId, collection.$id, attribute.key, attribute.required, attribute.xdefault || undefined);
183
+ await db.updateUrlAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined);
158
184
  }
159
185
  break;
160
186
  case "enum":
161
187
  if (action === "create") {
162
- await db.createEnumAttribute(dbId, collection.$id, attribute.key, attribute.elements, attribute.required, attribute.xdefault || undefined, attribute.array);
188
+ await db.createEnumAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.elements, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array);
163
189
  }
164
190
  else {
165
- await db.updateEnumAttribute(dbId, collection.$id, attribute.key, attribute.elements, attribute.required, attribute.xdefault || undefined);
191
+ await db.updateEnumAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.elements, finalAttribute.required || false, finalAttribute.xdefault || undefined);
166
192
  }
167
193
  break;
168
194
  case "relationship":
169
195
  if (action === "create") {
170
- await db.createRelationshipAttribute(dbId, collection.$id, relatedCollectionId, attribute.relationType, attribute.twoWay, attribute.key, attribute.twoWayKey, attribute.onDelete);
196
+ await db.createRelationshipAttribute(dbId, collection.$id, relatedCollectionId, finalAttribute.relationType, finalAttribute.twoWay, finalAttribute.key, finalAttribute.twoWayKey, finalAttribute.onDelete);
171
197
  }
172
198
  else {
173
- await db.updateRelationshipAttribute(dbId, collection.$id, attribute.key, attribute.onDelete);
199
+ await db.updateRelationshipAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.onDelete);
174
200
  }
175
201
  break;
176
202
  default: