@craftware / crafty-cli
狡猾的托管命令行-部署你的前端构建到 狡猾的托管 用一个命令。 CLI与狡猾的CMS租户对话;底层托管提供程序是完整的 抽象的(你永远不会直接处理它)。
安装
npm i -g @craftware/crafty-cli
要求Node.js 20+。
创建一个新站点
npm create crafty@latest # or: crafty create [dir]
复制一个官方启动器(今天是Astro,“sittio de servicios”),让你登录
您在浏览器(作用域)中的租户 deploy crafty:read crafty:write crafty:publish),使用启动器的块类型、集合、
形式及演示内容(已发布; --draft 保存为草稿),然后写作
.env, crafty.json 和 src/crafty.types.ts. 然后 npm install && npm run dev. 初学者住在 sdk/starters; npm run templates 副本
成 templates/ (自动完成) npm pack / npm publish)。
快速启动
从你的前端项目(已经使用了Crafty API的项目):
crafty login # opens a browser to approve the CLI (OAuth device flow)
crafty init # writes crafty.json (site + environment + build dir)
npm run build # produce ./dist (framework-specific)
crafty deploy # zips the build, uploads it, prints the live URL
命令行显示如下 CRAFTY_API_URL 从你的项目 .env 要知道哪个租户
,这样就没有其他东西需要配置了。主机必须为您的
租户、站点和环境(在Crafty面板中),然后才能进行部署。
多个租户
命令行保持 每个租户主机一个会话,所以你要一直登录
马上给你的房客。每个项目的 CRAFTY_API_URL 选择存储的
使用会话-切换目录不会强制重新登录。登录到
没有进入其项目的租户 crafty login --host=<url>.
命令
| 命令 | 描述 |
|---|---|
crafty create [dir] [--url=<url> --template=<id> --name=<name> --site=<slug> --draft --yes] | 在Crafty中从starter和它的站点创建一个项目(与 npm create crafty). 看到 创建一个新站点. |
crafty login [--host=<url>] | 通过OAuth 2.0设备授权授权进行身份验证。没有 --host租客来自哪里 CRAFTY_API_URL. 令牌范围 deploy中的每台主机存储 ~/.crafty/credentials (600)模式。 |
crafty init [--site=<slug> --environment=<env> --build-dir=<dir>] | 创建 crafty.json 在项目中。 |
crafty deploy [dir] [--force] | 打包并部署一个构建目录(默认: buildDir 从 crafty.json,即 dist). 项目根目录、主目录和项目外的目录被拒绝,除非 --force 是过去了。 |
crafty status | 显示项目最后一次部署的状态。 |
crafty types [--api-key=<key> --url=<url> --out=<file>] | 为环境的集合和块类型生成TypeScript类型(默认输出: crafty.types.ts). 看到 内容类型. |
crafty skills list / crafty skills install [name…] [--global | --dir=<path>] | 列出或安装Crafty代理技能(.claude/skills 默认情况下)。 |
crafty logout | 撤销和删除当前项目租户的会话。 |
crafty update (crafty --update / -u) | 在npm上将全局安装的CLI自动更新到最新版本。 |
crafty --version / crafty help | 打印版本/用法。 |
内容类型
crafty types 为内容模型(集合和
块类型),因此您的代码—以及您的编码代理—将停止
猜测场的形状:
crafty types # uses CRAFTY_API_URL + CRAFTY_API_KEY from .env
crafty types --api-key=$STAGING_KEY --out=src/crafty.types.ts
- 这个 环境来自API密钥:分级生成的类型 关键描述分期。在更改集合或块类型后再生。
- 它使用公共环境API密钥(
X-API-Key),而不是crafty login会话。--url/CRAFTY_API_URL选择租户;https是必需的 除了localhost. - 输出:
<Slug>Entry返回的每个集合(条目元数据+字段)/collections/{slug}/entries),<Slug>BlockData和<Slug>Block每一块 类型,CraftyPageBlock工会(受歧视)type),CraftyCollectionTypes/CraftyBlockDataTypes鼻涕虫映射,并共享CraftyEntryReference/CraftyMediaSummary. - 字段映射:
string/text/longText/url/datetime→string,number/decimal→number,boolean→boolean,select→并集 它的选项值(一个带有multiple),stringList→string[],repeater→项目对象数组,媒体引用→id加a<key>_media文件摘要、集合参考→CraftyEntryReference在 块上的条目和引用的条目类型,json→unknown. 可选字段包括| null.
import type { BlogEntry, CraftyPageBlock } from "./crafty.types";
const { data } = await crafty.entries.list("blog");
const posts = data as unknown as BlogEntry[];
const page = await crafty.pages.get("home");
for (const block of page.blocks as unknown as CraftyPageBlock[]) {
if (block.type === "hero") {
block.data.heading; // typed as HeroBlockData
}
}
(通用SDK方法,如 crafty.entries.list<"blog">() 计划;直到
然后,将SDK响应转换为生成的类型。)
图式来自于 GET /api/v1/schema (JSON模式,版本由
format_version); 命令行拒绝它不知道的格式-运行
crafty update.
crafty.json
{
"site": "acme",
"environment": "production",
"buildDir": "dist"
}
集 buildDir 到框架的输出:Vite/CRA/Astro dist.js静态
出口 out, Nuxt .output/public, SvelteKit(静态适配器) build.
它如何解决上下文
CRAFTY_API_URL从项目来看.env(或环境)→租户基础URL。crafty.json→site,environment,buildDir.CRAFTY_TOKEN从过程环境(CI)中,或者,如果没有它,~/.crafty/credentials→为该租户主机存储的访问令牌。
从CI部署(GitHub Actions)
在CI中没有 crafty login. 属性创建个人访问令牌
deploy Crafty panel的范围(完成→令牌(作为租户管理员)和
将其作为 CRAFTY_TOKEN,连同… CRAFTY_API_URL. CRAFTY_TOKEN 是
只从环境中读书,从不从环境中读书 .env.
要在内容更改时重新部署,请在 网站→
Integraciones→Webhooks 使用格式 GitHub的行为, URL
https://api.github.com/repos/{owner}/{repo}/dispatches 和一个 Authorization: Bearer <token> header(用于该存储库的细粒度GitHub令牌)
内容:读、写). 然后狡猾地发送了一个 repository_dispatch 与
event_type: crafty-content 和狡猾的有效载荷 client_payload;它的
测试ping使用 crafty-ping,它在不启动构建的情况下检查令牌。
# .github/workflows/crafty-deploy.yml
name: Deploy to Crafty Hosting
on:
push:
branches: [main]
repository_dispatch:
types: [crafty-content]
workflow_dispatch:
# Publishing 20 entries in a row sends 20 events: each new run replaces the
# pending one and cancels the one in progress, so only the last one deploys.
concurrency:
group: crafty-deploy
cancel-in-progress: true
jobs:
deploy:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run build
env:
CRAFTY_API_URL: ${{ vars.CRAFTY_API_URL }}
CRAFTY_API_KEY: ${{ secrets.CRAFTY_API_KEY }}
- run: npx --yes @craftware/crafty-cli@latest deploy
env:
CRAFTY_API_URL: ${{ vars.CRAFTY_API_URL }}
CRAFTY_TOKEN: ${{ secrets.CRAFTY_TOKEN }}
github.event.client_payload 承载事件(event, site,
environment, data.type, data.slug,…),如果构建需要知道什么
改变了。
为了安全起见,令牌只会被发送到发出令牌的主机, https 是
要求(除了 localhost), .git, .env*, .envrc, .dev.vars, .npmrc,
.netrc, .aws, .ssh, .crafty, id_rsa*风格的钥匙, *.pem, *.key,
node_modules 并且符号链接将从上传的构建中排除(不区分大小写)。
部署的URL和自定义域
成功的部署是在一个租户范围的子域上进行的
{tenant}-{hash}.crafty.do,每个环境一个(DNS + TLS自动设置)。
要使用自己的域,请将其添加到下面的Crafty面板中 站点→主机;它
返回要在DNS提供商处创建的CNAME记录。使用子域,例如
www,只创建该记录,并留下电子邮件记录(MX, SPF, DKIM, DMARC)
都没动。根域只有在DNS在Cloudflare上时才能连接;永远不要把
CNAME的根,因为它破坏了域的电子邮件。
代理技能
这个包发送狡猾的代理技能: crafty-deploy (此命令行:何时
运行 login/init/deploy, buildDir 每个框架,故障排除)和
crafty-cms (MCP服务器和SDK)。将它们安装在代理读取的位置
技能:
crafty skills list
crafty skills install # ./.claude/skills (this project)
crafty skills install --global # ~/.claude/skills (every project)
crafty skills install --dir=<path> # another agent's skills folder
npx @craftware/crafty-cli skills install # without installing the CLI
再次运行它将替换已安装的副本,因此它也将它们更新为以下内容
CLI的版本。克劳德。ai和Claude Desktop,从
docs.crafty.do (/skills/crafty-cms.zip, /skills/crafty-deploy.zip),
将它们作为技能上传。
开发
npm install
npm run build # tsc → dist
npm test # builds, then runs node:test
npm run typecheck
出版
作为公共的、限定范围的包发布 @craftware org。 publishConfig.access
已经 public 和 prepublishOnly 重建 dist,所以不需要额外的标志。
先决条件: 的成员的NPM帐户 craftware Org与publish
权限,以及启用2FA设备。
# 1. authenticate
npm login
npm whoami
# 2. from this package, install exact deps and validate
cd sdk/cli
npm ci
npm test
npm run typecheck
# 3. preview the exact tarball (no upload)
npm publish --dry-run
# expect: dist/**, skills/**, templates/**, LICENSE, README.md, package.json
# (never src/, tests/ or node_modules/)
# 4. publish
npm publish # add --otp=123456 if 2FA is enabled
# 5. verify
npm view @craftware/crafty-cli
npm i -g @craftware/crafty-cli && crafty --version
发布新版本
cd sdk/cli
npm version patch # or minor / major — creates a commit + git tag
git push --follow-tags
npm publish
注:
- 一个给定的版本只能出版一次;如果有任何变化,请点击版本。
- 在预定的提交处从干净树发布。
- 这个
crafty本是dist/bin/crafty.js(#!/usr/bin/env node工作)。 create-crafty(sdk/create-crafty,什么npm create crafty运行)依赖于此 包的./createexport:先发布CLI,然后再发布create-crafty.