appwrite-utils-cli 0.9.993 → 0.9.995

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.
Files changed (46) hide show
  1. package/README.md +1 -2
  2. package/dist/collections/methods.js +6 -4
  3. package/dist/functions/deployments.d.ts +4 -0
  4. package/dist/functions/deployments.js +114 -0
  5. package/dist/functions/methods.d.ts +13 -8
  6. package/dist/functions/methods.js +74 -20
  7. package/dist/functions/templates/count-docs-in-collection/src/main.d.ts +21 -0
  8. package/dist/functions/templates/count-docs-in-collection/src/main.js +114 -0
  9. package/dist/functions/templates/count-docs-in-collection/src/request.d.ts +15 -0
  10. package/dist/functions/templates/count-docs-in-collection/src/request.js +6 -0
  11. package/dist/functions/templates/typescript-node/src/index.d.ts +11 -0
  12. package/dist/functions/templates/typescript-node/src/index.js +11 -0
  13. package/dist/interactiveCLI.d.ts +6 -0
  14. package/dist/interactiveCLI.js +437 -32
  15. package/dist/main.js +0 -0
  16. package/dist/migrations/appwriteToX.js +32 -1
  17. package/dist/migrations/schemaStrings.d.ts +1 -0
  18. package/dist/migrations/schemaStrings.js +74 -2
  19. package/dist/migrations/transfer.js +112 -123
  20. package/dist/utils/loadConfigs.d.ts +1 -0
  21. package/dist/utils/loadConfigs.js +19 -0
  22. package/dist/utils/schemaStrings.js +27 -0
  23. package/dist/utilsController.d.ts +5 -1
  24. package/dist/utilsController.js +54 -2
  25. package/package.json +57 -55
  26. package/src/collections/methods.ts +29 -10
  27. package/src/functions/deployments.ts +190 -0
  28. package/src/functions/methods.ts +295 -235
  29. package/src/functions/templates/count-docs-in-collection/README.md +54 -0
  30. package/src/functions/templates/count-docs-in-collection/src/main.ts +159 -0
  31. package/src/functions/templates/count-docs-in-collection/src/request.ts +9 -0
  32. package/src/functions/templates/poetry/README.md +30 -0
  33. package/src/functions/templates/poetry/pyproject.toml +16 -0
  34. package/src/functions/templates/poetry/src/__init__.py +0 -0
  35. package/src/functions/templates/poetry/src/index.py +16 -0
  36. package/src/functions/templates/typescript-node/README.md +32 -0
  37. package/src/functions/templates/typescript-node/src/index.ts +23 -0
  38. package/src/interactiveCLI.ts +606 -47
  39. package/src/migrations/appwriteToX.ts +44 -1
  40. package/src/migrations/schemaStrings.ts +83 -2
  41. package/src/migrations/transfer.ts +280 -207
  42. package/src/setupController.ts +41 -41
  43. package/src/utils/loadConfigs.ts +24 -0
  44. package/src/utils/schemaStrings.ts +27 -0
  45. package/src/utilsController.ts +63 -3
  46. package/tsconfig.json +8 -1
