mcpField
A
appwrite-cli

appwrite-cli

github.com/appwrite云与 DevOps281.9k 次安装1 周前更新
代码仓库

关于 appwrite-cli

介绍如何使用 Appwrite CLI 管理项目、配置、部署和生成类型。指南区分持久化项目操作与一次性 API 调用,并说明安全同步和 CI 使用方式。

主要功能

  1. 01项目配置与资源同步
  2. 02身份验证、端点和环境变量管理
  3. 03按范围部署资源
  4. 04生成 TypeScript API 与类型
  5. 05筛选、JSON 输出和分页

适用场景

  1. 01根据配置同步项目架构和函数
  2. 02在 CI 中部署指定资源
  3. 03根据项目配置生成类型化 TablesDB 封装

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/appwrite/skills --skill appwrite-cli

安装后在 Claude Code 中输入/appwrite-cli确认已加载。

详细介绍

Appwrite CLI

appwrite <command> --help 已列出标志。请先查看,而不是猜测。

配置与 client

真实项目(代码库、架构、函数、部署、CI)存储在 appwrite.config.json 中。初始化一次即可。之后执行拉取和推送。不要在每条命令上都运行 appwrite client --project-id——配置文件已经指定了项目。

一次性操作(检查用户、修改一行数据、临时调用不会再用到的远程服务)使用 appwrite client。不要为了单次 API 调用搭建项目。

# Good — project
appwrite login
appwrite list-projects --json
appwrite init project --project-id <ID>
appwrite pull table
# edit appwrite.config.json, then:
appwrite push table --force

# Bad — project treated as a pile of API calls
appwrite tablesdb create-table --database-id main --table-id songs ...
appwrite tablesdb create-varchar-column --database-id main --table-id songs ...
# the next clone has no record of this

# Good — one-off (already logged in)
appwrite client --project-id <ID>
appwrite users get --user-id <ID> --json

# Bad — one-off that litters a repo
cd ~/some-unrelated-app && appwrite init project

没有会话?运行 appwrite client --endpoint https://<REGION>.cloud.appwrite.io/v1 --key "$APPWRITE_API_KEY" --project-id <ID>。

appwrite client --project-id 会在此目录中写入 appwrite.config.json(或更新向上查找时找到的配置文件)。这就是快速关联文件夹的方式。不要在不相关代码库的根目录运行它。APPWRITE_PROJECT_ID / APPWRITE_ENDPOINT 可以覆盖配置文件,且不会修改该文件——如果你已在某个项目中,但需要对其他项目进行一次性操作,请使用这些变量。

身份验证不等于项目

层存储位置设置方式
你的身份(会话或 API 密钥)CLI 全局首选项appwrite login 或 appwrite client --key
所属项目appwrite.config.jsoninit project、pull 或 client --project-id

init project 会与控制台通信,需要登录会话。API 密钥无法列出组织。

# Good — CI against a checked-in config
appwrite client --key "$APPWRITE_API_KEY"
appwrite push function --force

# Bad — CI that bakes the key into the repo
appwrite client --key 'standard_....'
# and commits appwrite.config.json with secrets inside

环境变量优先于配置文件:APPWRITE_PROJECT_ID、APPWRITE_ENDPOINT、APPWRITE_ORGANIZATION_ID。将配置文件提交到代码库(不含密钥)。将密钥放入环境变量中。

--force 会跳过提示。Agent 和 CI 没有 TTY,因此需要确认的推送若不使用该标志就会失败(请传入 --force)。先询问用户,再传入 --force。不要用它跳过本地列为空的变更表。

appwrite login --switch 会切换已保存的账号。appwrite client --debug 会显示生效的端点/项目,并屏蔽凭据。appwrite client --reset 会退出所有账号。

云端点

appwrite whoami 显示 https://cloud.appwrite.io/v1 时,这是账号登录主机。请保留它。项目 API 调用使用区域主机(例如 https://fra.cloud.appwrite.io/v1)。init project 和 client --project-id 会将该区域固定到配置文件中。自托管时,两者使用同一个端点。

# Good — project work uses the config's regional endpoint
cat appwrite.config.json   # "endpoint": "https://fra.cloud.appwrite.io/v1"

# Bad — "fixing" whoami
appwrite client --endpoint https://fra.cloud.appwrite.io/v1
# now login/session calls go to a region host they do not belong on

架构与数据行

拉取 / 推送(配置)服务命令(不在配置中)
设置、函数、站点、表和列、存储桶、团队、Webhook、主题数据行、用户、文件、执行、消息

如果某项内容应该在全新克隆后仍然存在,就应将其放入配置文件中。编辑文件,然后推送。使用 tablesdb create-* 或 functions create 创建相同资源,会绕过下次 pull / push 所依赖的文件。

databases 已弃用。请使用 tablesdb 和 push table。

如果变更表显示远程值对应的本地空值,说明配置文件缺少这些字段。拉取该资源,然后推送。不要用 --force 强行通过,也不要把拉取所有内容当作例行操作——pull settings 很慢。

   id            │ key             │ remote │ local
  ───────────────┼─────────────────┼────────┼───────
   Service       │ account         │ true   │
   Auth method   │ email-password  │ true   │
# Good — local column was empty, so sync first, then push
appwrite pull settings
appwrite push settings --force

# Bad — empty local, forced through
appwrite push settings --force

push all --all --force 会推送所有资源。请限定范围(例如 push function --function-id api),除非你确实需要推送全部资源。

