appwrite-utils-cli 1.6.3 → 1.6.5
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/CONFIG_TODO.md +1189 -0
- package/SERVICE_IMPLEMENTATION_REPORT.md +462 -0
- package/dist/cli/commands/configCommands.js +7 -1
- package/dist/collections/attributes.js +102 -30
- package/dist/collections/indexes.js +6 -1
- package/dist/collections/methods.js +4 -5
- package/dist/config/ConfigManager.d.ts +445 -0
- package/dist/config/ConfigManager.js +625 -0
- package/dist/config/index.d.ts +8 -0
- package/dist/config/index.js +7 -0
- package/dist/config/services/ConfigDiscoveryService.d.ts +126 -0
- package/dist/config/services/ConfigDiscoveryService.js +374 -0
- package/dist/config/services/ConfigLoaderService.d.ts +105 -0
- package/dist/config/services/ConfigLoaderService.js +410 -0
- package/dist/config/services/ConfigMergeService.d.ts +208 -0
- package/dist/config/services/ConfigMergeService.js +307 -0
- package/dist/config/services/ConfigValidationService.d.ts +214 -0
- package/dist/config/services/ConfigValidationService.js +310 -0
- package/dist/config/services/SessionAuthService.d.ts +225 -0
- package/dist/config/services/SessionAuthService.js +456 -0
- package/dist/config/services/__tests__/ConfigMergeService.test.d.ts +1 -0
- package/dist/config/services/__tests__/ConfigMergeService.test.js +271 -0
- package/dist/config/services/index.d.ts +13 -0
- package/dist/config/services/index.js +10 -0
- package/dist/interactiveCLI.js +8 -6
- package/dist/main.js +14 -19
- package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +1 -1
- package/dist/shared/operationQueue.js +1 -1
- package/dist/utils/ClientFactory.d.ts +87 -0
- package/dist/utils/ClientFactory.js +164 -0
- package/dist/utils/getClientFromConfig.js +4 -3
- package/dist/utils/helperFunctions.d.ts +1 -0
- package/dist/utils/helperFunctions.js +21 -5
- package/dist/utils/yamlConverter.d.ts +2 -2
- package/dist/utils/yamlConverter.js +2 -2
- package/dist/utilsController.d.ts +18 -15
- package/dist/utilsController.js +83 -131
- package/package.json +1 -1
- package/src/cli/commands/configCommands.ts +8 -1
- package/src/collections/attributes.ts +118 -31
- package/src/collections/indexes.ts +7 -1
- package/src/collections/methods.ts +4 -6
- package/src/config/ConfigManager.ts +808 -0
- package/src/config/index.ts +10 -0
- package/src/config/services/ConfigDiscoveryService.ts +463 -0
- package/src/config/services/ConfigLoaderService.ts +560 -0
- package/src/config/services/ConfigMergeService.ts +386 -0
- package/src/config/services/ConfigValidationService.ts +394 -0
- package/src/config/services/SessionAuthService.ts +565 -0
- package/src/config/services/__tests__/ConfigMergeService.test.ts +351 -0
- package/src/config/services/index.ts +29 -0
- package/src/interactiveCLI.ts +9 -7
- package/src/main.ts +14 -24
- package/src/shared/operationQueue.ts +1 -1
- package/src/utils/ClientFactory.ts +186 -0
- package/src/utils/getClientFromConfig.ts +4 -3
- package/src/utils/helperFunctions.ts +27 -7
- package/src/utils/yamlConverter.ts +4 -4
- package/src/utilsController.ts +99 -187
@@ -68,7 +68,8 @@ export const checkForCollection = async (db, dbId, collection) => {
|
|
68
68
|
const items = isLegacyDatabases(db) ? response.collections : (response.tables || response.collections);
|
69
69
|
if (items && items.length > 0) {
|
70
70
|
MessageFormatter.info(`Collection found: ${items[0].$id}`, { prefix: "Collections" });
|
71
|
-
|
71
|
+
// Return remote collection for update operations (don't merge local config over it)
|
72
|
+
return items[0];
|
72
73
|
}
|
73
74
|
else {
|
74
75
|
MessageFormatter.info(`No collection found with name: ${collection.name}`, { prefix: "Collections" });
|
@@ -223,10 +224,8 @@ export const createOrUpdateCollections = async (database, databaseId, config, de
|
|
223
224
|
attributes);
|
224
225
|
// Add delay after creating attributes
|
225
226
|
await delay(250);
|
226
|
-
|
227
|
-
|
228
|
-
: config.collections?.find((c) => c.$id === collectionToUse.$id)
|
229
|
-
?.indexes ?? [];
|
227
|
+
// For PUSH operations, only use indexes from local config (not remote)
|
228
|
+
const indexesToUse = indexes || [];
|
230
229
|
MessageFormatter.progress("Creating Indexes", { prefix: "Collections" });
|
231
230
|
await createOrUpdateIndexesWithStatusCheck(databaseId, database, collectionToUse.$id, collectionToUse, indexesToUse);
|
232
231
|
// Mark this collection as fully processed to prevent re-processing
|
@@ -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 {};
|