appwrite-utils-cli 0.10.86 → 1.0.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.
- 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 +264 -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 +262 -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 +379 -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 +349 -0
- package/src/utils/loadConfigs.ts +416 -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
@@ -67,7 +67,7 @@ export const validationRules = {
|
|
67
67
|
isDate: (value: any): boolean => isDate(value),
|
68
68
|
isEmpty: (value: any): boolean => isEmpty(value),
|
69
69
|
isInteger: (value: any): boolean => isInteger(value),
|
70
|
-
isFloat: (value: any): boolean => isNumber(value) && !isInteger(value),
|
70
|
+
isFloat: (value: any): boolean => isNumber(value) && !isInteger(value), // Note: Works for double precision numbers
|
71
71
|
isArrayLike: (value: any): boolean => isArrayLike(value),
|
72
72
|
isArrayLikeObject: (value: any): boolean => isArrayLikeObject(value),
|
73
73
|
isFunction: (value: any): boolean => isFunction(value),
|
@@ -0,0 +1,131 @@
|
|
1
|
+
import yaml from "js-yaml";
|
2
|
+
import type { Collection, CollectionCreate } from "appwrite-utils";
|
3
|
+
|
4
|
+
export interface YamlCollectionData {
|
5
|
+
name: string;
|
6
|
+
id?: string;
|
7
|
+
documentSecurity?: boolean;
|
8
|
+
enabled?: boolean;
|
9
|
+
permissions?: Array<{
|
10
|
+
permission: string;
|
11
|
+
target: string;
|
12
|
+
}>;
|
13
|
+
attributes?: Array<{
|
14
|
+
key: string;
|
15
|
+
type: string;
|
16
|
+
size?: number;
|
17
|
+
required?: boolean;
|
18
|
+
array?: boolean;
|
19
|
+
default?: any;
|
20
|
+
description?: string;
|
21
|
+
min?: number;
|
22
|
+
max?: number;
|
23
|
+
elements?: string[];
|
24
|
+
relatedCollection?: string;
|
25
|
+
relationType?: string;
|
26
|
+
twoWay?: boolean;
|
27
|
+
twoWayKey?: string;
|
28
|
+
onDelete?: string;
|
29
|
+
side?: string;
|
30
|
+
}>;
|
31
|
+
indexes?: Array<{
|
32
|
+
key: string;
|
33
|
+
type: string;
|
34
|
+
attributes: string[];
|
35
|
+
orders?: string[];
|
36
|
+
}>;
|
37
|
+
importDefs?: any[];
|
38
|
+
}
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Converts a Collection object to YAML format with proper schema reference
|
42
|
+
*/
|
43
|
+
export function collectionToYaml(collection: Collection | CollectionCreate, schemaPath = "../.yaml_schemas/collection.schema.json"): string {
|
44
|
+
// Convert Collection to YamlCollectionData format
|
45
|
+
const yamlData: YamlCollectionData = {
|
46
|
+
name: collection.name,
|
47
|
+
id: collection.$id,
|
48
|
+
documentSecurity: collection.documentSecurity,
|
49
|
+
enabled: collection.enabled,
|
50
|
+
};
|
51
|
+
|
52
|
+
// Convert permissions
|
53
|
+
if (collection.$permissions && collection.$permissions.length > 0) {
|
54
|
+
yamlData.permissions = collection.$permissions.map(p => ({
|
55
|
+
permission: p.permission,
|
56
|
+
target: p.target
|
57
|
+
}));
|
58
|
+
}
|
59
|
+
|
60
|
+
// Convert attributes
|
61
|
+
if (collection.attributes && collection.attributes.length > 0) {
|
62
|
+
yamlData.attributes = collection.attributes.map(attr => {
|
63
|
+
const yamlAttr: any = {
|
64
|
+
key: attr.key,
|
65
|
+
type: attr.type,
|
66
|
+
};
|
67
|
+
|
68
|
+
// Add optional properties only if they exist (safely access with 'in' operator)
|
69
|
+
if ('size' in attr && attr.size !== undefined) yamlAttr.size = attr.size;
|
70
|
+
if (attr.required !== undefined) yamlAttr.required = attr.required;
|
71
|
+
if (attr.array !== undefined) yamlAttr.array = attr.array;
|
72
|
+
if ('xdefault' in attr && attr.xdefault !== undefined) yamlAttr.default = attr.xdefault;
|
73
|
+
if (attr.description !== undefined) yamlAttr.description = attr.description;
|
74
|
+
if ('min' in attr && attr.min !== undefined) yamlAttr.min = attr.min;
|
75
|
+
if ('max' in attr && attr.max !== undefined) yamlAttr.max = attr.max;
|
76
|
+
if ('elements' in attr && attr.elements !== undefined) yamlAttr.elements = attr.elements;
|
77
|
+
if ('relatedCollection' in attr && attr.relatedCollection !== undefined) yamlAttr.relatedCollection = attr.relatedCollection;
|
78
|
+
if ('relationType' in attr && attr.relationType !== undefined) yamlAttr.relationType = attr.relationType;
|
79
|
+
if ('twoWay' in attr && attr.twoWay !== undefined) yamlAttr.twoWay = attr.twoWay;
|
80
|
+
if ('twoWayKey' in attr && attr.twoWayKey !== undefined) yamlAttr.twoWayKey = attr.twoWayKey;
|
81
|
+
if ('onDelete' in attr && attr.onDelete !== undefined) yamlAttr.onDelete = attr.onDelete;
|
82
|
+
if ('side' in attr && attr.side !== undefined) yamlAttr.side = attr.side;
|
83
|
+
|
84
|
+
return yamlAttr;
|
85
|
+
});
|
86
|
+
}
|
87
|
+
|
88
|
+
// Convert indexes
|
89
|
+
if (collection.indexes && collection.indexes.length > 0) {
|
90
|
+
yamlData.indexes = collection.indexes.map(idx => ({
|
91
|
+
key: idx.key,
|
92
|
+
type: idx.type,
|
93
|
+
attributes: idx.attributes,
|
94
|
+
...(idx.orders && idx.orders.length > 0 ? { orders: idx.orders } : {})
|
95
|
+
}));
|
96
|
+
}
|
97
|
+
|
98
|
+
// Add import definitions if they exist
|
99
|
+
if (collection.importDefs && collection.importDefs.length > 0) {
|
100
|
+
yamlData.importDefs = collection.importDefs;
|
101
|
+
} else {
|
102
|
+
yamlData.importDefs = [];
|
103
|
+
}
|
104
|
+
|
105
|
+
// Generate YAML with schema reference
|
106
|
+
const yamlContent = yaml.dump(yamlData, {
|
107
|
+
indent: 2,
|
108
|
+
lineWidth: 120,
|
109
|
+
sortKeys: false,
|
110
|
+
quotingType: '"',
|
111
|
+
forceQuotes: false,
|
112
|
+
});
|
113
|
+
|
114
|
+
return `# yaml-language-server: $schema=${schemaPath}
|
115
|
+
# Collection Definition: ${collection.name}
|
116
|
+
${yamlContent}`;
|
117
|
+
}
|
118
|
+
|
119
|
+
/**
|
120
|
+
* Sanitizes a collection name for use as a filename
|
121
|
+
*/
|
122
|
+
export function sanitizeFilename(name: string): string {
|
123
|
+
return name.replace(/[^a-zA-Z0-9_-]/g, '_');
|
124
|
+
}
|
125
|
+
|
126
|
+
/**
|
127
|
+
* Generates the filename for a collection YAML file
|
128
|
+
*/
|
129
|
+
export function getCollectionYamlFilename(collection: Collection | CollectionCreate): string {
|
130
|
+
return `${sanitizeFilename(collection.name)}.yaml`;
|
131
|
+
}
|
package/src/utilsController.ts
CHANGED
@@ -13,10 +13,11 @@ import {
|
|
13
13
|
} from "appwrite-utils";
|
14
14
|
import {
|
15
15
|
loadConfig,
|
16
|
+
loadConfigWithPath,
|
16
17
|
findAppwriteConfig,
|
17
18
|
findFunctionsDir,
|
18
19
|
} from "./utils/loadConfigs.js";
|
19
|
-
import { UsersController } from "./
|
20
|
+
import { UsersController } from "./users/methods.js";
|
20
21
|
import { AppwriteToX } from "./migrations/appwriteToX.js";
|
21
22
|
import { ImportController } from "./migrations/importController.js";
|
22
23
|
import { ImportDataActions } from "./migrations/importDataActions.js";
|
@@ -25,7 +26,7 @@ import {
|
|
25
26
|
ensureDatabasesExist,
|
26
27
|
wipeOtherDatabases,
|
27
28
|
ensureCollectionsExist,
|
28
|
-
} from "./
|
29
|
+
} from "./databases/setup.js";
|
29
30
|
import {
|
30
31
|
createOrUpdateCollections,
|
31
32
|
wipeDatabase,
|
@@ -57,7 +58,7 @@ import {
|
|
57
58
|
type TransferOptions,
|
58
59
|
} from "./migrations/transfer.js";
|
59
60
|
import { getClient } from "./utils/getClientFromConfig.js";
|
60
|
-
import { fetchAllDatabases } from "./
|
61
|
+
import { fetchAllDatabases } from "./databases/methods.js";
|
61
62
|
import {
|
62
63
|
listFunctions,
|
63
64
|
updateFunctionSpecifications,
|
@@ -65,6 +66,8 @@ import {
|
|
65
66
|
import chalk from "chalk";
|
66
67
|
import { deployLocalFunction } from "./functions/deployments.js";
|
67
68
|
import fs from "node:fs";
|
69
|
+
import { configureLogging, updateLogger } from "./shared/logging.js";
|
70
|
+
import { MessageFormatter, Messages } from "./shared/messageFormatter.js";
|
68
71
|
|
69
72
|
export interface SetupOptions {
|
70
73
|
databases?: Models.Database[];
|
@@ -105,15 +108,15 @@ export class UtilsController {
|
|
105
108
|
if (directConfig) {
|
106
109
|
let hasErrors = false;
|
107
110
|
if (!directConfig.appwriteEndpoint) {
|
108
|
-
|
111
|
+
MessageFormatter.error("Appwrite endpoint is required", undefined, { prefix: "Config" });
|
109
112
|
hasErrors = true;
|
110
113
|
}
|
111
114
|
if (!directConfig.appwriteProject) {
|
112
|
-
|
115
|
+
MessageFormatter.error("Appwrite project is required", undefined, { prefix: "Config" });
|
113
116
|
hasErrors = true;
|
114
117
|
}
|
115
118
|
if (!directConfig.appwriteKey) {
|
116
|
-
|
119
|
+
MessageFormatter.error("Appwrite key is required", undefined, { prefix: "Config" });
|
117
120
|
hasErrors = true;
|
118
121
|
}
|
119
122
|
if (!hasErrors) {
|
@@ -130,42 +133,56 @@ export class UtilsController {
|
|
130
133
|
enableMockData: false,
|
131
134
|
documentBucketId: "",
|
132
135
|
usersCollectionName: "",
|
136
|
+
useMigrations: true,
|
133
137
|
databases: [],
|
134
138
|
buckets: [],
|
135
139
|
functions: [],
|
140
|
+
logging: {
|
141
|
+
enabled: false,
|
142
|
+
level: "info",
|
143
|
+
console: false,
|
144
|
+
},
|
136
145
|
};
|
137
146
|
}
|
138
147
|
} else {
|
139
148
|
// Try to find config file
|
140
149
|
const appwriteConfigFound = findAppwriteConfig(basePath);
|
141
150
|
if (!appwriteConfigFound) {
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
)
|
151
|
+
MessageFormatter.warning(
|
152
|
+
"No appwriteConfig.ts found and no direct configuration provided",
|
153
|
+
{ prefix: "Config" }
|
146
154
|
);
|
147
155
|
return;
|
148
156
|
}
|
149
157
|
this.appwriteConfigPath = appwriteConfigFound;
|
150
|
-
this.appwriteFolderPath =
|
158
|
+
this.appwriteFolderPath = appwriteConfigFound; // For YAML configs, findAppwriteConfig already returns the correct directory
|
151
159
|
}
|
152
160
|
}
|
153
161
|
|
154
162
|
async init() {
|
155
163
|
if (!this.config) {
|
156
164
|
if (this.appwriteFolderPath && this.appwriteConfigPath) {
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
165
|
+
MessageFormatter.progress("Loading config from file...", { prefix: "Config" });
|
166
|
+
try {
|
167
|
+
const { config, actualConfigPath } = await loadConfigWithPath(this.appwriteFolderPath);
|
168
|
+
this.config = config;
|
169
|
+
MessageFormatter.info(`Loaded config from: ${actualConfigPath}`, { prefix: "Config" });
|
170
|
+
} catch (error) {
|
171
|
+
MessageFormatter.error("Failed to load config from file", undefined, { prefix: "Config" });
|
161
172
|
return;
|
162
173
|
}
|
163
174
|
} else {
|
164
|
-
|
175
|
+
MessageFormatter.error("No configuration available", undefined, { prefix: "Config" });
|
165
176
|
return;
|
166
177
|
}
|
167
178
|
}
|
168
179
|
|
180
|
+
// Configure logging based on config
|
181
|
+
if (this.config.logging) {
|
182
|
+
configureLogging(this.config.logging);
|
183
|
+
updateLogger();
|
184
|
+
}
|
185
|
+
|
169
186
|
this.appwriteServer = new Client();
|
170
187
|
this.appwriteServer
|
171
188
|
.setEndpoint(this.config.appwriteEndpoint)
|
@@ -179,7 +196,7 @@ export class UtilsController {
|
|
179
196
|
|
180
197
|
async reloadConfig() {
|
181
198
|
if (!this.appwriteFolderPath) {
|
182
|
-
|
199
|
+
MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
|
183
200
|
return;
|
184
201
|
}
|
185
202
|
this.config = await loadConfig(this.appwriteFolderPath);
|
@@ -187,6 +204,13 @@ export class UtilsController {
|
|
187
204
|
console.log(chalk.red("Failed to load config"));
|
188
205
|
return;
|
189
206
|
}
|
207
|
+
|
208
|
+
// Configure logging based on updated config
|
209
|
+
if (this.config.logging) {
|
210
|
+
configureLogging(this.config.logging);
|
211
|
+
updateLogger();
|
212
|
+
}
|
213
|
+
|
190
214
|
this.appwriteServer = new Client();
|
191
215
|
this.appwriteServer
|
192
216
|
.setEndpoint(this.config.appwriteEndpoint)
|
@@ -200,7 +224,7 @@ export class UtilsController {
|
|
200
224
|
async setupMigrationDatabase() {
|
201
225
|
await this.init();
|
202
226
|
if (!this.config) {
|
203
|
-
|
227
|
+
MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
|
204
228
|
return;
|
205
229
|
}
|
206
230
|
await setupMigrationDatabase(this.config);
|
@@ -209,11 +233,11 @@ export class UtilsController {
|
|
209
233
|
async ensureDatabaseConfigBucketsExist(databases: Models.Database[] = []) {
|
210
234
|
await this.init();
|
211
235
|
if (!this.storage) {
|
212
|
-
|
236
|
+
MessageFormatter.error("Storage not initialized", undefined, { prefix: "Controller" });
|
213
237
|
return;
|
214
238
|
}
|
215
239
|
if (!this.config) {
|
216
|
-
|
240
|
+
MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
|
217
241
|
return;
|
218
242
|
}
|
219
243
|
await ensureDatabaseConfigBucketsExist(
|
@@ -226,7 +250,7 @@ export class UtilsController {
|
|
226
250
|
async ensureDatabasesExist(databases?: Models.Database[]) {
|
227
251
|
await this.init();
|
228
252
|
if (!this.config) {
|
229
|
-
|
253
|
+
MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
|
230
254
|
return;
|
231
255
|
}
|
232
256
|
await this.setupMigrationDatabase();
|
@@ -240,7 +264,7 @@ export class UtilsController {
|
|
240
264
|
) {
|
241
265
|
await this.init();
|
242
266
|
if (!this.config) {
|
243
|
-
|
267
|
+
MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
|
244
268
|
return;
|
245
269
|
}
|
246
270
|
await ensureCollectionsExist(this.config, database, collections);
|
@@ -249,7 +273,7 @@ export class UtilsController {
|
|
249
273
|
async getDatabasesByIds(ids: string[]) {
|
250
274
|
await this.init();
|
251
275
|
if (!this.database) {
|
252
|
-
|
276
|
+
MessageFormatter.error("Database not initialized", undefined, { prefix: "Controller" });
|
253
277
|
return;
|
254
278
|
}
|
255
279
|
if (ids.length === 0) return [];
|
@@ -263,10 +287,10 @@ export class UtilsController {
|
|
263
287
|
async wipeOtherDatabases(databasesToKeep: Models.Database[]) {
|
264
288
|
await this.init();
|
265
289
|
if (!this.database) {
|
266
|
-
|
290
|
+
MessageFormatter.error("Database not initialized", undefined, { prefix: "Controller" });
|
267
291
|
return;
|
268
292
|
}
|
269
|
-
await wipeOtherDatabases(this.database, databasesToKeep);
|
293
|
+
await wipeOtherDatabases(this.database, databasesToKeep, this.config?.useMigrations ?? true);
|
270
294
|
}
|
271
295
|
|
272
296
|
async wipeUsers() {
|
@@ -307,7 +331,7 @@ export class UtilsController {
|
|
307
331
|
|
308
332
|
async findFunctionDirectories() {
|
309
333
|
if (!this.appwriteFolderPath) {
|
310
|
-
|
334
|
+
MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
|
311
335
|
return new Map();
|
312
336
|
}
|
313
337
|
const functionsDir = findFunctionsDir(this.appwriteFolderPath);
|
@@ -378,11 +402,11 @@ export class UtilsController {
|
|
378
402
|
]);
|
379
403
|
|
380
404
|
for (const localFunction of localFunctions) {
|
381
|
-
|
405
|
+
MessageFormatter.progress(`Syncing function ${localFunction.name}...`, { prefix: "Functions" });
|
382
406
|
await this.deployFunction(localFunction.name);
|
383
407
|
}
|
384
408
|
|
385
|
-
|
409
|
+
MessageFormatter.success("All functions synchronized successfully!", { prefix: "Functions" });
|
386
410
|
}
|
387
411
|
|
388
412
|
async wipeDatabase(database: Models.Database, wipeBucket: boolean = false) {
|
@@ -443,7 +467,7 @@ export class UtilsController {
|
|
443
467
|
if (!this.database || !this.config)
|
444
468
|
throw new Error("Database or config not initialized");
|
445
469
|
for (const database of databases) {
|
446
|
-
if (database.$id === "migrations") continue;
|
470
|
+
if (!this.config.useMigrations && database.$id === "migrations") continue;
|
447
471
|
await this.createOrUpdateCollections(database, undefined, collections);
|
448
472
|
}
|
449
473
|
}
|
@@ -468,11 +492,11 @@ export class UtilsController {
|
|
468
492
|
async generateSchemas() {
|
469
493
|
await this.init();
|
470
494
|
if (!this.config) {
|
471
|
-
|
495
|
+
MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
|
472
496
|
return;
|
473
497
|
}
|
474
498
|
if (!this.appwriteFolderPath) {
|
475
|
-
|
499
|
+
MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
|
476
500
|
return;
|
477
501
|
}
|
478
502
|
await generateSchemas(this.config, this.appwriteFolderPath);
|
@@ -481,19 +505,19 @@ export class UtilsController {
|
|
481
505
|
async importData(options: SetupOptions = {}) {
|
482
506
|
await this.init();
|
483
507
|
if (!this.database) {
|
484
|
-
|
508
|
+
MessageFormatter.error("Database not initialized", undefined, { prefix: "Controller" });
|
485
509
|
return;
|
486
510
|
}
|
487
511
|
if (!this.storage) {
|
488
|
-
|
512
|
+
MessageFormatter.error("Storage not initialized", undefined, { prefix: "Controller" });
|
489
513
|
return;
|
490
514
|
}
|
491
515
|
if (!this.config) {
|
492
|
-
|
516
|
+
MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
|
493
517
|
return;
|
494
518
|
}
|
495
519
|
if (!this.appwriteFolderPath) {
|
496
|
-
|
520
|
+
MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
|
497
521
|
return;
|
498
522
|
}
|
499
523
|
|
@@ -524,16 +548,16 @@ export class UtilsController {
|
|
524
548
|
) {
|
525
549
|
await this.init();
|
526
550
|
if (!this.storage) {
|
527
|
-
|
551
|
+
MessageFormatter.error("Storage not initialized", undefined, { prefix: "Controller" });
|
528
552
|
return;
|
529
553
|
}
|
530
554
|
const configToUse = config || this.config;
|
531
555
|
if (!configToUse) {
|
532
|
-
|
556
|
+
MessageFormatter.error("Config not initialized", undefined, { prefix: "Controller" });
|
533
557
|
return;
|
534
558
|
}
|
535
559
|
if (!this.appwriteFolderPath) {
|
536
|
-
|
560
|
+
MessageFormatter.error("Failed to get appwriteFolderPath", undefined, { prefix: "Controller" });
|
537
561
|
return;
|
538
562
|
}
|
539
563
|
const appwriteToX = new AppwriteToX(
|
@@ -550,7 +574,7 @@ export class UtilsController {
|
|
550
574
|
) {
|
551
575
|
await this.init();
|
552
576
|
if (!this.database) {
|
553
|
-
|
577
|
+
MessageFormatter.error("Database not initialized", undefined, { prefix: "Controller" });
|
554
578
|
return;
|
555
579
|
}
|
556
580
|
if (databases.length === 0) {
|
@@ -644,7 +668,7 @@ export class UtilsController {
|
|
644
668
|
console.log(chalk.red("Appwrite server not initialized"));
|
645
669
|
return;
|
646
670
|
} else {
|
647
|
-
|
671
|
+
MessageFormatter.progress("Starting user transfer...", { prefix: "Transfer" });
|
648
672
|
const localUsers = new Users(this.appwriteServer);
|
649
673
|
await transferUsersLocalToRemote(
|
650
674
|
localUsers,
|
@@ -652,7 +676,7 @@ export class UtilsController {
|
|
652
676
|
options.transferProject!,
|
653
677
|
options.transferKey!
|
654
678
|
);
|
655
|
-
|
679
|
+
MessageFormatter.success("User transfer completed", { prefix: "Transfer" });
|
656
680
|
}
|
657
681
|
}
|
658
682
|
|
@@ -677,10 +701,9 @@ export class UtilsController {
|
|
677
701
|
.replace(/\s+/g, "")}`);
|
678
702
|
|
679
703
|
if (sourceBucketId && targetBucketId) {
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
)
|
704
|
+
MessageFormatter.progress(
|
705
|
+
`Starting storage transfer from ${sourceBucketId} to ${targetBucketId}`,
|
706
|
+
{ prefix: "Transfer" }
|
684
707
|
);
|
685
708
|
|
686
709
|
if (options.isRemote) {
|
@@ -702,7 +725,7 @@ export class UtilsController {
|
|
702
725
|
}
|
703
726
|
}
|
704
727
|
|
705
|
-
|
728
|
+
MessageFormatter.success("Transfer completed", { prefix: "Transfer" });
|
706
729
|
}
|
707
730
|
|
708
731
|
async updateFunctionSpecifications(
|
@@ -712,20 +735,18 @@ export class UtilsController {
|
|
712
735
|
await this.init();
|
713
736
|
if (!this.appwriteServer)
|
714
737
|
throw new Error("Appwrite server not initialized");
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
)
|
738
|
+
MessageFormatter.progress(
|
739
|
+
`Updating function specifications for ${functionId} to ${specification}`,
|
740
|
+
{ prefix: "Functions" }
|
719
741
|
);
|
720
742
|
await updateFunctionSpecifications(
|
721
743
|
this.appwriteServer,
|
722
744
|
functionId,
|
723
745
|
specification
|
724
746
|
);
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
)
|
747
|
+
MessageFormatter.success(
|
748
|
+
`Successfully updated function specifications for ${functionId} to ${specification}`,
|
749
|
+
{ prefix: "Functions" }
|
729
750
|
);
|
730
751
|
}
|
731
752
|
}
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# Python Poetry Function Template
|
2
|
-
|
3
|
-
This is a Python template for Appwrite Functions using Poetry for dependency management.
|
4
|
-
|
5
|
-
## Structure
|
6
|
-
- `src/index.py`: Main function entry point
|
7
|
-
- `pyproject.toml`: Poetry configuration and dependencies
|
8
|
-
|
9
|
-
## Usage
|
10
|
-
Your function will receive a context object with:
|
11
|
-
- `req`: Request object containing request data, headers, and environment variables
|
12
|
-
- `res`: Response object for sending responses
|
13
|
-
- `log`: Function for logging (shows in your function logs)
|
14
|
-
- `error`: Function for error logging
|
15
|
-
|
16
|
-
## Example Request
|
17
|
-
```json
|
18
|
-
{
|
19
|
-
"key": "value"
|
20
|
-
}
|
21
|
-
```
|
22
|
-
|
23
|
-
## Development
|
24
|
-
1. Install Poetry: `curl -sSL https://install.python-poetry.org | python3 -`
|
25
|
-
2. Install dependencies: `poetry install`
|
26
|
-
3. Deploy: Dependencies will be installed during deployment
|
27
|
-
|
28
|
-
## Deployment
|
29
|
-
Make sure it's inside `appwriteConfig.ts` functions array, and if you want to install dependencies FIRST, before Appwrite (using your system), you can
|
30
|
-
add the `predeployCommands` to the function in `appwriteConfig.ts`.
|
@@ -1,16 +0,0 @@
|
|
1
|
-
[tool.poetry]
|
2
|
-
name = "{{functionName}}"
|
3
|
-
version = "0.1.0"
|
4
|
-
description = ""
|
5
|
-
authors = ["Your Name <you@example.com>"]
|
6
|
-
packages = [
|
7
|
-
{ include = "src" }
|
8
|
-
]
|
9
|
-
|
10
|
-
[tool.poetry.dependencies]
|
11
|
-
python = "^3.9"
|
12
|
-
appwrite = "^7.0.1"
|
13
|
-
|
14
|
-
[build-system]
|
15
|
-
requires = ["poetry-core>=1.0.0"]
|
16
|
-
build-backend = "poetry.core.masonry.api"
|