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