appwrite-utils-cli 1.7.8 → 1.8.1

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 (111) hide show
  1. package/CHANGELOG.md +14 -199
  2. package/README.md +87 -30
  3. package/dist/adapters/AdapterFactory.js +5 -25
  4. package/dist/adapters/DatabaseAdapter.d.ts +17 -2
  5. package/dist/adapters/LegacyAdapter.d.ts +2 -1
  6. package/dist/adapters/LegacyAdapter.js +212 -16
  7. package/dist/adapters/TablesDBAdapter.d.ts +2 -12
  8. package/dist/adapters/TablesDBAdapter.js +261 -57
  9. package/dist/cli/commands/databaseCommands.js +10 -10
  10. package/dist/cli/commands/functionCommands.js +17 -8
  11. package/dist/collections/attributes.js +447 -125
  12. package/dist/collections/methods.js +197 -186
  13. package/dist/collections/tableOperations.d.ts +86 -0
  14. package/dist/collections/tableOperations.js +434 -0
  15. package/dist/collections/transferOperations.d.ts +3 -2
  16. package/dist/collections/transferOperations.js +93 -12
  17. package/dist/config/services/ConfigLoaderService.d.ts +7 -0
  18. package/dist/config/services/ConfigLoaderService.js +47 -1
  19. package/dist/config/yamlConfig.d.ts +221 -88
  20. package/dist/examples/yamlTerminologyExample.d.ts +1 -1
  21. package/dist/examples/yamlTerminologyExample.js +6 -3
  22. package/dist/functions/deployments.js +5 -23
  23. package/dist/functions/fnConfigDiscovery.d.ts +3 -0
  24. package/dist/functions/fnConfigDiscovery.js +108 -0
  25. package/dist/functions/methods.js +4 -2
  26. package/dist/functions/pathResolution.d.ts +37 -0
  27. package/dist/functions/pathResolution.js +185 -0
  28. package/dist/functions/templates/count-docs-in-collection/README.md +54 -0
  29. package/dist/functions/templates/count-docs-in-collection/package.json +25 -0
  30. package/dist/functions/templates/count-docs-in-collection/src/main.ts +159 -0
  31. package/dist/functions/templates/count-docs-in-collection/src/request.ts +9 -0
  32. package/dist/functions/templates/count-docs-in-collection/tsconfig.json +28 -0
  33. package/dist/functions/templates/hono-typescript/README.md +286 -0
  34. package/dist/functions/templates/hono-typescript/package.json +26 -0
  35. package/dist/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
  36. package/dist/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
  37. package/dist/functions/templates/hono-typescript/src/app.ts +180 -0
  38. package/dist/functions/templates/hono-typescript/src/context.ts +103 -0
  39. package/dist/functions/templates/hono-typescript/src/index.ts +54 -0
  40. package/dist/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
  41. package/dist/functions/templates/hono-typescript/tsconfig.json +20 -0
  42. package/dist/functions/templates/typescript-node/README.md +32 -0
  43. package/dist/functions/templates/typescript-node/package.json +25 -0
  44. package/dist/functions/templates/typescript-node/src/context.ts +103 -0
  45. package/dist/functions/templates/typescript-node/src/index.ts +29 -0
  46. package/dist/functions/templates/typescript-node/tsconfig.json +28 -0
  47. package/dist/functions/templates/uv/README.md +31 -0
  48. package/dist/functions/templates/uv/pyproject.toml +30 -0
  49. package/dist/functions/templates/uv/src/__init__.py +0 -0
  50. package/dist/functions/templates/uv/src/context.py +125 -0
  51. package/dist/functions/templates/uv/src/index.py +46 -0
  52. package/dist/interactiveCLI.js +18 -15
  53. package/dist/main.js +219 -81
  54. package/dist/migrations/appwriteToX.d.ts +88 -23
  55. package/dist/migrations/comprehensiveTransfer.d.ts +2 -0
  56. package/dist/migrations/comprehensiveTransfer.js +83 -6
  57. package/dist/migrations/dataLoader.d.ts +227 -69
  58. package/dist/migrations/dataLoader.js +3 -3
  59. package/dist/migrations/importController.js +3 -3
  60. package/dist/migrations/relationships.d.ts +8 -2
  61. package/dist/migrations/services/ImportOrchestrator.js +3 -3
  62. package/dist/migrations/transfer.js +159 -37
  63. package/dist/shared/attributeMapper.d.ts +20 -0
  64. package/dist/shared/attributeMapper.js +203 -0
  65. package/dist/shared/selectionDialogs.d.ts +1 -1
  66. package/dist/shared/selectionDialogs.js +39 -11
  67. package/dist/storage/schemas.d.ts +354 -92
  68. package/dist/utils/configDiscovery.js +4 -3
  69. package/dist/utils/versionDetection.d.ts +0 -4
  70. package/dist/utils/versionDetection.js +41 -173
  71. package/dist/utils/yamlConverter.js +89 -16
  72. package/dist/utils/yamlLoader.d.ts +1 -1
  73. package/dist/utils/yamlLoader.js +6 -2
  74. package/dist/utilsController.d.ts +2 -1
  75. package/dist/utilsController.js +151 -22
  76. package/package.json +7 -5
  77. package/scripts/copy-templates.ts +23 -0
  78. package/src/adapters/AdapterFactory.ts +119 -143
  79. package/src/adapters/DatabaseAdapter.ts +18 -3
  80. package/src/adapters/LegacyAdapter.ts +236 -105
  81. package/src/adapters/TablesDBAdapter.ts +773 -643
  82. package/src/cli/commands/databaseCommands.ts +19 -19
  83. package/src/cli/commands/functionCommands.ts +23 -14
  84. package/src/collections/attributes.ts +2054 -1611
  85. package/src/collections/methods.ts +208 -293
  86. package/src/collections/tableOperations.ts +506 -0
  87. package/src/collections/transferOperations.ts +218 -144
  88. package/src/config/services/ConfigLoaderService.ts +62 -1
  89. package/src/examples/yamlTerminologyExample.ts +10 -5
  90. package/src/functions/deployments.ts +10 -35
  91. package/src/functions/fnConfigDiscovery.ts +103 -0
  92. package/src/functions/methods.ts +4 -2
  93. package/src/functions/pathResolution.ts +227 -0
  94. package/src/interactiveCLI.ts +25 -20
  95. package/src/main.ts +557 -202
  96. package/src/migrations/comprehensiveTransfer.ts +126 -50
  97. package/src/migrations/dataLoader.ts +3 -3
  98. package/src/migrations/importController.ts +3 -3
  99. package/src/migrations/services/ImportOrchestrator.ts +3 -3
  100. package/src/migrations/transfer.ts +148 -131
  101. package/src/shared/attributeMapper.ts +229 -0
  102. package/src/shared/selectionDialogs.ts +65 -32
  103. package/src/utils/configDiscovery.ts +9 -3
  104. package/src/utils/versionDetection.ts +74 -228
  105. package/src/utils/yamlConverter.ts +94 -17
  106. package/src/utils/yamlLoader.ts +11 -4
  107. package/src/utilsController.ts +202 -36
  108. package/dist/utils/schemaStrings.d.ts +0 -14
  109. package/dist/utils/schemaStrings.js +0 -428
  110. package/dist/utils/sessionPreservationExample.d.ts +0 -1666
  111. package/dist/utils/sessionPreservationExample.js +0 -101