@@ -0,0 +1,159 @@
1
+ import { Client, Databases, Query } from "node-appwrite";
2
+ import { AppwriteRequest, type AppwriteResponse } from "appwrite-utils";
3
+ import { requestSchema } from "./request.js";
4
+
5
+ /**
6
+ * Main function to handle document counting requests.
7
+ * @param {Object} params - The function parameters.
8
+ * @param {Object} params.req - The request object.
9
+ * @param {Object} params.res - The response object.
10
+ * @param {Function} params.log - Logging function.
11
+ * @param {Function} params.error - Error logging function.
12
+ * @returns {Promise<Object>} JSON response with count or error message.
13
+ */
14
+ export default async ({
15
+ req,
16
+ res,
17
+ log,
18
+ error,
19
+ }: {
20
+ req: AppwriteRequest;
21
+ res: AppwriteResponse;
22
+ log: (message: string) => void;
23
+ error: (message: string) => void;
24
+ }) => {
25
+ // Initialize Appwrite client
26
+ const client = new Client()
27
+ .setEndpoint(process.env["APPWRITE_FUNCTION_ENDPOINT"]!)
28
+ .setProject(process.env["APPWRITE_FUNCTION_PROJECT_ID"]!)
29
+ .setKey(req.headers["x-appwrite-key"] || "");
30
+
31
+ const databases = new Databases(client);
32
+
33
+ try {
34
+ if (req.method === "POST") {
35
+ // Parse request body
36
+ const body = requestSchema.safeParse(
37
+ typeof req.body === "string" ? JSON.parse(req.body) : req.body
38
+ );
39
+
40
+ if (!body.success) {
41
+ return res.json({ success: false, error: body.error }, 400);
42
+ }
43
+
44
+ const { databaseId, collectionId, queries = [] } = body.data;
45
+
46
+ log(`Queries: ${JSON.stringify(queries)}`);
47
+
48
+ // Count documents in the specified collection
49
+ const count = await countAllDocuments(
50
+ log,
51
+ databases,
52
+ databaseId,
53
+ collectionId,
54
+ queries
55
+ );
56
+
57
+ // Return successful response with document count
58
+ return res.json({
59
+ success: true,
60
+ count: count,
61
+ });
62
+ } else {
63
+ // Return error for non-POST requests
64
+ return res.json({ success: false, error: "Method not allowed" }, 405);
65
+ }
66
+ } catch (err) {
67
+ // Log and return any errors
68
+ error(`Error processing request: ${err}`);
69
+ return res.json({ success: false, error: (err as Error).message }, 500);
70
+ }
71
+ };
72
+
73
+ /**
74
+ * Counts all documents in a collection, handling large collections efficiently.
75
+ * @param {Function} log - Logging function.
76
+ * @param {Databases} databases - Appwrite Databases instance.
77
+ * @param {string} databaseId - ID of the database.
78
+ * @param {string} collectionId - ID of the collection.
79
+ * @param {string[]} queries - Array of query strings to filter documents.
80
+ * @param {number} batchSize - Size of batches for processing (default: 1000).
81
+ * @returns {Promise<number>} Total count of documents.
82
+ */
83
+ async function countAllDocuments(
84
+ log: any,
85
+ databases: Databases,
86
+ databaseId: string,
87
+ collectionId: string,
88
+ queries: string[] = [],
89
+ batchSize: number = 1000
90
+ ): Promise<number> {
91
+ // Filter out limit and offset queries
92
+ const initialQueries = queries.filter(
93
+ (q) => !(q.includes("limit") || q.includes("offset"))
94
+ );
95
+
96
+ // Initial query to check if total is less than 5000
97
+ const initialResponse = await databases.listDocuments(
98
+ databaseId,
99
+ collectionId,
100
+ [...initialQueries, Query.limit(1)]
101
+ );
102
+
103
+ if (initialResponse.total < 5000) {
104
+ log(`Total documents (from initial response): ${initialResponse.total}`);
105
+ return initialResponse.total;
106
+ }
107
+
108
+ // If total is 5000 or more, we need to count manually
109
+ let bound = 5000;
110
+
111
+ // Exponential search to find an upper bound
112
+ while (true) {
113
+ log(`Querying for offset ${bound}`);
114
+ try {
115
+ const response = await databases.listDocuments(databaseId, collectionId, [
116
+ ...initialQueries,
117
+ Query.limit(1),
118
+ Query.offset(bound),
119
+ ]);
120
+
121
+ if (response.documents.length === 0) {
122
+ break;
123
+ }
124
+ bound *= 2;
125
+ } catch (error) {
126
+ break;
127
+ }
128
+ }
129
+
130
+ // Binary search to find the exact count
131
+ let low = Math.floor(bound / 2);
132
+ let high = bound;
133
+ let lastValidCount = low;
134
+
135
+ while (low <= high) {
136
+ const mid = Math.floor((low + high) / 2);
137
+ log(`Binary search: Querying for offset ${mid}`);
138
+
139
+ try {
140
+ const response = await databases.listDocuments(databaseId, collectionId, [
141
+ ...initialQueries,
142
+ Query.limit(1),
143
+ Query.offset(mid),
144
+ ]);
145
+
146
+ if (response.documents.length > 0) {
147
+ lastValidCount = mid + 1; // +1 because offset is 0-based
148
+ low = mid + 1;
149
+ } else {
150
+ high = mid - 1;
151
+ }
152
+ } catch (error) {
153
+ high = mid - 1;
154
+ }
155
+ }
156
+
157
+ log(`Total documents: ${lastValidCount}`);
158
+ return lastValidCount;
159
+ }
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+
3
+ export const requestSchema = z.object({
4
+ databaseId: z.string(),
5
+ collectionId: z.string(),
6
+ queries: z.array(z.string()).optional(),
7
+ });
8
+
9
+ export type Request = z.infer<typeof requestSchema>;
@@ -0,0 +1,30 @@
1
+ # Python Poetry Function Template
2
+
3
+ This is a Python template for Appwrite Functions using Poetry for dependency management.
4
+
5
+ ## Structure
6
+ - `src/index.py`: Main function entry point
7
+ - `pyproject.toml`: Poetry configuration and dependencies
8
+
9
+ ## Usage
10
+ Your function will receive a context object with:
11
+ - `req`: Request object containing request data, headers, and environment variables
12
+ - `res`: Response object for sending responses
13
+ - `log`: Function for logging (shows in your function logs)
14
+ - `error`: Function for error logging
15
+
16
+ ## Example Request
17
+ ```json
18
+ {
19
+ "key": "value"
20
+ }
21
+ ```
22
+
23
+ ## Development
24
+ 1. Install Poetry: `curl -sSL https://install.python-poetry.org | python3 -`
25
+ 2. Install dependencies: `poetry install`
26
+ 3. Deploy: Dependencies will be installed during deployment
27
+
28
+ ## Deployment
29
+ Make sure it's inside `appwriteConfig.ts` functions array, and if you want to install dependencies FIRST, before Appwrite (using your system), you can
30
+ add the `predeployCommands` to the function in `appwriteConfig.ts`.
@@ -0,0 +1,16 @@
1
+ [tool.poetry]
2
+ name = "{{functionName}}"
3
+ version = "0.1.0"
4
+ description = ""
5
+ authors = ["Your Name <you@example.com>"]
6
+ packages = [
7
+ { include = "src" }
8
+ ]
9
+
10
+ [tool.poetry.dependencies]
11
+ python = "^3.9"
12
+ appwrite = "^7.0.1"
13
+
14
+ [build-system]
15
+ requires = ["poetry-core>=1.0.0"]
16
+ build-backend = "poetry.core.masonry.api"
File without changes
@@ -0,0 +1,16 @@
1
+ from appwrite.client import Client
2
+
3
+ def main(context):
4
+ req = context.req
5
+ res = context.res
6
+ log = context.log
7
+ error = context.error
8
+
9
+ client = Client()
10
+ client.set_endpoint(req.env['APPWRITE_FUNCTION_ENDPOINT'])
11
+ client.set_project(req.env['APPWRITE_FUNCTION_PROJECT_ID'])
12
+ client.set_key(req.env['APPWRITE_FUNCTION_API_KEY'])
13
+
14
+ return res.json({
15
+ 'message': 'Hello from Python function!'
16
+ })
@@ -0,0 +1,32 @@
1
+ # TypeScript Node.js Function Template
2
+
3
+ This is a TypeScript template for Appwrite Functions using Node.js runtime.
4
+
5
+ ## Structure
6
+ - `src/index.ts`: Main function entry point
7
+ - `src/appwriteRequest.ts`: Type definitions for Appwrite request object
8
+ - `src/appwriteResponse.ts`: Type definitions for Appwrite response object
9
+
10
+ ## Usage
11
+ Your function will receive:
12
+ - `req`: AppwriteRequest object containing request data, headers, and environment variables
13
+ - `res`: AppwriteResponse object for sending responses
14
+ - `log`: Function for logging (shows in your function logs)
15
+ - `error`: Function for error logging
16
+
17
+ ## Example Request
18
+ ```json
19
+ {
20
+ "databaseId": "your-database-id",
21
+ "collectionId": "your-collection-id"
22
+ }
23
+ ```
24
+
25
+ ## Development
26
+ 1. Install dependencies: `npm|yarn|bun install`
27
+ 2. Build: `npm|yarn|bun run build`
28
+ 3. Deploy: Function will be built automatically during deployment
29
+
30
+ ## Deployment
31
+ Make sure it's inside `appwriteConfig.ts` functions array, and if you want to build it FIRST, before Appwrite (using your system), you can
32
+ add the `predeployCommands` to the function in `appwriteConfig.ts` -- for an example, see `count-docs-in-collection` function.
@@ -0,0 +1,23 @@
1
+ import { Client } from "node-appwrite";
2
+ import { AppwriteRequest, type AppwriteResponse } from "appwrite-utils";
3
+
4
+ export default async function ({
5
+ req,
6
+ res,
7
+ log,
8
+ error,
9
+ }: {
10
+ req: AppwriteRequest;
11
+ res: AppwriteResponse;
12
+ log: (message: string) => void;
13
+ error: (message: string) => void;
14
+ }) {
15
+ const client = new Client()
16
+ .setEndpoint(process.env["APPWRITE_FUNCTION_ENDPOINT"]!)
17
+ .setProject(process.env["APPWRITE_FUNCTION_PROJECT_ID"]!)
18
+ .setKey(req.headers["x-appwrite-key"] || "");
19
+
20
+ return res.json({
21
+ message: "Hello from TypeScript function!",
22
+ });
23
+ }