appwrite-utils-cli 1.6.0 ā 1.6.2
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.
@@ -14,8 +14,9 @@ export const databaseCommands = {
|
|
14
14
|
MessageFormatter.warning("No databases selected. Skipping database sync.", { prefix: "Database" });
|
15
15
|
return;
|
16
16
|
}
|
17
|
-
const collections = await cli.selectCollectionsAndTables(databases[0], cli.controller.database, chalk.blue("Select local collections/tables to push:"), true,
|
18
|
-
true //
|
17
|
+
const collections = await cli.selectCollectionsAndTables(databases[0], cli.controller.database, chalk.blue("Select local collections/tables to push:"), true, // multiSelect
|
18
|
+
true // prefer local
|
19
|
+
// shouldFilterByDatabase removed - user will be prompted interactively
|
19
20
|
);
|
20
21
|
const { syncFunctions } = await inquirer.prompt([
|
21
22
|
{
|
package/dist/interactiveCLI.js
CHANGED
@@ -253,19 +253,13 @@ export class InteractiveCLI {
|
|
253
253
|
...configCollections.filter((c) => !remoteCollections.some((rc) => rc.name === c.name)),
|
254
254
|
];
|
255
255
|
if (shouldFilterByDatabase) {
|
256
|
-
//
|
256
|
+
// Show collections that EITHER exist in the remote database OR have matching local databaseId metadata
|
257
257
|
allCollections = allCollections.filter((c) => {
|
258
|
-
//
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
// - Collections without databaseId are kept (backward compatibility)
|
264
|
-
// - Tables with databaseId must match the selected database
|
265
|
-
// - Tables without databaseId are kept (fallback for misconfigured tables)
|
266
|
-
if (!c.databaseId)
|
267
|
-
return true;
|
268
|
-
return c.databaseId === database.$id;
|
258
|
+
// Include if it exists remotely in this database
|
259
|
+
const existsInRemoteDb = remoteCollections.some((rc) => rc.name === c.name);
|
260
|
+
// Include if local metadata claims it belongs to this database
|
261
|
+
const hasMatchingLocalMetadata = c.databaseId === database.$id;
|
262
|
+
return existsInRemoteDb || hasMatchingLocalMetadata;
|
269
263
|
});
|
270
264
|
}
|
271
265
|
// Filter out system tables (those starting with underscore)
|
@@ -341,26 +335,54 @@ export class InteractiveCLI {
|
|
341
335
|
const configCollections = this.getLocalCollections();
|
342
336
|
const collectionsCount = configCollections.filter(c => !c._isFromTablesDir).length;
|
343
337
|
const tablesCount = configCollections.filter(c => c._isFromTablesDir).length;
|
338
|
+
const totalCount = collectionsCount + tablesCount;
|
344
339
|
// Provide context about what's available
|
345
340
|
if (collectionsCount > 0 && tablesCount > 0) {
|
346
|
-
MessageFormatter.info(`\nš
|
341
|
+
MessageFormatter.info(`\nš ${totalCount} total items available:`, { prefix: "Collections" });
|
347
342
|
MessageFormatter.info(` Collections: ${collectionsCount} (from collections/ folder)`, { prefix: "Collections" });
|
348
343
|
MessageFormatter.info(` Tables: ${tablesCount} (from tables/ folder)`, { prefix: "Collections" });
|
349
|
-
|
344
|
+
}
|
345
|
+
else if (collectionsCount > 0) {
|
346
|
+
MessageFormatter.info(`š ${collectionsCount} collections available from collections/ folder`, { prefix: "Collections" });
|
347
|
+
}
|
348
|
+
else if (tablesCount > 0) {
|
349
|
+
MessageFormatter.info(`š ${tablesCount} tables available from tables/ folder`, { prefix: "Collections" });
|
350
|
+
}
|
351
|
+
// Ask user if they want to filter by database or show all
|
352
|
+
const { filterChoice } = await inquirer.prompt([
|
353
|
+
{
|
354
|
+
type: "list",
|
355
|
+
name: "filterChoice",
|
356
|
+
message: chalk.blue("How would you like to view collections/tables?"),
|
357
|
+
choices: [
|
358
|
+
{
|
359
|
+
name: `Show all available collections/tables (${totalCount} total) - You can push any collection to any database`,
|
360
|
+
value: "all"
|
361
|
+
},
|
362
|
+
{
|
363
|
+
name: `Filter by database "${database.name}" - Show only related collections/tables`,
|
364
|
+
value: "filter"
|
365
|
+
}
|
366
|
+
],
|
367
|
+
default: "all"
|
368
|
+
}
|
369
|
+
]);
|
370
|
+
// User's choice overrides the parameter
|
371
|
+
const userWantsFiltering = filterChoice === "filter";
|
372
|
+
// Show appropriate informational message
|
373
|
+
if (userWantsFiltering) {
|
374
|
+
MessageFormatter.info(`ā¹ļø Showing collections/tables related to database "${database.name}"`, { prefix: "Collections" });
|
375
|
+
if (tablesCount > 0) {
|
350
376
|
const filteredTables = configCollections.filter(c => c._isFromTablesDir && (!c.databaseId || c.databaseId === database.$id)).length;
|
351
377
|
if (filteredTables !== tablesCount) {
|
352
|
-
MessageFormatter.
|
378
|
+
MessageFormatter.info(` ${filteredTables}/${tablesCount} tables match this database`, { prefix: "Collections" });
|
353
379
|
}
|
354
380
|
}
|
355
|
-
MessageFormatter.info('', { prefix: "Collections" });
|
356
381
|
}
|
357
|
-
else
|
358
|
-
MessageFormatter.info(
|
359
|
-
}
|
360
|
-
else if (tablesCount > 0) {
|
361
|
-
MessageFormatter.info(`š ${tablesCount} tables available from tables/ folder\n`, { prefix: "Collections" });
|
382
|
+
else {
|
383
|
+
MessageFormatter.info(`ā¹ļø Showing all available collections/tables - you can push any collection to any database\n`, { prefix: "Collections" });
|
362
384
|
}
|
363
|
-
return this.selectCollections(database, databasesClient, message, multiSelect, preferLocal,
|
385
|
+
return this.selectCollections(database, databasesClient, message, multiSelect, preferLocal, userWantsFiltering);
|
364
386
|
}
|
365
387
|
getTemplateDefaults(template) {
|
366
388
|
const defaults = {
|
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": "1.6.
|
4
|
+
"version": "1.6.2",
|
5
5
|
"main": "src/main.ts",
|
6
6
|
"type": "module",
|
7
7
|
"repository": {
|
@@ -27,9 +27,9 @@ export const databaseCommands = {
|
|
27
27
|
databases[0],
|
28
28
|
(cli as any).controller!.database!,
|
29
29
|
chalk.blue("Select local collections/tables to push:"),
|
30
|
-
true,
|
31
|
-
true
|
32
|
-
|
30
|
+
true, // multiSelect
|
31
|
+
true // prefer local
|
32
|
+
// shouldFilterByDatabase removed - user will be prompted interactively
|
33
33
|
);
|
34
34
|
|
35
35
|
const { syncFunctions } = await inquirer.prompt([
|
package/src/interactiveCLI.ts
CHANGED
@@ -324,19 +324,15 @@ export class InteractiveCLI {
|
|
324
324
|
];
|
325
325
|
|
326
326
|
if (shouldFilterByDatabase) {
|
327
|
-
//
|
327
|
+
// Show collections that EITHER exist in the remote database OR have matching local databaseId metadata
|
328
328
|
allCollections = allCollections.filter((c: any) => {
|
329
|
-
//
|
330
|
-
|
331
|
-
|
332
|
-
|
329
|
+
// Include if it exists remotely in this database
|
330
|
+
const existsInRemoteDb = remoteCollections.some((rc) => rc.name === c.name);
|
331
|
+
|
332
|
+
// Include if local metadata claims it belongs to this database
|
333
|
+
const hasMatchingLocalMetadata = c.databaseId === database.$id;
|
333
334
|
|
334
|
-
|
335
|
-
// - Collections without databaseId are kept (backward compatibility)
|
336
|
-
// - Tables with databaseId must match the selected database
|
337
|
-
// - Tables without databaseId are kept (fallback for misconfigured tables)
|
338
|
-
if (!c.databaseId) return true;
|
339
|
-
return c.databaseId === database.$id;
|
335
|
+
return existsInRemoteDb || hasMatchingLocalMetadata;
|
340
336
|
});
|
341
337
|
}
|
342
338
|
|
@@ -436,29 +432,58 @@ export class InteractiveCLI {
|
|
436
432
|
const configCollections = this.getLocalCollections();
|
437
433
|
const collectionsCount = configCollections.filter(c => !c._isFromTablesDir).length;
|
438
434
|
const tablesCount = configCollections.filter(c => c._isFromTablesDir).length;
|
435
|
+
const totalCount = collectionsCount + tablesCount;
|
439
436
|
|
440
437
|
// Provide context about what's available
|
441
438
|
if (collectionsCount > 0 && tablesCount > 0) {
|
442
|
-
MessageFormatter.info(`\nš
|
439
|
+
MessageFormatter.info(`\nš ${totalCount} total items available:`, { prefix: "Collections" });
|
443
440
|
MessageFormatter.info(` Collections: ${collectionsCount} (from collections/ folder)`, { prefix: "Collections" });
|
444
441
|
MessageFormatter.info(` Tables: ${tablesCount} (from tables/ folder)`, { prefix: "Collections" });
|
442
|
+
} else if (collectionsCount > 0) {
|
443
|
+
MessageFormatter.info(`š ${collectionsCount} collections available from collections/ folder`, { prefix: "Collections" });
|
444
|
+
} else if (tablesCount > 0) {
|
445
|
+
MessageFormatter.info(`š ${tablesCount} tables available from tables/ folder`, { prefix: "Collections" });
|
446
|
+
}
|
447
|
+
|
448
|
+
// Ask user if they want to filter by database or show all
|
449
|
+
const { filterChoice } = await inquirer.prompt([
|
450
|
+
{
|
451
|
+
type: "list",
|
452
|
+
name: "filterChoice",
|
453
|
+
message: chalk.blue("How would you like to view collections/tables?"),
|
454
|
+
choices: [
|
455
|
+
{
|
456
|
+
name: `Show all available collections/tables (${totalCount} total) - You can push any collection to any database`,
|
457
|
+
value: "all"
|
458
|
+
},
|
459
|
+
{
|
460
|
+
name: `Filter by database "${database.name}" - Show only related collections/tables`,
|
461
|
+
value: "filter"
|
462
|
+
}
|
463
|
+
],
|
464
|
+
default: "all"
|
465
|
+
}
|
466
|
+
]);
|
445
467
|
|
446
|
-
|
468
|
+
// User's choice overrides the parameter
|
469
|
+
const userWantsFiltering = filterChoice === "filter";
|
470
|
+
|
471
|
+
// Show appropriate informational message
|
472
|
+
if (userWantsFiltering) {
|
473
|
+
MessageFormatter.info(`ā¹ļø Showing collections/tables related to database "${database.name}"`, { prefix: "Collections" });
|
474
|
+
if (tablesCount > 0) {
|
447
475
|
const filteredTables = configCollections.filter(c =>
|
448
476
|
c._isFromTablesDir && (!c.databaseId || c.databaseId === database.$id)
|
449
477
|
).length;
|
450
478
|
if (filteredTables !== tablesCount) {
|
451
|
-
MessageFormatter.
|
479
|
+
MessageFormatter.info(` ${filteredTables}/${tablesCount} tables match this database`, { prefix: "Collections" });
|
452
480
|
}
|
453
481
|
}
|
454
|
-
|
455
|
-
|
456
|
-
MessageFormatter.info(`š ${collectionsCount} collections available from collections/ folder\n`, { prefix: "Collections" });
|
457
|
-
} else if (tablesCount > 0) {
|
458
|
-
MessageFormatter.info(`š ${tablesCount} tables available from tables/ folder\n`, { prefix: "Collections" });
|
482
|
+
} else {
|
483
|
+
MessageFormatter.info(`ā¹ļø Showing all available collections/tables - you can push any collection to any database\n`, { prefix: "Collections" });
|
459
484
|
}
|
460
485
|
|
461
|
-
return this.selectCollections(database, databasesClient, message, multiSelect, preferLocal,
|
486
|
+
return this.selectCollections(database, databasesClient, message, multiSelect, preferLocal, userWantsFiltering);
|
462
487
|
}
|
463
488
|
|
464
489
|
private getTemplateDefaults(template: string) {
|