appwrite-utils-cli 0.0.4 → 0.0.5
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
CHANGED
|
@@ -77,4 +77,8 @@ This setup ensures that developers have robust tools at their fingertips to mana
|
|
|
77
77
|
|
|
78
78
|
- Syncing configuration
|
|
79
79
|
- Better file format for config (potentially)
|
|
80
|
-
- Separation of collections and import configuration from main config
|
|
80
|
+
- Separation of collections and import configuration from main config
|
|
81
|
+
|
|
82
|
+
### Changelog
|
|
83
|
+
|
|
84
|
+
- 0.0.5: Added `setFieldFromOtherCollectionDocuments` to set an array of ID's for instance from another collection as a `postImportAction`
|
|
@@ -7,6 +7,11 @@ export declare const afterImportActions: {
|
|
|
7
7
|
updateCreatedDocument: (config: AppwriteConfig, dbId: string, collId: string, docId: string, data: any) => Promise<void>;
|
|
8
8
|
checkAndUpdateFieldInDocument: (config: AppwriteConfig, dbId: string, collId: string, docId: string, fieldName: string, oldFieldValue: any, newFieldValue: any) => Promise<void>;
|
|
9
9
|
setFieldFromOtherCollectionDocument: (config: AppwriteConfig, dbId: string, collIdOrName: string, docId: string, fieldName: string, otherCollIdOrName: string, otherDocId: string, otherFieldName: string) => Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Updates a field in a document by setting it with document IDs from another collection
|
|
12
|
+
* based on a matching field value.
|
|
13
|
+
*/
|
|
14
|
+
setFieldFromOtherCollectionDocuments: (config: AppwriteConfig, dbId: string, collIdOrName: string, docId: string, fieldName: string, otherCollIdOrName: string, matchingFieldName: string, matchingFieldValue: any) => Promise<void>;
|
|
10
15
|
createOrGetBucket: (config: AppwriteConfig, bucketName: string, bucketId?: string, permissions?: string[], fileSecurity?: boolean, enabled?: boolean, maxFileSize?: number, allowedExtensions?: string[], compression?: string, encryption?: boolean, antivirus?: boolean) => Promise<Models.Bucket | undefined>;
|
|
11
16
|
createFileAndUpdateField: (config: AppwriteConfig, dbId: string, collId: string, docId: string, fieldName: string, bucketId: string, filePath: string, fileName: string) => Promise<void>;
|
|
12
17
|
};
|
|
@@ -79,6 +79,67 @@ export const afterImportActions = {
|
|
|
79
79
|
console.error("Error setting field from other collection document: ", error);
|
|
80
80
|
}
|
|
81
81
|
},
|
|
82
|
+
/**
|
|
83
|
+
* Updates a field in a document by setting it with document IDs from another collection
|
|
84
|
+
* based on a matching field value.
|
|
85
|
+
*/
|
|
86
|
+
setFieldFromOtherCollectionDocuments: async (config, dbId, collIdOrName, docId, fieldName, otherCollIdOrName, matchingFieldName, matchingFieldValue) => {
|
|
87
|
+
const db = getDatabaseFromConfig(config);
|
|
88
|
+
// Helper function to find a collection ID by name or return the ID if given
|
|
89
|
+
const findCollectionId = async (collectionIdentifier) => {
|
|
90
|
+
const collections = await db.listCollections(dbId, [
|
|
91
|
+
Query.equal("name", collectionIdentifier),
|
|
92
|
+
Query.limit(1),
|
|
93
|
+
]);
|
|
94
|
+
return collections.total > 0
|
|
95
|
+
? collections.collections[0].$id
|
|
96
|
+
: collectionIdentifier;
|
|
97
|
+
};
|
|
98
|
+
// Function to check if the target field is an array
|
|
99
|
+
const isTargetFieldArray = async (collectionId, fieldName) => {
|
|
100
|
+
const collection = await db.getCollection(dbId, collectionId);
|
|
101
|
+
const attribute = collection.attributes.find((attr) => attr.key === fieldName);
|
|
102
|
+
// @ts-ignore
|
|
103
|
+
return attribute?.array === true;
|
|
104
|
+
};
|
|
105
|
+
try {
|
|
106
|
+
const targetCollectionId = await findCollectionId(collIdOrName);
|
|
107
|
+
const otherCollectionId = await findCollectionId(otherCollIdOrName);
|
|
108
|
+
const targetFieldIsArray = await isTargetFieldArray(targetCollectionId, fieldName);
|
|
109
|
+
// Function to recursively fetch all matching documents from the other collection
|
|
110
|
+
const fetchAllMatchingDocuments = async (cursor) => {
|
|
111
|
+
const docLimit = 100;
|
|
112
|
+
const queries = targetFieldIsArray
|
|
113
|
+
? // @ts-ignore
|
|
114
|
+
[Query.contains(matchingFieldName, [matchingFieldValue])]
|
|
115
|
+
: [Query.equal(matchingFieldName, matchingFieldValue)];
|
|
116
|
+
if (cursor) {
|
|
117
|
+
queries.push(Query.cursorAfter(cursor));
|
|
118
|
+
}
|
|
119
|
+
queries.push(Query.limit(docLimit));
|
|
120
|
+
const response = await db.listDocuments(dbId, otherCollectionId, queries);
|
|
121
|
+
const documents = response.documents;
|
|
122
|
+
if (documents.length === 0 || documents.length < docLimit) {
|
|
123
|
+
return documents;
|
|
124
|
+
}
|
|
125
|
+
const nextCursor = documents[documents.length - 1].$id;
|
|
126
|
+
const nextBatch = await fetchAllMatchingDocuments(nextCursor);
|
|
127
|
+
return documents.concat(nextBatch);
|
|
128
|
+
};
|
|
129
|
+
const matchingDocuments = await fetchAllMatchingDocuments();
|
|
130
|
+
const documentIds = matchingDocuments.map((doc) => doc.$id);
|
|
131
|
+
if (documentIds.length > 0) {
|
|
132
|
+
const updatePayload = targetFieldIsArray
|
|
133
|
+
? { [fieldName]: documentIds }
|
|
134
|
+
: { [fieldName]: documentIds[0] };
|
|
135
|
+
await db.updateDocument(dbId, targetCollectionId, docId, updatePayload);
|
|
136
|
+
console.log(`Field ${fieldName} updated successfully in document ${docId} with ${documentIds.length} document IDs.`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
catch (error) {
|
|
140
|
+
console.error("Error setting field from other collection documents: ", error);
|
|
141
|
+
}
|
|
142
|
+
},
|
|
82
143
|
createOrGetBucket: async (config, bucketName, bucketId, permissions, fileSecurity, enabled, maxFileSize, allowedExtensions, compression, encryption, antivirus) => {
|
|
83
144
|
try {
|
|
84
145
|
const storage = getStorageFromConfig(config);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "appwrite-utils-cli",
|
|
3
3
|
"description": "Appwrite Utility Functions to help with database management, data conversion, data import, migrations, and much more. Meant to be used as a CLI tool, I do not recommend installing this in frontend environments.",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.5",
|
|
5
5
|
"main": "src/main.ts",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"repository": {
|
|
@@ -128,6 +128,101 @@ export const afterImportActions = {
|
|
|
128
128
|
);
|
|
129
129
|
}
|
|
130
130
|
},
|
|
131
|
+
/**
|
|
132
|
+
* Updates a field in a document by setting it with document IDs from another collection
|
|
133
|
+
* based on a matching field value.
|
|
134
|
+
*/
|
|
135
|
+
setFieldFromOtherCollectionDocuments: async (
|
|
136
|
+
config: AppwriteConfig,
|
|
137
|
+
dbId: string,
|
|
138
|
+
collIdOrName: string,
|
|
139
|
+
docId: string,
|
|
140
|
+
fieldName: string,
|
|
141
|
+
otherCollIdOrName: string,
|
|
142
|
+
matchingFieldName: string,
|
|
143
|
+
matchingFieldValue: any
|
|
144
|
+
): Promise<void> => {
|
|
145
|
+
const db = getDatabaseFromConfig(config);
|
|
146
|
+
|
|
147
|
+
// Helper function to find a collection ID by name or return the ID if given
|
|
148
|
+
const findCollectionId = async (collectionIdentifier: string) => {
|
|
149
|
+
const collections = await db.listCollections(dbId, [
|
|
150
|
+
Query.equal("name", collectionIdentifier),
|
|
151
|
+
Query.limit(1),
|
|
152
|
+
]);
|
|
153
|
+
return collections.total > 0
|
|
154
|
+
? collections.collections[0].$id
|
|
155
|
+
: collectionIdentifier;
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
// Function to check if the target field is an array
|
|
159
|
+
const isTargetFieldArray = async (
|
|
160
|
+
collectionId: string,
|
|
161
|
+
fieldName: string
|
|
162
|
+
) => {
|
|
163
|
+
const collection = await db.getCollection(dbId, collectionId);
|
|
164
|
+
const attribute = collection.attributes.find(
|
|
165
|
+
(attr: any) => attr.key === fieldName
|
|
166
|
+
);
|
|
167
|
+
// @ts-ignore
|
|
168
|
+
return attribute?.array === true;
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
try {
|
|
172
|
+
const targetCollectionId = await findCollectionId(collIdOrName);
|
|
173
|
+
const otherCollectionId = await findCollectionId(otherCollIdOrName);
|
|
174
|
+
const targetFieldIsArray = await isTargetFieldArray(
|
|
175
|
+
targetCollectionId,
|
|
176
|
+
fieldName
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// Function to recursively fetch all matching documents from the other collection
|
|
180
|
+
const fetchAllMatchingDocuments = async (
|
|
181
|
+
cursor?: string
|
|
182
|
+
): Promise<Models.Document[]> => {
|
|
183
|
+
const docLimit = 100;
|
|
184
|
+
const queries = targetFieldIsArray
|
|
185
|
+
? // @ts-ignore
|
|
186
|
+
[Query.contains(matchingFieldName, [matchingFieldValue])]
|
|
187
|
+
: [Query.equal(matchingFieldName, matchingFieldValue)];
|
|
188
|
+
if (cursor) {
|
|
189
|
+
queries.push(Query.cursorAfter(cursor));
|
|
190
|
+
}
|
|
191
|
+
queries.push(Query.limit(docLimit));
|
|
192
|
+
const response = await db.listDocuments(
|
|
193
|
+
dbId,
|
|
194
|
+
otherCollectionId,
|
|
195
|
+
queries
|
|
196
|
+
);
|
|
197
|
+
const documents = response.documents;
|
|
198
|
+
if (documents.length === 0 || documents.length < docLimit) {
|
|
199
|
+
return documents;
|
|
200
|
+
}
|
|
201
|
+
const nextCursor = documents[documents.length - 1].$id;
|
|
202
|
+
const nextBatch = await fetchAllMatchingDocuments(nextCursor);
|
|
203
|
+
return documents.concat(nextBatch);
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const matchingDocuments = await fetchAllMatchingDocuments();
|
|
207
|
+
const documentIds = matchingDocuments.map((doc) => doc.$id);
|
|
208
|
+
|
|
209
|
+
if (documentIds.length > 0) {
|
|
210
|
+
const updatePayload = targetFieldIsArray
|
|
211
|
+
? { [fieldName]: documentIds }
|
|
212
|
+
: { [fieldName]: documentIds[0] };
|
|
213
|
+
await db.updateDocument(dbId, targetCollectionId, docId, updatePayload);
|
|
214
|
+
|
|
215
|
+
console.log(
|
|
216
|
+
`Field ${fieldName} updated successfully in document ${docId} with ${documentIds.length} document IDs.`
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
} catch (error) {
|
|
220
|
+
console.error(
|
|
221
|
+
"Error setting field from other collection documents: ",
|
|
222
|
+
error
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
},
|
|
131
226
|
createOrGetBucket: async (
|
|
132
227
|
config: AppwriteConfig,
|
|
133
228
|
bucketName: string,
|