appwrite-utils-cli 1.3.0 → 1.3.4

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.
@@ -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 > 0 &&
171
- !existingIndex.indexes.some((existingIndex) => (existingIndex.key === index.key &&
172
- existingIndex.type === index.type &&
173
- existingIndex.attributes === index.attributes))) {
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
  }
@@ -235,7 +235,7 @@ declare const YamlConfigSchema: z.ZodObject<{
235
235
  functions: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{
236
236
  id: z.ZodString;
237
237
  name: z.ZodString;
238
- runtime: z.ZodEnum<["node-14.5", "node-16.0", "node-18.0", "node-19.0", "node-20.0", "node-21.0", "node-22", "bun-1.0", "bun-1.1", "deno-1.21", "deno-1.24", "deno-1.35", "deno-1.40", "deno-1.46", "deno-2.0", "go-1.23", "python-3.8", "python-3.9", "python-3.10", "python-3.11", "python-3.12", "python-ml-3.11", "dart-2.15", "dart-2.16", "dart-2.17", "dart-2.18", "dart-3.0", "dart-3.1", "dart-3.3", "dart-3.5", "php-8.0", "php-8.1", "php-8.2", "php-8.3", "ruby-3.0", "ruby-3.1", "ruby-3.2", "ruby-3.3", "dotnet-6.0", "dotnet-7.0", "dotnet-8.0", "java-8.0", "java-11.0", "java-17.0", "java-18.0", "java-21.0", "java-22", "swift-5.5", "swift-5.8", "swift-5.9", "swift-5.10", "kotlin-1.6", "kotlin-1.8", "kotlin-1.9", "kotlin-2.0", "cpp-17", "cpp-20"]>;
238
+ runtime: any;
239
239
  execute: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
240
240
  events: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
241
241
  schedule: z.ZodOptional<z.ZodString>;
@@ -244,7 +244,7 @@ declare const YamlConfigSchema: z.ZodObject<{
244
244
  logging: z.ZodOptional<z.ZodBoolean>;
245
245
  entrypoint: z.ZodOptional<z.ZodString>;
246
246
  commands: z.ZodOptional<z.ZodString>;
247
- scopes: z.ZodOptional<z.ZodArray<z.ZodEnum<["users.read", "users.write", "sessions.read", "sessions.write", "teams.read", "teams.write", "databases.read", "databases.write", "collections.read", "collections.write", "attributes.read", "attributes.write", "indexes.read", "indexes.write", "documents.read", "documents.write", "files.read", "files.write", "buckets.read", "buckets.write", "functions.read", "functions.write", "execution.read", "execution.write", "locale.read", "avatars.read", "health.read", "rules.read", "rules.write", "migrations.read", "migrations.write", "sites.read", "sites.write", "log.read", "log.write", "tokens.read", "tokens.write", "vcs.read", "vcs.write", "assistant.read", "messages.read", "messages.write", "targets.read", "targets.write", "providers.read", "providers.write", "topics.read", "topics.write", "subscribers.read", "subscribers.write"]>, "many">>;
247
+ scopes: z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodString, "users.read" | "users.write" | "sessions.read" | "sessions.write" | "teams.read" | "teams.write" | "databases.read" | "databases.write" | "collections.read" | "collections.write" | "attributes.read" | "attributes.write" | "indexes.read" | "indexes.write" | "documents.read" | "documents.write" | "files.read" | "files.write" | "buckets.read" | "buckets.write" | "functions.read" | "functions.write" | "execution.read" | "execution.write" | "locale.read" | "avatars.read" | "health.read" | "rules.read" | "rules.write" | "migrations.read" | "migrations.write" | "sites.read" | "sites.write" | "log.read" | "log.write" | "tokens.read" | "tokens.write" | "vcs.read" | "vcs.write" | "assistant.read" | "messages.read" | "messages.write" | "targets.read" | "targets.write" | "providers.read" | "providers.write" | "topics.read" | "topics.write" | "subscribers.read" | "subscribers.write", string>, "many">>;
248
248
  installationId: z.ZodOptional<z.ZodString>;
249
249
  providerRepositoryId: z.ZodOptional<z.ZodString>;
250
250
  providerBranch: z.ZodOptional<z.ZodString>;
@@ -254,7 +254,7 @@ declare const YamlConfigSchema: z.ZodObject<{
254
254
  templateOwner: z.ZodOptional<z.ZodString>;
255
255
  templateRootDirectory: z.ZodOptional<z.ZodString>;
256
256
  templateBranch: z.ZodOptional<z.ZodString>;
257
- specification: z.ZodOptional<z.ZodEnum<["s-0.5vcpu-512mb", "s-1vcpu-512mb", "s-1vcpu-1gb", "s-2vcpu-2gb", "s-2vcpu-4gb", "s-4vcpu-4gb", "s-4vcpu-8gb", "s-8vcpu-4gb", "s-8vcpu-8gb"]>>;
257
+ specification: z.ZodOptional<z.ZodEffects<z.ZodString, "s-0.5vcpu-512mb" | "s-1vcpu-512mb" | "s-1vcpu-1gb" | "s-2vcpu-2gb" | "s-2vcpu-4gb" | "s-4vcpu-4gb" | "s-4vcpu-8gb" | "s-8vcpu-4gb" | "s-8vcpu-8gb", string>>;
258
258
  dirPath: z.ZodOptional<z.ZodString>;
259
259
  predeployCommands: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
260
260
  deployDir: z.ZodOptional<z.ZodString>;
@@ -263,9 +263,9 @@ declare const YamlConfigSchema: z.ZodObject<{
263
263
  }, "strip", z.ZodTypeAny, {
264
264
  name: string;
265
265
  id: string;
266
- runtime: "node-14.5" | "node-16.0" | "node-18.0" | "node-19.0" | "node-20.0" | "node-21.0" | "node-22" | "bun-1.0" | "bun-1.1" | "deno-1.21" | "deno-1.24" | "deno-1.35" | "deno-1.40" | "deno-1.46" | "deno-2.0" | "go-1.23" | "python-3.8" | "python-3.9" | "python-3.10" | "python-3.11" | "python-3.12" | "python-ml-3.11" | "dart-2.15" | "dart-2.16" | "dart-2.17" | "dart-2.18" | "dart-3.0" | "dart-3.1" | "dart-3.3" | "dart-3.5" | "php-8.0" | "php-8.1" | "php-8.2" | "php-8.3" | "ruby-3.0" | "ruby-3.1" | "ruby-3.2" | "ruby-3.3" | "dotnet-6.0" | "dotnet-7.0" | "dotnet-8.0" | "java-8.0" | "java-11.0" | "java-17.0" | "java-18.0" | "java-21.0" | "java-22" | "swift-5.5" | "swift-5.8" | "swift-5.9" | "swift-5.10" | "kotlin-1.6" | "kotlin-1.8" | "kotlin-1.9" | "kotlin-2.0" | "cpp-17" | "cpp-20";
267
266
  enabled?: boolean | undefined;
268
267
  logging?: boolean | undefined;
268
+ runtime?: any;
269
269
  execute?: string[] | undefined;
270
270
  events?: string[] | undefined;
271
271
  schedule?: string | undefined;
@@ -291,16 +291,16 @@ declare const YamlConfigSchema: z.ZodObject<{
291
291
  }, {
292
292
  name: string;
293
293
  id: string;
294
- runtime: "node-14.5" | "node-16.0" | "node-18.0" | "node-19.0" | "node-20.0" | "node-21.0" | "node-22" | "bun-1.0" | "bun-1.1" | "deno-1.21" | "deno-1.24" | "deno-1.35" | "deno-1.40" | "deno-1.46" | "deno-2.0" | "go-1.23" | "python-3.8" | "python-3.9" | "python-3.10" | "python-3.11" | "python-3.12" | "python-ml-3.11" | "dart-2.15" | "dart-2.16" | "dart-2.17" | "dart-2.18" | "dart-3.0" | "dart-3.1" | "dart-3.3" | "dart-3.5" | "php-8.0" | "php-8.1" | "php-8.2" | "php-8.3" | "ruby-3.0" | "ruby-3.1" | "ruby-3.2" | "ruby-3.3" | "dotnet-6.0" | "dotnet-7.0" | "dotnet-8.0" | "java-8.0" | "java-11.0" | "java-17.0" | "java-18.0" | "java-21.0" | "java-22" | "swift-5.5" | "swift-5.8" | "swift-5.9" | "swift-5.10" | "kotlin-1.6" | "kotlin-1.8" | "kotlin-1.9" | "kotlin-2.0" | "cpp-17" | "cpp-20";
295
294
  enabled?: boolean | undefined;
296
295
  logging?: boolean | undefined;
296
+ runtime?: any;
297
297
  execute?: string[] | undefined;
298
298
  events?: string[] | undefined;
299
299
  schedule?: string | undefined;
300
300
  timeout?: number | undefined;
301
301
  entrypoint?: string | undefined;
302
302
  commands?: string | undefined;
303
- scopes?: ("users.read" | "users.write" | "sessions.read" | "sessions.write" | "teams.read" | "teams.write" | "databases.read" | "databases.write" | "collections.read" | "collections.write" | "attributes.read" | "attributes.write" | "indexes.read" | "indexes.write" | "documents.read" | "documents.write" | "files.read" | "files.write" | "buckets.read" | "buckets.write" | "functions.read" | "functions.write" | "execution.read" | "execution.write" | "locale.read" | "avatars.read" | "health.read" | "rules.read" | "rules.write" | "migrations.read" | "migrations.write" | "sites.read" | "sites.write" | "log.read" | "log.write" | "tokens.read" | "tokens.write" | "vcs.read" | "vcs.write" | "assistant.read" | "messages.read" | "messages.write" | "targets.read" | "targets.write" | "providers.read" | "providers.write" | "topics.read" | "topics.write" | "subscribers.read" | "subscribers.write")[] | undefined;
303
+ scopes?: string[] | undefined;
304
304
  installationId?: string | undefined;
305
305
  providerRepositoryId?: string | undefined;
306
306
  providerBranch?: string | undefined;
@@ -310,7 +310,7 @@ declare const YamlConfigSchema: z.ZodObject<{
310
310
  templateOwner?: string | undefined;
311
311
  templateRootDirectory?: string | undefined;
312
312
  templateBranch?: string | undefined;
313
- specification?: "s-0.5vcpu-512mb" | "s-1vcpu-512mb" | "s-1vcpu-1gb" | "s-2vcpu-2gb" | "s-2vcpu-4gb" | "s-4vcpu-4gb" | "s-4vcpu-8gb" | "s-8vcpu-4gb" | "s-8vcpu-8gb" | undefined;
313
+ specification?: string | undefined;
314
314
  dirPath?: string | undefined;
315
315
  predeployCommands?: string[] | undefined;
316
316
  deployDir?: string | undefined;
@@ -391,9 +391,9 @@ declare const YamlConfigSchema: z.ZodObject<{
391
391
  functions: {
392
392
  name: string;
393
393
  id: string;
394
- runtime: "node-14.5" | "node-16.0" | "node-18.0" | "node-19.0" | "node-20.0" | "node-21.0" | "node-22" | "bun-1.0" | "bun-1.1" | "deno-1.21" | "deno-1.24" | "deno-1.35" | "deno-1.40" | "deno-1.46" | "deno-2.0" | "go-1.23" | "python-3.8" | "python-3.9" | "python-3.10" | "python-3.11" | "python-3.12" | "python-ml-3.11" | "dart-2.15" | "dart-2.16" | "dart-2.17" | "dart-2.18" | "dart-3.0" | "dart-3.1" | "dart-3.3" | "dart-3.5" | "php-8.0" | "php-8.1" | "php-8.2" | "php-8.3" | "ruby-3.0" | "ruby-3.1" | "ruby-3.2" | "ruby-3.3" | "dotnet-6.0" | "dotnet-7.0" | "dotnet-8.0" | "java-8.0" | "java-11.0" | "java-17.0" | "java-18.0" | "java-21.0" | "java-22" | "swift-5.5" | "swift-5.8" | "swift-5.9" | "swift-5.10" | "kotlin-1.6" | "kotlin-1.8" | "kotlin-1.9" | "kotlin-2.0" | "cpp-17" | "cpp-20";
395
394
  enabled?: boolean | undefined;
396
395
  logging?: boolean | undefined;
396
+ runtime?: any;
397
397
  execute?: string[] | undefined;
398
398
  events?: string[] | undefined;
399
399
  schedule?: string | undefined;
@@ -485,16 +485,16 @@ declare const YamlConfigSchema: z.ZodObject<{
485
485
  functions?: {
486
486
  name: string;
487
487
  id: string;
488
- runtime: "node-14.5" | "node-16.0" | "node-18.0" | "node-19.0" | "node-20.0" | "node-21.0" | "node-22" | "bun-1.0" | "bun-1.1" | "deno-1.21" | "deno-1.24" | "deno-1.35" | "deno-1.40" | "deno-1.46" | "deno-2.0" | "go-1.23" | "python-3.8" | "python-3.9" | "python-3.10" | "python-3.11" | "python-3.12" | "python-ml-3.11" | "dart-2.15" | "dart-2.16" | "dart-2.17" | "dart-2.18" | "dart-3.0" | "dart-3.1" | "dart-3.3" | "dart-3.5" | "php-8.0" | "php-8.1" | "php-8.2" | "php-8.3" | "ruby-3.0" | "ruby-3.1" | "ruby-3.2" | "ruby-3.3" | "dotnet-6.0" | "dotnet-7.0" | "dotnet-8.0" | "java-8.0" | "java-11.0" | "java-17.0" | "java-18.0" | "java-21.0" | "java-22" | "swift-5.5" | "swift-5.8" | "swift-5.9" | "swift-5.10" | "kotlin-1.6" | "kotlin-1.8" | "kotlin-1.9" | "kotlin-2.0" | "cpp-17" | "cpp-20";
489
488
  enabled?: boolean | undefined;
490
489
  logging?: boolean | undefined;
490
+ runtime?: any;
491
491
  execute?: string[] | undefined;
492
492
  events?: string[] | undefined;
493
493
  schedule?: string | undefined;
494
494
  timeout?: number | undefined;
495
495
  entrypoint?: string | undefined;
496
496
  commands?: string | undefined;
497
- scopes?: ("users.read" | "users.write" | "sessions.read" | "sessions.write" | "teams.read" | "teams.write" | "databases.read" | "databases.write" | "collections.read" | "collections.write" | "attributes.read" | "attributes.write" | "indexes.read" | "indexes.write" | "documents.read" | "documents.write" | "files.read" | "files.write" | "buckets.read" | "buckets.write" | "functions.read" | "functions.write" | "execution.read" | "execution.write" | "locale.read" | "avatars.read" | "health.read" | "rules.read" | "rules.write" | "migrations.read" | "migrations.write" | "sites.read" | "sites.write" | "log.read" | "log.write" | "tokens.read" | "tokens.write" | "vcs.read" | "vcs.write" | "assistant.read" | "messages.read" | "messages.write" | "targets.read" | "targets.write" | "providers.read" | "providers.write" | "topics.read" | "topics.write" | "subscribers.read" | "subscribers.write")[] | undefined;
497
+ scopes?: string[] | undefined;
498
498
  installationId?: string | undefined;
499
499
  providerRepositoryId?: string | undefined;
500
500
  providerBranch?: string | undefined;
@@ -504,7 +504,7 @@ declare const YamlConfigSchema: z.ZodObject<{
504
504
  templateOwner?: string | undefined;
505
505
  templateRootDirectory?: string | undefined;
506
506
  templateBranch?: string | undefined;
507
- specification?: "s-0.5vcpu-512mb" | "s-1vcpu-512mb" | "s-1vcpu-1gb" | "s-2vcpu-2gb" | "s-2vcpu-4gb" | "s-4vcpu-4gb" | "s-4vcpu-8gb" | "s-8vcpu-4gb" | "s-8vcpu-8gb" | undefined;
507
+ specification?: string | undefined;
508
508
  dirPath?: string | undefined;
509
509
  predeployCommands?: string[] | undefined;
510
510
  deployDir?: string | undefined;
@@ -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.0",
4
+ "version": "1.3.4",
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.2.1",
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": "^16",
46
+ "node-appwrite": "^17",
47
47
  "p-limit": "^6.2.0",
48
48
  "tar": "^7.4.3",
49
49
  "tsx": "^4.20.3",
@@ -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
- if (
283
- existingIndex.total > 0 &&
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
 
@@ -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
@@ -1,47 +0,0 @@
1
- {
2
- "name": "appwrite-utils-cli",
3
- "technologies": [
4
- "Node.js",
5
- "TypeScript"
6
- ],
7
- "dependencies": [
8
- "@types/inquirer",
9
- "@types/json-schema",
10
- "@types/yargs",
11
- "appwrite-utils",
12
- "chalk",
13
- "cli-progress",
14
- "commander",
15
- "es-toolkit",
16
- "ignore",
17
- "inquirer",
18
- "js-yaml",
19
- "luxon",
20
- "nanostores",
21
- "node-appwrite",
22
- "p-limit",
23
- "tar",
24
- "tsx",
25
- "ulidx",
26
- "winston",
27
- "yargs",
28
- "zod",
29
- "@types/cli-progress",
30
- "@types/js-yaml",
31
- "@types/lodash",
32
- "@types/luxon",
33
- "typescript"
34
- ],
35
- "entryPoints": [
36
- "src/main.ts"
37
- ],
38
- "configFiles": [
39
- "package.json",
40
- "tsconfig.json"
41
- ],
42
- "buildOutputs": [
43
- "dist"
44
- ],
45
- "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.",
46
- "version": "1.2.30"
47
- }
@@ -1,132 +0,0 @@
1
- 📁 appwrite-utils-cli
2
- 📁 .appwrite
3
- 📁 .yaml_schemas
4
- 📄 appwrite-config.schema.json
5
- 📄 collection.schema.json
6
- 📁 collections
7
- 📄 Categories.yaml
8
- 📄 ExampleCollection.yaml
9
- 📄 Posts.yaml
10
- 📄 Users.yaml
11
- 📄 config.yaml
12
- 📁 import
13
- 📄 README.md
14
- 📄 categories-import.yaml
15
- 📄 posts-import.yaml
16
- 📄 users-import.yaml
17
- 📁 importData
18
- 📄 categories.json
19
- 📄 posts.json
20
- 📄 users.json
21
- 📁 schemas
22
- 📄 categories.json
23
- 📄 exampleCollection.json
24
- 📄 posts.json
25
- 📄 users.json
26
- 📄 .gitignore
27
- 📄 .npmignore
28
- 📄 README.md
29
- 📁 dist
30
- 📁 node_modules
31
- 📄 package.json
32
- 📁 src
33
- 📁 collections
34
- 📄 attributes.ts
35
- 📄 indexes.ts
36
- 📄 methods.ts
37
- 📁 config
38
- 📄 yamlConfig.ts
39
- 📁 databases
40
- 📄 methods.ts
41
- 📄 setup.ts
42
- 📁 functions
43
- 📄 deployments.ts
44
- 📄 methods.ts
45
- 📄 openapi.ts
46
- 📁 templates
47
- 📁 count-docs-in-collection
48
- 📄 README.md
49
- 📄 package.json
50
- 📁 src
51
- 📄 main.ts
52
- 📄 request.ts
53
- 📄 tsconfig.json
54
- 📁 typescript-node
55
- 📄 README.md
56
- 📄 package.json
57
- 📁 src
58
- 📄 index.ts
59
- 📄 tsconfig.json
60
- 📁 uv
61
- 📄 README.md
62
- 📄 pyproject.toml
63
- 📁 src
64
- 📄 __init__.py
65
- 📄 index.py
66
- 📄 init.ts
67
- 📄 interactiveCLI.ts
68
- 📄 main.ts
69
- 📁 migrations
70
- 📄 afterImportActions.ts
71
- 📄 appwriteToX.ts
72
- 📄 comprehensiveTransfer.ts
73
- 📄 dataLoader.ts
74
- 📄 importController.ts
75
- 📄 importDataActions.ts
76
- 📄 relationships.ts
77
- 📁 services
78
- 📄 DataTransformationService.ts
79
- 📄 FileHandlerService.ts
80
- 📄 ImportOrchestrator.ts
81
- 📄 RateLimitManager.ts
82
- 📄 RelationshipResolver.ts
83
- 📄 UserMappingService.ts
84
- 📄 ValidationService.ts
85
- 📄 transfer.ts
86
- 📁 yaml
87
- 📄 YamlImportConfigLoader.ts
88
- 📄 YamlImportIntegration.ts
89
- 📄 generateImportSchemas.ts
90
- 📁 schemas
91
- 📄 authUser.ts
92
- 📄 setup.ts
93
- 📄 setupCommands.ts
94
- 📄 setupController.ts
95
- 📁 shared
96
- 📄 attributeManager.ts
97
- 📄 confirmationDialogs.ts
98
- 📄 functionManager.ts
99
- 📄 indexManager.ts
100
- 📄 jsonSchemaGenerator.ts
101
- 📄 logging.ts
102
- 📄 messageFormatter.ts
103
- 📄 migrationHelpers.ts
104
- 📄 operationLogger.ts
105
- 📄 operationQueue.ts
106
- 📄 progressManager.ts
107
- 📄 schemaGenerator.ts
108
- 📁 storage
109
- 📄 methods.ts
110
- 📄 schemas.ts
111
- 📄 types.ts
112
- 📁 users
113
- 📄 methods.ts
114
- 📁 utils
115
- 📄 configMigration.ts
116
- 📄 constantsGenerator.ts
117
- 📄 dataConverters.ts
118
- 📄 getClientFromConfig.ts
119
- 📄 helperFunctions.ts
120
- 📄 index.ts
121
- 📄 loadConfigs.ts
122
- 📄 retryFailedPromises.ts
123
- 📄 schemaStrings.ts
124
- 📄 setupFiles.ts
125
- 📄 validationRules.ts
126
- 📄 yamlConverter.ts
127
- 📄 utilsController.ts
128
- 📄 tsconfig.json
129
- 📁 zlogs
130
- 📄 error.log
131
- 📄 info.log
132
- 📄 warn.log