@@ -1,6 +1,6 @@
1
1
  import path from "path";
2
2
  import fs from "fs";
3
- import {} from "appwrite-utils";
3
+ import { CollectionCreateSchema } from "appwrite-utils";
4
4
  import { register } from "tsx/esm/api";
5
5
  import { pathToFileURL } from "node:url";
6
6
  import yaml from "js-yaml";
@@ -185,7 +185,7 @@ export const loadYamlCollection = (filePath) => {
185
185
  const yamlData = yaml.load(fileContent);
186
186
  const parsedCollection = YamlCollectionSchema.parse(yamlData);
187
187
  // Convert YAML collection to CollectionCreate format
188
- const collection = {
188
+ const collectionInput = {
189
189
  name: parsedCollection.name,
190
190
  $id: parsedCollection.id || parsedCollection.name.toLowerCase().replace(/\s+/g, '_'),
191
191
  documentSecurity: parsedCollection.documentSecurity,
@@ -210,7 +210,7 @@ export const loadYamlCollection = (filePath) => {
210
210
  twoWayKey: attr.twoWayKey,
211
211
  onDelete: attr.onDelete,
212
212
  side: attr.side,
213
- encrypted: attr.encrypt,
213
+ encrypt: attr.encrypt,
214
214
  format: attr.format
215
215
  })),
216
216
  indexes: parsedCollection.indexes.map(idx => ({
@@ -221,6 +221,7 @@ export const loadYamlCollection = (filePath) => {
221
221
  })),
222
222
  importDefs: parsedCollection.importDefs && Array.isArray(parsedCollection.importDefs) && parsedCollection.importDefs.length > 0 ? parsedCollection.importDefs : []
223
223
  };
224
+ const collection = CollectionCreateSchema.parse(collectionInput);
224
225
  return collection;
225
226
  }
