i18n - docs translations (#18528)
Created by Github action --------- Co-authored-by: github-actions <github-actions@twenty.com> Co-authored-by: Charles Bochet <charles@twenty.com>
This commit is contained in:
committed by
GitHub
parent
c73a660e46
commit
59e9563fc7
@@ -15,7 +15,7 @@ description: 以代码的形式构建并管理 Twenty 自定义项。
|
||||
|
||||
* 以代码定义自定义对象和字段(受管理的数据模型)
|
||||
* 构建带有自定义触发器的逻辑函数
|
||||
* Define skills and agents for AI
|
||||
* 为 AI 定义技能和代理
|
||||
* 将同一个应用部署到多个工作空间
|
||||
|
||||
## 先决条件
|
||||
@@ -39,10 +39,10 @@ yarn twenty app:dev
|
||||
脚手架工具支持两种模式,用于控制包含哪些示例文件:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Default (exhaustive): all examples (object, field, logic function, front component, view, navigation menu item, skill, agent)
|
||||
# 默认(完整):所有示例(对象、字段、逻辑函数、前端组件、视图、导航菜单项、技能、代理)
|
||||
npx create-twenty-app@latest my-app
|
||||
|
||||
# Minimal: only core files (application-config.ts and default-role.ts)
|
||||
# 最小化:仅核心文件(application-config.ts 和 default-role.ts)
|
||||
npx create-twenty-app@latest my-app --minimal
|
||||
```
|
||||
|
||||
@@ -96,29 +96,29 @@ my-twenty-app/
|
||||
.oxlintrc.json
|
||||
tsconfig.json
|
||||
README.md
|
||||
public/ # Public assets folder (images, fonts, etc.)
|
||||
public/ # 公共资源文件夹(图片、字体等)
|
||||
src/
|
||||
├── application-config.ts # Required - main application configuration
|
||||
├── application-config.ts # 必需 - 主应用配置
|
||||
├── roles/
|
||||
│ └── default-role.ts # Default role for logic functions
|
||||
│ └── default-role.ts # 逻辑函数的默认角色
|
||||
├── objects/
|
||||
│ └── example-object.ts # Example custom object definition
|
||||
│ └── example-object.ts # 示例自定义对象定义
|
||||
├── fields/
|
||||
│ └── example-field.ts # Example standalone field definition
|
||||
│ └── example-field.ts # 示例独立字段定义
|
||||
├── logic-functions/
|
||||
│ ├── hello-world.ts # Example logic function
|
||||
│ ├── pre-install.ts # Pre-install logic function
|
||||
│ └── post-install.ts # Post-install logic function
|
||||
│ ├── hello-world.ts # 示例逻辑函数
|
||||
│ ├── pre-install.ts # 安装前逻辑函数
|
||||
│ └── post-install.ts # 安装后逻辑函数
|
||||
├── front-components/
|
||||
│ └── hello-world.tsx # Example front component
|
||||
│ └── hello-world.tsx # 示例前端组件
|
||||
├── views/
|
||||
│ └── example-view.ts # Example saved view definition
|
||||
│ └── example-view.ts # 示例已保存视图定义
|
||||
├── navigation-menu-items/
|
||||
│ └── example-navigation-menu-item.ts # Example sidebar navigation link
|
||||
│ └── example-navigation-menu-item.ts # 示例侧边栏导航链接
|
||||
├── skills/
|
||||
│ └── example-skill.ts # Example AI agent skill definition
|
||||
│ └── example-skill.ts # 示例 AI 代理技能定义
|
||||
└── agents/
|
||||
└── example-agent.ts # Example AI agent definition
|
||||
└── example-agent.ts # 示例 AI 代理定义
|
||||
```
|
||||
|
||||
使用 `--minimal` 时,只会创建核心文件(`application-config.ts`、`roles/default-role.ts`、`logic-functions/pre-install.ts` 和 `logic-functions/post-install.ts`)。
|
||||
@@ -150,7 +150,7 @@ my-twenty-app/
|
||||
| `defineView()` | Saved view definitions |
|
||||
| `defineNavigationMenuItem()` | Navigation menu item definitions |
|
||||
| `defineSkill()` | AI agent skill definitions |
|
||||
| `defineAgent()` | AI agent definitions |
|
||||
| `defineAgent()` | AI 代理定义 |
|
||||
|
||||
<Note>
|
||||
**文件命名是灵活的。** 实体检测基于 AST — SDK 会扫描你的源文件以查找 `export default define<Entity>({...})` 模式。 你可以按照自己的喜好组织文件和文件夹。 按实体类型分组(例如 `logic-functions/`、`roles/`)只是代码组织的一种约定,并非必需。
|
||||
@@ -171,7 +171,7 @@ export default defineObject({
|
||||
|
||||
后续命令将添加更多文件和文件夹:
|
||||
|
||||
* `yarn twenty app:dev` 会在 `node_modules/twenty-sdk/generated` 中自动生成两个类型化 API 客户端:`CoreApiClient`(通过 `/graphql` 获取工作区数据)和 `MetadataApiClient`(通过 `/metadata` 处理工作区配置和文件上传)。
|
||||
* `yarn twenty app:dev` 会在 `node_modules/twenty-sdk/clients` 中自动生成两个类型化 API 客户端:`CoreApiClient`(通过 `/graphql` 获取工作区数据)和 `MetadataApiClient`(通过 `/metadata` 处理工作区配置和文件上传)。
|
||||
* `yarn twenty entity:add` will add entity definition files under `src/` for your custom objects, functions, front components, roles, skills, and more.
|
||||
|
||||
## 身份验证
|
||||
@@ -215,20 +215,20 @@ twenty-sdk 提供你在应用中使用的类型化构件和辅助函数。 以
|
||||
|
||||
该 SDK 提供辅助函数用于定义你的应用实体。 如 [实体检测](#entity-detection) 中所述,你必须使用 `export default define<Entity>({...})` 才能让你的实体被检测到:
|
||||
|
||||
| 函数 | 目的 |
|
||||
| ---------------------------------- | ------------------------------------ |
|
||||
| `defineApplication()` | 配置应用元数据(必需,每个应用一个) |
|
||||
| `defineObject()` | 定义带字段的自定义对象 |
|
||||
| `defineLogicFunction()` | 定义带处理程序的逻辑函数 |
|
||||
| `definePreInstallLogicFunction()` | 定义一个安装前逻辑函数(每个应用一个) |
|
||||
| `definePostInstallLogicFunction()` | 定义一个安装后逻辑函数(每个应用一个) |
|
||||
| `defineFrontComponent()` | 为自定义 UI 定义前端组件 |
|
||||
| `defineRole()` | 配置角色权限和对象访问 |
|
||||
| `defineField()` | 为现有对象扩展额外字段 |
|
||||
| `defineView()` | Define saved views for objects |
|
||||
| `defineNavigationMenuItem()` | Define sidebar navigation links |
|
||||
| `defineSkill()` | Define AI agent skills |
|
||||
| `defineAgent()` | Define AI agents with system prompts |
|
||||
| 函数 | 目的 |
|
||||
| ---------------------------------- | ------------------------------- |
|
||||
| `defineApplication()` | 配置应用元数据(必需,每个应用一个) |
|
||||
| `defineObject()` | 定义带字段的自定义对象 |
|
||||
| `defineLogicFunction()` | 定义带处理程序的逻辑函数 |
|
||||
| `definePreInstallLogicFunction()` | 定义一个安装前逻辑函数(每个应用一个) |
|
||||
| `definePostInstallLogicFunction()` | 定义一个安装后逻辑函数(每个应用一个) |
|
||||
| `defineFrontComponent()` | 为自定义 UI 定义前端组件 |
|
||||
| `defineRole()` | 配置角色权限和对象访问 |
|
||||
| `defineField()` | 为现有对象扩展额外字段 |
|
||||
| `defineView()` | Define saved views for objects |
|
||||
| `defineNavigationMenuItem()` | Define sidebar navigation links |
|
||||
| `defineSkill()` | Define AI agent skills |
|
||||
| `defineAgent()` | 使用系统提示词定义 AI 智能体 |
|
||||
|
||||
这些函数会在构建时校验你的配置,并提供 IDE 自动补全和类型安全。
|
||||
|
||||
@@ -321,6 +321,72 @@ export default defineObject({
|
||||
但不建议这样做。
|
||||
</Note>
|
||||
|
||||
### Defining fields on existing objects
|
||||
|
||||
Use `defineField()` to add custom fields to existing objects — both standard objects (like `company`, `person`, `opportunity`) and custom objects defined by other apps. Each field lives in its own file and references the target object by its `universalIdentifier`.
|
||||
|
||||
To reference standard objects, import `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` from `twenty-sdk`. This constant provides stable identifiers for all built-in objects and their fields:
|
||||
|
||||
```typescript
|
||||
// src/fields/apollo-total-funding.field.ts
|
||||
import {
|
||||
defineField,
|
||||
FieldType,
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
|
||||
} from 'twenty-sdk';
|
||||
|
||||
export default defineField({
|
||||
universalIdentifier: 'c90ae72d-4ddf-4f22-882f-eef98c91e40e',
|
||||
objectUniversalIdentifier:
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
|
||||
type: FieldType.CURRENCY,
|
||||
name: 'apolloTotalFunding',
|
||||
label: 'Total Funding',
|
||||
description: 'Total funding raised by the company',
|
||||
icon: 'IconCash',
|
||||
});
|
||||
```
|
||||
|
||||
关键点:
|
||||
|
||||
* `objectUniversalIdentifier` tells Twenty which object to attach the field to. Use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.<objectName>.universalIdentifier` for standard objects.
|
||||
* Each field requires its own stable `universalIdentifier`, a `name`, `type`, `label`, and the target `objectUniversalIdentifier`.
|
||||
* You can scaffold new fields using `yarn twenty entity:add` and choosing the field option.
|
||||
* `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` is also exported as `STANDARD_OBJECT` for convenience — both refer to the same constant.
|
||||
|
||||
Available standard objects include: `attachment`, `blocklist`, `calendarChannel`, `calendarEvent`, `calendarEventParticipant`, `company`, `connectedAccount`, `dashboard`, `favorite`, `favoriteFolder`, `message`, `messageChannel`, `messageParticipant`, `messageThread`, `note`, `noteTarget`, `opportunity`, `person`, `task`, `taskTarget`, `timelineActivity`, `workflow`, `workflowAutomatedTrigger`, `workflowRun`, `workflowVersion`, and `workspaceMember`.
|
||||
|
||||
Each standard object also exposes its field identifiers. For example, to reference a specific field on a standard object in role permissions:
|
||||
|
||||
```typescript
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name.universalIdentifier
|
||||
```
|
||||
|
||||
#### Relation fields on existing objects
|
||||
|
||||
You can also define relation fields that link existing objects to your custom objects:
|
||||
|
||||
```typescript
|
||||
// src/fields/people-on-call-recording.field.ts
|
||||
import { defineField, FieldType, RelationType, STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from 'twenty-sdk';
|
||||
import { CALL_RECORDING_OBJECT_UNIVERSAL_IDENTIFIER } from 'src/objects/call-recording';
|
||||
import { CALL_RECORDING_ON_PERSON_ID } from 'src/fields/call-recording-on-person.field';
|
||||
|
||||
export default defineField({
|
||||
universalIdentifier: '4a2b3c4d-5e6f-7a8b-9c0d-1e2f3a4b5c6d',
|
||||
objectUniversalIdentifier:
|
||||
CALL_RECORDING_OBJECT_UNIVERSAL_IDENTIFIER,
|
||||
type: FieldType.RELATION,
|
||||
name: 'person',
|
||||
label: 'Person',
|
||||
relationTargetObjectMetadataUniversalIdentifier:
|
||||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.person.universalIdentifier,
|
||||
relationTargetFieldMetadataUniversalIdentifier:
|
||||
CALL_RECORDING_ON_PERSON_ID,
|
||||
relationType: RelationType.MANY_TO_ONE,
|
||||
});
|
||||
```
|
||||
|
||||
### 应用配置(application-config.ts)
|
||||
|
||||
每个应用都有一个 `application-config.ts` 文件,用于描述:
|
||||
@@ -434,7 +500,7 @@ export default defineRole({
|
||||
// src/app/createPostCard.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import type { DatabaseEventPayload, ObjectRecordCreateEvent, CronPayload, RoutePayload } from 'twenty-sdk';
|
||||
import { CoreApiClient, type Person } from 'twenty-sdk/generated';
|
||||
import { CoreApiClient, type Person } from 'twenty-sdk/clients';
|
||||
|
||||
const handler = async (params: RoutePayload) => {
|
||||
const client = new CoreApiClient();
|
||||
@@ -679,7 +745,7 @@ const handler = async (event: RoutePayload) => {
|
||||
```typescript
|
||||
// src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk';
|
||||
import { CoreApiClient } from 'twenty-sdk/generated';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const handler = async (params: { companyName: string; domain?: string }) => {
|
||||
const client = new CoreApiClient();
|
||||
@@ -808,7 +874,7 @@ You can create new skills in two ways:
|
||||
|
||||
### 代理
|
||||
|
||||
Agents define AI agents with system prompts that can operate within your workspace. Use `defineAgent()` to define agents with built-in validation:
|
||||
Agents 通过系统提示词定义可在你的工作区内运行的 AI 智能体。 使用 `defineAgent()` 以内置校验定义智能体:
|
||||
|
||||
```typescript
|
||||
// src/agents/example-agent.ts
|
||||
@@ -830,26 +896,27 @@ export default defineAgent({
|
||||
|
||||
关键点:
|
||||
|
||||
* `name` is a unique identifier string for the agent (kebab-case recommended).
|
||||
* `label` is the human-readable display name shown in the UI.
|
||||
* `prompt` contains the system prompt — this is the instruction text that defines the agent's behavior.
|
||||
* `icon` (optional) sets the icon displayed in the UI.
|
||||
* `description` (optional) provides additional context about the agent's purpose.
|
||||
* `name` 是该智能体的唯一标识字符串(推荐使用 kebab-case)。
|
||||
* `label` 是在 UI 中显示的人类可读名称。
|
||||
* `prompt` 包含系统提示词—这是定义智能体行为的指令文本。
|
||||
* `icon`(可选)设置在 UI 中显示的图标。
|
||||
* `description`(可选)提供有关智能体用途的更多上下文。
|
||||
|
||||
You can create new agents in two ways:
|
||||
你可以通过两种方式创建新智能体:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty entity:add` and choose the option to add a new agent.
|
||||
* **Manual**: Create a new file and use `defineAgent()`, following the same pattern.
|
||||
* **脚手架生成**:运行 `yarn twenty entity:add` 并选择添加新智能体的选项。
|
||||
* **手动**:创建一个新文件,并使用 `defineAgent()`,遵循相同的模式。
|
||||
|
||||
### 生成的类型化客户端
|
||||
|
||||
两个类型化客户端由 `yarn twenty app:dev` 自动生成(基于你的工作区架构),并存放在 `node_modules/twenty-sdk/generated`:
|
||||
两个类型化客户端由 `yarn twenty app:dev` 自动生成(基于你的工作区架构),并存放在 `node_modules/twenty-sdk/clients`:
|
||||
|
||||
* **`CoreApiClient`** — 查询 `/graphql` 端点以获取工作区数据
|
||||
* **`MetadataApiClient`** — 查询 `/metadata` 端点以获取工作区配置并处理文件上传
|
||||
|
||||
```typescript
|
||||
import { CoreApiClient, MetadataApiClient } from 'twenty-sdk/generated';
|
||||
import { CoreApiClient } from 'twenty-sdk/clients';
|
||||
import { MetadataApiClient } from 'twenty-sdk/clients';
|
||||
|
||||
const client = new CoreApiClient();
|
||||
const { me } = await client.query({ me: { id: true, displayName: true } });
|
||||
@@ -858,7 +925,7 @@ const metadataClient = new MetadataApiClient();
|
||||
const { currentWorkspace } = await metadataClient.query({ currentWorkspace: { id: true } });
|
||||
```
|
||||
|
||||
每当你的对象或字段发生变化时,`yarn twenty app:dev` 都会自动重新生成这两个客户端。
|
||||
每当你的对象或字段发生变化时,`yarn twenty app:dev` 都会自动重新生成 `CoreApiClient`。 `MetadataApiClient` 随 SDK 一并提供,已预构建。
|
||||
|
||||
#### 逻辑函数中的运行时凭据
|
||||
|
||||
@@ -875,10 +942,10 @@ const { currentWorkspace } = await metadataClient.query({ currentWorkspace: { id
|
||||
|
||||
#### 上传文件
|
||||
|
||||
生成的 `MetadataApiClient` 包含一个 `uploadFile` 方法,用于将文件附加到你的工作区对象的文件类型字段。 由于标准 GraphQL 客户端不原生支持多部分文件上传,该客户端提供了一个专用方法,在底层实现了 [GraphQL 多部分请求规范](https://github.com/jaydenseric/graphql-multipart-request-spec)。
|
||||
`MetadataApiClient` 包含一个 `uploadFile` 方法,用于将文件附加到你的工作区对象的文件类型字段。 由于标准 GraphQL 客户端不原生支持多部分文件上传,该客户端提供了一个专用方法,在底层实现了 [GraphQL 多部分请求规范](https://github.com/jaydenseric/graphql-multipart-request-spec)。
|
||||
|
||||
```typescript
|
||||
import { MetadataApiClient } from 'twenty-sdk/generated';
|
||||
import { MetadataApiClient } from 'twenty-sdk/clients';
|
||||
import * as fs from 'fs';
|
||||
|
||||
const metadataClient = new MetadataApiClient();
|
||||
|
||||
Reference in New Issue
Block a user