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
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ export declare const AuthUserSchema: z.ZodObject<{
3
+ $id: z.ZodString;
4
+ $createdAt: z.ZodOptional<z.ZodString>;
5
+ $updatedAt: z.ZodOptional<z.ZodString>;
6
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
7
+ email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
8
+ phone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
9
+ prefs: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
10
+ labels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
11
+ }, z.core.$strip>;
12
+ export type AuthUser = z.infer<typeof AuthUserSchema>;
13
+ export declare const AuthUserCreateSchema: z.ZodObject<{
14
+ email: z.ZodOptional<z.ZodNullable<z.ZodString>>;
15
+ name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
16
+ $createdAt: z.ZodOptional<z.ZodString>;
17
+ $updatedAt: z.ZodOptional<z.ZodString>;
18
+ phone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
19
+ prefs: z.ZodDefault<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>>;
20
+ labels: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString>>>;
21
+ userId: z.ZodOptional<z.ZodString>;
22
+ password: z.ZodOptional<z.ZodString>;
23
+ }, z.core.$strip>;
24
+ export type AuthUserCreate = z.infer<typeof AuthUserCreateSchema>;
@@ -0,0 +1,17 @@
1
+ import { z } from "zod";
2
+ export const AuthUserSchema = z.object({
3
+ $id: z.string(),
4
+ $createdAt: z.string().optional(),
5
+ $updatedAt: z.string().optional(),
6
+ name: z.string().nullish(),
7
+ email: z.string().email("Invalid Email Address").nullish(),
8
+ phone: z.string().nullish(),
9
+ prefs: z.record(z.string(), z.string()).optional().default({}),
10
+ labels: z.array(z.string()).optional().default([]),
11
+ });
12
+ export const AuthUserCreateSchema = AuthUserSchema.omit({
13
+ $id: true,
14
+ }).extend({
15
+ userId: z.string().optional(),
16
+ password: z.string().optional(),
17
+ });
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -1,8 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  import { setupDirsFiles } from "./utils/setupFiles.js";
3
-
4
3
  const args = process.argv.slice(2);
5
-
6
4
  const genExample = args.includes("--example");
7
-
8
5
  setupDirsFiles(genExample);
