appwrite-utils-cli 1.6.2 → 1.6.4

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.
Files changed (62) hide show
  1. package/CONFIG_TODO.md +1189 -0
  2. package/SERVICE_IMPLEMENTATION_REPORT.md +462 -0
  3. package/dist/cli/commands/configCommands.js +7 -1
  4. package/dist/cli/commands/databaseCommands.js +23 -15
  5. package/dist/collections/attributes.d.ts +1 -1
  6. package/dist/collections/attributes.js +163 -66
  7. package/dist/collections/indexes.js +3 -17
  8. package/dist/collections/methods.js +38 -0
  9. package/dist/config/ConfigManager.d.ts +445 -0
  10. package/dist/config/ConfigManager.js +625 -0
  11. package/dist/config/index.d.ts +8 -0
  12. package/dist/config/index.js +7 -0
  13. package/dist/config/services/ConfigDiscoveryService.d.ts +126 -0
  14. package/dist/config/services/ConfigDiscoveryService.js +374 -0
  15. package/dist/config/services/ConfigLoaderService.d.ts +105 -0
  16. package/dist/config/services/ConfigLoaderService.js +410 -0
  17. package/dist/config/services/ConfigMergeService.d.ts +208 -0
  18. package/dist/config/services/ConfigMergeService.js +307 -0
  19. package/dist/config/services/ConfigValidationService.d.ts +214 -0
  20. package/dist/config/services/ConfigValidationService.js +310 -0
  21. package/dist/config/services/SessionAuthService.d.ts +225 -0
  22. package/dist/config/services/SessionAuthService.js +456 -0
  23. package/dist/config/services/__tests__/ConfigMergeService.test.d.ts +1 -0
  24. package/dist/config/services/__tests__/ConfigMergeService.test.js +271 -0
  25. package/dist/config/services/index.d.ts +13 -0
  26. package/dist/config/services/index.js +10 -0
  27. package/dist/interactiveCLI.js +8 -6
  28. package/dist/main.js +2 -2
  29. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +1 -1
  30. package/dist/shared/operationQueue.js +1 -1
  31. package/dist/utils/ClientFactory.d.ts +87 -0
  32. package/dist/utils/ClientFactory.js +164 -0
  33. package/dist/utils/getClientFromConfig.js +4 -3
  34. package/dist/utils/helperFunctions.d.ts +1 -0
  35. package/dist/utils/helperFunctions.js +21 -5
  36. package/dist/utils/yamlConverter.d.ts +2 -0
  37. package/dist/utils/yamlConverter.js +21 -4
  38. package/dist/utilsController.d.ts +18 -15
  39. package/dist/utilsController.js +83 -131
  40. package/package.json +1 -1
  41. package/src/cli/commands/configCommands.ts +8 -1
  42. package/src/cli/commands/databaseCommands.ts +34 -20
  43. package/src/collections/attributes.ts +195 -150
  44. package/src/collections/indexes.ts +4 -19
  45. package/src/collections/methods.ts +46 -0
  46. package/src/config/ConfigManager.ts +808 -0
  47. package/src/config/index.ts +10 -0
  48. package/src/config/services/ConfigDiscoveryService.ts +463 -0
  49. package/src/config/services/ConfigLoaderService.ts +560 -0
  50. package/src/config/services/ConfigMergeService.ts +386 -0
  51. package/src/config/services/ConfigValidationService.ts +394 -0
  52. package/src/config/services/SessionAuthService.ts +565 -0
  53. package/src/config/services/__tests__/ConfigMergeService.test.ts +351 -0
  54. package/src/config/services/index.ts +29 -0
  55. package/src/interactiveCLI.ts +9 -7
  56. package/src/main.ts +2 -2
  57. package/src/shared/operationQueue.ts +1 -1
  58. package/src/utils/ClientFactory.ts +186 -0
  59. package/src/utils/getClientFromConfig.ts +4 -3
  60. package/src/utils/helperFunctions.ts +27 -7
  61. package/src/utils/yamlConverter.ts +28 -2
  62. package/src/utilsController.ts +99 -187
