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.
- package/CONFIG_TODO.md +1189 -0
- package/SERVICE_IMPLEMENTATION_REPORT.md +462 -0
- package/dist/cli/commands/configCommands.js +7 -1
- package/dist/cli/commands/databaseCommands.js +23 -15
- package/dist/collections/attributes.d.ts +1 -1
- package/dist/collections/attributes.js +163 -66
- package/dist/collections/indexes.js +3 -17
- package/dist/collections/methods.js +38 -0
- 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 +2 -2
- 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 -0
- package/dist/utils/yamlConverter.js +21 -4
- 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/cli/commands/databaseCommands.ts +34 -20
- package/src/collections/attributes.ts +195 -150
- package/src/collections/indexes.ts +4 -19
- package/src/collections/methods.ts +46 -0
- 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 +2 -2
- 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 +28 -2
- package/src/utilsController.ts +99 -187
@@ -0,0 +1,394 @@
|
|
1
|
+
import type { AppwriteConfig } from "appwrite-utils";
|
2
|
+
import {
|
3
|
+
validateCollectionsTablesConfig,
|
4
|
+
reportValidationResults,
|
5
|
+
type ValidationResult as BaseValidationResult,
|
6
|
+
type ValidationError as BaseValidationError
|
7
|
+
} from "../configValidation.js";
|
8
|
+
import { MessageFormatter } from "../../shared/messageFormatter.js";
|
9
|
+
import { logger } from "../../shared/logging.js";
|
10
|
+
|
11
|
+
/**
|
12
|
+
* Re-export types from configValidation for convenience
|
13
|
+
*/
|
14
|
+
export type ValidationError = BaseValidationError;
|
15
|
+
|
16
|
+
/**
|
17
|
+
* Warning-level validation issue (non-blocking)
|
18
|
+
*/
|
19
|
+
export interface ValidationWarning extends BaseValidationError {
|
20
|
+
severity: "warning";
|
21
|
+
}
|
22
|
+
|
23
|
+
/**
|
24
|
+
* Complete validation result including errors, warnings, and suggestions
|
25
|
+
*/
|
26
|
+
export interface ValidationResult {
|
27
|
+
isValid: boolean;
|
28
|
+
errors: ValidationError[];
|
29
|
+
warnings: ValidationWarning[];
|
30
|
+
suggestions?: ValidationError[];
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* Options for validation reporting
|
35
|
+
*/
|
36
|
+
export interface ValidationReportOptions {
|
37
|
+
/**
|
38
|
+
* Include detailed information in the report
|
39
|
+
* @default false
|
40
|
+
*/
|
41
|
+
verbose?: boolean;
|
42
|
+
|
43
|
+
/**
|
44
|
+
* Suppress console output (only log to file)
|
45
|
+
* @default false
|
46
|
+
*/
|
47
|
+
silent?: boolean;
|
48
|
+
|
49
|
+
/**
|
50
|
+
* Exit process if validation fails
|
51
|
+
* @default false
|
52
|
+
*/
|
53
|
+
exitOnError?: boolean;
|
54
|
+
}
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Service for validating Appwrite configuration with support for multiple validation modes
|
58
|
+
*
|
59
|
+
* This service provides centralized configuration validation with:
|
60
|
+
* - Standard validation (warnings allowed)
|
61
|
+
* - Strict validation (warnings treated as errors)
|
62
|
+
* - Detailed error reporting with suggestions
|
63
|
+
* - Configurable output verbosity
|
64
|
+
*
|
65
|
+
* @example
|
66
|
+
* ```typescript
|
67
|
+
* const validationService = new ConfigValidationService();
|
68
|
+
*
|
69
|
+
* // Standard validation
|
70
|
+
* const result = validationService.validate(config);
|
71
|
+
* if (!result.isValid) {
|
72
|
+
* validationService.reportResults(result, { verbose: true });
|
73
|
+
* }
|
74
|
+
*
|
75
|
+
* // Strict validation (warnings become errors)
|
76
|
+
* const strictResult = validationService.validateStrict(config);
|
77
|
+
* if (!strictResult.isValid) {
|
78
|
+
* throw new Error("Configuration validation failed in strict mode");
|
79
|
+
* }
|
80
|
+
* ```
|
81
|
+
*/
|
82
|
+
export class ConfigValidationService {
|
83
|
+
/**
|
84
|
+
* Validate configuration with standard rules
|
85
|
+
*
|
86
|
+
* Standard validation allows warnings - the configuration is considered valid
|
87
|
+
* even if warnings are present. Only errors cause validation to fail.
|
88
|
+
*
|
89
|
+
* Validation checks include:
|
90
|
+
* - Basic structure validation (required fields, array structure)
|
91
|
+
* - Naming conflict detection (collections vs tables)
|
92
|
+
* - Database reference validation
|
93
|
+
* - Schema consistency validation
|
94
|
+
* - Duplicate definition detection
|
95
|
+
*
|
96
|
+
* @param config - Appwrite configuration to validate
|
97
|
+
* @returns Validation result with errors, warnings, and suggestions
|
98
|
+
*
|
99
|
+
* @example
|
100
|
+
* ```typescript
|
101
|
+
* const result = validationService.validate(config);
|
102
|
+
*
|
103
|
+
* if (result.isValid) {
|
104
|
+
* console.log("Configuration is valid");
|
105
|
+
* if (result.warnings.length > 0) {
|
106
|
+
* console.log(`Found ${result.warnings.length} warnings`);
|
107
|
+
* }
|
108
|
+
* } else {
|
109
|
+
* console.error(`Configuration has ${result.errors.length} errors`);
|
110
|
+
* }
|
111
|
+
* ```
|
112
|
+
*/
|
113
|
+
public validate(config: AppwriteConfig): ValidationResult {
|
114
|
+
logger.debug("Starting configuration validation (standard mode)");
|
115
|
+
|
116
|
+
try {
|
117
|
+
const baseResult = validateCollectionsTablesConfig(config);
|
118
|
+
|
119
|
+
const result: ValidationResult = {
|
120
|
+
isValid: baseResult.isValid,
|
121
|
+
errors: baseResult.errors,
|
122
|
+
warnings: baseResult.warnings as ValidationWarning[],
|
123
|
+
suggestions: baseResult.suggestions
|
124
|
+
};
|
125
|
+
|
126
|
+
logger.debug("Configuration validation complete", {
|
127
|
+
isValid: result.isValid,
|
128
|
+
errorCount: result.errors.length,
|
129
|
+
warningCount: result.warnings.length,
|
130
|
+
suggestionCount: result.suggestions?.length || 0
|
131
|
+
});
|
132
|
+
|
133
|
+
return result;
|
134
|
+
} catch (error) {
|
135
|
+
logger.error("Configuration validation failed with exception", {
|
136
|
+
error: error instanceof Error ? error.message : String(error)
|
137
|
+
});
|
138
|
+
|
139
|
+
return {
|
140
|
+
isValid: false,
|
141
|
+
errors: [
|
142
|
+
{
|
143
|
+
type: "schema_inconsistency",
|
144
|
+
message: "Configuration validation failed",
|
145
|
+
details: error instanceof Error ? error.message : String(error),
|
146
|
+
suggestion: "Check configuration file for syntax errors or invalid structure",
|
147
|
+
severity: "error"
|
148
|
+
}
|
149
|
+
],
|
150
|
+
warnings: []
|
151
|
+
};
|
152
|
+
}
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* Validate configuration with strict rules
|
157
|
+
*
|
158
|
+
* Strict validation treats all warnings as errors. This is useful for:
|
159
|
+
* - CI/CD pipelines (fail builds on any issues)
|
160
|
+
* - Production deployments (ensure highest quality)
|
161
|
+
* - Configuration audits (enforce best practices)
|
162
|
+
*
|
163
|
+
* All warnings are promoted to errors, so the configuration is only
|
164
|
+
* considered valid if there are zero warnings and zero errors.
|
165
|
+
*
|
166
|
+
* @param config - Appwrite configuration to validate
|
167
|
+
* @returns Validation result with promoted warnings as errors
|
168
|
+
*
|
169
|
+
* @example
|
170
|
+
* ```typescript
|
171
|
+
* const result = validationService.validateStrict(config);
|
172
|
+
*
|
173
|
+
* if (!result.isValid) {
|
174
|
+
* console.error("Configuration failed strict validation");
|
175
|
+
* result.errors.forEach(err => {
|
176
|
+
* console.error(` - ${err.message}`);
|
177
|
+
* });
|
178
|
+
* process.exit(1);
|
179
|
+
* }
|
180
|
+
* ```
|
181
|
+
*/
|
182
|
+
public validateStrict(config: AppwriteConfig): ValidationResult {
|
183
|
+
logger.debug("Starting configuration validation (strict mode)");
|
184
|
+
|
185
|
+
try {
|
186
|
+
const baseResult = validateCollectionsTablesConfig(config);
|
187
|
+
|
188
|
+
// In strict mode, promote all warnings to errors
|
189
|
+
const promotedWarnings: ValidationError[] = baseResult.warnings.map(warning => ({
|
190
|
+
...warning,
|
191
|
+
severity: "error" as const
|
192
|
+
}));
|
193
|
+
|
194
|
+
const allErrors = [...baseResult.errors, ...promotedWarnings];
|
195
|
+
|
196
|
+
const result: ValidationResult = {
|
197
|
+
isValid: allErrors.length === 0,
|
198
|
+
errors: allErrors,
|
199
|
+
warnings: [], // No warnings in strict mode - all promoted to errors
|
200
|
+
suggestions: baseResult.suggestions
|
201
|
+
};
|
202
|
+
|
203
|
+
logger.debug("Configuration validation complete (strict mode)", {
|
204
|
+
isValid: result.isValid,
|
205
|
+
errorCount: result.errors.length,
|
206
|
+
promotedWarnings: promotedWarnings.length,
|
207
|
+
suggestionCount: result.suggestions?.length || 0
|
208
|
+
});
|
209
|
+
|
210
|
+
return result;
|
211
|
+
} catch (error) {
|
212
|
+
logger.error("Configuration validation failed with exception (strict mode)", {
|
213
|
+
error: error instanceof Error ? error.message : String(error)
|
214
|
+
});
|
215
|
+
|
216
|
+
return {
|
217
|
+
isValid: false,
|
218
|
+
errors: [
|
219
|
+
{
|
220
|
+
type: "schema_inconsistency",
|
221
|
+
message: "Configuration validation failed in strict mode",
|
222
|
+
details: error instanceof Error ? error.message : String(error),
|
223
|
+
suggestion: "Check configuration file for syntax errors or invalid structure",
|
224
|
+
severity: "error"
|
225
|
+
}
|
226
|
+
],
|
227
|
+
warnings: []
|
228
|
+
};
|
229
|
+
}
|
230
|
+
}
|
231
|
+
|
232
|
+
/**
|
233
|
+
* Report validation results to console with formatted output
|
234
|
+
*
|
235
|
+
* Provides user-friendly formatting of validation results:
|
236
|
+
* - Color-coded output (errors in red, warnings in yellow, etc.)
|
237
|
+
* - Detailed error descriptions with suggestions
|
238
|
+
* - Affected items listing
|
239
|
+
* - Optional verbose mode for additional details
|
240
|
+
*
|
241
|
+
* @param validation - Validation result to report
|
242
|
+
* @param options - Reporting options (verbose, silent, exitOnError)
|
243
|
+
*
|
244
|
+
* @example
|
245
|
+
* ```typescript
|
246
|
+
* const result = validationService.validate(config);
|
247
|
+
*
|
248
|
+
* // Basic reporting
|
249
|
+
* validationService.reportResults(result);
|
250
|
+
*
|
251
|
+
* // Verbose reporting with all details
|
252
|
+
* validationService.reportResults(result, { verbose: true });
|
253
|
+
*
|
254
|
+
* // Report and exit on error (useful for scripts)
|
255
|
+
* validationService.reportResults(result, { exitOnError: true });
|
256
|
+
* ```
|
257
|
+
*/
|
258
|
+
public reportResults(
|
259
|
+
validation: ValidationResult,
|
260
|
+
options: ValidationReportOptions = {}
|
261
|
+
): void {
|
262
|
+
const { verbose = false, silent = false, exitOnError = false } = options;
|
263
|
+
|
264
|
+
if (silent) {
|
265
|
+
// Only log to file, don't print to console
|
266
|
+
logger.info("Configuration validation results", {
|
267
|
+
isValid: validation.isValid,
|
268
|
+
errorCount: validation.errors.length,
|
269
|
+
warningCount: validation.warnings.length,
|
270
|
+
suggestionCount: validation.suggestions?.length || 0
|
271
|
+
});
|
272
|
+
|
273
|
+
if (validation.errors.length > 0) {
|
274
|
+
validation.errors.forEach(error => {
|
275
|
+
logger.error("Validation error", {
|
276
|
+
type: error.type,
|
277
|
+
message: error.message,
|
278
|
+
details: error.details,
|
279
|
+
suggestion: error.suggestion,
|
280
|
+
affectedItems: error.affectedItems
|
281
|
+
});
|
282
|
+
});
|
283
|
+
}
|
284
|
+
|
285
|
+
return;
|
286
|
+
}
|
287
|
+
|
288
|
+
// Use existing reportValidationResults for formatted console output
|
289
|
+
reportValidationResults(
|
290
|
+
{
|
291
|
+
isValid: validation.isValid,
|
292
|
+
errors: validation.errors,
|
293
|
+
warnings: validation.warnings,
|
294
|
+
suggestions: validation.suggestions || []
|
295
|
+
},
|
296
|
+
{ verbose }
|
297
|
+
);
|
298
|
+
|
299
|
+
// Exit on error if requested
|
300
|
+
if (exitOnError && !validation.isValid) {
|
301
|
+
logger.error("Exiting due to validation errors");
|
302
|
+
process.exit(1);
|
303
|
+
}
|
304
|
+
}
|
305
|
+
|
306
|
+
/**
|
307
|
+
* Validate and report in a single call
|
308
|
+
*
|
309
|
+
* Convenience method that combines validation and reporting.
|
310
|
+
* Useful for quick validation checks in CLI commands.
|
311
|
+
*
|
312
|
+
* @param config - Appwrite configuration to validate
|
313
|
+
* @param strict - Use strict validation mode
|
314
|
+
* @param reportOptions - Reporting options
|
315
|
+
* @returns Validation result
|
316
|
+
*
|
317
|
+
* @example
|
318
|
+
* ```typescript
|
319
|
+
* // Quick validation with reporting
|
320
|
+
* const result = validationService.validateAndReport(config, false, {
|
321
|
+
* verbose: true,
|
322
|
+
* exitOnError: true
|
323
|
+
* });
|
324
|
+
* ```
|
325
|
+
*/
|
326
|
+
public validateAndReport(
|
327
|
+
config: AppwriteConfig,
|
328
|
+
strict: boolean = false,
|
329
|
+
reportOptions: ValidationReportOptions = {}
|
330
|
+
): ValidationResult {
|
331
|
+
const result = strict ? this.validateStrict(config) : this.validate(config);
|
332
|
+
this.reportResults(result, reportOptions);
|
333
|
+
return result;
|
334
|
+
}
|
335
|
+
|
336
|
+
/**
|
337
|
+
* Check if configuration is valid without detailed reporting
|
338
|
+
*
|
339
|
+
* Quick validation check that returns a simple boolean.
|
340
|
+
* Useful for conditional logic where you don't need detailed error information.
|
341
|
+
*
|
342
|
+
* @param config - Appwrite configuration to validate
|
343
|
+
* @param strict - Use strict validation mode
|
344
|
+
* @returns true if configuration is valid, false otherwise
|
345
|
+
*
|
346
|
+
* @example
|
347
|
+
* ```typescript
|
348
|
+
* if (validationService.isValid(config)) {
|
349
|
+
* // Proceed with configuration
|
350
|
+
* } else {
|
351
|
+
* // Show error and prompt for correction
|
352
|
+
* }
|
353
|
+
* ```
|
354
|
+
*/
|
355
|
+
public isValid(config: AppwriteConfig, strict: boolean = false): boolean {
|
356
|
+
const result = strict ? this.validateStrict(config) : this.validate(config);
|
357
|
+
return result.isValid;
|
358
|
+
}
|
359
|
+
|
360
|
+
/**
|
361
|
+
* Get a summary of validation results as a formatted string
|
362
|
+
*
|
363
|
+
* Returns a human-readable summary of validation results suitable for
|
364
|
+
* logging or display in UIs.
|
365
|
+
*
|
366
|
+
* @param validation - Validation result to summarize
|
367
|
+
* @returns Formatted summary string
|
368
|
+
*
|
369
|
+
* @example
|
370
|
+
* ```typescript
|
371
|
+
* const result = validationService.validate(config);
|
372
|
+
* const summary = validationService.getSummary(result);
|
373
|
+
* console.log(summary);
|
374
|
+
* // Output: "Configuration valid with 2 warnings, 1 suggestion"
|
375
|
+
* ```
|
376
|
+
*/
|
377
|
+
public getSummary(validation: ValidationResult): string {
|
378
|
+
if (validation.isValid) {
|
379
|
+
const parts = ["Configuration valid"];
|
380
|
+
|
381
|
+
if (validation.warnings.length > 0) {
|
382
|
+
parts.push(`${validation.warnings.length} warning${validation.warnings.length > 1 ? "s" : ""}`);
|
383
|
+
}
|
384
|
+
|
385
|
+
if (validation.suggestions && validation.suggestions.length > 0) {
|
386
|
+
parts.push(`${validation.suggestions.length} suggestion${validation.suggestions.length > 1 ? "s" : ""}`);
|
387
|
+
}
|
388
|
+
|
389
|
+
return parts.join(" with ");
|
390
|
+
} else {
|
391
|
+
return `Configuration invalid: ${validation.errors.length} error${validation.errors.length > 1 ? "s" : ""}`;
|
392
|
+
}
|
393
|
+
}
|
394
|
+
}
|