appwrite-utils-cli 1.5.1 → 1.6.0

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 (233) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +251 -29
  3. package/dist/adapters/AdapterFactory.d.ts +10 -3
  4. package/dist/adapters/AdapterFactory.js +213 -17
  5. package/dist/adapters/TablesDBAdapter.js +60 -17
  6. package/dist/backups/operations/bucketBackup.d.ts +19 -0
  7. package/dist/backups/operations/bucketBackup.js +197 -0
  8. package/dist/backups/operations/collectionBackup.d.ts +30 -0
  9. package/dist/backups/operations/collectionBackup.js +201 -0
  10. package/dist/backups/operations/comprehensiveBackup.d.ts +25 -0
  11. package/dist/backups/operations/comprehensiveBackup.js +238 -0
  12. package/dist/backups/schemas/bucketManifest.d.ts +93 -0
  13. package/dist/backups/schemas/bucketManifest.js +33 -0
  14. package/dist/backups/schemas/comprehensiveManifest.d.ts +108 -0
  15. package/dist/backups/schemas/comprehensiveManifest.js +32 -0
  16. package/dist/backups/tracking/centralizedTracking.d.ts +34 -0
  17. package/dist/backups/tracking/centralizedTracking.js +274 -0
  18. package/dist/cli/commands/configCommands.d.ts +8 -0
  19. package/dist/cli/commands/configCommands.js +160 -0
  20. package/dist/cli/commands/databaseCommands.d.ts +13 -0
  21. package/dist/cli/commands/databaseCommands.js +478 -0
  22. package/dist/cli/commands/functionCommands.d.ts +7 -0
  23. package/dist/cli/commands/functionCommands.js +289 -0
  24. package/dist/cli/commands/schemaCommands.d.ts +7 -0
  25. package/dist/cli/commands/schemaCommands.js +134 -0
  26. package/dist/cli/commands/transferCommands.d.ts +5 -0
  27. package/dist/cli/commands/transferCommands.js +384 -0
  28. package/dist/collections/attributes.d.ts +5 -4
  29. package/dist/collections/attributes.js +539 -246
  30. package/dist/collections/indexes.js +39 -37
  31. package/dist/collections/methods.d.ts +2 -16
  32. package/dist/collections/methods.js +90 -538
  33. package/dist/collections/transferOperations.d.ts +7 -0
  34. package/dist/collections/transferOperations.js +331 -0
  35. package/dist/collections/wipeOperations.d.ts +16 -0
  36. package/dist/collections/wipeOperations.js +328 -0
  37. package/dist/config/configMigration.d.ts +87 -0
  38. package/dist/config/configMigration.js +390 -0
  39. package/dist/config/configValidation.d.ts +66 -0
  40. package/dist/config/configValidation.js +358 -0
  41. package/dist/config/yamlConfig.d.ts +455 -1
  42. package/dist/config/yamlConfig.js +145 -52
  43. package/dist/databases/methods.js +3 -2
  44. package/dist/databases/setup.d.ts +1 -2
  45. package/dist/databases/setup.js +9 -87
  46. package/dist/examples/yamlTerminologyExample.d.ts +42 -0
  47. package/dist/examples/yamlTerminologyExample.js +269 -0
  48. package/dist/functions/deployments.js +11 -10
  49. package/dist/functions/methods.d.ts +1 -1
  50. package/dist/functions/methods.js +5 -4
  51. package/dist/init.js +9 -9
  52. package/dist/interactiveCLI.d.ts +8 -17
  53. package/dist/interactiveCLI.js +186 -1171
  54. package/dist/main.js +364 -21
  55. package/dist/migrations/afterImportActions.js +22 -30
  56. package/dist/migrations/appwriteToX.js +71 -25
  57. package/dist/migrations/dataLoader.js +35 -26
  58. package/dist/migrations/importController.js +29 -30
  59. package/dist/migrations/relationships.js +13 -12
  60. package/dist/migrations/services/ImportOrchestrator.js +16 -19
  61. package/dist/migrations/transfer.js +46 -46
  62. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +3 -1
  63. package/dist/migrations/yaml/YamlImportConfigLoader.js +6 -3
  64. package/dist/migrations/yaml/YamlImportIntegration.d.ts +9 -3
  65. package/dist/migrations/yaml/YamlImportIntegration.js +22 -11
  66. package/dist/migrations/yaml/generateImportSchemas.d.ts +14 -1
  67. package/dist/migrations/yaml/generateImportSchemas.js +736 -7
  68. package/dist/schemas/authUser.d.ts +1 -1
  69. package/dist/setupController.js +3 -2
  70. package/dist/shared/backupMetadataSchema.d.ts +94 -0
  71. package/dist/shared/backupMetadataSchema.js +38 -0
  72. package/dist/shared/backupTracking.d.ts +18 -0
  73. package/dist/shared/backupTracking.js +176 -0
  74. package/dist/shared/confirmationDialogs.js +15 -15
  75. package/dist/shared/errorUtils.d.ts +54 -0
  76. package/dist/shared/errorUtils.js +95 -0
  77. package/dist/shared/functionManager.js +20 -19
  78. package/dist/shared/indexManager.js +12 -11
  79. package/dist/shared/jsonSchemaGenerator.js +10 -26
  80. package/dist/shared/logging.d.ts +51 -0
  81. package/dist/shared/logging.js +70 -0
  82. package/dist/shared/messageFormatter.d.ts +2 -0
  83. package/dist/shared/messageFormatter.js +10 -0
  84. package/dist/shared/migrationHelpers.d.ts +6 -16
  85. package/dist/shared/migrationHelpers.js +24 -21
  86. package/dist/shared/operationLogger.d.ts +8 -1
  87. package/dist/shared/operationLogger.js +11 -24
  88. package/dist/shared/operationQueue.d.ts +28 -1
  89. package/dist/shared/operationQueue.js +268 -66
  90. package/dist/shared/operationsTable.d.ts +26 -0
  91. package/dist/shared/operationsTable.js +286 -0
  92. package/dist/shared/operationsTableSchema.d.ts +48 -0
  93. package/dist/shared/operationsTableSchema.js +35 -0
  94. package/dist/shared/relationshipExtractor.d.ts +56 -0
  95. package/dist/shared/relationshipExtractor.js +138 -0
  96. package/dist/shared/schemaGenerator.d.ts +19 -1
  97. package/dist/shared/schemaGenerator.js +56 -75
  98. package/dist/storage/backupCompression.d.ts +20 -0
  99. package/dist/storage/backupCompression.js +67 -0
  100. package/dist/storage/methods.d.ts +16 -2
  101. package/dist/storage/methods.js +98 -14
  102. package/dist/users/methods.js +9 -8
  103. package/dist/utils/configDiscovery.d.ts +78 -0
  104. package/dist/utils/configDiscovery.js +430 -0
  105. package/dist/utils/directoryUtils.d.ts +22 -0
  106. package/dist/utils/directoryUtils.js +59 -0
  107. package/dist/utils/getClientFromConfig.d.ts +17 -8
  108. package/dist/utils/getClientFromConfig.js +162 -17
  109. package/dist/utils/helperFunctions.d.ts +16 -2
  110. package/dist/utils/helperFunctions.js +19 -5
  111. package/dist/utils/loadConfigs.d.ts +34 -9
  112. package/dist/utils/loadConfigs.js +236 -316
  113. package/dist/utils/pathResolvers.d.ts +53 -0
  114. package/dist/utils/pathResolvers.js +72 -0
  115. package/dist/utils/projectConfig.d.ts +119 -0
  116. package/dist/utils/projectConfig.js +171 -0
  117. package/dist/utils/retryFailedPromises.js +4 -2
  118. package/dist/utils/sessionAuth.d.ts +48 -0
  119. package/dist/utils/sessionAuth.js +164 -0
  120. package/dist/utils/sessionPreservationExample.d.ts +1666 -0
  121. package/dist/utils/sessionPreservationExample.js +101 -0
  122. package/dist/utils/setupFiles.js +301 -41
  123. package/dist/utils/typeGuards.d.ts +35 -0
  124. package/dist/utils/typeGuards.js +57 -0
  125. package/dist/utils/versionDetection.js +145 -9
  126. package/dist/utils/yamlConverter.d.ts +53 -3
  127. package/dist/utils/yamlConverter.js +232 -13
  128. package/dist/utils/yamlLoader.d.ts +70 -0
  129. package/dist/utils/yamlLoader.js +263 -0
  130. package/dist/utilsController.d.ts +36 -3
  131. package/dist/utilsController.js +186 -56
  132. package/package.json +12 -2
  133. package/src/adapters/AdapterFactory.ts +263 -35
  134. package/src/adapters/TablesDBAdapter.ts +225 -36
  135. package/src/backups/operations/bucketBackup.ts +277 -0
  136. package/src/backups/operations/collectionBackup.ts +310 -0
  137. package/src/backups/operations/comprehensiveBackup.ts +342 -0
  138. package/src/backups/schemas/bucketManifest.ts +78 -0
  139. package/src/backups/schemas/comprehensiveManifest.ts +76 -0
  140. package/src/backups/tracking/centralizedTracking.ts +352 -0
  141. package/src/cli/commands/configCommands.ts +194 -0
  142. package/src/cli/commands/databaseCommands.ts +635 -0
  143. package/src/cli/commands/functionCommands.ts +379 -0
  144. package/src/cli/commands/schemaCommands.ts +163 -0
  145. package/src/cli/commands/transferCommands.ts +457 -0
  146. package/src/collections/attributes.ts +900 -621
  147. package/src/collections/attributes.ts.backup +1555 -0
  148. package/src/collections/indexes.ts +116 -114
  149. package/src/collections/methods.ts +295 -968
  150. package/src/collections/transferOperations.ts +516 -0
  151. package/src/collections/wipeOperations.ts +501 -0
  152. package/src/config/README.md +274 -0
  153. package/src/config/configMigration.ts +575 -0
  154. package/src/config/configValidation.ts +445 -0
  155. package/src/config/yamlConfig.ts +168 -55
  156. package/src/databases/methods.ts +3 -2
  157. package/src/databases/setup.ts +11 -138
  158. package/src/examples/yamlTerminologyExample.ts +341 -0
  159. package/src/functions/deployments.ts +14 -12
  160. package/src/functions/methods.ts +11 -11
  161. package/src/functions/templates/hono-typescript/README.md +286 -0
  162. package/src/functions/templates/hono-typescript/package.json +26 -0
  163. package/src/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
  164. package/src/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
  165. package/src/functions/templates/hono-typescript/src/app.ts +180 -0
  166. package/src/functions/templates/hono-typescript/src/context.ts +103 -0
  167. package/src/functions/templates/hono-typescript/src/index.ts +54 -0
  168. package/src/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
  169. package/src/functions/templates/hono-typescript/tsconfig.json +20 -0
  170. package/src/functions/templates/typescript-node/package.json +2 -1
  171. package/src/functions/templates/typescript-node/src/context.ts +103 -0
  172. package/src/functions/templates/typescript-node/src/index.ts +18 -12
  173. package/src/functions/templates/uv/pyproject.toml +1 -0
  174. package/src/functions/templates/uv/src/context.py +125 -0
  175. package/src/functions/templates/uv/src/index.py +35 -5
  176. package/src/init.ts +9 -11
  177. package/src/interactiveCLI.ts +276 -1591
  178. package/src/main.ts +418 -24
  179. package/src/migrations/afterImportActions.ts +71 -44
  180. package/src/migrations/appwriteToX.ts +100 -34
  181. package/src/migrations/dataLoader.ts +48 -34
  182. package/src/migrations/importController.ts +44 -39
  183. package/src/migrations/relationships.ts +28 -18
  184. package/src/migrations/services/ImportOrchestrator.ts +24 -27
  185. package/src/migrations/transfer.ts +159 -121
  186. package/src/migrations/yaml/YamlImportConfigLoader.ts +11 -4
  187. package/src/migrations/yaml/YamlImportIntegration.ts +47 -20
  188. package/src/migrations/yaml/generateImportSchemas.ts +751 -12
  189. package/src/setupController.ts +3 -2
  190. package/src/shared/backupMetadataSchema.ts +93 -0
  191. package/src/shared/backupTracking.ts +211 -0
  192. package/src/shared/confirmationDialogs.ts +19 -19
  193. package/src/shared/errorUtils.ts +110 -0
  194. package/src/shared/functionManager.ts +21 -20
  195. package/src/shared/indexManager.ts +12 -11
  196. package/src/shared/jsonSchemaGenerator.ts +38 -52
  197. package/src/shared/logging.ts +75 -0
  198. package/src/shared/messageFormatter.ts +14 -1
  199. package/src/shared/migrationHelpers.ts +45 -38
  200. package/src/shared/operationLogger.ts +11 -36
  201. package/src/shared/operationQueue.ts +322 -93
  202. package/src/shared/operationsTable.ts +338 -0
  203. package/src/shared/operationsTableSchema.ts +60 -0
  204. package/src/shared/relationshipExtractor.ts +214 -0
  205. package/src/shared/schemaGenerator.ts +179 -219
  206. package/src/storage/backupCompression.ts +88 -0
  207. package/src/storage/methods.ts +131 -34
  208. package/src/users/methods.ts +11 -9
  209. package/src/utils/configDiscovery.ts +502 -0
  210. package/src/utils/directoryUtils.ts +61 -0
  211. package/src/utils/getClientFromConfig.ts +205 -22
  212. package/src/utils/helperFunctions.ts +23 -5
  213. package/src/utils/loadConfigs.ts +313 -345
  214. package/src/utils/pathResolvers.ts +81 -0
  215. package/src/utils/projectConfig.ts +299 -0
  216. package/src/utils/retryFailedPromises.ts +4 -2
  217. package/src/utils/sessionAuth.ts +230 -0
  218. package/src/utils/setupFiles.ts +322 -54
  219. package/src/utils/typeGuards.ts +65 -0
  220. package/src/utils/versionDetection.ts +218 -64
  221. package/src/utils/yamlConverter.ts +296 -13
  222. package/src/utils/yamlLoader.ts +364 -0
  223. package/src/utilsController.ts +314 -110
  224. package/tests/README.md +497 -0
  225. package/tests/adapters/AdapterFactory.test.ts +277 -0
  226. package/tests/integration/syncOperations.test.ts +463 -0
  227. package/tests/jest.config.js +25 -0
  228. package/tests/migration/configMigration.test.ts +546 -0
  229. package/tests/setup.ts +62 -0
  230. package/tests/testUtils.ts +340 -0
  231. package/tests/utils/loadConfigs.test.ts +350 -0
  232. package/tests/validation/configValidation.test.ts +412 -0
  233. package/src/utils/schemaStrings.ts +0 -517
