@njdamstra/appwrite-utils-cli 1.8.9

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 (392) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +1133 -0
  3. package/dist/adapters/AdapterFactory.d.ts +94 -0
  4. package/dist/adapters/AdapterFactory.js +405 -0
  5. package/dist/adapters/DatabaseAdapter.d.ts +233 -0
  6. package/dist/adapters/DatabaseAdapter.js +50 -0
  7. package/dist/adapters/LegacyAdapter.d.ts +50 -0
  8. package/dist/adapters/LegacyAdapter.js +612 -0
  9. package/dist/adapters/TablesDBAdapter.d.ts +45 -0
  10. package/dist/adapters/TablesDBAdapter.js +571 -0
  11. package/dist/adapters/index.d.ts +11 -0
  12. package/dist/adapters/index.js +12 -0
  13. package/dist/backups/operations/bucketBackup.d.ts +19 -0
  14. package/dist/backups/operations/bucketBackup.js +197 -0
  15. package/dist/backups/operations/collectionBackup.d.ts +30 -0
  16. package/dist/backups/operations/collectionBackup.js +201 -0
  17. package/dist/backups/operations/comprehensiveBackup.d.ts +25 -0
  18. package/dist/backups/operations/comprehensiveBackup.js +238 -0
  19. package/dist/backups/schemas/bucketManifest.d.ts +93 -0
  20. package/dist/backups/schemas/bucketManifest.js +33 -0
  21. package/dist/backups/schemas/comprehensiveManifest.d.ts +108 -0
  22. package/dist/backups/schemas/comprehensiveManifest.js +32 -0
  23. package/dist/backups/tracking/centralizedTracking.d.ts +34 -0
  24. package/dist/backups/tracking/centralizedTracking.js +274 -0
  25. package/dist/cli/commands/configCommands.d.ts +8 -0
  26. package/dist/cli/commands/configCommands.js +166 -0
  27. package/dist/cli/commands/databaseCommands.d.ts +13 -0
  28. package/dist/cli/commands/databaseCommands.js +554 -0
  29. package/dist/cli/commands/functionCommands.d.ts +7 -0
  30. package/dist/cli/commands/functionCommands.js +330 -0
  31. package/dist/cli/commands/schemaCommands.d.ts +7 -0
  32. package/dist/cli/commands/schemaCommands.js +169 -0
  33. package/dist/cli/commands/storageCommands.d.ts +5 -0
  34. package/dist/cli/commands/storageCommands.js +143 -0
  35. package/dist/cli/commands/transferCommands.d.ts +5 -0
  36. package/dist/cli/commands/transferCommands.js +384 -0
  37. package/dist/collections/attributes.d.ts +13 -0
  38. package/dist/collections/attributes.js +1364 -0
  39. package/dist/collections/indexes.d.ts +12 -0
  40. package/dist/collections/indexes.js +217 -0
  41. package/dist/collections/methods.d.ts +19 -0
  42. package/dist/collections/methods.js +682 -0
  43. package/dist/collections/tableOperations.d.ts +86 -0
  44. package/dist/collections/tableOperations.js +434 -0
  45. package/dist/collections/transferOperations.d.ts +8 -0
  46. package/dist/collections/transferOperations.js +412 -0
  47. package/dist/collections/wipeOperations.d.ts +16 -0
  48. package/dist/collections/wipeOperations.js +233 -0
  49. package/dist/config/ConfigManager.d.ts +445 -0
  50. package/dist/config/ConfigManager.js +625 -0
  51. package/dist/config/configMigration.d.ts +87 -0
  52. package/dist/config/configMigration.js +390 -0
  53. package/dist/config/configValidation.d.ts +66 -0
  54. package/dist/config/configValidation.js +358 -0
  55. package/dist/config/index.d.ts +8 -0
  56. package/dist/config/index.js +7 -0
  57. package/dist/config/services/ConfigDiscoveryService.d.ts +126 -0
  58. package/dist/config/services/ConfigDiscoveryService.js +374 -0
  59. package/dist/config/services/ConfigLoaderService.d.ts +129 -0
  60. package/dist/config/services/ConfigLoaderService.js +540 -0
  61. package/dist/config/services/ConfigMergeService.d.ts +208 -0
  62. package/dist/config/services/ConfigMergeService.js +308 -0
  63. package/dist/config/services/ConfigValidationService.d.ts +214 -0
  64. package/dist/config/services/ConfigValidationService.js +310 -0
  65. package/dist/config/services/SessionAuthService.d.ts +225 -0
  66. package/dist/config/services/SessionAuthService.js +456 -0
  67. package/dist/config/services/__tests__/ConfigMergeService.test.d.ts +1 -0
  68. package/dist/config/services/__tests__/ConfigMergeService.test.js +271 -0
  69. package/dist/config/services/index.d.ts +13 -0
  70. package/dist/config/services/index.js +10 -0
  71. package/dist/config/yamlConfig.d.ts +722 -0
  72. package/dist/config/yamlConfig.js +702 -0
  73. package/dist/databases/methods.d.ts +6 -0
  74. package/dist/databases/methods.js +35 -0
  75. package/dist/databases/setup.d.ts +5 -0
  76. package/dist/databases/setup.js +45 -0
  77. package/dist/examples/yamlTerminologyExample.d.ts +42 -0
  78. package/dist/examples/yamlTerminologyExample.js +272 -0
  79. package/dist/functions/deployments.d.ts +4 -0
  80. package/dist/functions/deployments.js +146 -0
  81. package/dist/functions/fnConfigDiscovery.d.ts +3 -0
  82. package/dist/functions/fnConfigDiscovery.js +108 -0
  83. package/dist/functions/methods.d.ts +16 -0
  84. package/dist/functions/methods.js +162 -0
  85. package/dist/functions/pathResolution.d.ts +37 -0
  86. package/dist/functions/pathResolution.js +185 -0
  87. package/dist/functions/templates/count-docs-in-collection/README.md +54 -0
  88. package/dist/functions/templates/count-docs-in-collection/src/main.ts +159 -0
  89. package/dist/functions/templates/count-docs-in-collection/src/request.ts +9 -0
  90. package/dist/functions/templates/hono-typescript/README.md +286 -0
  91. package/dist/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
  92. package/dist/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
  93. package/dist/functions/templates/hono-typescript/src/app.ts +180 -0
  94. package/dist/functions/templates/hono-typescript/src/context.ts +103 -0
  95. package/dist/functions/templates/hono-typescript/src/index.ts +54 -0
  96. package/dist/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
  97. package/dist/functions/templates/typescript-node/README.md +32 -0
  98. package/dist/functions/templates/typescript-node/src/context.ts +103 -0
  99. package/dist/functions/templates/typescript-node/src/index.ts +29 -0
  100. package/dist/functions/templates/uv/README.md +31 -0
  101. package/dist/functions/templates/uv/pyproject.toml +30 -0
  102. package/dist/functions/templates/uv/src/__init__.py +0 -0
  103. package/dist/functions/templates/uv/src/context.py +125 -0
  104. package/dist/functions/templates/uv/src/index.py +46 -0
  105. package/dist/init.d.ts +2 -0
  106. package/dist/init.js +57 -0
  107. package/dist/interactiveCLI.d.ts +31 -0
  108. package/dist/interactiveCLI.js +898 -0
  109. package/dist/main.d.ts +2 -0
  110. package/dist/main.js +1172 -0
  111. package/dist/migrations/afterImportActions.d.ts +17 -0
  112. package/dist/migrations/afterImportActions.js +306 -0
  113. package/dist/migrations/appwriteToX.d.ts +211 -0
  114. package/dist/migrations/appwriteToX.js +491 -0
  115. package/dist/migrations/comprehensiveTransfer.d.ts +147 -0
  116. package/dist/migrations/comprehensiveTransfer.js +1317 -0
  117. package/dist/migrations/dataLoader.d.ts +753 -0
  118. package/dist/migrations/dataLoader.js +1250 -0
  119. package/dist/migrations/importController.d.ts +23 -0
  120. package/dist/migrations/importController.js +268 -0
  121. package/dist/migrations/importDataActions.d.ts +50 -0
  122. package/dist/migrations/importDataActions.js +230 -0
  123. package/dist/migrations/relationships.d.ts +29 -0
  124. package/dist/migrations/relationships.js +204 -0
  125. package/dist/migrations/services/DataTransformationService.d.ts +55 -0
  126. package/dist/migrations/services/DataTransformationService.js +158 -0
  127. package/dist/migrations/services/FileHandlerService.d.ts +75 -0
  128. package/dist/migrations/services/FileHandlerService.js +236 -0
  129. package/dist/migrations/services/ImportOrchestrator.d.ts +97 -0
  130. package/dist/migrations/services/ImportOrchestrator.js +485 -0
  131. package/dist/migrations/services/RateLimitManager.d.ts +138 -0
  132. package/dist/migrations/services/RateLimitManager.js +279 -0
  133. package/dist/migrations/services/RelationshipResolver.d.ts +120 -0
  134. package/dist/migrations/services/RelationshipResolver.js +332 -0
  135. package/dist/migrations/services/UserMappingService.d.ts +109 -0
  136. package/dist/migrations/services/UserMappingService.js +277 -0
  137. package/dist/migrations/services/ValidationService.d.ts +74 -0
  138. package/dist/migrations/services/ValidationService.js +260 -0
  139. package/dist/migrations/transfer.d.ts +26 -0
  140. package/dist/migrations/transfer.js +608 -0
  141. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +131 -0
  142. package/dist/migrations/yaml/YamlImportConfigLoader.js +383 -0
  143. package/dist/migrations/yaml/YamlImportIntegration.d.ts +93 -0
  144. package/dist/migrations/yaml/YamlImportIntegration.js +341 -0
  145. package/dist/migrations/yaml/generateImportSchemas.d.ts +30 -0
  146. package/dist/migrations/yaml/generateImportSchemas.js +1327 -0
  147. package/dist/schemas/authUser.d.ts +24 -0
  148. package/dist/schemas/authUser.js +17 -0
  149. package/dist/setup.d.ts +2 -0
  150. package/dist/setup.js +5 -0
  151. package/dist/setupCommands.d.ts +58 -0
  152. package/dist/setupCommands.js +490 -0
  153. package/dist/setupController.d.ts +9 -0
  154. package/dist/setupController.js +34 -0
  155. package/dist/shared/attributeMapper.d.ts +20 -0
  156. package/dist/shared/attributeMapper.js +203 -0
  157. package/dist/shared/backupMetadataSchema.d.ts +94 -0
  158. package/dist/shared/backupMetadataSchema.js +38 -0
  159. package/dist/shared/backupTracking.d.ts +18 -0
  160. package/dist/shared/backupTracking.js +176 -0
  161. package/dist/shared/confirmationDialogs.d.ts +75 -0
  162. package/dist/shared/confirmationDialogs.js +236 -0
  163. package/dist/shared/errorUtils.d.ts +54 -0
  164. package/dist/shared/errorUtils.js +95 -0
  165. package/dist/shared/functionManager.d.ts +48 -0
  166. package/dist/shared/functionManager.js +336 -0
  167. package/dist/shared/indexManager.d.ts +24 -0
  168. package/dist/shared/indexManager.js +151 -0
  169. package/dist/shared/jsonSchemaGenerator.d.ts +50 -0
  170. package/dist/shared/jsonSchemaGenerator.js +290 -0
  171. package/dist/shared/logging.d.ts +61 -0
  172. package/dist/shared/logging.js +116 -0
  173. package/dist/shared/messageFormatter.d.ts +39 -0
  174. package/dist/shared/messageFormatter.js +162 -0
  175. package/dist/shared/migrationHelpers.d.ts +61 -0
  176. package/dist/shared/migrationHelpers.js +145 -0
  177. package/dist/shared/operationLogger.d.ts +10 -0
  178. package/dist/shared/operationLogger.js +12 -0
  179. package/dist/shared/operationQueue.d.ts +40 -0
  180. package/dist/shared/operationQueue.js +311 -0
  181. package/dist/shared/operationsTable.d.ts +26 -0
  182. package/dist/shared/operationsTable.js +286 -0
  183. package/dist/shared/operationsTableSchema.d.ts +48 -0
  184. package/dist/shared/operationsTableSchema.js +35 -0
  185. package/dist/shared/progressManager.d.ts +62 -0
  186. package/dist/shared/progressManager.js +215 -0
  187. package/dist/shared/pydanticModelGenerator.d.ts +17 -0
  188. package/dist/shared/pydanticModelGenerator.js +615 -0
  189. package/dist/shared/relationshipExtractor.d.ts +56 -0
  190. package/dist/shared/relationshipExtractor.js +138 -0
  191. package/dist/shared/schemaGenerator.d.ts +40 -0
  192. package/dist/shared/schemaGenerator.js +556 -0
  193. package/dist/shared/selectionDialogs.d.ts +214 -0
  194. package/dist/shared/selectionDialogs.js +544 -0
  195. package/dist/storage/backupCompression.d.ts +20 -0
  196. package/dist/storage/backupCompression.js +67 -0
  197. package/dist/storage/methods.d.ts +32 -0
  198. package/dist/storage/methods.js +472 -0
  199. package/dist/storage/schemas.d.ts +842 -0
  200. package/dist/storage/schemas.js +175 -0
  201. package/dist/types.d.ts +4 -0
  202. package/dist/types.js +3 -0
  203. package/dist/users/methods.d.ts +16 -0
  204. package/dist/users/methods.js +277 -0
  205. package/dist/utils/ClientFactory.d.ts +87 -0
  206. package/dist/utils/ClientFactory.js +212 -0
  207. package/dist/utils/configDiscovery.d.ts +78 -0
  208. package/dist/utils/configDiscovery.js +472 -0
  209. package/dist/utils/configMigration.d.ts +1 -0
  210. package/dist/utils/configMigration.js +261 -0
  211. package/dist/utils/constantsGenerator.d.ts +31 -0
  212. package/dist/utils/constantsGenerator.js +321 -0
  213. package/dist/utils/dataConverters.d.ts +46 -0
  214. package/dist/utils/dataConverters.js +139 -0
  215. package/dist/utils/directoryUtils.d.ts +22 -0
  216. package/dist/utils/directoryUtils.js +59 -0
  217. package/dist/utils/getClientFromConfig.d.ts +39 -0
  218. package/dist/utils/getClientFromConfig.js +199 -0
  219. package/dist/utils/helperFunctions.d.ts +63 -0
  220. package/dist/utils/helperFunctions.js +156 -0
  221. package/dist/utils/index.d.ts +2 -0
  222. package/dist/utils/index.js +2 -0
  223. package/dist/utils/loadConfigs.d.ts +50 -0
  224. package/dist/utils/loadConfigs.js +358 -0
  225. package/dist/utils/pathResolvers.d.ts +53 -0
  226. package/dist/utils/pathResolvers.js +72 -0
  227. package/dist/utils/projectConfig.d.ts +119 -0
  228. package/dist/utils/projectConfig.js +171 -0
  229. package/dist/utils/retryFailedPromises.d.ts +2 -0
  230. package/dist/utils/retryFailedPromises.js +23 -0
  231. package/dist/utils/sessionAuth.d.ts +48 -0
  232. package/dist/utils/sessionAuth.js +164 -0
  233. package/dist/utils/setupFiles.d.ts +4 -0
  234. package/dist/utils/setupFiles.js +1192 -0
  235. package/dist/utils/typeGuards.d.ts +35 -0
  236. package/dist/utils/typeGuards.js +57 -0
  237. package/dist/utils/validationRules.d.ts +43 -0
  238. package/dist/utils/validationRules.js +42 -0
  239. package/dist/utils/versionDetection.d.ts +58 -0
  240. package/dist/utils/versionDetection.js +251 -0
  241. package/dist/utils/yamlConverter.d.ts +100 -0
  242. package/dist/utils/yamlConverter.js +428 -0
  243. package/dist/utils/yamlLoader.d.ts +70 -0
  244. package/dist/utils/yamlLoader.js +267 -0
  245. package/dist/utilsController.d.ts +106 -0
  246. package/dist/utilsController.js +863 -0
  247. package/package.json +75 -0
  248. package/scripts/copy-templates.ts +23 -0
  249. package/src/adapters/AdapterFactory.ts +510 -0
  250. package/src/adapters/DatabaseAdapter.ts +306 -0
  251. package/src/adapters/LegacyAdapter.ts +841 -0
  252. package/src/adapters/TablesDBAdapter.ts +773 -0
  253. package/src/adapters/index.ts +37 -0
  254. package/src/backups/operations/bucketBackup.ts +277 -0
  255. package/src/backups/operations/collectionBackup.ts +310 -0
  256. package/src/backups/operations/comprehensiveBackup.ts +342 -0
  257. package/src/backups/schemas/bucketManifest.ts +78 -0
  258. package/src/backups/schemas/comprehensiveManifest.ts +76 -0
  259. package/src/backups/tracking/centralizedTracking.ts +352 -0
  260. package/src/cli/commands/configCommands.ts +201 -0
  261. package/src/cli/commands/databaseCommands.ts +749 -0
  262. package/src/cli/commands/functionCommands.ts +418 -0
  263. package/src/cli/commands/schemaCommands.ts +200 -0
  264. package/src/cli/commands/storageCommands.ts +152 -0
  265. package/src/cli/commands/transferCommands.ts +457 -0
  266. package/src/collections/attributes.ts +2054 -0
  267. package/src/collections/attributes.ts.backup +1555 -0
  268. package/src/collections/indexes.ts +352 -0
  269. package/src/collections/methods.ts +745 -0
  270. package/src/collections/tableOperations.ts +506 -0
  271. package/src/collections/transferOperations.ts +590 -0
  272. package/src/collections/wipeOperations.ts +346 -0
  273. package/src/config/ConfigManager.ts +808 -0
  274. package/src/config/README.md +274 -0
  275. package/src/config/configMigration.ts +575 -0
  276. package/src/config/configValidation.ts +445 -0
  277. package/src/config/index.ts +10 -0
  278. package/src/config/services/ConfigDiscoveryService.ts +463 -0
  279. package/src/config/services/ConfigLoaderService.ts +740 -0
  280. package/src/config/services/ConfigMergeService.ts +388 -0
  281. package/src/config/services/ConfigValidationService.ts +394 -0
  282. package/src/config/services/SessionAuthService.ts +565 -0
  283. package/src/config/services/__tests__/ConfigMergeService.test.ts +351 -0
  284. package/src/config/services/index.ts +29 -0
  285. package/src/config/yamlConfig.ts +761 -0
  286. package/src/databases/methods.ts +49 -0
  287. package/src/databases/setup.ts +77 -0
  288. package/src/examples/yamlTerminologyExample.ts +346 -0
  289. package/src/functions/deployments.ts +220 -0
  290. package/src/functions/fnConfigDiscovery.ts +103 -0
  291. package/src/functions/methods.ts +271 -0
  292. package/src/functions/pathResolution.ts +227 -0
  293. package/src/functions/templates/count-docs-in-collection/README.md +54 -0
  294. package/src/functions/templates/count-docs-in-collection/src/main.ts +159 -0
  295. package/src/functions/templates/count-docs-in-collection/src/request.ts +9 -0
  296. package/src/functions/templates/hono-typescript/README.md +286 -0
  297. package/src/functions/templates/hono-typescript/src/adapters/request.ts +74 -0
  298. package/src/functions/templates/hono-typescript/src/adapters/response.ts +106 -0
  299. package/src/functions/templates/hono-typescript/src/app.ts +180 -0
  300. package/src/functions/templates/hono-typescript/src/context.ts +103 -0
  301. package/src/functions/templates/hono-typescript/src/index.ts +54 -0
  302. package/src/functions/templates/hono-typescript/src/middleware/appwrite.ts +119 -0
  303. package/src/functions/templates/typescript-node/README.md +32 -0
  304. package/src/functions/templates/typescript-node/src/context.ts +103 -0
  305. package/src/functions/templates/typescript-node/src/index.ts +29 -0
  306. package/src/functions/templates/uv/README.md +31 -0
  307. package/src/functions/templates/uv/pyproject.toml +30 -0
  308. package/src/functions/templates/uv/src/__init__.py +0 -0
  309. package/src/functions/templates/uv/src/context.py +125 -0
  310. package/src/functions/templates/uv/src/index.py +46 -0
  311. package/src/init.ts +62 -0
  312. package/src/interactiveCLI.ts +1136 -0
  313. package/src/main.ts +1661 -0
  314. package/src/migrations/afterImportActions.ts +580 -0
  315. package/src/migrations/appwriteToX.ts +664 -0
  316. package/src/migrations/comprehensiveTransfer.ts +2285 -0
  317. package/src/migrations/dataLoader.ts +1702 -0
  318. package/src/migrations/importController.ts +428 -0
  319. package/src/migrations/importDataActions.ts +315 -0
  320. package/src/migrations/relationships.ts +334 -0
  321. package/src/migrations/services/DataTransformationService.ts +196 -0
  322. package/src/migrations/services/FileHandlerService.ts +311 -0
  323. package/src/migrations/services/ImportOrchestrator.ts +666 -0
  324. package/src/migrations/services/RateLimitManager.ts +363 -0
  325. package/src/migrations/services/RelationshipResolver.ts +461 -0
  326. package/src/migrations/services/UserMappingService.ts +345 -0
  327. package/src/migrations/services/ValidationService.ts +349 -0
  328. package/src/migrations/transfer.ts +1068 -0
  329. package/src/migrations/yaml/YamlImportConfigLoader.ts +439 -0
  330. package/src/migrations/yaml/YamlImportIntegration.ts +446 -0
  331. package/src/migrations/yaml/generateImportSchemas.ts +1354 -0
  332. package/src/schemas/authUser.ts +23 -0
  333. package/src/setup.ts +8 -0
  334. package/src/setupCommands.ts +603 -0
  335. package/src/setupController.ts +43 -0
  336. package/src/shared/attributeMapper.ts +229 -0
  337. package/src/shared/backupMetadataSchema.ts +93 -0
  338. package/src/shared/backupTracking.ts +211 -0
  339. package/src/shared/confirmationDialogs.ts +327 -0
  340. package/src/shared/errorUtils.ts +110 -0
  341. package/src/shared/functionManager.ts +525 -0
  342. package/src/shared/indexManager.ts +254 -0
  343. package/src/shared/jsonSchemaGenerator.ts +383 -0
  344. package/src/shared/logging.ts +149 -0
  345. package/src/shared/messageFormatter.ts +208 -0
  346. package/src/shared/migrationHelpers.ts +232 -0
  347. package/src/shared/operationLogger.ts +20 -0
  348. package/src/shared/operationQueue.ts +377 -0
  349. package/src/shared/operationsTable.ts +338 -0
  350. package/src/shared/operationsTableSchema.ts +60 -0
  351. package/src/shared/progressManager.ts +278 -0
  352. package/src/shared/pydanticModelGenerator.ts +618 -0
  353. package/src/shared/relationshipExtractor.ts +214 -0
  354. package/src/shared/schemaGenerator.ts +644 -0
  355. package/src/shared/selectionDialogs.ts +749 -0
  356. package/src/storage/backupCompression.ts +88 -0
  357. package/src/storage/methods.ts +698 -0
  358. package/src/storage/schemas.ts +205 -0
  359. package/src/types/node-appwrite-tablesdb.d.ts +44 -0
  360. package/src/types.ts +9 -0
  361. package/src/users/methods.ts +359 -0
  362. package/src/utils/ClientFactory.ts +240 -0
  363. package/src/utils/configDiscovery.ts +557 -0
  364. package/src/utils/configMigration.ts +348 -0
  365. package/src/utils/constantsGenerator.ts +369 -0
  366. package/src/utils/dataConverters.ts +159 -0
  367. package/src/utils/directoryUtils.ts +61 -0
  368. package/src/utils/getClientFromConfig.ts +257 -0
  369. package/src/utils/helperFunctions.ts +228 -0
  370. package/src/utils/index.ts +2 -0
  371. package/src/utils/loadConfigs.ts +449 -0
  372. package/src/utils/pathResolvers.ts +81 -0
  373. package/src/utils/projectConfig.ts +299 -0
  374. package/src/utils/retryFailedPromises.ts +29 -0
  375. package/src/utils/sessionAuth.ts +230 -0
  376. package/src/utils/setupFiles.ts +1238 -0
  377. package/src/utils/typeGuards.ts +65 -0
  378. package/src/utils/validationRules.ts +88 -0
  379. package/src/utils/versionDetection.ts +292 -0
  380. package/src/utils/yamlConverter.ts +542 -0
  381. package/src/utils/yamlLoader.ts +371 -0
  382. package/src/utilsController.ts +1203 -0
  383. package/tests/README.md +497 -0
  384. package/tests/adapters/AdapterFactory.test.ts +277 -0
  385. package/tests/integration/syncOperations.test.ts +463 -0
  386. package/tests/jest.config.js +25 -0
  387. package/tests/migration/configMigration.test.ts +546 -0
  388. package/tests/setup.ts +62 -0
  389. package/tests/testUtils.ts +340 -0
  390. package/tests/utils/loadConfigs.test.ts +350 -0
  391. package/tests/validation/configValidation.test.ts +412 -0
  392. package/tsconfig.json +44 -0
