appwrite-utils-cli 1.11.0 → 1.12.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 (250) hide show
  1. package/{src/adapters/index.ts → dist/adapters/index.d.ts} +0 -1
  2. package/dist/adapters/index.js +10 -0
  3. package/dist/backups/operations/bucketBackup.d.ts +19 -0
  4. package/dist/backups/operations/bucketBackup.js +197 -0
  5. package/dist/backups/operations/collectionBackup.d.ts +30 -0
  6. package/dist/backups/operations/collectionBackup.js +201 -0
  7. package/dist/backups/operations/comprehensiveBackup.d.ts +25 -0
  8. package/dist/backups/operations/comprehensiveBackup.js +238 -0
  9. package/dist/backups/schemas/bucketManifest.d.ts +93 -0
  10. package/dist/backups/schemas/bucketManifest.js +33 -0
  11. package/dist/backups/schemas/comprehensiveManifest.d.ts +108 -0
  12. package/dist/backups/schemas/comprehensiveManifest.js +32 -0
  13. package/dist/backups/tracking/centralizedTracking.d.ts +34 -0
  14. package/dist/backups/tracking/centralizedTracking.js +274 -0
  15. package/dist/cli/commands/configCommands.d.ts +8 -0
  16. package/dist/cli/commands/configCommands.js +210 -0
  17. package/dist/cli/commands/databaseCommands.d.ts +14 -0
  18. package/dist/cli/commands/databaseCommands.js +696 -0
  19. package/dist/cli/commands/functionCommands.d.ts +7 -0
  20. package/dist/cli/commands/functionCommands.js +330 -0
  21. package/dist/cli/commands/importFileCommands.d.ts +7 -0
  22. package/dist/cli/commands/importFileCommands.js +674 -0
  23. package/dist/cli/commands/schemaCommands.d.ts +7 -0
  24. package/dist/cli/commands/schemaCommands.js +169 -0
  25. package/dist/cli/commands/storageCommands.d.ts +5 -0
  26. package/dist/cli/commands/storageCommands.js +142 -0
  27. package/dist/cli/commands/transferCommands.d.ts +5 -0
  28. package/dist/cli/commands/transferCommands.js +382 -0
  29. package/dist/collections/columns.d.ts +13 -0
  30. package/dist/collections/columns.js +1339 -0
  31. package/dist/collections/indexes.d.ts +12 -0
  32. package/dist/collections/indexes.js +215 -0
  33. package/dist/collections/methods.d.ts +19 -0
  34. package/dist/collections/methods.js +605 -0
  35. package/dist/collections/tableOperations.d.ts +87 -0
  36. package/dist/collections/tableOperations.js +466 -0
  37. package/dist/collections/transferOperations.d.ts +8 -0
  38. package/dist/collections/transferOperations.js +411 -0
  39. package/dist/collections/wipeOperations.d.ts +17 -0
  40. package/dist/collections/wipeOperations.js +306 -0
  41. package/dist/databases/methods.d.ts +6 -0
  42. package/dist/databases/methods.js +35 -0
  43. package/dist/databases/setup.d.ts +5 -0
  44. package/dist/databases/setup.js +45 -0
  45. package/dist/examples/yamlTerminologyExample.d.ts +42 -0
  46. package/dist/examples/yamlTerminologyExample.js +272 -0
  47. package/dist/functions/deployments.d.ts +4 -0
  48. package/dist/functions/deployments.js +146 -0
  49. package/dist/functions/fnConfigDiscovery.d.ts +3 -0
  50. package/dist/functions/fnConfigDiscovery.js +108 -0
  51. package/dist/functions/methods.d.ts +16 -0
  52. package/dist/functions/methods.js +174 -0
  53. package/dist/init.d.ts +2 -0
  54. package/dist/init.js +57 -0
  55. package/dist/interactiveCLI.d.ts +36 -0
  56. package/dist/interactiveCLI.js +952 -0
  57. package/dist/main.d.ts +2 -0
  58. package/dist/main.js +1125 -0
  59. package/dist/migrations/afterImportActions.d.ts +17 -0
  60. package/dist/migrations/afterImportActions.js +305 -0
  61. package/dist/migrations/appwriteToX.d.ts +211 -0
  62. package/dist/migrations/appwriteToX.js +493 -0
  63. package/dist/migrations/comprehensiveTransfer.d.ts +147 -0
  64. package/dist/migrations/comprehensiveTransfer.js +1315 -0
  65. package/dist/migrations/dataLoader.d.ts +755 -0
  66. package/dist/migrations/dataLoader.js +1272 -0
  67. package/dist/migrations/importController.d.ts +25 -0
  68. package/dist/migrations/importController.js +283 -0
  69. package/dist/migrations/importDataActions.d.ts +50 -0
  70. package/dist/migrations/importDataActions.js +230 -0
  71. package/dist/migrations/relationships.d.ts +29 -0
  72. package/dist/migrations/relationships.js +203 -0
  73. package/dist/migrations/services/DataTransformationService.d.ts +55 -0
  74. package/dist/migrations/services/DataTransformationService.js +158 -0
  75. package/dist/migrations/services/FileHandlerService.d.ts +75 -0
  76. package/dist/migrations/services/FileHandlerService.js +236 -0
  77. package/dist/migrations/services/ImportOrchestrator.d.ts +99 -0
  78. package/dist/migrations/services/ImportOrchestrator.js +493 -0
  79. package/dist/migrations/services/RateLimitManager.d.ts +138 -0
  80. package/dist/migrations/services/RateLimitManager.js +279 -0
  81. package/dist/migrations/services/RelationshipResolver.d.ts +120 -0
  82. package/dist/migrations/services/RelationshipResolver.js +332 -0
  83. package/dist/migrations/services/UserMappingService.d.ts +109 -0
  84. package/dist/migrations/services/UserMappingService.js +277 -0
  85. package/dist/migrations/services/ValidationService.d.ts +74 -0
  86. package/dist/migrations/services/ValidationService.js +260 -0
  87. package/dist/migrations/transfer.d.ts +30 -0
  88. package/dist/migrations/transfer.js +661 -0
  89. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +131 -0
  90. package/dist/migrations/yaml/YamlImportConfigLoader.js +383 -0
  91. package/dist/migrations/yaml/YamlImportIntegration.d.ts +93 -0
  92. package/dist/migrations/yaml/YamlImportIntegration.js +341 -0
  93. package/dist/migrations/yaml/generateImportSchemas.d.ts +30 -0
  94. package/dist/migrations/yaml/generateImportSchemas.js +1327 -0
  95. package/dist/schemas/authUser.d.ts +24 -0
  96. package/dist/schemas/authUser.js +17 -0
  97. package/dist/setup.d.ts +2 -0
  98. package/{src/setup.ts → dist/setup.js} +0 -3
  99. package/dist/setupCommands.d.ts +58 -0
  100. package/dist/setupCommands.js +489 -0
  101. package/dist/setupController.d.ts +9 -0
  102. package/dist/setupController.js +34 -0
  103. package/dist/shared/backupMetadataSchema.d.ts +94 -0
  104. package/dist/shared/backupMetadataSchema.js +38 -0
  105. package/dist/shared/backupTracking.d.ts +18 -0
  106. package/dist/shared/backupTracking.js +176 -0
  107. package/dist/shared/confirmationDialogs.d.ts +75 -0
  108. package/dist/shared/confirmationDialogs.js +236 -0
  109. package/dist/shared/migrationHelpers.d.ts +61 -0
  110. package/dist/shared/migrationHelpers.js +145 -0
  111. package/{src/shared/operationLogger.ts → dist/shared/operationLogger.d.ts} +1 -11
  112. package/dist/shared/operationLogger.js +12 -0
  113. package/dist/shared/operationQueue.d.ts +40 -0
  114. package/dist/shared/operationQueue.js +310 -0
  115. package/dist/shared/operationsTable.d.ts +26 -0
  116. package/dist/shared/operationsTable.js +287 -0
  117. package/dist/shared/operationsTableSchema.d.ts +48 -0
  118. package/dist/shared/operationsTableSchema.js +35 -0
  119. package/dist/shared/progressManager.d.ts +62 -0
  120. package/dist/shared/progressManager.js +215 -0
  121. package/dist/shared/relationshipExtractor.d.ts +56 -0
  122. package/dist/shared/relationshipExtractor.js +138 -0
  123. package/dist/shared/selectionDialogs.d.ts +220 -0
  124. package/dist/shared/selectionDialogs.js +588 -0
  125. package/dist/storage/backupCompression.d.ts +20 -0
  126. package/dist/storage/backupCompression.js +67 -0
  127. package/dist/storage/methods.d.ts +44 -0
  128. package/dist/storage/methods.js +475 -0
  129. package/dist/storage/schemas.d.ts +842 -0
  130. package/dist/storage/schemas.js +175 -0
  131. package/dist/tables/indexManager.d.ts +65 -0
  132. package/dist/tables/indexManager.js +294 -0
  133. package/{src/types.ts → dist/types.d.ts} +1 -6
  134. package/dist/types.js +3 -0
  135. package/dist/users/methods.d.ts +16 -0
  136. package/dist/users/methods.js +276 -0
  137. package/dist/utils/configMigration.d.ts +1 -0
  138. package/dist/utils/configMigration.js +261 -0
  139. package/dist/utils/index.js +2 -0
  140. package/dist/utils/loadConfigs.d.ts +50 -0
  141. package/dist/utils/loadConfigs.js +357 -0
  142. package/dist/utils/setupFiles.d.ts +4 -0
  143. package/dist/utils/setupFiles.js +1190 -0
  144. package/dist/utilsController.d.ts +114 -0
  145. package/dist/utilsController.js +898 -0
  146. package/package.json +6 -3
  147. package/CHANGELOG.md +0 -35
  148. package/CONFIG_TODO.md +0 -1189
  149. package/SELECTION_DIALOGS.md +0 -146
  150. package/SERVICE_IMPLEMENTATION_REPORT.md +0 -462
  151. package/scripts/copy-templates.ts +0 -23
  152. package/src/backups/operations/bucketBackup.ts +0 -277
  153. package/src/backups/operations/collectionBackup.ts +0 -310
  154. package/src/backups/operations/comprehensiveBackup.ts +0 -342
  155. package/src/backups/schemas/bucketManifest.ts +0 -78
  156. package/src/backups/schemas/comprehensiveManifest.ts +0 -76
  157. package/src/backups/tracking/centralizedTracking.ts +0 -352
  158. package/src/cli/commands/configCommands.ts +0 -265
  159. package/src/cli/commands/databaseCommands.ts +0 -931
  160. package/src/cli/commands/functionCommands.ts +0 -419
  161. package/src/cli/commands/importFileCommands.ts +0 -815
  162. package/src/cli/commands/schemaCommands.ts +0 -200
  163. package/src/cli/commands/storageCommands.ts +0 -151
  164. package/src/cli/commands/transferCommands.ts +0 -454
  165. package/src/collections/attributes.ts.backup +0 -1555
  166. package/src/collections/columns.ts +0 -2025
  167. package/src/collections/indexes.ts +0 -350
  168. package/src/collections/methods.ts +0 -714
  169. package/src/collections/tableOperations.ts +0 -542
  170. package/src/collections/transferOperations.ts +0 -589
  171. package/src/collections/wipeOperations.ts +0 -449
  172. package/src/databases/methods.ts +0 -49
  173. package/src/databases/setup.ts +0 -77
  174. package/src/examples/yamlTerminologyExample.ts +0 -346
  175. package/src/functions/deployments.ts +0 -221
  176. package/src/functions/fnConfigDiscovery.ts +0 -103
  177. package/src/functions/methods.ts +0 -284
  178. package/src/init.ts +0 -62
  179. package/src/interactiveCLI.ts +0 -1201
  180. package/src/main.ts +0 -1517
  181. package/src/migrations/afterImportActions.ts +0 -579
  182. package/src/migrations/appwriteToX.ts +0 -668
  183. package/src/migrations/comprehensiveTransfer.ts +0 -2285
  184. package/src/migrations/dataLoader.ts +0 -1729
  185. package/src/migrations/importController.ts +0 -440
  186. package/src/migrations/importDataActions.ts +0 -315
  187. package/src/migrations/relationships.ts +0 -333
  188. package/src/migrations/services/DataTransformationService.ts +0 -196
  189. package/src/migrations/services/FileHandlerService.ts +0 -311
  190. package/src/migrations/services/ImportOrchestrator.ts +0 -675
  191. package/src/migrations/services/RateLimitManager.ts +0 -363
  192. package/src/migrations/services/RelationshipResolver.ts +0 -461
  193. package/src/migrations/services/UserMappingService.ts +0 -345
  194. package/src/migrations/services/ValidationService.ts +0 -349
  195. package/src/migrations/transfer.ts +0 -1113
  196. package/src/migrations/yaml/YamlImportConfigLoader.ts +0 -439
  197. package/src/migrations/yaml/YamlImportIntegration.ts +0 -446
  198. package/src/migrations/yaml/generateImportSchemas.ts +0 -1354
  199. package/src/schemas/authUser.ts +0 -23
  200. package/src/setupCommands.ts +0 -602
  201. package/src/setupController.ts +0 -43
  202. package/src/shared/backupMetadataSchema.ts +0 -93
  203. package/src/shared/backupTracking.ts +0 -211
  204. package/src/shared/confirmationDialogs.ts +0 -327
  205. package/src/shared/migrationHelpers.ts +0 -232
  206. package/src/shared/operationQueue.ts +0 -376
  207. package/src/shared/operationsTable.ts +0 -338
  208. package/src/shared/operationsTableSchema.ts +0 -60
  209. package/src/shared/progressManager.ts +0 -278
  210. package/src/shared/relationshipExtractor.ts +0 -214
  211. package/src/shared/selectionDialogs.ts +0 -802
  212. package/src/storage/backupCompression.ts +0 -88
  213. package/src/storage/methods.ts +0 -711
  214. package/src/storage/schemas.ts +0 -205
  215. package/src/tables/indexManager.ts +0 -409
  216. package/src/types/node-appwrite-tablesdb.d.ts +0 -44
  217. package/src/users/methods.ts +0 -358
  218. package/src/utils/configMigration.ts +0 -348
  219. package/src/utils/loadConfigs.ts +0 -457
  220. package/src/utils/setupFiles.ts +0 -1236
  221. package/src/utilsController.ts +0 -1263
  222. package/tests/README.md +0 -497
  223. package/tests/adapters/AdapterFactory.test.ts +0 -277
  224. package/tests/integration/syncOperations.test.ts +0 -463
  225. package/tests/jest.config.js +0 -25
  226. package/tests/migration/configMigration.test.ts +0 -546
  227. package/tests/setup.ts +0 -62
  228. package/tests/testUtils.ts +0 -340
  229. package/tests/utils/loadConfigs.test.ts +0 -350
  230. package/tests/validation/configValidation.test.ts +0 -412
  231. package/tsconfig.json +0 -44
  232. /package/{src → dist}/functions/templates/count-docs-in-collection/README.md +0 -0
  233. /package/{src → dist}/functions/templates/count-docs-in-collection/src/main.ts +0 -0
  234. /package/{src → dist}/functions/templates/count-docs-in-collection/src/request.ts +0 -0
  235. /package/{src → dist}/functions/templates/hono-typescript/README.md +0 -0
  236. /package/{src → dist}/functions/templates/hono-typescript/src/adapters/request.ts +0 -0
  237. /package/{src → dist}/functions/templates/hono-typescript/src/adapters/response.ts +0 -0
  238. /package/{src → dist}/functions/templates/hono-typescript/src/app.ts +0 -0
  239. /package/{src → dist}/functions/templates/hono-typescript/src/context.ts +0 -0
  240. /package/{src → dist}/functions/templates/hono-typescript/src/main.ts +0 -0
  241. /package/{src → dist}/functions/templates/hono-typescript/src/middleware/appwrite.ts +0 -0
  242. /package/{src → dist}/functions/templates/typescript-node/README.md +0 -0
  243. /package/{src → dist}/functions/templates/typescript-node/src/context.ts +0 -0
  244. /package/{src → dist}/functions/templates/typescript-node/src/main.ts +0 -0
  245. /package/{src → dist}/functions/templates/uv/README.md +0 -0
  246. /package/{src → dist}/functions/templates/uv/pyproject.toml +0 -0
  247. /package/{src → dist}/functions/templates/uv/src/__init__.py +0 -0
  248. /package/{src → dist}/functions/templates/uv/src/context.py +0 -0
  249. /package/{src → dist}/functions/templates/uv/src/main.py +0 -0
  250. /package/{src/utils/index.ts → dist/utils/index.d.ts} +0 -0