@@ -9,6 +9,8 @@
9
9
  * 2. Secondary: Health endpoint version check
10
10
  * 3. Fallback: Default to legacy mode for safety
11
11
  */
12
+ import { logger } from '../shared/logging.js';
13
+ import { MessageFormatter } from '../shared/messageFormatter.js';
12
14
  /**
13
15
  * Detects Appwrite API version and TablesDB support
14
16
  *
@@ -18,40 +20,117 @@
18
20
  * @returns Promise resolving to version detection result
19
21
  */
20
22
  export async function detectAppwriteVersion(endpoint, project, apiKey) {
23
+ const startTime = Date.now();
21
24
  // Clean endpoint URL
22
25
  const cleanEndpoint = endpoint.replace(/\/$/, '');
26
+ logger.info('Starting Appwrite version detection', {
27
+ endpoint: cleanEndpoint,
28
+ project,
29
+ operation: 'detectAppwriteVersion'
30
+ });
31
+ // STEP 1: Check server version FIRST
32
+ const serverVersion = await fetchServerVersion(cleanEndpoint);
33
+ if (serverVersion && !isVersionAtLeast(serverVersion, '1.8.0')) {
34
+ // Server < 1.8.0 doesn't support TablesDB
35
+ logger.info('Server version below 1.8.0 - using legacy adapter', {
36
+ serverVersion,
37
+ operation: 'detectAppwriteVersion'
38
+ });
39
+ return {
40
+ apiMode: 'legacy',
41
+ detectionMethod: 'health_check',
42
+ serverVersion,
43
+ confidence: 'high'
44
+ };
45
+ }
46
+ // STEP 2: Only proceed with endpoint probe if version >= 1.8.0 or version unknown
23
47
  // Try primary detection method: TablesDB endpoint probe
24
48
  try {
49
+ logger.debug('Attempting TablesDB endpoint probe', {
50
+ endpoint: cleanEndpoint,
51
+ serverVersion: serverVersion || 'unknown',
52
+ operation: 'detectAppwriteVersion'
53
+ });
54
+ const probeStartTime = Date.now();
25
55
  const tablesDbResult = await probeTablesDbEndpoint(cleanEndpoint, project, apiKey);
56
+ const probeDuration = Date.now() - probeStartTime;
26
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
+ });
27
66
  return tablesDbResult;
