appwrite-utils-cli 1.3.1 → 1.3.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/dist/collections/attributes.js +2 -2
- package/dist/collections/indexes.js +8 -4
- package/dist/functions/methods.js +15 -2
- package/dist/shared/functionManager.js +13 -0
- package/package.json +3 -3
- package/src/collections/attributes.ts +4 -4
- package/src/collections/indexes.ts +9 -2
- package/src/functions/methods.ts +16 -2
- package/src/shared/functionManager.ts +14 -0
@@ -336,12 +336,12 @@ export const createOrUpdateAttribute = async (db, dbId, collection, attribute) =
|
|
336
336
|
case "double":
|
337
337
|
case "float": // Backward compatibility
|
338
338
|
if (action === "create") {
|
339
|
-
await tryAwaitWithRetry(async () => await db.createFloatAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min
|
339
|
+
await tryAwaitWithRetry(async () => await db.createFloatAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min, finalAttribute.max, finalAttribute.xdefault !== undefined && !finalAttribute.required
|
340
340
|
? finalAttribute.xdefault
|
341
341
|
: null, finalAttribute.array || false));
|
342
342
|
}
|
343
343
|
else {
|
344
|
-
await tryAwaitWithRetry(async () => await db.updateFloatAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min
|
344
|
+
await tryAwaitWithRetry(async () => await db.updateFloatAttribute(dbId, collection.$id, finalAttribute.key, finalAttribute.required || false, finalAttribute.min, finalAttribute.max, finalAttribute.xdefault !== undefined && !finalAttribute.required
|
345
345
|
? finalAttribute.xdefault
|
346
346
|
: null));
|
347
347
|
}
|
@@ -167,10 +167,14 @@ export const createOrUpdateIndex = async (dbId, db, collectionId, index) => {
|
|
167
167
|
]);
|
168
168
|
let createIndex = false;
|
169
169
|
let newIndex = null;
|
170
|
-
if (existingIndex.total
|
171
|
-
|
172
|
-
|
173
|
-
|
170
|
+
if (existingIndex.total === 0) {
|
171
|
+
// No existing index, create it
|
172
|
+
createIndex = true;
|
173
|
+
}
|
174
|
+
else if (!existingIndex.indexes.some((existingIndex) => (existingIndex.key === index.key &&
|
175
|
+
existingIndex.type === index.type &&
|
176
|
+
existingIndex.attributes === index.attributes))) {
|
177
|
+
// Existing index doesn't match, delete and recreate
|
174
178
|
await db.deleteIndex(dbId, collectionId, existingIndex.indexes[0].key);
|
175
179
|
createIndex = true;
|
176
180
|
}
|
@@ -5,6 +5,19 @@ import fs from "node:fs";
|
|
5
5
|
import {} from "appwrite-utils";
|
6
6
|
import chalk from "chalk";
|
7
7
|
import { extract as extractTar } from "tar";
|
8
|
+
/**
|
9
|
+
* Validates and filters events array for Appwrite functions
|
10
|
+
* - Filters out empty/invalid strings
|
11
|
+
* - Limits to 100 items maximum (Appwrite limit)
|
12
|
+
* - Returns empty array if input is invalid
|
13
|
+
*/
|
14
|
+
const validateEvents = (events) => {
|
15
|
+
if (!events || !Array.isArray(events))
|
16
|
+
return [];
|
17
|
+
return events
|
18
|
+
.filter(event => event && typeof event === 'string' && event.trim().length > 0)
|
19
|
+
.slice(0, 100);
|
20
|
+
};
|
8
21
|
export const listFunctions = async (client, queries, search) => {
|
9
22
|
const functions = new Functions(client);
|
10
23
|
const functionsList = await functions.list(queries, search);
|
@@ -58,7 +71,7 @@ export const deleteFunction = async (client, functionId) => {
|
|
58
71
|
};
|
59
72
|
export const createFunction = async (client, functionConfig) => {
|
60
73
|
const functions = new Functions(client);
|
61
|
-
const functionResponse = await functions.create(functionConfig.$id, functionConfig.name, functionConfig.runtime, functionConfig.execute, functionConfig.events, functionConfig.schedule, functionConfig.timeout, functionConfig.enabled, functionConfig.logging, functionConfig.entrypoint, functionConfig.commands, functionConfig.scopes, functionConfig.installationId, functionConfig.providerRepositoryId, functionConfig.providerBranch, functionConfig.providerSilentMode, functionConfig.providerRootDirectory);
|
74
|
+
const functionResponse = await functions.create(functionConfig.$id, functionConfig.name, functionConfig.runtime, functionConfig.execute, validateEvents(functionConfig.events), functionConfig.schedule, functionConfig.timeout, functionConfig.enabled, functionConfig.logging, functionConfig.entrypoint, functionConfig.commands, functionConfig.scopes, functionConfig.installationId, functionConfig.providerRepositoryId, functionConfig.providerBranch, functionConfig.providerSilentMode, functionConfig.providerRootDirectory);
|
62
75
|
return functionResponse;
|
63
76
|
};
|
64
77
|
export const updateFunctionSpecifications = async (client, functionId, specification) => {
|
@@ -101,7 +114,7 @@ export const listFunctionDeployments = async (client, functionId, queries) => {
|
|
101
114
|
};
|
102
115
|
export const updateFunction = async (client, functionConfig) => {
|
103
116
|
const functions = new Functions(client);
|
104
|
-
const functionResponse = await functions.update(functionConfig.$id, functionConfig.name, functionConfig.runtime, functionConfig.execute, functionConfig.events, functionConfig.schedule, functionConfig.timeout, functionConfig.enabled, functionConfig.logging, functionConfig.entrypoint, functionConfig.commands, functionConfig.scopes, functionConfig.installationId, functionConfig.providerRepositoryId, functionConfig.providerBranch, functionConfig.providerSilentMode, functionConfig.providerRootDirectory, functionConfig.specification);
|
117
|
+
const functionResponse = await functions.update(functionConfig.$id, functionConfig.name, functionConfig.runtime, functionConfig.execute, validateEvents(functionConfig.events), functionConfig.schedule, functionConfig.timeout, functionConfig.enabled, functionConfig.logging, functionConfig.entrypoint, functionConfig.commands, functionConfig.scopes, functionConfig.installationId, functionConfig.providerRepositoryId, functionConfig.providerBranch, functionConfig.providerSilentMode, functionConfig.providerRootDirectory, functionConfig.specification);
|
105
118
|
return functionResponse;
|
106
119
|
};
|
107
120
|
export const createFunctionTemplate = async (templateType, functionName, basePath = "./functions") => {
|
@@ -5,6 +5,19 @@ import fs from "node:fs";
|
|
5
5
|
import chalk from "chalk";
|
6
6
|
import pLimit from "p-limit";
|
7
7
|
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
8
|
+
/**
|
9
|
+
* Validates and filters events array for Appwrite functions
|
10
|
+
* - Filters out empty/invalid strings
|
11
|
+
* - Limits to 100 items maximum (Appwrite limit)
|
12
|
+
* - Returns empty array if input is invalid
|
13
|
+
*/
|
14
|
+
const validateEvents = (events) => {
|
15
|
+
if (!events || !Array.isArray(events))
|
16
|
+
return [];
|
17
|
+
return events
|
18
|
+
.filter(event => event && typeof event === 'string' && event.trim().length > 0)
|
19
|
+
.slice(0, 100);
|
20
|
+
};
|
8
21
|
// Concurrency limits
|
9
22
|
const functionLimit = pLimit(5); // Moderate limit for function operations
|
10
23
|
const queryLimit = pLimit(25); // Higher limit for read operations
|
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": "1.3.
|
4
|
+
"version": "1.3.5",
|
5
5
|
"main": "src/main.ts",
|
6
6
|
"type": "module",
|
7
7
|
"repository": {
|
@@ -33,7 +33,7 @@
|
|
33
33
|
"@types/inquirer": "^9.0.8",
|
34
34
|
"@types/json-schema": "^7.0.15",
|
35
35
|
"@types/yargs": "^17.0.33",
|
36
|
-
"appwrite-utils": "^1.3.
|
36
|
+
"appwrite-utils": "^1.3.2",
|
37
37
|
"chalk": "^5.4.1",
|
38
38
|
"cli-progress": "^3.12.0",
|
39
39
|
"commander": "^12.1.0",
|
@@ -43,7 +43,7 @@
|
|
43
43
|
"js-yaml": "^4.1.0",
|
44
44
|
"luxon": "^3.6.1",
|
45
45
|
"nanostores": "^0.10.3",
|
46
|
-
"node-appwrite": "^
|
46
|
+
"node-appwrite": "^17",
|
47
47
|
"p-limit": "^6.2.0",
|
48
48
|
"tar": "^7.4.3",
|
49
49
|
"tsx": "^4.20.3",
|
@@ -553,8 +553,8 @@ export const createOrUpdateAttribute = async (
|
|
553
553
|
collection.$id,
|
554
554
|
finalAttribute.key,
|
555
555
|
finalAttribute.required || false,
|
556
|
-
finalAttribute.min
|
557
|
-
finalAttribute.max
|
556
|
+
finalAttribute.min,
|
557
|
+
finalAttribute.max,
|
558
558
|
finalAttribute.xdefault !== undefined && !finalAttribute.required
|
559
559
|
? finalAttribute.xdefault
|
560
560
|
: null,
|
@@ -569,8 +569,8 @@ export const createOrUpdateAttribute = async (
|
|
569
569
|
collection.$id,
|
570
570
|
finalAttribute.key,
|
571
571
|
finalAttribute.required || false,
|
572
|
-
finalAttribute.min
|
573
|
-
finalAttribute.max
|
572
|
+
finalAttribute.min,
|
573
|
+
finalAttribute.max,
|
574
574
|
finalAttribute.xdefault !== undefined && !finalAttribute.required
|
575
575
|
? finalAttribute.xdefault
|
576
576
|
: null
|
@@ -277,10 +277,14 @@ export const createOrUpdateIndex = async (
|
|
277
277
|
const existingIndex = await db.listIndexes(dbId, collectionId, [
|
278
278
|
Query.equal("key", index.key),
|
279
279
|
]);
|
280
|
+
|
280
281
|
let createIndex = false;
|
281
282
|
let newIndex: Models.Index | null = null;
|
282
|
-
|
283
|
-
|
283
|
+
|
284
|
+
if (existingIndex.total === 0) {
|
285
|
+
// No existing index, create it
|
286
|
+
createIndex = true;
|
287
|
+
} else if (
|
284
288
|
!existingIndex.indexes.some(
|
285
289
|
(existingIndex) =>
|
286
290
|
(existingIndex.key === index.key &&
|
@@ -288,9 +292,11 @@ export const createOrUpdateIndex = async (
|
|
288
292
|
existingIndex.attributes === index.attributes)
|
289
293
|
)
|
290
294
|
) {
|
295
|
+
// Existing index doesn't match, delete and recreate
|
291
296
|
await db.deleteIndex(dbId, collectionId, existingIndex.indexes[0].key);
|
292
297
|
createIndex = true;
|
293
298
|
}
|
299
|
+
|
294
300
|
if (createIndex) {
|
295
301
|
newIndex = await db.createIndex(
|
296
302
|
dbId,
|
@@ -301,6 +307,7 @@ export const createOrUpdateIndex = async (
|
|
301
307
|
index.orders
|
302
308
|
);
|
303
309
|
}
|
310
|
+
|
304
311
|
return newIndex;
|
305
312
|
};
|
306
313
|
|
package/src/functions/methods.ts
CHANGED
@@ -17,6 +17,20 @@ import {
|
|
17
17
|
import chalk from "chalk";
|
18
18
|
import { extract as extractTar } from "tar";
|
19
19
|
|
20
|
+
/**
|
21
|
+
* Validates and filters events array for Appwrite functions
|
22
|
+
* - Filters out empty/invalid strings
|
23
|
+
* - Limits to 100 items maximum (Appwrite limit)
|
24
|
+
* - Returns empty array if input is invalid
|
25
|
+
*/
|
26
|
+
const validateEvents = (events?: string[]): string[] => {
|
27
|
+
if (!events || !Array.isArray(events)) return [];
|
28
|
+
|
29
|
+
return events
|
30
|
+
.filter(event => event && typeof event === 'string' && event.trim().length > 0)
|
31
|
+
.slice(0, 100);
|
32
|
+
};
|
33
|
+
|
20
34
|
export const listFunctions = async (
|
21
35
|
client: Client,
|
22
36
|
queries?: string[],
|
@@ -101,7 +115,7 @@ export const createFunction = async (
|
|
101
115
|
functionConfig.name,
|
102
116
|
functionConfig.runtime as Runtime,
|
103
117
|
functionConfig.execute,
|
104
|
-
functionConfig.events,
|
118
|
+
validateEvents(functionConfig.events),
|
105
119
|
functionConfig.schedule,
|
106
120
|
functionConfig.timeout,
|
107
121
|
functionConfig.enabled,
|
@@ -181,7 +195,7 @@ export const updateFunction = async (
|
|
181
195
|
functionConfig.name,
|
182
196
|
functionConfig.runtime as Runtime,
|
183
197
|
functionConfig.execute,
|
184
|
-
functionConfig.events,
|
198
|
+
validateEvents(functionConfig.events),
|
185
199
|
functionConfig.schedule,
|
186
200
|
functionConfig.timeout,
|
187
201
|
functionConfig.enabled,
|
@@ -6,6 +6,20 @@ import chalk from "chalk";
|
|
6
6
|
import pLimit from "p-limit";
|
7
7
|
import { tryAwaitWithRetry } from "../utils/helperFunctions.js";
|
8
8
|
|
9
|
+
/**
|
10
|
+
* Validates and filters events array for Appwrite functions
|
11
|
+
* - Filters out empty/invalid strings
|
12
|
+
* - Limits to 100 items maximum (Appwrite limit)
|
13
|
+
* - Returns empty array if input is invalid
|
14
|
+
*/
|
15
|
+
const validateEvents = (events?: string[]): string[] => {
|
16
|
+
if (!events || !Array.isArray(events)) return [];
|
17
|
+
|
18
|
+
return events
|
19
|
+
.filter(event => event && typeof event === 'string' && event.trim().length > 0)
|
20
|
+
.slice(0, 100);
|
21
|
+
};
|
22
|
+
|
9
23
|
// Concurrency limits
|
10
24
|
const functionLimit = pLimit(5); // Moderate limit for function operations
|
11
25
|
const queryLimit = pLimit(25); // Higher limit for read operations
|