appwrite-utils-cli 0.0.281 → 0.0.284
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 +1 -1
- package/dist/main.js +3 -1
- package/dist/migrations/appwriteToX.js +24 -14
- package/dist/migrations/backup.d.ts +16 -16
- package/dist/migrations/dataLoader.d.ts +40 -26
- package/dist/migrations/schemaStrings.js +12 -4
- package/dist/utils/loadConfigs.js +5 -1
- package/dist/utilsController.d.ts +1 -1
- package/dist/utilsController.js +5 -2
- package/package.json +2 -2
- package/src/main.ts +3 -1
- package/src/migrations/appwriteToX.ts +24 -17
- package/src/migrations/schemaStrings.ts +15 -4
- package/src/utils/loadConfigs.ts +5 -1
- package/src/utilsController.ts +5 -2
package/README.md
CHANGED
@@ -24,7 +24,7 @@ npm install -g appwrite-utils-cli
|
|
24
24
|
However, due to the nature of the speed at which I am developing this project, I would recommend the following command:
|
25
25
|
|
26
26
|
```bash
|
27
|
-
npx --package=appwrite-utils-cli@latest appwrite-migrate --
|
27
|
+
npx --package=appwrite-utils-cli@latest appwrite-migrate --arg1 --arg2 --arg3
|
28
28
|
```
|
29
29
|
|
30
30
|
**DO NOT INSTALL THIS LOCALLY INTO YOUR PROJECT, IT IS MEANT TO BE USED AS A COMMAND LINE TOOL ONLY**
|
package/dist/main.js
CHANGED
@@ -34,7 +34,8 @@ program.on("--help", () => {
|
|
34
34
|
});
|
35
35
|
// Parse and handle options
|
36
36
|
program.action(async (options) => {
|
37
|
-
const
|
37
|
+
const currentUserDir = process.cwd();
|
38
|
+
const controller = new UtilsController(currentUserDir);
|
38
39
|
try {
|
39
40
|
// Convert Commander options to the format expected by UtilsController
|
40
41
|
const setupOptions = {
|
@@ -55,6 +56,7 @@ program.action(async (options) => {
|
|
55
56
|
project: options.project,
|
56
57
|
key: options.key,
|
57
58
|
};
|
59
|
+
console.log("Running operation...", setupOptions);
|
58
60
|
await controller.run(setupOptions);
|
59
61
|
console.log("Operation completed successfully.");
|
60
62
|
}
|
@@ -2,7 +2,7 @@ import { SchemaGenerator } from "./schemaStrings.js";
|
|
2
2
|
import { Databases, Query } from "node-appwrite";
|
3
3
|
import { fetchAllCollections } from "./collections.js";
|
4
4
|
import { fetchAllDatabases } from "./databases.js";
|
5
|
-
import { CollectionSchema, attributeSchema, AppwriteConfigSchema, permissionsSchema, attributesSchema, indexesSchema, } from "appwrite-utils";
|
5
|
+
import { CollectionSchema, attributeSchema, AppwriteConfigSchema, permissionsSchema, attributesSchema, indexesSchema, parseAttribute, } from "appwrite-utils";
|
6
6
|
import { getDatabaseFromConfig } from "./afterImportActions.js";
|
7
7
|
export class AppwriteToX {
|
8
8
|
config;
|
@@ -27,6 +27,9 @@ export class AppwriteToX {
|
|
27
27
|
};
|
28
28
|
// Function to parse an array of permission strings
|
29
29
|
parsePermissionsArray = (permissions) => {
|
30
|
+
if (permissions.length === 0) {
|
31
|
+
return [];
|
32
|
+
}
|
30
33
|
const parsedPermissions = permissionsSchema.parse(permissions);
|
31
34
|
// Validate the parsed permissions using Zod
|
32
35
|
return parsedPermissions ?? [];
|
@@ -51,22 +54,20 @@ export class AppwriteToX {
|
|
51
54
|
}
|
52
55
|
const collections = await fetchAllCollections(database.$id, db);
|
53
56
|
// Loop through each collection in the current database
|
57
|
+
if (!updatedConfig.collections) {
|
58
|
+
updatedConfig.collections = [];
|
59
|
+
}
|
54
60
|
for (const collection of collections) {
|
55
|
-
|
56
|
-
updatedConfig.collections = [];
|
57
|
-
}
|
61
|
+
console.log(`Processing collection: ${collection.name}`);
|
58
62
|
const existingCollectionIndex = updatedConfig.collections.findIndex((c) => c.name === collection.name);
|
63
|
+
console.log(`Parsing permissions...`);
|
59
64
|
// Parse the collection permissions and attributes
|
60
65
|
const collPermissions = this.parsePermissionsArray(collection.$permissions);
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
return { ...attr, type: attr.format };
|
67
|
-
}
|
68
|
-
return attr;
|
69
|
-
}))
|
66
|
+
console.log(`Parsing attributes...`, collection.attributes);
|
67
|
+
const collAttributes = collection.attributes
|
68
|
+
.map((attr) => {
|
69
|
+
return parseAttribute(attr);
|
70
|
+
})
|
70
71
|
.filter((attribute) => attribute.type === "relationship"
|
71
72
|
? attribute.side !== "child"
|
72
73
|
: true);
|
@@ -86,7 +87,16 @@ export class AppwriteToX {
|
|
86
87
|
}
|
87
88
|
}
|
88
89
|
this.collToAttributeMap.set(collection.name, collAttributes);
|
89
|
-
const
|
90
|
+
const finalIndexes = collection.indexes.map((index) => {
|
91
|
+
return {
|
92
|
+
...index,
|
93
|
+
orders: index.orders?.filter((order) => {
|
94
|
+
return order !== null && order;
|
95
|
+
}),
|
96
|
+
};
|
97
|
+
});
|
98
|
+
console.log(`Parsing indexes...`, finalIndexes);
|
99
|
+
const collIndexes = indexesSchema.parse(finalIndexes) ?? [];
|
90
100
|
// Prepare the collection object to be added or updated
|
91
101
|
const collToPush = CollectionSchema.parse({
|
92
102
|
$id: collection.$id,
|
@@ -280,6 +280,14 @@ export declare const getMigrationCollectionSchemas: () => {
|
|
280
280
|
permission: string;
|
281
281
|
target: string;
|
282
282
|
}[];
|
283
|
+
indexes: {
|
284
|
+
type: "key" | "unique" | "fulltext";
|
285
|
+
key: string;
|
286
|
+
attributes: string[];
|
287
|
+
status?: string | undefined;
|
288
|
+
error?: string | undefined;
|
289
|
+
orders?: string[] | undefined;
|
290
|
+
}[];
|
283
291
|
importDefs: {
|
284
292
|
filePath: string;
|
285
293
|
primaryKeyField: string;
|
@@ -317,14 +325,6 @@ export declare const getMigrationCollectionSchemas: () => {
|
|
317
325
|
description?: string | undefined;
|
318
326
|
enabled?: boolean | undefined;
|
319
327
|
documentSecurity?: boolean | undefined;
|
320
|
-
indexes?: {
|
321
|
-
type: "key" | "unique" | "fulltext";
|
322
|
-
key: string;
|
323
|
-
attributes: string[];
|
324
|
-
status?: string | undefined;
|
325
|
-
error?: string | undefined;
|
326
|
-
orders?: string[] | undefined;
|
327
|
-
}[] | undefined;
|
328
328
|
databaseId?: string | undefined;
|
329
329
|
};
|
330
330
|
attributes: ({
|
@@ -532,6 +532,14 @@ export declare const getMigrationCollectionSchemas: () => {
|
|
532
532
|
permission: string;
|
533
533
|
target: string;
|
534
534
|
}[];
|
535
|
+
indexes: {
|
536
|
+
type: "key" | "unique" | "fulltext";
|
537
|
+
key: string;
|
538
|
+
attributes: string[];
|
539
|
+
status?: string | undefined;
|
540
|
+
error?: string | undefined;
|
541
|
+
orders?: string[] | undefined;
|
542
|
+
}[];
|
535
543
|
importDefs: {
|
536
544
|
filePath: string;
|
537
545
|
primaryKeyField: string;
|
@@ -569,14 +577,6 @@ export declare const getMigrationCollectionSchemas: () => {
|
|
569
577
|
description?: string | undefined;
|
570
578
|
enabled?: boolean | undefined;
|
571
579
|
documentSecurity?: boolean | undefined;
|
572
|
-
indexes?: {
|
573
|
-
type: "key" | "unique" | "fulltext";
|
574
|
-
key: string;
|
575
|
-
attributes: string[];
|
576
|
-
status?: string | undefined;
|
577
|
-
error?: string | undefined;
|
578
|
-
orders?: string[] | undefined;
|
579
|
-
}[] | undefined;
|
580
580
|
databaseId?: string | undefined;
|
581
581
|
};
|
582
582
|
attributes: ({
|
@@ -319,7 +319,7 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
319
319
|
targetField?: string | undefined;
|
320
320
|
} | undefined;
|
321
321
|
}>]>, "many">>;
|
322
|
-
indexes: z.
|
322
|
+
indexes: z.ZodEffects<z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
323
323
|
key: z.ZodString;
|
324
324
|
type: z.ZodDefault<z.ZodOptional<z.ZodEnum<["key", "unique", "fulltext"]>>>;
|
325
325
|
status: z.ZodOptional<z.ZodString>;
|
@@ -340,7 +340,21 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
340
340
|
status?: string | undefined;
|
341
341
|
error?: string | undefined;
|
342
342
|
orders?: string[] | undefined;
|
343
|
-
}>, "many"
|
343
|
+
}>, "many">>>, {
|
344
|
+
type: "key" | "unique" | "fulltext";
|
345
|
+
key: string;
|
346
|
+
attributes: string[];
|
347
|
+
status?: string | undefined;
|
348
|
+
error?: string | undefined;
|
349
|
+
orders?: string[] | undefined;
|
350
|
+
}[], {
|
351
|
+
key: string;
|
352
|
+
attributes: string[];
|
353
|
+
type?: "key" | "unique" | "fulltext" | undefined;
|
354
|
+
status?: string | undefined;
|
355
|
+
error?: string | undefined;
|
356
|
+
orders?: string[] | undefined;
|
357
|
+
}[] | undefined>;
|
344
358
|
importDefs: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
345
359
|
type: z.ZodOptional<z.ZodDefault<z.ZodEnum<["create", "update"]>>>;
|
346
360
|
filePath: z.ZodString;
|
@@ -615,6 +629,14 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
615
629
|
permission: string;
|
616
630
|
target: string;
|
617
631
|
}[];
|
632
|
+
indexes: {
|
633
|
+
type: "key" | "unique" | "fulltext";
|
634
|
+
key: string;
|
635
|
+
attributes: string[];
|
636
|
+
status?: string | undefined;
|
637
|
+
error?: string | undefined;
|
638
|
+
orders?: string[] | undefined;
|
639
|
+
}[];
|
618
640
|
importDefs: {
|
619
641
|
filePath: string;
|
620
642
|
primaryKeyField: string;
|
@@ -652,14 +674,6 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
652
674
|
description?: string | undefined;
|
653
675
|
enabled?: boolean | undefined;
|
654
676
|
documentSecurity?: boolean | undefined;
|
655
|
-
indexes?: {
|
656
|
-
type: "key" | "unique" | "fulltext";
|
657
|
-
key: string;
|
658
|
-
attributes: string[];
|
659
|
-
status?: string | undefined;
|
660
|
-
error?: string | undefined;
|
661
|
-
orders?: string[] | undefined;
|
662
|
-
}[] | undefined;
|
663
677
|
databaseId?: string | undefined;
|
664
678
|
}, {
|
665
679
|
name: string;
|
@@ -1207,6 +1221,14 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
1207
1221
|
permission: string;
|
1208
1222
|
target: string;
|
1209
1223
|
}[];
|
1224
|
+
indexes: {
|
1225
|
+
type: "key" | "unique" | "fulltext";
|
1226
|
+
key: string;
|
1227
|
+
attributes: string[];
|
1228
|
+
status?: string | undefined;
|
1229
|
+
error?: string | undefined;
|
1230
|
+
orders?: string[] | undefined;
|
1231
|
+
}[];
|
1210
1232
|
importDefs: {
|
1211
1233
|
filePath: string;
|
1212
1234
|
primaryKeyField: string;
|
@@ -1244,14 +1266,6 @@ export declare const CollectionImportDataSchema: z.ZodObject<{
|
|
1244
1266
|
description?: string | undefined;
|
1245
1267
|
enabled?: boolean | undefined;
|
1246
1268
|
documentSecurity?: boolean | undefined;
|
1247
|
-
indexes?: {
|
1248
|
-
type: "key" | "unique" | "fulltext";
|
1249
|
-
key: string;
|
1250
|
-
attributes: string[];
|
1251
|
-
status?: string | undefined;
|
1252
|
-
error?: string | undefined;
|
1253
|
-
orders?: string[] | undefined;
|
1254
|
-
}[] | undefined;
|
1255
1269
|
databaseId?: string | undefined;
|
1256
1270
|
} | undefined;
|
1257
1271
|
}, {
|
@@ -1599,6 +1613,14 @@ export declare class DataLoader {
|
|
1599
1613
|
permission: string;
|
1600
1614
|
target: string;
|
1601
1615
|
}[];
|
1616
|
+
indexes: {
|
1617
|
+
type: "key" | "unique" | "fulltext";
|
1618
|
+
key: string;
|
1619
|
+
attributes: string[];
|
1620
|
+
status?: string | undefined;
|
1621
|
+
error?: string | undefined;
|
1622
|
+
orders?: string[] | undefined;
|
1623
|
+
}[];
|
1602
1624
|
importDefs: {
|
1603
1625
|
filePath: string;
|
1604
1626
|
primaryKeyField: string;
|
@@ -1636,14 +1658,6 @@ export declare class DataLoader {
|
|
1636
1658
|
description?: string | undefined;
|
1637
1659
|
enabled?: boolean | undefined;
|
1638
1660
|
documentSecurity?: boolean | undefined;
|
1639
|
-
indexes?: {
|
1640
|
-
type: "key" | "unique" | "fulltext";
|
1641
|
-
key: string;
|
1642
|
-
attributes: string[];
|
1643
|
-
status?: string | undefined;
|
1644
|
-
error?: string | undefined;
|
1645
|
-
orders?: string[] | undefined;
|
1646
|
-
}[] | undefined;
|
1647
1661
|
databaseId?: string | undefined;
|
1648
1662
|
} | undefined;
|
1649
1663
|
}>;
|
@@ -69,9 +69,14 @@ export class SchemaGenerator {
|
|
69
69
|
}
|
70
70
|
else if (Array.isArray(value)) {
|
71
71
|
// If the value is an array, join it with commas
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
if (value.length > 0) {
|
73
|
+
return `${key}: [${value
|
74
|
+
.map((item) => `"${item}"`)
|
75
|
+
.join(", ")}]`;
|
76
|
+
}
|
77
|
+
else {
|
78
|
+
return `${key}: []`;
|
79
|
+
}
|
75
80
|
}
|
76
81
|
else {
|
77
82
|
// If the value is not a string (e.g., boolean or number), output it directly
|
@@ -88,7 +93,10 @@ export class SchemaGenerator {
|
|
88
93
|
const formattedAttributes = index.attributes
|
89
94
|
.map((attr) => `"${attr}"`)
|
90
95
|
.join(", ");
|
91
|
-
return `{ key: "${index.key}", type: "${index.type}", attributes: [${formattedAttributes}]
|
96
|
+
return `{ key: "${index.key}", type: "${index.type}", attributes: [${formattedAttributes}], orders: [${index.orders
|
97
|
+
?.filter((order) => order !== null)
|
98
|
+
.map((order) => `"${order}"`)
|
99
|
+
.join(", ") ?? ""}] }`;
|
92
100
|
}) ?? []).join(",\n ")}
|
93
101
|
]
|
94
102
|
};
|
@@ -8,9 +8,12 @@ import { register } from "tsx/esm/api"; // Import the register function
|
|
8
8
|
* @returns The path to the file if found, or null if not found.
|
9
9
|
*/
|
10
10
|
export const findAppwriteConfig = (dir) => {
|
11
|
+
if (dir === "node_modules") {
|
12
|
+
return null;
|
13
|
+
}
|
11
14
|
const files = fs.readdirSync(dir, { withFileTypes: true });
|
12
15
|
for (const file of files) {
|
13
|
-
if (file.isDirectory()) {
|
16
|
+
if (file.isDirectory() && file.name !== "node_modules") {
|
14
17
|
const result = findAppwriteConfig(path.join(dir, file.name));
|
15
18
|
if (result)
|
16
19
|
return result;
|
@@ -30,6 +33,7 @@ export const loadConfig = async (configDir) => {
|
|
30
33
|
const unregister = register(); // Register tsx enhancement
|
31
34
|
try {
|
32
35
|
const configPath = path.resolve(configDir, "appwriteConfig.ts");
|
36
|
+
console.log(`Loading config from: ${configPath}`);
|
33
37
|
const config = (await import(configPath)).default;
|
34
38
|
const collectionsDir = path.resolve(configDir, "collections");
|
35
39
|
const collectionFiles = fs.readdirSync(collectionsDir);
|
@@ -27,7 +27,7 @@ export declare class UtilsController {
|
|
27
27
|
converterDefinitions: ConverterFunctions;
|
28
28
|
validityRuleDefinitions: ValidationRules;
|
29
29
|
afterImportActionsDefinitions: AfterImportActions;
|
30
|
-
constructor();
|
30
|
+
constructor(currentUserDir: string);
|
31
31
|
init(setupOptions: SetupOptions): Promise<void>;
|
32
32
|
run(options: SetupOptions): Promise<void>;
|
33
33
|
}
|
package/dist/utilsController.js
CHANGED
@@ -22,14 +22,17 @@ export class UtilsController {
|
|
22
22
|
converterDefinitions = converterFunctions;
|
23
23
|
validityRuleDefinitions = validationRules;
|
24
24
|
afterImportActionsDefinitions = afterImportActions;
|
25
|
-
constructor() {
|
26
|
-
const basePath =
|
25
|
+
constructor(currentUserDir) {
|
26
|
+
const basePath = currentUserDir; // Gets the current working directory
|
27
27
|
const appwriteConfigFound = findAppwriteConfig(basePath);
|
28
28
|
if (!appwriteConfigFound) {
|
29
29
|
throw new Error("Failed to find appwriteConfig.ts");
|
30
30
|
}
|
31
31
|
this.appwriteConfigPath = appwriteConfigFound;
|
32
32
|
this.appwriteFolderPath = path.dirname(appwriteConfigFound);
|
33
|
+
if (!this.appwriteFolderPath) {
|
34
|
+
throw new Error("Failed to get appwriteFolderPath");
|
35
|
+
}
|
33
36
|
}
|
34
37
|
// async loadCustomDefinitions(): Promise<void> {
|
35
38
|
// try {
|
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.0.
|
4
|
+
"version": "0.0.284",
|
5
5
|
"main": "src/main.ts",
|
6
6
|
"type": "module",
|
7
7
|
"repository": {
|
@@ -34,7 +34,7 @@
|
|
34
34
|
"dependencies": {
|
35
35
|
"@asteasolutions/zod-to-openapi": "^7.0.0",
|
36
36
|
"@types/inquirer": "^9.0.7",
|
37
|
-
"appwrite-utils": "^0.1
|
37
|
+
"appwrite-utils": "^0.2.1",
|
38
38
|
"commander": "^12.0.0",
|
39
39
|
"inquirer": "^9.2.20",
|
40
40
|
"js-yaml": "^4.1.0",
|
package/src/main.ts
CHANGED
@@ -49,7 +49,8 @@ program.on("--help", () => {
|
|
49
49
|
|
50
50
|
// Parse and handle options
|
51
51
|
program.action(async (options) => {
|
52
|
-
const
|
52
|
+
const currentUserDir = process.cwd();
|
53
|
+
const controller = new UtilsController(currentUserDir);
|
53
54
|
try {
|
54
55
|
// Convert Commander options to the format expected by UtilsController
|
55
56
|
const setupOptions = {
|
@@ -70,6 +71,7 @@ program.action(async (options) => {
|
|
70
71
|
project: options.project,
|
71
72
|
key: options.key,
|
72
73
|
};
|
74
|
+
console.log("Running operation...", setupOptions);
|
73
75
|
|
74
76
|
await controller.run(setupOptions);
|
75
77
|
console.log("Operation completed successfully.");
|
@@ -12,6 +12,7 @@ import {
|
|
12
12
|
permissionsSchema,
|
13
13
|
attributesSchema,
|
14
14
|
indexesSchema,
|
15
|
+
parseAttribute,
|
15
16
|
} from "appwrite-utils";
|
16
17
|
import { getDatabaseFromConfig } from "./afterImportActions.js";
|
17
18
|
|
@@ -41,6 +42,9 @@ export class AppwriteToX {
|
|
41
42
|
|
42
43
|
// Function to parse an array of permission strings
|
43
44
|
parsePermissionsArray = (permissions: string[]) => {
|
45
|
+
if (permissions.length === 0) {
|
46
|
+
return [];
|
47
|
+
}
|
44
48
|
const parsedPermissions = permissionsSchema.parse(permissions);
|
45
49
|
// Validate the parsed permissions using Zod
|
46
50
|
return parsedPermissions ?? [];
|
@@ -71,31 +75,25 @@ export class AppwriteToX {
|
|
71
75
|
const collections = await fetchAllCollections(database.$id, db);
|
72
76
|
|
73
77
|
// Loop through each collection in the current database
|
78
|
+
if (!updatedConfig.collections) {
|
79
|
+
updatedConfig.collections = [];
|
80
|
+
}
|
74
81
|
for (const collection of collections) {
|
75
|
-
|
76
|
-
updatedConfig.collections = [];
|
77
|
-
}
|
82
|
+
console.log(`Processing collection: ${collection.name}`);
|
78
83
|
const existingCollectionIndex = updatedConfig.collections.findIndex(
|
79
84
|
(c) => c.name === collection.name
|
80
85
|
);
|
81
86
|
|
87
|
+
console.log(`Parsing permissions...`);
|
82
88
|
// Parse the collection permissions and attributes
|
83
89
|
const collPermissions = this.parsePermissionsArray(
|
84
90
|
collection.$permissions
|
85
91
|
);
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
attr.format &&
|
92
|
-
attr.format.length > 0
|
93
|
-
) {
|
94
|
-
return { ...attr, type: attr.format };
|
95
|
-
}
|
96
|
-
return attr;
|
97
|
-
})
|
98
|
-
)
|
92
|
+
console.log(`Parsing attributes...`, collection.attributes);
|
93
|
+
const collAttributes = collection.attributes
|
94
|
+
.map((attr: any) => {
|
95
|
+
return parseAttribute(attr);
|
96
|
+
})
|
99
97
|
.filter((attribute) =>
|
100
98
|
attribute.type === "relationship"
|
101
99
|
? attribute.side !== "child"
|
@@ -127,7 +125,16 @@ export class AppwriteToX {
|
|
127
125
|
}
|
128
126
|
}
|
129
127
|
this.collToAttributeMap.set(collection.name, collAttributes);
|
130
|
-
const
|
128
|
+
const finalIndexes = collection.indexes.map((index) => {
|
129
|
+
return {
|
130
|
+
...index,
|
131
|
+
orders: index.orders?.filter((order) => {
|
132
|
+
return order !== null && order;
|
133
|
+
}),
|
134
|
+
};
|
135
|
+
});
|
136
|
+
console.log(`Parsing indexes...`, finalIndexes);
|
137
|
+
const collIndexes = indexesSchema.parse(finalIndexes) ?? [];
|
131
138
|
|
132
139
|
// Prepare the collection object to be added or updated
|
133
140
|
const collToPush = CollectionSchema.parse({
|
@@ -97,9 +97,13 @@ export class SchemaGenerator {
|
|
97
97
|
return `${key}: "${value.replace(/"/g, '\\"')}"`; // Escape existing quotes in the string
|
98
98
|
} else if (Array.isArray(value)) {
|
99
99
|
// If the value is an array, join it with commas
|
100
|
-
|
101
|
-
|
102
|
-
|
100
|
+
if (value.length > 0) {
|
101
|
+
return `${key}: [${value
|
102
|
+
.map((item) => `"${item}"`)
|
103
|
+
.join(", ")}]`;
|
104
|
+
} else {
|
105
|
+
return `${key}: []`;
|
106
|
+
}
|
103
107
|
} else {
|
104
108
|
// If the value is not a string (e.g., boolean or number), output it directly
|
105
109
|
return `${key}: ${value}`;
|
@@ -116,7 +120,14 @@ export class SchemaGenerator {
|
|
116
120
|
const formattedAttributes = index.attributes
|
117
121
|
.map((attr) => `"${attr}"`)
|
118
122
|
.join(", ");
|
119
|
-
return `{ key: "${index.key}", type: "${
|
123
|
+
return `{ key: "${index.key}", type: "${
|
124
|
+
index.type
|
125
|
+
}", attributes: [${formattedAttributes}], orders: [${
|
126
|
+
index.orders
|
127
|
+
?.filter((order) => order !== null)
|
128
|
+
.map((order) => `"${order}"`)
|
129
|
+
.join(", ") ?? ""
|
130
|
+
}] }`;
|
120
131
|
}) ?? []
|
121
132
|
).join(",\n ")}
|
122
133
|
]
|
package/src/utils/loadConfigs.ts
CHANGED
@@ -9,10 +9,13 @@ import { register } from "tsx/esm/api"; // Import the register function
|
|
9
9
|
* @returns The path to the file if found, or null if not found.
|
10
10
|
*/
|
11
11
|
export const findAppwriteConfig = (dir: string): string | null => {
|
12
|
+
if (dir === "node_modules") {
|
13
|
+
return null;
|
14
|
+
}
|
12
15
|
const files = fs.readdirSync(dir, { withFileTypes: true });
|
13
16
|
|
14
17
|
for (const file of files) {
|
15
|
-
if (file.isDirectory()) {
|
18
|
+
if (file.isDirectory() && file.name !== "node_modules") {
|
16
19
|
const result = findAppwriteConfig(path.join(dir, file.name));
|
17
20
|
if (result) return result;
|
18
21
|
} else if (file.name === "appwriteConfig.ts") {
|
@@ -35,6 +38,7 @@ export const loadConfig = async (
|
|
35
38
|
|
36
39
|
try {
|
37
40
|
const configPath = path.resolve(configDir, "appwriteConfig.ts");
|
41
|
+
console.log(`Loading config from: ${configPath}`);
|
38
42
|
const config = (await import(configPath)).default as AppwriteConfig;
|
39
43
|
|
40
44
|
const collectionsDir = path.resolve(configDir, "collections");
|
package/src/utilsController.ts
CHANGED
@@ -61,14 +61,17 @@ export class UtilsController {
|
|
61
61
|
public validityRuleDefinitions: ValidationRules = validationRules;
|
62
62
|
public afterImportActionsDefinitions: AfterImportActions = afterImportActions;
|
63
63
|
|
64
|
-
constructor() {
|
65
|
-
const basePath =
|
64
|
+
constructor(currentUserDir: string) {
|
65
|
+
const basePath = currentUserDir; // Gets the current working directory
|
66
66
|
const appwriteConfigFound = findAppwriteConfig(basePath);
|
67
67
|
if (!appwriteConfigFound) {
|
68
68
|
throw new Error("Failed to find appwriteConfig.ts");
|
69
69
|
}
|
70
70
|
this.appwriteConfigPath = appwriteConfigFound;
|
71
71
|
this.appwriteFolderPath = path.dirname(appwriteConfigFound);
|
72
|
+
if (!this.appwriteFolderPath) {
|
73
|
+
throw new Error("Failed to get appwriteFolderPath");
|
74
|
+
}
|
72
75
|
}
|
73
76
|
|
74
77
|
// async loadCustomDefinitions(): Promise<void> {
|