appwrite-utils-cli 1.0.5 → 1.0.7
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 +96 -0
- package/dist/config/yamlConfig.js +0 -9
- package/dist/interactiveCLI.d.ts +1 -0
- package/dist/interactiveCLI.js +83 -17
- package/dist/main.js +43 -0
- package/dist/utils/constantsGenerator.d.ts +19 -0
- package/dist/utils/constantsGenerator.js +309 -0
- package/dist/utils/loadConfigs.js +5 -5
- package/package.json +1 -1
- package/src/config/yamlConfig.ts +0 -9
- package/src/interactiveCLI.ts +90 -17
- package/src/main.ts +53 -0
- package/src/utils/constantsGenerator.ts +352 -0
- package/src/utils/loadConfigs.ts +6 -5
@@ -0,0 +1,352 @@
|
|
1
|
+
import fs from "fs/promises";
|
2
|
+
import path from "path";
|
3
|
+
import { type AppwriteConfig } from "appwrite-utils";
|
4
|
+
import { MessageFormatter } from "../shared/messageFormatter.js";
|
5
|
+
|
6
|
+
export type SupportedLanguage =
|
7
|
+
| "typescript"
|
8
|
+
| "javascript"
|
9
|
+
| "python"
|
10
|
+
| "php"
|
11
|
+
| "dart"
|
12
|
+
| "json"
|
13
|
+
| "env";
|
14
|
+
|
15
|
+
interface Constants {
|
16
|
+
databases: Record<string, string>;
|
17
|
+
collections: Record<string, string>;
|
18
|
+
buckets: Record<string, string>;
|
19
|
+
functions: Record<string, string>;
|
20
|
+
}
|
21
|
+
|
22
|
+
export class ConstantsGenerator {
|
23
|
+
private config: AppwriteConfig;
|
24
|
+
private constants: Constants;
|
25
|
+
|
26
|
+
constructor(config: AppwriteConfig) {
|
27
|
+
this.config = config;
|
28
|
+
this.constants = this.extractConstants();
|
29
|
+
}
|
30
|
+
|
31
|
+
private extractConstants(): Constants {
|
32
|
+
const constants: Constants = {
|
33
|
+
databases: {},
|
34
|
+
collections: {},
|
35
|
+
buckets: {},
|
36
|
+
functions: {}
|
37
|
+
};
|
38
|
+
|
39
|
+
// Extract database IDs
|
40
|
+
this.config.databases?.forEach(db => {
|
41
|
+
if (db.$id) {
|
42
|
+
const key = this.toConstantName(db.name || db.$id);
|
43
|
+
constants.databases[key] = db.$id;
|
44
|
+
}
|
45
|
+
});
|
46
|
+
|
47
|
+
// Extract collection IDs
|
48
|
+
this.config.collections?.forEach(collection => {
|
49
|
+
if (collection.$id) {
|
50
|
+
const key = this.toConstantName(collection.name || collection.$id);
|
51
|
+
constants.collections[key] = collection.$id;
|
52
|
+
}
|
53
|
+
});
|
54
|
+
|
55
|
+
// Extract bucket IDs
|
56
|
+
this.config.buckets?.forEach(bucket => {
|
57
|
+
if (bucket.$id) {
|
58
|
+
const key = this.toConstantName(bucket.name || bucket.$id);
|
59
|
+
constants.buckets[key] = bucket.$id;
|
60
|
+
}
|
61
|
+
});
|
62
|
+
|
63
|
+
// Extract function IDs
|
64
|
+
this.config.functions?.forEach(func => {
|
65
|
+
if (func.$id) {
|
66
|
+
const key = this.toConstantName(func.name || func.$id);
|
67
|
+
constants.functions[key] = func.$id;
|
68
|
+
}
|
69
|
+
});
|
70
|
+
|
71
|
+
return constants;
|
72
|
+
}
|
73
|
+
|
74
|
+
private toConstantName(name: string): string {
|
75
|
+
return name
|
76
|
+
.replace(/[^a-zA-Z0-9]/g, '_')
|
77
|
+
.replace(/_+/g, '_')
|
78
|
+
.replace(/^_|_$/g, '')
|
79
|
+
.toUpperCase();
|
80
|
+
}
|
81
|
+
|
82
|
+
private toCamelCase(name: string): string {
|
83
|
+
return name
|
84
|
+
.toLowerCase()
|
85
|
+
.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
|
86
|
+
}
|
87
|
+
|
88
|
+
private toSnakeCase(name: string): string {
|
89
|
+
return name.toLowerCase();
|
90
|
+
}
|
91
|
+
|
92
|
+
generateTypeScript(): string {
|
93
|
+
const { databases, collections, buckets, functions } = this.constants;
|
94
|
+
|
95
|
+
return `// Auto-generated Appwrite constants
|
96
|
+
// Generated on ${new Date().toISOString()}
|
97
|
+
|
98
|
+
export const DATABASE_IDS = {
|
99
|
+
${Object.entries(databases).map(([key, value]) => ` ${key}: "${value}"`).join(',\n')}
|
100
|
+
} as const;
|
101
|
+
|
102
|
+
export const COLLECTION_IDS = {
|
103
|
+
${Object.entries(collections).map(([key, value]) => ` ${key}: "${value}"`).join(',\n')}
|
104
|
+
} as const;
|
105
|
+
|
106
|
+
export const BUCKET_IDS = {
|
107
|
+
${Object.entries(buckets).map(([key, value]) => ` ${key}: "${value}"`).join(',\n')}
|
108
|
+
} as const;
|
109
|
+
|
110
|
+
export const FUNCTION_IDS = {
|
111
|
+
${Object.entries(functions).map(([key, value]) => ` ${key}: "${value}"`).join(',\n')}
|
112
|
+
} as const;
|
113
|
+
|
114
|
+
// Type helpers
|
115
|
+
export type DatabaseId = typeof DATABASE_IDS[keyof typeof DATABASE_IDS];
|
116
|
+
export type CollectionId = typeof COLLECTION_IDS[keyof typeof COLLECTION_IDS];
|
117
|
+
export type BucketId = typeof BUCKET_IDS[keyof typeof BUCKET_IDS];
|
118
|
+
export type FunctionId = typeof FUNCTION_IDS[keyof typeof FUNCTION_IDS];
|
119
|
+
|
120
|
+
// Helper objects for runtime use
|
121
|
+
export const ALL_DATABASE_IDS = Object.values(DATABASE_IDS);
|
122
|
+
export const ALL_COLLECTION_IDS = Object.values(COLLECTION_IDS);
|
123
|
+
export const ALL_BUCKET_IDS = Object.values(BUCKET_IDS);
|
124
|
+
export const ALL_FUNCTION_IDS = Object.values(FUNCTION_IDS);
|
125
|
+
`;
|
126
|
+
}
|
127
|
+
|
128
|
+
generateJavaScript(): string {
|
129
|
+
const { databases, collections, buckets, functions } = this.constants;
|
130
|
+
|
131
|
+
return `// Auto-generated Appwrite constants
|
132
|
+
// Generated on ${new Date().toISOString()}
|
133
|
+
|
134
|
+
export const DATABASE_IDS = {
|
135
|
+
${Object.entries(databases).map(([key, value]) => ` ${key}: "${value}"`).join(',\n')}
|
136
|
+
};
|
137
|
+
|
138
|
+
export const COLLECTION_IDS = {
|
139
|
+
${Object.entries(collections).map(([key, value]) => ` ${key}: "${value}"`).join(',\n')}
|
140
|
+
};
|
141
|
+
|
142
|
+
export const BUCKET_IDS = {
|
143
|
+
${Object.entries(buckets).map(([key, value]) => ` ${key}: "${value}"`).join(',\n')}
|
144
|
+
};
|
145
|
+
|
146
|
+
export const FUNCTION_IDS = {
|
147
|
+
${Object.entries(functions).map(([key, value]) => ` ${key}: "${value}"`).join(',\n')}
|
148
|
+
};
|
149
|
+
|
150
|
+
// Helper arrays for runtime use
|
151
|
+
export const ALL_DATABASE_IDS = Object.values(DATABASE_IDS);
|
152
|
+
export const ALL_COLLECTION_IDS = Object.values(COLLECTION_IDS);
|
153
|
+
export const ALL_BUCKET_IDS = Object.values(BUCKET_IDS);
|
154
|
+
export const ALL_FUNCTION_IDS = Object.values(FUNCTION_IDS);
|
155
|
+
`;
|
156
|
+
}
|
157
|
+
|
158
|
+
generatePython(): string {
|
159
|
+
const { databases, collections, buckets, functions } = this.constants;
|
160
|
+
|
161
|
+
return `# Auto-generated Appwrite constants
|
162
|
+
# Generated on ${new Date().toISOString()}
|
163
|
+
|
164
|
+
class DatabaseIds:
|
165
|
+
"""Database ID constants"""
|
166
|
+
${Object.entries(databases).map(([key, value]) => ` ${key} = "${value}"`).join('\n')}
|
167
|
+
|
168
|
+
class CollectionIds:
|
169
|
+
"""Collection ID constants"""
|
170
|
+
${Object.entries(collections).map(([key, value]) => ` ${key} = "${value}"`).join('\n')}
|
171
|
+
|
172
|
+
class BucketIds:
|
173
|
+
"""Bucket ID constants"""
|
174
|
+
${Object.entries(buckets).map(([key, value]) => ` ${key} = "${value}"`).join('\n')}
|
175
|
+
|
176
|
+
class FunctionIds:
|
177
|
+
"""Function ID constants"""
|
178
|
+
${Object.entries(functions).map(([key, value]) => ` ${key} = "${value}"`).join('\n')}
|
179
|
+
|
180
|
+
# Helper dictionaries for runtime use
|
181
|
+
DATABASE_ID_MAP = {
|
182
|
+
${Object.entries(databases).map(([key, value]) => ` "${this.toSnakeCase(key)}": "${value}"`).join(',\n')}
|
183
|
+
}
|
184
|
+
|
185
|
+
COLLECTION_ID_MAP = {
|
186
|
+
${Object.entries(collections).map(([key, value]) => ` "${this.toSnakeCase(key)}": "${value}"`).join(',\n')}
|
187
|
+
}
|
188
|
+
|
189
|
+
BUCKET_ID_MAP = {
|
190
|
+
${Object.entries(buckets).map(([key, value]) => ` "${this.toSnakeCase(key)}": "${value}"`).join(',\n')}
|
191
|
+
}
|
192
|
+
|
193
|
+
FUNCTION_ID_MAP = {
|
194
|
+
${Object.entries(functions).map(([key, value]) => ` "${this.toSnakeCase(key)}": "${value}"`).join(',\n')}
|
195
|
+
}
|
196
|
+
`;
|
197
|
+
}
|
198
|
+
|
199
|
+
generatePHP(): string {
|
200
|
+
const { databases, collections, buckets, functions } = this.constants;
|
201
|
+
|
202
|
+
return `<?php
|
203
|
+
// Auto-generated Appwrite constants
|
204
|
+
// Generated on ${new Date().toISOString()}
|
205
|
+
|
206
|
+
class AppwriteConstants {
|
207
|
+
|
208
|
+
const DATABASE_IDS = [
|
209
|
+
${Object.entries(databases).map(([key, value]) => ` '${key}' => '${value}'`).join(',\n')}
|
210
|
+
];
|
211
|
+
|
212
|
+
const COLLECTION_IDS = [
|
213
|
+
${Object.entries(collections).map(([key, value]) => ` '${key}' => '${value}'`).join(',\n')}
|
214
|
+
];
|
215
|
+
|
216
|
+
const BUCKET_IDS = [
|
217
|
+
${Object.entries(buckets).map(([key, value]) => ` '${key}' => '${value}'`).join(',\n')}
|
218
|
+
];
|
219
|
+
|
220
|
+
const FUNCTION_IDS = [
|
221
|
+
${Object.entries(functions).map(([key, value]) => ` '${key}' => '${value}'`).join(',\n')}
|
222
|
+
];
|
223
|
+
|
224
|
+
/**
|
225
|
+
* Get all database IDs as array
|
226
|
+
*/
|
227
|
+
public static function getAllDatabaseIds(): array {
|
228
|
+
return array_values(self::DATABASE_IDS);
|
229
|
+
}
|
230
|
+
|
231
|
+
/**
|
232
|
+
* Get all collection IDs as array
|
233
|
+
*/
|
234
|
+
public static function getAllCollectionIds(): array {
|
235
|
+
return array_values(self::COLLECTION_IDS);
|
236
|
+
}
|
237
|
+
|
238
|
+
/**
|
239
|
+
* Get all bucket IDs as array
|
240
|
+
*/
|
241
|
+
public static function getAllBucketIds(): array {
|
242
|
+
return array_values(self::BUCKET_IDS);
|
243
|
+
}
|
244
|
+
|
245
|
+
/**
|
246
|
+
* Get all function IDs as array
|
247
|
+
*/
|
248
|
+
public static function getAllFunctionIds(): array {
|
249
|
+
return array_values(self::FUNCTION_IDS);
|
250
|
+
}
|
251
|
+
}
|
252
|
+
`;
|
253
|
+
}
|
254
|
+
|
255
|
+
generateDart(): string {
|
256
|
+
const { databases, collections, buckets, functions } = this.constants;
|
257
|
+
|
258
|
+
return `// Auto-generated Appwrite constants
|
259
|
+
// Generated on ${new Date().toISOString()}
|
260
|
+
|
261
|
+
class AppwriteConstants {
|
262
|
+
|
263
|
+
static const Map<String, String> databaseIds = {
|
264
|
+
${Object.entries(databases).map(([key, value]) => ` '${this.toCamelCase(key)}': '${value}'`).join(',\n')}
|
265
|
+
};
|
266
|
+
|
267
|
+
static const Map<String, String> collectionIds = {
|
268
|
+
${Object.entries(collections).map(([key, value]) => ` '${this.toCamelCase(key)}': '${value}'`).join(',\n')}
|
269
|
+
};
|
270
|
+
|
271
|
+
static const Map<String, String> bucketIds = {
|
272
|
+
${Object.entries(buckets).map(([key, value]) => ` '${this.toCamelCase(key)}': '${value}'`).join(',\n')}
|
273
|
+
};
|
274
|
+
|
275
|
+
static const Map<String, String> functionIds = {
|
276
|
+
${Object.entries(functions).map(([key, value]) => ` '${this.toCamelCase(key)}': '${value}'`).join(',\n')}
|
277
|
+
};
|
278
|
+
|
279
|
+
// Helper getters for individual IDs
|
280
|
+
${Object.entries(databases).map(([key, value]) => ` static String get ${this.toCamelCase(key)}DatabaseId => '${value}';`).join('\n')}
|
281
|
+
|
282
|
+
${Object.entries(collections).map(([key, value]) => ` static String get ${this.toCamelCase(key)}CollectionId => '${value}';`).join('\n')}
|
283
|
+
|
284
|
+
${Object.entries(buckets).map(([key, value]) => ` static String get ${this.toCamelCase(key)}BucketId => '${value}';`).join('\n')}
|
285
|
+
|
286
|
+
${Object.entries(functions).map(([key, value]) => ` static String get ${this.toCamelCase(key)}FunctionId => '${value}';`).join('\n')}
|
287
|
+
}
|
288
|
+
`;
|
289
|
+
}
|
290
|
+
|
291
|
+
generateJSON(): string {
|
292
|
+
return JSON.stringify({
|
293
|
+
meta: {
|
294
|
+
generated: new Date().toISOString(),
|
295
|
+
generator: "appwrite-utils-cli"
|
296
|
+
},
|
297
|
+
databases: this.constants.databases,
|
298
|
+
collections: this.constants.collections,
|
299
|
+
buckets: this.constants.buckets,
|
300
|
+
functions: this.constants.functions
|
301
|
+
}, null, 2);
|
302
|
+
}
|
303
|
+
|
304
|
+
generateEnv(): string {
|
305
|
+
const { databases, collections, buckets, functions } = this.constants;
|
306
|
+
|
307
|
+
const lines = [
|
308
|
+
"# Auto-generated Appwrite constants",
|
309
|
+
`# Generated on ${new Date().toISOString()}`,
|
310
|
+
"",
|
311
|
+
"# Database IDs",
|
312
|
+
...Object.entries(databases).map(([key, value]) => `DATABASE_${key}=${value}`),
|
313
|
+
"",
|
314
|
+
"# Collection IDs",
|
315
|
+
...Object.entries(collections).map(([key, value]) => `COLLECTION_${key}=${value}`),
|
316
|
+
"",
|
317
|
+
"# Bucket IDs",
|
318
|
+
...Object.entries(buckets).map(([key, value]) => `BUCKET_${key}=${value}`),
|
319
|
+
"",
|
320
|
+
"# Function IDs",
|
321
|
+
...Object.entries(functions).map(([key, value]) => `FUNCTION_${key}=${value}`)
|
322
|
+
];
|
323
|
+
|
324
|
+
return lines.join('\n');
|
325
|
+
}
|
326
|
+
|
327
|
+
async generateFiles(languages: SupportedLanguage[], outputDir: string): Promise<void> {
|
328
|
+
await fs.mkdir(outputDir, { recursive: true });
|
329
|
+
|
330
|
+
const generators = {
|
331
|
+
typescript: () => ({ content: this.generateTypeScript(), filename: "appwrite-constants.ts" }),
|
332
|
+
javascript: () => ({ content: this.generateJavaScript(), filename: "appwrite-constants.js" }),
|
333
|
+
python: () => ({ content: this.generatePython(), filename: "appwrite_constants.py" }),
|
334
|
+
php: () => ({ content: this.generatePHP(), filename: "AppwriteConstants.php" }),
|
335
|
+
dart: () => ({ content: this.generateDart(), filename: "appwrite_constants.dart" }),
|
336
|
+
json: () => ({ content: this.generateJSON(), filename: "appwrite-constants.json" }),
|
337
|
+
env: () => ({ content: this.generateEnv(), filename: ".env.appwrite" })
|
338
|
+
};
|
339
|
+
|
340
|
+
for (const language of languages) {
|
341
|
+
const generator = generators[language];
|
342
|
+
if (generator) {
|
343
|
+
const { content, filename } = generator();
|
344
|
+
const filePath = path.join(outputDir, filename);
|
345
|
+
await fs.writeFile(filePath, content, 'utf-8');
|
346
|
+
MessageFormatter.success(`Generated ${language} constants: ${filePath}`, { prefix: "Constants" });
|
347
|
+
} else {
|
348
|
+
MessageFormatter.error(`Unsupported language: ${language}`, undefined, { prefix: "Constants" });
|
349
|
+
}
|
350
|
+
}
|
351
|
+
}
|
352
|
+
}
|
package/src/utils/loadConfigs.ts
CHANGED
@@ -7,6 +7,7 @@ import chalk from "chalk";
|
|
7
7
|
import { findYamlConfig, loadYamlConfig } from "../config/yamlConfig.js";
|
8
8
|
import yaml from "js-yaml";
|
9
9
|
import { z } from "zod";
|
10
|
+
import { MessageFormatter } from "../shared/messageFormatter.js";
|
10
11
|
|
11
12
|
/**
|
12
13
|
* Recursively searches for configuration files starting from the given directory.
|
@@ -88,7 +89,6 @@ const findAppwriteConfigTS = (dir: string, depth: number = 0): string | null =>
|
|
88
89
|
// First check current directory for appwriteConfig.ts
|
89
90
|
for (const entry of entries) {
|
90
91
|
if (entry.isFile() && entry.name === "appwriteConfig.ts") {
|
91
|
-
console.log(`Found appwriteConfig.ts at: ${path.join(dir, entry.name)}`);
|
92
92
|
return path.join(dir, entry.name);
|
93
93
|
}
|
94
94
|
}
|
@@ -102,7 +102,6 @@ const findAppwriteConfigTS = (dir: string, depth: number = 0): string | null =>
|
|
102
102
|
}
|
103
103
|
} catch (error) {
|
104
104
|
// Ignore directory access errors
|
105
|
-
console.log(`Error accessing directory ${dir}:`, error);
|
106
105
|
}
|
107
106
|
|
108
107
|
return null;
|
@@ -149,7 +148,6 @@ export const loadConfigWithPath = async (
|
|
149
148
|
const unregister = register(); // Register tsx enhancement
|
150
149
|
|
151
150
|
try {
|
152
|
-
console.log(`Loading TypeScript config from: ${configPath}`);
|
153
151
|
const configUrl = pathToFileURL(configPath).href;
|
154
152
|
const configModule = (await import(configUrl));
|
155
153
|
config = configModule.default?.default || configModule.default || configModule;
|
@@ -239,7 +237,6 @@ export const loadConfig = async (
|
|
239
237
|
// First try to find and load YAML config
|
240
238
|
const yamlConfigPath = findYamlConfig(configDir);
|
241
239
|
if (yamlConfigPath) {
|
242
|
-
console.log(`Loading YAML config from: ${yamlConfigPath}`);
|
243
240
|
config = await loadYamlConfig(yamlConfigPath);
|
244
241
|
actualConfigPath = yamlConfigPath;
|
245
242
|
}
|
@@ -253,7 +250,6 @@ export const loadConfig = async (
|
|
253
250
|
const unregister = register(); // Register tsx enhancement
|
254
251
|
|
255
252
|
try {
|
256
|
-
console.log(`Loading TypeScript config from: ${configPath}`);
|
257
253
|
const configUrl = pathToFileURL(configPath).href;
|
258
254
|
const configModule = (await import(configUrl));
|
259
255
|
config = configModule.default?.default || configModule.default || configModule;
|
@@ -332,6 +328,11 @@ export const loadConfig = async (
|
|
332
328
|
config.collections = config.collections || [];
|
333
329
|
}
|
334
330
|
|
331
|
+
// Log successful config loading
|
332
|
+
if (actualConfigPath) {
|
333
|
+
MessageFormatter.success(`Loaded config from: ${actualConfigPath}`, { prefix: "Config" });
|
334
|
+
}
|
335
|
+
|
335
336
|
return config;
|
336
337
|
};
|
337
338
|
|