appwrite-utils-cli 0.0.286 → 0.9.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 (109) hide show
  1. package/README.md +122 -96
  2. package/dist/collections/attributes.d.ts +4 -0
  3. package/dist/collections/attributes.js +224 -0
  4. package/dist/collections/indexes.d.ts +4 -0
  5. package/dist/collections/indexes.js +27 -0
  6. package/dist/collections/methods.d.ts +16 -0
  7. package/dist/collections/methods.js +216 -0
  8. package/dist/databases/methods.d.ts +6 -0
  9. package/dist/databases/methods.js +33 -0
  10. package/dist/interactiveCLI.d.ts +19 -0
  11. package/dist/interactiveCLI.js +555 -0
  12. package/dist/main.js +227 -62
  13. package/dist/migrations/afterImportActions.js +37 -40
  14. package/dist/migrations/appwriteToX.d.ts +26 -25
  15. package/dist/migrations/appwriteToX.js +42 -6
  16. package/dist/migrations/attributes.js +21 -20
  17. package/dist/migrations/backup.d.ts +93 -87
  18. package/dist/migrations/collections.d.ts +6 -0
  19. package/dist/migrations/collections.js +149 -20
  20. package/dist/migrations/converters.d.ts +2 -18
  21. package/dist/migrations/converters.js +13 -2
  22. package/dist/migrations/dataLoader.d.ts +276 -161
  23. package/dist/migrations/dataLoader.js +535 -292
  24. package/dist/migrations/databases.js +8 -2
  25. package/dist/migrations/helper.d.ts +3 -0
  26. package/dist/migrations/helper.js +21 -0
  27. package/dist/migrations/importController.d.ts +5 -2
  28. package/dist/migrations/importController.js +125 -88
  29. package/dist/migrations/importDataActions.d.ts +9 -1
  30. package/dist/migrations/importDataActions.js +15 -3
  31. package/dist/migrations/indexes.js +3 -2
  32. package/dist/migrations/logging.js +20 -8
  33. package/dist/migrations/migrationHelper.d.ts +9 -4
  34. package/dist/migrations/migrationHelper.js +6 -5
  35. package/dist/migrations/openapi.d.ts +1 -1
  36. package/dist/migrations/openapi.js +33 -18
  37. package/dist/migrations/queue.js +3 -2
  38. package/dist/migrations/relationships.d.ts +2 -2
  39. package/dist/migrations/schemaStrings.js +53 -41
  40. package/dist/migrations/setupDatabase.d.ts +2 -4
  41. package/dist/migrations/setupDatabase.js +24 -105
  42. package/dist/migrations/storage.d.ts +3 -1
  43. package/dist/migrations/storage.js +110 -16
  44. package/dist/migrations/transfer.d.ts +30 -0
  45. package/dist/migrations/transfer.js +337 -0
  46. package/dist/migrations/users.d.ts +2 -1
  47. package/dist/migrations/users.js +78 -43
  48. package/dist/schemas/authUser.d.ts +2 -2
  49. package/dist/storage/methods.d.ts +15 -0
  50. package/dist/storage/methods.js +207 -0
  51. package/dist/storage/schemas.d.ts +687 -0
  52. package/dist/storage/schemas.js +175 -0
  53. package/dist/utils/getClientFromConfig.d.ts +4 -0
  54. package/dist/utils/getClientFromConfig.js +16 -0
  55. package/dist/utils/helperFunctions.d.ts +11 -1
  56. package/dist/utils/helperFunctions.js +38 -0
  57. package/dist/utils/retryFailedPromises.d.ts +2 -0
  58. package/dist/utils/retryFailedPromises.js +21 -0
  59. package/dist/utils/schemaStrings.d.ts +13 -0
  60. package/dist/utils/schemaStrings.js +403 -0
  61. package/dist/utils/setupFiles.js +110 -61
  62. package/dist/utilsController.d.ts +40 -22
  63. package/dist/utilsController.js +164 -84
  64. package/package.json +13 -15
  65. package/src/collections/attributes.ts +483 -0
  66. package/src/collections/indexes.ts +53 -0
  67. package/src/collections/methods.ts +331 -0
  68. package/src/databases/methods.ts +47 -0
  69. package/src/init.ts +64 -64
  70. package/src/interactiveCLI.ts +767 -0
  71. package/src/main.ts +292 -83
  72. package/src/migrations/afterImportActions.ts +553 -490
  73. package/src/migrations/appwriteToX.ts +237 -174
  74. package/src/migrations/attributes.ts +483 -422
  75. package/src/migrations/backup.ts +205 -205
  76. package/src/migrations/collections.ts +545 -300
  77. package/src/migrations/converters.ts +161 -150
  78. package/src/migrations/dataLoader.ts +1615 -1304
  79. package/src/migrations/databases.ts +44 -25
  80. package/src/migrations/dbHelpers.ts +92 -92
  81. package/src/migrations/helper.ts +40 -0
  82. package/src/migrations/importController.ts +448 -384
  83. package/src/migrations/importDataActions.ts +315 -307
  84. package/src/migrations/indexes.ts +40 -37
  85. package/src/migrations/logging.ts +29 -16
  86. package/src/migrations/migrationHelper.ts +207 -201
  87. package/src/migrations/openapi.ts +83 -70
  88. package/src/migrations/queue.ts +118 -119
  89. package/src/migrations/relationships.ts +324 -324
  90. package/src/migrations/schemaStrings.ts +472 -460
  91. package/src/migrations/setupDatabase.ts +118 -219
  92. package/src/migrations/storage.ts +538 -358
  93. package/src/migrations/transfer.ts +608 -0
  94. package/src/migrations/users.ts +362 -285
  95. package/src/migrations/validationRules.ts +63 -63
  96. package/src/schemas/authUser.ts +23 -23
  97. package/src/setup.ts +8 -8
  98. package/src/storage/methods.ts +371 -0
  99. package/src/storage/schemas.ts +205 -0
  100. package/src/types.ts +9 -9
  101. package/src/utils/getClientFromConfig.ts +17 -0
  102. package/src/utils/helperFunctions.ts +181 -127
  103. package/src/utils/index.ts +2 -2
  104. package/src/utils/loadConfigs.ts +59 -59
  105. package/src/utils/retryFailedPromises.ts +27 -0
  106. package/src/utils/schemaStrings.ts +473 -0
  107. package/src/utils/setupFiles.ts +228 -182
  108. package/src/utilsController.ts +325 -194
  109. package/tsconfig.json +37 -37