@@ -0,0 +1,352 @@
1
+ import { indexSchema, type Index } from "@njdamstra/appwrite-utils";
2
+ import { Databases, IndexType, Query, type Models } from "node-appwrite";
3
+ import type { DatabaseAdapter } from "../adapters/DatabaseAdapter.js";
4
+ import { delay, tryAwaitWithRetry, calculateExponentialBackoff } from "../utils/helperFunctions.js";
5
+ import { isLegacyDatabases } from "../utils/typeGuards.js";
6
+ import { MessageFormatter } from "../shared/messageFormatter.js";
7
+
8
+ // System attributes that are always available for indexing in Appwrite
9
+ const SYSTEM_ATTRIBUTES = ['$id', '$createdAt', '$updatedAt', '$permissions'];
10
+
11
+ // Interface for index with status
12
+ interface IndexWithStatus {
13
+ key: string;
14
+ type: string;
15
+ status: 'available' | 'processing' | 'deleting' | 'stuck' | 'failed';
16
+ error: string;
17
+ attributes: string[];
18
+ orders?: string[];
19
+ $createdAt: string;
20
+ $updatedAt: string;
21
+ }
22
+
23
+ /**
24
+ * Wait for index to become available, with retry logic for stuck indexes and exponential backoff
25
+ */
26
+ const waitForIndexAvailable = async (
27
+ db: Databases | DatabaseAdapter,
28
+ dbId: string,
29
+ collectionId: string,
30
+ indexKey: string,
31
+ maxWaitTime: number = 60000, // 1 minute
32
+ retryCount: number = 0,
33
+ maxRetries: number = 5
34
+ ): Promise<boolean> => {
35
+ const startTime = Date.now();
36
+ let checkInterval = 2000; // Start with 2 seconds
37
+
38
+ // Calculate exponential backoff: 2s, 4s, 8s, 16s, 30s (capped at 30s)
39
+ if (retryCount > 0) {
40
+ const exponentialDelay = calculateExponentialBackoff(retryCount);
41
+ await delay(exponentialDelay);
42
+ }
43
+
44
+ while (Date.now() - startTime < maxWaitTime) {
45
+ try {
46
+ const indexList = await (isLegacyDatabases(db)
47
+ ? db.listIndexes(dbId, collectionId)
48
+ : (db as DatabaseAdapter).listIndexes({ databaseId: dbId, tableId: collectionId }));
49
+ const indexes: any[] = isLegacyDatabases(db)
50
+ ? (indexList as any).indexes
51
+ : ((indexList as any).data || (indexList as any).indexes || []);
52
+ const index = indexes.find((idx: any) => idx.key === indexKey) as IndexWithStatus | undefined;
53
+
54
+ if (!index) {
55
+ MessageFormatter.error(`Index '${indexKey}' not found in database '${dbId}' collection '${collectionId}'`);
56
+ return false;
57
+ }
58
+
59
+ switch (index.status) {
60
+ case 'available':
61
+ return true;
62
+
63
+ case 'failed':
64
+ MessageFormatter.error(`Index '${indexKey}' failed: ${index.error} (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
65
+ return false;
66
+
67
+ case 'stuck':
68
+ MessageFormatter.warning(`Index '${indexKey}' is stuck, will retry... (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
69
+ return false;
70
+
71
+ case 'processing':
72
+ // Continue waiting
73
+ break;
74
+
75
+ case 'deleting':
76
+ MessageFormatter.warning(`Index '${indexKey}' is being deleted`);
77
+ break;
78
+
79
+ default:
80
+ MessageFormatter.warning(`Unknown status '${index.status}' for index '${indexKey}'`);
81
+ break;
82
+ }
83
+
84
+ await delay(checkInterval);
85
+ } catch (error) {
86
+ MessageFormatter.error(`Error checking index '${indexKey}' status in database '${dbId}' collection '${collectionId}': ${error}`);
87
+ return false;
88
+ }
89
+ }
90
+
91
+ // Timeout reached
92
+ MessageFormatter.warning(`Timeout waiting for index '${indexKey}' (${maxWaitTime}ms)`);
93
+
94
+ // If we have retries left and this isn't the last retry, try recreating
95
+ if (retryCount < maxRetries) {
96
+ MessageFormatter.info(`Retrying index '${indexKey}' creation (attempt ${retryCount + 1}/${maxRetries})`);
97
+ return false; // Signal that we need to retry
98
+ }
99
+
100
+ return false;
101
+ };
102
+
103
+
104
+ /**
105
+ * Enhanced index creation with proper status monitoring and retry logic
106
+ */
107
+ export const createOrUpdateIndexWithStatusCheck = async (
108
+ dbId: string,
109
+ db: Databases,
110
+ collectionId: string,
111
+ collection: Models.Collection,
112
+ index: Index,
113
+ retryCount: number = 0,
114
+ maxRetries: number = 3,
115
+ ): Promise<boolean> => {
116
+ MessageFormatter.info(`Creating/updating index '${index.key}' (attempt ${retryCount + 1}/${maxRetries + 1}) - type: ${index.type}, attributes: [${index.attributes.join(', ')}]`);
117
+
118
+ try {
119
+ // First, validate that all required attributes exist
120
+ const freshCollection = await db.getCollection(dbId, collectionId);
121
+ const existingAttributeKeys = freshCollection.attributes.map((attr: any) => attr.key);
122
+
123
+ // Include system attributes that are always available
124
+ const allAvailableAttributes = [...existingAttributeKeys, ...SYSTEM_ATTRIBUTES];
125
+
126
+ const missingAttributes = index.attributes.filter(attr => !allAvailableAttributes.includes(attr));
127
+
128
+ if (missingAttributes.length > 0) {
129
+ MessageFormatter.error(`Index '${index.key}' cannot be created: missing attributes [${missingAttributes.join(', ')}] (type: ${index.type})`);
130
+ MessageFormatter.error(`Available attributes: [${existingAttributeKeys.join(', ')}, ${SYSTEM_ATTRIBUTES.join(', ')}]`);
131
+ return false; // Don't retry if attributes are missing
132
+ }
133
+
134
+ // Try to create/update the index using existing logic
135
+ await createOrUpdateIndex(dbId, db, collectionId, index);
136
+
137
+ // Now wait for the index to become available
138
+ const success = await waitForIndexAvailable(
139
+ db,
140
+ dbId,
141
+ collectionId,
142
+ index.key,
143
+ 60000, // 1 minute timeout
144
+ retryCount,
145
+ maxRetries
146
+ );
147
+
148
+ if (success) {
149
+ return true;
150
+ }
151
+
152
+ // If not successful and we have retries left, just retry the index creation
153
+ if (retryCount < maxRetries) {
154
+ MessageFormatter.warning(`Index '${index.key}' failed/stuck, retrying (${retryCount + 1}/${maxRetries}) - type: ${index.type}, attributes: [${index.attributes.join(', ')}]`);
155
+
156
+ // Wait a bit before retry
157
+ await new Promise(resolve => setTimeout(resolve, 2000 * (retryCount + 1)));
158
+
159
+ // Retry the index creation
160
+ return await createOrUpdateIndexWithStatusCheck(
161
+ dbId,
162
+ db,
163
+ collectionId,
164
+ collection,
165
+ index,
166
+ retryCount + 1,
167
+ maxRetries
168
+ );
169
+ }
170
+
171
+ MessageFormatter.error(`Failed to create index '${index.key}' after ${maxRetries + 1} attempts (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
172
+ return false;
173
+
174
+ } catch (error) {
175
+ const errorMessage = error instanceof Error ? error.message : String(error);
176
+ MessageFormatter.error(`Error creating index '${index.key}': ${errorMessage} (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
177
+
178
+ // Check if this is a permanent error that shouldn't be retried
179
+ if (errorMessage.toLowerCase().includes('not found') ||
180
+ errorMessage.toLowerCase().includes('missing') ||
181
+ errorMessage.toLowerCase().includes('does not exist') ||
182
+ errorMessage.toLowerCase().includes('attribute') && errorMessage.toLowerCase().includes('not found')) {
183
+ MessageFormatter.error(`Index '${index.key}' has permanent error - not retrying (type: ${index.type})`);
184
+ return false;
185
+ }
186
+
187
+ if (retryCount < maxRetries) {
188
+ MessageFormatter.warning(`Retrying index '${index.key}' due to error... (type: ${index.type}, attributes: [${index.attributes.join(', ')}])`);
189
+
190
+ // Wait a bit before retry
191
+ await delay(2000);
192
+
193
+ return await createOrUpdateIndexWithStatusCheck(
194
+ dbId,
195
+ db,
196
+ collectionId,
197
+ collection,
198
+ index,
199
+ retryCount + 1,
200
+ maxRetries
201
+ );
202
+ }
203
+
204
+ return false;
205
+ }
206
+ };
207
+
208
+ /**
209
+ * Enhanced index creation with status monitoring for all indexes
210
+ */
211
+ export const createOrUpdateIndexesWithStatusCheck = async (
212
+ dbId: string,
213
+ db: Databases,
214
+ collectionId: string,
215
+ collection: Models.Collection,
216
+ indexes: Index[]
217
+ ): Promise<boolean> => {
218
+ MessageFormatter.info(`Creating/updating ${indexes.length} indexes with status monitoring for collection '${collectionId}'`);
219
+
220
+ let indexesToProcess = [...indexes];
221
+ let overallRetryCount = 0;
222
+ const maxOverallRetries = 3;
223
+
224
+ while (indexesToProcess.length > 0 && overallRetryCount < maxOverallRetries) {
225
+ const remainingIndexes = [...indexesToProcess];
226
+ indexesToProcess = []; // Reset for next iteration
227
+
228
+ for (const index of remainingIndexes) {
229
+ const success = await createOrUpdateIndexWithStatusCheck(
230
+ dbId,
231
+ db,
232
+ collectionId,
233
+ collection,
234
+ index
235
+ );
236
+
237
+ if (success) {
238
+ MessageFormatter.info(`✅ ${index.key} (${index.type})`);
239
+
240
+ // Add delay between successful indexes
241
+ await delay(1000);
242
+ } else {
243
+ MessageFormatter.info(`❌ ${index.key} (${index.type})`);
244
+ indexesToProcess.push(index); // Add back to retry list
245
+ }
246
+ }
247
+
248
+ if (indexesToProcess.length === 0) {
249
+ return true;
250
+ }
251
+
252
+ overallRetryCount++;
253
+
254
+ if (overallRetryCount < maxOverallRetries) {
255
+ MessageFormatter.warning(`⏳ Retrying ${indexesToProcess.length} failed indexes...`);
256
+ await delay(5000);
257
+ }
258
+ }
259
+
260
+ // If we get here, some indexes still failed after all retries
261
+ if (indexesToProcess.length > 0) {
262
+ const failedIndexKeys = indexesToProcess.map(i => `${i.key} (${i.type})`).join(', ');
263
+ MessageFormatter.error(`\nFailed to create ${indexesToProcess.length} indexes after ${maxOverallRetries} attempts: ${failedIndexKeys}`);
264
+ MessageFormatter.error(`This may indicate a fundamental issue with the index definitions or Appwrite instance`);
265
+ return false;
266
+ }
267
+
268
+ MessageFormatter.success(`\nSuccessfully created all ${indexes.length} indexes for collection '${collectionId}'`);
269
+ return true;
270
+ };
271
+
272
+ export const createOrUpdateIndex = async (
273
+ dbId: string,
274
+ db: Databases,
275
+ collectionId: string,
276
+ index: Index
277
+ ) => {
278
+ const existingIndex = await db.listIndexes(dbId, collectionId, [
279
+ Query.equal("key", index.key),
280
+ ]);
281
+
282
+ let createIndex = false;
283
+ let newIndex: Models.Index | null = null;
284
+
285
+ if (existingIndex.total === 0) {
286
+ // No existing index, create it
287
+ createIndex = true;
288
+ } else {
289
+ const existing = existingIndex.indexes[0];
290
+
291
+ // Check key and type
292
+ const keyMatches = existing.key === index.key;
293
+ const typeMatches = existing.type === index.type;
294
+
295
+ // Compare attributes as SETS (order doesn't matter, only content)
296
+ const existingAttrsSet = new Set(existing.attributes);
297
+ const newAttrsSet = new Set(index.attributes);
298
+ const attributesMatch =
299
+ existingAttrsSet.size === newAttrsSet.size &&
300
+ [...existingAttrsSet].every(attr => newAttrsSet.has(attr));
301
+
302
+ // Compare orders as SETS if both exist (order doesn't matter)
303
+ let ordersMatch = true;
304
+ if (index.orders && existing.orders) {
305
+ const existingOrdersSet = new Set(existing.orders);
306
+ const newOrdersSet = new Set(index.orders);
307
+ ordersMatch =
308
+ existingOrdersSet.size === newOrdersSet.size &&
309
+ [...existingOrdersSet].every(ord => newOrdersSet.has(ord));
310
+ }
311
+
312
+ // Only recreate if something genuinely changed
313
+ if (!keyMatches || !typeMatches || !attributesMatch || !ordersMatch) {
314
+ await db.deleteIndex(dbId, collectionId, existing.key);
315
+ createIndex = true;
316
+ }
317
+ }
318
+
319
+ if (createIndex) {
320
+ // Ensure orders array exists and matches attributes length
321
+ // Default to "asc" for each attribute if not specified
322
+ const orders = index.orders && index.orders.length === index.attributes.length
323
+ ? index.orders
324
+ : index.attributes.map(() => "asc");
325
+
326
+ newIndex = await db.createIndex(
327
+ dbId,
328
+ collectionId,
329
+ index.key,
330
+ index.type as IndexType,
331
+ index.attributes,
332
+ orders
333
+ );
334
+ }
335
+
336
+ return newIndex;
337
+ };
338
+
339
+ export const createOrUpdateIndexes = async (
340
+ dbId: string,
341
+ db: Databases,
342
+ collectionId: string,
343
+ indexes: Index[]
344
+ ) => {
345
+ for (const index of indexes) {
346
+ await tryAwaitWithRetry(
347
+ async () => await createOrUpdateIndex(dbId, db, collectionId, index)
348
+ );
349
+ // Add delay after each index creation/update
350
+ await delay(500);
351
+ }
352
+ };