@@ -0,0 +1,58 @@
1
+ import { type ApiMode } from "appwrite-utils-helpers";
2
+ /**
3
+ * Terminology configuration for API mode-specific naming
4
+ */
5
+ interface TerminologyConfig {
6
+ container: "table" | "collection";
7
+ containerName: "Table" | "Collection";
8
+ fields: "columns" | "attributes";
9
+ fieldName: "Column" | "Attribute";
10
+ security: "rowSecurity" | "documentSecurity";
11
+ schemaRef: "table.schema.json" | "collection.schema.json";
12
+ items: "rows" | "documents";
13
+ }
14
+ /**
15
+ * Detection result with source information
16
+ */
17
+ interface ApiModeDetectionResult {
18
+ apiMode: ApiMode;
19
+ useTables: boolean;
20
+ detectionSource: "appwrite.json" | "server-version" | "default";
21
+ serverVersion?: string;
22
+ }
23
+ /**
24
+ * Get terminology configuration based on API mode
25
+ */
26
+ export declare function getTerminologyConfig(useTables: boolean): TerminologyConfig;
27
+ /**
28
+ * Detect API mode using multiple detection sources
29
+ * Priority: appwrite.json > server version > default (collections)
30
+ */
31
+ export declare function detectApiMode(basePath: string): Promise<ApiModeDetectionResult>;
32
+ /**
33
+ * Create directory structure for Appwrite project
34
+ */
35
+ export declare function createProjectDirectories(basePath: string, useTables: boolean): {
36
+ appwriteFolder: string;
37
+ containerFolder: string;
38
+ schemaFolder: string;
39
+ yamlSchemaFolder: string;
40
+ dataFolder: string;
41
+ };
42
+ /**
43
+ * Create example YAML schema file with correct terminology
44
+ */
45
+ export declare function createExampleSchema(containerFolder: string, terminology: TerminologyConfig): string;
46
+ /**
47
+ * Create JSON schema for YAML validation
48
+ */
49
+ export declare function createYamlValidationSchema(yamlSchemaFolder: string, useTables: boolean): string;
50
+ /**
51
+ * Initialize a new Appwrite project with correct directory structure and terminology
52
+ */
53
+ export declare function initProject(basePath?: string, forceApiMode?: 'legacy' | 'tablesdb'): Promise<void>;
54
+ /**
55
+ * Create a new collection or table schema file
56
+ */
57
+ export declare function createSchema(name: string, basePath?: string, forceApiMode?: 'legacy' | 'tablesdb'): Promise<void>;
58
+ export {};
@@ -0,0 +1,489 @@
1
+ import { mkdirSync, writeFileSync, existsSync } from "node:fs";
2
+ import path from "node:path";
3
+ import { ulid } from "ulidx";
4
+ import { MessageFormatter } from "appwrite-utils-helpers";
5
+ import { detectAppwriteVersionCached, fetchServerVersion, isVersionAtLeast } from "appwrite-utils-helpers";
6
+ import { loadAppwriteProjectConfig, findAppwriteProjectConfig, isTablesDBProject } from "appwrite-utils-helpers";
7
+ import { findYamlConfig, generateYamlConfigTemplate, loadYamlConfig } from "appwrite-utils-helpers";
8
+ import { hasSessionAuth } from "appwrite-utils-helpers";
9
+ /**
10
+ * Get terminology configuration based on API mode
11
+ */
12
+ export function getTerminologyConfig(useTables) {
13
+ return useTables
14
+ ? {
15
+ container: "table",
16
+ containerName: "Table",
17
+ fields: "columns",
18
+ fieldName: "Column",
19
+ security: "rowSecurity",
20
+ schemaRef: "table.schema.json",
21
+ items: "rows"
22
+ }
23
+ : {
24
+ container: "collection",
25
+ containerName: "Collection",
26
+ fields: "attributes",
27
+ fieldName: "Attribute",
28
+ security: "documentSecurity",
29
+ schemaRef: "collection.schema.json",
30
+ items: "documents"
31
+ };
32
+ }
33
+ /**
34
+ * Detect API mode using multiple detection sources
35
+ * Priority: appwrite.json > server version > default (collections)
36
+ */
37
+ export async function detectApiMode(basePath) {
38
+ let useTables = false;
39
+ let detectionSource = "default";
40
+ let serverVersion;
41
+ try {
42
+ // Priority 1: Check for existing appwrite.json project config
43
+ const projectConfigPath = findAppwriteProjectConfig(basePath);
44
+ if (projectConfigPath) {
45
+ const projectConfig = loadAppwriteProjectConfig(projectConfigPath);
46
+ if (projectConfig) {
47
+ useTables = isTablesDBProject(projectConfig);
48
+ detectionSource = "appwrite.json";
49
+ MessageFormatter.info(`Detected ${useTables ? 'TablesDB' : 'Collections'} project from ${projectConfigPath}`, { prefix: "Setup" });
50
+ return {
51
+ apiMode: useTables ? 'tablesdb' : 'legacy',
52
+ useTables,
53
+ detectionSource
54
+ };
55
+ }
56
+ }
57
+ // Priority 2: Try reading existing YAML config for version detection
58
+ const yamlPath = findYamlConfig(basePath);
59
+ if (yamlPath) {
60
+ const cfg = await loadYamlConfig(yamlPath);
61
+ if (cfg) {
62
+ const endpoint = cfg.appwriteEndpoint;
63
+ const projectId = cfg.appwriteProject;
64
+ if (hasSessionAuth(endpoint, projectId)) {
65
+ MessageFormatter.info("Using session authentication for version detection", { prefix: "Setup" });
66
+ }
67
+ const ver = await fetchServerVersion(endpoint);
68
+ serverVersion = ver || undefined;
69
+ if (isVersionAtLeast(ver || undefined, '1.8.0')) {
70
+ useTables = true;
71
+ detectionSource = "server-version";
72
+ MessageFormatter.info(`Detected TablesDB support (Appwrite ${ver})`, { prefix: "Setup" });
73
+ }
74
+ else {
75
+ MessageFormatter.info(`Using Collections API (Appwrite ${ver || 'unknown'})`, { prefix: "Setup" });
76
+ }
77
+ return {
78
+ apiMode: useTables ? 'tablesdb' : 'legacy',
79
+ useTables,
80
+ detectionSource,
81
+ serverVersion
82
+ };
83
+ }
84
+ }
85
+ }
86
+ catch (error) {
87
+ MessageFormatter.warning(`Version detection failed, defaulting to Collections API: ${error instanceof Error ? error.message : String(error)}`, { prefix: "Setup" });
88
+ }
89
+ // Default to Collections API
90
+ return {
91
+ apiMode: 'legacy',
92
+ useTables: false,
93
+ detectionSource: 'default'
94
+ };
95
+ }
96
+ /**
97
+ * Create directory structure for Appwrite project
98
+ */
99
+ export function createProjectDirectories(basePath, useTables) {
100
+ const appwriteFolder = path.join(basePath, ".appwrite");
101
+ const containerName = useTables ? "tables" : "collections";
102
+ const containerFolder = path.join(appwriteFolder, containerName);
103
+ const schemaFolder = path.join(appwriteFolder, "schemas");
104
+ const yamlSchemaFolder = path.join(appwriteFolder, ".yaml_schemas");
105
+ const dataFolder = path.join(appwriteFolder, "importData");
106
+ // Create all directories
107
+ for (const dir of [appwriteFolder, containerFolder, schemaFolder, yamlSchemaFolder, dataFolder]) {
108
+ if (!existsSync(dir)) {
109
+ mkdirSync(dir, { recursive: true });
110
+ }
111
+ }
112
+ return {
113
+ appwriteFolder,
114
+ containerFolder,
115
+ schemaFolder,
116
+ yamlSchemaFolder,
117
+ dataFolder
118
+ };
119
+ }
120
+ /**
121
+ * Create example YAML schema file with correct terminology
122
+ */
123
+ export function createExampleSchema(containerFolder, terminology) {
124
+ const yamlExample = `# yaml-language-server: $schema=../.yaml_schemas/${terminology.schemaRef}
125
+ # Example ${terminology.containerName} Definition
126
+ name: Example${terminology.containerName}
127
+ id: example_${terminology.container}_${Date.now()}
128
+ ${terminology.security}: false
129
+ enabled: true
130
+ permissions:
131
+ - permission: read
132
+ target: any
133
+ - permission: create
134
+ target: users
135
+ - permission: update
136
+ target: users
137
+ - permission: delete
138
+ target: users
139
+ ${terminology.fields}:
140
+ - key: title
141
+ type: string
142
+ size: 255
143
+ required: true
144
+ description: "The title of the item"
145
+ - key: description
146
+ type: string
147
+ size: 1000
148
+ required: false
149
+ description: "A longer description"
150
+ - key: isActive
151
+ type: boolean
152
+ required: false
153
+ default: true${terminology.container === 'table' ? `
154
+ - key: uniqueCode
155
+ type: string
156
+ size: 50
157
+ required: false
158
+ unique: true
159
+ description: "Unique identifier code (TablesDB feature)"` : ''}
160
+ indexes:
161
+ - key: title_search
162
+ type: fulltext
163
+ attributes:
164
+ - title
165
+ importDefs: []
166
+ `;
167
+ const examplePath = path.join(containerFolder, `Example${terminology.containerName}.yaml`);
168
+ writeFileSync(examplePath, yamlExample);
169
+ MessageFormatter.info(`Created example ${terminology.container} definition with ${terminology.fields} terminology`, { prefix: "Setup" });
170
+ return examplePath;
171
+ }
172
+ /**
173
+ * Create JSON schema for YAML validation
174
+ */
175
+ export function createYamlValidationSchema(yamlSchemaFolder, useTables) {
176
+ const schemaFileName = useTables ? "table.schema.json" : "collection.schema.json";
177
+ const containerType = useTables ? "Table" : "Collection";
178
+ const fieldsName = useTables ? "columns" : "attributes";
179
+ const fieldsDescription = useTables ? "Table columns (fields)" : "Collection attributes (fields)";
180
+ const securityField = useTables ? "rowSecurity" : "documentSecurity";
181
+ const securityDescription = useTables ? "Enable row-level permissions" : "Enable document-level permissions";
182
+ const itemType = useTables ? "row" : "document";
183
+ const schema = {
184
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
185
+ "$id": `https://appwrite-utils.dev/schemas/${schemaFileName}`,
186
+ "title": `Appwrite ${containerType} Definition`,
187
+ "description": `Schema for defining Appwrite ${useTables ? 'tables' : 'collections'} in YAML${useTables ? ' (TablesDB API)' : ''}`,
188
+ "type": "object",
189
+ "properties": {
190
+ "name": {
191
+ "type": "string",
192
+ "description": `The name of the ${useTables ? 'table' : 'collection'}`
193
+ },
194
+ "id": {
195
+ "type": "string",
196
+ "description": `The ID of the ${useTables ? 'table' : 'collection'} (optional, auto-generated if not provided)`,
197
+ "pattern": "^[a-zA-Z0-9][a-zA-Z0-9._-]{0,35}$"
198
+ },
199
+ [securityField]: {
200
+ "type": "boolean",
201
+ "default": false,
202
+ "description": securityDescription
203
+ },
204
+ "enabled": {
205
+ "type": "boolean",
206
+ "default": true,
207
+ "description": `Whether the ${useTables ? 'table' : 'collection'} is enabled`
208
+ },
209
+ "permissions": {
210
+ "type": "array",
211
+ "description": `${containerType}-level permissions`,
212
+ "items": {
213
+ "type": "object",
214
+ "properties": {
215
+ "permission": {
216
+ "type": "string",
217
+ "enum": ["read", "create", "update", "delete"],
218
+ "description": "The permission type"
219
+ },
220
+ "target": {
221
+ "type": "string",
222
+ "description": "Permission target (e.g., 'any', 'users', 'users/verified', 'label:admin')"
223
+ }
224
+ },
225
+ "required": ["permission", "target"],
226
+ "additionalProperties": false
227
+ }
228
+ },
229
+ [fieldsName]: {
230
+ "type": "array",
231
+ "description": fieldsDescription,
232
+ "items": {
233
+ "type": "object",
234
+ "properties": {
235
+ "key": {
236
+ "type": "string",
237
+ "description": `${useTables ? 'Column' : 'Attribute'} name`,
238
+ "pattern": "^[a-zA-Z][a-zA-Z0-9]*$"
239
+ },
240
+ "type": {
241
+ "type": "string",
242
+ "enum": ["string", "integer", "double", "boolean", "datetime", "email", "ip", "url", "enum", "relationship"],
243
+ "description": `${useTables ? 'Column' : 'Attribute'} data type`
244
+ },
245
+ "size": {
246
+ "type": "number",
247
+ "description": `Maximum size for string ${useTables ? 'columns' : 'attributes'}`,
248
+ "minimum": 1,
249
+ "maximum": 1073741824
250
+ },
251
+ "required": {
252
+ "type": "boolean",
253
+ "default": false,
254
+ "description": `Whether the ${useTables ? 'column' : 'attribute'} is required`
255
+ },
256
+ "array": {
257
+ "type": "boolean",
258
+ "default": false,
259
+ "description": `Whether the ${useTables ? 'column' : 'attribute'} is an array`
260
+ },
261
+ // Encryption flag for string types
262
+ "encrypt": {
263
+ "type": "boolean",
264
+ "default": false,
265
+ "description": `Enable encryption for string ${useTables ? 'columns' : 'attributes'}`
266
+ },
267
+ ...(useTables ? {
268
+ "unique": {
269
+ "type": "boolean",
270
+ "default": false,
271
+ "description": "Whether the column values must be unique (TablesDB feature)"
272
+ }
273
+ } : {}),
274
+ "default": {
275
+ "description": `Default value for the ${useTables ? 'column' : 'attribute'}`
276
+ },
277
+ "description": {
278
+ "type": "string",
279
+ "description": `${useTables ? 'Column' : 'Attribute'} description`
280
+ },
281
+ "min": {
282
+ "type": "number",
283
+ "description": `Minimum value for numeric ${useTables ? 'columns' : 'attributes'}`
284
+ },
285
+ "max": {
286
+ "type": "number",
287
+ "description": `Maximum value for numeric ${useTables ? 'columns' : 'attributes'}`
288
+ },
289
+ "elements": {
290
+ "type": "array",
291
+ "items": {
292
+ "type": "string"
293
+ },
294
+ "description": `Allowed values for enum ${useTables ? 'columns' : 'attributes'}`
295
+ },
296
+ "relatedCollection": {
297
+ "type": "string",
298
+ "description": `Related ${useTables ? 'table' : 'collection'} name for relationship ${useTables ? 'columns' : 'attributes'}`
299
+ },
300
+ "relationType": {
301
+ "type": "string",
302
+ "enum": ["oneToOne", "oneToMany", "manyToOne", "manyToMany"],
303
+ "description": "Type of relationship"
304
+ },
305
+ "twoWay": {
306
+ "type": "boolean",
307
+ "description": "Whether the relationship is bidirectional"
308
+ },
309
+ "twoWayKey": {
310
+ "type": "string",
311
+ "description": "Key name for the reverse relationship"
312
+ },
313
+ "onDelete": {
314
+ "type": "string",
315
+ "enum": ["cascade", "restrict", "setNull"],
316
+ "description": `Action to take when related ${itemType} is deleted`
317
+ },
318
+ "side": {
319
+ "type": "string",
320
+ "enum": ["parent", "child"],
321
+ "description": "Side of the relationship"
322
+ }
323
+ },
324
+ "required": ["key", "type"],
325
+ "additionalProperties": false,
326
+ "allOf": [
327
+ {
328
+ "if": {
329
+ "properties": { "type": { "const": "enum" } }
330
+ },
331
+ "then": {
332
+ "required": ["elements"]
333
+ }
334
+ },
335
+ {
336
+ "if": {
337
+ "properties": { "type": { "const": "relationship" } }
338
+ },
339
+ "then": {
340
+ "required": ["relatedCollection", "relationType"]
341
+ }
342
+ }
343
+ ]
344
+ }
345
+ },
346
+ "indexes": {
347
+ "type": "array",
348
+ "description": `Database indexes for the ${useTables ? 'table' : 'collection'}`,
349
+ "items": {
350
+ "type": "object",
351
+ "properties": {
352
+ "key": {
353
+ "type": "string",
354
+ "description": "Index name"
355
+ },
356
+ "type": {
357
+ "type": "string",
358
+ "enum": ["key", "fulltext", "unique"],
359
+ "description": "Index type"
360
+ },
361
+ "attributes": {
362
+ "type": "array",
363
+ "items": {
364
+ "type": "string"
365
+ },
366
+ "description": `${useTables ? 'Columns' : 'Attributes'} to index`,
367
+ "minItems": 1
368
+ },
369
+ "orders": {
370
+ "type": "array",
371
+ "items": {
372
+ "type": "string",
373
+ "enum": ["ASC", "DESC"]
374
+ },
375
+ "description": `Sort order for each ${useTables ? 'column' : 'attribute'}`
376
+ }
377
+ },
378
+ "required": ["key", "type", "attributes"],
379
+ "additionalProperties": false
380
+ }
381
+ },
382
+ "importDefs": {
383
+ "type": "array",
384
+ "description": "Import definitions for data migration",
385
+ "default": []
386
+ }
387
+ },
388
+ "required": ["name"],
389
+ "additionalProperties": false
390
+ };
391
+ const schemaPath = path.join(yamlSchemaFolder, schemaFileName);
392
+ writeFileSync(schemaPath, JSON.stringify(schema, null, 2));
393
+ return schemaPath;
394
+ }
395
+ /**
396
+ * Initialize a new Appwrite project with correct directory structure and terminology
397
+ */
398
+ export async function initProject(basePath, forceApiMode) {
399
+ const projectPath = basePath || process.cwd();
400
+ // Detect API mode
401
+ const detection = forceApiMode
402
+ ? {
403
+ apiMode: forceApiMode,
404
+ useTables: forceApiMode === 'tablesdb',
405
+ detectionSource: 'forced',
406
+ }
407
+ : await detectApiMode(projectPath);
408
+ const { useTables, detectionSource } = detection;
409
+ const terminology = getTerminologyConfig(useTables);
410
+ // Create directory structure
411
+ const dirs = createProjectDirectories(projectPath, useTables);
412
+ // Generate YAML config
413
+ const configPath = path.join(dirs.appwriteFolder, "config.yaml");
414
+ generateYamlConfigTemplate(configPath);
415
+ // Create example schema file
416
+ createExampleSchema(dirs.containerFolder, terminology);
417
+ // Create JSON validation schema
418
+ createYamlValidationSchema(dirs.yamlSchemaFolder, useTables);
419
+ // Success messages
420
+ const containerType = useTables ? "TablesDB" : "Collections";
421
+ MessageFormatter.success(`Created YAML config and setup files/directories in .appwrite/ folder.`, { prefix: "Setup" });
422
+ MessageFormatter.info(`Project configured for ${containerType} API (${detectionSource} detection)`, { prefix: "Setup" });
423
+ MessageFormatter.info("You can now configure your project in .appwrite/config.yaml", { prefix: "Setup" });
424
+ MessageFormatter.info(`${terminology.containerName}s can be defined in .appwrite/${terminology.container}s/ as .yaml files`, { prefix: "Setup" });
425
+ MessageFormatter.info("Schemas will be generated in .appwrite/schemas/", { prefix: "Setup" });
426
+ MessageFormatter.info("Import data can be placed in .appwrite/importData/", { prefix: "Setup" });
427
+ if (useTables) {
428
+ MessageFormatter.info("TablesDB features: unique constraints, enhanced performance, row-level security", { prefix: "Setup" });
429
+ }
430
+ }
431
+ /**
432
+ * Create a new collection or table schema file
433
+ */
434
+ export async function createSchema(name, basePath, forceApiMode) {
435
+ const projectPath = basePath || process.cwd();
436
+ // Detect API mode
437
+ const detection = forceApiMode
438
+ ? {
439
+ apiMode: forceApiMode,
440
+ useTables: forceApiMode === 'tablesdb',
441
+ detectionSource: 'forced',
442
+ }
443
+ : await detectApiMode(projectPath);
444
+ const { useTables } = detection;
445
+ const terminology = getTerminologyConfig(useTables);
446
+ // Find or create container directory
447
+ const appwriteFolder = path.join(projectPath, ".appwrite");
448
+ const containerFolder = path.join(appwriteFolder, useTables ? "tables" : "collections");
449
+ if (!existsSync(containerFolder)) {
450
+ mkdirSync(containerFolder, { recursive: true });
451
+ }
452
+ // Create YAML schema file
453
+ const yamlSchema = `# yaml-language-server: $schema=../.yaml_schemas/${terminology.schemaRef}
454
+ # ${terminology.containerName} Definition: ${name}
455
+ name: ${name}
456
+ id: ${ulid()}
457
+ ${terminology.security}: false
458
+ enabled: true
459
+ permissions:
460
+ - permission: read
461
+ target: any
462
+ - permission: create
463
+ target: users
464
+ - permission: update
465
+ target: users
466
+ - permission: delete
467
+ target: users
468
+ ${terminology.fields}:
469
+ # Add your ${terminology.fields} here
470
+ # Example:
471
+ # - key: title
472
+ # type: string
473
+ # size: 255
474
+ # required: true
475
+ # description: "The title of the item"
476
+ indexes:
477
+ # Add your indexes here
478
+ # Example:
479
+ # - key: title_search
480
+ # type: fulltext
481
+ # attributes:
482
+ # - title
483
+ importDefs: []
484
+ `;
485
+ const schemaPath = path.join(containerFolder, `${name}.yaml`);
486
+ writeFileSync(schemaPath, yamlSchema);
487
+ MessageFormatter.success(`Created ${terminology.container} schema: ${schemaPath}`, { prefix: "Setup" });
488
+ MessageFormatter.info(`Add your ${terminology.fields} to define the ${terminology.container} structure`, { prefix: "Setup" });
489
+ }
@@ -0,0 +1,9 @@
1
+ import type { AppwriteConfig } from "appwrite-utils";
2
+ export declare class SetupController {
3
+ private currentDir;
4
+ private config;
5
+ constructor(currentDir: string);
6
+ runSetup(withExampleData?: boolean): Promise<void>;
7
+ loadConfig(): Promise<AppwriteConfig | null>;
8
+ hasExistingConfig(): boolean;
9
+ }
@@ -0,0 +1,34 @@
1
+ import { setupDirsFiles } from "./utils/setupFiles.js";
2
+ import { loadConfig } from "./utils/loadConfigs.js";
3
+ import path from "path";
4
+ import fs from "fs";
5
+ import { MessageFormatter } from "appwrite-utils-helpers";
6
+ export class SetupController {
7
+ currentDir;
8
+ config = null;
9
+ constructor(currentDir) {
10
+ this.currentDir = currentDir;
11
+ }
12
+ async runSetup(withExampleData = false) {
13
+ await setupDirsFiles(withExampleData, this.currentDir);
14
+ MessageFormatter.success("Setup completed successfully", { prefix: "Setup" });
15
+ }
16
+ async loadConfig() {
17
+ if (this.hasExistingConfig()) {
18
+ try {
19
+ const appwriteDir = path.join(this.currentDir, "appwrite");
20
+ this.config = await loadConfig(appwriteDir);
21
+ return this.config;
22
+ }
23
+ catch (error) {
24
+ MessageFormatter.error("Error loading config", error, { prefix: "Setup" });
25
+ return null;
26
+ }
27
+ }
28
+ return null;
29
+ }
30
+ hasExistingConfig() {
31
+ const configPath = path.join(this.currentDir, "appwrite", "appwriteConfig.ts");
32
+ return fs.existsSync(configPath);
33
+ }
34
+ }