对于一次性的数据行或用户操作,使用 unique() 没问题。需要推送的资源必须在配置文件中拥有稳定的 $id,以便下次拉取时能够匹配。

类型安全的应用代码

编写针对 TablesDB 的应用代码时,请先检查 appwrite.config.json,再定义接口、数据库 ID、表 ID 或列名。生成器会读取本地配置,不会检查远程架构。过期的配置会生成过期的代码。

如果远程架构是事实来源,请先使用 appwrite pull table 更新配置。不要覆盖本地尚未推送的架构更改。如果本地配置更新,则直接根据它生成代码。

对于 TypeScript,优先使用 appwrite generate。它会生成完整的 TablesDB 封装:数据库和表选项、创建/更新载荷、返回的行、查询字段和查询值都会经过 TypeScript 检查。这比单独生成模型接口更可靠。

appwrite generate

请使用生成的 API,而不要退回到原始字符串 ID 和手写的载荷类型:

import { databases, type Songs } from "./generated/appwrite/index.js";

// Database lookup uses its ID; table lookup uses its name from the config.
const songs = databases.use("main").use("Songs");

const page = await songs.list({
  queries: (query) => [
    query.equal("published", true),
    query.orderDesc("createdAt"),
    query.limit(20),
  ],
});

const first: Songs | undefined = page.rows[0];

不要猜测示例中的字面值:请查看生成的类型或配置。尤其是,表的 .use() 接受其 name,而它可能与 $id 不同。让编译过程发现拼写错误的表名、列名或错误的查询值。生成后请运行项目的类型检查器。

目前,generate 仅为 TypeScript 提供完整封装。它会根据已安装的 Appwrite 软件包检测客户端或服务端输出。服务端输出会读取 APPWRITE_API_KEY;切勿将该密钥放入生成的常量或提交到版本库。仅当检测有误时,才覆盖语言、导入来源、模块扩展名或客户端/服务端模式——请查看 appwrite generate --help 了解这些标志。

对于其他受支持的语言,或项目有意直接使用常规 SDK 时,请使用 appwrite types <output-directory>。它支持 TypeScript(ts)、JavaScript(js)、PHP(php)、Kotlin(kotlin)、Swift(swift)、Java(java)、Dart(dart)和 C#(cs)。将这些短值传给 --language;typescript 和 csharp 等名称不是该命令接受的值。生成的文件会为行数据提供类型,但不会对原始数据库/表 ID 或 Query 调用进行类型检查:

对于 TypeScript,如果生成结果将作为模块导入,请指定 .ts 目标路径。若传入目录,则会在其中创建 appwrite.d.ts。

appwrite types ./src/appwrite-types.ts --language ts
import { Client, TablesDB } from "appwrite";
import type { Songs } from "./appwrite-types.js";

// Read these values from appwrite.config.json and expose them through the
// application's existing configuration mechanism.
const client = new Client()
  .setEndpoint("https://<REGION>.cloud.appwrite.io/v1")
  .setProject("<PROJECT_ID>");
const tablesDB = new TablesDB(client);

const page = await tablesDB.listRows<Songs>({
  databaseId: "main", // still an unchecked string
  tableId: "songs",  // still an unchecked string
});

不要将 types --strict 描述为“完全类型安全”。它只会将字段名转换为目标语言的命名约定。如果目标是获得完整类型化的 TypeScript 表 API,请使用 generate。

生成的代码属于派生输出。不要通过修改它来修复架构或命名问题;请修复 appwrite.config.json 或生成器输入,然后重新生成。每次更改表或列后,都要重新运行仓库使用的同一生成命令,并运行其格式化工具/类型检查器。保留仓库现有的输出路径和提交约定。

Functions 和 sites

变量存放在 <path>/.env 中,而非 appwrite.config.json 中。--with-variables 会用该文件替换远程变量集合。除非有意同步密钥,否则请省略它。

# Good — ship code, leave remote vars alone
appwrite push function --function-id api --activate --force

# Bad — remote vars you did not list locally are gone
appwrite push function --function-id api --with-variables --force

# Good — deploy without switching live traffic
appwrite push function --function-id api --activate=false --force

--async 会在构建完成前返回。本地运行:appwrite run function。

查询和输出

优先使用 --filter、--sort-asc / --sort-desc、--limit、--select、--cursor-after。--where 已弃用。仅当标志无法表达相应的 Query JSON 时,才使用 --queries。

# Good
appwrite users list \
  --filter 'emailVerification=true' \
  --sort-desc '$createdAt' \
  --limit 20 \
  --json

# Bad
appwrite users list --queries '[{"method":"equal","attribute":"emailVerification","values":[true]}]'

--filter 会解析 true / false / null、数字和 JSON 数组。重复使用该标志表示 AND。列表页最多返回 100 条;与其使用较大的 --offset,不如优先使用 --cursor-after <lastId>。

脚本使用 --json(空字段会被省略)。使用 --raw 获取未经筛选的载荷。除非使用 --show-secrets,否则密钥会保持隐藏。

配置文件本身

CLI 会从当前工作目录向上查找 appwrite.config.json(或旧版 appwrite.json)。在 functions/api/ 中运行 push,仍会找到项目根目录。父目录中多余的配置文件会让 CLI 使用该配置。

使用 includes 拆分大型项目——每个值都是相对路径的 .json 文件数组。资源不能同时内联并被包含。函数和站点的 path 值相对于包含文件解析,而非相对于仓库根目录。

不要凭记忆编写此文件。init project 或 pull 会生成有效的配置文件。然后再编辑。

评论

支持 Markdown