@@ -1,340 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { tmpdir } from 'os';
4
- import { randomBytes } from 'crypto';
5
- import { type AppwriteConfig, type CollectionCreate } from 'appwrite-utils';
6
-
7
- /**
8
- * Test utilities for creating temporary directories and test fixtures
9
- */
10
- export class TestUtils {
11
- private static tempDirs: string[] = [];
12
-
13
- /**
14
- * Creates a temporary directory for testing
15
- */
16
- static createTempDir(prefix = 'appwrite-test'): string {
17
- const tempDir = path.join(tmpdir(), `${prefix}-${randomBytes(8).toString('hex')}`);
18
- fs.mkdirSync(tempDir, { recursive: true });
19
- this.tempDirs.push(tempDir);
20
- return tempDir;
21
- }
22
-
23
- /**
24
- * Cleans up all created temporary directories
25
- */
26
- static cleanup(): void {
27
- this.tempDirs.forEach(dir => {
28
- try {
29
- fs.rmSync(dir, { recursive: true, force: true });
30
- } catch (error) {
31
- // Ignore cleanup errors
32
- }
33
- });
34
- this.tempDirs = [];
35
- }
36
-
37
- /**
38
- * Creates a test appwrite config
39
- */
40
- static createTestAppwriteConfig(overrides: Partial<AppwriteConfig> = {}): AppwriteConfig {
41
- return {
42
- appwriteEndpoint: 'http://localhost:8080/v1',
43
- appwriteProject: 'test-project',
44
- appwriteKey: 'test-key',
45
- databases: [
46
- {
47
- name: 'test-database',
48
- $id: 'test-db-id',
49
- enabled: true,
50
- }
51
- ],
52
- buckets: [],
53
- teams: [],
54
- functions: [],
55
- messaging: [],
56
- collections: [],
57
- ...overrides,
58
- };
59
- }
60
-
61
- /**
62
- * Creates a test collection configuration
63
- */
64
- static createTestCollection(overrides: Partial<CollectionCreate> = {}): CollectionCreate {
65
- return {
66
- name: 'TestCollection',
67
- $id: 'test-collection',
68
- documentSecurity: false,
69
- enabled: true,
70
- $permissions: [],
71
- attributes: [
72
- {
73
- key: 'name',
74
- type: 'string',
75
- size: 255,
76
- required: true,
77
- array: false,
78
- },
79
- {
80
- key: 'email',
81
- type: 'email',
82
- required: true,
83
- array: false,
84
- }
85
- ],
86
- indexes: [
87
- {
88
- key: 'email_index',
89
- type: 'unique',
90
- attributes: ['email'],
91
- }
92
- ],
93
- ...overrides,
94
- };
95
- }
96
-
97
- /**
98
- * Creates a test table configuration (tables API)
99
- */
100
- static createTestTable(overrides: any = {}): any {
101
- return {
102
- name: 'TestTable',
103
- tableId: 'test-table',
104
- databaseId: 'test-db-id',
105
- documentSecurity: false,
106
- enabled: true,
107
- $permissions: [],
108
- attributes: [
109
- {
110
- key: 'title',
111
- type: 'string',
112
- size: 255,
113
- required: true,
114
- array: false,
115
- },
116
- {
117
- key: 'count',
118
- type: 'integer',
119
- required: false,
120
- min: 0,
121
- max: 1000,
122
- }
123
- ],
124
- indexes: [
125
- {
126
- key: 'title_index',
127
- type: 'key',
128
- attributes: ['title'],
129
- }
130
- ],
131
- _isFromTablesDir: true,
132
- ...overrides,
133
- };
134
- }
135
-
136
- /**
137
- * Creates a test project structure with collections and/or tables
138
- */
139
- static createTestProject(options: {
140
- hasCollections?: boolean;
141
- hasTables?: boolean;
142
- hasConflicts?: boolean;
143
- useYaml?: boolean;
144
- configDir?: string;
145
- } = {}): string {
146
- const {
147
- hasCollections = true,
148
- hasTables = false,
149
- hasConflicts = false,
150
- useYaml = false,
151
- configDir,
152
- } = options;
153
-
154
- const testDir = configDir || this.createTempDir('test-project');
155
-
156
- // Create .appwrite directory
157
- const appwriteDir = path.join(testDir, '.appwrite');
158
- fs.mkdirSync(appwriteDir, { recursive: true });
159
-
160
- // Create config file
161
- const config = this.createTestAppwriteConfig();
162
- if (useYaml) {
163
- const yamlContent = `
164
- appwriteEndpoint: ${config.appwriteEndpoint}
165
- appwriteProject: ${config.appwriteProject}
166
- appwriteKey: ${config.appwriteKey}
167
- databases:
168
- - name: ${config.databases[0].name}
169
- $id: ${config.databases[0].$id}
170
- enabled: ${config.databases[0].enabled}
171
- buckets: []
172
- teams: []
173
- functions: []
174
- messaging: []
175
- `;
176
- fs.writeFileSync(path.join(appwriteDir, 'config.yaml'), yamlContent);
177
- } else {
178
- const tsContent = `
179
- import { type AppwriteConfig } from 'appwrite-utils';
180
-
181
- const appwriteConfig: AppwriteConfig = ${JSON.stringify(config, null, 2)};
182
-
183
- export default appwriteConfig;
184
- `;
185
- fs.writeFileSync(path.join(testDir, 'appwriteConfig.ts'), tsContent);
186
- }
187
-
188
- // Create collections directory if requested
189
- if (hasCollections) {
190
- const collectionsDir = path.join(testDir, 'collections');
191
- fs.mkdirSync(collectionsDir);
192
-
193
- const collection = this.createTestCollection();
194
- if (useYaml) {
195
- const yamlContent = `
196
- name: ${collection.name}
197
- id: ${collection.$id}
198
- documentSecurity: ${collection.documentSecurity}
199
- enabled: ${collection.enabled}
200
- permissions: []
201
- attributes:
202
- - key: name
203
- type: string
204
- size: 255
205
- required: true
206
- - key: email
207
- type: email
208
- required: true
209
- indexes:
210
- - key: email_index
211
- type: unique
212
- attributes: [email]
213
- `;
214
- fs.writeFileSync(path.join(collectionsDir, 'TestCollection.yaml'), yamlContent);
215
- } else {
216
- const tsContent = `
217
- import { type CollectionCreate } from 'appwrite-utils';
218
-
219
- const TestCollection: CollectionCreate = ${JSON.stringify(collection, null, 2)};
220
-
221
- export default TestCollection;
222
- `;
223
- fs.writeFileSync(path.join(collectionsDir, 'TestCollection.ts'), tsContent);
224
- }
225
- }
226
-
227
- // Create tables directory if requested
228
- if (hasTables) {
229
- const tablesDir = path.join(testDir, 'tables');
230
- fs.mkdirSync(tablesDir);
231
-
232
- const table = this.createTestTable();
233
- if (useYaml) {
234
- const yamlContent = `
235
- name: ${table.name}
236
- tableId: ${table.tableId}
237
- databaseId: ${table.databaseId}
238
- documentSecurity: ${table.documentSecurity}
239
- enabled: ${table.enabled}
240
- permissions: []
241
- attributes:
242
- - key: title
243
- type: string
244
- size: 255
245
- required: true
246
- - key: count
247
- type: integer
248
- required: false
249
- min: 0
250
- max: 1000
251
- indexes:
252
- - key: title_index
253
- type: key
254
- attributes: [title]
255
- `;
256
- fs.writeFileSync(path.join(tablesDir, 'TestTable.yaml'), yamlContent);
257
- } else {
258
- const tsContent = `
259
- import { type TableCreate } from 'appwrite-utils';
260
-
261
- const TestTable: any = ${JSON.stringify(table, null, 2)};
262
-
263
- export default TestTable;
264
- `;
265
- fs.writeFileSync(path.join(tablesDir, 'TestTable.ts'), tsContent);
266
- }
267
-
268
- // Create conflicting collection if requested
269
- if (hasConflicts && hasCollections) {
270
- const conflictTable = this.createTestTable({
271
- name: 'TestCollection', // Same name as collection
272
- tableId: 'test-collection-conflict'
273
- });
274
- const tsContent = `
275
- const ConflictTable: any = ${JSON.stringify(conflictTable, null, 2)};
276
- export default ConflictTable;
277
- `;
278
- fs.writeFileSync(path.join(tablesDir, 'ConflictTable.ts'), tsContent);
279
- }
280
- }
281
-
282
- return testDir;
283
- }
284
-
285
- /**
286
- * Creates mock Appwrite client responses
287
- */
288
- static createMockAppwriteResponses() {
289
- return {
290
- databases: {
291
- list: jest.fn().mockResolvedValue({
292
- databases: [
293
- {
294
- $id: 'test-db-id',
295
- name: 'test-database',
296
- enabled: true,
297
- $createdAt: new Date().toISOString(),
298
- $updatedAt: new Date().toISOString(),
299
- }
300
- ],
301
- total: 1,
302
- }),
303
- get: jest.fn().mockResolvedValue({
304
- $id: 'test-db-id',
305
- name: 'test-database',
306
- enabled: true,
307
- $createdAt: new Date().toISOString(),
308
- $updatedAt: new Date().toISOString(),
309
- }),
310
- listCollections: jest.fn().mockResolvedValue({
311
- collections: [
312
- {
313
- $id: 'test-collection',
314
- name: 'TestCollection',
315
- enabled: true,
316
- documentSecurity: false,
317
- $permissions: [],
318
- attributes: [],
319
- indexes: [],
320
- $createdAt: new Date().toISOString(),
321
- $updatedAt: new Date().toISOString(),
322
- }
323
- ],
324
- total: 1,
325
- }),
326
- },
327
- health: {
328
- get: jest.fn().mockResolvedValue({
329
- status: 'OK',
330
- version: '1.6.0',
331
- }),
332
- },
333
- };
334
- }
335
- }
336
-
337
- // Clean up after all tests
338
- afterAll(() => {
339
- TestUtils.cleanup();
340
- });
@@ -1,350 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import { jest } from '@jest/globals';
4
- import { TestUtils } from '../testUtils';
5
- import { loadConfig, loadConfigWithPath, findAppwriteConfig } from '../../src/utils/loadConfigs';
6
- import { MessageFormatter } from '../../src/shared/messageFormatter';
7
-
8
- // Mock MessageFormatter to capture log messages
9
- jest.mock('../../src/shared/messageFormatter', () => ({
10
- MessageFormatter: {
11
- success: jest.fn(),
12
- warning: jest.fn(),
13
- info: jest.fn(),
14
- error: jest.fn(),
15
- },
16
- }));
17
-
18
- // Mock version detection
19
- jest.mock('../../src/utils/versionDetection', () => ({
20
- detectAppwriteVersionCached: jest.fn().mockResolvedValue({
21
- serverVersion: '1.6.0',
22
- apiMode: 'database',
23
- }),
24
- fetchServerVersion: jest.fn().mockResolvedValue('1.6.0'),
25
- isVersionAtLeast: jest.fn((version, target) => {
26
- if (!version) return false;
27
- return version >= target;
28
- }),
29
- }));
30
-
31
- describe('loadConfigs - Dual Schema Support', () => {
32
- let testDir: string;
33
-
34
- beforeEach(() => {
35
- jest.clearAllMocks();
36
- });
37
-
38
- afterEach(() => {
39
- TestUtils.cleanup();
40
- });
41
-
42
- describe('findAppwriteConfig', () => {
43
- it('should find YAML config in .appwrite directory', () => {
44
- testDir = TestUtils.createTestProject({ useYaml: true });
45
- const configPath = findAppwriteConfig(testDir);
46
- expect(configPath).toBe(testDir);
47
- });
48
-
49
- it('should find TypeScript config as fallback', () => {
50
- testDir = TestUtils.createTestProject({ useYaml: false });
51
- const configPath = findAppwriteConfig(testDir);
52
- expect(configPath).toBe(testDir);
53
- });
54
-
55
- it('should return null when no config found', () => {
56
- testDir = TestUtils.createTempDir();
57
- const configPath = findAppwriteConfig(testDir);
58
- expect(configPath).toBeNull();
59
- });
60
- });
61
-
62
- describe('Dual Folder Loading', () => {
63
- it('should load collections from collections/ directory only', async () => {
64
- testDir = TestUtils.createTestProject({
65
- hasCollections: true,
66
- hasTables: false,
67
- });
68
-
69
- const config = await loadConfig(testDir);
70
-
71
- expect(config.collections).toHaveLength(1);
72
- expect(config.collections[0].name).toBe('TestCollection');
73
- expect(config.collections[0]._isFromTablesDir).toBeUndefined();
74
- expect(MessageFormatter.success).toHaveBeenCalledWith(
75
- 'Loading from collections/ directory: 1 files found',
76
- { prefix: 'Config' }
77
- );
78
- });
79
-
80
- it('should load tables from tables/ directory only', async () => {
81
- testDir = TestUtils.createTestProject({
82
- hasCollections: false,
83
- hasTables: true,
84
- });
85
-
86
- const config = await loadConfig(testDir);
87
-
88
- expect(config.collections).toHaveLength(1);
89
- expect(config.collections[0].name).toBe('TestTable');
90
- expect(config.collections[0]._isFromTablesDir).toBe(true);
91
- expect(MessageFormatter.success).toHaveBeenCalledWith(
92
- 'Loading from tables/ directory: 1 files found',
93
- { prefix: 'Config' }
94
- );
95
- });
96
-
97
- it('should load from both collections/ and tables/ directories', async () => {
98
- testDir = TestUtils.createTestProject({
99
- hasCollections: true,
100
- hasTables: true,
101
- });
102
-
103
- const config = await loadConfig(testDir);
104
-
105
- expect(config.collections).toHaveLength(2);
106
-
107
- const collection = config.collections.find((c: any) => !c._isFromTablesDir);
108
- const table = config.collections.find((c: any) => c._isFromTablesDir);
109
-
110
- expect(collection).toBeDefined();
111
- expect(collection.name).toBe('TestCollection');
112
-
113
- expect(table).toBeDefined();
114
- expect(table.name).toBe('TestTable');
115
- expect(table._isFromTablesDir).toBe(true);
116
-
117
- expect(MessageFormatter.success).toHaveBeenCalledWith(
118
- 'Loading from collections/ directory: 1 files found',
119
- { prefix: 'Config' }
120
- );
121
- expect(MessageFormatter.success).toHaveBeenCalledWith(
122
- 'Loading from tables/ directory: 1 files found',
123
- { prefix: 'Config' }
124
- );
125
- });
126
-
127
- it('should handle naming conflicts with collections/ taking priority', async () => {
128
- testDir = TestUtils.createTestProject({
129
- hasCollections: true,
130
- hasTables: true,
131
- hasConflicts: true,
132
- });
133
-
134
- const config = await loadConfig(testDir);
135
-
136
- // Should have 2 items: original collection + one table (conflict skipped)
137
- expect(config.collections).toHaveLength(2);
138
-
139
- // Check that the collection takes priority
140
- const collectionItems = config.collections.filter((c: any) => !c._isFromTablesDir);
141
- expect(collectionItems).toHaveLength(1);
142
- expect(collectionItems[0].name).toBe('TestCollection');
143
-
144
- // Check warning was logged
145
- expect(MessageFormatter.warning).toHaveBeenCalledWith(
146
- expect.stringContaining('Found 1 naming conflicts'),
147
- { prefix: 'Config' }
148
- );
149
- });
150
- });
151
-
152
- describe('YAML Support', () => {
153
- it('should load YAML collections', async () => {
154
- testDir = TestUtils.createTestProject({
155
- hasCollections: true,
156
- useYaml: true,
157
- });
158
-
159
- const config = await loadConfig(testDir);
160
-
161
- expect(config.collections).toHaveLength(1);
162
- expect(config.collections[0].name).toBe('TestCollection');
163
- expect(config.collections[0].$id).toBe('test-collection');
164
- expect(config.collections[0].attributes).toHaveLength(2);
165
- });
166
-
167
- it('should load YAML tables', async () => {
168
- testDir = TestUtils.createTestProject({
169
- hasTables: true,
170
- useYaml: true,
171
- });
172
-
173
- const config = await loadConfig(testDir);
174
-
175
- expect(config.collections).toHaveLength(1);
176
- expect(config.collections[0].name).toBe('TestTable');
177
- expect(config.collections[0]._isFromTablesDir).toBe(true);
178
- });
179
-
180
- it('should load mixed YAML and TypeScript files', async () => {
181
- testDir = TestUtils.createTestProject({
182
- hasCollections: true,
183
- useYaml: false,
184
- });
185
-
186
- // Add a YAML table alongside TypeScript collection
187
- const tablesDir = path.join(testDir, 'tables');
188
- fs.mkdirSync(tablesDir);
189
-
190
- const yamlContent = `
191
- name: YamlTable
192
- tableId: yaml-table
193
- databaseId: test-db-id
194
- documentSecurity: false
195
- enabled: true
196
- permissions: []
197
- attributes:
198
- - key: content
199
- type: string
200
- size: 1000
201
- required: true
202
- indexes: []
203
- `;
204
- fs.writeFileSync(path.join(tablesDir, 'YamlTable.yaml'), yamlContent);
205
-
206
- const config = await loadConfig(testDir);
207
-
208
- expect(config.collections).toHaveLength(2);
209
- expect(config.collections.some((c: any) => c.name === 'TestCollection')).toBe(true);
210
- expect(config.collections.some((c: any) => c.name === 'YamlTable')).toBe(true);
211
- });
212
- });
213
-
214
- describe('Legacy Single Directory Support', () => {
215
- it('should fall back to legacy collections/ directory when no dual directories', async () => {
216
- testDir = TestUtils.createTempDir();
217
-
218
- // Create config without .appwrite structure
219
- const config = TestUtils.createTestAppwriteConfig();
220
- const tsContent = `
221
- import { type AppwriteConfig } from 'appwrite-utils';
222
- const appwriteConfig: AppwriteConfig = ${JSON.stringify(config, null, 2)};
223
- export default appwriteConfig;
224
- `;
225
- fs.writeFileSync(path.join(testDir, 'appwriteConfig.ts'), tsContent);
226
-
227
- // Create only collections directory (legacy)
228
- const collectionsDir = path.join(testDir, 'collections');
229
- fs.mkdirSync(collectionsDir);
230
-
231
- const collection = TestUtils.createTestCollection();
232
- const collectionContent = `
233
- const TestCollection = ${JSON.stringify(collection, null, 2)};
234
- export default TestCollection;
235
- `;
236
- fs.writeFileSync(path.join(collectionsDir, 'TestCollection.ts'), collectionContent);
237
-
238
- const loadedConfig = await loadConfig(testDir);
239
-
240
- expect(loadedConfig.collections).toHaveLength(1);
241
- expect(loadedConfig.collections[0].name).toBe('TestCollection');
242
- expect(MessageFormatter.info).toHaveBeenCalledWith(
243
- 'Using legacy single directory: collections/',
244
- { prefix: 'Config' }
245
- );
246
- });
247
- });
248
-
249
- describe('loadConfigWithPath', () => {
250
- it('should return both config and actual config path', async () => {
251
- testDir = TestUtils.createTestProject({ useYaml: true });
252
-
253
- const result = await loadConfigWithPath(testDir);
254
-
255
- expect(result.config).toBeDefined();
256
- expect(result.actualConfigPath).toContain('config.yaml');
257
- expect(result.config.appwriteProject).toBe('test-project');
258
- });
259
-
260
- it('should handle .appwrite directory path directly', async () => {
261
- testDir = TestUtils.createTestProject({ useYaml: true });
262
- const appwriteDir = path.join(testDir, '.appwrite');
263
-
264
- const result = await loadConfigWithPath(appwriteDir);
265
-
266
- expect(result.config).toBeDefined();
267
- expect(result.actualConfigPath).toContain('config.yaml');
268
- });
269
- });
270
-
271
- describe('Error Handling', () => {
272
- it('should throw error when no config found', async () => {
273
- testDir = TestUtils.createTempDir();
274
-
275
- await expect(loadConfig(testDir)).rejects.toThrow('No valid configuration found');
276
- });
277
-
278
- it('should handle malformed YAML gracefully', async () => {
279
- testDir = TestUtils.createTestProject({ useYaml: true });
280
-
281
- // Create malformed YAML collection
282
- const collectionsDir = path.join(testDir, 'collections');
283
- fs.writeFileSync(path.join(collectionsDir, 'BadCollection.yaml'), 'invalid: yaml: content:');
284
-
285
- const config = await loadConfig(testDir);
286
-
287
- // Should still load other valid collections
288
- expect(config).toBeDefined();
289
- // The malformed collection should be skipped
290
- });
291
-
292
- it('should handle missing TypeScript exports gracefully', async () => {
293
- testDir = TestUtils.createTestProject({ useYaml: false });
294
-
295
- // Create TypeScript file with no export
296
- const collectionsDir = path.join(testDir, 'collections');
297
- fs.writeFileSync(path.join(collectionsDir, 'NoExport.ts'), 'const collection = {};');
298
-
299
- const config = await loadConfig(testDir);
300
-
301
- expect(config).toBeDefined();
302
- // Should still have the original test collection
303
- expect(config.collections.length).toBeGreaterThanOrEqual(1);
304
- });
305
- });
306
-
307
- describe('Performance and Scalability', () => {
308
- it('should handle large numbers of collections and tables', async () => {
309
- testDir = TestUtils.createTempDir();
310
-
311
- // Create config
312
- const config = TestUtils.createTestAppwriteConfig();
313
- const tsContent = `export default ${JSON.stringify(config, null, 2)};`;
314
- fs.writeFileSync(path.join(testDir, 'appwriteConfig.ts'), tsContent);
315
-
316
- // Create many collections
317
- const collectionsDir = path.join(testDir, 'collections');
318
- fs.mkdirSync(collectionsDir);
319
-
320
- for (let i = 0; i < 50; i++) {
321
- const collection = TestUtils.createTestCollection({
322
- name: `Collection${i}`,
323
- $id: `collection-${i}`,
324
- });
325
- const content = `export default ${JSON.stringify(collection, null, 2)};`;
326
- fs.writeFileSync(path.join(collectionsDir, `Collection${i}.ts`), content);
327
- }
328
-
329
- // Create many tables
330
- const tablesDir = path.join(testDir, 'tables');
331
- fs.mkdirSync(tablesDir);
332
-
333
- for (let i = 0; i < 30; i++) {
334
- const table = TestUtils.createTestTable({
335
- name: `Table${i}`,
336
- tableId: `table-${i}`,
337
- });
338
- const content = `export default ${JSON.stringify(table, null, 2)};`;
339
- fs.writeFileSync(path.join(tablesDir, `Table${i}.ts`), content);
340
- }
341
-
342
- const startTime = Date.now();
343
- const loadedConfig = await loadConfig(testDir);
344
- const loadTime = Date.now() - startTime;
345
-
346
- expect(loadedConfig.collections).toHaveLength(80); // 50 collections + 30 tables
347
- expect(loadTime).toBeLessThan(5000); // Should load within 5 seconds
348
- });
349
- });
350
- });