226
227
  catch (error) {
@@ -46,10 +46,6 @@ export declare function isCloudAppwriteEndpoint(endpoint: string): boolean;
46
46
  * SDK feature detection as a fallback method
47
47
  * Attempts to dynamically import TablesDB to check availability
48
48
  */
49
- export declare function detectSdkSupport(): Promise<{
50
- tablesDbAvailable: boolean;
51
- legacyAvailable: boolean;
52
- }>;
53
49
  /**
54
50
  * Clear version detection cache (useful for testing)
55
51
  */
@@ -11,6 +11,7 @@
11
11
  */
12
12
  import { logger } from '../shared/logging.js';
13
13
  import { MessageFormatter } from '../shared/messageFormatter.js';
14
+ import { Client, Databases, TablesDB, Query } from 'node-appwrite';
14
15
  /**
15
16
  * Detects Appwrite API version and TablesDB support
16
17
  *
@@ -43,179 +44,70 @@ export async function detectAppwriteVersion(endpoint, project, apiKey) {
43
44
  confidence: 'high'
44
45
  };
45
46
  }
46
- // STEP 2: Only proceed with endpoint probe if version >= 1.8.0 or version unknown
47
- // Try primary detection method: TablesDB endpoint probe
47
+ // STEP 2: If version is unknown, use SDK probe (no fake HTTP endpoints)
48
48
  try {
49
- logger.debug('Attempting TablesDB endpoint probe', {
49
+ logger.debug('Attempting SDK-based TablesDB probe', {
50
50
  endpoint: cleanEndpoint,
51
- serverVersion: serverVersion || 'unknown',
52
51
  operation: 'detectAppwriteVersion'
53
52
  });
54
- const probeStartTime = Date.now();
55
- const tablesDbResult = await probeTablesDbEndpoint(cleanEndpoint, project, apiKey);
56
- const probeDuration = Date.now() - probeStartTime;
57
- if (tablesDbResult.apiMode === 'tablesdb') {
58
- logger.info('TablesDB detected via endpoint probe', {
59
- endpoint: cleanEndpoint,
60
- detectionMethod: tablesDbResult.detectionMethod,
61
- confidence: tablesDbResult.confidence,
62
- probeDuration,
63
- totalDuration: Date.now() - startTime,
64
- operation: 'detectAppwriteVersion'
65
- });
66
- return tablesDbResult;
53
+ const client = new Client().setEndpoint(cleanEndpoint).setProject(project);
54
+ if (apiKey && apiKey.trim().length > 0)
55
+ client.setKey(apiKey);
56
+ const databases = new Databases(client);
57
+ // Try to get a database id to probe tables listing
58
+ let dbId;
59
+ try {
60
+ const dbList = await databases.list([Query.limit(1)]);
61
+ dbId = dbList?.databases?.[0]?.$id || dbList?.databases?.[0]?.id || dbList?.[0]?.$id;
67
62
  }
68
- }
69
- catch (error) {
70
- const errorMessage = error instanceof Error ? error.message : 'Unknown error';
71
- MessageFormatter.warning(`TablesDB endpoint probe failed: ${errorMessage}`, { prefix: "Version Detection" });
72
- logger.warn('TablesDB endpoint probe failed', {
73
- endpoint: cleanEndpoint,
74
- error: errorMessage,
75
- operation: 'detectAppwriteVersion'
76
- });
77
- }
78
- // Try secondary detection method: SDK feature detection
79
- try {
80
- logger.debug('Attempting SDK capability probe', {
63
+ catch (e) {
64
+ // Ignore, we'll still attempt a conservative probe
65
+ logger.debug('Databases.list probe failed or returned no items', { operation: 'detectAppwriteVersion' });
66
+ }
67
+ const tables = new TablesDB(client);
68
+ if (dbId) {
69
+ // Probe listTables for the first database (limit 1)
70
+ await tables.listTables({ databaseId: dbId, queries: [Query.limit(1)] });
71
+ }
72
+ else {
73
+ // No databases to probe; assume TablesDB available (cannot falsify-positively without a db)
74
+ logger.debug('No databases found to probe tables; assuming TablesDB if SDK available', { operation: 'detectAppwriteVersion' });
75
+ }
76
+ const result = {
77
+ apiMode: 'tablesdb',
78
+ detectionMethod: 'endpoint_probe', // repurpose label for SDK probe
79
+ confidence: 'medium',
80
+ serverVersion: serverVersion || undefined
81
+ };
82
+ logger.info('TablesDB detected via SDK probe', {
81
83
  endpoint: cleanEndpoint,
84
+ result,
82
85
  operation: 'detectAppwriteVersion'
83
86
  });
84
- const sdkProbeStartTime = Date.now();
85
- const sdkResult = await probeSdkCapabilities();
86
- const sdkProbeDuration = Date.now() - sdkProbeStartTime;
87
- if (sdkResult.apiMode === 'tablesdb') {
88
- logger.info('TablesDB detected via SDK capability probe', {
89
- endpoint: cleanEndpoint,
90
- detectionMethod: sdkResult.detectionMethod,
91
- confidence: sdkResult.confidence,
92
- sdkProbeDuration,
93
- totalDuration: Date.now() - startTime,
94
- operation: 'detectAppwriteVersion'
95
- });
96
- return sdkResult;
97
- }
87
+ return result;
98
88
  }
99
89
  catch (error) {
100
90
  const errorMessage = error instanceof Error ? error.message : 'Unknown error';
101
- MessageFormatter.warning(`SDK capability probe failed: ${errorMessage}`, { prefix: "Version Detection" });
102
- logger.warn('SDK capability probe failed', {
91
+ logger.warn('SDK TablesDB probe failed; defaulting conservatively', {
103
92
  endpoint: cleanEndpoint,
104
93
  error: errorMessage,
105
94
  operation: 'detectAppwriteVersion'
106
95
  });
107
96
  }
108
- // Fallback to legacy mode
97
+ // Final fallback: default to tablesdb for modern environments when version unknown
109
98
  const fallbackResult = {
110
- apiMode: 'legacy',
99
+ apiMode: 'tablesdb',
111
100
  detectionMethod: 'fallback',
112
- confidence: 'low'
101
+ confidence: 'low',
102
+ serverVersion: serverVersion || undefined
113
103
  };
114
- logger.info('Falling back to legacy mode', {
104
+ logger.info('Defaulting to TablesDB mode (fallback)', {
115
105
  endpoint: cleanEndpoint,
116
- totalDuration: Date.now() - startTime,
117
106
  result: fallbackResult,
118
107
  operation: 'detectAppwriteVersion'
119
108
  });
120
109
  return fallbackResult;
121
110
  }
122
- /**
123
- * Test TablesDB endpoint availability - most reliable detection method
124
- */
125
- async function probeTablesDbEndpoint(endpoint, project, apiKey) {
126
- const startTime = Date.now();
127
- const url = `${endpoint}/tablesdb/`;
128
- logger.debug('Probing TablesDB endpoint', {
129
- url,
130
- project,
131
- operation: 'probeTablesDbEndpoint'
132
- });
133
- const response = await fetch(url, {
134
- method: 'GET',
135
- headers: {
136
- 'Content-Type': 'application/json',
137
- 'X-Appwrite-Project': project,
138
- 'X-Appwrite-Key': apiKey
139
- },
140
- // Short timeout for faster detection
141
- signal: AbortSignal.timeout(5000)
142
- });
143
- const duration = Date.now() - startTime;
144
- logger.debug('TablesDB endpoint response received', {
145
- url,
146
- status: response.status,
147
- statusText: response.statusText,
148
- duration,
149
- operation: 'probeTablesDbEndpoint'
150
- });
151
- if (response.ok) {
152
- // ONLY 200 OK means TablesDB available
153
- // 404 means endpoint doesn't exist (server < 1.8.0)
154
- const result = {
155
- apiMode: 'tablesdb',
156
- detectionMethod: 'endpoint_probe',
157
- confidence: 'high'
158
- };
159
- logger.info('TablesDB endpoint probe successful', {
160
- url,
161
- status: response.status,
162
- result,
163
- duration,
164
- operation: 'probeTablesDbEndpoint'
165
- });
166
- return result;
167
- }
168
- // 501 Not Implemented or other errors = no TablesDB support
169
- const error = new Error(`TablesDB endpoint returned ${response.status}: ${response.statusText}`);
170
- logger.debug('TablesDB endpoint probe failed', {
171
- url,
172
- status: response.status,
173
- statusText: response.statusText,
174
- duration,
175
- operation: 'probeTablesDbEndpoint'
176
- });
177
- throw error;
178
- }
179
- /**
180
- * SDK capability detection as secondary method
181
- */
182
- async function probeSdkCapabilities() {
183
- try {
184
- // Try to import TablesDB SDK
185
- let TablesDBModule;
186
- try {
187
- TablesDBModule = await import('node-appwrite-tablesdb');
188
- }
189
- catch (importError) {
190
- // TablesDB SDK not available, will fall back to legacy
191
- }
192
- if (TablesDBModule?.TablesDB) {
193
- return {
194
- apiMode: 'tablesdb',
195
- detectionMethod: 'endpoint_probe',
196
- confidence: 'medium'
197
- };
198
- }
199
- }
200
- catch (error) {
201
- // TablesDB SDK not available, assume legacy
202
- }
203
- // Check for legacy SDK availability
204
- try {
205
- const { Databases } = await import('node-appwrite');
206
- if (Databases) {
207
- return {
208
- apiMode: 'legacy',
209
- detectionMethod: 'endpoint_probe',
210
- confidence: 'medium'
211
- };
212
- }
213
- }
214
- catch (error) {
215
- throw new Error('No Appwrite SDK available');
216
- }
217
- throw new Error('Unable to determine SDK capabilities');
218
- }
219
111
  /**
220
112
  * Cached version detection to avoid repeated API calls
221
113
  */
@@ -320,31 +212,7 @@ export function isCloudAppwriteEndpoint(endpoint) {
320
212
  * SDK feature detection as a fallback method
321
213
  * Attempts to dynamically import TablesDB to check availability
322
214
  */
323
- export async function detectSdkSupport() {
324
- const result = {
325
- tablesDbAvailable: false,
326
- legacyAvailable: false
327
- };
328
- // Test TablesDB SDK availability
329
- try {
330
- const tablesModule = await import('node-appwrite-tablesdb');
331
- if (tablesModule) {
332
- result.tablesDbAvailable = true;
333
- }
334
- }
335
- catch (error) {
336
- // TablesDB SDK not available
337
- }
338
- // Test legacy SDK availability
339
- try {
340
- await import('node-appwrite');
341
- result.legacyAvailable = true;
342
- }
343
- catch (error) {
344
- // Legacy SDK not available
345
- }
346
- return result;
347
- }
215
+ // Removed dynamic SDK capability checks to avoid confusion and side effects.
348
216
  /**
349
217
  * Clear version detection cache (useful for testing)
350
218
  */
@@ -1,6 +1,86 @@
1
1
  import yaml from "js-yaml";
2
- // Threshold for treating min/max values as undefined (1 trillion)
3
- const MIN_MAX_THRESHOLD = 1_000_000_000_000;
2
+ import { Decimal } from "decimal.js";
3
+ // Extreme values that Appwrite may return, which should be treated as undefined
4
+ const EXTREME_MIN_INTEGER = -9223372036854776000;
5
+ const EXTREME_MAX_INTEGER = 9223372036854776000;
6
+ const EXTREME_MIN_FLOAT = -1.7976931348623157e+308;
7
+ const EXTREME_MAX_FLOAT = 1.7976931348623157e+308;
8
+ /**
9
+ * Type guard to check if an attribute has min/max properties
10
+ */
11
+ const hasMinMaxProperties = (yamlAttr) => {
12
+ return yamlAttr.type === 'integer' || yamlAttr.type === 'double' || yamlAttr.type === 'float';
13
+ };
14
+ /**
15
+ * Normalizes min/max values for integer and float attributes using Decimal.js for precision
16
+ * Validates that min < max and handles extreme database values
17
+ */
18
+ const normalizeMinMaxValues = (yamlAttr) => {
19
+ if (!hasMinMaxProperties(yamlAttr)) {
20
+ return {};
21
+ }
22
+ const { type, min, max, key } = yamlAttr;
23
+ let normalizedMin = min;
24
+ let normalizedMax = max;
25
+ // Handle min value - only filter out extreme database values
26
+ if (normalizedMin !== undefined && normalizedMin !== null) {
27
+ const minValue = Number(normalizedMin);
28
+ const originalMin = normalizedMin;
29
+ // Check if it's an extreme database value (but don't filter out large numbers)
30
+ if (type === 'integer') {
31
+ if (minValue === EXTREME_MIN_INTEGER) {
32
+ console.debug(`Min value normalized to undefined for attribute '${yamlAttr.key}': extreme database value`);
33
+ normalizedMin = undefined;
34
+ }
35
+ }
36
+ else { // float/double
37
+ if (minValue === EXTREME_MIN_FLOAT) {
38
+ console.debug(`Min value normalized to undefined for attribute '${yamlAttr.key}': extreme database value`);
39
+ normalizedMin = undefined;
40
+ }
41
+ }
42
+ }
43
+ // Handle max value - only filter out extreme database values
44
+ if (normalizedMax !== undefined && normalizedMax !== null) {
45
+ const maxValue = Number(normalizedMax);
46
+ const originalMax = normalizedMax;
47
+ // Check if it's an extreme database value (but don't filter out large numbers)
48
+ if (type === 'integer') {
49
+ if (maxValue === EXTREME_MAX_INTEGER) {
50
+ console.debug(`Max value normalized to undefined for attribute '${yamlAttr.key}': extreme database value`);
51
+ normalizedMax = undefined;
52
+ }
53
+ }
54
+ else { // float/double
55
+ if (maxValue === EXTREME_MAX_FLOAT) {
56
+ console.debug(`Max value normalized to undefined for attribute '${yamlAttr.key}': extreme database value`);
57
+ normalizedMax = undefined;
58
+ }
59
+ }
60
+ }
61
+ // Validate that min < max using Decimal.js for safe comparison
62
+ if (normalizedMin !== undefined && normalizedMax !== undefined &&
63
+ normalizedMin !== null && normalizedMax !== null) {
64
+ try {
65
+ const minDecimal = new Decimal(normalizedMin.toString());
66
+ const maxDecimal = new Decimal(normalizedMax.toString());
67
+ if (minDecimal.greaterThanOrEqualTo(maxDecimal)) {
68
+ // Swap values to ensure min < max (graceful handling)
69
+ console.warn(`Swapping min/max values for attribute '${yamlAttr.key}' to fix validation: min (${normalizedMin}) must be less than max (${normalizedMax})`);
70
+ const temp = normalizedMin;
71
+ normalizedMin = normalizedMax;
72
+ normalizedMax = temp;
73
+ }
74
+ }
75
+ catch (error) {
76
+ console.error(`Error comparing min/max values for attribute '${yamlAttr.key}':`, error);
77
+ // If Decimal comparison fails, set both to undefined to avoid API errors
78
+ normalizedMin = undefined;
79
+ normalizedMax = undefined;
80
+ }
81
+ }
82
+ return { min: normalizedMin, max: normalizedMax };
83
+ };
4
84
  /**
5
85
  * Converts a Collection object to YAML format with proper schema reference
6
86
  * Supports both collection and table terminology based on configuration
@@ -51,20 +131,13 @@ export function collectionToYaml(collection, config = {
51
131
  }
52
132
  if ('xdefault' in attr && attr.xdefault !== undefined)
53
133
  yamlAttr.default = attr.xdefault;
54
- // Normalize min/max values - filter out extreme database values
55
- if ('min' in attr && attr.min !== undefined) {
56
- const minValue = Number(attr.min);
57
- // Only include min if it's within reasonable range (< 1 trillion)
58
- if (Math.abs(minValue) < MIN_MAX_THRESHOLD) {
59
- yamlAttr.min = attr.min;
60
- }
61
- }
62
- if ('max' in attr && attr.max !== undefined) {
63
- const maxValue = Number(attr.max);
64
- // Only include max if it's within reasonable range (< 1 trillion)
65
- if (Math.abs(maxValue) < MIN_MAX_THRESHOLD) {
66
- yamlAttr.max = attr.max;
67
- }
134
+ // Normalize min/max values using Decimal.js precision
135
+ if ('min' in attr || 'max' in attr) {
136
+ const { min, max } = normalizeMinMaxValues(attr);
137
+ if (min !== undefined)
138
+ yamlAttr.min = min;
139
+ if (max !== undefined)
140
+ yamlAttr.max = max;
68
141
  }
69
142
  if ('elements' in attr && attr.elements !== undefined)
70
143
  yamlAttr.elements = attr.elements;
@@ -1,5 +1,5 @@
1
1
  import { type YamlCollectionData, type YamlTerminologyConfig } from "./yamlConverter.js";
2
- import type { CollectionCreate } from "appwrite-utils";
2
+ import { type CollectionCreate } from "appwrite-utils";
3
3
  /**
4
4
  * Enhanced YAML loader with dual terminology support
5
5
  */
@@ -3,6 +3,7 @@ import fs from "fs";
3
3
  import path from "path";
4
4
  import { logger } from "../shared/logging.js";
5
5
  import { normalizeYamlData, usesTableTerminology, convertTerminology } from "./yamlConverter.js";
6
+ import { CollectionCreateSchema, } from "appwrite-utils";
6
7
  /**
7
8
  * Enhanced YAML loader with dual terminology support
8
9
  */
@@ -99,7 +100,7 @@ export class YamlLoader {
99
100
  yamlToCollectionCreate(yamlData) {
100
101
  // Always normalize to ensure consistent attribute terminology
101
102
  const normalized = normalizeYamlData(yamlData);
102
- return {
103
+ const collectionInput = {
103
104
  name: normalized.name,
104
105
  $id: normalized.id || normalized.name.toLowerCase().replace(/\s+/g, '_'),
105
106
  enabled: normalized.enabled !== false,
@@ -123,7 +124,9 @@ export class YamlLoader {
123
124
  twoWay: attr.twoWay,
124
125
  twoWayKey: attr.twoWayKey,
125
126
  onDelete: attr.onDelete,
126
- side: attr.side
127
+ side: attr.side,
128
+ encrypt: attr.encrypt,
129
+ format: attr.format
127
130
  })) || [],
128
131
  indexes: normalized.indexes?.map(idx => ({
129
132
  key: idx.key,
@@ -133,6 +136,7 @@ export class YamlLoader {
133
136
  })) || [],
134
137
  importDefs: normalized.importDefs || []
135
138
  };
139
+ return CollectionCreateSchema.parse(collectionInput);
136
140
  }
137
141
  /**
138
142
  * Saves YAML data with specified terminology
@@ -83,7 +83,8 @@ export declare class UtilsController {
83
83
  generateSchemas(): Promise<void>;
84
84
  importData(options?: SetupOptions): Promise<void>;
85
85
  synchronizeConfigurations(databases?: Models.Database[], config?: AppwriteConfig, databaseSelections?: DatabaseSelection[], bucketSelections?: BucketSelection[]): Promise<void>;
86
- selectiveSync(databaseSelections: DatabaseSelection[], bucketSelections: BucketSelection[]): Promise<void>;
86
+ selectivePull(databaseSelections: DatabaseSelection[], bucketSelections: BucketSelection[]): Promise<void>;
87
+ selectivePush(databaseSelections: DatabaseSelection[], bucketSelections: BucketSelection[]): Promise<void>;
87
88
  syncDb(databases?: Models.Database[], collections?: Models.Collection[]): Promise<void>;
88
89
  getAppwriteFolderPath(): string | undefined;
89
90
  transferData(options: TransferOptions): Promise<void>;