28
67
  }
29
68
  }
30
69
  catch (error) {
31
- console.warn('TablesDB endpoint probe failed:', error instanceof Error ? error.message : 'Unknown 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
+ });
32
77
  }
33
78
  // Try secondary detection method: SDK feature detection
34
79
  try {
80
+ logger.debug('Attempting SDK capability probe', {
81
+ endpoint: cleanEndpoint,
82
+ operation: 'detectAppwriteVersion'
83
+ });
84
+ const sdkProbeStartTime = Date.now();
35
85
  const sdkResult = await probeSdkCapabilities();
86
+ const sdkProbeDuration = Date.now() - sdkProbeStartTime;
36
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
+ });
37
96
  return sdkResult;
38
97
  }
39
98
  }
40
99
  catch (error) {
41
- console.warn('SDK capability probe failed:', error instanceof Error ? error.message : 'Unknown error');
100
+ 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', {
103
+ endpoint: cleanEndpoint,
104
+ error: errorMessage,
105
+ operation: 'detectAppwriteVersion'
106
+ });
42
107
  }
43
108
  // Fallback to legacy mode
44
- return {
109
+ const fallbackResult = {
45
110
  apiMode: 'legacy',
46
111
  detectionMethod: 'fallback',
47
112
  confidence: 'low'
48
113
  };
114
+ logger.info('Falling back to legacy mode', {
115
+ endpoint: cleanEndpoint,
116
+ totalDuration: Date.now() - startTime,
117
+ result: fallbackResult,
118
+ operation: 'detectAppwriteVersion'
119
+ });
120
+ return fallbackResult;
49
121
  }
