appwrite-utils-cli 0.0.286 → 0.9.0

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 (109) hide show
  1. package/README.md +122 -96
  2. package/dist/collections/attributes.d.ts +4 -0
  3. package/dist/collections/attributes.js +224 -0
  4. package/dist/collections/indexes.d.ts +4 -0
  5. package/dist/collections/indexes.js +27 -0
  6. package/dist/collections/methods.d.ts +16 -0
  7. package/dist/collections/methods.js +216 -0
  8. package/dist/databases/methods.d.ts +6 -0
  9. package/dist/databases/methods.js +33 -0
  10. package/dist/interactiveCLI.d.ts +19 -0
  11. package/dist/interactiveCLI.js +555 -0
  12. package/dist/main.js +227 -62
  13. package/dist/migrations/afterImportActions.js +37 -40
  14. package/dist/migrations/appwriteToX.d.ts +26 -25
  15. package/dist/migrations/appwriteToX.js +42 -6
  16. package/dist/migrations/attributes.js +21 -20
  17. package/dist/migrations/backup.d.ts +93 -87
  18. package/dist/migrations/collections.d.ts +6 -0
  19. package/dist/migrations/collections.js +149 -20
  20. package/dist/migrations/converters.d.ts +2 -18
  21. package/dist/migrations/converters.js +13 -2
  22. package/dist/migrations/dataLoader.d.ts +276 -161
  23. package/dist/migrations/dataLoader.js +535 -292
  24. package/dist/migrations/databases.js +8 -2
  25. package/dist/migrations/helper.d.ts +3 -0
  26. package/dist/migrations/helper.js +21 -0
  27. package/dist/migrations/importController.d.ts +5 -2
  28. package/dist/migrations/importController.js +125 -88
  29. package/dist/migrations/importDataActions.d.ts +9 -1
  30. package/dist/migrations/importDataActions.js +15 -3
  31. package/dist/migrations/indexes.js +3 -2
  32. package/dist/migrations/logging.js +20 -8
  33. package/dist/migrations/migrationHelper.d.ts +9 -4
  34. package/dist/migrations/migrationHelper.js +6 -5
  35. package/dist/migrations/openapi.d.ts +1 -1
  36. package/dist/migrations/openapi.js +33 -18
  37. package/dist/migrations/queue.js +3 -2
  38. package/dist/migrations/relationships.d.ts +2 -2
  39. package/dist/migrations/schemaStrings.js +53 -41
  40. package/dist/migrations/setupDatabase.d.ts +2 -4
  41. package/dist/migrations/setupDatabase.js +24 -105
  42. package/dist/migrations/storage.d.ts +3 -1
  43. package/dist/migrations/storage.js +110 -16
  44. package/dist/migrations/transfer.d.ts +30 -0
  45. package/dist/migrations/transfer.js +337 -0
  46. package/dist/migrations/users.d.ts +2 -1
  47. package/dist/migrations/users.js +78 -43
  48. package/dist/schemas/authUser.d.ts +2 -2
  49. package/dist/storage/methods.d.ts +15 -0
  50. package/dist/storage/methods.js +207 -0
  51. package/dist/storage/schemas.d.ts +687 -0
  52. package/dist/storage/schemas.js +175 -0
  53. package/dist/utils/getClientFromConfig.d.ts +4 -0
  54. package/dist/utils/getClientFromConfig.js +16 -0
  55. package/dist/utils/helperFunctions.d.ts +11 -1
  56. package/dist/utils/helperFunctions.js +38 -0
  57. package/dist/utils/retryFailedPromises.d.ts +2 -0
  58. package/dist/utils/retryFailedPromises.js +21 -0
  59. package/dist/utils/schemaStrings.d.ts +13 -0
  60. package/dist/utils/schemaStrings.js +403 -0
  61. package/dist/utils/setupFiles.js +110 -61
  62. package/dist/utilsController.d.ts +40 -22
  63. package/dist/utilsController.js +164 -84
  64. package/package.json +13 -15
  65. package/src/collections/attributes.ts +483 -0
  66. package/src/collections/indexes.ts +53 -0
  67. package/src/collections/methods.ts +331 -0
  68. package/src/databases/methods.ts +47 -0
  69. package/src/init.ts +64 -64
  70. package/src/interactiveCLI.ts +767 -0
  71. package/src/main.ts +292 -83
  72. package/src/migrations/afterImportActions.ts +553 -490
  73. package/src/migrations/appwriteToX.ts +237 -174
  74. package/src/migrations/attributes.ts +483 -422
  75. package/src/migrations/backup.ts +205 -205
  76. package/src/migrations/collections.ts +545 -300
  77. package/src/migrations/converters.ts +161 -150
  78. package/src/migrations/dataLoader.ts +1615 -1304
  79. package/src/migrations/databases.ts +44 -25
  80. package/src/migrations/dbHelpers.ts +92 -92
  81. package/src/migrations/helper.ts +40 -0
  82. package/src/migrations/importController.ts +448 -384
  83. package/src/migrations/importDataActions.ts +315 -307
  84. package/src/migrations/indexes.ts +40 -37
  85. package/src/migrations/logging.ts +29 -16
  86. package/src/migrations/migrationHelper.ts +207 -201
  87. package/src/migrations/openapi.ts +83 -70
  88. package/src/migrations/queue.ts +118 -119
  89. package/src/migrations/relationships.ts +324 -324
  90. package/src/migrations/schemaStrings.ts +472 -460
  91. package/src/migrations/setupDatabase.ts +118 -219
  92. package/src/migrations/storage.ts +538 -358
  93. package/src/migrations/transfer.ts +608 -0
  94. package/src/migrations/users.ts +362 -285
  95. package/src/migrations/validationRules.ts +63 -63
  96. package/src/schemas/authUser.ts +23 -23
  97. package/src/setup.ts +8 -8
  98. package/src/storage/methods.ts +371 -0
  99. package/src/storage/schemas.ts +205 -0
  100. package/src/types.ts +9 -9
  101. package/src/utils/getClientFromConfig.ts +17 -0
  102. package/src/utils/helperFunctions.ts +181 -127
  103. package/src/utils/index.ts +2 -2
  104. package/src/utils/loadConfigs.ts +59 -59
  105. package/src/utils/retryFailedPromises.ts +27 -0
  106. package/src/utils/schemaStrings.ts +473 -0
  107. package/src/utils/setupFiles.ts +228 -182
  108. package/src/utilsController.ts +325 -194
  109. package/tsconfig.json +37 -37
