appwrite-utils-cli 0.10.86 → 1.0.1
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/.appwrite/.yaml_schemas/appwrite-config.schema.json +380 -0
- package/.appwrite/.yaml_schemas/collection.schema.json +255 -0
- package/.appwrite/collections/Categories.yaml +182 -0
- package/.appwrite/collections/ExampleCollection.yaml +36 -0
- package/.appwrite/collections/Posts.yaml +227 -0
- package/.appwrite/collections/Users.yaml +149 -0
- package/.appwrite/config.yaml +109 -0
- package/.appwrite/import/README.md +148 -0
- package/.appwrite/import/categories-import.yaml +129 -0
- package/.appwrite/import/posts-import.yaml +208 -0
- package/.appwrite/import/users-import.yaml +130 -0
- package/.appwrite/importData/categories.json +194 -0
- package/.appwrite/importData/posts.json +270 -0
- package/.appwrite/importData/users.json +220 -0
- package/.appwrite/schemas/categories.json +128 -0
- package/.appwrite/schemas/exampleCollection.json +52 -0
- package/.appwrite/schemas/posts.json +173 -0
- package/.appwrite/schemas/users.json +125 -0
- package/README.md +260 -33
- package/dist/collections/attributes.js +3 -2
- package/dist/collections/methods.js +56 -38
- package/dist/config/yamlConfig.d.ts +501 -0
- package/dist/config/yamlConfig.js +452 -0
- package/dist/databases/setup.d.ts +6 -0
- package/dist/databases/setup.js +119 -0
- package/dist/functions/methods.d.ts +1 -1
- package/dist/functions/methods.js +5 -2
- package/dist/functions/openapi.d.ts +4 -0
- package/dist/functions/openapi.js +60 -0
- package/dist/interactiveCLI.d.ts +5 -0
- package/dist/interactiveCLI.js +194 -49
- package/dist/main.js +91 -30
- package/dist/migrations/afterImportActions.js +2 -2
- package/dist/migrations/appwriteToX.d.ts +10 -0
- package/dist/migrations/appwriteToX.js +15 -4
- package/dist/migrations/backup.d.ts +16 -16
- package/dist/migrations/dataLoader.d.ts +83 -1
- package/dist/migrations/dataLoader.js +4 -4
- package/dist/migrations/importController.js +25 -18
- package/dist/migrations/importDataActions.js +2 -2
- package/dist/migrations/logging.d.ts +9 -1
- package/dist/migrations/logging.js +41 -22
- package/dist/migrations/migrationHelper.d.ts +4 -4
- package/dist/migrations/relationships.js +1 -1
- package/dist/migrations/services/DataTransformationService.d.ts +55 -0
- package/dist/migrations/services/DataTransformationService.js +158 -0
- package/dist/migrations/services/FileHandlerService.d.ts +75 -0
- package/dist/migrations/services/FileHandlerService.js +236 -0
- package/dist/migrations/services/ImportOrchestrator.d.ts +97 -0
- package/dist/migrations/services/ImportOrchestrator.js +488 -0
- package/dist/migrations/services/RateLimitManager.d.ts +138 -0
- package/dist/migrations/services/RateLimitManager.js +279 -0
- package/dist/migrations/services/RelationshipResolver.d.ts +120 -0
- package/dist/migrations/services/RelationshipResolver.js +332 -0
- package/dist/migrations/services/UserMappingService.d.ts +109 -0
- package/dist/migrations/services/UserMappingService.js +277 -0
- package/dist/migrations/services/ValidationService.d.ts +74 -0
- package/dist/migrations/services/ValidationService.js +260 -0
- package/dist/migrations/transfer.d.ts +0 -6
- package/dist/migrations/transfer.js +16 -132
- package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +384 -0
- package/dist/migrations/yaml/YamlImportConfigLoader.js +375 -0
- package/dist/migrations/yaml/YamlImportIntegration.d.ts +87 -0
- package/dist/migrations/yaml/YamlImportIntegration.js +330 -0
- package/dist/migrations/yaml/generateImportSchemas.d.ts +17 -0
- package/dist/migrations/yaml/generateImportSchemas.js +575 -0
- package/dist/schemas/authUser.d.ts +9 -9
- package/dist/shared/attributeManager.d.ts +17 -0
- package/dist/shared/attributeManager.js +273 -0
- package/dist/shared/confirmationDialogs.d.ts +75 -0
- package/dist/shared/confirmationDialogs.js +236 -0
- package/dist/shared/functionManager.d.ts +48 -0
- package/dist/shared/functionManager.js +322 -0
- package/dist/shared/indexManager.d.ts +24 -0
- package/dist/shared/indexManager.js +150 -0
- package/dist/shared/jsonSchemaGenerator.d.ts +51 -0
- package/dist/shared/jsonSchemaGenerator.js +313 -0
- package/dist/shared/logging.d.ts +10 -0
- package/dist/shared/logging.js +46 -0
- package/dist/shared/messageFormatter.d.ts +37 -0
- package/dist/shared/messageFormatter.js +152 -0
- package/dist/shared/migrationHelpers.d.ts +173 -0
- package/dist/shared/migrationHelpers.js +142 -0
- package/dist/shared/operationLogger.d.ts +3 -0
- package/dist/shared/operationLogger.js +25 -0
- package/dist/shared/operationQueue.d.ts +13 -0
- package/dist/shared/operationQueue.js +79 -0
- package/dist/shared/progressManager.d.ts +62 -0
- package/dist/shared/progressManager.js +215 -0
- package/dist/shared/schemaGenerator.d.ts +18 -0
- package/dist/shared/schemaGenerator.js +523 -0
- package/dist/storage/methods.d.ts +3 -1
- package/dist/storage/methods.js +144 -55
- package/dist/storage/schemas.d.ts +56 -16
- package/dist/types.d.ts +2 -2
- package/dist/types.js +1 -1
- package/dist/users/methods.d.ts +16 -0
- package/dist/users/methods.js +276 -0
- package/dist/utils/configMigration.d.ts +1 -0
- package/dist/utils/configMigration.js +156 -0
- package/dist/utils/dataConverters.d.ts +46 -0
- package/dist/utils/dataConverters.js +139 -0
- package/dist/utils/loadConfigs.d.ts +15 -4
- package/dist/utils/loadConfigs.js +377 -51
- package/dist/utils/schemaStrings.js +2 -1
- package/dist/utils/setupFiles.d.ts +2 -1
- package/dist/utils/setupFiles.js +723 -28
- package/dist/utils/validationRules.d.ts +43 -0
- package/dist/utils/validationRules.js +42 -0
- package/dist/utils/yamlConverter.d.ts +48 -0
- package/dist/utils/yamlConverter.js +98 -0
- package/dist/utilsController.js +65 -43
- package/package.json +19 -15
- package/src/collections/attributes.ts +3 -2
- package/src/collections/methods.ts +85 -51
- package/src/config/yamlConfig.ts +488 -0
- package/src/{migrations/setupDatabase.ts → databases/setup.ts} +11 -5
- package/src/functions/methods.ts +8 -4
- package/src/functions/templates/count-docs-in-collection/package.json +25 -0
- package/src/functions/templates/count-docs-in-collection/tsconfig.json +28 -0
- package/src/functions/templates/typescript-node/package.json +24 -0
- package/src/functions/templates/typescript-node/tsconfig.json +28 -0
- package/src/functions/templates/uv/README.md +31 -0
- package/src/functions/templates/uv/pyproject.toml +29 -0
- package/src/interactiveCLI.ts +226 -61
- package/src/main.ts +111 -37
- package/src/migrations/afterImportActions.ts +2 -2
- package/src/migrations/appwriteToX.ts +17 -4
- package/src/migrations/dataLoader.ts +4 -4
- package/src/migrations/importController.ts +30 -22
- package/src/migrations/importDataActions.ts +2 -2
- package/src/migrations/relationships.ts +1 -1
- package/src/migrations/services/DataTransformationService.ts +196 -0
- package/src/migrations/services/FileHandlerService.ts +311 -0
- package/src/migrations/services/ImportOrchestrator.ts +669 -0
- package/src/migrations/services/RateLimitManager.ts +363 -0
- package/src/migrations/services/RelationshipResolver.ts +461 -0
- package/src/migrations/services/UserMappingService.ts +345 -0
- package/src/migrations/services/ValidationService.ts +349 -0
- package/src/migrations/transfer.ts +22 -228
- package/src/migrations/yaml/YamlImportConfigLoader.ts +427 -0
- package/src/migrations/yaml/YamlImportIntegration.ts +419 -0
- package/src/migrations/yaml/generateImportSchemas.ts +589 -0
- package/src/shared/attributeManager.ts +429 -0
- package/src/shared/confirmationDialogs.ts +327 -0
- package/src/shared/functionManager.ts +515 -0
- package/src/shared/indexManager.ts +253 -0
- package/src/shared/jsonSchemaGenerator.ts +403 -0
- package/src/shared/logging.ts +74 -0
- package/src/shared/messageFormatter.ts +195 -0
- package/src/{migrations/migrationHelper.ts → shared/migrationHelpers.ts} +22 -4
- package/src/{migrations/helper.ts → shared/operationLogger.ts} +7 -2
- package/src/{migrations/queue.ts → shared/operationQueue.ts} +1 -1
- package/src/shared/progressManager.ts +278 -0
- package/src/{migrations/schemaStrings.ts → shared/schemaGenerator.ts} +71 -17
- package/src/storage/methods.ts +199 -78
- package/src/types.ts +2 -2
- package/src/{migrations/users.ts → users/methods.ts} +2 -2
- package/src/utils/configMigration.ts +212 -0
- package/src/utils/loadConfigs.ts +414 -52
- package/src/utils/schemaStrings.ts +2 -1
- package/src/utils/setupFiles.ts +742 -40
- package/src/{migrations → utils}/validationRules.ts +1 -1
- package/src/utils/yamlConverter.ts +131 -0
- package/src/utilsController.ts +75 -54
- package/src/functions/templates/poetry/README.md +0 -30
- package/src/functions/templates/poetry/pyproject.toml +0 -16
- package/src/migrations/attributes.ts +0 -561
- package/src/migrations/backup.ts +0 -205
- package/src/migrations/databases.ts +0 -39
- package/src/migrations/dbHelpers.ts +0 -92
- package/src/migrations/indexes.ts +0 -40
- package/src/migrations/logging.ts +0 -29
- package/src/migrations/storage.ts +0 -538
- /package/src/{migrations → functions}/openapi.ts +0 -0
- /package/src/functions/templates/{poetry → uv}/src/__init__.py +0 -0
- /package/src/functions/templates/{poetry → uv}/src/index.py +0 -0
- /package/src/{migrations/converters.ts → utils/dataConverters.ts} +0 -0
package/dist/main.js
CHANGED
@@ -6,29 +6,31 @@ import { InteractiveCLI } from "./interactiveCLI.js";
|
|
6
6
|
import { UtilsController } from "./utilsController.js";
|
7
7
|
import { Databases, Storage } from "node-appwrite";
|
8
8
|
import { getClient } from "./utils/getClientFromConfig.js";
|
9
|
-
import { fetchAllDatabases } from "./
|
9
|
+
import { fetchAllDatabases } from "./databases/methods.js";
|
10
10
|
import { setupDirsFiles } from "./utils/setupFiles.js";
|
11
11
|
import { fetchAllCollections } from "./collections/methods.js";
|
12
12
|
import chalk from "chalk";
|
13
13
|
import { listSpecifications } from "./functions/methods.js";
|
14
|
+
import { MessageFormatter } from "./shared/messageFormatter.js";
|
15
|
+
import { ConfirmationDialogs } from "./shared/confirmationDialogs.js";
|
14
16
|
const argv = yargs(hideBin(process.argv))
|
15
17
|
.option("config", {
|
16
18
|
type: "string",
|
17
|
-
description: "Appwrite
|
19
|
+
description: "Path to Appwrite configuration file (appwriteConfig.ts)",
|
18
20
|
})
|
19
21
|
.option("it", {
|
20
22
|
alias: ["interactive", "i"],
|
21
23
|
type: "boolean",
|
22
|
-
description: "
|
24
|
+
description: "Launch interactive CLI mode with guided prompts",
|
23
25
|
})
|
24
26
|
.option("dbIds", {
|
25
27
|
type: "string",
|
26
|
-
description: "Comma-separated list of database IDs to
|
28
|
+
description: "Comma-separated list of database IDs to target (e.g., 'db1,db2,db3')",
|
27
29
|
})
|
28
30
|
.option("collectionIds", {
|
29
31
|
alias: ["collIds"],
|
30
32
|
type: "string",
|
31
|
-
description: "Comma-separated list of collection IDs to
|
33
|
+
description: "Comma-separated list of collection IDs to target (e.g., 'users,posts')",
|
32
34
|
})
|
33
35
|
.option("bucketIds", {
|
34
36
|
type: "string",
|
@@ -36,11 +38,11 @@ const argv = yargs(hideBin(process.argv))
|
|
36
38
|
})
|
37
39
|
.option("wipe", {
|
38
40
|
choices: ["all", "docs", "users"],
|
39
|
-
description: "Wipe data (all:
|
41
|
+
description: "⚠️ DESTRUCTIVE: Wipe data (all: databases+storage+users, docs: documents only, users: user accounts only)",
|
40
42
|
})
|
41
43
|
.option("wipeCollections", {
|
42
44
|
type: "boolean",
|
43
|
-
description: "Wipe collections
|
45
|
+
description: "⚠️ DESTRUCTIVE: Wipe specific collections (requires --collectionIds)",
|
44
46
|
})
|
45
47
|
.option("transferUsers", {
|
46
48
|
type: "boolean",
|
@@ -48,27 +50,27 @@ const argv = yargs(hideBin(process.argv))
|
|
48
50
|
})
|
49
51
|
.option("generate", {
|
50
52
|
type: "boolean",
|
51
|
-
description: "Generate TypeScript schemas from database schemas",
|
53
|
+
description: "Generate TypeScript schemas and types from your Appwrite database schemas",
|
52
54
|
})
|
53
55
|
.option("import", {
|
54
56
|
type: "boolean",
|
55
|
-
description: "Import data into your databases",
|
57
|
+
description: "Import data from importData/ directory into your Appwrite databases",
|
56
58
|
})
|
57
59
|
.option("backup", {
|
58
60
|
type: "boolean",
|
59
|
-
description: "
|
61
|
+
description: "Create a complete backup of your databases and collections",
|
60
62
|
})
|
61
63
|
.option("writeData", {
|
62
64
|
type: "boolean",
|
63
|
-
description: "
|
65
|
+
description: "Output converted import data to files for validation before importing",
|
64
66
|
})
|
65
67
|
.option("push", {
|
66
68
|
type: "boolean",
|
67
|
-
description: "
|
69
|
+
description: "Deploy your local configuration (collections, attributes, indexes) to Appwrite",
|
68
70
|
})
|
69
71
|
.option("sync", {
|
70
72
|
type: "boolean",
|
71
|
-
description: "
|
73
|
+
description: "Pull and synchronize your local config with the remote Appwrite project schema",
|
72
74
|
})
|
73
75
|
.option("endpoint", {
|
74
76
|
type: "string",
|
@@ -84,17 +86,17 @@ const argv = yargs(hideBin(process.argv))
|
|
84
86
|
})
|
85
87
|
.option("transfer", {
|
86
88
|
type: "boolean",
|
87
|
-
description: "Transfer
|
89
|
+
description: "Transfer documents and files between databases, collections, or projects",
|
88
90
|
})
|
89
91
|
.option("fromDbId", {
|
90
92
|
alias: ["fromDb", "sourceDbId", "sourceDb"],
|
91
93
|
type: "string",
|
92
|
-
description: "
|
94
|
+
description: "Source database ID for transfer operations",
|
93
95
|
})
|
94
96
|
.option("toDbId", {
|
95
97
|
alias: ["toDb", "targetDbId", "targetDb"],
|
96
98
|
type: "string",
|
97
|
-
description: "
|
99
|
+
description: "Target database ID for transfer operations",
|
98
100
|
})
|
99
101
|
.option("fromCollectionId", {
|
100
102
|
alias: ["fromCollId", "fromColl"],
|
@@ -128,7 +130,7 @@ const argv = yargs(hideBin(process.argv))
|
|
128
130
|
})
|
129
131
|
.option("setup", {
|
130
132
|
type: "boolean",
|
131
|
-
description: "
|
133
|
+
description: "Initialize project with configuration files and directory structure",
|
132
134
|
})
|
133
135
|
.option("updateFunctionSpec", {
|
134
136
|
type: "boolean",
|
@@ -151,9 +153,16 @@ const argv = yargs(hideBin(process.argv))
|
|
151
153
|
"s-8vcpu-4gb",
|
152
154
|
"s-8vcpu-8gb",
|
153
155
|
],
|
156
|
+
})
|
157
|
+
.option("migrateConfig", {
|
158
|
+
alias: ["migrate"],
|
159
|
+
type: "boolean",
|
160
|
+
description: "Migrate appwriteConfig.ts to .appwrite structure with YAML configuration",
|
154
161
|
})
|
155
162
|
.parse();
|
156
163
|
async function main() {
|
164
|
+
const startTime = Date.now();
|
165
|
+
const operationStats = {};
|
157
166
|
if (argv.it) {
|
158
167
|
const cli = new InteractiveCLI(process.cwd());
|
159
168
|
await cli.run();
|
@@ -172,8 +181,13 @@ async function main() {
|
|
172
181
|
await setupDirsFiles(false, process.cwd());
|
173
182
|
return;
|
174
183
|
}
|
184
|
+
if (argv.migrateConfig) {
|
185
|
+
const { migrateConfig } = await import("./utils/configMigration.js");
|
186
|
+
await migrateConfig(process.cwd());
|
187
|
+
return;
|
188
|
+
}
|
175
189
|
if (!controller.config) {
|
176
|
-
|
190
|
+
MessageFormatter.error("No Appwrite connection found", undefined, { prefix: "CLI" });
|
177
191
|
return;
|
178
192
|
}
|
179
193
|
const parsedArgv = argv;
|
@@ -196,10 +210,10 @@ async function main() {
|
|
196
210
|
if (!parsedArgv.functionId || !parsedArgv.specification) {
|
197
211
|
throw new Error("Function ID and specification are required for updating function specs");
|
198
212
|
}
|
199
|
-
|
213
|
+
MessageFormatter.info(`Updating function specification for ${parsedArgv.functionId} to ${parsedArgv.specification}`, { prefix: "Functions" });
|
200
214
|
const specifications = await listSpecifications(controller.appwriteServer);
|
201
215
|
if (!specifications.specifications.some((s) => s.slug === parsedArgv.specification)) {
|
202
|
-
|
216
|
+
MessageFormatter.error(`Specification ${parsedArgv.specification} not found`, undefined, { prefix: "Functions" });
|
203
217
|
return;
|
204
218
|
}
|
205
219
|
await controller.updateFunctionSpecifications(parsedArgv.functionId, parsedArgv.specification);
|
@@ -207,7 +221,10 @@ async function main() {
|
|
207
221
|
// Add default databases if not specified
|
208
222
|
if (!options.databases || options.databases.length === 0) {
|
209
223
|
const allDatabases = await fetchAllDatabases(controller.database);
|
210
|
-
options.databases = allDatabases.filter((db) =>
|
224
|
+
options.databases = allDatabases.filter((db) => {
|
225
|
+
const useMigrations = controller.config?.useMigrations ?? true;
|
226
|
+
return useMigrations || db.name.toLowerCase() !== "migrations";
|
227
|
+
});
|
211
228
|
}
|
212
229
|
// Add default collections if not specified
|
213
230
|
if (!options.collections || options.collections.length === 0) {
|
@@ -219,47 +236,80 @@ async function main() {
|
|
219
236
|
}
|
220
237
|
}
|
221
238
|
if (options.doBackup && options.databases) {
|
239
|
+
MessageFormatter.info(`Creating backups for ${options.databases.length} database(s)`, { prefix: "Backup" });
|
222
240
|
for (const db of options.databases) {
|
223
241
|
await controller.backupDatabase(db);
|
224
242
|
}
|
243
|
+
operationStats.backups = options.databases.length;
|
244
|
+
MessageFormatter.success(`Backup completed for ${options.databases.length} database(s)`, { prefix: "Backup" });
|
225
245
|
}
|
226
246
|
if (options.wipeDatabase ||
|
227
247
|
options.wipeDocumentStorage ||
|
228
248
|
options.wipeUsers ||
|
229
249
|
options.wipeCollections) {
|
250
|
+
// Confirm destructive operations
|
251
|
+
const databaseNames = options.databases?.map(db => db.name) || [];
|
252
|
+
const confirmed = await ConfirmationDialogs.confirmDatabaseWipe(databaseNames, {
|
253
|
+
includeStorage: options.wipeDocumentStorage,
|
254
|
+
includeUsers: options.wipeUsers
|
255
|
+
});
|
256
|
+
if (!confirmed) {
|
257
|
+
MessageFormatter.info("Operation cancelled by user", { prefix: "CLI" });
|
258
|
+
return;
|
259
|
+
}
|
260
|
+
let wipeStats = { databases: 0, collections: 0, users: 0, buckets: 0 };
|
230
261
|
if (parsedArgv.wipe === "all") {
|
231
262
|
if (options.databases) {
|
232
263
|
for (const db of options.databases) {
|
233
264
|
await controller.wipeDatabase(db, true); // true to wipe associated buckets
|
234
265
|
}
|
266
|
+
wipeStats.databases = options.databases.length;
|
235
267
|
}
|
236
268
|
await controller.wipeUsers();
|
269
|
+
wipeStats.users = 1;
|
237
270
|
}
|
238
271
|
else if (parsedArgv.wipe === "docs") {
|
239
272
|
if (options.databases) {
|
240
273
|
for (const db of options.databases) {
|
241
274
|
await controller.wipeBucketFromDatabase(db);
|
242
275
|
}
|
276
|
+
wipeStats.databases = options.databases.length;
|
243
277
|
}
|
244
278
|
if (parsedArgv.bucketIds) {
|
245
|
-
|
279
|
+
const bucketIds = parsedArgv.bucketIds.split(",");
|
280
|
+
for (const bucketId of bucketIds) {
|
246
281
|
await controller.wipeDocumentStorage(bucketId);
|
247
282
|
}
|
283
|
+
wipeStats.buckets = bucketIds.length;
|
248
284
|
}
|
249
285
|
}
|
250
286
|
else if (parsedArgv.wipe === "users") {
|
251
287
|
await controller.wipeUsers();
|
288
|
+
wipeStats.users = 1;
|
252
289
|
}
|
253
290
|
// Handle specific collection wipes
|
254
291
|
if (options.wipeCollections && options.databases) {
|
255
292
|
for (const db of options.databases) {
|
256
293
|
const dbCollections = await fetchAllCollections(db.$id, controller.database);
|
257
294
|
const collectionsToWipe = dbCollections.filter((c) => options.collections.includes(c.$id));
|
258
|
-
|
259
|
-
|
295
|
+
// Confirm collection wipe
|
296
|
+
const collectionNames = collectionsToWipe.map(c => c.name);
|
297
|
+
const collectionConfirmed = await ConfirmationDialogs.confirmCollectionWipe(db.name, collectionNames);
|
298
|
+
if (collectionConfirmed) {
|
299
|
+
for (const collection of collectionsToWipe) {
|
300
|
+
await controller.wipeCollection(db, collection);
|
301
|
+
}
|
302
|
+
wipeStats.collections += collectionsToWipe.length;
|
260
303
|
}
|
261
304
|
}
|
262
305
|
}
|
306
|
+
// Show wipe operation summary
|
307
|
+
if (wipeStats.databases > 0 || wipeStats.collections > 0 || wipeStats.users > 0 || wipeStats.buckets > 0) {
|
308
|
+
operationStats.wipedDatabases = wipeStats.databases;
|
309
|
+
operationStats.wipedCollections = wipeStats.collections;
|
310
|
+
operationStats.wipedUsers = wipeStats.users;
|
311
|
+
operationStats.wipedBuckets = wipeStats.buckets;
|
312
|
+
}
|
263
313
|
}
|
264
314
|
if (parsedArgv.push || parsedArgv.sync) {
|
265
315
|
const databases = options.databases || (await fetchAllDatabases(controller.database));
|
@@ -272,16 +322,21 @@ async function main() {
|
|
272
322
|
}
|
273
323
|
if (parsedArgv.push) {
|
274
324
|
await controller.syncDb(databases, collections);
|
325
|
+
operationStats.pushedDatabases = databases.length;
|
326
|
+
operationStats.pushedCollections = collections.length;
|
275
327
|
}
|
276
328
|
else if (parsedArgv.sync) {
|
277
329
|
await controller.synchronizeConfigurations(databases);
|
330
|
+
operationStats.syncedDatabases = databases.length;
|
278
331
|
}
|
279
332
|
}
|
280
333
|
if (options.generateSchemas) {
|
281
334
|
await controller.generateSchemas();
|
335
|
+
operationStats.generatedSchemas = 1;
|
282
336
|
}
|
283
337
|
if (options.importData) {
|
284
338
|
await controller.importData(options);
|
339
|
+
operationStats.importCompleted = 1;
|
285
340
|
}
|
286
341
|
if (parsedArgv.transfer) {
|
287
342
|
const isRemote = !!parsedArgv.remoteEndpoint;
|
@@ -290,10 +345,10 @@ async function main() {
|
|
290
345
|
let targetStorage;
|
291
346
|
// Only fetch databases if database IDs are provided
|
292
347
|
if (parsedArgv.fromDbId && parsedArgv.toDbId) {
|
293
|
-
|
348
|
+
MessageFormatter.info(`Starting database transfer from ${parsedArgv.fromDbId} to ${parsedArgv.toDbId}`, { prefix: "Transfer" });
|
294
349
|
fromDb = (await controller.getDatabasesByIds([parsedArgv.fromDbId]))?.[0];
|
295
350
|
if (!fromDb) {
|
296
|
-
|
351
|
+
MessageFormatter.error("Source database not found", undefined, { prefix: "Transfer" });
|
297
352
|
return;
|
298
353
|
}
|
299
354
|
if (isRemote) {
|
@@ -308,19 +363,19 @@ async function main() {
|
|
308
363
|
const remoteDbs = await fetchAllDatabases(targetDatabases);
|
309
364
|
toDb = remoteDbs.find((db) => db.$id === parsedArgv.toDbId);
|
310
365
|
if (!toDb) {
|
311
|
-
|
366
|
+
MessageFormatter.error("Target database not found", undefined, { prefix: "Transfer" });
|
312
367
|
return;
|
313
368
|
}
|
314
369
|
}
|
315
370
|
else {
|
316
371
|
toDb = (await controller.getDatabasesByIds([parsedArgv.toDbId]))?.[0];
|
317
372
|
if (!toDb) {
|
318
|
-
|
373
|
+
MessageFormatter.error("Target database not found", undefined, { prefix: "Transfer" });
|
319
374
|
return;
|
320
375
|
}
|
321
376
|
}
|
322
377
|
if (!fromDb || !toDb) {
|
323
|
-
|
378
|
+
MessageFormatter.error("Source or target database not found", undefined, { prefix: "Transfer" });
|
324
379
|
return;
|
325
380
|
}
|
326
381
|
}
|
@@ -357,10 +412,16 @@ async function main() {
|
|
357
412
|
transferUsers: options.transferUsers,
|
358
413
|
};
|
359
414
|
await controller.transferData(transferOptions);
|
415
|
+
operationStats.transfers = 1;
|
416
|
+
}
|
417
|
+
// Show final operation summary if any operations were performed
|
418
|
+
if (Object.keys(operationStats).length > 0) {
|
419
|
+
const duration = Date.now() - startTime;
|
420
|
+
MessageFormatter.operationSummary("CLI Operations", operationStats, duration);
|
360
421
|
}
|
361
422
|
}
|
362
423
|
}
|
363
424
|
main().catch((error) => {
|
364
|
-
|
425
|
+
MessageFormatter.error("CLI execution failed", error, { prefix: "CLI" });
|
365
426
|
process.exit(1);
|
366
427
|
});
|
@@ -3,7 +3,7 @@ import { InputFile } from "node-appwrite/file";
|
|
3
3
|
import path from "path";
|
4
4
|
import fs from "fs";
|
5
5
|
import os from "os";
|
6
|
-
import { logger } from "
|
6
|
+
import { logger } from "../shared/logging.js";
|
7
7
|
import { tryAwaitWithRetry, } from "appwrite-utils";
|
8
8
|
export const getDatabaseFromConfig = (config) => {
|
9
9
|
if (!config.appwriteClient) {
|
@@ -264,7 +264,7 @@ export const afterImportActions = {
|
|
264
264
|
// Use arrayBuffer if buffer is not available
|
265
265
|
const arrayBuffer = await response.arrayBuffer();
|
266
266
|
const buffer = Buffer.from(arrayBuffer);
|
267
|
-
fs.writeFileSync(tempFilePath, buffer);
|
267
|
+
fs.writeFileSync(tempFilePath, new Uint8Array(buffer));
|
268
268
|
// Create InputFile from the downloaded file
|
269
269
|
const inputFile = InputFile.fromPath(tempFilePath, fileName);
|
270
270
|
// Use the full file name (with extension) for creating the file
|
@@ -25,6 +25,16 @@ export declare class AppwriteToX {
|
|
25
25
|
xdefault?: number | null | undefined;
|
26
26
|
min?: number | undefined;
|
27
27
|
max?: number | undefined;
|
28
|
+
} | {
|
29
|
+
type: "double";
|
30
|
+
key: string;
|
31
|
+
description?: string | Record<string, string> | null | undefined;
|
32
|
+
required?: boolean | undefined;
|
33
|
+
array?: boolean | undefined;
|
34
|
+
error?: string | undefined;
|
35
|
+
xdefault?: number | null | undefined;
|
36
|
+
min?: number | undefined;
|
37
|
+
max?: number | undefined;
|
28
38
|
} | {
|
29
39
|
type: "float";
|
30
40
|
key: string;
|
@@ -1,7 +1,8 @@
|
|
1
|
-
import { SchemaGenerator } from "
|
1
|
+
import { SchemaGenerator } from "../shared/schemaGenerator.js";
|
2
|
+
import { findYamlConfig } from "../config/yamlConfig.js";
|
2
3
|
import { Client, Compression, Databases, Query, Storage, } from "node-appwrite";
|
3
4
|
import { fetchAllCollections } from "../collections/methods.js";
|
4
|
-
import { fetchAllDatabases } from "
|
5
|
+
import { fetchAllDatabases } from "../databases/methods.js";
|
5
6
|
import { CollectionSchema, attributeSchema, AppwriteConfigSchema, permissionsSchema, attributesSchema, indexesSchema, parseAttribute, } from "appwrite-utils";
|
6
7
|
import { getDatabaseFromConfig } from "./afterImportActions.js";
|
7
8
|
import { listBuckets } from "../storage/methods.js";
|
@@ -57,7 +58,7 @@ export class AppwriteToX {
|
|
57
58
|
const allBuckets = await listBuckets(this.storage);
|
58
59
|
// Loop through each database
|
59
60
|
for (const database of databases) {
|
60
|
-
if (database.name.toLowerCase() === "migrations") {
|
61
|
+
if (!this.config.useMigrations && database.name.toLowerCase() === "migrations") {
|
61
62
|
continue;
|
62
63
|
}
|
63
64
|
// Match bucket to database
|
@@ -189,7 +190,17 @@ export class AppwriteToX {
|
|
189
190
|
async toSchemas(databases) {
|
190
191
|
await this.appwriteSync(this.config, databases);
|
191
192
|
const generator = new SchemaGenerator(this.updatedConfig, this.appwriteFolderPath);
|
192
|
-
|
193
|
+
// Check if this is a YAML-based project
|
194
|
+
const yamlConfigPath = findYamlConfig(this.appwriteFolderPath);
|
195
|
+
const isYamlProject = !!yamlConfigPath;
|
196
|
+
if (isYamlProject) {
|
197
|
+
console.log("📄 Detected YAML configuration - generating YAML collection definitions");
|
198
|
+
generator.updateYamlCollections();
|
199
|
+
}
|
200
|
+
else {
|
201
|
+
console.log("📝 Generating TypeScript collection definitions");
|
202
|
+
generator.updateTsSchemas();
|
203
|
+
}
|
193
204
|
generator.generateSchemas();
|
194
205
|
}
|
195
206
|
}
|
@@ -9,31 +9,31 @@ export declare const BackupSchema: z.ZodObject<{
|
|
9
9
|
collectionId: z.ZodString;
|
10
10
|
data: z.ZodString;
|
11
11
|
}, "strip", z.ZodTypeAny, {
|
12
|
-
collectionId: string;
|
13
12
|
data: string;
|
14
|
-
}, {
|
15
13
|
collectionId: string;
|
14
|
+
}, {
|
16
15
|
data: string;
|
16
|
+
collectionId: string;
|
17
17
|
}>, "many">>;
|
18
18
|
}, "strip", z.ZodTypeAny, {
|
19
|
-
collections: string[];
|
20
19
|
documents: {
|
21
|
-
collectionId: string;
|
22
20
|
data: string;
|
21
|
+
collectionId: string;
|
23
22
|
}[];
|
24
23
|
$id: string;
|
24
|
+
collections: string[];
|
25
25
|
$createdAt: string;
|
26
26
|
$updatedAt: string;
|
27
27
|
database: string;
|
28
28
|
}, {
|
29
|
-
collections: string[];
|
30
29
|
$id: string;
|
30
|
+
collections: string[];
|
31
31
|
$createdAt: string;
|
32
32
|
$updatedAt: string;
|
33
33
|
database: string;
|
34
34
|
documents?: {
|
35
|
-
collectionId: string;
|
36
35
|
data: string;
|
36
|
+
collectionId: string;
|
37
37
|
}[] | undefined;
|
38
38
|
}>;
|
39
39
|
export type Backup = z.infer<typeof BackupSchema>;
|
@@ -47,25 +47,25 @@ export declare const BackupCreateSchema: z.ZodObject<Omit<{
|
|
47
47
|
collectionId: z.ZodString;
|
48
48
|
data: z.ZodString;
|
49
49
|
}, "strip", z.ZodTypeAny, {
|
50
|
-
collectionId: string;
|
51
50
|
data: string;
|
52
|
-
}, {
|
53
51
|
collectionId: string;
|
52
|
+
}, {
|
54
53
|
data: string;
|
54
|
+
collectionId: string;
|
55
55
|
}>, "many">>;
|
56
56
|
}, "$id" | "$createdAt" | "$updatedAt">, "strip", z.ZodTypeAny, {
|
57
|
-
collections: string[];
|
58
57
|
documents: {
|
59
|
-
collectionId: string;
|
60
58
|
data: string;
|
59
|
+
collectionId: string;
|
61
60
|
}[];
|
61
|
+
collections: string[];
|
62
62
|
database: string;
|
63
63
|
}, {
|
64
64
|
collections: string[];
|
65
65
|
database: string;
|
66
66
|
documents?: {
|
67
|
-
collectionId: string;
|
68
67
|
data: string;
|
68
|
+
collectionId: string;
|
69
69
|
}[] | undefined;
|
70
70
|
}>;
|
71
71
|
export type BackupCreate = z.infer<typeof BackupCreateSchema>;
|
@@ -76,16 +76,16 @@ export declare const BatchSchema: z.ZodObject<{
|
|
76
76
|
data: z.ZodString;
|
77
77
|
processed: z.ZodDefault<z.ZodBoolean>;
|
78
78
|
}, "strip", z.ZodTypeAny, {
|
79
|
+
data: string;
|
79
80
|
$id: string;
|
80
81
|
$createdAt: string;
|
81
82
|
$updatedAt: string;
|
82
|
-
data: string;
|
83
83
|
processed: boolean;
|
84
84
|
}, {
|
85
|
+
data: string;
|
85
86
|
$id: string;
|
86
87
|
$createdAt: string;
|
87
88
|
$updatedAt: string;
|
88
|
-
data: string;
|
89
89
|
processed?: boolean | undefined;
|
90
90
|
}>;
|
91
91
|
export type Batch = z.infer<typeof BatchSchema>;
|
@@ -116,11 +116,11 @@ export declare const OperationSchema: z.ZodObject<{
|
|
116
116
|
error: z.ZodString;
|
117
117
|
status: z.ZodDefault<z.ZodEnum<["pending", "ready", "in_progress", "completed", "error", "cancelled"]>>;
|
118
118
|
}, "strip", z.ZodTypeAny, {
|
119
|
+
status: "error" | "pending" | "ready" | "in_progress" | "completed" | "cancelled";
|
120
|
+
error: string;
|
119
121
|
$id: string;
|
120
122
|
$createdAt: string;
|
121
123
|
$updatedAt: string;
|
122
|
-
status: "error" | "pending" | "ready" | "in_progress" | "completed" | "cancelled";
|
123
|
-
error: string;
|
124
124
|
collectionId: string;
|
125
125
|
operationType: string;
|
126
126
|
progress: number;
|
@@ -128,10 +128,10 @@ export declare const OperationSchema: z.ZodObject<{
|
|
128
128
|
data?: any;
|
129
129
|
batches?: string[] | undefined;
|
130
130
|
}, {
|
131
|
+
error: string;
|
131
132
|
$id: string;
|
132
133
|
$createdAt: string;
|
133
134
|
$updatedAt: string;
|
134
|
-
error: string;
|
135
135
|
collectionId: string;
|
136
136
|
operationType: string;
|
137
137
|
progress: number;
|
@@ -87,7 +87,6 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
87
87
|
max?: number | undefined;
|
88
88
|
}>, z.ZodObject<{
|
89
89
|
key: z.ZodString;
|
90
|
-
type: z.ZodDefault<z.ZodLiteral<"float">>;
|
91
90
|
error: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
92
91
|
required: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
93
92
|
array: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
@@ -95,6 +94,39 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
95
94
|
max: z.ZodOptional<z.ZodNumber>;
|
96
95
|
xdefault: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
97
96
|
description: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
|
97
|
+
} & {
|
98
|
+
type: z.ZodDefault<z.ZodLiteral<"double">>;
|
99
|
+
}, "strip", z.ZodTypeAny, {
|
100
|
+
type: "double";
|
101
|
+
key: string;
|
102
|
+
description?: string | Record<string, string> | null | undefined;
|
103
|
+
required?: boolean | undefined;
|
104
|
+
array?: boolean | undefined;
|
105
|
+
error?: string | undefined;
|
106
|
+
xdefault?: number | null | undefined;
|
107
|
+
min?: number | undefined;
|
108
|
+
max?: number | undefined;
|
109
|
+
}, {
|
110
|
+
key: string;
|
111
|
+
type?: "double" | undefined;
|
112
|
+
description?: string | Record<string, string> | null | undefined;
|
113
|
+
required?: boolean | undefined;
|
114
|
+
array?: boolean | undefined;
|
115
|
+
error?: string | undefined;
|
116
|
+
xdefault?: number | null | undefined;
|
117
|
+
min?: number | undefined;
|
118
|
+
max?: number | undefined;
|
119
|
+
}>, z.ZodObject<{
|
120
|
+
key: z.ZodString;
|
121
|
+
error: z.ZodOptional<z.ZodDefault<z.ZodString>>;
|
122
|
+
required: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
123
|
+
array: z.ZodOptional<z.ZodDefault<z.ZodBoolean>>;
|
124
|
+
min: z.ZodOptional<z.ZodNumber>;
|
125
|
+
max: z.ZodOptional<z.ZodNumber>;
|
126
|
+
xdefault: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
127
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>>;
|
128
|
+
} & {
|
129
|
+
type: z.ZodDefault<z.ZodLiteral<"float">>;
|
98
130
|
}, "strip", z.ZodTypeAny, {
|
99
131
|
type: "float";
|
100
132
|
key: string;
|
@@ -561,6 +593,16 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
561
593
|
xdefault?: number | null | undefined;
|
562
594
|
min?: number | undefined;
|
563
595
|
max?: number | undefined;
|
596
|
+
} | {
|
597
|
+
type: "double";
|
598
|
+
key: string;
|
599
|
+
description?: string | Record<string, string> | null | undefined;
|
600
|
+
required?: boolean | undefined;
|
601
|
+
array?: boolean | undefined;
|
602
|
+
error?: string | undefined;
|
603
|
+
xdefault?: number | null | undefined;
|
604
|
+
min?: number | undefined;
|
605
|
+
max?: number | undefined;
|
564
606
|
} | {
|
565
607
|
type: "float";
|
566
608
|
key: string;
|
@@ -716,6 +758,16 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
716
758
|
xdefault?: number | null | undefined;
|
717
759
|
min?: number | undefined;
|
718
760
|
max?: number | undefined;
|
761
|
+
} | {
|
762
|
+
key: string;
|
763
|
+
type?: "double" | undefined;
|
764
|
+
description?: string | Record<string, string> | null | undefined;
|
765
|
+
required?: boolean | undefined;
|
766
|
+
array?: boolean | undefined;
|
767
|
+
error?: string | undefined;
|
768
|
+
xdefault?: number | null | undefined;
|
769
|
+
min?: number | undefined;
|
770
|
+
max?: number | undefined;
|
719
771
|
} | {
|
720
772
|
key: string;
|
721
773
|
type?: "float" | undefined;
|
@@ -1181,6 +1233,16 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
1181
1233
|
xdefault?: number | null | undefined;
|
1182
1234
|
min?: number | undefined;
|
1183
1235
|
max?: number | undefined;
|
1236
|
+
} | {
|
1237
|
+
type: "double";
|
1238
|
+
key: string;
|
1239
|
+
description?: string | Record<string, string> | null | undefined;
|
1240
|
+
required?: boolean | undefined;
|
1241
|
+
array?: boolean | undefined;
|
1242
|
+
error?: string | undefined;
|
1243
|
+
xdefault?: number | null | undefined;
|
1244
|
+
min?: number | undefined;
|
1245
|
+
max?: number | undefined;
|
1184
1246
|
} | {
|
1185
1247
|
type: "float";
|
1186
1248
|
key: string;
|
@@ -1380,6 +1442,16 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
1380
1442
|
xdefault?: number | null | undefined;
|
1381
1443
|
min?: number | undefined;
|
1382
1444
|
max?: number | undefined;
|
1445
|
+
} | {
|
1446
|
+
key: string;
|
1447
|
+
type?: "double" | undefined;
|
1448
|
+
description?: string | Record<string, string> | null | undefined;
|
1449
|
+
required?: boolean | undefined;
|
1450
|
+
array?: boolean | undefined;
|
1451
|
+
error?: string | undefined;
|
1452
|
+
xdefault?: number | null | undefined;
|
1453
|
+
min?: number | undefined;
|
1454
|
+
max?: number | undefined;
|
1383
1455
|
} | {
|
1384
1456
|
key: string;
|
1385
1457
|
type?: "float" | undefined;
|
@@ -1585,6 +1657,16 @@ export declare class DataLoader {
|
|
1585
1657
|
xdefault?: number | null | undefined;
|
1586
1658
|
min?: number | undefined;
|
1587
1659
|
max?: number | undefined;
|
1660
|
+
} | {
|
1661
|
+
type: "double";
|
1662
|
+
key: string;
|
1663
|
+
description?: string | Record<string, string> | null | undefined;
|
1664
|
+
required?: boolean | undefined;
|
1665
|
+
array?: boolean | undefined;
|
1666
|
+
error?: string | undefined;
|
1667
|
+
xdefault?: number | null | undefined;
|
1668
|
+
min?: number | undefined;
|
1669
|
+
max?: number | undefined;
|
1588
1670
|
} | {
|
1589
1671
|
type: "float";
|
1590
1672
|
key: string;
|
@@ -1,14 +1,14 @@
|
|
1
1
|
import { AttributeMappingsSchema, CollectionCreateSchema, importDefSchema, } from "appwrite-utils";
|
2
2
|
import path from "path";
|
3
3
|
import fs from "fs";
|
4
|
-
import { convertObjectByAttributeMappings } from "
|
4
|
+
import { convertObjectByAttributeMappings } from "../utils/dataConverters.js";
|
5
5
|
import { z } from "zod";
|
6
6
|
import { checkForCollection } from "../collections/methods.js";
|
7
7
|
import { ID, Users } from "node-appwrite";
|
8
|
-
import { logger } from "
|
9
|
-
import { findOrCreateOperation, updateOperation } from "
|
8
|
+
import { logger } from "../shared/logging.js";
|
9
|
+
import { findOrCreateOperation, updateOperation } from "../shared/migrationHelpers.js";
|
10
10
|
import { AuthUserCreateSchema } from "../schemas/authUser.js";
|
11
|
-
import { UsersController } from "
|
11
|
+
import { UsersController } from "../users/methods.js";
|
12
12
|
import { finalizeByAttributeMap } from "../utils/helperFunctions.js";
|
13
13
|
import { isEmpty } from "es-toolkit/compat";
|
14
14
|
// Define a schema for the structure of collection import data using Zod for validation
|