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.
- package/README.md +1 -2
- package/dist/collections/methods.js +6 -4
- package/dist/functions/deployments.d.ts +4 -0
- package/dist/functions/deployments.js +114 -0
- package/dist/functions/methods.d.ts +13 -8
- package/dist/functions/methods.js +74 -20
- package/dist/functions/templates/count-docs-in-collection/src/main.d.ts +21 -0
- package/dist/functions/templates/count-docs-in-collection/src/main.js +114 -0
- package/dist/functions/templates/count-docs-in-collection/src/request.d.ts +15 -0
- package/dist/functions/templates/count-docs-in-collection/src/request.js +6 -0
- package/dist/functions/templates/typescript-node/src/index.d.ts +11 -0
- package/dist/functions/templates/typescript-node/src/index.js +11 -0
- package/dist/interactiveCLI.d.ts +6 -0
- package/dist/interactiveCLI.js +437 -32
- package/dist/main.js +0 -0
- package/dist/migrations/appwriteToX.js +32 -1
- package/dist/migrations/schemaStrings.d.ts +1 -0
- package/dist/migrations/schemaStrings.js +74 -2
- package/dist/migrations/transfer.js +112 -123
- package/dist/utils/loadConfigs.d.ts +1 -0
- package/dist/utils/loadConfigs.js +19 -0
- package/dist/utils/schemaStrings.js +27 -0
- package/dist/utilsController.d.ts +5 -1
- package/dist/utilsController.js +54 -2
- package/package.json +57 -55
- package/src/collections/methods.ts +29 -10
- package/src/functions/deployments.ts +190 -0
- package/src/functions/methods.ts +295 -235
- package/src/functions/templates/count-docs-in-collection/README.md +54 -0
- package/src/functions/templates/count-docs-in-collection/src/main.ts +159 -0
- package/src/functions/templates/count-docs-in-collection/src/request.ts +9 -0
- package/src/functions/templates/poetry/README.md +30 -0
- package/src/functions/templates/poetry/pyproject.toml +16 -0
- package/src/functions/templates/poetry/src/__init__.py +0 -0
- package/src/functions/templates/poetry/src/index.py +16 -0
- package/src/functions/templates/typescript-node/README.md +32 -0
- package/src/functions/templates/typescript-node/src/index.ts +23 -0
- package/src/interactiveCLI.ts +606 -47
- package/src/migrations/appwriteToX.ts +44 -1
- package/src/migrations/schemaStrings.ts +83 -2
- package/src/migrations/transfer.ts +280 -207
- package/src/setupController.ts +41 -41
- package/src/utils/loadConfigs.ts +24 -0
- package/src/utils/schemaStrings.ts +27 -0
- package/src/utilsController.ts +63 -3
- 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,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
|
+
}
|