appwrite-utils-cli 0.0.285 → 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.
- package/README.md +122 -96
- package/dist/collections/attributes.d.ts +4 -0
- package/dist/collections/attributes.js +224 -0
- package/dist/collections/indexes.d.ts +4 -0
- package/dist/collections/indexes.js +27 -0
- package/dist/collections/methods.d.ts +16 -0
- package/dist/collections/methods.js +216 -0
- package/dist/databases/methods.d.ts +6 -0
- package/dist/databases/methods.js +33 -0
- package/dist/interactiveCLI.d.ts +19 -0
- package/dist/interactiveCLI.js +555 -0
- package/dist/main.js +227 -62
- package/dist/migrations/afterImportActions.js +37 -40
- package/dist/migrations/appwriteToX.d.ts +26 -25
- package/dist/migrations/appwriteToX.js +42 -6
- package/dist/migrations/attributes.js +21 -20
- package/dist/migrations/backup.d.ts +93 -87
- package/dist/migrations/collections.d.ts +6 -0
- package/dist/migrations/collections.js +149 -20
- package/dist/migrations/converters.d.ts +2 -18
- package/dist/migrations/converters.js +13 -2
- package/dist/migrations/dataLoader.d.ts +276 -161
- package/dist/migrations/dataLoader.js +535 -292
- package/dist/migrations/databases.js +8 -2
- package/dist/migrations/helper.d.ts +3 -0
- package/dist/migrations/helper.js +21 -0
- package/dist/migrations/importController.d.ts +5 -2
- package/dist/migrations/importController.js +125 -88
- package/dist/migrations/importDataActions.d.ts +9 -1
- package/dist/migrations/importDataActions.js +15 -3
- package/dist/migrations/indexes.js +3 -2
- package/dist/migrations/logging.js +20 -8
- package/dist/migrations/migrationHelper.d.ts +9 -4
- package/dist/migrations/migrationHelper.js +6 -5
- package/dist/migrations/openapi.d.ts +1 -1
- package/dist/migrations/openapi.js +33 -18
- package/dist/migrations/queue.js +3 -2
- package/dist/migrations/relationships.d.ts +2 -2
- package/dist/migrations/schemaStrings.js +53 -41
- package/dist/migrations/setupDatabase.d.ts +2 -4
- package/dist/migrations/setupDatabase.js +24 -105
- package/dist/migrations/storage.d.ts +3 -1
- package/dist/migrations/storage.js +110 -16
- package/dist/migrations/transfer.d.ts +30 -0
- package/dist/migrations/transfer.js +337 -0
- package/dist/migrations/users.d.ts +2 -1
- package/dist/migrations/users.js +78 -43
- package/dist/schemas/authUser.d.ts +2 -2
- package/dist/storage/methods.d.ts +15 -0
- package/dist/storage/methods.js +207 -0
- package/dist/storage/schemas.d.ts +687 -0
- package/dist/storage/schemas.js +175 -0
- package/dist/utils/getClientFromConfig.d.ts +4 -0
- package/dist/utils/getClientFromConfig.js +16 -0
- package/dist/utils/helperFunctions.d.ts +11 -1
- package/dist/utils/helperFunctions.js +38 -0
- package/dist/utils/retryFailedPromises.d.ts +2 -0
- package/dist/utils/retryFailedPromises.js +21 -0
- package/dist/utils/schemaStrings.d.ts +13 -0
- package/dist/utils/schemaStrings.js +403 -0
- package/dist/utils/setupFiles.js +110 -61
- package/dist/utilsController.d.ts +40 -22
- package/dist/utilsController.js +164 -84
- package/package.json +13 -15
- package/src/collections/attributes.ts +483 -0
- package/src/collections/indexes.ts +53 -0
- package/src/collections/methods.ts +331 -0
- package/src/databases/methods.ts +47 -0
- package/src/init.ts +64 -64
- package/src/interactiveCLI.ts +767 -0
- package/src/main.ts +292 -83
- package/src/migrations/afterImportActions.ts +553 -490
- package/src/migrations/appwriteToX.ts +237 -174
- package/src/migrations/attributes.ts +483 -422
- package/src/migrations/backup.ts +205 -205
- package/src/migrations/collections.ts +545 -300
- package/src/migrations/converters.ts +161 -150
- package/src/migrations/dataLoader.ts +1615 -1304
- package/src/migrations/databases.ts +44 -25
- package/src/migrations/dbHelpers.ts +92 -92
- package/src/migrations/helper.ts +40 -0
- package/src/migrations/importController.ts +448 -384
- package/src/migrations/importDataActions.ts +315 -307
- package/src/migrations/indexes.ts +40 -37
- package/src/migrations/logging.ts +29 -16
- package/src/migrations/migrationHelper.ts +207 -201
- package/src/migrations/openapi.ts +83 -70
- package/src/migrations/queue.ts +118 -119
- package/src/migrations/relationships.ts +324 -324
- package/src/migrations/schemaStrings.ts +472 -460
- package/src/migrations/setupDatabase.ts +118 -219
- package/src/migrations/storage.ts +538 -358
- package/src/migrations/transfer.ts +608 -0
- package/src/migrations/users.ts +362 -285
- package/src/migrations/validationRules.ts +63 -63
- package/src/schemas/authUser.ts +23 -23
- package/src/setup.ts +8 -8
- package/src/storage/methods.ts +371 -0
- package/src/storage/schemas.ts +205 -0
- package/src/types.ts +9 -9
- package/src/utils/getClientFromConfig.ts +17 -0
- package/src/utils/helperFunctions.ts +181 -127
- package/src/utils/index.ts +2 -2
- package/src/utils/loadConfigs.ts +59 -59
- package/src/utils/retryFailedPromises.ts +27 -0
- package/src/utils/schemaStrings.ts +473 -0
- package/src/utils/setupFiles.ts +228 -182
- package/src/utilsController.ts +325 -194
- 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
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
fs.
|
57
|
-
};
|
58
|
-
|
59
|
-
export const
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
*
|
77
|
-
*
|
78
|
-
* @
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
*
|
99
|
-
*
|
100
|
-
* @
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
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
|
+
};
|
package/src/utils/index.ts
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
export * from "./helperFunctions.js";
|
2
|
-
export * from "./setupFiles.js";
|
1
|
+
export * from "./helperFunctions.js";
|
2
|
+
export * from "./setupFiles.js";
|
package/src/utils/loadConfigs.ts
CHANGED
@@ -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
|
+
};
|