@@ -1,70 +1,83 @@
1
- import {
2
- OpenAPIRegistry,
3
- OpenApiGeneratorV3,
4
- OpenApiGeneratorV31,
5
- } from "@asteasolutions/zod-to-openapi";
6
- import {
7
- attributeSchema,
8
- CollectionSchema,
9
- type AppwriteConfig,
10
- type Attribute,
11
- type Collection,
12
- type CollectionCreate,
13
- } from "appwrite-utils";
14
- import { z } from "zod";
15
- import { writeFileSync } from "fs";
16
-
17
- const registry = new OpenAPIRegistry();
18
-
19
- export const generateOpenApi = async (config: AppwriteConfig) => {
20
- if (!config.collections) {
21
- return;
22
- }
23
- for (const collection of config.collections) {
24
- // Transform and register each attribute schema
25
- const attributeSchemas = collection.attributes.map((attribute) => {
26
- return transformTypeToOpenApi(attributeSchema);
27
- });
28
-
29
- // Create and register the collection schema with descriptions
30
- const updatedCollectionSchema = CollectionSchema.extend({
31
- // @ts-ignore
32
- attributes: z.array(z.union(attributeSchemas)),
33
- }).openapi(collection.description ?? "No description");
34
-
35
- // Register the updated collection schema under the collection name
36
- registry.register(collection.name, updatedCollectionSchema);
37
- }
38
-
39
- // Convert the registry to OpenAPI JSON
40
- // @ts-ignore
41
- const openApiSpec = registry.toOpenAPI();
42
-
43
- // Output the OpenAPI spec to a file
44
- writeFileSync(
45
- "./appwrite/openapi/openapi.json",
46
- JSON.stringify(openApiSpec, null, 2)
47
- );
48
- };
49
-
50
- export function transformTypeToOpenApi<T extends z.ZodTypeAny>(
51
- schema: T
52
- ): z.infer<T> {
53
- return schema.transform((data) => {
54
- let finalData = data;
55
- if (data._def.attributes) {
56
- finalData._def.attributes = data._def.attributes.map(
57
- (attribute: typeof attributeSchema) => {
58
- if (attribute.description) {
59
- return attribute.openapi(attribute.description);
60
- }
61
- return attribute;
62
- }
63
- );
64
- }
65
- if (schema.description) {
66
- finalData.openapi(schema.description);
67
- }
68
- return finalData;
69
- });
70
- }
1
+ import {
2
+ OpenAPIRegistry,
3
+ OpenApiGeneratorV3,
4
+ OpenApiGeneratorV31,
5
+ } from "@asteasolutions/zod-to-openapi";
6
+ import {
7
+ attributeSchema,
8
+ CollectionSchema,
9
+ type AppwriteConfig,
10
+ type Attribute,
11
+ type Collection,
12
+ type CollectionCreate,
13
+ } from "appwrite-utils";
14
+ import { z } from "zod";
15
+ import { writeFileSync } from "fs";
16
+
17
+ const registry = new OpenAPIRegistry();
18
+
19
+ export const generateOpenApi = async (config: AppwriteConfig) => {
20
+ if (!config.collections) {
21
+ return;
22
+ }
23
+ for (const collection of config.collections) {
24
+ // Transform and register each attribute schema
25
+ const attributeSchemas = collection.attributes.map((attribute) => {
26
+ return transformTypeToOpenApi(attributeSchema, attribute.description);
27
+ });
28
+
29
+ // Create and register the collection schema with descriptions
30
+ const updatedCollectionSchema = CollectionSchema.extend({
31
+ // @ts-ignore
32
+ attributes: attributeSchemas,
33
+ }).openapi(collection.description ?? "No description");
34
+
35
+ // Register the updated collection schema under the collection name
36
+ registry.register(collection.name, updatedCollectionSchema);
37
+ }
38
+
39
+ // Convert the registry to OpenAPI JSON
40
+ const generator = new OpenApiGeneratorV31(registry.definitions);
41
+ const openApiSpec = generator.generateComponents();
42
+
43
+ // Output the OpenAPI spec to a file
44
+ writeFileSync(
45
+ "./appwrite/openapi/openapi.json",
46
+ JSON.stringify(openApiSpec, null, 2)
47
+ );
48
+ };
49
+
50
+ export function transformTypeToOpenApi<T extends z.ZodTypeAny>(
51
+ schema: T,
52
+ description?: string | Record<string, any> | null | undefined
53
+ ): T {
54
+ // Check if description is an object (OpenAPI properties) or a string
55
+ let updatedSchema: z.infer<T>;
56
+ if (!description) {
57
+ return schema;
58
+ }
59
+ if (typeof description === "string") {
60
+ updatedSchema = schema.openapi(description);
61
+ } else if (typeof description === "object") {
62
+ updatedSchema = schema.openapi(description);
63
+ } else {
64
+ updatedSchema = schema;
65
+ }
66
+
67
+ // Check and transform attributes if they exist
68
+ if ((schema as any)._def && (schema as any)._def.shape) {
69
+ const shape = (schema as any)._def.shape();
70
+ for (const key in shape) {
71
+ const attributeDesc = shape[key].description;
72
+ if (attributeDesc) {
73
+ if (typeof attributeDesc === "string") {
74
+ shape[key] = shape[key].openapi(attributeDesc);
75
+ } else if (typeof attributeDesc === "object") {
76
+ shape[key] = shape[key].openapi(attributeDesc);
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ return updatedSchema;
83
+ }
@@ -1,119 +1,118 @@
1
- import { Query, type Databases, type Models } from "node-appwrite";
2
- import type { Attribute } from "appwrite-utils";
3
- import { createOrUpdateAttribute } from "./attributes.js";
4
- import _ from "lodash";
5
- import { fetchAndCacheCollectionByName } from "./collections.js";
6
-
7
- export interface QueuedOperation {
8
- type: "attribute";
9
- collectionId?: string;
10
- attribute?: Attribute;
11
- collection?: Models.Collection;
12
- dependencies?: string[];
13
- }
14
- export const queuedOperations: QueuedOperation[] = [];
15
- export const nameToIdMapping: Map<string, string> = new Map();
16
-
17
- export const enqueueOperation = (operation: QueuedOperation) => {
18
- queuedOperations.push(operation);
19
- };
20
-
21
- export const processQueue = async (db: Databases, dbId: string) => {
22
- console.log("---------------------------------");
23
- console.log(`Starting Queue processing of ${dbId}`);
24
- console.log("---------------------------------");
25
- let progress = true;
26
-
27
- while (progress) {
28
- progress = false;
29
- console.log("Processing queued operations:");
30
- for (let i = 0; i < queuedOperations.length; i++) {
31
- const operation = queuedOperations[i];
32
- let collectionFound: Models.Collection | undefined;
33
-
34
- // Handle relationship attribute operations
35
- if (operation.attribute?.type === "relationship") {
36
- // Attempt to resolve the collection directly if collectionId is specified
37
- if (operation.collectionId) {
38
- console.log(`\tFetching collection by ID: ${operation.collectionId}`);
39
- try {
40
- collectionFound = await db.getCollection(
41
- dbId,
42
- operation.collectionId
43
- );
44
- } catch (e) {
45
- console.log(
46
- `\tCollection not found by ID: ${operation.collectionId}`
47
- );
48
- }
49
- }
50
- // Attempt to resolve related collection if specified and not already found
51
- if (!collectionFound && operation.attribute?.relatedCollection) {
52
- collectionFound = await fetchAndCacheCollectionByName(
53
- db,
54
- dbId,
55
- operation.attribute.relatedCollection
56
- );
57
- }
58
- // Handle dependencies if collection still not found
59
- if (!collectionFound) {
60
- for (const dep of operation.dependencies || []) {
61
- collectionFound = await fetchAndCacheCollectionByName(
62
- db,
63
- dbId,
64
- dep
65
- );
66
- if (collectionFound) break; // Break early if collection is found
67
- }
68
- }
69
- } else if (operation.collectionId) {
70
- // Handle non-relationship operations with a specified collectionId
71
- console.log(`\tFetching collection by ID: ${operation.collectionId}`);
72
- try {
73
- collectionFound = await db.getCollection(
74
- dbId,
75
- operation.collectionId
76
- );
77
- } catch (e) {
78
- console.log(
79
- `\tCollection not found by ID: ${operation.collectionId}`
80
- );
81
- }
82
- }
83
-
84
- // Process the operation if the collection is found
85
- if (collectionFound && operation.attribute) {
86
- console.log(
87
- `\tProcessing attribute: ${operation.attribute.key} for collection ID: ${collectionFound.$id}`
88
- );
89
- await createOrUpdateAttribute(
90
- db,
91
- dbId,
92
- collectionFound,
93
- operation.attribute
94
- );
95
- queuedOperations.splice(i, 1);
96
- i--; // Adjust index since we're modifying the array
97
- progress = true;
98
- } else {
99
- console.error(
100
- `\tCollection not found for operation, removing from queue: ${JSON.stringify(
101
- operation
102
- )}`
103
- );
104
- queuedOperations.splice(i, 1);
105
- i--; // Adjust index since we're modifying the array
106
- }
107
- }
108
- console.log(`\tFinished processing queued operations`);
109
- }
110
-
111
- if (queuedOperations.length > 0) {
112
- console.error("Unresolved operations remain due to unmet dependencies.");
113
- console.log(queuedOperations);
114
- }
115
-
116
- console.log("---------------------------------");
117
- console.log(`Queue processing complete for ${dbId}`);
118
- console.log("---------------------------------");
119
- };
1
+ import { Query, type Databases, type Models } from "node-appwrite";
2
+ import type { Attribute } from "appwrite-utils";
3
+ import { createOrUpdateAttribute } from "./attributes.js";
4
+ import _ from "lodash";
5
+ import { fetchAndCacheCollectionByName } from "./collections.js";
6
+ import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
7
+
8
+ export interface QueuedOperation {
9
+ type: "attribute";
10
+ collectionId?: string;
11
+ attribute?: Attribute;
12
+ collection?: Models.Collection;
13
+ dependencies?: string[];
14
+ }
15
+ export const queuedOperations: QueuedOperation[] = [];
16
+ export const nameToIdMapping: Map<string, string> = new Map();
17
+
18
+ export const enqueueOperation = (operation: QueuedOperation) => {
19
+ queuedOperations.push(operation);
20
+ };
21
+
22
+ export const processQueue = async (db: Databases, dbId: string) => {
23
+ console.log("---------------------------------");
24
+ console.log(`Starting Queue processing of ${dbId}`);
25
+ console.log("---------------------------------");
26
+ let progress = true;
27
+
28
+ while (progress) {
29
+ progress = false;
30
+ console.log("Processing queued operations:");
31
+ for (let i = 0; i < queuedOperations.length; i++) {
32
+ const operation = queuedOperations[i];
33
+ let collectionFound: Models.Collection | undefined;
34
+
35
+ // Handle relationship attribute operations
36
+ if (operation.attribute?.type === "relationship") {
37
+ // Attempt to resolve the collection directly if collectionId is specified
38
+ if (operation.collectionId) {
39
+ console.log(`\tFetching collection by ID: ${operation.collectionId}`);
40
+ try {
41
+ collectionFound = await tryAwaitWithRetry(
42
+ async () => await db.getCollection(dbId, operation.collectionId!)
43
+ );
44
+ } catch (e) {
45
+ console.log(
46
+ `\tCollection not found by ID: ${operation.collectionId}`
47
+ );
48
+ }
49
+ }
50
+ // Attempt to resolve related collection if specified and not already found
51
+ if (!collectionFound && operation.attribute?.relatedCollection) {
52
+ collectionFound = await fetchAndCacheCollectionByName(
53
+ db,
54
+ dbId,
55
+ operation.attribute.relatedCollection
56
+ );
57
+ }
58
+ // Handle dependencies if collection still not found
59
+ if (!collectionFound) {
60
+ for (const dep of operation.dependencies || []) {
61
+ collectionFound = await fetchAndCacheCollectionByName(
62
+ db,
63
+ dbId,
64
+ dep
65
+ );
66
+ if (collectionFound) break; // Break early if collection is found
67
+ }
68
+ }
69
+ } else if (operation.collectionId) {
70
+ // Handle non-relationship operations with a specified collectionId
71
+ console.log(`\tFetching collection by ID: ${operation.collectionId}`);
72
+ try {
73
+ collectionFound = await tryAwaitWithRetry(
74
+ async () => await db.getCollection(dbId, operation.collectionId!)
75
+ );
76
+ } catch (e) {
77
+ console.log(
78
+ `\tCollection not found by ID: ${operation.collectionId}`
79
+ );
80
+ }
81
+ }
82
+
83
+ // Process the operation if the collection is found
84
+ if (collectionFound && operation.attribute) {
85
+ console.log(
86
+ `\tProcessing attribute: ${operation.attribute.key} for collection ID: ${collectionFound.$id}`
87
+ );
88
+ await createOrUpdateAttribute(
89
+ db,
90
+ dbId,
91
+ collectionFound,
92
+ operation.attribute
93
+ );
94
+ queuedOperations.splice(i, 1);
95
+ i--; // Adjust index since we're modifying the array
96
+ progress = true;
97
+ } else {
98
+ console.error(
99
+ `\tCollection not found for operation, removing from queue: ${JSON.stringify(
100
+ operation
101
+ )}`
102
+ );
103
+ queuedOperations.splice(i, 1);
104
+ i--; // Adjust index since we're modifying the array
105
+ }
106
+ }
107
+ console.log(`\tFinished processing queued operations`);
108
+ }
109
+
110
+ if (queuedOperations.length > 0) {
111
+ console.error("Unresolved operations remain due to unmet dependencies.");
112
+ console.log(queuedOperations);
113
+ }
114
+
115
+ console.log("---------------------------------");
116
+ console.log(`Queue processing complete for ${dbId}`);
117
+ console.log("---------------------------------");
118
+ };