@@ -0,0 +1,445 @@
1
+ import type { AppwriteConfig, Collection, CollectionCreate, AppwriteFunction } from "appwrite-utils";
2
+ import { type ConfigOverrides, type SessionAuthInfo, type AuthenticationStatus, type ValidationResult } from "./services/index.js";
3
+ /**
4
+ * Database type from AppwriteConfig
5
+ */
6
+ type Database = {
7
+ $id: string;
8
+ name: string;
9
+ bucket?: any;
10
+ };
11
+ /**
12
+ * Bucket type from AppwriteConfig
13
+ */
14
+ type Bucket = {
15
+ $id: string;
16
+ name: string;
17
+ $permissions?: any[];
18
+ [key: string]: any;
19
+ };
20
+ /**
21
+ * Options for loading configuration
22
+ */
23
+ export interface ConfigLoadOptions {
24
+ /**
25
+ * Directory to start searching for config files
26
+ * @default process.cwd()
27
+ */
28
+ configDir?: string;
29
+ /**
30
+ * Force reload configuration even if cached
31
+ * @default false
32
+ */
33
+ forceReload?: boolean;
34
+ /**
35
+ * Validate configuration after loading
36
+ * @default false
37
+ */
38
+ validate?: boolean;
39
+ /**
40
+ * Use strict validation mode (warnings as errors)
41
+ * @default false
42
+ */
43
+ strictMode?: boolean;
44
+ /**
45
+ * Report validation results to console
46
+ * @default false
47
+ */
48
+ reportValidation?: boolean;
49
+ /**
50
+ * Override configuration values
51
+ */
52
+ overrides?: ConfigOverrides;
53
+ /**
54
+ * Override session authentication (used for preserving session on reload)
55
+ */
56
+ sessionOverride?: SessionAuthInfo;
57
+ }
58
+ /**
59
+ * Filter function for collections (accepts both Collection and CollectionCreate)
60
+ */
61
+ export type CollectionFilter = (collection: Collection | CollectionCreate) => boolean;
62
+ /**
63
+ * Centralized configuration manager with intelligent caching and session management.
64
+ *
65
+ * This singleton provides a unified interface for:
66
+ * - Configuration discovery and loading (YAML, TypeScript, JSON)
67
+ * - Session authentication with automatic caching
68
+ * - Configuration validation and merging
69
+ * - Session preservation across reloads
70
+ * - File watching for configuration changes
71
+ *
72
+ * @example
73
+ * ```typescript
74
+ * const configManager = ConfigManager.getInstance();
75
+ *
76
+ * // Load configuration (cached after first call)
77
+ * const config = await configManager.loadConfig({
78
+ * validate: true,
79
+ * reportValidation: true,
80
+ * });
81
+ *
82
+ * // Get cached config synchronously
83
+ * const cachedConfig = configManager.getConfig();
84
+ *
85
+ * // Reload with session preservation
86
+ * const reloadedConfig = await configManager.reloadConfig();
87
+ *
88
+ * // Watch for config changes
89
+ * const unwatch = configManager.watchConfig(async (config) => {
90
+ * console.log("Config changed:", config);
91
+ * });
92
+ * ```
93
+ */
94
+ export declare class ConfigManager {
95
+ private static instance;
96
+ /**
97
+ * Get the ConfigManager singleton instance
98
+ *
99
+ * @returns The singleton ConfigManager instance
100
+ *
101
+ * @example
102
+ * ```typescript
103
+ * const configManager = ConfigManager.getInstance();
104
+ * ```
105
+ */
106
+ static getInstance(): ConfigManager;
107
+ /**
108
+ * Reset the singleton instance (useful for testing)
109
+ *
110
+ * @example
111
+ * ```typescript
112
+ * ConfigManager.resetInstance();
113
+ * const newInstance = ConfigManager.getInstance();
114
+ * ```
115
+ */
116
+ static resetInstance(): void;
117
+ private cachedConfig;
118
+ private cachedConfigPath;
119
+ private cachedSession;
120
+ private lastLoadTimestamp;
121
+ private isInitialized;
122
+ private discoveryService;
123
+ private loaderService;
124
+ private validationService;
125
+ private sessionService;
126
+ private mergeService;
127
+ /**
128
+ * Private constructor to enforce singleton pattern.
129
+ * Use ConfigManager.getInstance() instead.
130
+ */
131
+ private constructor();
132
+ /**
133
+ * Load configuration with intelligent caching and session management.
134
+ *
135
+ * This method orchestrates the entire configuration loading flow:
136
+ * 1. Returns cached config if available (unless forceReload is true)
137
+ * 2. Discovers config file using ConfigDiscoveryService
138
+ * 3. Loads config from file using ConfigLoaderService
139
+ * 4. Loads and merges session authentication using SessionAuthService
140
+ * 5. Applies CLI/environment overrides using ConfigMergeService
141
+ * 6. Validates configuration if requested
142
+ * 7. Caches the result for future calls
143
+ *
144
+ * @param options - Configuration loading options
145
+ * @returns The loaded and processed configuration
146
+ * @throws Error if no configuration file is found
147
+ * @throws Error if validation fails in strict mode
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * const config = await configManager.loadConfig({
152
+ * configDir: process.cwd(),
153
+ * validate: true,
154
+ * strictMode: true,
155
+ * reportValidation: true,
156
+ * overrides: {
157
+ * appwriteEndpoint: "https://custom.endpoint.com/v1"
158
+ * }
159
+ * });
160
+ * ```
161
+ */
162
+ loadConfig(options?: ConfigLoadOptions): Promise<AppwriteConfig>;
163
+ /**
164
+ * Get the cached configuration synchronously.
165
+ *
166
+ * @returns The cached configuration
167
+ * @throws Error if configuration has not been loaded yet
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * const config = configManager.getConfig();
172
+ * ```
173
+ */
174
+ getConfig(): AppwriteConfig;
175
+ /**
176
+ * Get the path to the loaded configuration file.
177
+ *
178
+ * @returns The configuration file path, or null if not loaded
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * const configPath = configManager.getConfigPath();
183
+ * console.log(`Config loaded from: ${configPath}`);
184
+ * ```
185
+ */
186
+ getConfigPath(): string | null;
187
+ /**
188
+ * Check if configuration has been loaded.
189
+ *
190
+ * @returns True if configuration is loaded and cached
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * if (!configManager.hasConfig()) {
195
+ * await configManager.loadConfig();
196
+ * }
197
+ * ```
198
+ */
199
+ hasConfig(): boolean;
200
+ /**
201
+ * Check if the ConfigManager has been initialized.
202
+ *
203
+ * @returns True if initialized (config loaded at least once)
204
+ *
205
+ * @example
206
+ * ```typescript
207
+ * if (configManager.isConfigInitialized()) {
208
+ * console.log("Config ready");
209
+ * }
210
+ * ```
211
+ */
212
+ isConfigInitialized(): boolean;
213
+ /**
214
+ * Invalidate the configuration cache.
215
+ * Next call to loadConfig() will reload from disk.
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * configManager.invalidateCache();
220
+ * const freshConfig = await configManager.loadConfig();
221
+ * ```
222
+ */
223
+ invalidateCache(): void;
224
+ /**
225
+ * Reload configuration from disk, preserving current session.
226
+ *
227
+ * This is a convenience method that combines invalidation and reloading
228
+ * while automatically preserving the current session authentication.
229
+ *
230
+ * @param options - Configuration loading options (forceReload is automatically set)
231
+ * @returns The reloaded configuration
232
+ *
233
+ * @example
234
+ * ```typescript
235
+ * // Reload config after manual file changes
236
+ * const config = await configManager.reloadConfig({
237
+ * validate: true,
238
+ * reportValidation: true
239
+ * });
240
+ * ```
241
+ */
242
+ reloadConfig(options?: Omit<ConfigLoadOptions, "forceReload">): Promise<AppwriteConfig>;
243
+ /**
244
+ * Get the current session information.
245
+ *
246
+ * @returns The cached session info, or null if no session
247
+ *
248
+ * @example
249
+ * ```typescript
250
+ * const session = configManager.getSession();
251
+ * if (session) {
252
+ * console.log(`Authenticated as: ${session.email}`);
253
+ * }
254
+ * ```
255
+ */
256
+ getSession(): SessionAuthInfo | null;
257
+ /**
258
+ * Check if a session is available.
259
+ *
260
+ * @returns True if a session is cached
261
+ *
262
+ * @example
263
+ * ```typescript
264
+ * if (configManager.hasSession()) {
265
+ * console.log("Using session authentication");
266
+ * } else {
267
+ * console.log("Using API key authentication");
268
+ * }
269
+ * ```
270
+ */
271
+ hasSession(): boolean;
272
+ /**
273
+ * Refresh session from disk (bypasses session cache).
274
+ *
275
+ * This forces SessionAuthService to reload from ~/.appwrite/prefs.json
276
+ * and update the cached session.
277
+ *
278
+ * @returns The refreshed session, or null if no session found
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * // After logging in via appwrite CLI
283
+ * const session = await configManager.refreshSession();
284
+ * if (session) {
285
+ * console.log("Session refreshed successfully");
286
+ * }
287
+ * ```
288
+ */
289
+ refreshSession(): Promise<SessionAuthInfo | null>;
290
+ /**
291
+ * Get authentication status for the current configuration.
292
+ *
293
+ * @returns Authentication status object with details about current auth method
294
+ * @throws Error if configuration has not been loaded
295
+ *
296
+ * @example
297
+ * ```typescript
298
+ * const authStatus = await configManager.getAuthStatus();
299
+ * console.log(`Auth method: ${authStatus.authMethod}`);
300
+ * console.log(`Has valid session: ${authStatus.hasValidSession}`);
301
+ * ```
302
+ */
303
+ getAuthStatus(): Promise<AuthenticationStatus>;
304
+ /**
305
+ * Clear the cached session.
306
+ * Next load will attempt to find a new session.
307
+ *
308
+ * @example
309
+ * ```typescript
310
+ * configManager.clearSession();
311
+ * const config = await configManager.reloadConfig();
312
+ * ```
313
+ */
314
+ clearSession(): void;
315
+ /**
316
+ * Validate the current configuration (warnings allowed).
317
+ *
318
+ * @param reportResults - Whether to report validation results to console
319
+ * @returns Validation result with errors and warnings
320
+ * @throws Error if configuration has not been loaded
321
+ *
322
+ * @example
323
+ * ```typescript
324
+ * const validation = configManager.validateConfig(true);
325
+ * if (!validation.isValid) {
326
+ * console.log(`Found ${validation.errors.length} errors`);
327
+ * }
328
+ * ```
329
+ */
330
+ validateConfig(reportResults?: boolean): ValidationResult;
331
+ /**
332
+ * Validate the current configuration in strict mode (warnings as errors).
333
+ *
334
+ * @param reportResults - Whether to report validation results to console
335
+ * @returns Validation result with errors and warnings (warnings treated as errors)
336
+ * @throws Error if configuration has not been loaded
337
+ *
338
+ * @example
339
+ * ```typescript
340
+ * const validation = configManager.validateConfigStrict(true);
341
+ * if (!validation.isValid) {
342
+ * console.log("Config validation failed (strict mode)");
343
+ * }
344
+ * ```
345
+ */
346
+ validateConfigStrict(reportResults?: boolean): ValidationResult;
347
+ /**
348
+ * Watch configuration file for changes and reload automatically.
349
+ *
350
+ * Returns a function to stop watching.
351
+ *
352
+ * @param callback - Function to call when config changes
353
+ * @returns Function to stop watching
354
+ *
355
+ * @example
356
+ * ```typescript
357
+ * const unwatch = configManager.watchConfig(async (config) => {
358
+ * console.log("Config changed, reloading...");
359
+ * // Handle config change
360
+ * });
361
+ *
362
+ * // Later, stop watching
363
+ * unwatch();
364
+ * ```
365
+ */
366
+ watchConfig(callback: (config: AppwriteConfig) => void | Promise<void>): () => void;
367
+ /**
368
+ * Merge overrides into the current configuration without persisting.
369
+ *
370
+ * This creates a new config object with overrides applied, without
371
+ * affecting the cached configuration.
372
+ *
373
+ * @param overrides - Configuration overrides to apply
374
+ * @returns New configuration with overrides applied
375
+ * @throws Error if configuration has not been loaded
376
+ *
377
+ * @example
378
+ * ```typescript
379
+ * const customConfig = configManager.mergeOverrides({
380
+ * appwriteEndpoint: "https://test.endpoint.com/v1"
381
+ * });
382
+ * ```
383
+ */
384
+ mergeOverrides(overrides: ConfigOverrides): AppwriteConfig;
385
+ /**
386
+ * Get collections from the configuration, optionally filtered.
387
+ *
388
+ * @param filter - Optional filter function for collections
389
+ * @returns Array of collections (or tables, depending on API mode)
390
+ *
391
+ * @example
392
+ * ```typescript
393
+ * // Get all collections
394
+ * const allCollections = configManager.getCollections();
395
+ *
396
+ * // Get enabled collections only
397
+ * const enabledCollections = configManager.getCollections(
398
+ * (c) => c.enabled !== false
399
+ * );
400
+ * ```
401
+ */
402
+ getCollections(filter?: CollectionFilter): (Collection | CollectionCreate)[];
403
+ /**
404
+ * Get databases from the configuration.
405
+ *
406
+ * @returns Array of databases
407
+ *
408
+ * @example
409
+ * ```typescript
410
+ * const databases = configManager.getDatabases();
411
+ * console.log(`Found ${databases.length} databases`);
412
+ * ```
413
+ */
414
+ getDatabases(): Database[];
415
+ /**
416
+ * Get buckets from the configuration.
417
+ *
418
+ * @returns Array of buckets
419
+ *
420
+ * @example
421
+ * ```typescript
422
+ * const buckets = configManager.getBuckets();
423
+ * console.log(`Found ${buckets.length} buckets`);
424
+ * ```
425
+ */
426
+ getBuckets(): Bucket[];
427
+ /**
428
+ * Get functions from the configuration.
429
+ *
430
+ * @returns Array of functions
431
+ *
432
+ * @example
433
+ * ```typescript
434
+ * const functions = configManager.getFunctions();
435
+ * console.log(`Found ${functions.length} functions`);
436
+ * ```
437
+ */
438
+ getFunctions(): AppwriteFunction[];
439
+ /**
440
+ * Get cached config with optional overrides applied.
441
+ * Used internally to avoid reloading when only overrides change.
442
+ */
443
+ private getCachedConfigWithOverrides;
444
+ }
445
+ export {};