appwrite-utils-cli 0.9.92 → 0.9.95
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 +2 -0
- package/dist/interactiveCLI.js +68 -21
- package/package.json +2 -2
- package/src/interactiveCLI.ts +141 -46
package/README.md
CHANGED
@@ -125,6 +125,8 @@ This updated CLI ensures that developers have robust tools at their fingertips t
|
|
125
125
|
|
126
126
|
## Changelog
|
127
127
|
|
128
|
+
- 0.9.95: Updated to include new version of `appwrite-utils`
|
129
|
+
- 0.9.93: Updated `selectDatabases` and `selectCollections` from the interactive CLI to prefer local collections or databases when synchronizing the databases
|
128
130
|
- 0.9.92: Fixed `createOrUpdateAttributes` so it deletes attributes that don't exist in local config when you are running `syncDb`. Also updated the database and collection selection, so it won't try and fetch the collections and databases that don't exist (ones you picked from local config) and error
|
129
131
|
- 0.9.91: Fixed another webpack error, screw you react (but you're supported now so I guess not-screw-you)
|
130
132
|
- 0.9.90: Fixed Webpack errors (why tf does webpack add an extra `default`...???)
|
package/dist/interactiveCLI.js
CHANGED
@@ -6,7 +6,7 @@ import { fetchAllCollections } from "./collections/methods.js";
|
|
6
6
|
import { listBuckets, createBucket } from "./storage/methods.js";
|
7
7
|
import { Databases, Storage, Client, Compression, Query, } from "node-appwrite";
|
8
8
|
import { getClient } from "./utils/getClientFromConfig.js";
|
9
|
-
import { parseAttribute, PermissionToAppwritePermission } from "appwrite-utils";
|
9
|
+
import { parseAttribute, PermissionToAppwritePermission, } from "appwrite-utils";
|
10
10
|
import { ulid } from "ulidx";
|
11
11
|
import chalk from "chalk";
|
12
12
|
import { DateTime } from "luxon";
|
@@ -106,15 +106,34 @@ export class InteractiveCLI {
|
|
106
106
|
async selectDatabases(databases, message, multiSelect = true) {
|
107
107
|
await this.initControllerIfNeeded();
|
108
108
|
const configDatabases = this.getLocalDatabases();
|
109
|
-
const allDatabases = [...databases, ...configDatabases]
|
110
|
-
|
109
|
+
const allDatabases = [...databases, ...configDatabases]
|
110
|
+
.reduce((acc, db) => {
|
111
|
+
// Local config takes precedence - if a database with same name exists, use local version
|
112
|
+
const existingIndex = acc.findIndex((d) => d.name === db.name);
|
113
|
+
if (existingIndex >= 0) {
|
114
|
+
if (configDatabases.some((cdb) => cdb.name === db.name)) {
|
115
|
+
acc[existingIndex] = db; // Replace with local version
|
116
|
+
}
|
117
|
+
}
|
118
|
+
else {
|
111
119
|
acc.push(db);
|
112
120
|
}
|
113
121
|
return acc;
|
114
|
-
}, [])
|
122
|
+
}, [])
|
123
|
+
.filter((db) => db.name.toLowerCase() !== "migrations");
|
124
|
+
const hasLocalAndRemote = allDatabases.some((db) => configDatabases.some((c) => c.name === db.name)) &&
|
125
|
+
allDatabases.some((db) => !configDatabases.some((c) => c.name === db.name));
|
115
126
|
const choices = allDatabases
|
116
127
|
.sort((a, b) => a.name.localeCompare(b.name))
|
117
|
-
.map((db) => ({
|
128
|
+
.map((db) => ({
|
129
|
+
name: db.name +
|
130
|
+
(hasLocalAndRemote
|
131
|
+
? configDatabases.some((c) => c.name === db.name)
|
132
|
+
? " (Local)"
|
133
|
+
: " (Remote)"
|
134
|
+
: ""),
|
135
|
+
value: db,
|
136
|
+
}))
|
118
137
|
.filter((db) => db.name.toLowerCase() !== "migrations");
|
119
138
|
const { selectedDatabases } = await inquirer.prompt([
|
120
139
|
{
|
@@ -128,22 +147,41 @@ export class InteractiveCLI {
|
|
128
147
|
]);
|
129
148
|
return selectedDatabases;
|
130
149
|
}
|
131
|
-
async selectCollections(database, databasesClient, message, multiSelect = true) {
|
150
|
+
async selectCollections(database, databasesClient, message, multiSelect = true, preferLocal = false) {
|
132
151
|
await this.initControllerIfNeeded();
|
133
|
-
const
|
134
|
-
let
|
152
|
+
const configCollections = this.getLocalCollections();
|
153
|
+
let remoteCollections = [];
|
154
|
+
const dbExists = await databasesClient.list([
|
155
|
+
Query.equal("name", database.name),
|
156
|
+
]);
|
135
157
|
if (dbExists.total === 0) {
|
136
158
|
console.log(chalk.red(`Database "${database.name}" does not exist, using only local collection options`));
|
137
159
|
}
|
138
160
|
else {
|
139
|
-
|
161
|
+
remoteCollections = await fetchAllCollections(database.$id, databasesClient);
|
140
162
|
}
|
141
|
-
const
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
163
|
+
const allCollections = preferLocal
|
164
|
+
? remoteCollections.reduce((acc, remoteCollection) => {
|
165
|
+
if (!acc.some((c) => c.name === remoteCollection.name)) {
|
166
|
+
acc.push(remoteCollection);
|
167
|
+
}
|
168
|
+
return acc;
|
169
|
+
}, [...configCollections])
|
170
|
+
: [
|
171
|
+
...remoteCollections,
|
172
|
+
...configCollections.filter((c) => !remoteCollections.some((rc) => rc.name === c.name)),
|
173
|
+
];
|
174
|
+
const hasLocalAndRemote = allCollections.some((coll) => configCollections.some((c) => c.name === coll.name)) &&
|
175
|
+
allCollections.some((coll) => !configCollections.some((c) => c.name === coll.name));
|
176
|
+
const choices = allCollections
|
177
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
178
|
+
.map((collection) => ({
|
179
|
+
name: collection.name +
|
180
|
+
(hasLocalAndRemote
|
181
|
+
? configCollections.some((c) => c.name === collection.name)
|
182
|
+
? " (Local)"
|
183
|
+
: " (Remote)"
|
184
|
+
: ""),
|
147
185
|
value: collection,
|
148
186
|
}));
|
149
187
|
const { selectedCollections } = await inquirer.prompt([
|
@@ -195,7 +233,14 @@ export class InteractiveCLI {
|
|
195
233
|
const allBuckets = await listBuckets(storage);
|
196
234
|
// If there are no buckets, ask to create one for each database
|
197
235
|
if (allBuckets.total === 0) {
|
198
|
-
|
236
|
+
const databasesToUse = databases ?? config.databases;
|
237
|
+
for (const database of databasesToUse) {
|
238
|
+
// If database has bucket config in local config, use that
|
239
|
+
const localDatabase = this.controller.config?.databases.find((db) => db.name === database.name);
|
240
|
+
if (localDatabase?.bucket) {
|
241
|
+
database.bucket = localDatabase.bucket;
|
242
|
+
continue;
|
243
|
+
}
|
199
244
|
const { wantCreateBucket } = await inquirer.prompt([
|
200
245
|
{
|
201
246
|
type: "confirm",
|
@@ -361,7 +406,8 @@ export class InteractiveCLI {
|
|
361
406
|
async syncDb() {
|
362
407
|
console.log(chalk.yellow("Syncing database..."));
|
363
408
|
const databases = await this.selectDatabases(await fetchAllDatabases(this.controller.database), chalk.blue("Select databases to synchronize:"), true);
|
364
|
-
const collections = await this.selectCollections(databases[0], this.controller.database, chalk.blue("Select collections to synchronize:"), true
|
409
|
+
const collections = await this.selectCollections(databases[0], this.controller.database, chalk.blue("Select collections to synchronize:"), true, true // prefer local
|
410
|
+
);
|
365
411
|
await this.controller.syncDb(databases, collections);
|
366
412
|
console.log(chalk.green("Database sync completed."));
|
367
413
|
}
|
@@ -493,7 +539,7 @@ export class InteractiveCLI {
|
|
493
539
|
]);
|
494
540
|
const options = {
|
495
541
|
databases,
|
496
|
-
collections: collections.map(c => c.name),
|
542
|
+
collections: collections.map((c) => c.name),
|
497
543
|
doBackup,
|
498
544
|
importData: true,
|
499
545
|
shouldWriteFile,
|
@@ -562,7 +608,8 @@ export class InteractiveCLI {
|
|
562
608
|
if (!targetDb) {
|
563
609
|
throw new Error("No target database selected");
|
564
610
|
}
|
565
|
-
const selectedCollections = await this.selectCollections(fromDb, sourceClient, "Select collections to transfer:"
|
611
|
+
const selectedCollections = await this.selectCollections(fromDb, sourceClient, "Select collections to transfer:", true, false // don't prefer local for transfers
|
612
|
+
);
|
566
613
|
const { transferStorage } = await inquirer.prompt([
|
567
614
|
{
|
568
615
|
type: "confirm",
|
@@ -609,7 +656,7 @@ export class InteractiveCLI {
|
|
609
656
|
getLocalCollections() {
|
610
657
|
const configCollections = this.controller.config?.collections || [];
|
611
658
|
// @ts-expect-error - appwrite invalid types
|
612
|
-
return configCollections.map(c => ({
|
659
|
+
return configCollections.map((c) => ({
|
613
660
|
$id: c.$id || ulid(),
|
614
661
|
$createdAt: DateTime.now().toISO(),
|
615
662
|
$updatedAt: DateTime.now().toISO(),
|
@@ -624,7 +671,7 @@ export class InteractiveCLI {
|
|
624
671
|
}
|
625
672
|
getLocalDatabases() {
|
626
673
|
const configDatabases = this.controller.config?.databases || [];
|
627
|
-
return configDatabases.map(db => ({
|
674
|
+
return configDatabases.map((db) => ({
|
628
675
|
$id: db.$id || ulid(),
|
629
676
|
$createdAt: DateTime.now().toISO(),
|
630
677
|
$updatedAt: DateTime.now().toISO(),
|
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.9.
|
4
|
+
"version": "0.9.95",
|
5
5
|
"main": "src/main.ts",
|
6
6
|
"type": "module",
|
7
7
|
"repository": {
|
@@ -31,7 +31,7 @@
|
|
31
31
|
},
|
32
32
|
"dependencies": {
|
33
33
|
"@types/inquirer": "^9.0.7",
|
34
|
-
"appwrite-utils": "^0.3.
|
34
|
+
"appwrite-utils": "^0.3.95",
|
35
35
|
"chalk": "^5.3.0",
|
36
36
|
"commander": "^12.1.0",
|
37
37
|
"inquirer": "^9.3.6",
|
package/src/interactiveCLI.ts
CHANGED
@@ -14,7 +14,12 @@ import {
|
|
14
14
|
} from "node-appwrite";
|
15
15
|
import { getClient } from "./utils/getClientFromConfig.js";
|
16
16
|
import type { TransferOptions } from "./migrations/transfer.js";
|
17
|
-
import {
|
17
|
+
import {
|
18
|
+
parseAttribute,
|
19
|
+
PermissionToAppwritePermission,
|
20
|
+
type AppwriteConfig,
|
21
|
+
type ConfigDatabases,
|
22
|
+
} from "appwrite-utils";
|
18
23
|
import { ulid } from "ulidx";
|
19
24
|
import chalk from "chalk";
|
20
25
|
import { DateTime } from "luxon";
|
@@ -38,12 +43,16 @@ enum CHOICES {
|
|
38
43
|
export class InteractiveCLI {
|
39
44
|
private controller: UtilsController | undefined;
|
40
45
|
|
41
|
-
constructor(private currentDir: string) {
|
46
|
+
constructor(private currentDir: string) {}
|
42
47
|
|
43
48
|
async run(): Promise<void> {
|
44
|
-
console.log(chalk.green("Welcome to Appwrite Utils CLI Tool by Zach Handley"));
|
45
49
|
console.log(
|
46
|
-
chalk.
|
50
|
+
chalk.green("Welcome to Appwrite Utils CLI Tool by Zach Handley")
|
51
|
+
);
|
52
|
+
console.log(
|
53
|
+
chalk.blue(
|
54
|
+
"For more information, visit https://github.com/zachhandley/AppwriteUtils"
|
55
|
+
)
|
47
56
|
);
|
48
57
|
|
49
58
|
while (true) {
|
@@ -124,16 +133,41 @@ export class InteractiveCLI {
|
|
124
133
|
): Promise<Models.Database[]> {
|
125
134
|
await this.initControllerIfNeeded();
|
126
135
|
const configDatabases = this.getLocalDatabases();
|
127
|
-
const allDatabases = [...databases, ...configDatabases]
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
136
|
+
const allDatabases = [...databases, ...configDatabases]
|
137
|
+
.reduce((acc, db) => {
|
138
|
+
// Local config takes precedence - if a database with same name exists, use local version
|
139
|
+
const existingIndex = acc.findIndex((d) => d.name === db.name);
|
140
|
+
if (existingIndex >= 0) {
|
141
|
+
if (configDatabases.some((cdb) => cdb.name === db.name)) {
|
142
|
+
acc[existingIndex] = db; // Replace with local version
|
143
|
+
}
|
144
|
+
} else {
|
145
|
+
acc.push(db);
|
146
|
+
}
|
147
|
+
return acc;
|
148
|
+
}, [] as Models.Database[])
|
149
|
+
.filter((db) => db.name.toLowerCase() !== "migrations");
|
150
|
+
|
151
|
+
const hasLocalAndRemote =
|
152
|
+
allDatabases.some((db) =>
|
153
|
+
configDatabases.some((c) => c.name === db.name)
|
154
|
+
) &&
|
155
|
+
allDatabases.some(
|
156
|
+
(db) => !configDatabases.some((c) => c.name === db.name)
|
157
|
+
);
|
133
158
|
|
134
159
|
const choices = allDatabases
|
135
160
|
.sort((a, b) => a.name.localeCompare(b.name))
|
136
|
-
.map((db) => ({
|
161
|
+
.map((db) => ({
|
162
|
+
name:
|
163
|
+
db.name +
|
164
|
+
(hasLocalAndRemote
|
165
|
+
? configDatabases.some((c) => c.name === db.name)
|
166
|
+
? " (Local)"
|
167
|
+
: " (Remote)"
|
168
|
+
: ""),
|
169
|
+
value: db,
|
170
|
+
}))
|
137
171
|
.filter((db) => db.name.toLowerCase() !== "migrations");
|
138
172
|
|
139
173
|
const { selectedDatabases } = await inquirer.prompt([
|
@@ -154,27 +188,67 @@ export class InteractiveCLI {
|
|
154
188
|
database: Models.Database,
|
155
189
|
databasesClient: Databases,
|
156
190
|
message: string,
|
157
|
-
multiSelect = true
|
191
|
+
multiSelect = true,
|
192
|
+
preferLocal = false
|
158
193
|
): Promise<Models.Collection[]> {
|
159
194
|
await this.initControllerIfNeeded();
|
160
|
-
|
161
|
-
|
195
|
+
|
196
|
+
const configCollections = this.getLocalCollections();
|
197
|
+
let remoteCollections: Models.Collection[] = [];
|
198
|
+
|
199
|
+
const dbExists = await databasesClient.list([
|
200
|
+
Query.equal("name", database.name),
|
201
|
+
]);
|
162
202
|
if (dbExists.total === 0) {
|
163
|
-
console.log(
|
203
|
+
console.log(
|
204
|
+
chalk.red(
|
205
|
+
`Database "${database.name}" does not exist, using only local collection options`
|
206
|
+
)
|
207
|
+
);
|
164
208
|
} else {
|
165
|
-
|
209
|
+
remoteCollections = await fetchAllCollections(
|
166
210
|
database.$id,
|
167
211
|
databasesClient
|
168
212
|
);
|
169
213
|
}
|
170
|
-
|
171
|
-
const
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
214
|
+
|
215
|
+
const allCollections = preferLocal
|
216
|
+
? remoteCollections.reduce(
|
217
|
+
(acc, remoteCollection) => {
|
218
|
+
if (!acc.some((c) => c.name === remoteCollection.name)) {
|
219
|
+
acc.push(remoteCollection);
|
220
|
+
}
|
221
|
+
return acc;
|
222
|
+
},
|
223
|
+
[...configCollections]
|
224
|
+
)
|
225
|
+
: [
|
226
|
+
...remoteCollections,
|
227
|
+
...configCollections.filter(
|
228
|
+
(c) => !remoteCollections.some((rc) => rc.name === c.name)
|
229
|
+
),
|
230
|
+
];
|
231
|
+
|
232
|
+
const hasLocalAndRemote =
|
233
|
+
allCollections.some((coll) =>
|
234
|
+
configCollections.some((c) => c.name === coll.name)
|
235
|
+
) &&
|
236
|
+
allCollections.some(
|
237
|
+
(coll) => !configCollections.some((c) => c.name === coll.name)
|
238
|
+
);
|
239
|
+
|
240
|
+
const choices = allCollections
|
241
|
+
.sort((a, b) => a.name.localeCompare(b.name))
|
242
|
+
.map((collection) => ({
|
243
|
+
name:
|
244
|
+
collection.name +
|
245
|
+
(hasLocalAndRemote
|
246
|
+
? configCollections.some((c) => c.name === collection.name)
|
247
|
+
? " (Local)"
|
248
|
+
: " (Remote)"
|
249
|
+
: ""),
|
250
|
+
value: collection,
|
251
|
+
}));
|
178
252
|
|
179
253
|
const { selectedCollections } = await inquirer.prompt([
|
180
254
|
{
|
@@ -224,7 +298,9 @@ export class InteractiveCLI {
|
|
224
298
|
input.trim() !== "" || "Collection name cannot be empty.",
|
225
299
|
},
|
226
300
|
]);
|
227
|
-
console.log(
|
301
|
+
console.log(
|
302
|
+
chalk.green(`Creating collection config file for '${collectionName}'...`)
|
303
|
+
);
|
228
304
|
createEmptyCollection(collectionName);
|
229
305
|
}
|
230
306
|
|
@@ -243,12 +319,23 @@ export class InteractiveCLI {
|
|
243
319
|
|
244
320
|
// If there are no buckets, ask to create one for each database
|
245
321
|
if (allBuckets.total === 0) {
|
246
|
-
|
322
|
+
const databasesToUse = databases ?? config.databases;
|
323
|
+
for (const database of databasesToUse) {
|
324
|
+
// If database has bucket config in local config, use that
|
325
|
+
const localDatabase = this.controller!.config?.databases.find(
|
326
|
+
(db) => db.name === database.name
|
327
|
+
);
|
328
|
+
if (localDatabase?.bucket) {
|
329
|
+
database.bucket = localDatabase.bucket;
|
330
|
+
continue;
|
331
|
+
}
|
247
332
|
const { wantCreateBucket } = await inquirer.prompt([
|
248
333
|
{
|
249
334
|
type: "confirm",
|
250
335
|
name: "wantCreateBucket",
|
251
|
-
message: chalk.blue(
|
336
|
+
message: chalk.blue(
|
337
|
+
`There are no buckets. Do you want to create a bucket for the database "${database.name}"?`
|
338
|
+
),
|
252
339
|
default: true,
|
253
340
|
},
|
254
341
|
]);
|
@@ -455,13 +542,14 @@ export class InteractiveCLI {
|
|
455
542
|
const databases = await this.selectDatabases(
|
456
543
|
await fetchAllDatabases(this.controller!.database!),
|
457
544
|
chalk.blue("Select databases to synchronize:"),
|
458
|
-
true
|
545
|
+
true
|
459
546
|
);
|
460
547
|
const collections = await this.selectCollections(
|
461
548
|
databases[0],
|
462
549
|
this.controller!.database!,
|
463
550
|
chalk.blue("Select collections to synchronize:"),
|
464
551
|
true,
|
552
|
+
true // prefer local
|
465
553
|
);
|
466
554
|
await this.controller!.syncDb(databases, collections);
|
467
555
|
console.log(chalk.green("Database sync completed."));
|
@@ -607,13 +695,19 @@ export class InteractiveCLI {
|
|
607
695
|
]);
|
608
696
|
|
609
697
|
if (confirm) {
|
610
|
-
console.log(
|
698
|
+
console.log(
|
699
|
+
chalk.yellow(`Wiping selected collections from ${database.name}...`)
|
700
|
+
);
|
611
701
|
for (const collection of collections) {
|
612
702
|
await this.controller!.wipeCollection(database, collection);
|
613
|
-
console.log(
|
703
|
+
console.log(
|
704
|
+
chalk.green(`Collection ${collection.name} wiped successfully.`)
|
705
|
+
);
|
614
706
|
}
|
615
707
|
} else {
|
616
|
-
console.log(
|
708
|
+
console.log(
|
709
|
+
chalk.blue(`Wipe operation cancelled for ${database.name}.`)
|
710
|
+
);
|
617
711
|
}
|
618
712
|
}
|
619
713
|
console.log(chalk.green("Wipe collections operation completed."));
|
@@ -661,7 +755,7 @@ export class InteractiveCLI {
|
|
661
755
|
|
662
756
|
const options = {
|
663
757
|
databases,
|
664
|
-
collections: collections.map(c => c.name),
|
758
|
+
collections: collections.map((c) => c.name),
|
665
759
|
doBackup,
|
666
760
|
importData: true,
|
667
761
|
shouldWriteFile,
|
@@ -697,10 +791,10 @@ export class InteractiveCLI {
|
|
697
791
|
let targetDatabases: Models.Database[];
|
698
792
|
let remoteOptions:
|
699
793
|
| {
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
794
|
+
transferEndpoint: string;
|
795
|
+
transferProject: string;
|
796
|
+
transferKey: string;
|
797
|
+
}
|
704
798
|
| undefined;
|
705
799
|
|
706
800
|
if (isRemote) {
|
@@ -760,7 +854,9 @@ export class InteractiveCLI {
|
|
760
854
|
const selectedCollections = await this.selectCollections(
|
761
855
|
fromDb,
|
762
856
|
sourceClient,
|
763
|
-
"Select collections to transfer:"
|
857
|
+
"Select collections to transfer:",
|
858
|
+
true,
|
859
|
+
false // don't prefer local for transfers
|
764
860
|
);
|
765
861
|
|
766
862
|
const { transferStorage } = await inquirer.prompt([
|
@@ -778,12 +874,12 @@ export class InteractiveCLI {
|
|
778
874
|
const sourceStorage = new Storage(this.controller!.appwriteServer!);
|
779
875
|
const targetStorage = isRemote
|
780
876
|
? new Storage(
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
877
|
+
getClient(
|
878
|
+
remoteOptions!.transferEndpoint,
|
879
|
+
remoteOptions!.transferProject,
|
880
|
+
remoteOptions!.transferKey
|
881
|
+
)
|
785
882
|
)
|
786
|
-
)
|
787
883
|
: sourceStorage;
|
788
884
|
|
789
885
|
const sourceBuckets = await listBuckets(sourceStorage);
|
@@ -829,11 +925,10 @@ export class InteractiveCLI {
|
|
829
925
|
console.log(chalk.green("Data transfer completed."));
|
830
926
|
}
|
831
927
|
|
832
|
-
|
833
928
|
private getLocalCollections(): Models.Collection[] {
|
834
929
|
const configCollections = this.controller!.config?.collections || [];
|
835
930
|
// @ts-expect-error - appwrite invalid types
|
836
|
-
return configCollections.map(c => ({
|
931
|
+
return configCollections.map((c) => ({
|
837
932
|
$id: c.$id || ulid(),
|
838
933
|
$createdAt: DateTime.now().toISO(),
|
839
934
|
$updatedAt: DateTime.now().toISO(),
|
@@ -849,7 +944,7 @@ export class InteractiveCLI {
|
|
849
944
|
|
850
945
|
private getLocalDatabases(): Models.Database[] {
|
851
946
|
const configDatabases = this.controller!.config?.databases || [];
|
852
|
-
return configDatabases.map(db => ({
|
947
|
+
return configDatabases.map((db) => ({
|
853
948
|
$id: db.$id || ulid(),
|
854
949
|
$createdAt: DateTime.now().toISO(),
|
855
950
|
$updatedAt: DateTime.now().toISO(),
|
@@ -867,4 +962,4 @@ export class InteractiveCLI {
|
|
867
962
|
console.error(chalk.red("Error reloading configuration files:"), error);
|
868
963
|
}
|
869
964
|
}
|
870
|
-
}
|
965
|
+
}
|