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
package/README.md
CHANGED
@@ -1,96 +1,122 @@
|
|
1
|
-
# appwrite-utils-cli
|
2
|
-
|
3
|
-
## Overview
|
4
|
-
|
5
|
-
`appwrite-utils-cli` is a powerful command-line interface tool designed for Appwrite developers who need to manage database migrations, schema generation, data import, and much more. This CLI tool facilitates complex tasks like setting up databases, running migrations, generating schemas, and managing backups efficiently, making it an indispensable part of your Appwrite project management.
|
6
|
-
|
7
|
-
## Features
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
- `--
|
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
|
-
|
1
|
+
# appwrite-utils-cli
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
`appwrite-utils-cli` is a powerful command-line interface tool designed for Appwrite developers who need to manage database migrations, schema generation, data import, and much more. This CLI tool facilitates complex tasks like setting up databases, running migrations, generating schemas, and managing backups efficiently, making it an indispensable part of your Appwrite project management.
|
6
|
+
|
7
|
+
## Features
|
8
|
+
|
9
|
+
- **Interactive Mode**: Run the CLI in interactive mode for a guided experience through all available options.
|
10
|
+
- **Easy Configuration**: Initialize your Appwrite project configurations interactively directly from the command line.
|
11
|
+
- **Database Migrations**: Control the migration process with options to target specific databases and collections.
|
12
|
+
- **Schema Generation**: Generate and manage TypeScript schemas directly from your Appwrite database schemas.
|
13
|
+
- **Data Import**: Facilitate the import of data into your Appwrite databases with comprehensive command-line support.
|
14
|
+
- **Backup Management**: Create backups of your Appwrite databases to ensure data integrity and safety.
|
15
|
+
- **Flexible Database Management**: Includes commands to wipe databases, documents, or user data, providing flexibility in managing your database state during development or testing.
|
16
|
+
- **Data Transfer**: Transfer data between databases, collections, and even between local and remote Appwrite instances.
|
17
|
+
- **Configuration Synchronization**: Sync your local Appwrite configuration with your remote Appwrite project.
|
18
|
+
|
19
|
+
## Installation
|
20
|
+
|
21
|
+
To use `appwrite-utils-cli`, you can install it globally via npm to make it accessible from anywhere in your command line:
|
22
|
+
|
23
|
+
```bash
|
24
|
+
npm install -g appwrite-utils-cli
|
25
|
+
```
|
26
|
+
|
27
|
+
However, due to the rapid development of this project, it's recommended to use the following command:
|
28
|
+
|
29
|
+
```bash
|
30
|
+
npx --package=appwrite-utils-cli@latest appwrite-migrate [options]
|
31
|
+
```
|
32
|
+
|
33
|
+
**Note: Do not install this locally into your project. It is meant to be used as a command-line tool only.**
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
After installation, you can access the tool directly from your command line using the provided commands.
|
38
|
+
|
39
|
+
### Interactive Mode
|
40
|
+
|
41
|
+
Run the CLI in interactive mode:
|
42
|
+
|
43
|
+
```bash
|
44
|
+
npx --package=appwrite-utils-cli@latest appwrite-migrate --it
|
45
|
+
```
|
46
|
+
|
47
|
+
This will guide you through all available options interactively.
|
48
|
+
|
49
|
+
### Non-Interactive Mode
|
50
|
+
|
51
|
+
You can also use specific flags to run tasks without the interactive prompt:
|
52
|
+
|
53
|
+
```bash
|
54
|
+
npx --package=appwrite-utils-cli@latest appwrite-migrate [options]
|
55
|
+
```
|
56
|
+
|
57
|
+
Available options:
|
58
|
+
|
59
|
+
- `--it`: Run in interactive mode
|
60
|
+
- `--dbIds`: Comma-separated list of database IDs to operate on
|
61
|
+
- `--collectionIds`: Comma-separated list of collection IDs to operate on
|
62
|
+
- `--bucketIds`: Comma-separated list of bucket IDs to operate on
|
63
|
+
- `--wipe`: Wipe data (all: everything, docs: only documents, users: only user data)
|
64
|
+
- `--generate`: Generate TypeScript schemas from database schemas
|
65
|
+
- `--import`: Import data into your databases
|
66
|
+
- `--backup`: Perform a backup of your databases
|
67
|
+
- `--writeData`: Write converted imported data to file
|
68
|
+
- `--push`: Push your local Appwrite config to your configured Appwrite Project
|
69
|
+
- `--sync`: Synchronize by pulling your Appwrite config from your configured Appwrite Project
|
70
|
+
- `--endpoint`: Set the Appwrite endpoint
|
71
|
+
- `--projectId`: Set the Appwrite project ID
|
72
|
+
- `--apiKey`: Set the Appwrite API key
|
73
|
+
- `--transfer`: Transfer data between databases or collections
|
74
|
+
- `--fromDbId`: Set the source database ID for transfer
|
75
|
+
- `--toDbId`: Set the destination database ID for transfer
|
76
|
+
- `--fromCollectionId`: Set the source collection ID for transfer
|
77
|
+
- `--toCollectionId`: Set the destination collection ID for transfer
|
78
|
+
- `--fromBucketId`: Set the source bucket ID for transfer
|
79
|
+
- `--toBucketId`: Set the destination bucket ID for transfer
|
80
|
+
- `--remoteEndpoint`: Set the remote Appwrite endpoint for transfers
|
81
|
+
- `--remoteProjectId`: Set the remote Appwrite project ID for transfers
|
82
|
+
- `--remoteApiKey`: Set the remote Appwrite API key for transfers
|
83
|
+
|
84
|
+
## Examples
|
85
|
+
|
86
|
+
### Transfer Databases
|
87
|
+
|
88
|
+
Transfer databases within the same project or from a local to a remote project:
|
89
|
+
|
90
|
+
```bash
|
91
|
+
npx appwrite-utils-cli appwrite-migrate --transfer --fromDbId sourceDbId --toDbId targetDbId --remoteEndpoint https://appwrite.otherserver.com --remoteProjectId yourProjectId --remoteApiKey yourApiKey
|
92
|
+
```
|
93
|
+
|
94
|
+
### Transfer Specific Collections
|
95
|
+
|
96
|
+
Transfer specific collections from one place to another, with all of their data:
|
97
|
+
|
98
|
+
```bash
|
99
|
+
npx appwrite-utils-cli appwrite-migrate --transfer --fromDbId sourceDbId --toDbId targetDbId --fromCollectionId sourceCollectionId --toCollectionId targetCollectionId --remoteEndpoint https://appwrite.otherserver.com --remoteProjectId yourProjectId --remoteApiKey yourApiKey
|
100
|
+
```
|
101
|
+
|
102
|
+
### Transfer Buckets
|
103
|
+
|
104
|
+
Transfer files between buckets:
|
105
|
+
|
106
|
+
```bash
|
107
|
+
npx appwrite-utils-cli appwrite-migrate --transfer --fromBucketId sourceBucketId --toBucketId targetBucketId --remoteEndpoint https://appwrite.otherserver.com --remoteProjectId yourProjectId --remoteApiKey yourApiKey
|
108
|
+
```
|
109
|
+
|
110
|
+
## Additional Notes
|
111
|
+
|
112
|
+
- If you run out of RAM during large data imports, you can increase Node's memory allocation:
|
113
|
+
|
114
|
+
```bash
|
115
|
+
export NODE_OPTIONS="--max-old-space-size=16384"
|
116
|
+
```
|
117
|
+
|
118
|
+
This sets the allocation to 16GB. For most cases, 8GB (`8192`) should be sufficient.
|
119
|
+
|
120
|
+
- The CLI now supports OpenAPI generation for each attribute in the schema. Add a `description` to any attribute or collection, and it will export that schema to the `appwrite/openapi` folder.
|
121
|
+
|
122
|
+
This updated CLI ensures that developers have robust tools at their fingertips to manage complex Appwrite projects effectively from the command line, with both interactive and non-interactive modes available for flexibility.
|
@@ -0,0 +1,4 @@
|
|
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>;
|
@@ -0,0 +1,224 @@
|
|
1
|
+
import { Query } from "node-appwrite";
|
2
|
+
import { attributeSchema, parseAttribute, } from "appwrite-utils";
|
3
|
+
import { nameToIdMapping, enqueueOperation } from "../migrations/queue.js";
|
4
|
+
import _ from "lodash";
|
5
|
+
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
6
|
+
const attributesSame = (databaseAttribute, configAttribute) => {
|
7
|
+
return (databaseAttribute.key == configAttribute.key &&
|
8
|
+
databaseAttribute.type == configAttribute.type &&
|
9
|
+
databaseAttribute.array == configAttribute.array);
|
10
|
+
};
|
11
|
+
export const createOrUpdateAttribute = async (db, dbId, collection, attribute) => {
|
12
|
+
let action = "create";
|
13
|
+
let foundAttribute;
|
14
|
+
const updateEnabled = false;
|
15
|
+
let finalAttribute = attribute;
|
16
|
+
try {
|
17
|
+
const collectionAttr = collection.attributes.find(
|
18
|
+
// @ts-expect-error
|
19
|
+
(attr) => attr.key === attribute.key);
|
20
|
+
foundAttribute = parseAttribute(collectionAttr);
|
21
|
+
}
|
22
|
+
catch (error) {
|
23
|
+
foundAttribute = undefined;
|
24
|
+
}
|
25
|
+
if (foundAttribute &&
|
26
|
+
attributesSame(foundAttribute, attribute) &&
|
27
|
+
updateEnabled) {
|
28
|
+
// Check if mutable properties have changed and set action to "update" if necessary
|
29
|
+
const requiredChanged = "required" in foundAttribute && "required" in attribute
|
30
|
+
? foundAttribute.required !== attribute.required
|
31
|
+
: false;
|
32
|
+
// const xdefaultChanged =
|
33
|
+
// "xdefault" in foundAttribute && "xdefault" in attribute
|
34
|
+
// ? foundAttribute.xdefault !== attribute.xdefault
|
35
|
+
// : false;
|
36
|
+
const onDeleteChanged = foundAttribute.type === "relationship" &&
|
37
|
+
attribute.type === "relationship" &&
|
38
|
+
"onDelete" in foundAttribute &&
|
39
|
+
"onDelete" in attribute
|
40
|
+
? foundAttribute.onDelete !== attribute.onDelete
|
41
|
+
: false;
|
42
|
+
if (requiredChanged || onDeleteChanged) {
|
43
|
+
console.log(`Required changed: ${requiredChanged}\nOnDelete changed: ${onDeleteChanged}`);
|
44
|
+
console.log(`Found attribute: ${JSON.stringify(foundAttribute, null, 2)}`);
|
45
|
+
console.log(`Attribute: ${JSON.stringify(attribute, null, 2)}`);
|
46
|
+
finalAttribute = {
|
47
|
+
...attribute,
|
48
|
+
...foundAttribute,
|
49
|
+
};
|
50
|
+
action = "update";
|
51
|
+
}
|
52
|
+
else {
|
53
|
+
// If no properties that can be updated have changed, return early
|
54
|
+
return;
|
55
|
+
}
|
56
|
+
}
|
57
|
+
else if (foundAttribute &&
|
58
|
+
!attributesSame(foundAttribute, attribute) &&
|
59
|
+
updateEnabled) {
|
60
|
+
console.log(`Deleting attribute with same key ${attribute.key} -- but different values -- ${JSON.stringify(attribute, null, 2)} -- ${JSON.stringify(foundAttribute, null, 2)}`);
|
61
|
+
await db.deleteAttribute(dbId, collection.$id, attribute.key);
|
62
|
+
// After deletion, you might want to create the attribute anew
|
63
|
+
finalAttribute = attribute;
|
64
|
+
action = "create";
|
65
|
+
}
|
66
|
+
else if (!updateEnabled && foundAttribute) {
|
67
|
+
return;
|
68
|
+
}
|
69
|
+
// Relationship attribute logic with adjustments
|
70
|
+
let collectionFoundViaRelatedCollection;
|
71
|
+
let relatedCollectionId;
|
72
|
+
if (finalAttribute.type === "relationship") {
|
73
|
+
if (nameToIdMapping.has(finalAttribute.relatedCollection)) {
|
74
|
+
relatedCollectionId = nameToIdMapping.get(finalAttribute.relatedCollection);
|
75
|
+
try {
|
76
|
+
collectionFoundViaRelatedCollection = await db.getCollection(dbId, relatedCollectionId);
|
77
|
+
}
|
78
|
+
catch (e) {
|
79
|
+
console.log(`Collection not found: ${finalAttribute.relatedCollection} when nameToIdMapping was set`);
|
80
|
+
collectionFoundViaRelatedCollection = undefined;
|
81
|
+
}
|
82
|
+
}
|
83
|
+
else {
|
84
|
+
const collectionsPulled = await db.listCollections(dbId, [
|
85
|
+
Query.equal("name", finalAttribute.relatedCollection),
|
86
|
+
]);
|
87
|
+
if (collectionsPulled.total > 0) {
|
88
|
+
collectionFoundViaRelatedCollection = collectionsPulled.collections[0];
|
89
|
+
relatedCollectionId = collectionFoundViaRelatedCollection.$id;
|
90
|
+
nameToIdMapping.set(finalAttribute.relatedCollection, relatedCollectionId);
|
91
|
+
}
|
92
|
+
}
|
93
|
+
if (!(relatedCollectionId && collectionFoundViaRelatedCollection)) {
|
94
|
+
console.log(`Enqueueing operation for attribute: ${finalAttribute.key}`);
|
95
|
+
enqueueOperation({
|
96
|
+
type: "attribute",
|
97
|
+
collectionId: collection.$id,
|
98
|
+
collection: collection,
|
99
|
+
attribute,
|
100
|
+
dependencies: [finalAttribute.relatedCollection],
|
101
|
+
});
|
102
|
+
return;
|
103
|
+
}
|
104
|
+
}
|
105
|
+
finalAttribute = attributeSchema.parse(finalAttribute);
|
106
|
+
switch (finalAttribute.type) {
|
107
|
+
case "string":
|
108
|
+
if (action === "create") {
|
109
|
+
await tryAwaitWithRetry(async () => await db.createStringAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.size, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array || false, finalAttribute.encrypted));
|
110
|
+
}
|
111
|
+
else {
|
112
|
+
await tryAwaitWithRetry(async () => await db.updateStringAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined));
|
113
|
+
}
|
114
|
+
break;
|
115
|
+
case "integer":
|
116
|
+
if (action === "create") {
|
117
|
+
if (finalAttribute.min &&
|
118
|
+
BigInt(finalAttribute.min) === BigInt(-9223372036854776000)) {
|
119
|
+
delete finalAttribute.min;
|
120
|
+
}
|
121
|
+
if (finalAttribute.max &&
|
122
|
+
BigInt(finalAttribute.max) === BigInt(9223372036854776000)) {
|
123
|
+
delete finalAttribute.max;
|
124
|
+
}
|
125
|
+
await tryAwaitWithRetry(async () => await db.createIntegerAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min, finalAttribute.max, finalAttribute.xdefault || undefined, finalAttribute.array));
|
126
|
+
}
|
127
|
+
else {
|
128
|
+
if (finalAttribute.min &&
|
129
|
+
BigInt(finalAttribute.min) === BigInt(-9223372036854776000)) {
|
130
|
+
delete finalAttribute.min;
|
131
|
+
}
|
132
|
+
if (finalAttribute.max &&
|
133
|
+
BigInt(finalAttribute.max) === BigInt(9223372036854776000)) {
|
134
|
+
delete finalAttribute.max;
|
135
|
+
}
|
136
|
+
await tryAwaitWithRetry(async () => await db.updateIntegerAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min || 0, finalAttribute.max || 2147483647, finalAttribute.xdefault || undefined));
|
137
|
+
}
|
138
|
+
break;
|
139
|
+
case "float":
|
140
|
+
if (action === "create") {
|
141
|
+
await tryAwaitWithRetry(async () => await db.createFloatAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min, finalAttribute.max, finalAttribute.xdefault || undefined, finalAttribute.array));
|
142
|
+
}
|
143
|
+
else {
|
144
|
+
await tryAwaitWithRetry(async () => await db.updateFloatAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min || 0, finalAttribute.max || 2147483647, finalAttribute.xdefault || undefined));
|
145
|
+
}
|
146
|
+
break;
|
147
|
+
case "boolean":
|
148
|
+
if (action === "create") {
|
149
|
+
await tryAwaitWithRetry(async () => await db.createBooleanAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array));
|
150
|
+
}
|
151
|
+
else {
|
152
|
+
await tryAwaitWithRetry(async () => await db.updateBooleanAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || null));
|
153
|
+
}
|
154
|
+
break;
|
155
|
+
case "datetime":
|
156
|
+
if (action === "create") {
|
157
|
+
await tryAwaitWithRetry(async () => await db.createDatetimeAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array));
|
158
|
+
}
|
159
|
+
else {
|
160
|
+
await tryAwaitWithRetry(async () => await db.updateDatetimeAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined));
|
161
|
+
}
|
162
|
+
break;
|
163
|
+
case "email":
|
164
|
+
if (action === "create") {
|
165
|
+
await tryAwaitWithRetry(async () => await db.createEmailAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array));
|
166
|
+
}
|
167
|
+
else {
|
168
|
+
await tryAwaitWithRetry(async () => await db.updateEmailAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined));
|
169
|
+
}
|
170
|
+
break;
|
171
|
+
case "ip":
|
172
|
+
if (action === "create") {
|
173
|
+
await tryAwaitWithRetry(async () => await db.createIpAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array));
|
174
|
+
}
|
175
|
+
else {
|
176
|
+
await tryAwaitWithRetry(async () => await db.updateIpAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined));
|
177
|
+
}
|
178
|
+
break;
|
179
|
+
case "url":
|
180
|
+
if (action === "create") {
|
181
|
+
await tryAwaitWithRetry(async () => await db.createUrlAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array));
|
182
|
+
}
|
183
|
+
else {
|
184
|
+
await tryAwaitWithRetry(async () => await db.updateUrlAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.xdefault || undefined));
|
185
|
+
}
|
186
|
+
break;
|
187
|
+
case "enum":
|
188
|
+
if (action === "create") {
|
189
|
+
await tryAwaitWithRetry(async () => await db.createEnumAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.elements, finalAttribute.required || false, finalAttribute.xdefault || undefined, finalAttribute.array));
|
190
|
+
}
|
191
|
+
else {
|
192
|
+
await tryAwaitWithRetry(async () => await db.updateEnumAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.elements, finalAttribute.required || false, finalAttribute.xdefault || undefined));
|
193
|
+
}
|
194
|
+
break;
|
195
|
+
case "relationship":
|
196
|
+
if (action === "create") {
|
197
|
+
await tryAwaitWithRetry(async () => await db.createRelationshipAttribute(dbId, collection.$id, relatedCollectionId, finalAttribute.relationType, finalAttribute.twoWay, finalAttribute.key, finalAttribute.twoWayKey, finalAttribute.onDelete));
|
198
|
+
}
|
199
|
+
else {
|
200
|
+
await tryAwaitWithRetry(async () => await db.updateRelationshipAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.onDelete));
|
201
|
+
}
|
202
|
+
break;
|
203
|
+
default:
|
204
|
+
console.error("Invalid attribute type");
|
205
|
+
break;
|
206
|
+
}
|
207
|
+
};
|
208
|
+
export const createUpdateCollectionAttributes = async (db, dbId, collection, attributes) => {
|
209
|
+
console.log(`Creating/Updating attributes for collection: ${collection.name}`);
|
210
|
+
const batchSize = 3; // Size of each batch
|
211
|
+
for (let i = 0; i < attributes.length; i += batchSize) {
|
212
|
+
// Slice the attributes array to get a batch of at most batchSize elements
|
213
|
+
const batch = attributes.slice(i, i + batchSize);
|
214
|
+
const attributePromises = batch.map((attribute) => createOrUpdateAttribute(db, dbId, collection, attribute));
|
215
|
+
// Await the completion of all promises in the current batch
|
216
|
+
const results = await Promise.allSettled(attributePromises);
|
217
|
+
results.forEach((result) => {
|
218
|
+
if (result.status === "rejected") {
|
219
|
+
console.error("An attribute promise was rejected:", result.reason);
|
220
|
+
}
|
221
|
+
});
|
222
|
+
}
|
223
|
+
console.log(`Finished creating/updating attributes for collection: ${collection.name}`);
|
224
|
+
};
|
@@ -0,0 +1,4 @@
|
|
1
|
+
import { type Index } from "appwrite-utils";
|
2
|
+
import { Databases, type Models } from "node-appwrite";
|
3
|
+
export declare const createOrUpdateIndex: (dbId: string, db: Databases, collectionId: string, index: Index) => Promise<Models.Index | null>;
|
4
|
+
export declare const createOrUpdateIndexes: (dbId: string, db: Databases, collectionId: string, indexes: Index[]) => Promise<void>;
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { indexSchema } from "appwrite-utils";
|
2
|
+
import { Databases, IndexType, Query } from "node-appwrite";
|
3
|
+
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
4
|
+
export const createOrUpdateIndex = async (dbId, db, collectionId, index) => {
|
5
|
+
const existingIndex = await db.listIndexes(dbId, collectionId, [
|
6
|
+
Query.equal("key", index.key),
|
7
|
+
]);
|
8
|
+
let createIndex = false;
|
9
|
+
let newIndex = null;
|
10
|
+
if (existingIndex.total > 0 &&
|
11
|
+
existingIndex.indexes.some((index) => (index.key === index.key &&
|
12
|
+
index.type === index.type &&
|
13
|
+
index.attributes === index.attributes) ||
|
14
|
+
JSON.stringify(index) === JSON.stringify(index))) {
|
15
|
+
await db.deleteIndex(dbId, collectionId, existingIndex.indexes[0].key);
|
16
|
+
createIndex = true;
|
17
|
+
}
|
18
|
+
if (createIndex) {
|
19
|
+
newIndex = await db.createIndex(dbId, collectionId, index.key, index.type, index.attributes, index.orders);
|
20
|
+
}
|
21
|
+
return newIndex;
|
22
|
+
};
|
23
|
+
export const createOrUpdateIndexes = async (dbId, db, collectionId, indexes) => {
|
24
|
+
for (const index of indexes) {
|
25
|
+
await tryAwaitWithRetry(async () => await createOrUpdateIndex(dbId, db, collectionId, index));
|
26
|
+
}
|
27
|
+
};
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { Databases, type Models } from "node-appwrite";
|
2
|
+
import type { AppwriteConfig, CollectionCreate } from "appwrite-utils";
|
3
|
+
export declare const documentExists: (db: Databases, dbId: string, targetCollectionId: string, toCreateObject: any) => Promise<Models.Document | null>;
|
4
|
+
export declare const checkForCollection: (db: Databases, dbId: string, collection: Partial<CollectionCreate>) => Promise<Models.Collection | null>;
|
5
|
+
export declare const fetchAndCacheCollectionByName: (db: Databases, dbId: string, collectionName: string) => Promise<Models.Collection | undefined>;
|
6
|
+
export declare const wipeDatabase: (database: Databases, databaseId: string) => Promise<{
|
7
|
+
collectionId: string;
|
8
|
+
collectionName: string;
|
9
|
+
}[]>;
|
10
|
+
export declare const generateSchemas: (config: AppwriteConfig, appwriteFolderPath: string) => Promise<void>;
|
11
|
+
export declare const createOrUpdateCollections: (database: Databases, databaseId: string, config: AppwriteConfig, deletedCollections?: {
|
12
|
+
collectionId: string;
|
13
|
+
collectionName: string;
|
14
|
+
}[]) => Promise<void>;
|
15
|
+
export declare const generateMockData: (database: Databases, databaseId: string, configCollections: any[]) => Promise<void>;
|
16
|
+
export declare const fetchAllCollections: (dbId: string, database: Databases) => Promise<Models.Collection[]>;
|