appwrite-utils-cli 1.3.4 → 1.4.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 (116) hide show
  1. package/dist/adapters/AdapterFactory.d.ts +87 -0
  2. package/dist/adapters/AdapterFactory.js +217 -0
  3. package/dist/adapters/DatabaseAdapter.d.ts +217 -0
  4. package/dist/adapters/DatabaseAdapter.js +50 -0
  5. package/dist/adapters/LegacyAdapter.d.ts +49 -0
  6. package/dist/adapters/LegacyAdapter.js +382 -0
  7. package/dist/adapters/TablesDBAdapter.d.ts +55 -0
  8. package/dist/adapters/TablesDBAdapter.js +302 -0
  9. package/dist/adapters/index.d.ts +11 -0
  10. package/dist/adapters/index.js +12 -0
  11. package/dist/collections/attributes.js +43 -24
  12. package/dist/collections/methods.d.ts +4 -3
  13. package/dist/collections/methods.js +34 -14
  14. package/dist/config/yamlConfig.d.ts +40 -437
  15. package/dist/config/yamlConfig.js +8 -2
  16. package/dist/databases/setup.js +2 -2
  17. package/dist/main.js +0 -0
  18. package/dist/migrations/appwriteToX.d.ts +26 -37
  19. package/dist/migrations/comprehensiveTransfer.js +4 -4
  20. package/dist/migrations/dataLoader.d.ts +124 -1484
  21. package/dist/migrations/dataLoader.js +2 -1
  22. package/dist/migrations/relationships.d.ts +2 -3
  23. package/dist/migrations/relationships.js +1 -1
  24. package/dist/migrations/services/UserMappingService.js +1 -1
  25. package/dist/migrations/yaml/YamlImportConfigLoader.d.ts +24 -279
  26. package/dist/migrations/yaml/YamlImportConfigLoader.js +7 -2
  27. package/dist/schemas/authUser.d.ts +7 -47
  28. package/dist/schemas/authUser.js +1 -1
  29. package/dist/shared/jsonSchemaGenerator.d.ts +0 -2
  30. package/dist/shared/jsonSchemaGenerator.js +4 -17
  31. package/dist/shared/migrationHelpers.d.ts +17 -119
  32. package/dist/shared/operationQueue.js +16 -7
  33. package/dist/shared/schemaGenerator.js +2 -17
  34. package/dist/storage/schemas.d.ts +149 -296
  35. package/dist/users/methods.d.ts +2 -2
  36. package/dist/utils/configMigration.js +0 -1
  37. package/dist/utils/getClientFromConfig.d.ts +26 -0
  38. package/dist/utils/getClientFromConfig.js +37 -0
  39. package/dist/utils/loadConfigs.js +0 -2
  40. package/dist/utils/schemaStrings.js +2 -17
  41. package/dist/utils/setupFiles.js +2 -0
  42. package/dist/utils/versionDetection.d.ts +56 -0
  43. package/dist/utils/versionDetection.js +217 -0
  44. package/dist/utils/yamlConverter.d.ts +0 -1
  45. package/dist/utils/yamlConverter.js +0 -2
  46. package/dist/utilsController.js +2 -0
  47. package/package.json +3 -2
  48. package/src/adapters/AdapterFactory.ts +296 -0
  49. package/src/adapters/DatabaseAdapter.ts +290 -0
  50. package/src/adapters/LegacyAdapter.ts +667 -0
  51. package/src/adapters/TablesDBAdapter.ts +429 -0
  52. package/src/adapters/index.ts +37 -0
  53. package/src/collections/attributes.ts +351 -157
  54. package/src/collections/methods.ts +43 -28
  55. package/src/config/yamlConfig.ts +8 -2
  56. package/src/databases/setup.ts +2 -2
  57. package/src/migrations/afterImportActions.ts +2 -2
  58. package/src/migrations/comprehensiveTransfer.ts +4 -0
  59. package/src/migrations/dataLoader.ts +2 -1
  60. package/src/migrations/relationships.ts +1 -1
  61. package/src/migrations/services/UserMappingService.ts +1 -1
  62. package/src/migrations/yaml/YamlImportConfigLoader.ts +7 -2
  63. package/src/schemas/authUser.ts +1 -1
  64. package/src/shared/jsonSchemaGenerator.ts +4 -19
  65. package/src/shared/operationQueue.ts +20 -13
  66. package/src/shared/schemaGenerator.ts +2 -16
  67. package/src/types/node-appwrite-tablesdb.d.ts +44 -0
  68. package/src/users/methods.ts +2 -2
  69. package/src/utils/configMigration.ts +0 -1
  70. package/src/utils/getClientFromConfig.ts +56 -0
  71. package/src/utils/loadConfigs.ts +0 -2
  72. package/src/utils/schemaStrings.ts +2 -16
  73. package/src/utils/setupFiles.ts +2 -0
  74. package/src/utils/versionDetection.ts +265 -0
  75. package/src/utils/yamlConverter.ts +0 -2
  76. package/src/utilsController.ts +2 -0
  77. package/dist/functions/openapi.d.ts +0 -4
  78. package/dist/functions/openapi.js +0 -60
  79. package/dist/migrations/attributes.d.ts +0 -4
  80. package/dist/migrations/attributes.js +0 -301
  81. package/dist/migrations/backup.d.ts +0 -687
  82. package/dist/migrations/backup.js +0 -175
  83. package/dist/migrations/collections.d.ts +0 -22
  84. package/dist/migrations/collections.js +0 -347
  85. package/dist/migrations/converters.d.ts +0 -46
  86. package/dist/migrations/converters.js +0 -139
  87. package/dist/migrations/databases.d.ts +0 -2
  88. package/dist/migrations/databases.js +0 -28
  89. package/dist/migrations/dbHelpers.d.ts +0 -5
  90. package/dist/migrations/dbHelpers.js +0 -57
  91. package/dist/migrations/helper.d.ts +0 -3
  92. package/dist/migrations/helper.js +0 -21
  93. package/dist/migrations/indexes.d.ts +0 -4
  94. package/dist/migrations/indexes.js +0 -19
  95. package/dist/migrations/logging.d.ts +0 -10
  96. package/dist/migrations/logging.js +0 -46
  97. package/dist/migrations/migrationHelper.d.ts +0 -173
  98. package/dist/migrations/migrationHelper.js +0 -130
  99. package/dist/migrations/openapi.d.ts +0 -4
  100. package/dist/migrations/openapi.js +0 -60
  101. package/dist/migrations/queue.d.ts +0 -13
  102. package/dist/migrations/queue.js +0 -79
  103. package/dist/migrations/schemaStrings.d.ts +0 -14
  104. package/dist/migrations/schemaStrings.js +0 -478
  105. package/dist/migrations/setupDatabase.d.ts +0 -6
  106. package/dist/migrations/setupDatabase.js +0 -115
  107. package/dist/migrations/storage.d.ts +0 -10
  108. package/dist/migrations/storage.js +0 -340
  109. package/dist/migrations/users.d.ts +0 -16
  110. package/dist/migrations/users.js +0 -276
  111. package/dist/migrations/validationRules.d.ts +0 -43
  112. package/dist/migrations/validationRules.js +0 -42
  113. package/dist/shared/attributeManager.d.ts +0 -17
  114. package/dist/shared/attributeManager.js +0 -272
  115. package/src/functions/openapi.ts +0 -83
  116. package/src/shared/attributeManager.ts +0 -428