50
122
  /**
51
123
  * Test TablesDB endpoint availability - most reliable detection method
52
124
  */
53
125
  async function probeTablesDbEndpoint(endpoint, project, apiKey) {
54
- const response = await fetch(`${endpoint}/tablesdb/`, {
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, {
55
134
  method: 'GET',
56
135
  headers: {
57
136
  'Content-Type': 'application/json',
@@ -61,17 +140,41 @@ async function probeTablesDbEndpoint(endpoint, project, apiKey) {
61
140
  // Short timeout for faster detection
62
141
  signal: AbortSignal.timeout(5000)
63
142
  });
64
- if (response.ok || response.status === 404) {
65
- // 200 = TablesDB available, 404 = endpoint exists but no tables
66
- // Both indicate TablesDB support
67
- return {
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 = {
68
155
  apiMode: 'tablesdb',
69
156
  detectionMethod: 'endpoint_probe',
70
157
  confidence: 'high'
71
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;
72
167
  }
73
168
  // 501 Not Implemented or other errors = no TablesDB support
74
- throw new Error(`TablesDB endpoint returned ${response.status}: ${response.statusText}`);
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;
75
178
  }
76
179
  /**
77
180
  * SDK capability detection as secondary method
@@ -158,17 +261,50 @@ const detectionCache = new VersionDetectionCache();
158
261
  * @returns Promise resolving to version detection result
159
262
  */
160
263
  export async function detectAppwriteVersionCached(endpoint, project, apiKey, forceRefresh = false) {
264
+ const startTime = Date.now();
265
+ logger.debug('Version detection with cache requested', {
266
+ endpoint,
267
+ project,
268
+ forceRefresh,
269
+ operation: 'detectAppwriteVersionCached'
270
+ });
161
271
  // Check cache first (unless force refresh)
162
272
  if (!forceRefresh) {
163
273
  const cached = detectionCache.get(endpoint, project);
164
274
  if (cached) {
275
+ logger.info('Using cached version detection result', {
276
+ endpoint,
277
+ project,
278
+ cachedResult: cached,
279
+ operation: 'detectAppwriteVersionCached'
280
+ });
165
281
  return cached;
166
282
  }
283
+ logger.debug('No cached result found, performing fresh detection', {
284
+ endpoint,
285
+ project,
286
+ operation: 'detectAppwriteVersionCached'
287
+ });
288
+ }
289
+ else {
290
+ logger.debug('Force refresh requested, bypassing cache', {
291
+ endpoint,
292
+ project,
293
+ operation: 'detectAppwriteVersionCached'
294
+ });
167
295
  }
168
296
  // Perform fresh detection
169
297
  const result = await detectAppwriteVersion(endpoint, project, apiKey);
298
+ const totalDuration = Date.now() - startTime;
170
299
  // Cache the result
171
300
  detectionCache.set(endpoint, project, result);
301
+ logger.info('Version detection completed and cached', {
302
+ endpoint,
303
+ project,
304
+ result,
305
+ totalDuration,
306
+ operation: 'detectAppwriteVersionCached'
307
+ });
172
308
  return result;
173
309
  }
174
310
  /**
@@ -25,23 +25,73 @@ export interface YamlCollectionData {
25
25
  onDelete?: string;
26
26
  side?: string;
27
27
  }>;
28
+ columns?: Array<{
29
+ key: string;
30
+ type: string;
31
+ size?: number;
32
+ required?: boolean;
33
+ array?: boolean;
34
+ default?: any;
35
+ min?: number;
36
+ max?: number;
37
+ elements?: string[];
38
+ relatedTable?: string;
39
+ relationType?: string;
40
+ twoWay?: boolean;
41
+ twoWayKey?: string;
42
+ onDelete?: string;
43
+ side?: string;
44
+ }>;
28
45
  indexes?: Array<{
29
46
  key: string;
30
47
  type: string;
31
48
  attributes: string[];
49
+ columns?: string[];
32
50
  orders?: string[];
33
51
  }>;
34
52
  importDefs?: any[];
35
53
  }
54
+ /**
55
+ * Configuration for terminology selection
56
+ */
57
+ export interface YamlTerminologyConfig {
58
+ useTableTerminology: boolean;
59
+ entityType: 'collection' | 'table';
60
+ schemaPath?: string;
61
+ }
36
62
  /**
37
63
  * Converts a Collection object to YAML format with proper schema reference
64
+ * Supports both collection and table terminology based on configuration
38
65
  */
39
- export declare function collectionToYaml(collection: Collection | CollectionCreate, schemaPath?: string): string;
66
+ export declare function collectionToYaml(collection: Collection | CollectionCreate, config?: YamlTerminologyConfig): string;
40
67
  /**
41
68
  * Sanitizes a collection name for use as a filename
42
69
  */
43
70
  export declare function sanitizeFilename(name: string): string;
44
71
  /**
45
- * Generates the filename for a collection YAML file
72
+ * Generates the filename for a collection/table YAML file
73
+ */
74
+ export declare function getCollectionYamlFilename(collection: Collection | CollectionCreate, useTableTerminology?: boolean): string;
75
+ /**
76
+ * Converts column terminology back to attribute terminology for loading
77
+ */
78
+ export declare function normalizeYamlData(yamlData: YamlCollectionData): YamlCollectionData;
79
+ /**
80
+ * Determines if YAML data uses table terminology
81
+ */
82
+ export declare function usesTableTerminology(yamlData: YamlCollectionData): boolean;
83
+ /**
84
+ * Converts between attribute and column terminology
85
+ */
86
+ export declare function convertTerminology(yamlData: YamlCollectionData, toTableTerminology: boolean): YamlCollectionData;
87
+ /**
88
+ * Generates a template YAML file for collections or tables
89
+ */
90
+ export declare function generateYamlTemplate(entityName: string, config: YamlTerminologyConfig): string;
91
+ /**
92
+ * Generates example YAML files for both collection and table formats
46
93
  */
47
- export declare function getCollectionYamlFilename(collection: Collection | CollectionCreate): string;
94
+ export declare function generateExampleYamls(entityName: string): {
95
+ collection: string;
96
+ table: string;
97
+ };
@@ -1,8 +1,14 @@
1
1
  import yaml from "js-yaml";
2
2
  /**
3
3
  * Converts a Collection object to YAML format with proper schema reference
4
+ * Supports both collection and table terminology based on configuration
4
5
  */
5
- export function collectionToYaml(collection, schemaPath = "../.yaml_schemas/collection.schema.json") {
6
+ export function collectionToYaml(collection, config = {
7
+ useTableTerminology: false,
8
+ entityType: 'collection',
9
+ schemaPath: "../.yaml_schemas/collection.schema.json"
10
+ }) {
11
+ const schemaPath = config.schemaPath || (config.useTableTerminology ? "../.yaml_schemas/table.schema.json" : "../.yaml_schemas/collection.schema.json");
6
12
  // Convert Collection to YamlCollectionData format
7
13
  const yamlData = {
8
14
  name: collection.name,
@@ -17,9 +23,9 @@ export function collectionToYaml(collection, schemaPath = "../.yaml_schemas/coll
17
23
  target: p.target
18
24
  }));
19
25
  }
20
- // Convert attributes
26
+ // Convert attributes/columns based on terminology
21
27
  if (collection.attributes && collection.attributes.length > 0) {
22
- yamlData.attributes = collection.attributes.map(attr => {
28
+ const attributeArray = collection.attributes.map(attr => {
23
29
  const yamlAttr = {
24
30
  key: attr.key,
25
31
  type: attr.type,
@@ -53,15 +59,31 @@ export function collectionToYaml(collection, schemaPath = "../.yaml_schemas/coll
53
59
  yamlAttr.side = attr.side;
54
60
  return yamlAttr;
55
61
  });
62
+ // Use appropriate terminology
63
+ if (config.useTableTerminology) {
64
+ yamlData.columns = attributeArray;
65
+ }
66
+ else {
67
+ yamlData.attributes = attributeArray;
68
+ }
56
69
  }
57
- // Convert indexes
70
+ // Convert indexes with appropriate field references
58
71
  if (collection.indexes && collection.indexes.length > 0) {
59
- yamlData.indexes = collection.indexes.map(idx => ({
60
- key: idx.key,
61
- type: idx.type,
62
- attributes: idx.attributes,
63
- ...(idx.orders && idx.orders.length > 0 ? { orders: idx.orders } : {})
64
- }));
72
+ yamlData.indexes = collection.indexes.map(idx => {
73
+ const indexData = {
74
+ key: idx.key,
75
+ type: idx.type,
76
+ ...(idx.orders && idx.orders.length > 0 ? { orders: idx.orders } : {})
77
+ };
78
+ // Use appropriate field terminology for index references
79
+ if (config.useTableTerminology) {
80
+ indexData.columns = idx.attributes;
81
+ }
82
+ else {
83
+ indexData.attributes = idx.attributes;
84
+ }
85
+ return indexData;
86
+ });
65
87
  }
66
88
  // Add import definitions if they exist
67
89
  if (collection.importDefs && collection.importDefs.length > 0) {
@@ -78,8 +100,10 @@ export function collectionToYaml(collection, schemaPath = "../.yaml_schemas/coll
78
100
  quotingType: '"',
79
101
  forceQuotes: false,
80
102
  });
103
+ // Determine the appropriate schema comment based on configuration
104
+ const entityType = config.useTableTerminology ? 'Table' : 'Collection';
81
105
  return `# yaml-language-server: $schema=${schemaPath}
82
- # Collection Definition: ${collection.name}
106
+ # ${entityType} Definition: ${collection.name}
83
107
  ${yamlContent}`;
84
108
  }
85
109
  /**
@@ -89,8 +113,203 @@ export function sanitizeFilename(name) {
89
113
  return name.replace(/[^a-zA-Z0-9_-]/g, '_');
90
114
  }
91
115
  /**
92
- * Generates the filename for a collection YAML file
116
+ * Generates the filename for a collection/table YAML file
93
117
  */
94
- export function getCollectionYamlFilename(collection) {
118
+ export function getCollectionYamlFilename(collection, useTableTerminology = false) {
95
119
  return `${sanitizeFilename(collection.name)}.yaml`;
96
120
  }
121
+ /**
122
+ * Converts column terminology back to attribute terminology for loading
123
+ */
124
+ export function normalizeYamlData(yamlData) {
125
+ const normalized = { ...yamlData };
126
+ // Convert columns to attributes if present
127
+ if (yamlData.columns && !yamlData.attributes) {
128
+ normalized.attributes = yamlData.columns.map(col => ({
129
+ ...col,
130
+ // Convert table-specific fields back to collection terminology
131
+ relatedCollection: col.relatedTable || col.relatedCollection,
132
+ }));
133
+ delete normalized.columns;
134
+ }
135
+ // Normalize index field references
136
+ if (normalized.indexes) {
137
+ normalized.indexes = normalized.indexes.map(idx => ({
138
+ ...idx,
139
+ attributes: idx.columns || idx.attributes,
140
+ // Remove columns field after normalization
141
+ columns: undefined
142
+ }));
143
+ }
144
+ return normalized;
145
+ }
146
+ /**
147
+ * Determines if YAML data uses table terminology
148
+ */
149
+ export function usesTableTerminology(yamlData) {
150
+ return !!(yamlData.columns && yamlData.columns.length > 0) ||
151
+ !!(yamlData.indexes?.some(idx => !!idx.columns));
152
+ }
153
+ /**
154
+ * Converts between attribute and column terminology
155
+ */
156
+ export function convertTerminology(yamlData, toTableTerminology) {
157
+ if (toTableTerminology) {
158
+ // Convert attributes to columns
159
+ const converted = { ...yamlData };
160
+ if (yamlData.attributes) {
161
+ converted.columns = yamlData.attributes.map(attr => ({
162
+ ...attr,
163
+ relatedTable: attr.relatedCollection,
164
+ relatedCollection: undefined
165
+ }));
166
+ delete converted.attributes;
167
+ }
168
+ // Convert index references
169
+ if (converted.indexes) {
170
+ converted.indexes = converted.indexes.map(idx => ({
171
+ ...idx,
172
+ columns: idx.attributes,
173
+ attributes: idx.attributes // Keep both for compatibility
174
+ }));
175
+ }
176
+ return converted;
177
+ }
178
+ else {
179
+ // Convert columns to attributes (normalize)
180
+ return normalizeYamlData(yamlData);
181
+ }
182
+ }
183
+ /**
184
+ * Generates a template YAML file for collections or tables
185
+ */
186
+ export function generateYamlTemplate(entityName, config) {
187
+ const entityType = config.useTableTerminology ? 'table' : 'collection';
188
+ const fieldsKey = config.useTableTerminology ? 'columns' : 'attributes';
189
+ const relationKey = config.useTableTerminology ? 'relatedTable' : 'relatedCollection';
190
+ const indexFieldsKey = config.useTableTerminology ? 'columns' : 'attributes';
191
+ // Build template dynamically to handle computed property names
192
+ const fieldsArray = [
193
+ {
194
+ key: "id",
195
+ type: "string",
196
+ required: true,
197
+ size: 36
198
+ },
199
+ {
200
+ key: "name",
201
+ type: "string",
202
+ required: true,
203
+ size: 255
204
+ },
205
+ {
206
+ key: "description",
207
+ type: "string",
208
+ required: false,
209
+ size: 1000
210
+ },
211
+ {
212
+ key: "isActive",
213
+ type: "boolean",
214
+ required: true,
215
+ default: true
216
+ },
217
+ {
218
+ key: "createdAt",
219
+ type: "datetime",
220
+ required: true
221
+ },
222
+ {
223
+ key: "tags",
224
+ type: "string",
225
+ array: true,
226
+ required: false
227
+ },
228
+ {
229
+ key: "categoryId",
230
+ type: "relationship",
231
+ relationType: "manyToOne",
232
+ [relationKey]: "Categories",
233
+ required: false,
234
+ onDelete: "setNull"
235
+ }
236
+ ];
237
+ const indexesArray = [
238
+ {
239
+ key: "name_index",
240
+ type: "key",
241
+ [indexFieldsKey]: ["name"]
242
+ },
243
+ {
244
+ key: "active_created_index",
245
+ type: "key",
246
+ [indexFieldsKey]: ["isActive", "createdAt"],
247
+ orders: ["asc", "desc"]
248
+ },
249
+ {
250
+ key: "name_fulltext",
251
+ type: "fulltext",
252
+ [indexFieldsKey]: ["name", "description"]
253
+ }
254
+ ];
255
+ const template = {
256
+ name: entityName,
257
+ id: entityName.toLowerCase().replace(/\s+/g, '_'),
258
+ documentSecurity: false,
259
+ enabled: true,
260
+ permissions: [
261
+ {
262
+ permission: "read",
263
+ target: "users"
264
+ },
265
+ {
266
+ permission: "create",
267
+ target: "users"
268
+ },
269
+ {
270
+ permission: "update",
271
+ target: "users"
272
+ },
273
+ {
274
+ permission: "delete",
275
+ target: "users"
276
+ }
277
+ ],
278
+ importDefs: []
279
+ };
280
+ // Assign fields with correct property name
281
+ template[fieldsKey] = fieldsArray;
282
+ template.indexes = indexesArray;
283
+ // Generate YAML content
284
+ const yamlContent = yaml.dump(template, {
285
+ indent: 2,
286
+ lineWidth: 120,
287
+ sortKeys: false,
288
+ quotingType: '"',
289
+ forceQuotes: false,
290
+ });
291
+ // Add schema reference and documentation
292
+ const schemaPath = config.schemaPath ||
293
+ (config.useTableTerminology ? "../.yaml_schemas/table.schema.json" : "../.yaml_schemas/collection.schema.json");
294
+ const documentation = config.useTableTerminology
295
+ ? `# Table Definition: ${entityName}\n# This file defines a table for the new TablesDB API\n#\n# Key differences from Collections:\n# - Uses 'columns' instead of 'attributes'\n# - Uses 'relatedTable' instead of 'relatedCollection'\n# - Indexes reference 'columns' instead of 'attributes'\n#\n`
296
+ : `# Collection Definition: ${entityName}\n# This file defines a collection for the legacy Databases API\n#\n# Note: For new projects, consider using TablesDB API with table definitions\n#\n`;
297
+ return `# yaml-language-server: $schema=${schemaPath}\n${documentation}${yamlContent}`;
298
+ }
299
+ /**
300
+ * Generates example YAML files for both collection and table formats
301
+ */
302
+ export function generateExampleYamls(entityName) {
303
+ const collectionYaml = generateYamlTemplate(entityName, {
304
+ useTableTerminology: false,
305
+ entityType: 'collection'
306
+ });
307
+ const tableYaml = generateYamlTemplate(entityName, {
308
+ useTableTerminology: true,
309
+ entityType: 'table'
310
+ });
311
+ return {
312
+ collection: collectionYaml,
313
+ table: tableYaml
314
+ };
315
+ }
@@ -0,0 +1,70 @@
1
+ import { type YamlCollectionData, type YamlTerminologyConfig } from "./yamlConverter.js";
2
+ import type { CollectionCreate } from "appwrite-utils";
3
+ /**
4
+ * Enhanced YAML loader with dual terminology support
5
+ */
6
+ export declare class YamlLoader {
7
+ private baseDirectory;
8
+ constructor(baseDirectory: string);
9
+ /**
10
+ * Loads a YAML file with automatic terminology detection and normalization
11
+ */
12
+ loadCollectionYaml(filePath: string): Promise<{
13
+ data: YamlCollectionData;
14
+ originalTerminology: 'collection' | 'table';
15
+ normalized: YamlCollectionData;
16
+ }>;
17
+ /**
18
+ * Loads multiple YAML files from a directory with terminology support
19
+ */
20
+ loadDirectoryYamls(directoryPath: string, targetTerminology?: 'collection' | 'table'): Promise<{
21
+ collections: Array<{
22
+ filePath: string;
23
+ data: YamlCollectionData;
24
+ originalTerminology: 'collection' | 'table';
25
+ converted?: YamlCollectionData;
26
+ }>;
27
+ summary: {
28
+ total: number;
29
+ collectionFormat: number;
30
+ tableFormat: number;
31
+ converted: number;
32
+ };
33
+ }>;
34
+ /**
35
+ * Converts YAML data to CollectionCreate format for internal use
36
+ */
37
+ yamlToCollectionCreate(yamlData: YamlCollectionData): CollectionCreate;
38
+ /**
39
+ * Saves YAML data with specified terminology
40
+ */
41
+ saveCollectionYaml(filePath: string, data: YamlCollectionData, config: YamlTerminologyConfig): Promise<void>;
42
+ /**
43
+ * Migrates YAML files from one terminology to another
44
+ */
45
+ migrateTerminology(sourceDirectory: string, targetDirectory: string, toTableTerminology: boolean): Promise<{
46
+ migrated: number;
47
+ skipped: number;
48
+ errors: string[];
49
+ }>;
50
+ /**
51
+ * Validates YAML files for terminology consistency
52
+ */
53
+ validateTerminologyConsistency(directoryPath: string): Promise<{
54
+ isConsistent: boolean;
55
+ issues: Array<{
56
+ file: string;
57
+ issue: string;
58
+ severity: 'warning' | 'error';
59
+ }>;
60
+ summary: {
61
+ collectionFiles: number;
62
+ tableFiles: number;
63
+ mixedFiles: number;
64
+ };
65
+ }>;
66
+ }
67
+ /**
68
+ * Creates a YAML loader instance for the given base directory
69
+ */
70
+ export declare function createYamlLoader(baseDirectory: string): YamlLoader;