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
@@ -0,0 +1,205 @@
1
+ import { z } from "zod";
2
+ import {
3
+ attributeSchema,
4
+ type Attribute,
5
+ parseAttribute,
6
+ CollectionCreateSchema,
7
+ } from "appwrite-utils";
8
+
9
+ export const BackupSchema = z.object({
10
+ $id: z.string(),
11
+ $createdAt: z.string(),
12
+ $updatedAt: z.string(),
13
+ database: z.string(),
14
+ collections: z.array(z.string()),
15
+ documents: z
16
+ .array(
17
+ z.object({
18
+ collectionId: z.string(),
19
+ data: z.string(),
20
+ })
21
+ )
22
+ .default([]),
23
+ });
24
+
25
+ export type Backup = z.infer<typeof BackupSchema>;
26
+
27
+ export const BackupCreateSchema = BackupSchema.omit({
28
+ $id: true,
29
+ $createdAt: true,
30
+ $updatedAt: true,
31
+ });
32
+
33
+ export type BackupCreate = z.infer<typeof BackupCreateSchema>;
34
+
35
+ export const BatchSchema = z.object({
36
+ $id: z.string(),
37
+ $createdAt: z.string(),
38
+ $updatedAt: z.string(),
39
+ data: z.string().describe("The serialized data for this batch"),
40
+ processed: z
41
+ .boolean()
42
+ .default(false)
43
+ .describe("Whether the batch has been processed"),
44
+ });
45
+
46
+ export type Batch = z.infer<typeof BatchSchema>;
47
+
48
+ export const BatchCreateSchema = BatchSchema.omit({
49
+ $id: true,
50
+ $createdAt: true,
51
+ $updatedAt: true,
52
+ });
53
+
54
+ export type BatchCreate = z.infer<typeof BatchCreateSchema>;
55
+
56
+ export const OperationSchema = z.object({
57
+ $id: z.string(),
58
+ $createdAt: z.string(),
59
+ $updatedAt: z.string(),
60
+ operationType: z.string(),
61
+ collectionId: z.string(),
62
+ data: z.any(),
63
+ batches: z.array(z.string()).default([]).optional(),
64
+ progress: z.number(),
65
+ total: z.number(),
66
+ error: z.string(),
67
+ status: z
68
+ .enum([
69
+ "pending",
70
+ "ready",
71
+ "in_progress",
72
+ "completed",
73
+ "error",
74
+ "cancelled",
75
+ ])
76
+ .default("pending"),
77
+ });
78
+
79
+ export type Operation = z.infer<typeof OperationSchema>;
80
+
81
+ export const OperationCreateSchema = OperationSchema.omit({
82
+ $id: true,
83
+ $createdAt: true,
84
+ $updatedAt: true,
85
+ });
86
+
87
+ export type OperationCreate = z.infer<typeof OperationCreateSchema>;
88
+
89
+ export const getMigrationCollectionSchemas = () => {
90
+ const currentOperationsAttributes: Attribute[] = [
91
+ parseAttribute({
92
+ key: "operationType",
93
+ type: "string",
94
+ error: "Invalid Operation Type",
95
+ size: 50,
96
+ required: true,
97
+ array: false,
98
+ xdefault: null,
99
+ }),
100
+ attributeSchema.parse({
101
+ key: "collectionId",
102
+ type: "string",
103
+ error: "Invalid Collection Id",
104
+ size: 50,
105
+ array: false,
106
+ xdefault: null,
107
+ }),
108
+ attributeSchema.parse({
109
+ key: "batches",
110
+ type: "string",
111
+ error: "Invalid Batches",
112
+ size: 1073741824,
113
+ array: true,
114
+ }),
115
+ attributeSchema.parse({
116
+ key: "data",
117
+ type: "string",
118
+ error: "Invalid Data",
119
+ size: 1073741824,
120
+ }),
121
+ attributeSchema.parse({
122
+ key: "progress",
123
+ type: "integer",
124
+ error: "Invalid Progress",
125
+ required: true,
126
+ array: false,
127
+ }),
128
+ attributeSchema.parse({
129
+ key: "total",
130
+ type: "integer",
131
+ error: "Invalid Total",
132
+ required: true,
133
+ array: false,
134
+ }),
135
+ attributeSchema.parse({
136
+ key: "error",
137
+ type: "string",
138
+ error: "Operation Error",
139
+ required: false,
140
+ array: false,
141
+ }),
142
+ attributeSchema.parse({
143
+ key: "status",
144
+ type: "enum",
145
+ elements: [
146
+ "pending",
147
+ "ready",
148
+ "in_progress",
149
+ "completed",
150
+ "error",
151
+ "cancelled",
152
+ ],
153
+ error: "Invalid Status",
154
+ array: false,
155
+ xdefault: "pending",
156
+ }),
157
+ ];
158
+
159
+ const currentOperationsConfig = CollectionCreateSchema.parse({
160
+ name: "CurrentOperations",
161
+ enabled: true,
162
+ documentSecurity: false,
163
+ attributes: [],
164
+ indexes: [],
165
+ });
166
+
167
+ const batchesAttributes: Attribute[] = [
168
+ attributeSchema.parse({
169
+ key: "data",
170
+ type: "string",
171
+ size: 1073741824,
172
+ error: "Invalid Data",
173
+ required: true,
174
+ array: false,
175
+ }),
176
+ attributeSchema.parse({
177
+ key: "processed",
178
+ type: "boolean",
179
+ error: "Invalid Processed",
180
+ required: true,
181
+ array: false,
182
+ xdefault: false,
183
+ }),
184
+ ];
185
+
186
+ const batchesConfig = CollectionCreateSchema.parse({
187
+ name: "Batches",
188
+ enabled: true,
189
+ documentSecurity: false,
190
+ attributes: [],
191
+ indexes: [],
192
+ });
193
+
194
+ const toReturn = {
195
+ CurrentOperations: {
196
+ collection: currentOperationsConfig,
197
+ attributes: currentOperationsAttributes,
198
+ },
199
+ Batches: {
200
+ collection: batchesConfig,
201
+ attributes: batchesAttributes,
202
+ },
203
+ };
204
+ return toReturn;
205
+ };
package/src/types.ts CHANGED
@@ -1,9 +1,9 @@
1
- export type { ValidationRules } from "./migrations/validationRules.js";
2
- export {
3
- type AuthUserCreate,
4
- AuthUserCreateSchema,
5
- type AuthUser,
6
- AuthUserSchema,
7
- } from "./schemas/authUser.js";
8
- export { validationRules } from "./migrations/validationRules.js";
9
- export { afterImportActions } from "./migrations/afterImportActions.js";
1
+ export type { ValidationRules } from "./migrations/validationRules.js";
2
+ export {
3
+ type AuthUserCreate,
4
+ AuthUserCreateSchema,
5
+ type AuthUser,
6
+ AuthUserSchema,
7
+ } from "./schemas/authUser.js";
8
+ export { validationRules } from "./migrations/validationRules.js";
9
+ export { afterImportActions } from "./migrations/afterImportActions.js";
@@ -0,0 +1,17 @@
1
+ import { type AppwriteConfig } from "appwrite-utils";
2
+ import { Client } from "node-appwrite";
3
+ export const getClientFromConfig = (config: AppwriteConfig) => {
4
+ let appwriteClient: Client | undefined;
5
+ if (!config.appwriteClient) {
6
+ appwriteClient = new Client()
7
+ .setEndpoint(config.appwriteEndpoint)
8
+ .setProject(config.appwriteProject)
9
+ .setKey(config.appwriteKey);
10
+ config.appwriteClient = appwriteClient;
11
+ }
12
+ return appwriteClient;
13
+ };
14
+
15
+ export const getClient = (endpoint: string, project: string, key: string) => {
16
+ return new Client().setEndpoint(endpoint).setProject(project).setKey(key);
17
+ };
@@ -1,127 +1,181 @@
1
- import type { Models, Storage } from "node-appwrite";
2
- import fs from "node:fs";
3
- import path from "node:path";
4
- import type { CollectionImportData } from "../migrations/dataLoader.js";
5
- import type { ConfigCollection } from "appwrite-utils";
6
-
7
- export const toPascalCase = (str: string): string => {
8
- return (
9
- str
10
- // Split the string into words on spaces or camelCase transitions
11
- .split(/(?:\s+)|(?:([A-Z][a-z]+))/g)
12
- // Filter out empty strings that can appear due to the split regex
13
- .filter(Boolean)
14
- // Capitalize the first letter of each word and join them together
15
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
16
- .join("")
17
- );
18
- };
19
-
20
- export const toCamelCase = (str: string): string => {
21
- return str
22
- .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) =>
23
- index === 0 ? word.toLowerCase() : word.toUpperCase()
24
- )
25
- .replace(/\s+/g, "");
26
- };
27
-
28
- export const ensureDirectoryExistence = (filePath: string) => {
29
- const dirname = path.dirname(filePath);
30
- if (fs.existsSync(dirname)) {
31
- return true;
32
- }
33
- ensureDirectoryExistence(dirname);
34
- fs.mkdirSync(dirname);
35
- };
36
-
37
- export const writeFileSync = (
38
- filePath: string,
39
- content: string,
40
- options: { flag: string }
41
- ) => {
42
- ensureDirectoryExistence(filePath);
43
- fs.writeFileSync(filePath, content, options);
44
- };
45
-
46
- export const readFileSync = (filePath: string) => {
47
- return fs.readFileSync(filePath, "utf8");
48
- };
49
-
50
- export const existsSync = (filePath: string) => {
51
- return fs.existsSync(filePath);
52
- };
53
-
54
- export const mkdirSync = (filePath: string) => {
55
- ensureDirectoryExistence(filePath);
56
- fs.mkdirSync(filePath);
57
- };
58
-
59
- export const readdirSync = (filePath: string) => {
60
- return fs.readdirSync(filePath);
61
- };
62
-
63
- export const areCollectionNamesSame = (a: string, b: string) => {
64
- return (
65
- a.toLowerCase().trim().replace(" ", "") ===
66
- b.toLowerCase().trim().replace(" ", "")
67
- );
68
- };
69
-
70
- /**
71
- * Generates the view URL for a specific file based on the provided endpoint, project ID, bucket ID, file ID, and optional JWT token.
72
- *
73
- * @param {string} endpoint - the base URL endpoint
74
- * @param {string} projectId - the ID of the project
75
- * @param {string} bucketId - the ID of the bucket
76
- * @param {string} fileId - the ID of the file
77
- * @param {Models.Jwt} [jwt] - optional JWT token generated via the Appwrite SDK
78
- * @return {string} the generated view URL for the file
79
- */
80
- export const getFileViewUrl = (
81
- endpoint: string,
82
- projectId: string,
83
- bucketId: string,
84
- fileId: string,
85
- jwt?: Models.Jwt
86
- ) => {
87
- return `${endpoint}/storage/buckets/${bucketId}/files/${fileId}/view?project=${projectId}${
88
- jwt ? `&jwt=${jwt.jwt}` : ""
89
- }`;
90
- };
91
-
92
- /**
93
- * Generates a download URL for a file based on the provided endpoint, project ID, bucket ID, file ID, and optionally a JWT.
94
- *
95
- * @param {string} endpoint - The base URL endpoint.
96
- * @param {string} projectId - The ID of the project.
97
- * @param {string} bucketId - The ID of the bucket.
98
- * @param {string} fileId - The ID of the file.
99
- * @param {Models.Jwt} [jwt] - Optional JWT object for authentication with Appwrite.
100
- * @return {string} The complete download URL for the file.
101
- */
102
- export const getFileDownloadUrl = (
103
- endpoint: string,
104
- projectId: string,
105
- bucketId: string,
106
- fileId: string,
107
- jwt?: Models.Jwt
108
- ) => {
109
- return `${endpoint}/storage/buckets/${bucketId}/files/${fileId}/download?project=${projectId}${
110
- jwt ? `&jwt=${jwt.jwt}` : ""
111
- }`;
112
- };
113
-
114
- export const finalizeByAttributeMap = async (
115
- appwriteFolderPath: string,
116
- collection: ConfigCollection,
117
- item: CollectionImportData["data"][number]
118
- ) => {
119
- const schemaFolderPath = path.join(appwriteFolderPath, "schemas");
120
- const zodSchema = await import(
121
- `${schemaFolderPath}/${toCamelCase(collection.name)}.ts`
122
- );
123
- return zodSchema.parse({
124
- ...item.context,
125
- ...item.finalData,
126
- });
127
- };
1
+ import {
2
+ AppwriteException,
3
+ Client,
4
+ type Models,
5
+ type Storage,
6
+ } from "node-appwrite";
7
+ import fs from "node:fs";
8
+ import path from "node:path";
9
+ import type { CollectionImportData } from "../migrations/dataLoader.js";
10
+ import type { ConfigCollection } from "appwrite-utils";
11
+
12
+ export const toPascalCase = (str: string): string => {
13
+ return (
14
+ str
15
+ // Split the string into words on spaces or camelCase transitions
16
+ .split(/(?:\s+)|(?:([A-Z][a-z]+))/g)
17
+ // Filter out empty strings that can appear due to the split regex
18
+ .filter(Boolean)
19
+ // Capitalize the first letter of each word and join them together
20
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
21
+ .join("")
22
+ );
23
+ };
24
+
25
+ export const toCamelCase = (str: string): string => {
26
+ return str
27
+ .replace(/(?:^\w|[A-Z]|\b\w)/g, (word, index) =>
28
+ index === 0 ? word.toLowerCase() : word.toUpperCase()
29
+ )
30
+ .replace(/\s+/g, "");
31
+ };
32
+
33
+ export const ensureDirectoryExistence = (filePath: string) => {
34
+ const dirname = path.dirname(filePath);
35
+ if (fs.existsSync(dirname)) {
36
+ return true;
37
+ }
38
+ ensureDirectoryExistence(dirname);
39
+ fs.mkdirSync(dirname);
40
+ };
41
+
42
+ export const writeFileSync = (
43
+ filePath: string,
44
+ content: string,
45
+ options: { flag: string }
46
+ ) => {
47
+ ensureDirectoryExistence(filePath);
48
+ fs.writeFileSync(filePath, content, options);
49
+ };
50
+
51
+ export const readFileSync = (filePath: string) => {
52
+ return fs.readFileSync(filePath, "utf8");
53
+ };
54
+
55
+ export const existsSync = (filePath: string) => {
56
+ return fs.existsSync(filePath);
57
+ };
58
+
59
+ export const mkdirSync = (filePath: string) => {
60
+ ensureDirectoryExistence(filePath);
61
+ fs.mkdirSync(filePath);
62
+ };
63
+
64
+ export const readdirSync = (filePath: string) => {
65
+ return fs.readdirSync(filePath);
66
+ };
67
+
68
+ export const areCollectionNamesSame = (a: string, b: string) => {
69
+ return (
70
+ a.toLowerCase().trim().replace(" ", "") ===
71
+ b.toLowerCase().trim().replace(" ", "")
72
+ );
73
+ };
74
+
75
+ /**
76
+ * Generates the view URL for a specific file based on the provided endpoint, project ID, bucket ID, file ID, and optional JWT token.
77
+ *
78
+ * @param {string} endpoint - the base URL endpoint
79
+ * @param {string} projectId - the ID of the project
80
+ * @param {string} bucketId - the ID of the bucket
81
+ * @param {string} fileId - the ID of the file
82
+ * @param {Models.Jwt} [jwt] - optional JWT token generated via the Appwrite SDK
83
+ * @return {string} the generated view URL for the file
84
+ */
85
+ export const getFileViewUrl = (
86
+ endpoint: string,
87
+ projectId: string,
88
+ bucketId: string,
89
+ fileId: string,
90
+ jwt?: Models.Jwt
91
+ ) => {
92
+ return `${endpoint}/storage/buckets/${bucketId}/files/${fileId}/view?project=${projectId}${
93
+ jwt ? `&jwt=${jwt.jwt}` : ""
94
+ }`;
95
+ };
96
+
97
+ /**
98
+ * Generates a download URL for a file based on the provided endpoint, project ID, bucket ID, file ID, and optionally a JWT.
99
+ *
100
+ * @param {string} endpoint - The base URL endpoint.
101
+ * @param {string} projectId - The ID of the project.
102
+ * @param {string} bucketId - The ID of the bucket.
103
+ * @param {string} fileId - The ID of the file.
104
+ * @param {Models.Jwt} [jwt] - Optional JWT object for authentication with Appwrite.
105
+ * @return {string} The complete download URL for the file.
106
+ */
107
+ export const getFileDownloadUrl = (
108
+ endpoint: string,
109
+ projectId: string,
110
+ bucketId: string,
111
+ fileId: string,
112
+ jwt?: Models.Jwt
113
+ ) => {
114
+ return `${endpoint}/storage/buckets/${bucketId}/files/${fileId}/download?project=${projectId}${
115
+ jwt ? `&jwt=${jwt.jwt}` : ""
116
+ }`;
117
+ };
118
+
119
+ export const finalizeByAttributeMap = async (
120
+ appwriteFolderPath: string,
121
+ collection: ConfigCollection,
122
+ item: CollectionImportData["data"][number]
123
+ ) => {
124
+ const schemaFolderPath = path.join(appwriteFolderPath, "schemas");
125
+ const zodSchema = await import(
126
+ `${schemaFolderPath}/${toCamelCase(collection.name)}.ts`
127
+ );
128
+ return zodSchema.parse({
129
+ ...item.context,
130
+ ...item.finalData,
131
+ });
132
+ };
133
+
134
+ export let numTimesFailedTotal = 0;
135
+
136
+ /**
137
+ * Tries to execute the given createFunction and retries up to 5 times if it fails.
138
+ *
139
+ * @param {() => Promise<any>} createFunction - The function to be executed.
140
+ * @param {number} [attemptNum=0] - The number of attempts made so far (default: 0).
141
+ * @return {Promise<any>} - A promise that resolves to the result of the createFunction or rejects with an error if it fails after 5 attempts.
142
+ */
143
+ export const tryAwaitWithRetry = async <T>(
144
+ createFunction: () => Promise<T>,
145
+ attemptNum: number = 0,
146
+ throwError: boolean = false
147
+ ): Promise<T> => {
148
+ try {
149
+ return await createFunction();
150
+ } catch (error) {
151
+ if (
152
+ error instanceof AppwriteException &&
153
+ (error.message.toLowerCase().includes("fetch failed") ||
154
+ error.message.toLowerCase().includes("server error"))
155
+ ) {
156
+ numTimesFailedTotal++;
157
+ console.log(`Fetch failed on attempt ${attemptNum}. Retrying...`);
158
+ if (attemptNum > 5) {
159
+ throw error;
160
+ }
161
+ return tryAwaitWithRetry(createFunction, attemptNum + 1);
162
+ }
163
+ if (throwError) {
164
+ throw error;
165
+ }
166
+ console.error("Error during retryAwait function: " + error);
167
+ // @ts-ignore
168
+ return Promise.resolve();
169
+ }
170
+ };
171
+
172
+ export const getAppwriteClient = (
173
+ endpoint: string,
174
+ projectId: string,
175
+ apiKey: string
176
+ ) => {
177
+ return new Client()
178
+ .setEndpoint(endpoint)
179
+ .setProject(projectId)
180
+ .setKey(apiKey);
181
+ };
@@ -1,2 +1,2 @@
1
- export * from "./helperFunctions.js";
2
- export * from "./setupFiles.js";
1
+ export * from "./helperFunctions.js";
2
+ export * from "./setupFiles.js";
@@ -1,59 +1,59 @@
1
- import path from "path";
2
- import fs from "fs";
3
- import { type AppwriteConfig, type Collection } from "appwrite-utils";
4
- import { register } from "tsx/esm/api"; // Import the register function
5
-
6
- /**
7
- * Recursively searches for a file named 'appwriteConfig.ts' starting from the given directory.
8
- * @param dir The directory to start the search from.
9
- * @returns The path to the file if found, or null if not found.
10
- */
11
- export const findAppwriteConfig = (dir: string): string | null => {
12
- if (dir === "node_modules") {
13
- return null;
14
- }
15
- const files = fs.readdirSync(dir, { withFileTypes: true });
16
-
17
- for (const file of files) {
18
- if (file.isDirectory() && file.name !== "node_modules") {
19
- const result = findAppwriteConfig(path.join(dir, file.name));
20
- if (result) return result;
21
- } else if (file.name === "appwriteConfig.ts") {
22
- return path.join(dir, file.name);
23
- }
24
- }
25
-
26
- return null;
27
- };
28
-
29
- /**
30
- * Loads the Appwrite configuration and all collection configurations from a specified directory.
31
- * @param configDir The directory containing the appwriteConfig.ts and collections folder.
32
- * @returns The loaded Appwrite configuration including collections.
33
- */
34
- export const loadConfig = async (
35
- configDir: string
36
- ): Promise<AppwriteConfig> => {
37
- const unregister = register(); // Register tsx enhancement
38
-
39
- try {
40
- const configPath = path.resolve(configDir, "appwriteConfig.ts");
41
- console.log(`Loading config from: ${configPath}`);
42
- const config = (await import(configPath)).default as AppwriteConfig;
43
-
44
- const collectionsDir = path.resolve(configDir, "collections");
45
- const collectionFiles = fs.readdirSync(collectionsDir);
46
-
47
- config.collections = [];
48
-
49
- for (const file of collectionFiles) {
50
- const filePath = path.resolve(collectionsDir, file);
51
- const collectionModule = (await import(filePath)).default as Collection;
52
- config.collections.push(collectionModule);
53
- }
54
-
55
- return config;
56
- } finally {
57
- unregister(); // Unregister tsx when done
58
- }
59
- };
1
+ import path from "path";
2
+ import fs from "fs";
3
+ import { type AppwriteConfig, type Collection } from "appwrite-utils";
4
+ import { register } from "tsx/esm/api"; // Import the register function
5
+
6
+ /**
7
+ * Recursively searches for a file named 'appwriteConfig.ts' starting from the given directory.
8
+ * @param dir The directory to start the search from.
9
+ * @returns The path to the file if found, or null if not found.
10
+ */
11
+ export const findAppwriteConfig = (dir: string): string | null => {
12
+ if (dir === "node_modules") {
13
+ return null;
14
+ }
15
+ const files = fs.readdirSync(dir, { withFileTypes: true });
16
+
17
+ for (const file of files) {
18
+ if (file.isDirectory() && file.name !== "node_modules") {
19
+ const result = findAppwriteConfig(path.join(dir, file.name));
20
+ if (result) return result;
21
+ } else if (file.name === "appwriteConfig.ts") {
22
+ return path.join(dir, file.name);
23
+ }
24
+ }
25
+
26
+ return null;
27
+ };
28
+
29
+ /**
30
+ * Loads the Appwrite configuration and all collection configurations from a specified directory.
31
+ * @param configDir The directory containing the appwriteConfig.ts and collections folder.
32
+ * @returns The loaded Appwrite configuration including collections.
33
+ */
34
+ export const loadConfig = async (
35
+ configDir: string
36
+ ): Promise<AppwriteConfig> => {
37
+ const unregister = register(); // Register tsx enhancement
38
+
39
+ try {
40
+ const configPath = path.resolve(configDir, "appwriteConfig.ts");
41
+ console.log(`Loading config from: ${configPath}`);
42
+ const config = (await import(configPath)).default as AppwriteConfig;
43
+
44
+ const collectionsDir = path.resolve(configDir, "collections");
45
+ const collectionFiles = fs.readdirSync(collectionsDir);
46
+
47
+ config.collections = [];
48
+
49
+ for (const file of collectionFiles) {
50
+ const filePath = path.resolve(collectionsDir, file);
51
+ const collectionModule = (await import(filePath)).default as Collection;
52
+ config.collections.push(collectionModule);
53
+ }
54
+
55
+ return config;
56
+ } finally {
57
+ unregister(); // Unregister tsx when done
58
+ }
59
+ };