@@ -1,5 +1,12 @@
1
1
  import { type AppwriteConfig } from "appwrite-utils";
2
2
  import { Client } from "node-appwrite";
3
+ import { AdapterFactory, type AdapterFactoryResult } from "../adapters/AdapterFactory.js";
4
+ import type { DatabaseAdapter } from "../adapters/DatabaseAdapter.js";
5
+
6
+ /**
7
+ * Legacy function - returns basic Client for backwards compatibility
8
+ * @deprecated Use getAdapterFromConfig for dual API support
9
+ */
3
10
  export const getClientFromConfig = (config: AppwriteConfig) => {
4
11
  let appwriteClient: Client | undefined;
5
12
  if (!config.appwriteClient) {
@@ -12,6 +19,55 @@ export const getClientFromConfig = (config: AppwriteConfig) => {
12
19
  return appwriteClient;
13
20
  };
14
21
 
22
+ /**
23
+ * Legacy function - returns basic Client
24
+ * @deprecated Use createDatabaseAdapter for dual API support
25
+ */
15
26
  export const getClient = (endpoint: string, project: string, key: string) => {
16
27
  return new Client().setEndpoint(endpoint).setProject(project).setKey(key);
17
28
  };
29
+
30
+ /**
31
+ * Modern adapter-based client creation with dual API support
32
+ * Returns both adapter and legacy client for compatibility
33
+ */
34
+ export const getAdapterFromConfig = async (config: AppwriteConfig, forceRefresh?: boolean): Promise<{
35
+ adapter: DatabaseAdapter;
36
+ client: Client;
37
+ apiMode: 'legacy' | 'tablesdb';
38
+ }> => {
39
+ const result = await AdapterFactory.createFromConfig(config, forceRefresh);
40
+
41
+ return {
42
+ adapter: result.adapter,
43
+ client: result.client,
44
+ apiMode: result.apiMode
45
+ };
46
+ };
47
+
48
+ /**
49
+ * Create adapter from individual parameters
50
+ */
51
+ export const getAdapter = async (
52
+ endpoint: string,
53
+ project: string,
54
+ key: string,
55
+ apiMode: 'auto' | 'legacy' | 'tablesdb' = 'auto'
56
+ ): Promise<{
57
+ adapter: DatabaseAdapter;
58
+ client: Client;
59
+ apiMode: 'legacy' | 'tablesdb';
60
+ }> => {
61
+ const result = await AdapterFactory.create({
62
+ appwriteEndpoint: endpoint,
63
+ appwriteProject: project,
64
+ appwriteKey: key,
65
+ apiMode
66
+ });
67
+
68
+ return {
69
+ adapter: result.adapter,
70
+ client: result.client,
71
+ apiMode: result.apiMode
72
+ };
73
+ };
@@ -388,7 +388,6 @@ const YamlCollectionSchema = z.object({
388
388
  required: z.boolean().default(false),
389
389
  array: z.boolean().optional(),
390
390
  default: z.any().optional(),
391
- description: z.string().optional(),
392
391
  min: z.number().optional(),
393
392
  max: z.number().optional(),
394
393
  elements: z.array(z.string()).optional(),
@@ -436,7 +435,6 @@ const loadYamlCollection = (filePath: string): CollectionCreate | null => {
436
435
  required: attr.required,
437
436
  array: attr.array,
438
437
  xdefault: attr.default,
439
- description: attr.description,
440
438
  min: attr.min,
441
439
  max: attr.max,
442
440
  elements: attr.elements,
@@ -277,11 +277,6 @@ export class SchemaGenerator {
277
277
  createSchemaString = (name: string, attributes: Attribute[]): string => {
278
278
  const pascalName = toPascalCase(name);
279
279
  let imports = `import { z } from "zod";\n`;
280
- const hasDescription = attributes.some((attr) => attr.description);
281
- if (hasDescription) {
282
- imports += `import { extendZodWithOpenApi } from "@asteasolutions/zod-to-openapi";\n`;
283
- imports += `extendZodWithOpenApi(z);\n`;
284
- }
285
280
 
286
281
  // Use the relationshipMap to find related collections
287
282
  const relationshipDetails = this.relationshipMap.get(name) || [];
@@ -418,14 +413,14 @@ export class SchemaGenerator {
418
413
  baseSchemaCode = "z.number().int()";
419
414
  if (finalAttribute.min !== undefined) {
420
415
  if (BigInt(finalAttribute.min) === BigInt(-9223372036854776000)) {
421
- delete finalAttribute.min;
416
+ finalAttribute.min = undefined;
422
417
  } else {
423
418
  baseSchemaCode += `.min(${finalAttribute.min}, "Minimum value of ${finalAttribute.min} not met")`;
424
419
  }
425
420
  }
426
421
  if (finalAttribute.max !== undefined) {
427
422
  if (BigInt(finalAttribute.max) === BigInt(9223372036854776000)) {
428
- delete finalAttribute.max;
423
+ finalAttribute.max = undefined;
429
424
  } else {
430
425
  baseSchemaCode += `.max(${finalAttribute.max}, "Maximum value of ${finalAttribute.max} exceeded")`;
431
426
  }
@@ -522,15 +517,6 @@ export class SchemaGenerator {
522
517
  if (attribute.array && !attribute.required) {
523
518
  baseSchemaCode += ".nullish()";
524
519
  }
525
- if (attribute.description) {
526
- if (typeof attribute.description === "string") {
527
- baseSchemaCode += `.openapi({ description: "${attribute.description}" })`;
528
- } else {
529
- baseSchemaCode += `.openapi(${Object.entries(attribute.description)
530
- .map(([key, value]) => `"${key}": ${value}`)
531
- .join(", ")})`;
532
- }
533
- }
534
520
 
535
521
  return baseSchemaCode;
536
522
  };
@@ -12,6 +12,8 @@ const baseConfig: AppwriteConfig = {
12
12
  appwriteEndpoint: "https://cloud.appwrite.io/v1",
13
13
  appwriteProject: "YOUR_PROJECT_ID",
14
14
  appwriteKey: "YOUR_API_KEY",
15
+ appwriteClient: null,
16
+ apiMode: "auto", // Enable dual API support - auto-detect TablesDB vs legacy
15
17
  logging: {
16
18
  enabled: false,
17
19
  level: "info",
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Version Detection Utility for Appwrite API Compatibility
3
+ *
4
+ * This module provides functions to detect whether an Appwrite instance
5
+ * supports the new TablesDB API or uses the legacy Databases API.
6
+ *
7
+ * Detection Strategy:
8
+ * 1. Primary: Test TablesDB-specific endpoint availability
9
+ * 2. Secondary: Health endpoint version check
10
+ * 3. Fallback: Default to legacy mode for safety
11
+ */
12
+
13
+ export type ApiMode = 'legacy' | 'tablesdb';
14
+
15
+ export interface VersionDetectionResult {
16
+ apiMode: ApiMode;
17
+ detectionMethod: 'endpoint_probe' | 'health_check' | 'fallback';
18
+ serverVersion?: string;
19
+ confidence: 'high' | 'medium' | 'low';
20
+ }
21
+
22
+ /**
23
+ * Detects Appwrite API version and TablesDB support
24
+ *
25
+ * @param endpoint - Appwrite server endpoint URL
26
+ * @param project - Project ID
27
+ * @param apiKey - API key for authentication
28
+ * @returns Promise resolving to version detection result
29
+ */
30
+ export async function detectAppwriteVersion(
31
+ endpoint: string,
32
+ project: string,
33
+ apiKey: string
34
+ ): Promise<VersionDetectionResult> {
35
+ // Clean endpoint URL
36
+ const cleanEndpoint = endpoint.replace(/\/$/, '');
37
+
38
+ // Try primary detection method: TablesDB endpoint probe
39
+ try {
40
+ const tablesDbResult = await probeTablesDbEndpoint(cleanEndpoint, project, apiKey);
41
+ if (tablesDbResult.apiMode === 'tablesdb') {
42
+ return tablesDbResult;
43
+ }
44
+ } catch (error) {
45
+ console.warn('TablesDB endpoint probe failed:', error instanceof Error ? error.message : 'Unknown error');
46
+ }
47
+
48
+ // Try secondary detection method: SDK feature detection
49
+ try {
50
+ const sdkResult = await probeSdkCapabilities();
51
+ if (sdkResult.apiMode === 'tablesdb') {
52
+ return sdkResult;
53
+ }
54
+ } catch (error) {
55
+ console.warn('SDK capability probe failed:', error instanceof Error ? error.message : 'Unknown error');
56
+ }
57
+
58
+ // Fallback to legacy mode
59
+ return {
60
+ apiMode: 'legacy',
61
+ detectionMethod: 'fallback',
62
+ confidence: 'low'
63
+ };
64
+ }
65
+
66
+ /**
67
+ * Test TablesDB endpoint availability - most reliable detection method
68
+ */
69
+ async function probeTablesDbEndpoint(
70
+ endpoint: string,
71
+ project: string,
72
+ apiKey: string
73
+ ): Promise<VersionDetectionResult> {
74
+ const response = await fetch(`${endpoint}/tablesdb/`, {
75
+ method: 'GET',
76
+ headers: {
77
+ 'Content-Type': 'application/json',
78
+ 'X-Appwrite-Project': project,
79
+ 'X-Appwrite-Key': apiKey
80
+ },
81
+ // Short timeout for faster detection
82
+ signal: AbortSignal.timeout(5000)
83
+ });
84
+
85
+ if (response.ok || response.status === 404) {
86
+ // 200 = TablesDB available, 404 = endpoint exists but no tables
87
+ // Both indicate TablesDB support
88
+ return {
89
+ apiMode: 'tablesdb',
90
+ detectionMethod: 'endpoint_probe',
91
+ confidence: 'high'
92
+ };
93
+ }
94
+
95
+ // 501 Not Implemented or other errors = no TablesDB support
96
+ throw new Error(`TablesDB endpoint returned ${response.status}: ${response.statusText}`);
97
+ }
98
+
99
+ /**
100
+ * SDK capability detection as secondary method
101
+ */
102
+ async function probeSdkCapabilities(): Promise<VersionDetectionResult> {
103
+ try {
104
+ // Try to import TablesDB SDK
105
+ let TablesDBModule;
106
+ try {
107
+ TablesDBModule = await import('node-appwrite-tablesdb');
108
+ } catch (importError) {
109
+ // TablesDB SDK not available, will fall back to legacy
110
+ }
111
+
112
+ if (TablesDBModule?.TablesDB) {
113
+ return {
114
+ apiMode: 'tablesdb',
115
+ detectionMethod: 'endpoint_probe',
116
+ confidence: 'medium'
117
+ };
118
+ }
119
+ } catch (error) {
120
+ // TablesDB SDK not available, assume legacy
121
+ }
122
+
123
+ // Check for legacy SDK availability
124
+ try {
125
+ const { Databases } = await import('node-appwrite');
126
+ if (Databases) {
127
+ return {
128
+ apiMode: 'legacy',
129
+ detectionMethod: 'endpoint_probe',
130
+ confidence: 'medium'
131
+ };
132
+ }
133
+ } catch (error) {
134
+ throw new Error('No Appwrite SDK available');
135
+ }
136
+
137
+ throw new Error('Unable to determine SDK capabilities');
138
+ }
139
+
140
+ /**
141
+ * Cached version detection to avoid repeated API calls
142
+ */
143
+ class VersionDetectionCache {
144
+ private cache = new Map<string, { result: VersionDetectionResult; timestamp: number }>();
145
+ private readonly CACHE_DURATION = 5 * 60 * 1000; // 5 minutes
146
+
147
+ private getCacheKey(endpoint: string, project: string): string {
148
+ return `${endpoint}:${project}`;
149
+ }
150
+
151
+ get(endpoint: string, project: string): VersionDetectionResult | null {
152
+ const key = this.getCacheKey(endpoint, project);
153
+ const cached = this.cache.get(key);
154
+
155
+ if (!cached) {
156
+ return null;
157
+ }
158
+
159
+ // Check if cache is expired
160
+ if (Date.now() - cached.timestamp > this.CACHE_DURATION) {
161
+ this.cache.delete(key);
162
+ return null;
163
+ }
164
+
165
+ return cached.result;
166
+ }
167
+
168
+ set(endpoint: string, project: string, result: VersionDetectionResult): void {
169
+ const key = this.getCacheKey(endpoint, project);
170
+ this.cache.set(key, {
171
+ result,
172
+ timestamp: Date.now()
173
+ });
174
+ }
175
+
176
+ clear(): void {
177
+ this.cache.clear();
178
+ }
179
+ }
180
+
181
+ // Global cache instance
182
+ const detectionCache = new VersionDetectionCache();
183
+
184
+ /**
185
+ * Cached version detection with automatic cache management
186
+ *
187
+ * @param endpoint - Appwrite server endpoint URL
188
+ * @param project - Project ID
189
+ * @param apiKey - API key for authentication
190
+ * @param forceRefresh - Skip cache and force fresh detection
191
+ * @returns Promise resolving to version detection result
192
+ */
193
+ export async function detectAppwriteVersionCached(
194
+ endpoint: string,
195
+ project: string,
196
+ apiKey: string,
197
+ forceRefresh: boolean = false
198
+ ): Promise<VersionDetectionResult> {
199
+ // Check cache first (unless force refresh)
200
+ if (!forceRefresh) {
201
+ const cached = detectionCache.get(endpoint, project);
202
+ if (cached) {
203
+ return cached;
204
+ }
205
+ }
206
+
207
+ // Perform fresh detection
208
+ const result = await detectAppwriteVersion(endpoint, project, apiKey);
209
+
210
+ // Cache the result
211
+ detectionCache.set(endpoint, project, result);
212
+
213
+ return result;
214
+ }
215
+
216
+ /**
217
+ * Quick check for cloud.appwrite.io instances (likely have TablesDB)
218
+ *
219
+ * @param endpoint - Appwrite server endpoint URL
220
+ * @returns boolean indicating if endpoint is likely cloud-hosted
221
+ */
222
+ export function isCloudAppwriteEndpoint(endpoint: string): boolean {
223
+ return endpoint.includes('cloud.appwrite.io');
224
+ }
225
+
226
+ /**
227
+ * SDK feature detection as a fallback method
228
+ * Attempts to dynamically import TablesDB to check availability
229
+ */
230
+ export async function detectSdkSupport(): Promise<{
231
+ tablesDbAvailable: boolean;
232
+ legacyAvailable: boolean;
233
+ }> {
234
+ const result = {
235
+ tablesDbAvailable: false,
236
+ legacyAvailable: false
237
+ };
238
+
239
+ // Test TablesDB SDK availability
240
+ try {
241
+ const tablesModule = await import('node-appwrite-tablesdb');
242
+ if (tablesModule) {
243
+ result.tablesDbAvailable = true;
244
+ }
245
+ } catch (error) {
246
+ // TablesDB SDK not available
247
+ }
248
+
249
+ // Test legacy SDK availability
250
+ try {
251
+ await import('node-appwrite');
252
+ result.legacyAvailable = true;
253
+ } catch (error) {
254
+ // Legacy SDK not available
255
+ }
256
+
257
+ return result;
258
+ }
259
+
260
+ /**
261
+ * Clear version detection cache (useful for testing)
262
+ */
263
+ export function clearVersionDetectionCache(): void {
264
+ detectionCache.clear();
265
+ }
@@ -17,7 +17,6 @@ export interface YamlCollectionData {
17
17
  required?: boolean;
18
18
  array?: boolean;
19
19
  default?: any;
20
- description?: string;
21
20
  min?: number;
22
21
  max?: number;
23
22
  elements?: string[];
@@ -70,7 +69,6 @@ export function collectionToYaml(collection: Collection | CollectionCreate, sche
70
69
  if (attr.required !== undefined) yamlAttr.required = attr.required;
71
70
  if (attr.array !== undefined) yamlAttr.array = attr.array;
72
71
  if ('xdefault' in attr && attr.xdefault !== undefined) yamlAttr.default = attr.xdefault;
73
- if (attr.description !== undefined) yamlAttr.description = attr.description;
74
72
  if ('min' in attr && attr.min !== undefined) yamlAttr.min = attr.min;
75
73
  if ('max' in attr && attr.max !== undefined) yamlAttr.max = attr.max;
76
74
  if ('elements' in attr && attr.elements !== undefined) yamlAttr.elements = attr.elements;
@@ -128,6 +128,8 @@ export class UtilsController {
128
128
  appwriteEndpoint: directConfig.appwriteEndpoint!,
129
129
  appwriteProject: directConfig.appwriteProject!,
130
130
  appwriteKey: directConfig.appwriteKey!,
131
+ appwriteClient: null,
132
+ apiMode: "auto", // Default to auto-detect for dual API support
131
133
  enableBackups: false,
132
134
  backupInterval: 0,
133
135
  backupRetention: 0,
@@ -1,4 +0,0 @@
1
- import { type AppwriteConfig } from "appwrite-utils";
2
- import { z } from "zod";
3
- export declare const generateOpenApi: (config: AppwriteConfig) => Promise<void>;
4
- export declare function transformTypeToOpenApi<T extends z.ZodTypeAny>(schema: T, description?: string | Record<string, any> | null | undefined): T;
@@ -1,60 +0,0 @@
1
- import { OpenAPIRegistry, OpenApiGeneratorV3, OpenApiGeneratorV31, } from "@asteasolutions/zod-to-openapi";
2
- import { attributeSchema, CollectionSchema, } from "appwrite-utils";
3
- import { z } from "zod";
4
- import { writeFileSync } from "fs";
5
- const registry = new OpenAPIRegistry();
6
- export const generateOpenApi = async (config) => {
7
- if (!config.collections) {
8
- return;
9
- }
10
- for (const collection of config.collections) {
11
- // Transform and register each attribute schema
12
- const attributeSchemas = collection.attributes.map((attribute) => {
13
- return transformTypeToOpenApi(attributeSchema, attribute.description);
14
- });
15
- // Create and register the collection schema with descriptions
16
- const updatedCollectionSchema = CollectionSchema.extend({
17
- // @ts-ignore
18
- attributes: attributeSchemas,
19
- }).openapi(collection.description ?? "No description");
20
- // Register the updated collection schema under the collection name
21
- registry.register(collection.name, updatedCollectionSchema);
22
- }
23
- // Convert the registry to OpenAPI JSON
24
- const generator = new OpenApiGeneratorV31(registry.definitions);
25
- const openApiSpec = generator.generateComponents();
26
- // Output the OpenAPI spec to a file
27
- writeFileSync("./appwrite/openapi/openapi.json", JSON.stringify(openApiSpec, null, 2));
28
- };
29
- export function transformTypeToOpenApi(schema, description) {
30
- // Check if description is an object (OpenAPI properties) or a string
31
- let updatedSchema;
32
- if (!description) {
33
- return schema;
34
- }
35
- if (typeof description === "string") {
36
- updatedSchema = schema.openapi(description);
37
- }
38
- else if (typeof description === "object") {
39
- updatedSchema = schema.openapi(description);
40
- }
41
- else {
42
- updatedSchema = schema;
43
- }
44
- // Check and transform attributes if they exist
45
- if (schema._def && schema._def.shape) {
46
- const shape = schema._def.shape();
47
- for (const key in shape) {
48
- const attributeDesc = shape[key].description;
49
- if (attributeDesc) {
50
- if (typeof attributeDesc === "string") {
51
- shape[key] = shape[key].openapi(attributeDesc);
52
- }
53
- else if (typeof attributeDesc === "object") {
54
- shape[key] = shape[key].openapi(attributeDesc);
55
- }
56
- }
57
- }
58
- }
59
- return updatedSchema;
60
- }
@@ -1,4 +0,0 @@
1
- import { type Databases, type Models } from "node-appwrite";
2
- import { type Attribute } from "appwrite-utils";
3
- export declare const createOrUpdateAttribute: (db: Databases, dbId: string, collection: Models.Collection, attribute: Attribute) => Promise<void>;
4
- export declare const createUpdateCollectionAttributes: (db: Databases, dbId: string, collection: Models.Collection, attributes: Attribute[]) => Promise<void>;