diff --git a/CHANGELOG.md b/CHANGELOG.md index 72dd1760..12ff683e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Change Log +## 19.1.0 + +* Added `--where`, `--sort-asc`, `--sort-desc`, `--limit`, `--offset`, `--cursor-after`, and `--cursor-before` flags on list commands across services +* Added `--select` flag on `databases list-documents`, `tablesdb list-rows`, and other row/document list commands +* Added a hint after query-related errors that points to the new flag-based filters +* Updated `--queries` description to mark it as the legacy raw-JSON option, recommending the new flag-based filters for common cases +* Updated bundled examples to demonstrate `--limit` on list commands + ## 19.0.0 * Breaking: Renamed `project update-protocol-status` to `project update-protocol` diff --git a/README.md b/README.md index 00c2f00d..c4a8da5b 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ Once the installation is complete, you can verify the install using ```sh $ appwrite -v -19.0.0 +19.1.0 ``` ### Install using prebuilt binaries @@ -62,7 +62,7 @@ $ scoop install https://raw.githubusercontent.com/appwrite/sdk-for-cli/master/sc Once the installation completes, you can verify your install using ``` $ appwrite -v -19.0.0 +19.1.0 ``` ## Getting Started diff --git a/bun.lock b/bun.lock index 67781618..6f2555ab 100644 --- a/bun.lock +++ b/bun.lock @@ -48,6 +48,7 @@ "overrides": { "@xmldom/xmldom": "^0.9.10", "phin": "3.7.1", + "tmp": "0.2.5", }, "packages": { "@appwrite.io/console": ["@appwrite.io/console@11.0.0", "", { "dependencies": { "json-bigint": "1.0.0" } }, "sha512-7w2MNVDP5cNLExJlEOttfBAvOFd1GA+rAUBoqhtvd81GLZZrMZck7QZv4cyhz3LO54jUg5zBWbyC1lsXCRWiEg=="], @@ -248,7 +249,7 @@ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="], - "@roberts_lando/vfs": ["@roberts_lando/vfs@0.3.2", "", {}, "sha512-whXj9v78S4n3t0RvoTGj8vui27VVtK/oy8YfBL+gDWdlfRFkKpPjry+U8p+3XM++5rAIpXEtXcTUgUAEHZVoFA=="], + "@roberts_lando/vfs": ["@roberts_lando/vfs@0.3.3", "", {}, "sha512-YjkxVSLw5WMZQoARaryRAjcxA+GbBzWMJdwYZX5oLUt9cC/gew9as4Dn7tcLzPp7BPoR221VpTZ+78TRPawnjg=="], "@tokenizer/inflate": ["@tokenizer/inflate@0.4.1", "", { "dependencies": { "debug": "^4.4.3", "token-types": "^6.1.1" } }, "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA=="], @@ -294,7 +295,7 @@ "@xmldom/xmldom": ["@xmldom/xmldom@0.9.10", "", {}, "sha512-A9gOqLdi6cV4ibazAjcQufGj0B1y/vDqYrcuP6d/6x8P27gRS8643Dj9o1dEKtB6O7fwxb2FgBmJS2mX7gpvdw=="], - "@yao-pkg/pkg": ["@yao-pkg/pkg@6.18.2", "", { "dependencies": { "@babel/generator": "^7.23.0", "@babel/parser": "^7.23.0", "@babel/traverse": "^7.23.0", "@babel/types": "^7.23.0", "@roberts_lando/vfs": "^0.3.2", "@yao-pkg/pkg-fetch": "3.5.33", "esbuild": "^0.27.3", "into-stream": "^9.1.0", "minimist": "^1.2.6", "multistream": "^4.1.0", "picocolors": "^1.1.0", "picomatch": "^4.0.2", "postject": "^1.0.0-alpha.6", "prebuild-install": "^7.1.1", "resolve": "^1.22.10", "resolve.exports": "^2.0.3", "stream-meter": "^1.0.4", "tar": "^7.5.7", "tinyglobby": "^0.2.11", "unzipper": "^0.12.3" }, "bin": { "pkg": "lib-es5/bin.js" } }, "sha512-lo+fNeV10ldTeTrDbgK2eYTIhKDqCUVVq7a4W3s7LiTwd9/8UKYdxBodVNNCbEd2JBtqKA4BZpevitfsOzyXig=="], + "@yao-pkg/pkg": ["@yao-pkg/pkg@6.19.0", "", { "dependencies": { "@babel/generator": "^7.23.0", "@babel/parser": "^7.23.0", "@babel/traverse": "^7.23.0", "@babel/types": "^7.23.0", "@roberts_lando/vfs": "^0.3.3", "@yao-pkg/pkg-fetch": "3.5.33", "esbuild": "^0.27.3", "into-stream": "^9.1.0", "multistream": "^4.1.0", "picocolors": "^1.1.0", "picomatch": "^4.0.2", "postject": "^1.0.0-alpha.6", "prebuild-install": "^7.1.1", "resolve": "^1.22.10", "resolve.exports": "^2.0.3", "stream-meter": "^1.0.4", "tar": "^7.5.7", "tinyglobby": "^0.2.11", "unzipper": "^0.12.3" }, "bin": { "pkg": "lib-es5/bin.js" } }, "sha512-Ys9Fn/F44C3nOTlNyhwviLyMxydgFzsB13jAAXKxEuIR7aAz8PrFlUpxTUlwaXUU847nlmg5mnaGIyOJpnVtRw=="], "@yao-pkg/pkg-fetch": ["@yao-pkg/pkg-fetch@3.5.33", "", { "dependencies": { "https-proxy-agent": "^5.0.0", "node-fetch": "^2.6.6", "picocolors": "^1.1.0", "progress": "^2.0.3", "semver": "^7.3.5", "tar-fs": "^3.1.1", "yargs": "^16.2.0" }, "bin": { "pkg-fetch": "lib-es5/bin.js" } }, "sha512-j2UoH+eP4VobfovQg1gkWwDoB4O/tv8rlLnEjUEEHuWXJ5eBLNUIrobMSEp773/2pgUJUfqqPUFIhS1pN8OZuQ=="], @@ -304,7 +305,7 @@ "agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="], - "ajv": ["ajv@6.14.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw=="], + "ajv": ["ajv@6.15.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw=="], "ansi-escapes": ["ansi-escapes@4.3.2", "", { "dependencies": { "type-fest": "^0.21.3" } }, "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ=="], @@ -684,8 +685,6 @@ "ora": ["ora@5.4.1", "", { "dependencies": { "bl": "^4.1.0", "chalk": "^4.1.0", "cli-cursor": "^3.1.0", "cli-spinners": "^2.5.0", "is-interactive": "^1.0.0", "is-unicode-supported": "^0.1.0", "log-symbols": "^4.1.0", "strip-ansi": "^6.0.0", "wcwidth": "^1.0.1" } }, "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ=="], - "os-tmpdir": ["os-tmpdir@1.0.2", "", {}, "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g=="], - "p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="], "p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="], @@ -836,7 +835,7 @@ "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="], - "tmp": ["tmp@0.0.33", "", { "dependencies": { "os-tmpdir": "~1.0.2" } }, "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw=="], + "tmp": ["tmp@0.2.5", "", {}, "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow=="], "to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="], diff --git a/docs/examples/account/list-identities.md b/docs/examples/account/list-identities.md index 583d515c..ecc5d685 100644 --- a/docs/examples/account/list-identities.md +++ b/docs/examples/account/list-identities.md @@ -1,3 +1,4 @@ ```bash -appwrite account list-identities +appwrite account list-identities \ + --limit 25 ``` diff --git a/docs/examples/account/list-logs.md b/docs/examples/account/list-logs.md index 2414a8aa..5149c953 100644 --- a/docs/examples/account/list-logs.md +++ b/docs/examples/account/list-logs.md @@ -1,3 +1,4 @@ ```bash -appwrite account list-logs +appwrite account list-logs \ + --limit 25 ``` diff --git a/docs/examples/backups/list-archives.md b/docs/examples/backups/list-archives.md index 81a64aa1..403c0395 100644 --- a/docs/examples/backups/list-archives.md +++ b/docs/examples/backups/list-archives.md @@ -1,3 +1,4 @@ ```bash -appwrite backups list-archives +appwrite backups list-archives \ + --limit 25 ``` diff --git a/docs/examples/backups/list-policies.md b/docs/examples/backups/list-policies.md index 29feba3d..cdaccd02 100644 --- a/docs/examples/backups/list-policies.md +++ b/docs/examples/backups/list-policies.md @@ -1,3 +1,4 @@ ```bash -appwrite backups list-policies +appwrite backups list-policies \ + --limit 25 ``` diff --git a/docs/examples/backups/list-restorations.md b/docs/examples/backups/list-restorations.md index aba2d2a0..37406de1 100644 --- a/docs/examples/backups/list-restorations.md +++ b/docs/examples/backups/list-restorations.md @@ -1,3 +1,4 @@ ```bash -appwrite backups list-restorations +appwrite backups list-restorations \ + --limit 25 ``` diff --git a/docs/examples/databases/delete-documents.md b/docs/examples/databases/delete-documents.md index 081420c5..7b1b3cb3 100644 --- a/docs/examples/databases/delete-documents.md +++ b/docs/examples/databases/delete-documents.md @@ -1,5 +1,6 @@ ```bash appwrite databases delete-documents \ --database-id \ - --collection-id + --collection-id \ + --limit 25 ``` diff --git a/docs/examples/databases/list-attributes.md b/docs/examples/databases/list-attributes.md index e38711de..677b7e1f 100644 --- a/docs/examples/databases/list-attributes.md +++ b/docs/examples/databases/list-attributes.md @@ -1,5 +1,6 @@ ```bash appwrite databases list-attributes \ --database-id \ - --collection-id + --collection-id \ + --limit 25 ``` diff --git a/docs/examples/databases/list-collection-logs.md b/docs/examples/databases/list-collection-logs.md index fe4f7cdc..63f62f50 100644 --- a/docs/examples/databases/list-collection-logs.md +++ b/docs/examples/databases/list-collection-logs.md @@ -1,5 +1,6 @@ ```bash appwrite databases list-collection-logs \ --database-id \ - --collection-id + --collection-id \ + --limit 25 ``` diff --git a/docs/examples/databases/list-collections.md b/docs/examples/databases/list-collections.md index 9e71024e..6935aeb0 100644 --- a/docs/examples/databases/list-collections.md +++ b/docs/examples/databases/list-collections.md @@ -1,4 +1,5 @@ ```bash appwrite databases list-collections \ - --database-id + --database-id \ + --limit 25 ``` diff --git a/docs/examples/databases/list-document-logs.md b/docs/examples/databases/list-document-logs.md index 6ee590ea..0c5b5521 100644 --- a/docs/examples/databases/list-document-logs.md +++ b/docs/examples/databases/list-document-logs.md @@ -2,5 +2,6 @@ appwrite databases list-document-logs \ --database-id \ --collection-id \ - --document-id + --document-id \ + --limit 25 ``` diff --git a/docs/examples/databases/list-documents.md b/docs/examples/databases/list-documents.md index 34e87518..9a1e55a6 100644 --- a/docs/examples/databases/list-documents.md +++ b/docs/examples/databases/list-documents.md @@ -1,5 +1,6 @@ ```bash appwrite databases list-documents \ --database-id \ - --collection-id + --collection-id \ + --limit 25 ``` diff --git a/docs/examples/databases/list-indexes.md b/docs/examples/databases/list-indexes.md index c660a669..7ba7a81d 100644 --- a/docs/examples/databases/list-indexes.md +++ b/docs/examples/databases/list-indexes.md @@ -1,5 +1,6 @@ ```bash appwrite databases list-indexes \ --database-id \ - --collection-id + --collection-id \ + --limit 25 ``` diff --git a/docs/examples/databases/list-logs.md b/docs/examples/databases/list-logs.md index fbb6aac3..d205ea6f 100644 --- a/docs/examples/databases/list-logs.md +++ b/docs/examples/databases/list-logs.md @@ -1,4 +1,5 @@ ```bash appwrite databases list-logs \ - --database-id + --database-id \ + --limit 25 ``` diff --git a/docs/examples/databases/list-transactions.md b/docs/examples/databases/list-transactions.md index d3857f3a..f74d48bc 100644 --- a/docs/examples/databases/list-transactions.md +++ b/docs/examples/databases/list-transactions.md @@ -1,3 +1,4 @@ ```bash -appwrite databases list-transactions +appwrite databases list-transactions \ + --limit 25 ``` diff --git a/docs/examples/databases/list.md b/docs/examples/databases/list.md index b3475f33..dd8c3bb0 100644 --- a/docs/examples/databases/list.md +++ b/docs/examples/databases/list.md @@ -1,3 +1,4 @@ ```bash -appwrite databases list +appwrite databases list \ + --limit 25 ``` diff --git a/docs/examples/databases/update-documents.md b/docs/examples/databases/update-documents.md index 4047ec8d..27f82540 100644 --- a/docs/examples/databases/update-documents.md +++ b/docs/examples/databases/update-documents.md @@ -1,5 +1,6 @@ ```bash appwrite databases update-documents \ --database-id \ - --collection-id + --collection-id \ + --limit 25 ``` diff --git a/docs/examples/functions/list-deployments.md b/docs/examples/functions/list-deployments.md index c47edd24..db709006 100644 --- a/docs/examples/functions/list-deployments.md +++ b/docs/examples/functions/list-deployments.md @@ -1,4 +1,5 @@ ```bash appwrite functions list-deployments \ - --function-id + --function-id \ + --limit 25 ``` diff --git a/docs/examples/functions/list-executions.md b/docs/examples/functions/list-executions.md index d04eeb8e..1b82ec5e 100644 --- a/docs/examples/functions/list-executions.md +++ b/docs/examples/functions/list-executions.md @@ -1,4 +1,5 @@ ```bash appwrite functions list-executions \ - --function-id + --function-id \ + --limit 25 ``` diff --git a/docs/examples/functions/list.md b/docs/examples/functions/list.md index 17324582..9542b5c7 100644 --- a/docs/examples/functions/list.md +++ b/docs/examples/functions/list.md @@ -1,3 +1,4 @@ ```bash -appwrite functions list +appwrite functions list \ + --limit 25 ``` diff --git a/docs/examples/messaging/list-message-logs.md b/docs/examples/messaging/list-message-logs.md index 45b14aa3..e5278e5c 100644 --- a/docs/examples/messaging/list-message-logs.md +++ b/docs/examples/messaging/list-message-logs.md @@ -1,4 +1,5 @@ ```bash appwrite messaging list-message-logs \ - --message-id + --message-id \ + --limit 25 ``` diff --git a/docs/examples/messaging/list-messages.md b/docs/examples/messaging/list-messages.md index 3efe7459..fbbdea82 100644 --- a/docs/examples/messaging/list-messages.md +++ b/docs/examples/messaging/list-messages.md @@ -1,3 +1,4 @@ ```bash -appwrite messaging list-messages +appwrite messaging list-messages \ + --limit 25 ``` diff --git a/docs/examples/messaging/list-provider-logs.md b/docs/examples/messaging/list-provider-logs.md index ca94e511..c71e1449 100644 --- a/docs/examples/messaging/list-provider-logs.md +++ b/docs/examples/messaging/list-provider-logs.md @@ -1,4 +1,5 @@ ```bash appwrite messaging list-provider-logs \ - --provider-id + --provider-id \ + --limit 25 ``` diff --git a/docs/examples/messaging/list-providers.md b/docs/examples/messaging/list-providers.md index 6fa490ab..787ee524 100644 --- a/docs/examples/messaging/list-providers.md +++ b/docs/examples/messaging/list-providers.md @@ -1,3 +1,4 @@ ```bash -appwrite messaging list-providers +appwrite messaging list-providers \ + --limit 25 ``` diff --git a/docs/examples/messaging/list-subscriber-logs.md b/docs/examples/messaging/list-subscriber-logs.md index 5dc4100f..c42b8844 100644 --- a/docs/examples/messaging/list-subscriber-logs.md +++ b/docs/examples/messaging/list-subscriber-logs.md @@ -1,4 +1,5 @@ ```bash appwrite messaging list-subscriber-logs \ - --subscriber-id + --subscriber-id \ + --limit 25 ``` diff --git a/docs/examples/messaging/list-subscribers.md b/docs/examples/messaging/list-subscribers.md index 1431c324..bc7d3340 100644 --- a/docs/examples/messaging/list-subscribers.md +++ b/docs/examples/messaging/list-subscribers.md @@ -1,4 +1,5 @@ ```bash appwrite messaging list-subscribers \ - --topic-id + --topic-id \ + --limit 25 ``` diff --git a/docs/examples/messaging/list-targets.md b/docs/examples/messaging/list-targets.md index 08072882..d49b1922 100644 --- a/docs/examples/messaging/list-targets.md +++ b/docs/examples/messaging/list-targets.md @@ -1,4 +1,5 @@ ```bash appwrite messaging list-targets \ - --message-id + --message-id \ + --limit 25 ``` diff --git a/docs/examples/messaging/list-topic-logs.md b/docs/examples/messaging/list-topic-logs.md index 3bcda10f..bdfe5a95 100644 --- a/docs/examples/messaging/list-topic-logs.md +++ b/docs/examples/messaging/list-topic-logs.md @@ -1,4 +1,5 @@ ```bash appwrite messaging list-topic-logs \ - --topic-id + --topic-id \ + --limit 25 ``` diff --git a/docs/examples/messaging/list-topics.md b/docs/examples/messaging/list-topics.md index 87e895e0..3cb2a5dd 100644 --- a/docs/examples/messaging/list-topics.md +++ b/docs/examples/messaging/list-topics.md @@ -1,3 +1,4 @@ ```bash -appwrite messaging list-topics +appwrite messaging list-topics \ + --limit 25 ``` diff --git a/docs/examples/migrations/create-csv-export.md b/docs/examples/migrations/create-csv-export.md index 0e2a463e..4f00222e 100644 --- a/docs/examples/migrations/create-csv-export.md +++ b/docs/examples/migrations/create-csv-export.md @@ -1,5 +1,6 @@ ```bash appwrite migrations create-csv-export \ --resource-id \ - --filename + --filename \ + --limit 25 ``` diff --git a/docs/examples/migrations/create-json-export.md b/docs/examples/migrations/create-json-export.md index 9c87078c..5dbf4d62 100644 --- a/docs/examples/migrations/create-json-export.md +++ b/docs/examples/migrations/create-json-export.md @@ -1,5 +1,6 @@ ```bash appwrite migrations create-json-export \ --resource-id \ - --filename + --filename \ + --limit 25 ``` diff --git a/docs/examples/migrations/list.md b/docs/examples/migrations/list.md index ffc69a20..7aa5c19f 100644 --- a/docs/examples/migrations/list.md +++ b/docs/examples/migrations/list.md @@ -1,3 +1,4 @@ ```bash -appwrite migrations list +appwrite migrations list \ + --limit 25 ``` diff --git a/docs/examples/organizations/list-aggregations.md b/docs/examples/organizations/list-aggregations.md index d93be54d..200d8e4d 100644 --- a/docs/examples/organizations/list-aggregations.md +++ b/docs/examples/organizations/list-aggregations.md @@ -1,4 +1,5 @@ ```bash appwrite organizations list-aggregations \ - --organization-id + --organization-id \ + --limit 25 ``` diff --git a/docs/examples/organizations/list-credits.md b/docs/examples/organizations/list-credits.md index 73ee191a..5d8f9d1d 100644 --- a/docs/examples/organizations/list-credits.md +++ b/docs/examples/organizations/list-credits.md @@ -1,4 +1,5 @@ ```bash appwrite organizations list-credits \ - --organization-id + --organization-id \ + --limit 25 ``` diff --git a/docs/examples/organizations/list.md b/docs/examples/organizations/list.md index 457315ce..ca0c5ea1 100644 --- a/docs/examples/organizations/list.md +++ b/docs/examples/organizations/list.md @@ -1,3 +1,4 @@ ```bash -appwrite organizations list +appwrite organizations list \ + --limit 25 ``` diff --git a/docs/examples/project/list-keys.md b/docs/examples/project/list-keys.md index 83042b73..ce3e44e3 100644 --- a/docs/examples/project/list-keys.md +++ b/docs/examples/project/list-keys.md @@ -1,3 +1,4 @@ ```bash -appwrite project list-keys +appwrite project list-keys \ + --limit 25 ``` diff --git a/docs/examples/project/list-platforms.md b/docs/examples/project/list-platforms.md index f6f5d665..0c61bb5f 100644 --- a/docs/examples/project/list-platforms.md +++ b/docs/examples/project/list-platforms.md @@ -1,3 +1,4 @@ ```bash -appwrite project list-platforms +appwrite project list-platforms \ + --limit 25 ``` diff --git a/docs/examples/project/list-variables.md b/docs/examples/project/list-variables.md index 2f564671..5ab4c9d9 100644 --- a/docs/examples/project/list-variables.md +++ b/docs/examples/project/list-variables.md @@ -1,3 +1,4 @@ ```bash -appwrite project list-variables +appwrite project list-variables \ + --limit 25 ``` diff --git a/docs/examples/projects/list-dev-keys.md b/docs/examples/projects/list-dev-keys.md index aa0c9502..ce7ff188 100644 --- a/docs/examples/projects/list-dev-keys.md +++ b/docs/examples/projects/list-dev-keys.md @@ -1,4 +1,5 @@ ```bash appwrite projects list-dev-keys \ - --project-id + --project-id \ + --limit 25 ``` diff --git a/docs/examples/projects/list-schedules.md b/docs/examples/projects/list-schedules.md index f2b04e9f..16ae9bea 100644 --- a/docs/examples/projects/list-schedules.md +++ b/docs/examples/projects/list-schedules.md @@ -1,4 +1,5 @@ ```bash appwrite projects list-schedules \ - --project-id + --project-id \ + --limit 25 ``` diff --git a/docs/examples/projects/list.md b/docs/examples/projects/list.md index e22f4117..91e8ef85 100644 --- a/docs/examples/projects/list.md +++ b/docs/examples/projects/list.md @@ -1,3 +1,4 @@ ```bash -appwrite projects list +appwrite projects list \ + --limit 25 ``` diff --git a/docs/examples/proxy/list-rules.md b/docs/examples/proxy/list-rules.md index 167603db..219fdfc7 100644 --- a/docs/examples/proxy/list-rules.md +++ b/docs/examples/proxy/list-rules.md @@ -1,3 +1,4 @@ ```bash -appwrite proxy list-rules +appwrite proxy list-rules \ + --limit 25 ``` diff --git a/docs/examples/sites/list-deployments.md b/docs/examples/sites/list-deployments.md index 9d27a69f..f93db87f 100644 --- a/docs/examples/sites/list-deployments.md +++ b/docs/examples/sites/list-deployments.md @@ -1,4 +1,5 @@ ```bash appwrite sites list-deployments \ - --site-id + --site-id \ + --limit 25 ``` diff --git a/docs/examples/sites/list-logs.md b/docs/examples/sites/list-logs.md index 3cc1e0a2..97e098e9 100644 --- a/docs/examples/sites/list-logs.md +++ b/docs/examples/sites/list-logs.md @@ -1,4 +1,5 @@ ```bash appwrite sites list-logs \ - --site-id + --site-id \ + --limit 25 ``` diff --git a/docs/examples/sites/list.md b/docs/examples/sites/list.md index 7ca046dc..025a917d 100644 --- a/docs/examples/sites/list.md +++ b/docs/examples/sites/list.md @@ -1,3 +1,4 @@ ```bash -appwrite sites list +appwrite sites list \ + --limit 25 ``` diff --git a/docs/examples/storage/list-buckets.md b/docs/examples/storage/list-buckets.md index 2b466f64..3208c83d 100644 --- a/docs/examples/storage/list-buckets.md +++ b/docs/examples/storage/list-buckets.md @@ -1,3 +1,4 @@ ```bash -appwrite storage list-buckets +appwrite storage list-buckets \ + --limit 25 ``` diff --git a/docs/examples/storage/list-files.md b/docs/examples/storage/list-files.md index bb45294c..1a37b3f5 100644 --- a/docs/examples/storage/list-files.md +++ b/docs/examples/storage/list-files.md @@ -1,4 +1,5 @@ ```bash appwrite storage list-files \ - --bucket-id + --bucket-id \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/delete-rows.md b/docs/examples/tablesdb/delete-rows.md index eccdc150..dd8e9a61 100644 --- a/docs/examples/tablesdb/delete-rows.md +++ b/docs/examples/tablesdb/delete-rows.md @@ -1,5 +1,6 @@ ```bash appwrite tables-db delete-rows \ --database-id \ - --table-id + --table-id \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/list-columns.md b/docs/examples/tablesdb/list-columns.md index d84d3b88..44fc8937 100644 --- a/docs/examples/tablesdb/list-columns.md +++ b/docs/examples/tablesdb/list-columns.md @@ -1,5 +1,6 @@ ```bash appwrite tables-db list-columns \ --database-id \ - --table-id + --table-id \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/list-indexes.md b/docs/examples/tablesdb/list-indexes.md index 5880cfd9..c78ad6f1 100644 --- a/docs/examples/tablesdb/list-indexes.md +++ b/docs/examples/tablesdb/list-indexes.md @@ -1,5 +1,6 @@ ```bash appwrite tables-db list-indexes \ --database-id \ - --table-id + --table-id \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/list-row-logs.md b/docs/examples/tablesdb/list-row-logs.md index f956b3ee..f99cff06 100644 --- a/docs/examples/tablesdb/list-row-logs.md +++ b/docs/examples/tablesdb/list-row-logs.md @@ -2,5 +2,6 @@ appwrite tables-db list-row-logs \ --database-id \ --table-id \ - --row-id + --row-id \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/list-rows.md b/docs/examples/tablesdb/list-rows.md index adf42b30..5a47f9fb 100644 --- a/docs/examples/tablesdb/list-rows.md +++ b/docs/examples/tablesdb/list-rows.md @@ -1,5 +1,6 @@ ```bash appwrite tables-db list-rows \ --database-id \ - --table-id + --table-id \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/list-table-logs.md b/docs/examples/tablesdb/list-table-logs.md index 3b7bf557..b8625741 100644 --- a/docs/examples/tablesdb/list-table-logs.md +++ b/docs/examples/tablesdb/list-table-logs.md @@ -1,5 +1,6 @@ ```bash appwrite tables-db list-table-logs \ --database-id \ - --table-id + --table-id \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/list-tables.md b/docs/examples/tablesdb/list-tables.md index 5954aa17..b7ff4209 100644 --- a/docs/examples/tablesdb/list-tables.md +++ b/docs/examples/tablesdb/list-tables.md @@ -1,4 +1,5 @@ ```bash appwrite tables-db list-tables \ - --database-id + --database-id \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/list-transactions.md b/docs/examples/tablesdb/list-transactions.md index b99de5fb..9554db6b 100644 --- a/docs/examples/tablesdb/list-transactions.md +++ b/docs/examples/tablesdb/list-transactions.md @@ -1,3 +1,4 @@ ```bash -appwrite tables-db list-transactions +appwrite tables-db list-transactions \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/list.md b/docs/examples/tablesdb/list.md index 832493db..c3e86e0f 100644 --- a/docs/examples/tablesdb/list.md +++ b/docs/examples/tablesdb/list.md @@ -1,3 +1,4 @@ ```bash -appwrite tables-db list +appwrite tables-db list \ + --limit 25 ``` diff --git a/docs/examples/tablesdb/update-rows.md b/docs/examples/tablesdb/update-rows.md index 51766164..7e46f618 100644 --- a/docs/examples/tablesdb/update-rows.md +++ b/docs/examples/tablesdb/update-rows.md @@ -1,5 +1,6 @@ ```bash appwrite tables-db update-rows \ --database-id \ - --table-id + --table-id \ + --limit 25 ``` diff --git a/docs/examples/teams/list-logs.md b/docs/examples/teams/list-logs.md index 6a192922..dddb83c2 100644 --- a/docs/examples/teams/list-logs.md +++ b/docs/examples/teams/list-logs.md @@ -1,4 +1,5 @@ ```bash appwrite teams list-logs \ - --team-id + --team-id \ + --limit 25 ``` diff --git a/docs/examples/teams/list-memberships.md b/docs/examples/teams/list-memberships.md index bce1769d..1a324ea4 100644 --- a/docs/examples/teams/list-memberships.md +++ b/docs/examples/teams/list-memberships.md @@ -1,4 +1,5 @@ ```bash appwrite teams list-memberships \ - --team-id + --team-id \ + --limit 25 ``` diff --git a/docs/examples/teams/list.md b/docs/examples/teams/list.md index 6f4f38dc..8a783324 100644 --- a/docs/examples/teams/list.md +++ b/docs/examples/teams/list.md @@ -1,3 +1,4 @@ ```bash -appwrite teams list +appwrite teams list \ + --limit 25 ``` diff --git a/docs/examples/tokens/list.md b/docs/examples/tokens/list.md index 8f059914..ae34788d 100644 --- a/docs/examples/tokens/list.md +++ b/docs/examples/tokens/list.md @@ -1,5 +1,6 @@ ```bash appwrite tokens list \ --bucket-id \ - --file-id + --file-id \ + --limit 25 ``` diff --git a/docs/examples/users/list-identities.md b/docs/examples/users/list-identities.md index 4dcdb5d8..49032aa1 100644 --- a/docs/examples/users/list-identities.md +++ b/docs/examples/users/list-identities.md @@ -1,3 +1,4 @@ ```bash -appwrite users list-identities +appwrite users list-identities \ + --limit 25 ``` diff --git a/docs/examples/users/list-logs.md b/docs/examples/users/list-logs.md index 0b622bf9..e32e654b 100644 --- a/docs/examples/users/list-logs.md +++ b/docs/examples/users/list-logs.md @@ -1,4 +1,5 @@ ```bash appwrite users list-logs \ - --user-id + --user-id \ + --limit 25 ``` diff --git a/docs/examples/users/list-memberships.md b/docs/examples/users/list-memberships.md index df51790f..c10ce745 100644 --- a/docs/examples/users/list-memberships.md +++ b/docs/examples/users/list-memberships.md @@ -1,4 +1,5 @@ ```bash appwrite users list-memberships \ - --user-id + --user-id \ + --limit 25 ``` diff --git a/docs/examples/users/list-targets.md b/docs/examples/users/list-targets.md index 38d7eee8..9d5046a2 100644 --- a/docs/examples/users/list-targets.md +++ b/docs/examples/users/list-targets.md @@ -1,4 +1,5 @@ ```bash appwrite users list-targets \ - --user-id + --user-id \ + --limit 25 ``` diff --git a/docs/examples/users/list.md b/docs/examples/users/list.md index 9930d184..7d1e4bc2 100644 --- a/docs/examples/users/list.md +++ b/docs/examples/users/list.md @@ -1,3 +1,4 @@ ```bash -appwrite users list +appwrite users list \ + --limit 25 ``` diff --git a/docs/examples/vcs/list-installations.md b/docs/examples/vcs/list-installations.md index 9f342c86..b78449bf 100644 --- a/docs/examples/vcs/list-installations.md +++ b/docs/examples/vcs/list-installations.md @@ -1,3 +1,4 @@ ```bash -appwrite vcs list-installations +appwrite vcs list-installations \ + --limit 25 ``` diff --git a/docs/examples/vcs/list-repositories.md b/docs/examples/vcs/list-repositories.md index f0b67571..5b38fe39 100644 --- a/docs/examples/vcs/list-repositories.md +++ b/docs/examples/vcs/list-repositories.md @@ -1,5 +1,6 @@ ```bash appwrite vcs list-repositories \ --installation-id \ - --type runtime + --type runtime \ + --limit 25 ``` diff --git a/docs/examples/webhooks/list.md b/docs/examples/webhooks/list.md index 50e57740..bbf2f8ac 100644 --- a/docs/examples/webhooks/list.md +++ b/docs/examples/webhooks/list.md @@ -1,3 +1,4 @@ ```bash -appwrite webhooks list +appwrite webhooks list \ + --limit 25 ``` diff --git a/install.ps1 b/install.ps1 index a87d5f0b..655a629d 100644 --- a/install.ps1 +++ b/install.ps1 @@ -13,8 +13,8 @@ # You can use "View source" of this page to see the full script. # REPO -$GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/19.0.0/appwrite-cli-win-x64.exe" -$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/19.0.0/appwrite-cli-win-arm64.exe" +$GITHUB_x64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/19.1.0/appwrite-cli-win-x64.exe" +$GITHUB_arm64_URL = "https://github.com/appwrite/sdk-for-cli/releases/download/19.1.0/appwrite-cli-win-arm64.exe" $APPWRITE_BINARY_NAME = "appwrite.exe" diff --git a/install.sh b/install.sh index e24b6e37..bdd80e9a 100644 --- a/install.sh +++ b/install.sh @@ -115,7 +115,7 @@ verifyMacOSCodeSignature() { downloadBinary() { echo "[2/4] Downloading executable for $OS ($ARCH) ..." - GITHUB_LATEST_VERSION="19.0.0" + GITHUB_LATEST_VERSION="19.1.0" GITHUB_FILE="appwrite-cli-${OS}-${ARCH}" GITHUB_URL="https://github.com/$GITHUB_REPOSITORY_NAME/releases/download/$GITHUB_LATEST_VERSION/$GITHUB_FILE" diff --git a/lib/commands/services/account.ts b/lib/commands/services/account.ts index 3f601863..89c5bbb4 100644 --- a/lib/commands/services/account.ts +++ b/lib/commands/services/account.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForConsole } from "../../sdks.js"; import { actionRunner, @@ -79,17 +84,24 @@ This endpoint can also be used to convert an anonymous account to a normal one, const accountListIdentitiesCommand = account .command(`list-identities`) .description(`Get the list of identities for the currently logged in user.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, provider, providerUid, providerEmail, providerAccessTokenExpiry`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, provider, providerUid, providerEmail, providerAccessTokenExpiry`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, total }) => - parse(await (await getAccountClient()).listIdentities(queries, total)), + async ({ queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getAccountClient()).listIdentities(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); @@ -191,17 +203,19 @@ const accountDeleteKeyCommand = account const accountListLogsCommand = account .command(`list-logs`) .description(`Get the list of latest security activity logs for the currently logged in user. Each log returns user IP address, location and date and time of log.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ queries, total }) => - parse(await (await getAccountClient()).listLogs(queries, total)), + async ({ queries, total, limit, offset }) => + parse(await (await getAccountClient()).listLogs(buildQueries({ queries, limit, offset }), total)), ), ); diff --git a/lib/commands/services/backups.ts b/lib/commands/services/backups.ts index abec1835..e2f01bb5 100644 --- a/lib/commands/services/backups.ts +++ b/lib/commands/services/backups.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -29,11 +34,18 @@ export const backups = new Command("backups") const backupsListArchivesCommand = backups .command(`list-archives`) .description(`List all archives for a project.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries }) => - parse(await (await getBackupsClient()).listArchives(queries)), + async ({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getBackupsClient()).listArchives(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }))), ), ); @@ -78,11 +90,18 @@ const backupsDeleteArchiveCommand = backups const backupsListPoliciesCommand = backups .command(`list-policies`) .description(`List all policies for a project.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries }) => - parse(await (await getBackupsClient()).listPolicies(queries)), + async ({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getBackupsClient()).listPolicies(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }))), ), ); @@ -173,11 +192,18 @@ const backupsCreateRestorationCommand = backups const backupsListRestorationsCommand = backups .command(`list-restorations`) .description(`List all backup restorations for a project.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries }) => - parse(await (await getBackupsClient()).listRestorations(queries)), + async ({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getBackupsClient()).listRestorations(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }))), ), ); diff --git a/lib/commands/services/databases.ts b/lib/commands/services/databases.ts index d49df1cc..d6acdb4d 100644 --- a/lib/commands/services/databases.ts +++ b/lib/commands/services/databases.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -29,7 +34,7 @@ export const databases = new Command("databases") const databasesListCommand = databases .command(`list`) .description(`Get a list of all databases from the current Appwrite project. You can use the search parameter to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -37,10 +42,17 @@ const databasesListCommand = databases (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getDatabasesClient()).list(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getDatabasesClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -68,11 +80,18 @@ const databasesCreateCommand = databases const databasesListTransactionsCommand = databases .command(`list-transactions`) .description(`List transactions across all databases.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries).`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries).`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries }) => - parse(await (await getDatabasesClient()).listTransactions(queries)), + async ({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getDatabasesClient()).listTransactions(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }))), ), ); @@ -209,7 +228,7 @@ const databasesListCollectionsCommand = databases .command(`list-collections`) .description(`Get a list of all collections that belong to the provided databaseId. You can use the search parameter to filter your results.`) .requiredOption(`--database-id `, `Database ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, documentSecurity`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, documentSecurity`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -217,10 +236,17 @@ const databasesListCollectionsCommand = databases (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, queries, search, total }) => - parse(await (await getDatabasesClient()).listCollections(databaseId, queries, search, total)), + async ({ databaseId, queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getDatabasesClient()).listCollections(databaseId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -318,17 +344,24 @@ const databasesListAttributesCommand = databases .description(`List attributes in the collection.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--collection-id `, `Collection ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, type, size, required, array, status, error`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, type, size, required, array, status, error`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, collectionId, queries, total }) => - parse(await (await getDatabasesClient()).listAttributes(databaseId, collectionId, queries, total)), + async ({ databaseId, collectionId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getDatabasesClient()).listAttributes(databaseId, collectionId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); @@ -1086,7 +1119,7 @@ const databasesListDocumentsCommand = databases .description(`Get a list of all the user's documents in a given collection. You can use the query params to filter your results.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--collection-id `, `Collection ID. You can create a new collection using the Database service server integration (https://appwrite.io/docs/server/databases#databasesCreateCollection).`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, pagination, and selection prefer --where, --sort-asc, --sort-desc, --limit, --offset, and --select. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) .option(`--transaction-id `, `Transaction ID to read uncommitted changes within the transaction.`) .option( `--total [value]`, @@ -1095,10 +1128,18 @@ const databasesListDocumentsCommand = databases value === undefined ? true : parseBool(value), ) .option(`--ttl `, `TTL (seconds) for caching list responses. Responses are stored in an in-memory key-value cache, keyed per project, collection, schema version (attributes and indexes), caller authorization roles, and the exact query — so users with different permissions never share cached entries. Schema changes invalidate cached entries automatically; document writes do not, so choose a TTL you are comfortable serving as stale data. Set to 0 to disable caching. Must be between 0 and 86400 (24 hours).`, parseInteger) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) + .option(`--select `, `Attribute to include in the response. Repeat for multiple attributes.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) .action( actionRunner( - async ({ databaseId, collectionId, queries, transactionId, total, ttl }) => - parse(await (await getDatabasesClient()).listDocuments(databaseId, collectionId, queries, transactionId, total, ttl)), + async ({ databaseId, collectionId, queries, transactionId, total, ttl, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset, select }) => + parse(await (await getDatabasesClient()).listDocuments(databaseId, collectionId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset, select }), transactionId, total, ttl)), ), ); @@ -1157,12 +1198,19 @@ const databasesUpdateDocumentsCommand = databases .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--collection-id `, `Collection ID.`) .option(`--data `, `Document data as JSON object. Include only attribute and value pairs to be updated.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) .option(`--transaction-id `, `Transaction ID for staging the operation.`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, collectionId, data, queries, transactionId }) => - parse(await (await getDatabasesClient()).updateDocuments(databaseId, collectionId, JSON.parse(data), queries, transactionId)), + async ({ databaseId, collectionId, data, queries, transactionId, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getDatabasesClient()).updateDocuments(databaseId, collectionId, JSON.parse(data), buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), transactionId)), ), ); @@ -1172,12 +1220,19 @@ const databasesDeleteDocumentsCommand = databases .description(`Bulk delete documents using queries, if no queries are passed then all documents are deleted.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--collection-id `, `Collection ID. You can create a new collection using the Database service server integration (https://appwrite.io/docs/server/databases#databasesCreateCollection).`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) .option(`--transaction-id `, `Transaction ID for staging the operation.`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, collectionId, queries, transactionId }) => - parse(await (await getDatabasesClient()).deleteDocuments(databaseId, collectionId, queries, transactionId)), + async ({ databaseId, collectionId, queries, transactionId, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getDatabasesClient()).deleteDocuments(databaseId, collectionId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), transactionId)), ), ); @@ -1188,12 +1243,13 @@ const databasesGetDocumentCommand = databases .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--collection-id `, `Collection ID. You can create a new collection using the Database service server integration (https://appwrite.io/docs/server/databases#databasesCreateCollection).`) .requiredOption(`--document-id `, `Document ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for selecting returned attributes prefer --select. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) .option(`--transaction-id `, `Transaction ID to read uncommitted changes within the transaction.`) + .option(`--select `, `Attribute to include in the response. Repeat for multiple attributes.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) .action( actionRunner( - async ({ databaseId, collectionId, documentId, queries, transactionId }) => - parse(await (await getDatabasesClient()).getDocument(databaseId, collectionId, documentId, queries, transactionId)), + async ({ databaseId, collectionId, documentId, queries, transactionId, select }) => + parse(await (await getDatabasesClient()).getDocument(databaseId, collectionId, documentId, buildQueries({ queries, select }), transactionId)), ), ); @@ -1253,11 +1309,13 @@ const databasesListDocumentLogsCommand = databases .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--collection-id `, `Collection ID.`) .requiredOption(`--document-id `, `Document ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ databaseId, collectionId, documentId, queries }) => - parse(await (await getDatabasesClient()).listDocumentLogs(databaseId, collectionId, documentId, queries)), + async ({ databaseId, collectionId, documentId, queries, limit, offset }) => + parse(await (await getDatabasesClient()).listDocumentLogs(databaseId, collectionId, documentId, buildQueries({ queries, limit, offset }))), ), ); @@ -1303,17 +1361,24 @@ const databasesListIndexesCommand = databases .description(`List indexes in the collection.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--collection-id `, `Collection ID. You can create a new collection using the Database service server integration (https://appwrite.io/docs/server/databases#databasesCreateCollection).`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, type, status, attributes, error`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, type, status, attributes, error`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, collectionId, queries, total }) => - parse(await (await getDatabasesClient()).listIndexes(databaseId, collectionId, queries, total)), + async ({ databaseId, collectionId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getDatabasesClient()).listIndexes(databaseId, collectionId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); @@ -1370,11 +1435,13 @@ const databasesListCollectionLogsCommand = databases .description(`Get the collection activity logs list by its unique ID.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--collection-id `, `Collection ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ databaseId, collectionId, queries }) => - parse(await (await getDatabasesClient()).listCollectionLogs(databaseId, collectionId, queries)), + async ({ databaseId, collectionId, queries, limit, offset }) => + parse(await (await getDatabasesClient()).listCollectionLogs(databaseId, collectionId, buildQueries({ queries, limit, offset }))), ), ); @@ -1397,11 +1464,13 @@ const databasesListLogsCommand = databases .command(`list-logs`) .description(`Get the database activity logs list by its unique ID.`) .requiredOption(`--database-id `, `Database ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ databaseId, queries }) => - parse(await (await getDatabasesClient()).listLogs(databaseId, queries)), + async ({ databaseId, queries, limit, offset }) => + parse(await (await getDatabasesClient()).listLogs(databaseId, buildQueries({ queries, limit, offset }))), ), ); diff --git a/lib/commands/services/functions.ts b/lib/commands/services/functions.ts index 00f8595a..73e68e2f 100644 --- a/lib/commands/services/functions.ts +++ b/lib/commands/services/functions.ts @@ -1,6 +1,11 @@ import { Command } from "commander"; import fs from "fs"; import { resolveFileParam } from "../utils/deployment.js"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -31,7 +36,7 @@ export const functions = new Command("functions") const functionsListCommand = functions .command(`list`) .description(`Get a list of all the project's functions. You can use the query params to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, runtime, deploymentId, schedule, scheduleNext, schedulePrevious, timeout, entrypoint, commands, installationId`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, runtime, deploymentId, schedule, scheduleNext, schedulePrevious, timeout, entrypoint, commands, installationId`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -39,10 +44,17 @@ const functionsListCommand = functions (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getFunctionsClient()).list(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getFunctionsClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -245,7 +257,7 @@ const functionsListDeploymentsCommand = functions .command(`list-deployments`) .description(`Get a list of all the function's code deployments. You can use the query params to filter your results.`) .requiredOption(`--function-id `, `Function ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -253,10 +265,17 @@ const functionsListDeploymentsCommand = functions (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ functionId, queries, search, total }) => - parse(await (await getFunctionsClient()).listDeployments(functionId, queries, search, total)), + async ({ functionId, queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getFunctionsClient()).listDeployments(functionId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -405,17 +424,24 @@ const functionsListExecutionsCommand = functions .command(`list-executions`) .description(`Get a list of all the current user function execution logs. You can use the query params to filter your results.`) .requiredOption(`--function-id `, `Function ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: trigger, status, responseStatusCode, duration, requestMethod, requestPath, deploymentId`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: trigger, status, responseStatusCode, duration, requestMethod, requestPath, deploymentId`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ functionId, queries, total }) => - parse(await (await getFunctionsClient()).listExecutions(functionId, queries, total)), + async ({ functionId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getFunctionsClient()).listExecutions(functionId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); diff --git a/lib/commands/services/messaging.ts b/lib/commands/services/messaging.ts index 71a47973..f69721a8 100644 --- a/lib/commands/services/messaging.ts +++ b/lib/commands/services/messaging.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -29,7 +34,7 @@ export const messaging = new Command("messaging") const messagingListMessagesCommand = messaging .command(`list-messages`) .description(`Get a list of all messages from the current Appwrite project.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: scheduledAt, deliveredAt, deliveredTotal, status, description, providerType`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: scheduledAt, deliveredAt, deliveredTotal, status, description, providerType`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -37,10 +42,17 @@ const messagingListMessagesCommand = messaging (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getMessagingClient()).listMessages(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getMessagingClient()).listMessages(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -279,17 +291,19 @@ const messagingListMessageLogsCommand = messaging .command(`list-message-logs`) .description(`Get the message activity logs listed by its unique ID.`) .requiredOption(`--message-id `, `Message ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ messageId, queries, total }) => - parse(await (await getMessagingClient()).listMessageLogs(messageId, queries, total)), + async ({ messageId, queries, total, limit, offset }) => + parse(await (await getMessagingClient()).listMessageLogs(messageId, buildQueries({ queries, limit, offset }), total)), ), ); @@ -298,17 +312,24 @@ const messagingListTargetsCommand = messaging .command(`list-targets`) .description(`Get a list of the targets associated with a message.`) .requiredOption(`--message-id `, `Message ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, providerId, identifier, providerType`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, providerId, identifier, providerType`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ messageId, queries, total }) => - parse(await (await getMessagingClient()).listTargets(messageId, queries, total)), + async ({ messageId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getMessagingClient()).listTargets(messageId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); @@ -316,7 +337,7 @@ const messagingListTargetsCommand = messaging const messagingListProvidersCommand = messaging .command(`list-providers`) .description(`Get a list of all providers from the current Appwrite project.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, provider, type, enabled`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, provider, type, enabled`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -324,10 +345,17 @@ const messagingListProvidersCommand = messaging (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getMessagingClient()).listProviders(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getMessagingClient()).listProviders(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -907,17 +935,19 @@ const messagingListProviderLogsCommand = messaging .command(`list-provider-logs`) .description(`Get the provider activity logs listed by its unique ID.`) .requiredOption(`--provider-id `, `Provider ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ providerId, queries, total }) => - parse(await (await getMessagingClient()).listProviderLogs(providerId, queries, total)), + async ({ providerId, queries, total, limit, offset }) => + parse(await (await getMessagingClient()).listProviderLogs(providerId, buildQueries({ queries, limit, offset }), total)), ), ); @@ -926,17 +956,19 @@ const messagingListSubscriberLogsCommand = messaging .command(`list-subscriber-logs`) .description(`Get the subscriber activity logs listed by its unique ID.`) .requiredOption(`--subscriber-id `, `Subscriber ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ subscriberId, queries, total }) => - parse(await (await getMessagingClient()).listSubscriberLogs(subscriberId, queries, total)), + async ({ subscriberId, queries, total, limit, offset }) => + parse(await (await getMessagingClient()).listSubscriberLogs(subscriberId, buildQueries({ queries, limit, offset }), total)), ), ); @@ -944,7 +976,7 @@ const messagingListSubscriberLogsCommand = messaging const messagingListTopicsCommand = messaging .command(`list-topics`) .description(`Get a list of all topics from the current Appwrite project.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, description, emailTotal, smsTotal, pushTotal`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, description, emailTotal, smsTotal, pushTotal`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -952,10 +984,17 @@ const messagingListTopicsCommand = messaging (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getMessagingClient()).listTopics(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getMessagingClient()).listTopics(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -1018,17 +1057,19 @@ const messagingListTopicLogsCommand = messaging .command(`list-topic-logs`) .description(`Get the topic activity logs listed by its unique ID.`) .requiredOption(`--topic-id `, `Topic ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ topicId, queries, total }) => - parse(await (await getMessagingClient()).listTopicLogs(topicId, queries, total)), + async ({ topicId, queries, total, limit, offset }) => + parse(await (await getMessagingClient()).listTopicLogs(topicId, buildQueries({ queries, limit, offset }), total)), ), ); @@ -1037,7 +1078,7 @@ const messagingListSubscribersCommand = messaging .command(`list-subscribers`) .description(`Get a list of all subscribers from the current Appwrite project.`) .requiredOption(`--topic-id `, `Topic ID. The topic ID subscribed to.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: targetId, topicId, userId, providerType`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: targetId, topicId, userId, providerType`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -1045,10 +1086,17 @@ const messagingListSubscribersCommand = messaging (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ topicId, queries, search, total }) => - parse(await (await getMessagingClient()).listSubscribers(topicId, queries, search, total)), + async ({ topicId, queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getMessagingClient()).listSubscribers(topicId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); diff --git a/lib/commands/services/migrations.ts b/lib/commands/services/migrations.ts index bad5715a..9b7c2bd7 100644 --- a/lib/commands/services/migrations.ts +++ b/lib/commands/services/migrations.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -29,7 +34,7 @@ export const migrations = new Command("migrations") const migrationsListCommand = migrations .command(`list`) .description(`List all migrations in the current project. This endpoint returns a list of all migrations including their status, progress, and any errors that occurred during the migration process.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, destination, resources, resourceId, resourceType, statusCounters, resourceData, errors`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: status, stage, source, destination, resources, resourceId, resourceType, statusCounters, resourceData, errors`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -37,10 +42,17 @@ const migrationsListCommand = migrations (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getMigrationsClient()).list(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getMigrationsClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -81,7 +93,7 @@ const migrationsCreateCSVExportCommand = migrations .requiredOption(`--resource-id `, `Composite ID in the format {databaseId:collectionId}, identifying a collection within a database to export.`) .requiredOption(`--filename `, `The name of the file to be created for the export, excluding the .csv extension.`) .option(`--columns [columns...]`, `List of attributes to export. If empty, all attributes will be exported. You can use the \`*\` wildcard to export all attributes from the collection.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK to filter documents to export. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK to filter documents to export. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long.`) .option(`--delimiter `, `The character that separates each column value. Default is comma.`) .option(`--enclosure `, `The character that encloses each column value. Default is double quotes.`) .option(`--escape `, `The escape character for the enclosure character. Default is double quotes.`) @@ -97,10 +109,17 @@ const migrationsCreateCSVExportCommand = migrations (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ resourceId, filename, columns, queries, delimiter, enclosure, escape, header, notify }) => - parse(await (await getMigrationsClient()).createCSVExport(resourceId, filename, columns, queries, delimiter, enclosure, escape, header, notify)), + async ({ resourceId, filename, columns, queries, delimiter, enclosure, escape, header, notify, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getMigrationsClient()).createCSVExport(resourceId, filename, columns, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), delimiter, enclosure, escape, header, notify)), ), ); @@ -158,17 +177,24 @@ const migrationsCreateJSONExportCommand = migrations .requiredOption(`--resource-id `, `Composite ID in the format {databaseId:collectionId}, identifying a collection within a database to export.`) .requiredOption(`--filename `, `The name of the file to be created for the export, excluding the .json extension.`) .option(`--columns [columns...]`, `List of attributes to export. If empty, all attributes will be exported. You can use the \`*\` wildcard to export all attributes from the collection.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK to filter documents to export. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK to filter documents to export. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long.`) .option( `--notify [value]`, `Set to true to receive an email when the export is complete. Default is true.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ resourceId, filename, columns, queries, notify }) => - parse(await (await getMigrationsClient()).createJSONExport(resourceId, filename, columns, queries, notify)), + async ({ resourceId, filename, columns, queries, notify, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getMigrationsClient()).createJSONExport(resourceId, filename, columns, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), notify)), ), ); diff --git a/lib/commands/services/organizations.ts b/lib/commands/services/organizations.ts index cd12ccec..94c47600 100644 --- a/lib/commands/services/organizations.ts +++ b/lib/commands/services/organizations.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForConsole } from "../../sdks.js"; import { actionRunner, @@ -29,12 +34,19 @@ export const organizations = new Command("organizations") const organizationsListCommand = organizations .command(`list`) .description(`Get a list of all the teams in which the current user is a member. You can use the parameters to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, total, billingPlan, paymentMethodId, backupPaymentMethodId, platform`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, total, billingPlan, paymentMethodId, backupPaymentMethodId, platform`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search }) => - parse(await (await getOrganizationsClient()).list(queries, search)), + async ({ queries, search, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getOrganizationsClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search)), ), ); @@ -175,11 +187,18 @@ const organizationsListAggregationsCommand = organizations .command(`list-aggregations`) .description(`Get a list of all aggregations for an organization.`) .requiredOption(`--organization-id `, `Organization ID`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: teamId, aggregationId, from, to`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: teamId, aggregationId, from, to`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ organizationId, queries }) => - parse(await (await getOrganizationsClient()).listAggregations(organizationId, queries)), + async ({ organizationId, queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getOrganizationsClient()).listAggregations(organizationId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }))), ), ); @@ -244,11 +263,18 @@ const organizationsListCreditsCommand = organizations .description(`List all credits for an organization. `) .requiredOption(`--organization-id `, `Organization ID`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: teamId, couponId, credits, expiration, status`) - .action( - actionRunner( - async ({ organizationId, queries }) => - parse(await (await getOrganizationsClient()).listCredits(organizationId, queries)), + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: teamId, couponId, credits, expiration, status`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) + .action( + actionRunner( + async ({ organizationId, queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getOrganizationsClient()).listCredits(organizationId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }))), ), ); diff --git a/lib/commands/services/project.ts b/lib/commands/services/project.ts index 3a9d8c0c..128e7ba6 100644 --- a/lib/commands/services/project.ts +++ b/lib/commands/services/project.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -65,17 +70,24 @@ const projectUpdateFreeEmailsCommand = project const projectListKeysCommand = project .command(`list-keys`) .description(`Get a list of all API keys from the current project.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: expire, accessedAt, name, scopes`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: expire, accessedAt, name, scopes`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, total }) => - parse(await (await getProjectClient()).listKeys(queries, total)), + async ({ queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getProjectClient()).listKeys(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); @@ -149,17 +161,24 @@ const projectUpdateLabelsCommand = project const projectListPlatformsCommand = project .command(`list-platforms`) .description(`Get a list of all platforms in the project. This endpoint returns an array of all platforms and their configurations.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: type, name, hostname, bundleIdentifier, applicationId, packageIdentifierName, packageName`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: type, name, hostname, bundleIdentifier, applicationId, packageIdentifierName, packageName`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, total }) => - parse(await (await getProjectClient()).listPlatforms(queries, total)), + async ({ queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getProjectClient()).listPlatforms(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); @@ -580,17 +599,24 @@ const projectGetUsageCommand = project const projectListVariablesCommand = project .command(`list-variables`) .description(`Get a list of all project environment variables.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, resourceType, resourceId, secret`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: key, resourceType, resourceId, secret`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, total }) => - parse(await (await getProjectClient()).listVariables(queries, total)), + async ({ queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getProjectClient()).listVariables(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); diff --git a/lib/commands/services/projects.ts b/lib/commands/services/projects.ts index a239656f..0bf931e9 100644 --- a/lib/commands/services/projects.ts +++ b/lib/commands/services/projects.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForConsole } from "../../sdks.js"; import { actionRunner, @@ -29,7 +34,7 @@ export const projects = new Command("projects") const projectsListCommand = projects .command(`list`) .description(`Get a list of all projects. You can use the query params to filter your results. `) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, teamId, labels, search`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, teamId, labels, search`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -37,10 +42,17 @@ const projectsListCommand = projects (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getProjectsClient()).list(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getProjectsClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -147,11 +159,18 @@ const projectsListDevKeysCommand = projects .command(`list-dev-keys`) .description(`List all the project\'s dev keys. Dev keys are project specific and allow you to bypass rate limits and get better error logging during development.'`) .requiredOption(`--project-id `, `Project unique ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: accessedAt, expire`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: accessedAt, expire`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ projectId, queries }) => - parse(await (await getProjectsClient()).listDevKeys(projectId, queries)), + async ({ projectId, queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getProjectsClient()).listDevKeys(projectId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }))), ), ); @@ -250,17 +269,24 @@ const projectsListSchedulesCommand = projects .command(`list-schedules`) .description(`Get a list of all the project's schedules. You can use the query params to filter your results.`) .requiredOption(`--project-id `, `Project unique ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: resourceType, resourceId, projectId, schedule, active, region`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: resourceType, resourceId, projectId, schedule, active, region`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ projectId, queries, total }) => - parse(await (await getProjectsClient()).listSchedules(projectId, queries, total)), + async ({ projectId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getProjectsClient()).listSchedules(projectId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); diff --git a/lib/commands/services/proxy.ts b/lib/commands/services/proxy.ts index 919e6952..dc9542bb 100644 --- a/lib/commands/services/proxy.ts +++ b/lib/commands/services/proxy.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -29,7 +34,7 @@ export const proxy = new Command("proxy") const proxyListRulesCommand = proxy .command(`list-rules`) .description(`Get a list of all the proxy rules. You can use the query params to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: domain, type, trigger, deploymentResourceType, deploymentResourceId, deploymentId, deploymentVcsProviderBranch`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/databases#querying-documents). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: domain, type, trigger, deploymentResourceType, deploymentResourceId, deploymentId, deploymentVcsProviderBranch`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -37,10 +42,17 @@ const proxyListRulesCommand = proxy (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getProxyClient()).listRules(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getProxyClient()).listRules(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); diff --git a/lib/commands/services/sites.ts b/lib/commands/services/sites.ts index 563e64bb..68bb68b8 100644 --- a/lib/commands/services/sites.ts +++ b/lib/commands/services/sites.ts @@ -1,6 +1,11 @@ import { Command } from "commander"; import fs from "fs"; import { resolveFileParam } from "../utils/deployment.js"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -31,7 +36,7 @@ export const sites = new Command("sites") const sitesListCommand = sites .command(`list`) .description(`Get a list of all the project's sites. You can use the query params to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, framework, deploymentId, buildCommand, installCommand, outputDirectory, installationId`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, enabled, framework, deploymentId, buildCommand, installCommand, outputDirectory, installationId`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -39,10 +44,17 @@ const sitesListCommand = sites (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getSitesClient()).list(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getSitesClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -241,7 +253,7 @@ const sitesListDeploymentsCommand = sites .command(`list-deployments`) .description(`Get a list of all the site's code deployments. You can use the query params to filter your results.`) .requiredOption(`--site-id `, `Site ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: buildSize, sourceSize, totalSize, buildDuration, status, activate, type`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -249,10 +261,17 @@ const sitesListDeploymentsCommand = sites (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ siteId, queries, search, total }) => - parse(await (await getSitesClient()).listDeployments(siteId, queries, search, total)), + async ({ siteId, queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getSitesClient()).listDeployments(siteId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -402,17 +421,24 @@ const sitesListLogsCommand = sites .command(`list-logs`) .description(`Get a list of all site logs. You can use the query params to filter your results.`) .requiredOption(`--site-id `, `Site ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: trigger, status, responseStatusCode, duration, requestMethod, requestPath, deploymentId`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: trigger, status, responseStatusCode, duration, requestMethod, requestPath, deploymentId`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ siteId, queries, total }) => - parse(await (await getSitesClient()).listLogs(siteId, queries, total)), + async ({ siteId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getSitesClient()).listLogs(siteId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); diff --git a/lib/commands/services/storage.ts b/lib/commands/services/storage.ts index e48df45d..73c9fc6f 100644 --- a/lib/commands/services/storage.ts +++ b/lib/commands/services/storage.ts @@ -1,6 +1,11 @@ import { Command } from "commander"; import fs from "fs"; import { resolveFileParam } from "../utils/deployment.js"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -31,7 +36,7 @@ export const storage = new Command("storage") const storageListBucketsCommand = storage .command(`list-buckets`) .description(`Get a list of all the storage buckets. You can use the query params to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: enabled, name, fileSecurity, maximumFileSize, encryption, antivirus, transformations`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: enabled, name, fileSecurity, maximumFileSize, encryption, antivirus, transformations`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -39,10 +44,17 @@ const storageListBucketsCommand = storage (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getStorageClient()).listBuckets(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getStorageClient()).listBuckets(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -169,7 +181,7 @@ const storageListFilesCommand = storage .command(`list-files`) .description(`Get a list of all the user files. You can use the query params to filter your results.`) .requiredOption(`--bucket-id `, `Storage bucket unique ID. You can create a new storage bucket using the Storage service server integration (https://appwrite.io/docs/server/storage#createBucket).`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, signature, mimeType, sizeOriginal, chunksTotal, chunksUploaded`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, signature, mimeType, sizeOriginal, chunksTotal, chunksUploaded`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -177,10 +189,17 @@ const storageListFilesCommand = storage (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ bucketId, queries, search, total }) => - parse(await (await getStorageClient()).listFiles(bucketId, queries, search, total)), + async ({ bucketId, queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getStorageClient()).listFiles(bucketId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); diff --git a/lib/commands/services/tables-db.ts b/lib/commands/services/tables-db.ts index 1fade326..13ce8a94 100644 --- a/lib/commands/services/tables-db.ts +++ b/lib/commands/services/tables-db.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -29,7 +34,7 @@ export const tablesDB = new Command("tables-db") const tablesDBListCommand = tablesDB .command(`list`) .description(`Get a list of all databases from the current Appwrite project. You can use the search parameter to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: name`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: name`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -37,10 +42,17 @@ const tablesDBListCommand = tablesDB (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getTablesDBClient()).list(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTablesDBClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -68,11 +80,18 @@ const tablesDBCreateCommand = tablesDB const tablesDBListTransactionsCommand = tablesDB .command(`list-transactions`) .description(`List transactions across all databases.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries).`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries).`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries }) => - parse(await (await getTablesDBClient()).listTransactions(queries)), + async ({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTablesDBClient()).listTransactions(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }))), ), ); @@ -209,7 +228,7 @@ const tablesDBListTablesCommand = tablesDB .command(`list-tables`) .description(`Get a list of all tables that belong to the provided databaseId. You can use the search parameter to filter your results.`) .requiredOption(`--database-id `, `Database ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: name, enabled, rowSecurity`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: name, enabled, rowSecurity`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -217,10 +236,17 @@ const tablesDBListTablesCommand = tablesDB (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, queries, search, total }) => - parse(await (await getTablesDBClient()).listTables(databaseId, queries, search, total)), + async ({ databaseId, queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTablesDBClient()).listTables(databaseId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -318,17 +344,24 @@ const tablesDBListColumnsCommand = tablesDB .description(`List columns in the table.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--table-id `, `Table ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: key, type, size, required, array, status, error`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: key, type, size, required, array, status, error`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, tableId, queries, total }) => - parse(await (await getTablesDBClient()).listColumns(databaseId, tableId, queries, total)), + async ({ databaseId, tableId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTablesDBClient()).listColumns(databaseId, tableId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); @@ -1085,17 +1118,24 @@ const tablesDBListIndexesCommand = tablesDB .description(`List indexes on the table.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--table-id `, `Table ID. You can create a new table using the Database service server integration (https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable).`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: key, type, status, attributes, error`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following columns: key, type, status, attributes, error`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, tableId, queries, total }) => - parse(await (await getTablesDBClient()).listIndexes(databaseId, tableId, queries, total)), + async ({ databaseId, tableId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTablesDBClient()).listIndexes(databaseId, tableId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); @@ -1152,11 +1192,13 @@ const tablesDBListTableLogsCommand = tablesDB .description(`Get the table activity logs list by its unique ID.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--table-id `, `Table ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ databaseId, tableId, queries }) => - parse(await (await getTablesDBClient()).listTableLogs(databaseId, tableId, queries)), + async ({ databaseId, tableId, queries, limit, offset }) => + parse(await (await getTablesDBClient()).listTableLogs(databaseId, tableId, buildQueries({ queries, limit, offset }))), ), ); @@ -1166,7 +1208,7 @@ const tablesDBListRowsCommand = tablesDB .description(`Get a list of all the user's rows in a given table. You can use the query params to filter your results.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--table-id `, `Table ID. You can create a new table using the TablesDB service server integration (https://appwrite.io/docs/products/databases/tables#create-table).`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, pagination, and selection prefer --where, --sort-asc, --sort-desc, --limit, --offset, and --select. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) .option(`--transaction-id `, `Transaction ID to read uncommitted changes within the transaction.`) .option( `--total [value]`, @@ -1175,10 +1217,18 @@ const tablesDBListRowsCommand = tablesDB value === undefined ? true : parseBool(value), ) .option(`--ttl `, `TTL (seconds) for caching list responses. Responses are stored in an in-memory key-value cache, keyed per project, table, schema version (columns and indexes), caller authorization roles, and the exact query — so users with different permissions never share cached entries. Schema changes invalidate cached entries automatically; row writes do not, so choose a TTL you are comfortable serving as stale data. Set to 0 to disable caching. Must be between 0 and 86400 (24 hours).`, parseInteger) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) + .option(`--select `, `Attribute to include in the response. Repeat for multiple attributes.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) .action( actionRunner( - async ({ databaseId, tableId, queries, transactionId, total, ttl }) => - parse(await (await getTablesDBClient()).listRows(databaseId, tableId, queries, transactionId, total, ttl)), + async ({ databaseId, tableId, queries, transactionId, total, ttl, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset, select }) => + parse(await (await getTablesDBClient()).listRows(databaseId, tableId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset, select }), transactionId, total, ttl)), ), ); @@ -1237,12 +1287,19 @@ const tablesDBUpdateRowsCommand = tablesDB .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--table-id `, `Table ID.`) .option(`--data `, `Row data as JSON object. Include only column and value pairs to be updated.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) .option(`--transaction-id `, `Transaction ID for staging the operation.`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, tableId, data, queries, transactionId }) => - parse(await (await getTablesDBClient()).updateRows(databaseId, tableId, JSON.parse(data), queries, transactionId)), + async ({ databaseId, tableId, data, queries, transactionId, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTablesDBClient()).updateRows(databaseId, tableId, JSON.parse(data), buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), transactionId)), ), ); @@ -1252,12 +1309,19 @@ const tablesDBDeleteRowsCommand = tablesDB .description(`Bulk delete rows using queries, if no queries are passed then all rows are deleted.`) .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--table-id `, `Table ID. You can create a new table using the Database service server integration (https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable).`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) .option(`--transaction-id `, `Transaction ID for staging the operation.`) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ databaseId, tableId, queries, transactionId }) => - parse(await (await getTablesDBClient()).deleteRows(databaseId, tableId, queries, transactionId)), + async ({ databaseId, tableId, queries, transactionId, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTablesDBClient()).deleteRows(databaseId, tableId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), transactionId)), ), ); @@ -1268,12 +1332,13 @@ const tablesDBGetRowCommand = tablesDB .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--table-id `, `Table ID. You can create a new table using the Database service server integration (https://appwrite.io/docs/references/cloud/server-dart/tablesDB#createTable).`) .requiredOption(`--row-id `, `Row ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for selecting returned attributes prefer --select. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long.`) .option(`--transaction-id `, `Transaction ID to read uncommitted changes within the transaction.`) + .option(`--select `, `Attribute to include in the response. Repeat for multiple attributes.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) .action( actionRunner( - async ({ databaseId, tableId, rowId, queries, transactionId }) => - parse(await (await getTablesDBClient()).getRow(databaseId, tableId, rowId, queries, transactionId)), + async ({ databaseId, tableId, rowId, queries, transactionId, select }) => + parse(await (await getTablesDBClient()).getRow(databaseId, tableId, rowId, buildQueries({ queries, select }), transactionId)), ), ); @@ -1333,11 +1398,13 @@ const tablesDBListRowLogsCommand = tablesDB .requiredOption(`--database-id `, `Database ID.`) .requiredOption(`--table-id `, `Table ID.`) .requiredOption(`--row-id `, `Row ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ databaseId, tableId, rowId, queries }) => - parse(await (await getTablesDBClient()).listRowLogs(databaseId, tableId, rowId, queries)), + async ({ databaseId, tableId, rowId, queries, limit, offset }) => + parse(await (await getTablesDBClient()).listRowLogs(databaseId, tableId, rowId, buildQueries({ queries, limit, offset }))), ), ); diff --git a/lib/commands/services/teams.ts b/lib/commands/services/teams.ts index ed6e2642..dd2bad14 100644 --- a/lib/commands/services/teams.ts +++ b/lib/commands/services/teams.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -38,7 +43,7 @@ export const teams = new Command("teams") const teamsListCommand = teams .command(`list`) .description(`Get a list of all the teams in which the current user is a member. You can use the parameters to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, total, billingPlan`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, total, billingPlan`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -46,10 +51,17 @@ const teamsListCommand = teams (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getTeamsClient()).list(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTeamsClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -109,17 +121,19 @@ const teamsListLogsCommand = teams .command(`list-logs`) .description(`Get the team activity logs list by its unique ID.`) .requiredOption(`--team-id `, `Team ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ teamId, queries, total }) => - parse(await (await getTeamsClient()).listLogs(teamId, queries, total)), + async ({ teamId, queries, total, limit, offset }) => + parse(await (await getTeamsClient()).listLogs(teamId, buildQueries({ queries, limit, offset }), total)), ), ); @@ -128,7 +142,7 @@ const teamsListMembershipsCommand = teams .command(`list-memberships`) .description(`Use this endpoint to list a team's members using the team's ID. All team members have read access to this endpoint. Hide sensitive attributes from the response by toggling membership privacy in the Console.`) .requiredOption(`--team-id `, `Team ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, teamId, invited, joined, confirm, roles`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, teamId, invited, joined, confirm, roles`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -136,10 +150,17 @@ const teamsListMembershipsCommand = teams (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ teamId, queries, search, total }) => - parse(await (await getTeamsClient()).listMemberships(teamId, queries, search, total)), + async ({ teamId, queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTeamsClient()).listMemberships(teamId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); diff --git a/lib/commands/services/tokens.ts b/lib/commands/services/tokens.ts index 85dbb31e..af1d99c7 100644 --- a/lib/commands/services/tokens.ts +++ b/lib/commands/services/tokens.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -31,17 +36,24 @@ const tokensListCommand = tokens .description(`List all the tokens created for a specific file or bucket. You can use the query params to filter your results.`) .requiredOption(`--bucket-id `, `Storage bucket unique ID. You can create a new storage bucket using the Storage service server integration (https://appwrite.io/docs/server/storage#createBucket).`) .requiredOption(`--file-id `, `File unique ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: expire`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: expire`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ bucketId, fileId, queries, total }) => - parse(await (await getTokensClient()).list(bucketId, fileId, queries, total)), + async ({ bucketId, fileId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getTokensClient()).list(bucketId, fileId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); diff --git a/lib/commands/services/users.ts b/lib/commands/services/users.ts index 281deab5..6412fd1d 100644 --- a/lib/commands/services/users.ts +++ b/lib/commands/services/users.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -29,7 +34,7 @@ export const users = new Command("users") const usersListCommand = users .command(`list`) .description(`Get a list of all the project's users. You can use the query params to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, email, phone, status, passwordUpdate, registration, emailVerification, phoneVerification, labels, impersonator`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, email, phone, status, passwordUpdate, registration, emailVerification, phoneVerification, labels, impersonator`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -37,10 +42,17 @@ const usersListCommand = users (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getUsersClient()).list(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getUsersClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -94,7 +106,7 @@ const usersCreateBcryptUserCommand = users const usersListIdentitiesCommand = users .command(`list-identities`) .description(`Get identities for all users.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, provider, providerUid, providerEmail, providerAccessTokenExpiry`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, provider, providerUid, providerEmail, providerAccessTokenExpiry`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -102,10 +114,17 @@ const usersListIdentitiesCommand = users (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getUsersClient()).listIdentities(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getUsersClient()).listIdentities(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -303,17 +322,19 @@ const usersListLogsCommand = users .command(`list-logs`) .description(`Get the user activity logs list by its unique ID.`) .requiredOption(`--user-id `, `User ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ userId, queries, total }) => - parse(await (await getUsersClient()).listLogs(userId, queries, total)), + async ({ userId, queries, total, limit, offset }) => + parse(await (await getUsersClient()).listLogs(userId, buildQueries({ queries, limit, offset }), total)), ), ); @@ -322,7 +343,7 @@ const usersListMembershipsCommand = users .command(`list-memberships`) .description(`Get the user membership list by its unique ID.`) .requiredOption(`--user-id `, `User ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, teamId, invited, joined, confirm, roles`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, teamId, invited, joined, confirm, roles`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -330,10 +351,17 @@ const usersListMembershipsCommand = users (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ userId, queries, search, total }) => - parse(await (await getUsersClient()).listMemberships(userId, queries, search, total)), + async ({ userId, queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getUsersClient()).listMemberships(userId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); @@ -550,17 +578,24 @@ const usersListTargetsCommand = users .command(`list-targets`) .description(`List the messaging targets that are associated with a user.`) .requiredOption(`--user-id `, `User ID.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, providerId, identifier, providerType`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: userId, providerId, identifier, providerType`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ userId, queries, total }) => - parse(await (await getUsersClient()).listTargets(userId, queries, total)), + async ({ userId, queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getUsersClient()).listTargets(userId, buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); diff --git a/lib/commands/services/vcs.ts b/lib/commands/services/vcs.ts index 76f753ef..96ac14c1 100644 --- a/lib/commands/services/vcs.ts +++ b/lib/commands/services/vcs.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -47,11 +52,13 @@ const vcsListRepositoriesCommand = vcs .requiredOption(`--installation-id `, `Installation Id`) .requiredOption(`--type `, `Detector type. Must be one of the following: runtime, framework`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common pagination prefer --limit and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Only supported methods are limit and offset`) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) .action( actionRunner( - async ({ installationId, type, search, queries }) => - parse(await (await getVcsClient()).listRepositories(installationId, type, search, queries)), + async ({ installationId, type, search, queries, limit, offset }) => + parse(await (await getVcsClient()).listRepositories(installationId, type, search, buildQueries({ queries, limit, offset }))), ), ); @@ -130,7 +137,7 @@ const vcsListInstallationsCommand = vcs .command(`list-installations`) .description(`List all VCS installations configured for the current project. This endpoint returns a list of installations including their provider, organization, and other configuration details. `) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: provider, organization`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: provider, organization`) .option(`--search `, `Search term to filter your list results. Max length: 256 chars.`) .option( `--total [value]`, @@ -138,10 +145,17 @@ const vcsListInstallationsCommand = vcs (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, search, total }) => - parse(await (await getVcsClient()).listInstallations(queries, search, total)), + async ({ queries, search, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getVcsClient()).listInstallations(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), search, total)), ), ); diff --git a/lib/commands/services/webhooks.ts b/lib/commands/services/webhooks.ts index f7dfbb5d..b9fe9bb0 100644 --- a/lib/commands/services/webhooks.ts +++ b/lib/commands/services/webhooks.ts @@ -1,4 +1,9 @@ import { Command } from "commander"; +import { + buildQueries, + collectQueryValue, + parseWhereQuery, +} from "../utils/query.js"; import { sdkForProject } from "../../sdks.js"; import { actionRunner, @@ -29,17 +34,24 @@ export const webhooks = new Command("webhooks") const webhooksListCommand = webhooks .command(`list`) .description(`Get a list of all webhooks belonging to the project. You can use the query params to filter your results.`) - .option(`--queries [queries...]`, `Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, url, authUsername, tls, events, enabled, logs, attempts`) + .option(`--queries [queries...]`, `Raw Appwrite JSON query strings (legacy). Use this for advanced queries or automation; for common filtering, sorting, and pagination prefer --where, --sort-asc, --sort-desc, --limit, and --offset. When mixed, raw --queries are sent before generated flag queries. Array of query strings generated using the Query class provided by the SDK. Learn more about queries (https://appwrite.io/docs/queries). Maximum of 100 queries are allowed, each 4096 characters long. You may filter on the following attributes: name, url, authUsername, tls, events, enabled, logs, attempts`) .option( `--total [value]`, `When set to false, the total count returned will be 0 and will not be calculated.`, (value: string | undefined) => value === undefined ? true : parseBool(value), ) + .option(`--where `, `Filter using a simple comparison expression. Repeat for multiple filters. Supports field=value, field!=value, field>value, field>=value, field collectQueryValue(parseWhereQuery(value), previous)) + .option(`--sort-asc `, `Sort results by an attribute in ascending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--sort-desc `, `Sort results by an attribute in descending order. Repeat for multiple sort fields.`, (value: string, previous: string[] | undefined) => collectQueryValue(value, previous)) + .option(`--limit `, `Maximum number of results to return.`, parseInteger) + .option(`--offset `, `Number of results to skip.`, parseInteger) + .option(`--cursor-after `, `Return results after this cursor ID.`) + .option(`--cursor-before `, `Return results before this cursor ID.`) .action( actionRunner( - async ({ queries, total }) => - parse(await (await getWebhooksClient()).list(queries, total)), + async ({ queries, total, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }) => + parse(await (await getWebhooksClient()).list(buildQueries({ queries, where, sortAsc, sortDesc, cursorAfter, cursorBefore, limit, offset }), total)), ), ); diff --git a/lib/commands/utils/query.ts b/lib/commands/utils/query.ts new file mode 100644 index 00000000..be7dbf84 --- /dev/null +++ b/lib/commands/utils/query.ts @@ -0,0 +1,197 @@ +import { InvalidArgumentError } from "commander"; + +type QueryValue = string | number | boolean | null; +type QueryValues = QueryValue | QueryValue[]; + +export type CliQueryOptions = { + queries?: string[]; + limit?: number; + offset?: number; + cursorAfter?: string; + cursorBefore?: string; + sortAsc?: string[]; + sortDesc?: string[]; + select?: string[]; + where?: string[]; +}; + +const stringifyQuery = ( + method: string, + attribute?: string, + values?: QueryValues, +): string => { + const query: { + method: string; + attribute?: string; + values?: QueryValue[]; + } = { method }; + + if (attribute !== undefined) { + query.attribute = attribute; + } + + if (values !== undefined) { + query.values = Array.isArray(values) ? values : [values]; + } + + return JSON.stringify(query); +}; + +const parseQueryValue = (value: string): QueryValues => { + const normalized = value.trim(); + + if (normalized === "true") { + return true; + } + + if (normalized === "false") { + return false; + } + + if (normalized === "null") { + return null; + } + + if (/^-?(?:\d+|\d*\.\d+)(?:e[+-]?\d+)?$/i.test(normalized)) { + const parsed = Number(normalized); + + if (!Number.isFinite(parsed)) { + throw new InvalidArgumentError( + "Numeric filter values must be finite numbers.", + ); + } + + return parsed; + } + + if (normalized.startsWith("[") && normalized.endsWith("]")) { + try { + const parsed = JSON.parse(normalized) as unknown; + if (Array.isArray(parsed)) { + return parsed.map((item) => { + if ( + item === null || + typeof item === "string" || + typeof item === "boolean" + ) { + return item; + } + + if (typeof item === "number") { + if (!Number.isFinite(item)) { + throw new InvalidArgumentError( + "Array filter values must be finite numbers.", + ); + } + + return item; + } + + throw new InvalidArgumentError( + "Array filters can only contain strings, numbers, booleans, or null.", + ); + }); + } + } catch (error) { + if (error instanceof InvalidArgumentError) { + throw error; + } + + throw new InvalidArgumentError( + "Array filter values must be valid JSON arrays.", + ); + } + } + + return normalized; +}; + +const whereOperators: Array<[RegExp, string]> = [ + [/^(.+?)\s*!=\s*(.*)$/, "notEqual"], + [/^(.+?)\s*>=\s*(.*)$/, "greaterThanEqual"], + [/^(.+?)\s*<=\s*(.*)$/, "lessThanEqual"], + [/^(.+?)\s*=\s*(.*)$/, "equal"], + [/^(.+?)\s*>\s*(.*)$/, "greaterThan"], + [/^(.+?)\s*<\s*(.*)$/, "lessThan"], +]; + +export const collectQueryValue = (value: T, previous: T[] = []): T[] => [ + ...previous, + value, +]; + +export const parseWhereQuery = (expression: string): string => { + for (const [pattern, method] of whereOperators) { + const match = expression.match(pattern); + + if (!match) { + continue; + } + + const attribute = match[1].trim(); + if (attribute === "") { + throw new InvalidArgumentError( + "Where filters must include an attribute before the operator.", + ); + } + + return stringifyQuery(method, attribute, parseQueryValue(match[2])); + } + + throw new InvalidArgumentError( + "Where filters must use one of: field=value, field!=value, field>value, field>=value, field { + const builtQueries = [...(queries ?? [])]; + + if (where) { + // parseWhereQuery returns fully serialized Appwrite query JSON strings. + builtQueries.push(...where); + } + + if (sortAsc) { + builtQueries.push( + ...sortAsc.map((attribute) => stringifyQuery("orderAsc", attribute)), + ); + } + + if (sortDesc) { + builtQueries.push( + ...sortDesc.map((attribute) => stringifyQuery("orderDesc", attribute)), + ); + } + + if (limit !== undefined) { + builtQueries.push(stringifyQuery("limit", undefined, limit)); + } + + if (offset !== undefined) { + builtQueries.push(stringifyQuery("offset", undefined, offset)); + } + + if (cursorAfter !== undefined) { + builtQueries.push(stringifyQuery("cursorAfter", undefined, cursorAfter)); + } + + if (cursorBefore !== undefined) { + builtQueries.push(stringifyQuery("cursorBefore", undefined, cursorBefore)); + } + + if (select && select.length > 0) { + builtQueries.push(stringifyQuery("select", undefined, select)); + } + + return builtQueries.length > 0 ? builtQueries : undefined; +}; diff --git a/lib/constants.ts b/lib/constants.ts index 8a9516cb..2eef4fb7 100644 --- a/lib/constants.ts +++ b/lib/constants.ts @@ -1,7 +1,7 @@ // SDK export const SDK_TITLE = 'Appwrite'; export const SDK_TITLE_LOWER = 'appwrite'; -export const SDK_VERSION = '19.0.0'; +export const SDK_VERSION = '19.1.0'; export const SDK_NAME = 'Command Line'; export const SDK_PLATFORM = 'console'; export const SDK_LANGUAGE = 'cli'; diff --git a/lib/parser.ts b/lib/parser.ts index fa4642e8..5800df6a 100644 --- a/lib/parser.ts +++ b/lib/parser.ts @@ -649,6 +649,20 @@ export const drawJSON = (data: unknown): void => { console.log(JSON.stringify(data, null, 2)); }; +const isQueryError = (message: string): boolean => + /Invalid query(?: method)?/i.test(message) || + /query[^.:\n]*syntax error|syntax error[^.:\n]*query/i.test(message); + +const printQueryErrorHint = (err: Error): void => { + if (!isQueryError(err.message)) { + return; + } + + hint( + `For common list filters, use flags like --limit 25, --sort-desc '$createdAt', or --where 'status=active'. Raw --queries values must be Appwrite JSON query strings, for example: ${EXECUTABLE_NAME} tables-db list-rows --queries '{"method":"limit","values":[25]}'`, + ); +}; + export const parseError = (err: Error): void => { if (cliConfig.report) { void (async () => { @@ -695,6 +709,7 @@ export const parseError = (err: Error): void => { log( `To report this error you can:\n - Create a support ticket in our Discord server https://appwrite.io/discord \n - Create an issue in our Github\n ${githubIssueUrl.href}\n`, ); + printQueryErrorHint(err); error("\n Stack Trace: \n"); console.error(err); @@ -703,9 +718,11 @@ export const parseError = (err: Error): void => { } else { if (cliConfig.verbose) { console.error(err); + printQueryErrorHint(err); } else { log("For detailed error pass the --verbose or --report flag"); error(err.message); + printQueryErrorHint(err); } process.exit(1); } diff --git a/package-lock.json b/package-lock.json index c93a5d58..71a7cd36 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "appwrite-cli", - "version": "19.0.0", + "version": "19.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "appwrite-cli", - "version": "19.0.0", + "version": "19.1.0", "license": "BSD-3-Clause", "dependencies": { "@appwrite.io/console": "11.0.0", @@ -2021,9 +2021,9 @@ } }, "node_modules/@roberts_lando/vfs": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@roberts_lando/vfs/-/vfs-0.3.2.tgz", - "integrity": "sha512-whXj9v78S4n3t0RvoTGj8vui27VVtK/oy8YfBL+gDWdlfRFkKpPjry+U8p+3XM++5rAIpXEtXcTUgUAEHZVoFA==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@roberts_lando/vfs/-/vfs-0.3.3.tgz", + "integrity": "sha512-YjkxVSLw5WMZQoARaryRAjcxA+GbBzWMJdwYZX5oLUt9cC/gew9as4Dn7tcLzPp7BPoR221VpTZ+78TRPawnjg==", "dev": true, "license": "MIT", "engines": { @@ -2379,9 +2379,9 @@ } }, "node_modules/@yao-pkg/pkg": { - "version": "6.18.2", - "resolved": "https://registry.npmjs.org/@yao-pkg/pkg/-/pkg-6.18.2.tgz", - "integrity": "sha512-lo+fNeV10ldTeTrDbgK2eYTIhKDqCUVVq7a4W3s7LiTwd9/8UKYdxBodVNNCbEd2JBtqKA4BZpevitfsOzyXig==", + "version": "6.19.0", + "resolved": "https://registry.npmjs.org/@yao-pkg/pkg/-/pkg-6.19.0.tgz", + "integrity": "sha512-Ys9Fn/F44C3nOTlNyhwviLyMxydgFzsB13jAAXKxEuIR7aAz8PrFlUpxTUlwaXUU847nlmg5mnaGIyOJpnVtRw==", "dev": true, "license": "MIT", "dependencies": { @@ -2389,11 +2389,10 @@ "@babel/parser": "^7.23.0", "@babel/traverse": "^7.23.0", "@babel/types": "^7.23.0", - "@roberts_lando/vfs": "^0.3.2", + "@roberts_lando/vfs": "^0.3.3", "@yao-pkg/pkg-fetch": "3.5.33", "esbuild": "^0.27.3", "into-stream": "^9.1.0", - "minimist": "^1.2.6", "multistream": "^4.1.0", "picocolors": "^1.1.0", "picomatch": "^4.0.2", @@ -2469,9 +2468,9 @@ } }, "node_modules/ajv": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "dev": true, "license": "MIT", "dependencies": { @@ -5487,15 +5486,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -6684,15 +6674,12 @@ } }, "node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, "engines": { - "node": ">=0.6.0" + "node": ">=14.14" } }, "node_modules/to-regex-range": { diff --git a/package.json b/package.json index a4ed73f6..2e17bb79 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "type": "module", "homepage": "https://appwrite.io/support", "description": "Appwrite is an open-source self-hosted backend server that abstracts and simplifies complex and repetitive development tasks behind a very simple REST API", - "version": "19.0.0", + "version": "19.1.0", "license": "BSD-3-Clause", "main": "dist/index.cjs", "module": "dist/index.js", @@ -73,7 +73,8 @@ }, "overrides": { "phin": "3.7.1", - "@xmldom/xmldom": "^0.9.10" + "@xmldom/xmldom": "^0.9.10", + "tmp": "0.2.5" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^8.0.0", diff --git a/scoop/appwrite.config.json b/scoop/appwrite.config.json index 7d7b1792..4dfe2856 100644 --- a/scoop/appwrite.config.json +++ b/scoop/appwrite.config.json @@ -1,12 +1,12 @@ { "$schema": "https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json", - "version": "19.0.0", + "version": "19.1.0", "description": "The Appwrite CLI is a command-line application that allows you to interact with Appwrite and perform server-side tasks using your terminal.", "homepage": "https://github.com/appwrite/sdk-for-cli", "license": "BSD-3-Clause", "architecture": { "64bit": { - "url": "https://github.com/appwrite/sdk-for-cli/releases/download/19.0.0/appwrite-cli-win-x64.exe", + "url": "https://github.com/appwrite/sdk-for-cli/releases/download/19.1.0/appwrite-cli-win-x64.exe", "bin": [ [ "appwrite-cli-win-x64.exe", @@ -15,7 +15,7 @@ ] }, "arm64": { - "url": "https://github.com/appwrite/sdk-for-cli/releases/download/19.0.0/appwrite-cli-win-arm64.exe", + "url": "https://github.com/appwrite/sdk-for-cli/releases/download/19.1.0/appwrite-cli-win-arm64.exe", "bin": [ [ "appwrite-cli-win-arm64.exe",