@@ -1,174 +1,237 @@
1
- import { SchemaGenerator } from "./schemaStrings.js";
2
- import { Databases, Query, type Models, type Permission } from "node-appwrite";
3
- import { fetchAllCollections } from "./collections.js";
4
- import { fetchAllDatabases } from "./databases.js";
5
- import {
6
- CollectionSchema,
7
- attributeSchema,
8
- type AppwriteConfig,
9
- AppwriteConfigSchema,
10
- type ConfigDatabases,
11
- type Attribute,
12
- permissionsSchema,
13
- attributesSchema,
14
- indexesSchema,
15
- parseAttribute,
16
- } from "appwrite-utils";
17
- import { getDatabaseFromConfig } from "./afterImportActions.js";
18
-
19
- export class AppwriteToX {
20
- config: AppwriteConfig;
21
- updatedConfig: AppwriteConfig;
22
- collToAttributeMap = new Map<string, Attribute[]>();
23
- appwriteFolderPath: string;
24
-
25
- constructor(config: AppwriteConfig, appwriteFolderPath: string) {
26
- this.config = config;
27
- this.updatedConfig = config;
28
- this.appwriteFolderPath = appwriteFolderPath;
29
- }
30
-
31
- // Function to parse a single permission string
32
- parsePermissionString = (permissionString: string) => {
33
- const match = permissionString.match(/^(\w+)\('([^']+)'\)$/);
34
- if (!match) {
35
- throw new Error(`Invalid permission format: ${permissionString}`);
36
- }
37
- return {
38
- permission: match[1],
39
- target: match[2],
40
- };
41
- };
42
-
43
- // Function to parse an array of permission strings
44
- parsePermissionsArray = (permissions: string[]) => {
45
- if (permissions.length === 0) {
46
- return [];
47
- }
48
- const parsedPermissions = permissionsSchema.parse(permissions);
49
- // Validate the parsed permissions using Zod
50
- return parsedPermissions ?? [];
51
- };
52
-
53
- updateCollectionConfigAttributes = (collection: Models.Collection) => {
54
- for (const attribute of collection.attributes) {
55
- const attributeMap = this.collToAttributeMap.get(
56
- collection.name as string
57
- );
58
- const attributeParsed = attributeSchema.parse(attribute);
59
- this.collToAttributeMap
60
- .get(collection.name as string)
61
- ?.push(attributeParsed);
62
- }
63
- };
64
-
65
- async appwriteSync(config: AppwriteConfig) {
66
- const db = getDatabaseFromConfig(config);
67
- const databases = await fetchAllDatabases(db);
68
- let updatedConfig: AppwriteConfig = { ...config };
69
-
70
- // Loop through each database
71
- for (const database of databases) {
72
- if (database.name.toLowerCase() === "migrations") {
73
- continue;
74
- }
75
- const collections = await fetchAllCollections(database.$id, db);
76
-
77
- // Loop through each collection in the current database
78
- if (!updatedConfig.collections) {
79
- updatedConfig.collections = [];
80
- }
81
- for (const collection of collections) {
82
- console.log(`Processing collection: ${collection.name}`);
83
- const existingCollectionIndex = updatedConfig.collections.findIndex(
84
- (c) => c.name === collection.name
85
- );
86
- // Parse the collection permissions and attributes
87
- const collPermissions = this.parsePermissionsArray(
88
- collection.$permissions
89
- );
90
- const collAttributes = collection.attributes
91
- .map((attr: any) => {
92
- return parseAttribute(attr);
93
- })
94
- .filter((attribute) =>
95
- attribute.type === "relationship"
96
- ? attribute.side !== "child"
97
- : true
98
- );
99
- for (const attribute of collAttributes) {
100
- if (
101
- attribute.type === "relationship" &&
102
- attribute.relatedCollection
103
- ) {
104
- console.log(
105
- `Fetching related collection for ID: ${attribute.relatedCollection}`
106
- );
107
- try {
108
- const relatedCollectionPulled = await db.getCollection(
109
- database.$id,
110
- attribute.relatedCollection
111
- );
112
- console.log(
113
- `Fetched Collection Name: ${relatedCollectionPulled.name}`
114
- );
115
- attribute.relatedCollection = relatedCollectionPulled.name;
116
- console.log(
117
- `Updated attribute.relatedCollection to: ${attribute.relatedCollection}`
118
- );
119
- } catch (error) {
120
- console.log("Error fetching related collection:", error);
121
- }
122
- }
123
- }
124
- this.collToAttributeMap.set(collection.name, collAttributes);
125
- const finalIndexes = collection.indexes.map((index) => {
126
- return {
127
- ...index,
128
- orders: index.orders?.filter((order) => {
129
- return order !== null && order;
130
- }),
131
- };
132
- });
133
- const collIndexes = indexesSchema.parse(finalIndexes) ?? [];
134
-
135
- // Prepare the collection object to be added or updated
136
- const collToPush = CollectionSchema.parse({
137
- $id: collection.$id,
138
- name: collection.name,
139
- enabled: collection.enabled,
140
- documentSecurity: collection.documentSecurity,
141
- $createdAt: collection.$createdAt,
142
- $updatedAt: collection.$updatedAt,
143
- $permissions:
144
- collPermissions.length > 0 ? collPermissions : undefined,
145
- indexes: collIndexes.length > 0 ? collIndexes : undefined,
146
- attributes: collAttributes.length > 0 ? collAttributes : undefined,
147
- });
148
-
149
- if (existingCollectionIndex !== -1) {
150
- // Update existing collection
151
- updatedConfig.collections[existingCollectionIndex] = collToPush;
152
- } else {
153
- // Add new collection
154
- updatedConfig.collections.push(collToPush);
155
- }
156
- }
157
-
158
- console.log(
159
- `Processed ${collections.length} collections in ${database.name}`
160
- );
161
- }
162
- this.updatedConfig = updatedConfig;
163
- }
164
-
165
- async toSchemas() {
166
- await this.appwriteSync(this.config);
167
- const generator = new SchemaGenerator(
168
- this.updatedConfig,
169
- this.appwriteFolderPath
170
- );
171
- generator.updateTsSchemas();
172
- generator.generateSchemas();
173
- }
174
- }
1
+ import { SchemaGenerator } from "./schemaStrings.js";
2
+ import {
3
+ Client,
4
+ Compression,
5
+ Databases,
6
+ Query,
7
+ Storage,
8
+ type Models,
9
+ type Permission,
10
+ } from "node-appwrite";
11
+ import { fetchAllCollections } from "./collections.js";
12
+ import { fetchAllDatabases } from "./databases.js";
13
+ import {
14
+ CollectionSchema,
15
+ attributeSchema,
16
+ type AppwriteConfig,
17
+ AppwriteConfigSchema,
18
+ type ConfigDatabases,
19
+ type Attribute,
20
+ permissionsSchema,
21
+ attributesSchema,
22
+ indexesSchema,
23
+ parseAttribute,
24
+ } from "appwrite-utils";
25
+ import { getDatabaseFromConfig } from "./afterImportActions.js";
26
+ import { listBuckets } from "../storage/methods.js";
27
+
28
+ export class AppwriteToX {
29
+ config: AppwriteConfig;
30
+ storage: Storage;
31
+ updatedConfig: AppwriteConfig;
32
+ collToAttributeMap = new Map<string, Attribute[]>();
33
+ appwriteFolderPath: string;
34
+
35
+ constructor(
36
+ config: AppwriteConfig,
37
+ appwriteFolderPath: string,
38
+ storage: Storage
39
+ ) {
40
+ this.config = config;
41
+ this.updatedConfig = config;
42
+ this.storage = storage;
43
+ this.appwriteFolderPath = appwriteFolderPath;
44
+ }
45
+
46
+ // Function to parse a single permission string
47
+ parsePermissionString = (permissionString: string) => {
48
+ const match = permissionString.match(/^(\w+)\('([^']+)'\)$/);
49
+ if (!match) {
50
+ throw new Error(`Invalid permission format: ${permissionString}`);
51
+ }
52
+ return {
53
+ permission: match[1],
54
+ target: match[2],
55
+ };
56
+ };
57
+
58
+ // Function to parse an array of permission strings
59
+ parsePermissionsArray = (permissions: string[]) => {
60
+ if (permissions.length === 0) {
61
+ return [];
62
+ }
63
+ const parsedPermissions = permissionsSchema.parse(permissions);
64
+ // Validate the parsed permissions using Zod
65
+ return parsedPermissions ?? [];
66
+ };
67
+
68
+ updateCollectionConfigAttributes = (collection: Models.Collection) => {
69
+ for (const attribute of collection.attributes) {
70
+ const attributeMap = this.collToAttributeMap.get(
71
+ collection.name as string
72
+ );
73
+ const attributeParsed = attributeSchema.parse(attribute);
74
+ this.collToAttributeMap
75
+ .get(collection.name as string)
76
+ ?.push(attributeParsed);
77
+ }
78
+ };
79
+
80
+ async appwriteSync(config: AppwriteConfig, databases?: Models.Database[]) {
81
+ const db = getDatabaseFromConfig(config);
82
+ if (!databases) {
83
+ databases = await fetchAllDatabases(db);
84
+ }
85
+ let updatedConfig: AppwriteConfig = { ...config };
86
+
87
+ // Fetch all buckets
88
+ const allBuckets = await listBuckets(this.storage);
89
+
90
+ // Loop through each database
91
+ for (const database of databases) {
92
+ if (database.name.toLowerCase() === "migrations") {
93
+ continue;
94
+ }
95
+
96
+ // Match bucket to database
97
+ const matchedBucket = allBuckets.buckets.find((bucket) =>
98
+ bucket.$id.toLowerCase().includes(database.$id.toLowerCase())
99
+ );
100
+
101
+ if (matchedBucket) {
102
+ const dbConfig = updatedConfig.databases.find(
103
+ (db) => db.$id === database.$id
104
+ );
105
+ if (dbConfig) {
106
+ dbConfig.bucket = {
107
+ $id: matchedBucket.$id,
108
+ name: matchedBucket.name,
109
+ enabled: matchedBucket.enabled,
110
+ maximumFileSize: matchedBucket.maximumFileSize,
111
+ allowedFileExtensions: matchedBucket.allowedFileExtensions,
112
+ compression: matchedBucket.compression as Compression,
113
+ encryption: matchedBucket.encryption,
114
+ antivirus: matchedBucket.antivirus,
115
+ };
116
+ }
117
+ }
118
+
119
+ const collections = await fetchAllCollections(database.$id, db);
120
+
121
+ // Loop through each collection in the current database
122
+ if (!updatedConfig.collections) {
123
+ updatedConfig.collections = [];
124
+ }
125
+ for (const collection of collections) {
126
+ console.log(`Processing collection: ${collection.name}`);
127
+ const existingCollectionIndex = updatedConfig.collections.findIndex(
128
+ (c) => c.name === collection.name
129
+ );
130
+ // Parse the collection permissions and attributes
131
+ const collPermissions = this.parsePermissionsArray(
132
+ collection.$permissions
133
+ );
134
+ const collAttributes = collection.attributes
135
+ .map((attr: any) => {
136
+ return parseAttribute(attr);
137
+ })
138
+ .filter((attribute) =>
139
+ attribute.type === "relationship"
140
+ ? attribute.side !== "child"
141
+ : true
142
+ );
143
+ for (const attribute of collAttributes) {
144
+ if (
145
+ attribute.type === "relationship" &&
146
+ attribute.relatedCollection
147
+ ) {
148
+ console.log(
149
+ `Fetching related collection for ID: ${attribute.relatedCollection}`
150
+ );
151
+ try {
152
+ const relatedCollectionPulled = await db.getCollection(
153
+ database.$id,
154
+ attribute.relatedCollection
155
+ );
156
+ console.log(
157
+ `Fetched Collection Name: ${relatedCollectionPulled.name}`
158
+ );
159
+ attribute.relatedCollection = relatedCollectionPulled.name;
160
+ console.log(
161
+ `Updated attribute.relatedCollection to: ${attribute.relatedCollection}`
162
+ );
163
+ } catch (error) {
164
+ console.log("Error fetching related collection:", error);
165
+ }
166
+ }
167
+ }
168
+ this.collToAttributeMap.set(collection.name, collAttributes);
169
+ const finalIndexes = collection.indexes.map((index) => {
170
+ return {
171
+ ...index,
172
+ orders: index.orders?.filter((order) => {
173
+ return order !== null && order;
174
+ }),
175
+ };
176
+ });
177
+ const collIndexes = indexesSchema.parse(finalIndexes) ?? [];
178
+
179
+ // Prepare the collection object to be added or updated
180
+ const collToPush = CollectionSchema.parse({
181
+ $id: collection.$id,
182
+ name: collection.name,
183
+ enabled: collection.enabled,
184
+ documentSecurity: collection.documentSecurity,
185
+ $createdAt: collection.$createdAt,
186
+ $updatedAt: collection.$updatedAt,
187
+ $permissions:
188
+ collPermissions.length > 0 ? collPermissions : undefined,
189
+ indexes: collIndexes.length > 0 ? collIndexes : undefined,
190
+ attributes: collAttributes.length > 0 ? collAttributes : undefined,
191
+ });
192
+
193
+ if (existingCollectionIndex !== -1) {
194
+ // Update existing collection
195
+ updatedConfig.collections[existingCollectionIndex] = collToPush;
196
+ } else {
197
+ // Add new collection
198
+ updatedConfig.collections.push(collToPush);
199
+ }
200
+ }
201
+
202
+ console.log(
203
+ `Processed ${collections.length} collections in ${database.name}`
204
+ );
205
+ }
206
+ // Add unmatched buckets as global buckets
207
+ const globalBuckets = allBuckets.buckets.filter(
208
+ (bucket) =>
209
+ !updatedConfig.databases.some(
210
+ (db) => db.bucket && db.bucket.$id === bucket.$id
211
+ )
212
+ );
213
+
214
+ updatedConfig.buckets = globalBuckets.map((bucket) => ({
215
+ $id: bucket.$id,
216
+ name: bucket.name,
217
+ enabled: bucket.enabled,
218
+ maximumFileSize: bucket.maximumFileSize,
219
+ allowedFileExtensions: bucket.allowedFileExtensions,
220
+ compression: bucket.compression as Compression,
221
+ encryption: bucket.encryption,
222
+ antivirus: bucket.antivirus,
223
+ }));
224
+
225
+ this.updatedConfig = updatedConfig;
226
+ }
227
+
228
+ async toSchemas(databases?: Models.Database[]) {
229
+ await this.appwriteSync(this.config, databases);
230
+ const generator = new SchemaGenerator(
231
+ this.updatedConfig,
232
+ this.appwriteFolderPath
233
+ );
234
+ generator.updateTsSchemas();
235
+ generator.generateSchemas();
236
+ }
237
+ }