appwrite-utils-cli 0.0.274 → 0.0.276
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 +4 -39
- package/dist/init.d.ts +2 -0
- package/dist/init.js +57 -0
- package/dist/main.js +62 -100
- package/dist/migrations/afterImportActions.d.ts +1 -4
- package/dist/migrations/afterImportActions.js +1 -0
- package/dist/migrations/appwriteToX.d.ts +46 -46
- package/dist/migrations/appwriteToX.js +6 -2
- package/dist/migrations/attributes.d.ts +1 -1
- package/dist/migrations/attributes.js +97 -71
- package/dist/migrations/backup.d.ts +240 -240
- package/dist/migrations/backup.js +1 -1
- package/dist/migrations/collections.d.ts +1 -1
- package/dist/migrations/collections.js +4 -4
- package/dist/migrations/converters.d.ts +9 -127
- package/dist/migrations/converters.js +1 -504
- package/dist/migrations/dataLoader.d.ts +470 -453
- package/dist/migrations/dataLoader.js +19 -1
- package/dist/migrations/dbHelpers.d.ts +1 -1
- package/dist/migrations/dbHelpers.js +3 -0
- package/dist/migrations/importController.d.ts +1 -1
- package/dist/migrations/importController.js +4 -7
- package/dist/migrations/importDataActions.d.ts +4 -6
- package/dist/migrations/importDataActions.js +6 -4
- package/dist/migrations/indexes.d.ts +1 -1
- package/dist/migrations/indexes.js +1 -1
- package/dist/migrations/migrationHelper.d.ts +29 -29
- package/dist/migrations/migrationHelper.js +1 -1
- package/dist/migrations/openapi.d.ts +1 -1
- package/dist/migrations/openapi.js +4 -1
- package/dist/migrations/queue.d.ts +1 -1
- package/dist/migrations/relationships.d.ts +5 -5
- package/dist/migrations/relationships.js +3 -0
- package/dist/migrations/schemaStrings.d.ts +2 -2
- package/dist/migrations/schemaStrings.js +93 -8
- package/dist/migrations/setupDatabase.d.ts +1 -1
- package/dist/migrations/setupDatabase.js +1 -1
- package/dist/migrations/storage.d.ts +1 -1
- package/dist/migrations/users.d.ts +1 -1
- package/dist/schemas/authUser.d.ts +12 -10
- package/dist/types.d.ts +0 -5
- package/dist/types.js +0 -2
- package/dist/utils/helperFunctions.d.ts +2 -3
- package/dist/utils/loadConfigs.d.ts +13 -0
- package/dist/utils/loadConfigs.js +47 -0
- package/dist/utils/setupFiles.d.ts +1 -0
- package/dist/utils/setupFiles.js +98 -223
- package/dist/utilsController.d.ts +1 -3
- package/dist/utilsController.js +14 -18
- package/package.json +9 -2
- package/src/init.ts +64 -0
- package/src/main.ts +73 -98
- package/src/migrations/afterImportActions.ts +1 -5
- package/src/migrations/appwriteToX.ts +6 -2
- package/src/migrations/attributes.ts +198 -150
- package/src/migrations/backup.ts +1 -1
- package/src/migrations/collections.ts +5 -11
- package/src/migrations/converters.ts +1 -540
- package/src/migrations/dataLoader.ts +19 -2
- package/src/migrations/dbHelpers.ts +4 -1
- package/src/migrations/importController.ts +5 -15
- package/src/migrations/importDataActions.ts +10 -14
- package/src/migrations/indexes.ts +1 -1
- package/src/migrations/migrationHelper.ts +1 -1
- package/src/migrations/openapi.ts +4 -1
- package/src/migrations/queue.ts +1 -1
- package/src/migrations/relationships.ts +4 -1
- package/src/migrations/schemaStrings.ts +106 -9
- package/src/migrations/setupDatabase.ts +1 -1
- package/src/migrations/storage.ts +1 -1
- package/src/migrations/users.ts +1 -1
- package/src/types.ts +0 -5
- package/src/utils/helperFunctions.ts +2 -3
- package/src/utils/loadConfigs.ts +55 -0
- package/src/utils/setupFiles.ts +114 -225
- package/src/utilsController.ts +27 -35
- package/src/migrations/schema.ts +0 -748
@@ -5,22 +5,18 @@ import {
|
|
5
5
|
type Databases,
|
6
6
|
type Storage,
|
7
7
|
} from "node-appwrite";
|
8
|
-
import type { AppwriteConfig } from "
|
9
|
-
import { validationRules, type ValidationRules } from "./validationRules.js";
|
8
|
+
import type { AppwriteConfig } from "appwrite-utils";
|
10
9
|
import {
|
11
|
-
|
12
|
-
|
13
|
-
type
|
14
|
-
} from "
|
15
|
-
import {
|
16
|
-
|
17
|
-
|
18
|
-
} from "./afterImportActions.js";
|
10
|
+
validationRules,
|
11
|
+
type ValidationRules,
|
12
|
+
type AttributeMappings,
|
13
|
+
} from "appwrite-utils";
|
14
|
+
import { converterFunctions, type ConverterFunctions } from "appwrite-utils";
|
15
|
+
import { convertObjectBySchema } from "./converters.js";
|
16
|
+
import { type AfterImportActions } from "appwrite-utils";
|
17
|
+
import { afterImportActions } from "./afterImportActions.js";
|
19
18
|
import { logger } from "./logging.js";
|
20
19
|
|
21
|
-
type AttributeMappings =
|
22
|
-
AppwriteConfig["collections"][number]["importDefs"][number]["attributeMappings"];
|
23
|
-
|
24
20
|
export class ImportDataActions {
|
25
21
|
private db: Databases;
|
26
22
|
private storage: Storage;
|
@@ -48,7 +44,7 @@ export class ImportDataActions {
|
|
48
44
|
runConverterFunctions(item: any, attributeMappings: AttributeMappings) {
|
49
45
|
const conversionSchema = attributeMappings.reduce((schema, mapping) => {
|
50
46
|
schema[mapping.targetKey] = (originalValue: any) => {
|
51
|
-
return mapping.converters
|
47
|
+
return mapping.converters?.reduce((value, converterName) => {
|
52
48
|
let shouldProcessAsArray = false;
|
53
49
|
if (
|
54
50
|
(converterName.includes("[Arr]") ||
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { ID, Query, type Databases } from "node-appwrite";
|
2
2
|
import { BatchSchema, OperationSchema, type Operation } from "./backup.js";
|
3
|
-
import {
|
3
|
+
import { AttributeMappingsSchema } from "appwrite-utils";
|
4
4
|
import { z } from "zod";
|
5
5
|
import { logger } from "./logging.js";
|
6
6
|
|
@@ -10,13 +10,16 @@ import {
|
|
10
10
|
type Attribute,
|
11
11
|
type Collection,
|
12
12
|
type CollectionCreate,
|
13
|
-
} from "
|
13
|
+
} from "appwrite-utils";
|
14
14
|
import { z } from "zod";
|
15
15
|
import { writeFileSync } from "fs";
|
16
16
|
|
17
17
|
const registry = new OpenAPIRegistry();
|
18
18
|
|
19
19
|
export const generateOpenApi = async (config: AppwriteConfig) => {
|
20
|
+
if (!config.collections) {
|
21
|
+
return;
|
22
|
+
}
|
20
23
|
for (const collection of config.collections) {
|
21
24
|
// Transform and register each attribute schema
|
22
25
|
const attributeSchemas = collection.attributes.map((attribute) => {
|
package/src/migrations/queue.ts
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
import { Query, type Databases, type Models } from "node-appwrite";
|
2
|
-
import type { Attribute } from "
|
2
|
+
import type { Attribute } from "appwrite-utils";
|
3
3
|
import { createOrUpdateAttribute } from "./attributes.js";
|
4
4
|
import _ from "lodash";
|
5
5
|
import { fetchAndCacheCollectionByName } from "./collections.js";
|
@@ -4,7 +4,7 @@ import type {
|
|
4
4
|
AppwriteConfig,
|
5
5
|
Attribute,
|
6
6
|
RelationshipAttribute,
|
7
|
-
} from "
|
7
|
+
} from "appwrite-utils";
|
8
8
|
import { logger } from "./logging.js";
|
9
9
|
|
10
10
|
/**
|
@@ -12,6 +12,9 @@ import { logger } from "./logging.js";
|
|
12
12
|
*/
|
13
13
|
export const findCollectionsWithRelationships = (config: AppwriteConfig) => {
|
14
14
|
const toReturn = new Map<string, RelationshipAttribute[]>();
|
15
|
+
if (!config.collections) {
|
16
|
+
return toReturn;
|
17
|
+
}
|
15
18
|
for (const collection of config.collections) {
|
16
19
|
if (collection.attributes) {
|
17
20
|
for (const attribute of collection.attributes) {
|
@@ -3,7 +3,7 @@ import type {
|
|
3
3
|
AppwriteConfig,
|
4
4
|
Attribute,
|
5
5
|
RelationshipAttribute,
|
6
|
-
} from "
|
6
|
+
} from "appwrite-utils";
|
7
7
|
import { z } from "zod";
|
8
8
|
import fs from "fs";
|
9
9
|
import path from "path";
|
@@ -30,17 +30,111 @@ export class SchemaGenerator {
|
|
30
30
|
this.extractRelationships();
|
31
31
|
}
|
32
32
|
|
33
|
-
public
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
const
|
38
|
-
const
|
39
|
-
|
40
|
-
|
33
|
+
public updateTsSchemas(): void {
|
34
|
+
const collections = this.config.collections;
|
35
|
+
delete this.config.collections;
|
36
|
+
|
37
|
+
const configPath = path.join(this.appwriteFolderPath, "appwriteConfig.ts");
|
38
|
+
const configContent = `import { AppwriteConfig } from "appwrite-utils";
|
39
|
+
|
40
|
+
const appwriteConfig: AppwriteConfig = {
|
41
|
+
appwriteEndpoint: "${this.config.appwriteEndpoint}",
|
42
|
+
appwriteProject: "${this.config.appwriteProject}",
|
43
|
+
appwriteKey: "${this.config.appwriteKey}",
|
44
|
+
enableDevDatabase: ${this.config.enableDevDatabase},
|
45
|
+
enableBackups: ${this.config.enableBackups},
|
46
|
+
backupInterval: ${this.config.backupInterval},
|
47
|
+
backupRetention: ${this.config.backupRetention},
|
48
|
+
enableBackupCleanup: ${this.config.enableBackupCleanup},
|
49
|
+
enableMockData: ${this.config.enableMockData},
|
50
|
+
enableWipeOtherDatabases: ${this.config.enableWipeOtherDatabases},
|
51
|
+
documentBucketId: "${this.config.documentBucketId}",
|
52
|
+
usersCollectionName: "${this.config.usersCollectionName}",
|
53
|
+
databases: ${JSON.stringify(this.config.databases)}
|
54
|
+
};
|
55
|
+
|
56
|
+
export default appwriteConfig;
|
57
|
+
`;
|
58
|
+
fs.writeFileSync(configPath, configContent, { encoding: "utf-8" });
|
59
|
+
|
60
|
+
const collectionsFolderPath = path.join(
|
61
|
+
this.appwriteFolderPath,
|
62
|
+
"collections"
|
63
|
+
);
|
64
|
+
if (!fs.existsSync(collectionsFolderPath)) {
|
65
|
+
fs.mkdirSync(collectionsFolderPath, { recursive: true });
|
66
|
+
}
|
67
|
+
|
68
|
+
collections?.forEach((collection) => {
|
69
|
+
const { databaseId, ...collectionWithoutDbId } = collection; // Destructure to exclude databaseId
|
70
|
+
const collectionFilePath = path.join(
|
71
|
+
collectionsFolderPath,
|
72
|
+
`${collection.name}.ts`
|
73
|
+
);
|
74
|
+
const collectionContent = `import { CollectionCreate } from "appwrite-utils";
|
75
|
+
|
76
|
+
const ${collection.name}Config: Partial<CollectionCreate> = {
|
77
|
+
name: "${collection.name}",
|
78
|
+
$id: "${collection.$id}",
|
79
|
+
enabled: ${collection.enabled},
|
80
|
+
documentSecurity: ${collection.documentSecurity},
|
81
|
+
$permissions: [
|
82
|
+
${collection.$permissions
|
83
|
+
.map(
|
84
|
+
(permission) =>
|
85
|
+
`{ permission: "${permission.permission}", target: "${permission.target}" }`
|
86
|
+
)
|
87
|
+
.join(",\n ")}
|
88
|
+
],
|
89
|
+
attributes: [
|
90
|
+
${collection.attributes
|
91
|
+
.map((attr) => {
|
92
|
+
return `{ ${Object.entries(attr)
|
93
|
+
.map(([key, value]) => {
|
94
|
+
// Check the type of the value and format it accordingly
|
95
|
+
if (typeof value === "string") {
|
96
|
+
// If the value is a string, wrap it in quotes
|
97
|
+
return `${key}: "${value.replace(/"/g, '\\"')}"`; // Escape existing quotes in the string
|
98
|
+
} else if (Array.isArray(value)) {
|
99
|
+
// If the value is an array, join it with commas
|
100
|
+
return `${key}: [${value
|
101
|
+
.map((item) => `"${item}"`)
|
102
|
+
.join(", ")}]`;
|
103
|
+
} else {
|
104
|
+
// If the value is not a string (e.g., boolean or number), output it directly
|
105
|
+
return `${key}: ${value}`;
|
106
|
+
}
|
107
|
+
})
|
108
|
+
.join(", ")} }`;
|
109
|
+
})
|
110
|
+
.join(",\n ")}
|
111
|
+
],
|
112
|
+
indexes: [
|
113
|
+
${(
|
114
|
+
collection.indexes?.map((index) => {
|
115
|
+
// Map each attribute to ensure it is properly quoted
|
116
|
+
const formattedAttributes = index.attributes
|
117
|
+
.map((attr) => `"${attr}"`)
|
118
|
+
.join(", ");
|
119
|
+
return `{ key: "${index.key}", type: "${index.type}", attributes: [${formattedAttributes}] }`;
|
120
|
+
}) ?? []
|
121
|
+
).join(",\n ")}
|
122
|
+
]
|
123
|
+
};
|
124
|
+
|
125
|
+
export default ${collection.name}Config;
|
126
|
+
`;
|
127
|
+
fs.writeFileSync(collectionFilePath, collectionContent, {
|
128
|
+
encoding: "utf-8",
|
129
|
+
});
|
130
|
+
console.log(`Collection schema written to ${collectionFilePath}`);
|
131
|
+
});
|
41
132
|
}
|
42
133
|
|
43
134
|
private extractRelationships(): void {
|
135
|
+
if (!this.config.collections) {
|
136
|
+
return;
|
137
|
+
}
|
44
138
|
this.config.collections.forEach((collection) => {
|
45
139
|
collection.attributes.forEach((attr) => {
|
46
140
|
if (attr.type === "relationship" && attr.twoWay && attr.twoWayKey) {
|
@@ -115,6 +209,9 @@ export class SchemaGenerator {
|
|
115
209
|
}
|
116
210
|
|
117
211
|
public generateSchemas(): void {
|
212
|
+
if (!this.config.collections) {
|
213
|
+
return;
|
214
|
+
}
|
118
215
|
this.config.collections.forEach((collection) => {
|
119
216
|
const schemaString = this.createSchemaString(
|
120
217
|
collection.name,
|
@@ -13,7 +13,7 @@ import {
|
|
13
13
|
initOrGetDocumentStorage,
|
14
14
|
wipeDocumentStorage,
|
15
15
|
} from "./storage.js";
|
16
|
-
import { type AppwriteConfig } from "
|
16
|
+
import { type AppwriteConfig } from "appwrite-utils";
|
17
17
|
import type { SetupOptions } from "../utilsController.js";
|
18
18
|
import { nameToIdMapping } from "./queue.js";
|
19
19
|
import { UsersController } from "./users.js";
|
@@ -9,7 +9,7 @@ import {
|
|
9
9
|
} from "node-appwrite";
|
10
10
|
import { type OperationCreate, type BackupCreate } from "./backup.js";
|
11
11
|
import { splitIntoBatches } from "./migrationHelper.js";
|
12
|
-
import type { AppwriteConfig } from "
|
12
|
+
import type { AppwriteConfig } from "appwrite-utils";
|
13
13
|
|
14
14
|
export const logOperation = async (
|
15
15
|
db: Databases,
|
package/src/migrations/users.ts
CHANGED
package/src/types.ts
CHANGED
@@ -1,14 +1,9 @@
|
|
1
|
-
export type { AppwriteConfig } from "./migrations/schema.js";
|
2
|
-
export type { ConverterFunctions } from "./migrations/converters.js";
|
3
1
|
export type { ValidationRules } from "./migrations/validationRules.js";
|
4
|
-
export type { AfterImportActions } from "./migrations/afterImportActions.js";
|
5
2
|
export {
|
6
3
|
type AuthUserCreate,
|
7
4
|
AuthUserCreateSchema,
|
8
5
|
type AuthUser,
|
9
6
|
AuthUserSchema,
|
10
7
|
} from "./schemas/authUser.js";
|
11
|
-
export { getFileViewUrl, getFileDownloadUrl } from "./utils/helperFunctions.js";
|
12
|
-
export { converterFunctions } from "./migrations/converters.js";
|
13
8
|
export { validationRules } from "./migrations/validationRules.js";
|
14
9
|
export { afterImportActions } from "./migrations/afterImportActions.js";
|
@@ -1,9 +1,8 @@
|
|
1
|
-
import type { AppwriteConfig } from "../types.js";
|
2
1
|
import type { Models, Storage } from "node-appwrite";
|
3
2
|
import fs from "node:fs";
|
4
3
|
import path from "node:path";
|
5
|
-
import type { CollectionImportData } from "
|
6
|
-
import type { ConfigCollection } from "
|
4
|
+
import type { CollectionImportData } from "../migrations/dataLoader.js";
|
5
|
+
import type { ConfigCollection } from "appwrite-utils";
|
7
6
|
|
8
7
|
export const toPascalCase = (str: string): string => {
|
9
8
|
return (
|
@@ -0,0 +1,55 @@
|
|
1
|
+
import path from "path";
|
2
|
+
import fs from "fs";
|
3
|
+
import { type AppwriteConfig, type Collection } from "appwrite-utils";
|
4
|
+
import { register } from "tsx/esm/api"; // Import the register function
|
5
|
+
|
6
|
+
/**
|
7
|
+
* Recursively searches for a file named 'appwriteConfig.ts' starting from the given directory.
|
8
|
+
* @param dir The directory to start the search from.
|
9
|
+
* @returns The path to the file if found, or null if not found.
|
10
|
+
*/
|
11
|
+
export const findAppwriteConfig = (dir: string): string | null => {
|
12
|
+
const files = fs.readdirSync(dir, { withFileTypes: true });
|
13
|
+
|
14
|
+
for (const file of files) {
|
15
|
+
if (file.isDirectory()) {
|
16
|
+
const result = findAppwriteConfig(path.join(dir, file.name));
|
17
|
+
if (result) return result;
|
18
|
+
} else if (file.name === "appwriteConfig.ts") {
|
19
|
+
return path.join(dir, file.name);
|
20
|
+
}
|
21
|
+
}
|
22
|
+
|
23
|
+
return null;
|
24
|
+
};
|
25
|
+
|
26
|
+
/**
|
27
|
+
* Loads the Appwrite configuration and all collection configurations from a specified directory.
|
28
|
+
* @param configDir The directory containing the appwriteConfig.ts and collections folder.
|
29
|
+
* @returns The loaded Appwrite configuration including collections.
|
30
|
+
*/
|
31
|
+
export const loadConfig = async (
|
32
|
+
configDir: string
|
33
|
+
): Promise<AppwriteConfig> => {
|
34
|
+
const unregister = register(); // Register tsx enhancement
|
35
|
+
|
36
|
+
try {
|
37
|
+
const configPath = path.resolve(configDir, "appwriteConfig.ts");
|
38
|
+
const config = (await import(configPath)).default as AppwriteConfig;
|
39
|
+
|
40
|
+
const collectionsDir = path.resolve(configDir, "collections");
|
41
|
+
const collectionFiles = fs.readdirSync(collectionsDir);
|
42
|
+
|
43
|
+
config.collections = [];
|
44
|
+
|
45
|
+
for (const file of collectionFiles) {
|
46
|
+
const filePath = path.resolve(collectionsDir, file);
|
47
|
+
const collectionModule = (await import(filePath)).default as Collection;
|
48
|
+
config.collections.push(collectionModule);
|
49
|
+
}
|
50
|
+
|
51
|
+
return config;
|
52
|
+
} finally {
|
53
|
+
unregister(); // Unregister tsx when done
|
54
|
+
}
|
55
|
+
};
|