i18n - docs translations (#19119)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
committed by
GitHub
parent
cb85a1b5a3
commit
107914b437
@@ -15,21 +15,21 @@ Il pacchetto twenty-sdk fornisce blocchi tipizzati e funzioni helper da usare ne
|
||||
|
||||
L'SDK fornisce funzioni helper per definire le entità della tua app. Come descritto in [Rilevamento delle entità](/l/it/developers/extend/apps/getting-started#entity-detection), devi usare `export default define<Entity>({...})` affinché le tue entità vengano rilevate:
|
||||
|
||||
| Funzione | Scopo |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `defineApplication` | Configura i metadati dell'applicazione (obbligatorio, uno per app) |
|
||||
| `defineObject` | Definisci oggetti personalizzati con campi |
|
||||
| `defineField` | Extend existing objects with additional fields or define standalone relation fields |
|
||||
| `defineLogicFunction` | Definisci funzioni logiche con handler |
|
||||
| `definePreInstallLogicFunction` | Definisci una funzione logica di pre-installazione (una per app) |
|
||||
| `definePostInstallLogicFunction` | Definisci una funzione logica di post-installazione (una per app) |
|
||||
| `defineFrontComponent` | Definisci componenti front-end per un'interfaccia utente personalizzata |
|
||||
| `defineRole` | Configura i permessi dei ruoli e l'accesso agli oggetti |
|
||||
| `defineView` | Definisci viste salvate per gli oggetti |
|
||||
| `defineNavigationMenuItem` | Definisci i link di navigazione della barra laterale |
|
||||
| `defineSkill` | Definisci le competenze dell'agente IA |
|
||||
| `defineAgent` | Define AI agents |
|
||||
| `definePageLayout` | Define custom page layouts |
|
||||
| Funzione | Scopo |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `defineApplication` | Configura i metadati dell'applicazione (obbligatorio, uno per app) |
|
||||
| `defineObject` | Definisci oggetti personalizzati con campi |
|
||||
| `defineField` | Estendi gli oggetti esistenti con campi aggiuntivi oppure definisci campi di relazione autonomi |
|
||||
| `defineLogicFunction` | Definisci funzioni logiche con handler |
|
||||
| `definePreInstallLogicFunction` | Definisci una funzione logica di pre-installazione (una per app) |
|
||||
| `definePostInstallLogicFunction` | Definisci una funzione logica di post-installazione (una per app) |
|
||||
| `defineFrontComponent` | Definisci componenti front-end per un'interfaccia utente personalizzata |
|
||||
| `defineRole` | Configura i permessi dei ruoli e l'accesso agli oggetti |
|
||||
| `defineView` | Definisci viste salvate per gli oggetti |
|
||||
| `defineNavigationMenuItem` | Definisci i link di navigazione della barra laterale |
|
||||
| `defineSkill` | Definisci le competenze dell'agente IA |
|
||||
| `defineAgent` | Definisci gli agenti IA |
|
||||
| `definePageLayout` | Definisci layout di pagina personalizzati |
|
||||
|
||||
Queste funzioni convalidano la configurazione in fase di build e offrono il completamento automatico nell'IDE e la sicurezza dei tipi.
|
||||
|
||||
@@ -112,7 +112,7 @@ Punti chiave:
|
||||
* Il `universalIdentifier` deve essere univoco e stabile tra i deployment.
|
||||
* Ogni campo richiede un `name`, `type`, `label` e il proprio `universalIdentifier` stabile.
|
||||
* L'array `fields` è facoltativo: puoi definire oggetti senza campi personalizzati.
|
||||
* You can scaffold new objects using `yarn twenty add`, which guides you through naming, fields, and relationships.
|
||||
* Puoi generare nuovi oggetti con `yarn twenty add`, che ti guida nella denominazione, nei campi e nelle relazioni.
|
||||
|
||||
<Note>
|
||||
**I campi base vengono creati automaticamente.** Quando definisci un oggetto personalizzato, Twenty aggiunge automaticamente i campi standard
|
||||
@@ -124,7 +124,7 @@ ma non è consigliato.
|
||||
|
||||
### Definire campi sugli oggetti esistenti
|
||||
|
||||
Use `defineField()` to add fields to objects you don't own — such as standard Twenty objects (Person, Company, etc.) or objects from other apps. Unlike inline fields in `defineObject()`, standalone fields require an `objectUniversalIdentifier` to specify which object they extend:
|
||||
Usa `defineField()` per aggiungere campi a oggetti che non possiedi — come gli oggetti standard di Twenty (Person, Company, ecc.) o oggetti di altre app. A differenza dei campi inline in `defineObject()`, i campi autonomi richiedono un `objectUniversalIdentifier` per specificare quale oggetto estendono:
|
||||
|
||||
```typescript
|
||||
// src/fields/company-loyalty-tier.field.ts
|
||||
@@ -147,35 +147,35 @@ export default defineField({
|
||||
|
||||
Punti chiave:
|
||||
|
||||
* `objectUniversalIdentifier` identifies the target object. For standard objects, use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` exported from `twenty-sdk`.
|
||||
* When defining fields inline in `defineObject()`, you do **not** need `objectUniversalIdentifier` — it's inherited from the parent object.
|
||||
* `defineField()` is the only way to add fields to objects you didn't create with `defineObject()`.
|
||||
* `objectUniversalIdentifier` identifica l'oggetto di destinazione. Per gli oggetti standard, usa `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` esportati da `twenty-sdk`.
|
||||
* Quando definisci campi inline in `defineObject()`, **non** hai bisogno di `objectUniversalIdentifier` — viene ereditato dall'oggetto padre.
|
||||
* `defineField()` è l'unico modo per aggiungere campi a oggetti che non hai creato con `defineObject()`.
|
||||
|
||||
### Relazioni
|
||||
|
||||
Relations connect objects together. In Twenty, relations are always **bidirectional** — you define both sides, and each side references the other.
|
||||
Le relazioni collegano gli oggetti tra loro. In Twenty, le relazioni sono sempre **bidirezionali** — definisci entrambi i lati e ciascun lato fa riferimento all'altro.
|
||||
|
||||
There are two relation types:
|
||||
Esistono due tipi di relazione:
|
||||
|
||||
| Tipo di relazione | Descrizione | Has foreign key? |
|
||||
| ----------------- | ------------------------------------------------------------- | ---------------------- |
|
||||
| `MANY_TO_ONE` | Many records of this object point to one record of the target | Yes (`joinColumnName`) |
|
||||
| `ONE_TO_MANY` | One record of this object has many records of the target | No (inverse side) |
|
||||
| Tipo di relazione | Descrizione | Ha una chiave esterna? |
|
||||
| ----------------- | --------------------------------------------------------------------- | ---------------------- |
|
||||
| `MANY_TO_ONE` | Molti record di questo oggetto puntano a un record della destinazione | Sì (`joinColumnName`) |
|
||||
| `ONE_TO_MANY` | Un record di questo oggetto ha molti record della destinazione | No (lato inverso) |
|
||||
|
||||
#### How relations work
|
||||
#### Come funzionano le relazioni
|
||||
|
||||
Every relation requires **two fields** that reference each other:
|
||||
Ogni relazione richiede **due campi** che fanno riferimento l'uno all'altro:
|
||||
|
||||
1. The **MANY_TO_ONE** side — lives on the object that holds the foreign key
|
||||
2. The **ONE_TO_MANY** side — lives on the object that owns the collection
|
||||
1. Il lato **MANY_TO_ONE** — risiede sull'oggetto che detiene la chiave esterna
|
||||
2. Il lato **ONE_TO_MANY** — risiede sull'oggetto che possiede la collezione
|
||||
|
||||
Both fields use `FieldType.RELATION` and cross-reference each other via `relationTargetFieldMetadataUniversalIdentifier`.
|
||||
Entrambi i campi usano `FieldType.RELATION` e si riferiscono reciprocamente tramite `relationTargetFieldMetadataUniversalIdentifier`.
|
||||
|
||||
#### Example: Post Card has many Recipients
|
||||
#### Esempio: Post Card ha molti destinatari
|
||||
|
||||
Suppose a `PostCard` can be sent to many `PostCardRecipient` records. Each recipient belongs to exactly one post card.
|
||||
Supponiamo che un `PostCard` possa essere inviato a molti record `PostCardRecipient`. Ogni destinatario appartiene esattamente a una sola cartolina.
|
||||
|
||||
**Step 1: Define the ONE_TO_MANY side on PostCard** (the "one" side):
|
||||
**Passaggio 1: definisci il lato ONE_TO_MANY su PostCard** (il lato "uno"):
|
||||
|
||||
```typescript
|
||||
// src/fields/post-card-recipients-on-post-card.field.ts
|
||||
@@ -203,7 +203,7 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Define the MANY_TO_ONE side on PostCardRecipient** (the "many" side — holds the foreign key):
|
||||
**Passaggio 2: definisci il lato MANY_TO_ONE su PostCardRecipient** (il lato "molti" — contiene la chiave esterna):
|
||||
|
||||
```typescript
|
||||
// src/fields/post-card-on-post-card-recipient.field.ts
|
||||
@@ -234,12 +234,12 @@ export default defineField({
|
||||
```
|
||||
|
||||
<Note>
|
||||
**Circular imports:** Both relation fields reference each other's `universalIdentifier`. To avoid circular import issues, export your field IDs as named constants from each file, and import them in the other file. The build system resolves these at compile time.
|
||||
**Importazioni circolari:** Entrambi i campi di relazione fanno riferimento all'`universalIdentifier` dell'altro. Per evitare problemi di importazioni circolari, esporta gli ID dei campi come costanti denominate da ciascun file e importale nell'altro file. Il sistema di build le risolve in fase di compilazione.
|
||||
</Note>
|
||||
|
||||
#### Relating to standard objects
|
||||
#### Relazioni con gli oggetti standard
|
||||
|
||||
To create a relation with a built-in Twenty object (Person, Company, etc.), use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`:
|
||||
Per creare una relazione con un oggetto Twenty integrato (Person, Company, ecc.), usa `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`:
|
||||
|
||||
```typescript
|
||||
// src/fields/person-on-self-hosting-user.field.ts
|
||||
@@ -274,20 +274,20 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
#### Relation field properties
|
||||
#### Proprietà dei campi di relazione
|
||||
|
||||
| Proprietà | Obbligatorio | Descrizione |
|
||||
| ------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `tipo` | Sì | Must be `FieldType.RELATION` |
|
||||
| `relationTargetObjectMetadataUniversalIdentifier` | Sì | The `universalIdentifier` of the target object |
|
||||
| `relationTargetFieldMetadataUniversalIdentifier` | Sì | The `universalIdentifier` of the matching field on the target object |
|
||||
| `universalSettings.relationType` | Sì | `RelationType.MANY_TO_ONE` or `RelationType.ONE_TO_MANY` |
|
||||
| `universalSettings.onDelete` | MANY_TO_ONE only | What happens when the referenced record is deleted: `CASCADE`, `SET_NULL`, `RESTRICT`, or `NO_ACTION` |
|
||||
| `universalSettings.joinColumnName` | MANY_TO_ONE only | Database column name for the foreign key (e.g., `postCardId`) |
|
||||
| Proprietà | Obbligatorio | Descrizione |
|
||||
| ------------------------------------------------- | ---------------- | ---------------------------------------------------------------------------------------------------------- |
|
||||
| `tipo` | Sì | Deve essere `FieldType.RELATION` |
|
||||
| `relationTargetObjectMetadataUniversalIdentifier` | Sì | L'`universalIdentifier` dell'oggetto di destinazione |
|
||||
| `relationTargetFieldMetadataUniversalIdentifier` | Sì | L'`universalIdentifier` del campo corrispondente sull'oggetto di destinazione |
|
||||
| `universalSettings.relationType` | Sì | `RelationType.MANY_TO_ONE` or `RelationType.ONE_TO_MANY` |
|
||||
| `universalSettings.onDelete` | Solo MANY_TO_ONE | Cosa accade quando il record referenziato viene eliminato: `CASCADE`, `SET_NULL`, `RESTRICT` o `NO_ACTION` |
|
||||
| `universalSettings.joinColumnName` | Solo MANY_TO_ONE | Nome della colonna del database per la chiave esterna (ad es., `postCardId`) |
|
||||
|
||||
#### Inline relation fields in defineObject
|
||||
#### Campi di relazione inline in defineObject
|
||||
|
||||
You can also define relation fields directly inside `defineObject()`. In that case, omit `objectUniversalIdentifier` — it's inherited from the parent object:
|
||||
Puoi anche definire i campi di relazione direttamente all'interno di `defineObject()`. In tal caso, ometti `objectUniversalIdentifier` — viene ereditato dall'oggetto padre:
|
||||
|
||||
```typescript
|
||||
export default defineObject({
|
||||
@@ -354,21 +354,21 @@ Note:
|
||||
* `defaultRoleUniversalIdentifier` deve corrispondere al file del ruolo (vedi sotto).
|
||||
* Le funzioni di pre-installazione e post-installazione vengono rilevate automaticamente durante la build del manifesto. Vedi [Funzioni di pre-installazione](#pre-install-functions) e [Funzioni di post-installazione](#post-install-functions).
|
||||
|
||||
#### Marketplace metadata
|
||||
#### Metadati del marketplace
|
||||
|
||||
If you plan to [publish your app](/l/it/developers/extend/apps/publishing), these optional fields control how your app appears in the marketplace:
|
||||
Se prevedi di [pubblicare la tua app](/l/it/developers/extend/apps/publishing), questi campi opzionali controllano come la tua app appare nel marketplace:
|
||||
|
||||
| Campo | Descrizione |
|
||||
| ------------------ | --------------------------------------------------- |
|
||||
| `autore` | Author or company name |
|
||||
| `categoria` | App category for marketplace filtering |
|
||||
| `logoUrl` | Path to your app logo (relative to `./assets/`) |
|
||||
| `screenshots` | Array of screenshot paths (relative to `./assets/`) |
|
||||
| `aboutDescription` | Longer markdown description for the "About" tab |
|
||||
| `websiteUrl` | Link to your website |
|
||||
| `termsUrl` | Link to terms of service |
|
||||
| `emailSupport` | Support email address |
|
||||
| `issueReportUrl` | Link to issue tracker |
|
||||
| Campo | Descrizione |
|
||||
| ------------------ | ----------------------------------------------------------- |
|
||||
| `autore` | Nome dell'autore o dell'azienda |
|
||||
| `categoria` | Categoria dell'app per il filtraggio nel marketplace |
|
||||
| `logoUrl` | Percorso del logo della tua app (relativo a `./assets/`) |
|
||||
| `screenshots` | Array di percorsi degli screenshot (relativi a `./assets/`) |
|
||||
| `aboutDescription` | Descrizione markdown più lunga per la scheda "Informazioni" |
|
||||
| `websiteUrl` | Link al tuo sito web |
|
||||
| `termsUrl` | Link ai Termini di servizio |
|
||||
| `emailSupport` | Indirizzo email di supporto |
|
||||
| `issueReportUrl` | Link al sistema di tracciamento dei problemi |
|
||||
|
||||
#### Ruoli e permessi
|
||||
|
||||
@@ -376,7 +376,7 @@ Le applicazioni possono definire ruoli che incapsulano i permessi sugli oggetti
|
||||
|
||||
* La chiave API di runtime iniettata come `TWENTY_API_KEY` è derivata da questo ruolo funzione predefinito.
|
||||
* Il client tipizzato sarà limitato ai permessi concessi a quel ruolo.
|
||||
* Follow least-privilege: create a dedicated role with only the permissions your functions need, then reference its universal identifier.
|
||||
* Segui il principio del privilegio minimo: crea un ruolo dedicato con solo i permessi necessari alle tue funzioni, quindi fai riferimento al suo identificatore universale.
|
||||
|
||||
##### Ruolo funzione predefinito (*.role.ts)
|
||||
|
||||
@@ -429,7 +429,7 @@ L'`universalIdentifier` di questo ruolo viene quindi referenziato in `applicatio
|
||||
|
||||
Note:
|
||||
|
||||
* Start from the scaffolded role, then progressively restrict it following least-privilege.
|
||||
* Parti dal ruolo generato dallo scaffolder, quindi restringilo progressivamente seguendo il principio del privilegio minimo.
|
||||
* Sostituisci `objectPermissions` e `fieldPermissions` con gli oggetti/campi di cui le tue funzioni hanno bisogno.
|
||||
* `permissionFlags` controllano l'accesso alle funzionalità a livello di piattaforma. Mantienili al minimo; aggiungi solo ciò che ti serve.
|
||||
* Vedi un esempio funzionante nell'app Hello World: [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
|
||||
@@ -543,7 +543,7 @@ Punti chiave:
|
||||
* È consentita una sola funzione di pre-installazione per applicazione. La build del manifesto genererà un errore se ne viene rilevata più di una.
|
||||
* L'`universalIdentifier` della funzione viene impostato automaticamente come `preInstallLogicFunctionUniversalIdentifier` nel manifesto dell'applicazione durante la build — non è necessario farvi riferimento in `defineApplication()`.
|
||||
* Il timeout predefinito è impostato a 300 secondi (5 minuti) per consentire attività di preparazione più lunghe.
|
||||
* Pre-install functions do not need triggers — they are invoked by the platform before installation or manually via `exec --preInstall`.
|
||||
* Le funzioni di pre-installazione non necessitano di trigger — vengono invocate dalla piattaforma prima dell'installazione o manualmente tramite `exec --preInstall`.
|
||||
|
||||
### Funzioni post-installazione
|
||||
|
||||
@@ -581,7 +581,7 @@ Punti chiave:
|
||||
* È consentita una sola funzione di post-installazione per applicazione. La build del manifesto genererà un errore se ne viene rilevata più di una.
|
||||
* L'`universalIdentifier` della funzione viene impostato automaticamente come `postInstallLogicFunctionUniversalIdentifier` nel manifesto dell'applicazione durante la build — non è necessario farvi riferimento in `defineApplication()`.
|
||||
* Il timeout predefinito è impostato a 300 secondi (5 minuti) per consentire attività di configurazione più lunghe, come il popolamento dei dati.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `exec --postInstall`.
|
||||
* Le funzioni di post-installazione non necessitano di trigger — vengono invocate dalla piattaforma durante l'installazione o manualmente tramite `exec --postInstall`.
|
||||
|
||||
### Payload del trigger di route
|
||||
|
||||
@@ -625,15 +625,15 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Il tipo `RoutePayload` ha la seguente struttura:
|
||||
|
||||
| Proprietà | Tipo | Descrizione |
|
||||
| ---------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| `headers` | `Record<string, string \| undefined>` | Intestazioni HTTP (solo quelle elencate in `forwardedRequestHeaders`) |
|
||||
| `queryStringParameters` | `Record<string, string \| undefined>` | Parametri della query string (valori multipli uniti da virgole) |
|
||||
| `pathParameters` | `Record<string, string \| undefined>` | Path parameters extracted from the route pattern (e.g., `/users/:id` -> `{ id: '123' }`) |
|
||||
| `body` | `object \| null` | Corpo della richiesta analizzato (JSON) |
|
||||
| `isBase64Encoded` | `boolean` | Indica se il corpo è codificato in base64 |
|
||||
| `requestContext.http.method` | `string` | Metodo HTTP (GET, POST, PUT, PATCH, DELETE) |
|
||||
| `requestContext.http.path` | `string` | Percorso della richiesta non elaborato |
|
||||
| Proprietà | Tipo | Descrizione |
|
||||
| ---------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| `headers` | `Record<string, string \| undefined>` | Intestazioni HTTP (solo quelle elencate in `forwardedRequestHeaders`) |
|
||||
| `queryStringParameters` | `Record<string, string \| undefined>` | Parametri della query string (valori multipli uniti da virgole) |
|
||||
| `pathParameters` | `Record<string, string \| undefined>` | Parametri di percorso estratti dal pattern della route (ad es., `/users/:id` -> `{ id: '123' }`) |
|
||||
| `body` | `object \| null` | Corpo della richiesta analizzato (JSON) |
|
||||
| `isBase64Encoded` | `boolean` | Indica se il corpo è codificato in base64 |
|
||||
| `requestContext.http.method` | `string` | Metodo HTTP (GET, POST, PUT, PATCH, DELETE) |
|
||||
| `requestContext.http.path` | `string` | Percorso della richiesta non elaborato |
|
||||
|
||||
### Inoltro delle intestazioni HTTP
|
||||
|
||||
@@ -675,7 +675,7 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Puoi creare nuove funzioni in due modi:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new logic function. Questo genera un file iniziale con un handler e una configurazione.
|
||||
* **Generata dallo scaffolder**: Esegui `yarn twenty add` e scegli l'opzione per aggiungere una nuova funzione logica. Questo genera un file iniziale con un handler e una configurazione.
|
||||
* **Manuale**: Crea un nuovo file `*.logic-function.ts` e usa `defineLogicFunction()`, seguendo lo stesso schema.
|
||||
|
||||
### Contrassegnare una funzione logica come strumento
|
||||
@@ -776,7 +776,7 @@ Punti chiave:
|
||||
|
||||
Puoi creare nuovi componenti front-end in due modi:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new front component.
|
||||
* **Generata dallo scaffolder**: Esegui `yarn twenty add` e scegli l'opzione per aggiungere un nuovo componente front-end.
|
||||
* **Manuale**: Crea un nuovo file `.tsx` e usa `defineFrontComponent()`, seguendo lo stesso schema.
|
||||
|
||||
### Abilità
|
||||
@@ -811,21 +811,21 @@ Punti chiave:
|
||||
|
||||
Puoi creare nuove skill in due modi:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new skill.
|
||||
* **Generata dallo scaffolder**: Esegui `yarn twenty add` e scegli l'opzione per aggiungere una nuova skill.
|
||||
* **Manuale**: Crea un nuovo file e usa `defineSkill()`, seguendo lo stesso schema.
|
||||
|
||||
### Typed API clients (`twenty-client-sdk`)
|
||||
### Client API tipizzati (`twenty-client-sdk`)
|
||||
|
||||
The `twenty-client-sdk` package provides two typed GraphQL clients for interacting with the Twenty API from your logic functions and front components:
|
||||
Il pacchetto `twenty-client-sdk` fornisce due client GraphQL tipizzati per interagire con l'API di Twenty dalle tue funzioni logiche e dai componenti front-end:
|
||||
|
||||
| Client | Importa | Endpoint | Generated? |
|
||||
| ------------------- | ---------------------------- | ---------------------------------------------- | ---------------------- |
|
||||
| `CoreApiClient` | `twenty-client-sdk/core` | `/graphql` — workspace data (records, objects) | Yes, at dev/build time |
|
||||
| `MetadataApiClient` | `twenty-client-sdk/metadata` | `/metadata` — workspace config, file uploads | No, ships pre-built |
|
||||
| Client | Importa | Endpoint | Generato? |
|
||||
| ------------------- | ---------------------------- | ------------------------------------------------------------------------ | -------------------------- |
|
||||
| `CoreApiClient` | `twenty-client-sdk/core` | `/graphql` — dati dello spazio di lavoro (record, oggetti) | Sì, in fase di dev/build |
|
||||
| `MetadataApiClient` | `twenty-client-sdk/metadata` | `/metadata` — configurazione dello spazio di lavoro, caricamenti di file | No, fornito pronto all'uso |
|
||||
|
||||
#### CoreApiClient
|
||||
|
||||
`CoreApiClient` is the main client for querying and mutating workspace data. It is **generated from your workspace schema** during `yarn twenty dev` or `yarn twenty build`, so it's fully typed to match your objects and fields.
|
||||
`CoreApiClient` è il client principale per interrogare e modificare i dati dello spazio di lavoro. Viene **generato dallo schema del tuo spazio di lavoro** durante `yarn twenty dev` o `yarn twenty build`, quindi è completamente tipizzato per corrispondere ai tuoi oggetti e campi.
|
||||
|
||||
```typescript
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
@@ -859,15 +859,15 @@ const { createCompany } = await client.mutation({
|
||||
});
|
||||
```
|
||||
|
||||
The client uses a selection-set syntax: pass `true` to include a field, use `__args` for arguments, and nest objects for relations. You get full autocompletion and type checking based on your workspace schema.
|
||||
Il client utilizza una sintassi a selection-set: passa `true` per includere un campo, usa `__args` per gli argomenti e annida oggetti per le relazioni. Ottieni completamento automatico e controllo dei tipi completi basati sullo schema del tuo spazio di lavoro.
|
||||
|
||||
<Note>
|
||||
**CoreApiClient is generated at dev/build time.** If you try to use it without running `yarn twenty dev` or `yarn twenty build` first, it throws an error. The generation happens automatically — the CLI introspects your workspace's GraphQL schema, generates a typed client using `@genql/cli`, writes the generated sources to `node_modules/twenty-client-sdk/dist/core/generated/`, and replaces the stubs in `node_modules/twenty-client-sdk/dist/core.mjs` and `node_modules/twenty-client-sdk/dist/core.cjs`.
|
||||
**CoreApiClient viene generato in fase di dev/build.** Se provi a usarlo senza eseguire prima `yarn twenty dev` o `yarn twenty build`, genererà un errore. La generazione avviene automaticamente — la CLI esegue l'introspezione dello schema GraphQL del tuo spazio di lavoro, genera un client tipizzato usando `@genql/cli`, scrive le sorgenti generate in `node_modules/twenty-client-sdk/dist/core/generated/` e sostituisce gli stub in `node_modules/twenty-client-sdk/dist/core.mjs` e `node_modules/twenty-client-sdk/dist/core.cjs`.
|
||||
</Note>
|
||||
|
||||
#### Using CoreSchema for type annotations
|
||||
#### Utilizzo di CoreSchema per le annotazioni di tipo
|
||||
|
||||
`CoreSchema` provides TypeScript types matching your workspace objects, useful for typing component state or function parameters:
|
||||
`CoreSchema` fornisce tipi TypeScript corrispondenti agli oggetti del tuo spazio di lavoro, utili per tipizzare lo stato dei componenti o i parametri delle funzioni:
|
||||
|
||||
```typescript
|
||||
import { CoreApiClient, CoreSchema } from 'twenty-client-sdk/core';
|
||||
@@ -890,7 +890,7 @@ setCompany(result.company);
|
||||
|
||||
#### MetadataApiClient
|
||||
|
||||
`MetadataApiClient` ships pre-built with the SDK (no generation required). It queries the `/metadata` endpoint for workspace configuration, applications, and file uploads:
|
||||
`MetadataApiClient` è fornito pronto all'uso con l'SDK (nessuna generazione richiesta). Interroga l'endpoint `/metadata` per la configurazione dello spazio di lavoro, le applicazioni e i caricamenti di file:
|
||||
|
||||
```typescript
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -912,18 +912,18 @@ const { findManyApplications } = await metadataClient.query({
|
||||
});
|
||||
```
|
||||
|
||||
#### Runtime credentials
|
||||
#### Credenziali di runtime
|
||||
|
||||
When your code runs on Twenty (logic functions or front components), the platform injects credentials as environment variables:
|
||||
Quando il tuo codice viene eseguito su Twenty (funzioni logiche o componenti front-end), la piattaforma inietta le credenziali come variabili d'ambiente:
|
||||
|
||||
* `TWENTY_API_URL` — Base URL of the Twenty API
|
||||
* `TWENTY_API_KEY` — Short-lived key scoped to your application's default function role
|
||||
* `TWENTY_API_URL` — URL di base dell'API di Twenty
|
||||
* `TWENTY_API_KEY` — Chiave a breve durata con ambito al ruolo funzione predefinito della tua applicazione
|
||||
|
||||
You do **not** need to pass these to the clients — they read from `process.env` automatically. The API key's permissions are determined by the role referenced in `defaultRoleUniversalIdentifier` in your `application-config.ts`.
|
||||
Non è **necessario** passarle ai client — vengono lette automaticamente da `process.env`. I permessi della chiave API sono determinati dal ruolo referenziato in `defaultRoleUniversalIdentifier` nel tuo `application-config.ts`.
|
||||
|
||||
#### Caricamento dei file
|
||||
|
||||
`MetadataApiClient` includes an `uploadFile` method for attaching files to file-type fields. It implements the [GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec):
|
||||
`MetadataApiClient` include un metodo `uploadFile` per allegare file ai campi di tipo file. Implementa la [specifica delle richieste GraphQL multipart](https://github.com/jaydenseric/graphql-multipart-request-spec):
|
||||
|
||||
```typescript
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -953,7 +953,7 @@ console.log(uploadedFile);
|
||||
|
||||
Punti chiave:
|
||||
|
||||
* Uses the field's `universalIdentifier` (not its workspace-specific ID), so your upload code works across any workspace where your app is installed.
|
||||
* Usa l'`universalIdentifier` del campo (non il suo ID specifico dello spazio di lavoro), quindi il tuo codice di upload funziona in qualsiasi spazio di lavoro in cui la tua app è installata.
|
||||
* L'`url` restituito è un URL firmato che puoi usare per accedere al file caricato.
|
||||
|
||||
### Esempio Hello World
|
||||
|
||||
@@ -15,21 +15,21 @@ Biblioteca twenty-sdk oferă blocuri de bază tipizate și funcții ajutătoare
|
||||
|
||||
SDK-ul oferă funcții ajutătoare pentru definirea entităților aplicației. După cum este descris în [Detectarea entităților](/l/ro/developers/extend/apps/getting-started#entity-detection), trebuie să folosiți `export default define<Entity>({...})` pentru ca entitățile să fie detectate:
|
||||
|
||||
| Funcție | Scop |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `defineApplication` | Configurați metadatele aplicației (obligatoriu, una per aplicație) |
|
||||
| `defineObject` | Definiți obiecte personalizate cu câmpuri |
|
||||
| `defineField` | Extend existing objects with additional fields or define standalone relation fields |
|
||||
| `defineLogicFunction` | Definiți funcții de logică cu handleri |
|
||||
| `definePreInstallLogicFunction` | Definește o funcție logică de pre-instalare (una per aplicație) |
|
||||
| `definePostInstallLogicFunction` | Definește o funcție logică post-instalare (una per aplicație) |
|
||||
| `defineFrontComponent` | Definiți componente Front pentru interfața de utilizator personalizată |
|
||||
| `defineRole` | Configurați permisiunile rolurilor și accesul la obiecte |
|
||||
| `defineView` | Definește vizualizări salvate pentru obiecte |
|
||||
| `defineNavigationMenuItem` | Definește linkuri de navigare în bara laterală |
|
||||
| `defineSkill` | Definiți abilități pentru agentul AI |
|
||||
| `defineAgent` | Define AI agents |
|
||||
| `definePageLayout` | Define custom page layouts |
|
||||
| Funcție | Scop |
|
||||
| -------------------------------- | -------------------------------------------------------------------------------------------------- |
|
||||
| `defineApplication` | Configurați metadatele aplicației (obligatoriu, una per aplicație) |
|
||||
| `defineObject` | Definiți obiecte personalizate cu câmpuri |
|
||||
| `defineField` | Extindeți obiectele existente cu câmpuri suplimentare sau definiți câmpuri de relație independente |
|
||||
| `defineLogicFunction` | Definiți funcții de logică cu handleri |
|
||||
| `definePreInstallLogicFunction` | Definește o funcție logică de pre-instalare (una per aplicație) |
|
||||
| `definePostInstallLogicFunction` | Definește o funcție logică post-instalare (una per aplicație) |
|
||||
| `defineFrontComponent` | Definiți componente Front pentru interfața de utilizator personalizată |
|
||||
| `defineRole` | Configurați permisiunile rolurilor și accesul la obiecte |
|
||||
| `defineView` | Definește vizualizări salvate pentru obiecte |
|
||||
| `defineNavigationMenuItem` | Definește linkuri de navigare în bara laterală |
|
||||
| `defineSkill` | Definiți abilități pentru agentul AI |
|
||||
| `defineAgent` | Definiți agenți AI |
|
||||
| `definePageLayout` | Definiți machete de pagină personalizate |
|
||||
|
||||
Aceste funcții validează configurația în timpul build-ului și oferă completare automată în IDE și siguranța tipurilor.
|
||||
|
||||
@@ -112,7 +112,7 @@ Puncte cheie:
|
||||
* `universalIdentifier` trebuie să fie unic și stabil între implementări.
|
||||
* Fiecare câmp necesită un `name`, un `type`, un `label` și propriul `universalIdentifier` stabil.
|
||||
* Matricea `fields` este opțională — puteți defini obiecte fără câmpuri personalizate.
|
||||
* You can scaffold new objects using `yarn twenty add`, which guides you through naming, fields, and relationships.
|
||||
* Puteți genera obiecte noi folosind `yarn twenty add`, care vă ghidează prin denumire, câmpuri și relații.
|
||||
|
||||
<Note>
|
||||
**Câmpurile de bază sunt create automat.** Când definiți un obiect personalizat, Twenty adaugă automat câmpuri standard
|
||||
@@ -124,7 +124,7 @@ dar acest lucru nu este recomandat.
|
||||
|
||||
### Definirea câmpurilor pe obiecte existente
|
||||
|
||||
Use `defineField()` to add fields to objects you don't own — such as standard Twenty objects (Person, Company, etc.) or objects from other apps. Unlike inline fields in `defineObject()`, standalone fields require an `objectUniversalIdentifier` to specify which object they extend:
|
||||
Utilizați `defineField()` pentru a adăuga câmpuri la obiecte pe care nu le dețineți — cum ar fi obiectele standard Twenty (Person, Company etc.). sau obiecte din alte aplicații. Spre deosebire de câmpurile inline din `defineObject()`, câmpurile independente necesită un `objectUniversalIdentifier` pentru a specifica obiectul pe care îl extind:
|
||||
|
||||
```typescript
|
||||
// src/fields/company-loyalty-tier.field.ts
|
||||
@@ -147,35 +147,35 @@ export default defineField({
|
||||
|
||||
Puncte cheie:
|
||||
|
||||
* `objectUniversalIdentifier` identifies the target object. For standard objects, use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` exported from `twenty-sdk`.
|
||||
* When defining fields inline in `defineObject()`, you do **not** need `objectUniversalIdentifier` — it's inherited from the parent object.
|
||||
* `defineField()` is the only way to add fields to objects you didn't create with `defineObject()`.
|
||||
* `objectUniversalIdentifier` identifică obiectul țintă. Pentru obiectele standard, utilizați `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` exportați din `twenty-sdk`.
|
||||
* Atunci când definiți câmpuri inline în `defineObject()`, nu aveți nevoie de `objectUniversalIdentifier` — este moștenit de la obiectul părinte.
|
||||
* `defineField()` este singura modalitate de a adăuga câmpuri la obiecte pe care nu le-ați creat cu `defineObject()`.
|
||||
|
||||
### Relații
|
||||
|
||||
Relations connect objects together. In Twenty, relations are always **bidirectional** — you define both sides, and each side references the other.
|
||||
Relațiile conectează obiectele între ele. În Twenty, relațiile sunt întotdeauna bidirecționale — definiți ambele părți, iar fiecare parte o referențiază pe cealaltă.
|
||||
|
||||
There are two relation types:
|
||||
Există două tipuri de relații:
|
||||
|
||||
| Tip relație | Descriere | Has foreign key? |
|
||||
| ------------- | ------------------------------------------------------------- | ---------------------- |
|
||||
| `MANY_TO_ONE` | Many records of this object point to one record of the target | Yes (`joinColumnName`) |
|
||||
| `ONE_TO_MANY` | One record of this object has many records of the target | No (inverse side) |
|
||||
| Tip relație | Descriere | Are cheie străină? |
|
||||
| ------------- | ---------------------------------------------------------------------------------- | --------------------- |
|
||||
| `MANY_TO_ONE` | Multe înregistrări ale acestui obiect indică către o singură înregistrare a țintei | Da (`joinColumnName`) |
|
||||
| `ONE_TO_MANY` | O înregistrare a acestui obiect are multe înregistrări ale țintei | Nu (partea inversă) |
|
||||
|
||||
#### How relations work
|
||||
#### Cum funcționează relațiile
|
||||
|
||||
Every relation requires **two fields** that reference each other:
|
||||
Fiecare relație necesită **două câmpuri** care se referențiază reciproc:
|
||||
|
||||
1. The **MANY_TO_ONE** side — lives on the object that holds the foreign key
|
||||
2. The **ONE_TO_MANY** side — lives on the object that owns the collection
|
||||
1. Partea **MANY_TO_ONE** — se află pe obiectul care deține cheia străină
|
||||
2. Partea **ONE_TO_MANY** — se află pe obiectul care deține colecția
|
||||
|
||||
Both fields use `FieldType.RELATION` and cross-reference each other via `relationTargetFieldMetadataUniversalIdentifier`.
|
||||
Ambele câmpuri folosesc `FieldType.RELATION` și se referențiază încrucișat prin `relationTargetFieldMetadataUniversalIdentifier`.
|
||||
|
||||
#### Example: Post Card has many Recipients
|
||||
#### Exemplu: Post Card are mulți destinatari
|
||||
|
||||
Suppose a `PostCard` can be sent to many `PostCardRecipient` records. Each recipient belongs to exactly one post card.
|
||||
Presupuneți că un `PostCard` poate fi trimis către multe înregistrări `PostCardRecipient`. Fiecare destinatar aparține exact unui Post Card.
|
||||
|
||||
**Step 1: Define the ONE_TO_MANY side on PostCard** (the "one" side):
|
||||
**Pasul 1: Definiți partea ONE_TO_MANY pe PostCard** (partea "one"):
|
||||
|
||||
```typescript
|
||||
// src/fields/post-card-recipients-on-post-card.field.ts
|
||||
@@ -203,7 +203,7 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Define the MANY_TO_ONE side on PostCardRecipient** (the "many" side — holds the foreign key):
|
||||
**Pasul 2: Definiți partea MANY_TO_ONE pe PostCardRecipient** (partea "many" — deține cheia străină):
|
||||
|
||||
```typescript
|
||||
// src/fields/post-card-on-post-card-recipient.field.ts
|
||||
@@ -234,12 +234,12 @@ export default defineField({
|
||||
```
|
||||
|
||||
<Note>
|
||||
**Circular imports:** Both relation fields reference each other's `universalIdentifier`. To avoid circular import issues, export your field IDs as named constants from each file, and import them in the other file. The build system resolves these at compile time.
|
||||
**Importuri circulare:** Ambele câmpuri de relație se referă unul la celălalt prin `universalIdentifier`. Pentru a evita problemele de import circular, exportați ID-urile câmpurilor ca constante denumite din fiecare fișier și importați-le în celălalt fișier. Sistemul de build le rezolvă în timpul compilării.
|
||||
</Note>
|
||||
|
||||
#### Relating to standard objects
|
||||
#### Relaționarea cu obiectele standard
|
||||
|
||||
To create a relation with a built-in Twenty object (Person, Company, etc.), use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`:
|
||||
Pentru a crea o relație cu un obiect Twenty încorporat (Person, Company etc.), utilizați `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`:
|
||||
|
||||
```typescript
|
||||
// src/fields/person-on-self-hosting-user.field.ts
|
||||
@@ -274,20 +274,20 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
#### Relation field properties
|
||||
#### Proprietăți ale câmpului de relație
|
||||
|
||||
| Proprietate | Obligatoriu | Descriere |
|
||||
| ------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `tip` | Da | Must be `FieldType.RELATION` |
|
||||
| `relationTargetObjectMetadataUniversalIdentifier` | Da | The `universalIdentifier` of the target object |
|
||||
| `relationTargetFieldMetadataUniversalIdentifier` | Da | The `universalIdentifier` of the matching field on the target object |
|
||||
| `universalSettings.relationType` | Da | `RelationType.MANY_TO_ONE` or `RelationType.ONE_TO_MANY` |
|
||||
| `universalSettings.onDelete` | MANY_TO_ONE only | What happens when the referenced record is deleted: `CASCADE`, `SET_NULL`, `RESTRICT`, or `NO_ACTION` |
|
||||
| `universalSettings.joinColumnName` | MANY_TO_ONE only | Database column name for the foreign key (e.g., `postCardId`) |
|
||||
| Proprietate | Obligatoriu | Descriere |
|
||||
| ------------------------------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------- |
|
||||
| `tip` | Da | Trebuie să fie `FieldType.RELATION` |
|
||||
| `relationTargetObjectMetadataUniversalIdentifier` | Da | `universalIdentifier` al obiectului țintă |
|
||||
| `relationTargetFieldMetadataUniversalIdentifier` | Da | `universalIdentifier` al câmpului corespunzător de pe obiectul țintă |
|
||||
| `universalSettings.relationType` | Da | `RelationType.MANY_TO_ONE` sau `RelationType.ONE_TO_MANY` |
|
||||
| `universalSettings.onDelete` | Doar MANY_TO_ONE | Ce se întâmplă atunci când înregistrarea referențiată este ștearsă: `CASCADE`, `SET_NULL`, `RESTRICT` sau `NO_ACTION` |
|
||||
| `universalSettings.joinColumnName` | Doar MANY_TO_ONE | Numele coloanei din baza de date pentru cheia străină (de ex., `postCardId`) |
|
||||
|
||||
#### Inline relation fields in defineObject
|
||||
#### Câmpuri de relație inline în defineObject
|
||||
|
||||
You can also define relation fields directly inside `defineObject()`. In that case, omit `objectUniversalIdentifier` — it's inherited from the parent object:
|
||||
Puteți defini, de asemenea, câmpuri de relație direct în `defineObject()`. În acest caz, omiteți `objectUniversalIdentifier` — este moștenit de la obiectul părinte:
|
||||
|
||||
```typescript
|
||||
export default defineObject({
|
||||
@@ -354,21 +354,21 @@ Notițe:
|
||||
* `defaultRoleUniversalIdentifier` trebuie să corespundă fișierului de rol (vedeți mai jos).
|
||||
* Funcțiile de pre-instalare și post-instalare sunt detectate automat în timpul construirii manifestului. Vezi [Funcții de pre-instalare](#pre-install-functions) și [Funcții post-instalare](#post-install-functions).
|
||||
|
||||
#### Marketplace metadata
|
||||
#### Metadate pentru marketplace
|
||||
|
||||
If you plan to [publish your app](/l/ro/developers/extend/apps/publishing), these optional fields control how your app appears in the marketplace:
|
||||
Dacă intenționați să [publicați aplicația](/l/ro/developers/extend/apps/publishing), aceste câmpuri opționale controlează modul în care aplicația apare în marketplace:
|
||||
|
||||
| Câmp | Descriere |
|
||||
| ------------------ | --------------------------------------------------- |
|
||||
| `autor` | Author or company name |
|
||||
| `categorie` | App category for marketplace filtering |
|
||||
| `logoUrl` | Path to your app logo (relative to `./assets/`) |
|
||||
| `screenshots` | Array of screenshot paths (relative to `./assets/`) |
|
||||
| `aboutDescription` | Longer markdown description for the "About" tab |
|
||||
| `websiteUrl` | Link to your website |
|
||||
| `termsUrl` | Link to terms of service |
|
||||
| `emailSupport` | Support email address |
|
||||
| `issueReportUrl` | Link to issue tracker |
|
||||
| Câmp | Descriere |
|
||||
| ------------------ | ------------------------------------------------------------- |
|
||||
| `autor` | Numele autorului sau al companiei |
|
||||
| `categorie` | Categoria aplicației pentru filtrarea în marketplace |
|
||||
| `logoUrl` | Calea către logo-ul aplicației (relativă la `./assets/`) |
|
||||
| `screenshots` | Listă de căi către capturi de ecran (relative la `./assets/`) |
|
||||
| `aboutDescription` | Descriere markdown mai lungă pentru fila "About" |
|
||||
| `websiteUrl` | Link către site-ul dvs. |
|
||||
| `termsUrl` | Link către termenii de serviciu |
|
||||
| `emailSupport` | Adresă de e-mail pentru suport |
|
||||
| `issueReportUrl` | Link către sistemul de urmărire a problemelor |
|
||||
|
||||
#### Roluri și permisiuni
|
||||
|
||||
@@ -376,7 +376,7 @@ Aplicațiile pot defini roluri care încapsulează permisiuni asupra obiectelor
|
||||
|
||||
* Cheia API de runtime injectată ca `TWENTY_API_KEY` este derivată din acest rol implicit pentru funcții.
|
||||
* Clientul tipizat va fi restricționat la permisiunile acordate acelui rol.
|
||||
* Follow least-privilege: create a dedicated role with only the permissions your functions need, then reference its universal identifier.
|
||||
* Respectați principiul celui mai mic privilegiu: creați un rol dedicat doar cu permisiunile de care au nevoie funcțiile, apoi referiți identificatorul său universal.
|
||||
|
||||
##### Rol implicit pentru funcții (*.role.ts)
|
||||
|
||||
@@ -429,7 +429,7 @@ export default defineRole({
|
||||
|
||||
Notițe:
|
||||
|
||||
* Start from the scaffolded role, then progressively restrict it following least-privilege.
|
||||
* Porniți de la rolul generat, apoi restrângeți-l progresiv urmând principiul celui mai mic privilegiu.
|
||||
* Înlocuiți `objectPermissions` și `fieldPermissions` cu obiectele/câmpurile de care au nevoie funcțiile.
|
||||
* `permissionFlags` controlează accesul la capabilități la nivelul platformei. Mențineți-le la minimum; adăugați doar ceea ce aveți nevoie.
|
||||
* Vedeți un exemplu funcțional în aplicația Hello World: [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
|
||||
@@ -543,7 +543,7 @@ Puncte cheie:
|
||||
* Este permisă o singură funcție de pre-instalare per aplicație. Construirea manifestului va genera o eroare dacă este detectată mai mult de una.
|
||||
* Proprietatea `universalIdentifier` a funcției este setată automat ca `preInstallLogicFunctionUniversalIdentifier` în manifestul aplicației în timpul build-ului — nu este nevoie să o referi în `defineApplication()`.
|
||||
* Timpul de expirare implicit este setat la 300 de secunde (5 minute) pentru a permite sarcini de pregătire mai lungi.
|
||||
* Pre-install functions do not need triggers — they are invoked by the platform before installation or manually via `exec --preInstall`.
|
||||
* Funcțiile de pre-instalare nu au nevoie de declanșatoare — sunt invocate de platformă înainte de instalare sau manual prin `exec --preInstall`.
|
||||
|
||||
### Funcții post-instalare
|
||||
|
||||
@@ -581,7 +581,7 @@ Puncte cheie:
|
||||
* Este permisă o singură funcție de post-instalare per aplicație. Construirea manifestului va genera o eroare dacă este detectată mai mult de una.
|
||||
* Proprietatea `universalIdentifier` a funcției este setată automat ca `postInstallLogicFunctionUniversalIdentifier` în manifestul aplicației în timpul build-ului — nu este nevoie să o referi în `defineApplication()`.
|
||||
* Timpul de expirare implicit este setat la 300 de secunde (5 minute) pentru a permite sarcini de configurare mai lungi, cum ar fi popularea datelor.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `exec --postInstall`.
|
||||
* Funcțiile post-instalare nu au nevoie de declanșatoare — sunt invocate de platformă în timpul instalării sau manual prin `exec --postInstall`.
|
||||
|
||||
### Payload-ul declanșatorului de rută
|
||||
|
||||
@@ -625,15 +625,15 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Tipul `RoutePayload` are următoarea structură:
|
||||
|
||||
| Proprietate | Tip | Descriere |
|
||||
| ---------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| `headers` | `Record<string, string \| undefined>` | Anteturi HTTP (doar cele listate în `forwardedRequestHeaders`) |
|
||||
| `queryStringParameters` | `Record<string, string \| undefined>` | Parametri query string (valorile multiple unite cu virgule) |
|
||||
| `pathParameters` | `Record<string, string \| undefined>` | Path parameters extracted from the route pattern (e.g., `/users/:id` -> `{ id: '123' }`) |
|
||||
| `body` | `object \| null` | Corpul cererii analizat (JSON) |
|
||||
| `isBase64Encoded` | `boolean` | Indică dacă corpul este codificat în base64 |
|
||||
| `requestContext.http.method` | `string` | Metoda HTTP (GET, POST, PUT, PATCH, DELETE) |
|
||||
| `requestContext.http.path` | `string` | Calea brută a cererii |
|
||||
| Proprietate | Tip | Descriere |
|
||||
| ---------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------- |
|
||||
| `headers` | `Record<string, string \| undefined>` | Anteturi HTTP (doar cele listate în `forwardedRequestHeaders`) |
|
||||
| `queryStringParameters` | `Record<string, string \| undefined>` | Parametri query string (valorile multiple unite cu virgule) |
|
||||
| `pathParameters` | `Record<string, string \| undefined>` | Parametri de cale extrași din modelul rutei (de ex., `/users/:id` -> `{ id: '123' }`) |
|
||||
| `body` | `object \| null` | Corpul cererii analizat (JSON) |
|
||||
| `isBase64Encoded` | `boolean` | Indică dacă corpul este codificat în base64 |
|
||||
| `requestContext.http.method` | `string` | Metoda HTTP (GET, POST, PUT, PATCH, DELETE) |
|
||||
| `requestContext.http.path` | `string` | Calea brută a cererii |
|
||||
|
||||
### Transmiterea anteturilor HTTP
|
||||
|
||||
@@ -675,7 +675,7 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Puteți crea funcții noi în două moduri:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new logic function. Aceasta generează un fișier inițial cu un handler și o configurație.
|
||||
* **Generat**: Rulați `yarn twenty add` și alegeți opțiunea de a adăuga o funcție de logică nouă. Aceasta generează un fișier inițial cu un handler și o configurație.
|
||||
* **Manual**: Creați un fișier nou `*.logic-function.ts` și folosiți `defineLogicFunction()`, urmând același model.
|
||||
|
||||
### Marcarea unei funcții logice drept instrument
|
||||
@@ -776,7 +776,7 @@ Puncte cheie:
|
||||
|
||||
Puteți crea componente Front noi în două moduri:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new front component.
|
||||
* **Generat**: Rulați `yarn twenty add` și alegeți opțiunea de a adăuga o componentă Front nouă.
|
||||
* **Manual**: Creați un fișier nou `.tsx` și folosiți `defineFrontComponent()`, urmând același model.
|
||||
|
||||
### Abilități
|
||||
@@ -811,21 +811,21 @@ Puncte cheie:
|
||||
|
||||
Puteți crea abilități noi în două moduri:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new skill.
|
||||
* **Generat**: Rulați `yarn twenty add` și alegeți opțiunea de a adăuga o abilitate nouă.
|
||||
* **Manual**: Creați un fișier nou și folosiți `defineSkill()`, urmând același model.
|
||||
|
||||
### Typed API clients (`twenty-client-sdk`)
|
||||
### Clienți API tipați (`twenty-client-sdk`)
|
||||
|
||||
The `twenty-client-sdk` package provides two typed GraphQL clients for interacting with the Twenty API from your logic functions and front components:
|
||||
Pachetul `twenty-client-sdk` oferă doi clienți GraphQL tipați pentru a interacționa cu API-ul Twenty din funcțiile de logică și componentele Front:
|
||||
|
||||
| Client | Importați | Endpoint | Generated? |
|
||||
| ------------------- | ---------------------------- | ---------------------------------------------- | ---------------------- |
|
||||
| `CoreApiClient` | `twenty-client-sdk/core` | `/graphql` — workspace data (records, objects) | Yes, at dev/build time |
|
||||
| `MetadataApiClient` | `twenty-client-sdk/metadata` | `/metadata` — workspace config, file uploads | No, ships pre-built |
|
||||
| Client | Importați | Endpoint | Generat? |
|
||||
| ------------------- | ---------------------------- | ------------------------------------------------------------------- | ---------------------------- |
|
||||
| `CoreApiClient` | `twenty-client-sdk/core` | `/graphql` — date ale spațiului de lucru (înregistrări, obiecte) | Da, în timpul dev/build |
|
||||
| `MetadataApiClient` | `twenty-client-sdk/metadata` | `/metadata` — configurarea spațiului de lucru, încărcări de fișiere | Nu, este livrat preconstruit |
|
||||
|
||||
#### CoreApiClient
|
||||
|
||||
`CoreApiClient` is the main client for querying and mutating workspace data. It is **generated from your workspace schema** during `yarn twenty dev` or `yarn twenty build`, so it's fully typed to match your objects and fields.
|
||||
`CoreApiClient` este clientul principal pentru interogarea și modificarea datelor din spațiul de lucru. Este generat din schema spațiului dvs. de lucru în timpul `yarn twenty dev` sau `yarn twenty build`, astfel încât este complet tipat pentru a corespunde obiectelor și câmpurilor dvs.
|
||||
|
||||
```typescript
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
@@ -859,15 +859,15 @@ const { createCompany } = await client.mutation({
|
||||
});
|
||||
```
|
||||
|
||||
The client uses a selection-set syntax: pass `true` to include a field, use `__args` for arguments, and nest objects for relations. You get full autocompletion and type checking based on your workspace schema.
|
||||
Clientul folosește o sintaxă de tip selection-set: transmiteți `true` pentru a include un câmp, folosiți `__args` pentru argumente și imbricați obiecte pentru relații. Obțineți autocompletare și verificare a tipurilor complete, pe baza schemei spațiului dvs. de lucru.
|
||||
|
||||
<Note>
|
||||
**CoreApiClient is generated at dev/build time.** If you try to use it without running `yarn twenty dev` or `yarn twenty build` first, it throws an error. The generation happens automatically — the CLI introspects your workspace's GraphQL schema, generates a typed client using `@genql/cli`, writes the generated sources to `node_modules/twenty-client-sdk/dist/core/generated/`, and replaces the stubs in `node_modules/twenty-client-sdk/dist/core.mjs` and `node_modules/twenty-client-sdk/dist/core.cjs`.
|
||||
**CoreApiClient este generat în timpul dev/build.** Dacă încercați să îl utilizați fără a rula mai întâi `yarn twenty dev` sau `yarn twenty build`, va arunca o eroare. Generarea are loc automat — CLI-ul introspectează schema GraphQL a spațiului dvs. de lucru, generează un client tipat folosind `@genql/cli`, scrie sursele generate în `node_modules/twenty-client-sdk/dist/core/generated/` și înlocuiește stubs-urile din `node_modules/twenty-client-sdk/dist/core.mjs` și `node_modules/twenty-client-sdk/dist/core.cjs`.
|
||||
</Note>
|
||||
|
||||
#### Using CoreSchema for type annotations
|
||||
#### Folosirea CoreSchema pentru adnotări de tip
|
||||
|
||||
`CoreSchema` provides TypeScript types matching your workspace objects, useful for typing component state or function parameters:
|
||||
`CoreSchema` oferă tipuri TypeScript care se potrivesc obiectelor din spațiul dvs. de lucru, utile pentru tiparea stării componentelor sau a parametrilor funcțiilor:
|
||||
|
||||
```typescript
|
||||
import { CoreApiClient, CoreSchema } from 'twenty-client-sdk/core';
|
||||
@@ -890,7 +890,7 @@ setCompany(result.company);
|
||||
|
||||
#### MetadataApiClient
|
||||
|
||||
`MetadataApiClient` ships pre-built with the SDK (no generation required). It queries the `/metadata` endpoint for workspace configuration, applications, and file uploads:
|
||||
`MetadataApiClient` este livrat preconstruit împreună cu SDK-ul (nu este necesară generarea). Interoghează endpointul `/metadata` pentru configurarea spațiului de lucru, aplicații și încărcări de fișiere:
|
||||
|
||||
```typescript
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -912,18 +912,18 @@ const { findManyApplications } = await metadataClient.query({
|
||||
});
|
||||
```
|
||||
|
||||
#### Runtime credentials
|
||||
#### Acreditări la rulare
|
||||
|
||||
When your code runs on Twenty (logic functions or front components), the platform injects credentials as environment variables:
|
||||
Când codul dvs. rulează pe Twenty (funcții de logică sau componente Front), platforma injectează acreditările ca variabile de mediu:
|
||||
|
||||
* `TWENTY_API_URL` — Base URL of the Twenty API
|
||||
* `TWENTY_API_KEY` — Short-lived key scoped to your application's default function role
|
||||
* `TWENTY_API_URL` — URL-ul de bază al API-ului Twenty
|
||||
* `TWENTY_API_KEY` — Cheie cu durată scurtă, limitată la rolul implicit de funcție al aplicației
|
||||
|
||||
You do **not** need to pass these to the clients — they read from `process.env` automatically. The API key's permissions are determined by the role referenced in `defaultRoleUniversalIdentifier` in your `application-config.ts`.
|
||||
Nu trebuie să le transmiteți clienților — aceștia citesc automat din `process.env`. Permisiunile cheii API sunt determinate de rolul referențiat în `defaultRoleUniversalIdentifier` din `application-config.ts`.
|
||||
|
||||
#### Încărcarea fișierelor
|
||||
|
||||
`MetadataApiClient` includes an `uploadFile` method for attaching files to file-type fields. It implements the [GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec):
|
||||
`MetadataApiClient` include o metodă `uploadFile` pentru atașarea fișierelor la câmpuri de tip fișier. Implementează [specificația pentru cereri GraphQL multipart](https://github.com/jaydenseric/graphql-multipart-request-spec):
|
||||
|
||||
```typescript
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -953,7 +953,7 @@ console.log(uploadedFile);
|
||||
|
||||
Puncte cheie:
|
||||
|
||||
* Uses the field's `universalIdentifier` (not its workspace-specific ID), so your upload code works across any workspace where your app is installed.
|
||||
* Folosește `universalIdentifier` al câmpului (nu ID-ul specific spațiului de lucru), astfel încât codul dvs. de încărcare funcționează în orice spațiu de lucru în care aplicația dvs. este instalată.
|
||||
* `url` returnat este un URL semnat pe care îl poți folosi pentru a accesa fișierul încărcat.
|
||||
|
||||
### Exemplu Hello World
|
||||
|
||||
@@ -15,21 +15,21 @@ description: Определяйте объекты, функции логики,
|
||||
|
||||
SDK предоставляет вспомогательные функции для определения сущностей вашего приложения. Как описано в [Обнаружение сущностей](/l/ru/developers/extend/apps/getting-started#entity-detection), вы должны использовать `export default define<Entity>({...})`, чтобы ваши сущности были обнаружены:
|
||||
|
||||
| Функция | Назначение |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `defineApplication` | Настройка метаданных приложения (обязательно, по одному на приложение) |
|
||||
| `defineObject` | Определяет пользовательские объекты с полями |
|
||||
| `defineField` | Extend existing objects with additional fields or define standalone relation fields |
|
||||
| `defineLogicFunction` | Определение логических функций с обработчиками |
|
||||
| `definePreInstallLogicFunction` | Определяет предустановочную логическую функцию (по одной на приложение) |
|
||||
| `definePostInstallLogicFunction` | Определяет послеустановочную логическую функцию (по одной на приложение) |
|
||||
| `defineFrontComponent` | Определение фронт-компонентов для настраиваемого интерфейса |
|
||||
| `defineRole` | Настраивает права роли и доступ к объектам |
|
||||
| `defineView` | Определяйте сохранённые представления для объектов |
|
||||
| `defineNavigationMenuItem` | Определяйте ссылки боковой панели навигации |
|
||||
| `defineSkill` | Определение навыков агента ИИ |
|
||||
| `defineAgent` | Define AI agents |
|
||||
| `definePageLayout` | Define custom page layouts |
|
||||
| Функция | Назначение |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `defineApplication` | Настройка метаданных приложения (обязательно, по одному на приложение) |
|
||||
| `defineObject` | Определяет пользовательские объекты с полями |
|
||||
| `defineField` | Расширяйте существующие объекты дополнительными полями или определяйте отдельные поля отношений |
|
||||
| `defineLogicFunction` | Определение логических функций с обработчиками |
|
||||
| `definePreInstallLogicFunction` | Определяет предустановочную логическую функцию (по одной на приложение) |
|
||||
| `definePostInstallLogicFunction` | Определяет послеустановочную логическую функцию (по одной на приложение) |
|
||||
| `defineFrontComponent` | Определение фронт-компонентов для настраиваемого интерфейса |
|
||||
| `defineRole` | Настраивает права роли и доступ к объектам |
|
||||
| `defineView` | Определяйте сохранённые представления для объектов |
|
||||
| `defineNavigationMenuItem` | Определяйте ссылки боковой панели навигации |
|
||||
| `defineSkill` | Определение навыков агента ИИ |
|
||||
| `defineAgent` | Определяйте агентов ИИ |
|
||||
| `definePageLayout` | Определяйте пользовательские макеты страниц |
|
||||
|
||||
Эти функции проверяют вашу конфигурацию на этапе сборки и обеспечивают автодополнение в IDE и безопасность типов.
|
||||
|
||||
@@ -112,7 +112,7 @@ export default defineObject({
|
||||
* `universalIdentifier` должен быть уникальным и стабильным между развёртываниями.
|
||||
* Каждому полю требуются `name`, `type`, `label` и собственный стабильный `universalIdentifier`.
|
||||
* Массив `fields` необязателен — вы можете определять объекты без пользовательских полей.
|
||||
* You can scaffold new objects using `yarn twenty add`, which guides you through naming, fields, and relationships.
|
||||
* Вы можете сгенерировать новые объекты с помощью `yarn twenty add`, который проведёт вас через выбор именования, полей и связей.
|
||||
|
||||
<Note>
|
||||
**Базовые поля создаются автоматически.** Когда вы определяете пользовательский объект, Twenty автоматически добавляет стандартные поля,
|
||||
@@ -124,7 +124,7 @@ export default defineObject({
|
||||
|
||||
### Определение полей для существующих объектов
|
||||
|
||||
Use `defineField()` to add fields to objects you don't own — such as standard Twenty objects (Person, Company, etc.) or objects from other apps. Unlike inline fields in `defineObject()`, standalone fields require an `objectUniversalIdentifier` to specify which object they extend:
|
||||
Используйте `defineField()` для добавления полей к объектам, которые вам не принадлежат — например, к стандартным объектам Twenty (Person, Company и т. д.). или к объектам из других приложений. В отличие от встроенных полей в `defineObject()`, отдельные поля требуют `objectUniversalIdentifier`, чтобы указать, какой объект они расширяют:
|
||||
|
||||
```typescript
|
||||
// src/fields/company-loyalty-tier.field.ts
|
||||
@@ -147,35 +147,35 @@ export default defineField({
|
||||
|
||||
Основные моменты:
|
||||
|
||||
* `objectUniversalIdentifier` identifies the target object. For standard objects, use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` exported from `twenty-sdk`.
|
||||
* When defining fields inline in `defineObject()`, you do **not** need `objectUniversalIdentifier` — it's inherited from the parent object.
|
||||
* `defineField()` is the only way to add fields to objects you didn't create with `defineObject()`.
|
||||
* `objectUniversalIdentifier` определяет целевой объект. Для стандартных объектов используйте `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`, экспортируемые из `twenty-sdk`.
|
||||
* При определении полей непосредственно в `defineObject()` вам не нужен `objectUniversalIdentifier` — он наследуется от родительского объекта.
|
||||
* `defineField()` — единственный способ добавить поля к объектам, которые вы не создавали с помощью `defineObject()`.
|
||||
|
||||
### Связи
|
||||
|
||||
Relations connect objects together. In Twenty, relations are always **bidirectional** — you define both sides, and each side references the other.
|
||||
Отношения связывают объекты между собой. В Twenty отношения всегда двунаправленные — вы определяете обе стороны, и каждая сторона ссылается на другую.
|
||||
|
||||
There are two relation types:
|
||||
Существуют два типа отношений:
|
||||
|
||||
| Тип отношения | Описание | Has foreign key? |
|
||||
| ------------- | ------------------------------------------------------------- | ---------------------- |
|
||||
| `MANY_TO_ONE` | Many records of this object point to one record of the target | Yes (`joinColumnName`) |
|
||||
| `ONE_TO_MANY` | One record of this object has many records of the target | No (inverse side) |
|
||||
| Тип отношения | Описание | Есть внешний ключ? |
|
||||
| ------------- | --------------------------------------------------------------------- | ---------------------- |
|
||||
| `MANY_TO_ONE` | Многие записи этого объекта указывают на одну запись целевого объекта | Да (`joinColumnName`) |
|
||||
| `ONE_TO_MANY` | Одна запись этого объекта имеет много записей целевого объекта | Нет (обратная сторона) |
|
||||
|
||||
#### How relations work
|
||||
#### Как работают отношения
|
||||
|
||||
Every relation requires **two fields** that reference each other:
|
||||
Каждое отношение требует **двух полей**, которые ссылаются друг на друга:
|
||||
|
||||
1. The **MANY_TO_ONE** side — lives on the object that holds the foreign key
|
||||
2. The **ONE_TO_MANY** side — lives on the object that owns the collection
|
||||
1. Сторона **MANY_TO_ONE** — находится в объекте, который содержит внешний ключ
|
||||
2. Сторона **ONE_TO_MANY** — находится в объекте, которому принадлежит коллекция
|
||||
|
||||
Both fields use `FieldType.RELATION` and cross-reference each other via `relationTargetFieldMetadataUniversalIdentifier`.
|
||||
Оба поля используют `FieldType.RELATION` и ссылаются друг на друга через `relationTargetFieldMetadataUniversalIdentifier`.
|
||||
|
||||
#### Example: Post Card has many Recipients
|
||||
#### Пример: Почтовая открытка имеет много получателей
|
||||
|
||||
Suppose a `PostCard` can be sent to many `PostCardRecipient` records. Each recipient belongs to exactly one post card.
|
||||
Предположим, `PostCard` может быть отправлен множству записей `PostCardRecipient`. Каждый получатель относится ровно к одной открытке.
|
||||
|
||||
**Step 1: Define the ONE_TO_MANY side on PostCard** (the "one" side):
|
||||
**Шаг 1: Определите сторону ONE_TO_MANY на PostCard** (сторона "one"):
|
||||
|
||||
```typescript
|
||||
// src/fields/post-card-recipients-on-post-card.field.ts
|
||||
@@ -203,7 +203,7 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Define the MANY_TO_ONE side on PostCardRecipient** (the "many" side — holds the foreign key):
|
||||
**Шаг 2: Определите сторону MANY_TO_ONE на PostCardRecipient** (сторона "many" — содержит внешний ключ):
|
||||
|
||||
```typescript
|
||||
// src/fields/post-card-on-post-card-recipient.field.ts
|
||||
@@ -234,12 +234,12 @@ export default defineField({
|
||||
```
|
||||
|
||||
<Note>
|
||||
**Circular imports:** Both relation fields reference each other's `universalIdentifier`. To avoid circular import issues, export your field IDs as named constants from each file, and import them in the other file. The build system resolves these at compile time.
|
||||
**Циклические импорты:** Оба поля отношений ссылаются на `universalIdentifier` друг друга. Чтобы избежать проблем с циклическими импортами, экспортируйте идентификаторы полей как именованные константы из каждого файла и импортируйте их в другом файле. Система сборки разрешает это на этапе компиляции.
|
||||
</Note>
|
||||
|
||||
#### Relating to standard objects
|
||||
#### Связывание со стандартными объектами
|
||||
|
||||
To create a relation with a built-in Twenty object (Person, Company, etc.), use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`:
|
||||
Чтобы создать отношение со встроенным объектом Twenty (Person, Company и т. д.), используйте `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`:
|
||||
|
||||
```typescript
|
||||
// src/fields/person-on-self-hosting-user.field.ts
|
||||
@@ -274,20 +274,20 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
#### Relation field properties
|
||||
#### Свойства поля отношения
|
||||
|
||||
| Свойство | Обязательно | Описание |
|
||||
| ------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `type` | Да | Must be `FieldType.RELATION` |
|
||||
| `relationTargetObjectMetadataUniversalIdentifier` | Да | The `universalIdentifier` of the target object |
|
||||
| `relationTargetFieldMetadataUniversalIdentifier` | Да | The `universalIdentifier` of the matching field on the target object |
|
||||
| `universalSettings.relationType` | Да | `RelationType.MANY_TO_ONE` or `RelationType.ONE_TO_MANY` |
|
||||
| `universalSettings.onDelete` | MANY_TO_ONE only | What happens when the referenced record is deleted: `CASCADE`, `SET_NULL`, `RESTRICT`, or `NO_ACTION` |
|
||||
| `universalSettings.joinColumnName` | MANY_TO_ONE only | Database column name for the foreign key (e.g., `postCardId`) |
|
||||
| Свойство | Обязательно | Описание |
|
||||
| ------------------------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `type` | Да | Должно быть `FieldType.RELATION` |
|
||||
| `relationTargetObjectMetadataUniversalIdentifier` | Да | `universalIdentifier` целевого объекта |
|
||||
| `relationTargetFieldMetadataUniversalIdentifier` | Да | `universalIdentifier` соответствующего поля на целевом объекте |
|
||||
| `universalSettings.relationType` | Да | `RelationType.MANY_TO_ONE` или `RelationType.ONE_TO_MANY` |
|
||||
| `universalSettings.onDelete` | Только для MANY_TO_ONE | Что происходит при удалении связанной записи: `CASCADE`, `SET_NULL`, `RESTRICT` или `NO_ACTION` |
|
||||
| `universalSettings.joinColumnName` | Только для MANY_TO_ONE | Имя столбца базы данных для внешнего ключа (например, `postCardId`) |
|
||||
|
||||
#### Inline relation fields in defineObject
|
||||
#### Встроенные поля отношений в defineObject
|
||||
|
||||
You can also define relation fields directly inside `defineObject()`. In that case, omit `objectUniversalIdentifier` — it's inherited from the parent object:
|
||||
Вы также можете определять поля отношений непосредственно внутри `defineObject()`. В этом случае опустите `objectUniversalIdentifier` — он наследуется от родительского объекта:
|
||||
|
||||
```typescript
|
||||
export default defineObject({
|
||||
@@ -354,21 +354,21 @@ export default defineApplication({
|
||||
* `defaultRoleUniversalIdentifier` должен соответствовать файлу роли (см. ниже).
|
||||
* Предустановочные и послеустановочные функции автоматически обнаруживаются во время сборки манифеста. См. [Предустановочные функции](#pre-install-functions) и [Послеустановочные функции](#post-install-functions).
|
||||
|
||||
#### Marketplace metadata
|
||||
#### Метаданные маркетплейса
|
||||
|
||||
If you plan to [publish your app](/l/ru/developers/extend/apps/publishing), these optional fields control how your app appears in the marketplace:
|
||||
Если вы планируете [опубликовать приложение](/l/ru/developers/extend/apps/publishing), эти необязательные поля определяют, как ваше приложение отображается в маркетплейсе:
|
||||
|
||||
| Поле | Описание |
|
||||
| ------------------ | --------------------------------------------------- |
|
||||
| `author` | Author or company name |
|
||||
| `category` | App category for marketplace filtering |
|
||||
| `logoUrl` | Path to your app logo (relative to `./assets/`) |
|
||||
| `screenshots` | Array of screenshot paths (relative to `./assets/`) |
|
||||
| `aboutDescription` | Longer markdown description for the "About" tab |
|
||||
| `websiteUrl` | Link to your website |
|
||||
| `termsUrl` | Link to terms of service |
|
||||
| `emailSupport` | Support email address |
|
||||
| `issueReportUrl` | Link to issue tracker |
|
||||
| Поле | Описание |
|
||||
| ------------------ | ------------------------------------------------------------ |
|
||||
| `author` | Имя автора или название компании |
|
||||
| `category` | Категория приложения для фильтрации в маркетплейсе |
|
||||
| `logoUrl` | Путь к логотипу вашего приложения (относительно `./assets/`) |
|
||||
| `screenshots` | Массив путей к скриншотам (относительно `./assets/`) |
|
||||
| `aboutDescription` | Расширенное описание в Markdown для вкладки "About" |
|
||||
| `websiteUrl` | Ссылка на ваш сайт |
|
||||
| `termsUrl` | Ссылка на условия предоставления услуг |
|
||||
| `emailSupport` | Адрес электронной почты поддержки |
|
||||
| `issueReportUrl` | Ссылка на систему отслеживания проблем |
|
||||
|
||||
#### Роли и разрешения
|
||||
|
||||
@@ -376,7 +376,7 @@ If you plan to [publish your app](/l/ru/developers/extend/apps/publishing), thes
|
||||
|
||||
* Ключ API во время выполнения, подставляемый как `TWENTY_API_KEY`, получается из этой роли функции по умолчанию.
|
||||
* Типизированный клиент будет ограничен правами, предоставленными этой ролью.
|
||||
* Follow least-privilege: create a dedicated role with only the permissions your functions need, then reference its universal identifier.
|
||||
* Следуйте принципу наименьших привилегий: создайте отдельную роль только с теми правами, которые нужны вашим функциям, и укажите её универсальный идентификатор.
|
||||
|
||||
##### Роль функции по умолчанию (*.role.ts)
|
||||
|
||||
@@ -429,7 +429,7 @@ export default defineRole({
|
||||
|
||||
Заметки:
|
||||
|
||||
* Start from the scaffolded role, then progressively restrict it following least-privilege.
|
||||
* Начните со сгенерированной роли, затем постепенно ограничивайте её, следуя принципу наименьших привилегий.
|
||||
* Замените `objectPermissions` и `fieldPermissions` на объекты/поля, которые нужны вашим функциям.
|
||||
* `permissionFlags` управляют доступом к возможностям на уровне платформы. Держите их минимальными; добавляйте только то, что нужно.
|
||||
* См. рабочий пример в приложении Hello World: [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
|
||||
@@ -543,7 +543,7 @@ yarn twenty exec --preInstall
|
||||
* Для каждого приложения допускается только одна предустановочная функция. Сборка манифеста завершится ошибкой, если будет обнаружено более одной такой функции.
|
||||
* Параметр `universalIdentifier` функции автоматически устанавливается как `preInstallLogicFunctionUniversalIdentifier` в манифесте приложения во время сборки — вам не нужно ссылаться на него в `defineApplication()`.
|
||||
* Тайм-аут по умолчанию установлен на 300 секунд (5 минут), чтобы обеспечить выполнение более длительных задач подготовки.
|
||||
* Pre-install functions do not need triggers — they are invoked by the platform before installation or manually via `exec --preInstall`.
|
||||
* Предустановочным функциям не нужны триггеры — платформа вызывает их перед установкой или вручную через `exec --preInstall`.
|
||||
|
||||
### Послеустановочные функции
|
||||
|
||||
@@ -581,7 +581,7 @@ yarn twenty exec --postInstall
|
||||
* Для каждого приложения допускается только одна послеустановочная функция. Сборка манифеста завершится ошибкой, если будет обнаружено более одной такой функции.
|
||||
* Параметр `universalIdentifier` функции автоматически устанавливается как `postInstallLogicFunctionUniversalIdentifier` в манифесте приложения во время сборки — вам не нужно ссылаться на него в `defineApplication()`.
|
||||
* Тайм-аут по умолчанию установлен на 300 секунд (5 минут), чтобы позволить выполнять более длительные задачи настройки, такие как инициализация данных.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `exec --postInstall`.
|
||||
* Постустановочным функциям не нужны триггеры — платформа вызывает их во время установки или вручную через `exec --postInstall`.
|
||||
|
||||
### Полезная нагрузка триггера маршрута
|
||||
|
||||
@@ -625,15 +625,15 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Тип `RoutePayload` имеет следующую структуру:
|
||||
|
||||
| Свойство | Тип | Описание |
|
||||
| ---------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| `headers` | `Record<string, string \| undefined>` | HTTP-заголовки (только перечисленные в `forwardedRequestHeaders`) |
|
||||
| `queryStringParameters` | `Record<string, string \| undefined>` | Параметры строки запроса (несколько значений объединяются запятыми) |
|
||||
| `pathParameters` | `Record<string, string \| undefined>` | Path parameters extracted from the route pattern (e.g., `/users/:id` -> `{ id: '123' }`) |
|
||||
| `body` | `object \| null` | Разобранное тело запроса (JSON) |
|
||||
| `isBase64Encoded` | `логический тип` | Является ли тело закодированным в base64 |
|
||||
| `requestContext.http.method` | `строка` | Метод HTTP (GET, POST, PUT, PATCH, DELETE) |
|
||||
| `requestContext.http.path` | `строка` | Необработанный путь запроса |
|
||||
| Свойство | Тип | Описание |
|
||||
| ---------------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| `headers` | `Record<string, string \| undefined>` | HTTP-заголовки (только перечисленные в `forwardedRequestHeaders`) |
|
||||
| `queryStringParameters` | `Record<string, string \| undefined>` | Параметры строки запроса (несколько значений объединяются запятыми) |
|
||||
| `pathParameters` | `Record<string, string \| undefined>` | Параметры пути, извлечённые из шаблона маршрута (например, `/users/:id` -> `{ id: '123' }`) |
|
||||
| `body` | `object \| null` | Разобранное тело запроса (JSON) |
|
||||
| `isBase64Encoded` | `логический тип` | Является ли тело закодированным в base64 |
|
||||
| `requestContext.http.method` | `строка` | Метод HTTP (GET, POST, PUT, PATCH, DELETE) |
|
||||
| `requestContext.http.path` | `строка` | Необработанный путь запроса |
|
||||
|
||||
### Проброс HTTP-заголовков
|
||||
|
||||
@@ -675,7 +675,7 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Вы можете создать новые функции двумя способами:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new logic function. Это создаёт стартовый файл с обработчиком и конфигурацией.
|
||||
* **Сгенерировано**: Запустите `yarn twenty add` и выберите опцию добавления новой логической функции. Это создаёт стартовый файл с обработчиком и конфигурацией.
|
||||
* **Вручную**: Создайте новый файл `*.logic-function.ts` и используйте `defineLogicFunction()`, следуя тому же шаблону.
|
||||
|
||||
### Пометка логической функции как инструмента
|
||||
@@ -776,7 +776,7 @@ export default defineFrontComponent({
|
||||
|
||||
Вы можете создать новые фронт-компоненты двумя способами:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new front component.
|
||||
* **Сгенерировано**: Запустите `yarn twenty add` и выберите опцию добавления нового фронт-компонента.
|
||||
* **Вручную**: Создайте новый файл `.tsx` и используйте `defineFrontComponent()`, следуя тому же шаблону.
|
||||
|
||||
### Навыки
|
||||
@@ -811,21 +811,21 @@ export default defineSkill({
|
||||
|
||||
Вы можете создать новые навыки двумя способами:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new skill.
|
||||
* **Сгенерировано**: Запустите `yarn twenty add` и выберите опцию добавления нового навыка.
|
||||
* **Вручную**: Создайте новый файл и используйте `defineSkill()`, следуя тому же шаблону.
|
||||
|
||||
### Typed API clients (`twenty-client-sdk`)
|
||||
### Типизированные клиенты API (`twenty-client-sdk`)
|
||||
|
||||
The `twenty-client-sdk` package provides two typed GraphQL clients for interacting with the Twenty API from your logic functions and front components:
|
||||
Пакет `twenty-client-sdk` предоставляет два типизированных клиента GraphQL для взаимодействия с API Twenty из ваших логических функций и фронт-компонентов:
|
||||
|
||||
| Клиент | Импорт | Endpoint | Generated? |
|
||||
| ------------------- | ---------------------------- | ---------------------------------------------- | ---------------------- |
|
||||
| `CoreApiClient` | `twenty-client-sdk/core` | `/graphql` — workspace data (records, objects) | Yes, at dev/build time |
|
||||
| `MetadataApiClient` | `twenty-client-sdk/metadata` | `/metadata` — workspace config, file uploads | No, ships pre-built |
|
||||
| Клиент | Импорт | Конечная точка | Генерируется? |
|
||||
| ------------------- | ---------------------------- | ----------------------------------------------------------------- | -------------------------------- |
|
||||
| `CoreApiClient` | `twenty-client-sdk/core` | `/graphql` — данные рабочего пространства (записи, объекты) | Да, на этапе dev/build |
|
||||
| `MetadataApiClient` | `twenty-client-sdk/metadata` | `/metadata` — конфигурация рабочего пространства, загрузка файлов | Нет, поставляется в готовом виде |
|
||||
|
||||
#### CoreApiClient
|
||||
|
||||
`CoreApiClient` is the main client for querying and mutating workspace data. It is **generated from your workspace schema** during `yarn twenty dev` or `yarn twenty build`, so it's fully typed to match your objects and fields.
|
||||
`CoreApiClient` — основной клиент для запросов и изменений данных рабочего пространства. Он генерируется из схемы вашего рабочего пространства во время `yarn twenty dev` или `yarn twenty build`, поэтому он полностью типизирован в соответствии с вашими объектами и полями.
|
||||
|
||||
```typescript
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
@@ -859,15 +859,15 @@ const { createCompany } = await client.mutation({
|
||||
});
|
||||
```
|
||||
|
||||
The client uses a selection-set syntax: pass `true` to include a field, use `__args` for arguments, and nest objects for relations. You get full autocompletion and type checking based on your workspace schema.
|
||||
Клиент использует синтаксис selection-set: передайте `true`, чтобы включить поле, используйте `__args` для аргументов и вкладывайте объекты для отношений. Вы получаете полное автодополнение и проверку типов на основе схемы вашего рабочего пространства.
|
||||
|
||||
<Note>
|
||||
**CoreApiClient is generated at dev/build time.** If you try to use it without running `yarn twenty dev` or `yarn twenty build` first, it throws an error. The generation happens automatically — the CLI introspects your workspace's GraphQL schema, generates a typed client using `@genql/cli`, writes the generated sources to `node_modules/twenty-client-sdk/dist/core/generated/`, and replaces the stubs in `node_modules/twenty-client-sdk/dist/core.mjs` and `node_modules/twenty-client-sdk/dist/core.cjs`.
|
||||
**CoreApiClient генерируется на этапе dev/build.** Если вы попытаетесь использовать его, не запустив сначала `yarn twenty dev` или `yarn twenty build`, он выбросит ошибку. Генерация происходит автоматически — CLI анализирует GraphQL-схему вашего рабочего пространства, генерирует типизированный клиент с помощью `@genql/cli`, записывает сгенерированные исходники в `node_modules/twenty-client-sdk/dist/core/generated/` и заменяет заглушки в `node_modules/twenty-client-sdk/dist/core.mjs` и `node_modules/twenty-client-sdk/dist/core.cjs`.
|
||||
</Note>
|
||||
|
||||
#### Using CoreSchema for type annotations
|
||||
#### Использование CoreSchema для аннотаций типов
|
||||
|
||||
`CoreSchema` provides TypeScript types matching your workspace objects, useful for typing component state or function parameters:
|
||||
`CoreSchema` предоставляет типы TypeScript, соответствующие объектам вашего рабочего пространства, что полезно для типизации состояния компонентов или параметров функций:
|
||||
|
||||
```typescript
|
||||
import { CoreApiClient, CoreSchema } from 'twenty-client-sdk/core';
|
||||
@@ -890,7 +890,7 @@ setCompany(result.company);
|
||||
|
||||
#### MetadataApiClient
|
||||
|
||||
`MetadataApiClient` ships pre-built with the SDK (no generation required). It queries the `/metadata` endpoint for workspace configuration, applications, and file uploads:
|
||||
`MetadataApiClient` поставляется в готовом виде вместе с SDK (генерация не требуется). Он выполняет запросы к эндпоинту `/metadata` для получения конфигурации рабочего пространства, приложений и загрузки файлов:
|
||||
|
||||
```typescript
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -912,18 +912,18 @@ const { findManyApplications } = await metadataClient.query({
|
||||
});
|
||||
```
|
||||
|
||||
#### Runtime credentials
|
||||
#### Учётные данные времени выполнения
|
||||
|
||||
When your code runs on Twenty (logic functions or front components), the platform injects credentials as environment variables:
|
||||
Когда ваш код выполняется на Twenty (логические функции или фронт-компоненты), платформа предоставляет учётные данные в виде переменных окружения:
|
||||
|
||||
* `TWENTY_API_URL` — Base URL of the Twenty API
|
||||
* `TWENTY_API_KEY` — Short-lived key scoped to your application's default function role
|
||||
* `TWENTY_API_URL` — базовый URL API Twenty
|
||||
* `TWENTY_API_KEY` — краткоживущий ключ, ограниченный ролью функции по умолчанию вашего приложения
|
||||
|
||||
You do **not** need to pass these to the clients — they read from `process.env` automatically. The API key's permissions are determined by the role referenced in `defaultRoleUniversalIdentifier` in your `application-config.ts`.
|
||||
Вам не нужно передавать их клиентам — они автоматически читаются из `process.env`. Права ключа API определяются ролью, указанной в `defaultRoleUniversalIdentifier` в вашем `application-config.ts`.
|
||||
|
||||
#### Загрузка файлов
|
||||
|
||||
`MetadataApiClient` includes an `uploadFile` method for attaching files to file-type fields. It implements the [GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec):
|
||||
`MetadataApiClient` включает метод `uploadFile` для прикрепления файлов к полям типа файла. Он реализует [спецификацию многочастных запросов GraphQL](https://github.com/jaydenseric/graphql-multipart-request-spec):
|
||||
|
||||
```typescript
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -953,7 +953,7 @@ console.log(uploadedFile);
|
||||
|
||||
Основные моменты:
|
||||
|
||||
* Uses the field's `universalIdentifier` (not its workspace-specific ID), so your upload code works across any workspace where your app is installed.
|
||||
* Он использует `universalIdentifier` поля (а не его идентификатор, специфичный для рабочего пространства), поэтому ваш код загрузки будет работать в любом рабочем пространстве, где установлено ваше приложение.
|
||||
* Возвращаемый `url` — это подписанный URL, который можно использовать для доступа к загруженному файлу.
|
||||
|
||||
### Пример Hello World
|
||||
|
||||
@@ -15,21 +15,21 @@ twenty-sdk, uygulamanız içinde kullandığınız türlendirilmiş yapı taşla
|
||||
|
||||
SDK, uygulama varlıklarınızı tanımlamak için yardımcı fonksiyonlar sağlar. [Varlık algılama](/l/tr/developers/extend/apps/getting-started#entity-detection) bölümünde açıklandığı gibi, varlıklarınızın algılanması için `export default define<Entity>({...})` kullanmalısınız:
|
||||
|
||||
| Fonksiyon | Amaç |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `defineApplication` | Uygulama meta verilerini yapılandırın (zorunlu, uygulama başına bir adet) |
|
||||
| `defineObject` | Alanlara sahip özel nesneler tanımlayın |
|
||||
| `defineField` | Extend existing objects with additional fields or define standalone relation fields |
|
||||
| `defineLogicFunction` | İşleyicilerle mantık fonksiyonları tanımlayın |
|
||||
| `definePreInstallLogicFunction` | Bir kurulum öncesi mantık işlevi tanımlayın (uygulama başına bir adet) |
|
||||
| `definePostInstallLogicFunction` | Bir kurulum sonrası mantık işlevi tanımlayın (uygulama başına bir adet) |
|
||||
| `defineFrontComponent` | Özel kullanıcı arayüzü için ön uç bileşenlerini tanımlayın |
|
||||
| `defineRole` | Rol izinlerini ve nesne erişimini yapılandırın |
|
||||
| `defineView` | Nesneler için kaydedilmiş görünümler tanımlayın |
|
||||
| `defineNavigationMenuItem` | Kenar çubuğu gezinme bağlantılarını tanımlayın |
|
||||
| `defineSkill` | Yapay zekâ ajanı yeteneklerini tanımlayın |
|
||||
| `defineAgent` | Define AI agents |
|
||||
| `definePageLayout` | Define custom page layouts |
|
||||
| Fonksiyon | Amaç |
|
||||
| -------------------------------- | ---------------------------------------------------------------------------------- |
|
||||
| `defineApplication` | Uygulama meta verilerini yapılandırın (zorunlu, uygulama başına bir adet) |
|
||||
| `defineObject` | Alanlara sahip özel nesneler tanımlayın |
|
||||
| `defineField` | Mevcut nesneleri ek alanlarla genişletin veya bağımsız ilişki alanları tanımlayın. |
|
||||
| `defineLogicFunction` | İşleyicilerle mantık fonksiyonları tanımlayın |
|
||||
| `definePreInstallLogicFunction` | Bir kurulum öncesi mantık işlevi tanımlayın (uygulama başına bir adet) |
|
||||
| `definePostInstallLogicFunction` | Bir kurulum sonrası mantık işlevi tanımlayın (uygulama başına bir adet) |
|
||||
| `defineFrontComponent` | Özel kullanıcı arayüzü için ön uç bileşenlerini tanımlayın |
|
||||
| `defineRole` | Rol izinlerini ve nesne erişimini yapılandırın |
|
||||
| `defineView` | Nesneler için kaydedilmiş görünümler tanımlayın |
|
||||
| `defineNavigationMenuItem` | Kenar çubuğu gezinme bağlantılarını tanımlayın |
|
||||
| `defineSkill` | Yapay zekâ ajanı yeteneklerini tanımlayın |
|
||||
| `defineAgent` | Yapay zekâ ajanlarını tanımlayın. |
|
||||
| `definePageLayout` | Özel sayfa düzenlerini tanımlayın. |
|
||||
|
||||
Bu fonksiyonlar, derleme zamanında yapılandırmanızı doğrular ve IDE otomatik tamamlama ile tür güvenliği sağlar.
|
||||
|
||||
@@ -112,7 +112,7 @@ export default defineObject({
|
||||
* `universalIdentifier` dağıtımlar arasında benzersiz ve kararlı olmalıdır.
|
||||
* Her alan bir `name`, `type`, `label` ve kendi kararlı `universalIdentifier` değerini gerektirir.
|
||||
* `fields` dizisi isteğe bağlıdır — özel alanlar olmadan da nesneler tanımlayabilirsiniz.
|
||||
* You can scaffold new objects using `yarn twenty add`, which guides you through naming, fields, and relationships.
|
||||
* `yarn twenty add` kullanarak, adlandırma, alanlar ve ilişkiler konusunda sizi yönlendirerek yeni nesneler oluşturabilirsiniz.
|
||||
|
||||
<Note>
|
||||
**Temel alanlar otomatik olarak oluşturulur.** Özel bir nesne tanımladığınızda Twenty, standart alanları otomatik olarak ekler
|
||||
@@ -124,7 +124,7 @@ ancak bu önerilmez.
|
||||
|
||||
### Mevcut nesneler üzerinde alanları tanımlama
|
||||
|
||||
Use `defineField()` to add fields to objects you don't own — such as standard Twenty objects (Person, Company, etc.) or objects from other apps. Unlike inline fields in `defineObject()`, standalone fields require an `objectUniversalIdentifier` to specify which object they extend:
|
||||
Sahibi olmadığınız nesnelere alan eklemek için `defineField()` kullanın — standart Twenty nesneleri (Person, Company, vb.) gibi. veya diğer uygulamalardaki nesneler. `defineObject()` içindeki satır içi alanların aksine, bağımsız alanlar hangi nesneyi genişlettiklerini belirtmek için bir `objectUniversalIdentifier` gerektirir:
|
||||
|
||||
```typescript
|
||||
// src/fields/company-loyalty-tier.field.ts
|
||||
@@ -147,35 +147,35 @@ export default defineField({
|
||||
|
||||
Önemli noktalar:
|
||||
|
||||
* `objectUniversalIdentifier` identifies the target object. For standard objects, use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` exported from `twenty-sdk`.
|
||||
* When defining fields inline in `defineObject()`, you do **not** need `objectUniversalIdentifier` — it's inherited from the parent object.
|
||||
* `defineField()` is the only way to add fields to objects you didn't create with `defineObject()`.
|
||||
* `objectUniversalIdentifier` hedef nesneyi tanımlar. Standart nesneler için, `twenty-sdk`'den dışa aktarılan `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`'ı kullanın.
|
||||
* Alanları `defineObject()` içinde satır içi tanımlarken, `objectUniversalIdentifier`'a ihtiyacınız yoktur — üst nesneden devralınır.
|
||||
* `defineField()`, `defineObject()` ile oluşturmadığınız nesnelere alan eklemenin tek yoludur.
|
||||
|
||||
### İlişkiler
|
||||
|
||||
Relations connect objects together. In Twenty, relations are always **bidirectional** — you define both sides, and each side references the other.
|
||||
İlişkiler nesneleri birbirine bağlar. Twenty'de ilişkiler her zaman **çift yönlüdür** — her iki tarafı da tanımlarsınız ve her taraf diğerine başvurur.
|
||||
|
||||
There are two relation types:
|
||||
İki ilişki türü vardır:
|
||||
|
||||
| İlişki türü | Açıklama | Has foreign key? |
|
||||
| ------------- | ------------------------------------------------------------- | ---------------------- |
|
||||
| `MANY_TO_ONE` | Many records of this object point to one record of the target | Yes (`joinColumnName`) |
|
||||
| `ONE_TO_MANY` | One record of this object has many records of the target | No (inverse side) |
|
||||
| İlişki türü | Açıklama | Yabancı anahtar var mı? |
|
||||
| ------------- | --------------------------------------------------------- | ----------------------- |
|
||||
| `MANY_TO_ONE` | Bu nesnenin birçok kaydı, hedefin bir kaydını işaret eder | Evet (`joinColumnName`) |
|
||||
| `ONE_TO_MANY` | Bu nesnenin bir kaydı, hedefin birçok kaydına sahiptir | Hayır (ters taraf) |
|
||||
|
||||
#### How relations work
|
||||
#### İlişkiler nasıl çalışır
|
||||
|
||||
Every relation requires **two fields** that reference each other:
|
||||
Her ilişki, birbirine referans veren iki alan gerektirir:
|
||||
|
||||
1. The **MANY_TO_ONE** side — lives on the object that holds the foreign key
|
||||
2. The **ONE_TO_MANY** side — lives on the object that owns the collection
|
||||
1. **MANY_TO_ONE** tarafı — yabancı anahtarı tutan nesne üzerinde bulunur
|
||||
2. **ONE_TO_MANY** tarafı — koleksiyona sahip olan nesne üzerinde bulunur
|
||||
|
||||
Both fields use `FieldType.RELATION` and cross-reference each other via `relationTargetFieldMetadataUniversalIdentifier`.
|
||||
Her iki alan da `FieldType.RELATION` kullanır ve `relationTargetFieldMetadataUniversalIdentifier` aracılığıyla birbirine karşılıklı referans verir.
|
||||
|
||||
#### Example: Post Card has many Recipients
|
||||
#### Örnek: Posta Kartı'nın birçok Alıcısı vardır
|
||||
|
||||
Suppose a `PostCard` can be sent to many `PostCardRecipient` records. Each recipient belongs to exactly one post card.
|
||||
Bir `PostCard`'ın birçok `PostCardRecipient` kaydına gönderilebildiğini varsayalım. Her alıcı tam olarak bir posta kartına aittir.
|
||||
|
||||
**Step 1: Define the ONE_TO_MANY side on PostCard** (the "one" side):
|
||||
**Adım 1: PostCard üzerinde ONE_TO_MANY tarafını tanımlayın** ("bir" taraf):
|
||||
|
||||
```typescript
|
||||
// src/fields/post-card-recipients-on-post-card.field.ts
|
||||
@@ -203,7 +203,7 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
**Step 2: Define the MANY_TO_ONE side on PostCardRecipient** (the "many" side — holds the foreign key):
|
||||
**Adım 2: PostCardRecipient üzerinde MANY_TO_ONE tarafını tanımlayın** ("çok" taraf — yabancı anahtarı tutar):
|
||||
|
||||
```typescript
|
||||
// src/fields/post-card-on-post-card-recipient.field.ts
|
||||
@@ -234,12 +234,12 @@ export default defineField({
|
||||
```
|
||||
|
||||
<Note>
|
||||
**Circular imports:** Both relation fields reference each other's `universalIdentifier`. To avoid circular import issues, export your field IDs as named constants from each file, and import them in the other file. The build system resolves these at compile time.
|
||||
**Döngüsel içe aktarmalar:** Her iki ilişki alanı da birbirlerinin `universalIdentifier` değerine referans verir. Döngüsel içe aktarma sorunlarından kaçınmak için, alan kimliklerinizi her dosyadan adlandırılmış sabitler olarak dışa aktarın ve diğer dosyada içe aktarın. Derleme sistemi bunları derleme zamanında çözer.
|
||||
</Note>
|
||||
|
||||
#### Relating to standard objects
|
||||
#### Standart nesnelerle ilişkilendirme
|
||||
|
||||
To create a relation with a built-in Twenty object (Person, Company, etc.), use `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS`:
|
||||
Yerleşik bir Twenty nesnesiyle (Person, Company, vb.) ilişki oluşturmak için `STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS` kullanın:
|
||||
|
||||
```typescript
|
||||
// src/fields/person-on-self-hosting-user.field.ts
|
||||
@@ -274,20 +274,20 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
#### Relation field properties
|
||||
#### İlişki alanı özellikleri
|
||||
|
||||
| Özellik | Zorunlu | Açıklama |
|
||||
| ------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `type` | Evet | Must be `FieldType.RELATION` |
|
||||
| `relationTargetObjectMetadataUniversalIdentifier` | Evet | The `universalIdentifier` of the target object |
|
||||
| `relationTargetFieldMetadataUniversalIdentifier` | Evet | The `universalIdentifier` of the matching field on the target object |
|
||||
| `universalSettings.relationType` | Evet | `RelationType.MANY_TO_ONE` or `RelationType.ONE_TO_MANY` |
|
||||
| `universalSettings.onDelete` | MANY_TO_ONE only | What happens when the referenced record is deleted: `CASCADE`, `SET_NULL`, `RESTRICT`, or `NO_ACTION` |
|
||||
| `universalSettings.joinColumnName` | MANY_TO_ONE only | Database column name for the foreign key (e.g., `postCardId`) |
|
||||
| Özellik | Zorunlu | Açıklama |
|
||||
| ------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| `type` | Evet | `FieldType.RELATION` olmalıdır |
|
||||
| `relationTargetObjectMetadataUniversalIdentifier` | Evet | Hedef nesnenin `universalIdentifier` değeri |
|
||||
| `relationTargetFieldMetadataUniversalIdentifier` | Evet | Hedef nesnedeki eşleşen alanın `universalIdentifier` değeri |
|
||||
| `universalSettings.relationType` | Evet | `RelationType.MANY_TO_ONE` veya `RelationType.ONE_TO_MANY` |
|
||||
| `universalSettings.onDelete` | Yalnızca MANY_TO_ONE | Başvurulan kayıt silindiğinde ne olacağı: `CASCADE`, `SET_NULL`, `RESTRICT` veya `NO_ACTION` |
|
||||
| `universalSettings.joinColumnName` | Yalnızca MANY_TO_ONE | Yabancı anahtar için veritabanı sütun adı (örn. `postCardId`) |
|
||||
|
||||
#### Inline relation fields in defineObject
|
||||
#### defineObject içinde satır içi ilişki alanları
|
||||
|
||||
You can also define relation fields directly inside `defineObject()`. In that case, omit `objectUniversalIdentifier` — it's inherited from the parent object:
|
||||
İlişki alanlarını doğrudan `defineObject()` içinde de tanımlayabilirsiniz. Bu durumda, `objectUniversalIdentifier`'ı atlayın — üst nesneden devralınır:
|
||||
|
||||
```typescript
|
||||
export default defineObject({
|
||||
@@ -354,21 +354,21 @@ Notlar:
|
||||
* `defaultRoleUniversalIdentifier`, rol dosyasıyla eşleşmelidir (aşağıya bakın).
|
||||
* Kurulum öncesi ve kurulum sonrası işlevler, manifest oluşturma sırasında otomatik olarak algılanır. Bkz. [Kurulum öncesi işlevler](#pre-install-functions) ve [Kurulum sonrası işlevler](#post-install-functions).
|
||||
|
||||
#### Marketplace metadata
|
||||
#### Pazaryeri meta verileri
|
||||
|
||||
If you plan to [publish your app](/l/tr/developers/extend/apps/publishing), these optional fields control how your app appears in the marketplace:
|
||||
Eğer [uygulamanızı yayımlamayı](/l/tr/developers/extend/apps/publishing) planlıyorsanız, bu isteğe bağlı alanlar uygulamanızın pazaryerinde nasıl görüneceğini kontrol eder:
|
||||
|
||||
| Alan | Açıklama |
|
||||
| ------------------ | --------------------------------------------------- |
|
||||
| `author` | Author or company name |
|
||||
| `category` | App category for marketplace filtering |
|
||||
| `logoUrl` | Path to your app logo (relative to `./assets/`) |
|
||||
| `screenshots` | Array of screenshot paths (relative to `./assets/`) |
|
||||
| `aboutDescription` | Longer markdown description for the "About" tab |
|
||||
| `websiteUrl` | Link to your website |
|
||||
| `termsUrl` | Link to terms of service |
|
||||
| `emailSupport` | Support email address |
|
||||
| `issueReportUrl` | Link to issue tracker |
|
||||
| Alan | Açıklama |
|
||||
| ------------------ | ------------------------------------------------------------- |
|
||||
| `author` | Yazar veya şirket adı |
|
||||
| `category` | Pazaryerinde filtreleme için uygulama kategorisi |
|
||||
| `logoUrl` | Uygulama logonuzun yolu (`./assets/` dizinine göre) |
|
||||
| `screenshots` | Ekran görüntüsü yollarının dizisi (`./assets/` dizinine göre) |
|
||||
| `aboutDescription` | "Hakkında" sekmesi için daha uzun bir markdown açıklaması |
|
||||
| `websiteUrl` | Web sitenize bağlantı |
|
||||
| `termsUrl` | Hizmet Koşulları'na bağlantı |
|
||||
| `emailSupport` | Destek e-posta adresi |
|
||||
| `issueReportUrl` | Sorun izleyicisine bağlantı |
|
||||
|
||||
#### Roller ve izinler
|
||||
|
||||
@@ -376,7 +376,7 @@ Uygulamalar, çalışma alanınızdaki nesneler ve eylemler üzerindeki izinleri
|
||||
|
||||
* `TWENTY_API_KEY` olarak enjekte edilen çalışma zamanı API anahtarı bu varsayılan fonksiyon rolünden türetilir.
|
||||
* Türlendirilmiş istemci, o role tanınan izinlerle sınırlandırılır.
|
||||
* Follow least-privilege: create a dedicated role with only the permissions your functions need, then reference its universal identifier.
|
||||
* En az ayrıcalık ilkesini izleyin: Yalnızca fonksiyonlarınızın ihtiyaç duyduğu izinlere sahip özel bir rol oluşturun ve ardından evrensel tanımlayıcısına referans verin.
|
||||
|
||||
##### Varsayılan fonksiyon rolü (*.role.ts)
|
||||
|
||||
@@ -429,7 +429,7 @@ Bu rolün `universalIdentifier` değeri daha sonra `application-config.ts` için
|
||||
|
||||
Notlar:
|
||||
|
||||
* Start from the scaffolded role, then progressively restrict it following least-privilege.
|
||||
* Oluşturulan rolden başlayın ve en az ayrıcalık ilkesini izleyerek bunu aşamalı olarak kısıtlayın.
|
||||
* `objectPermissions` ve `fieldPermissions` değerlerini, fonksiyonlarınızın ihtiyaç duyduğu nesneler/alanlarla değiştirin.
|
||||
* `permissionFlags`, platform düzeyindeki yeteneklere erişimi kontrol eder. Minimumda tutun; yalnızca ihtiyacınız olanları ekleyin.
|
||||
* Çalışan bir örneği Hello World uygulamasında görün: [`packages/twenty-apps/hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
|
||||
@@ -543,7 +543,7 @@ yarn twenty exec --preInstall
|
||||
* Uygulama başına yalnızca bir kurulum öncesi işlevine izin verilir. Birden fazla tespit edilirse manifest oluşturma hataya düşer.
|
||||
* İşlevin `universalIdentifier` değeri, oluşturma sırasında uygulama manifestinde otomatik olarak `preInstallLogicFunctionUniversalIdentifier` olarak ayarlanır — `defineApplication()` içinde buna atıfta bulunmanıza gerek yoktur.
|
||||
* Varsayılan zaman aşımı, daha uzun hazırlık görevlerine izin vermek için 300 saniye (5 dakika) olarak ayarlanmıştır.
|
||||
* Pre-install functions do not need triggers — they are invoked by the platform before installation or manually via `exec --preInstall`.
|
||||
* Kurulum öncesi işlevlerin tetikleyicilere ihtiyacı yoktur — kurulumdan önce platform tarafından veya `exec --preInstall` aracılığıyla manuel olarak çağrılırlar.
|
||||
|
||||
### Kurulum sonrası işlevler
|
||||
|
||||
@@ -581,7 +581,7 @@ yarn twenty exec --postInstall
|
||||
* Uygulama başına yalnızca bir kurulum sonrası işlevine izin verilir. Birden fazla tespit edilirse manifest oluşturma hataya düşer.
|
||||
* İşlevin `universalIdentifier` değeri, oluşturma sırasında uygulama manifestinde otomatik olarak `postInstallLogicFunctionUniversalIdentifier` olarak ayarlanır — `defineApplication()` içinde buna atıfta bulunmanıza gerek yoktur.
|
||||
* Varsayılan zaman aşımı, veri tohumlama gibi daha uzun kurulum görevlerine izin vermek için 300 saniye (5 dakika) olarak ayarlanmıştır.
|
||||
* Post-install functions do not need triggers — they are invoked by the platform during installation or manually via `exec --postInstall`.
|
||||
* Kurulum sonrası işlevlerin tetikleyicilere ihtiyacı yoktur — kurulum sırasında platform tarafından veya `exec --postInstall` aracılığıyla manuel olarak çağrılırlar.
|
||||
|
||||
### Rota tetikleyicisi yükü
|
||||
|
||||
@@ -625,15 +625,15 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
`RoutePayload` türünün yapısı şu şekildedir:
|
||||
|
||||
| Özellik | Tür | Açıklama |
|
||||
| ---------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------- |
|
||||
| `headers` | `Record<string, string \| undefined>` | HTTP başlıkları (`forwardedRequestHeaders` içinde listelenenlerle sınırlı) |
|
||||
| `queryStringParameters` | `Record<string, string \| undefined>` | Sorgu dizesi parametreleri (birden çok değer virgülle birleştirilir) |
|
||||
| `pathParameters` | `Record<string, string \| undefined>` | Path parameters extracted from the route pattern (e.g., `/users/:id` -> `{ id: '123' }`) |
|
||||
| `body` | `object \| null` | Ayrıştırılmış istek gövdesi (JSON) |
|
||||
| `isBase64Encoded` | `boolean` | Gövdenin base64 ile kodlanıp kodlanmadığı |
|
||||
| `requestContext.http.method` | `string` | HTTP yöntemi (GET, POST, PUT, PATCH, DELETE) |
|
||||
| `requestContext.http.path` | `string` | Ham istek yolu |
|
||||
| Özellik | Tür | Açıklama |
|
||||
| ---------------------------- | ------------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| `headers` | `Record<string, string \| undefined>` | HTTP başlıkları (`forwardedRequestHeaders` içinde listelenenlerle sınırlı) |
|
||||
| `queryStringParameters` | `Record<string, string \| undefined>` | Sorgu dizesi parametreleri (birden çok değer virgülle birleştirilir) |
|
||||
| `pathParameters` | `Record<string, string \| undefined>` | Rota deseninden çıkarılan yol parametreleri (örn., `/users/:id` -> `{ id: '123' }`) |
|
||||
| `body` | `object \| null` | Ayrıştırılmış istek gövdesi (JSON) |
|
||||
| `isBase64Encoded` | `boolean` | Gövdenin base64 ile kodlanıp kodlanmadığı |
|
||||
| `requestContext.http.method` | `string` | HTTP yöntemi (GET, POST, PUT, PATCH, DELETE) |
|
||||
| `requestContext.http.path` | `string` | Ham istek yolu |
|
||||
|
||||
### HTTP başlıklarını iletme
|
||||
|
||||
@@ -675,7 +675,7 @@ const handler = async (event: RoutePayload) => {
|
||||
|
||||
Yeni fonksiyonları iki şekilde oluşturabilirsiniz:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new logic function. Bu, bir işleyici ve yapılandırma içeren bir başlangıç dosyası oluşturur.
|
||||
* **Şablondan**: `yarn twenty add` çalıştırın ve yeni bir mantık fonksiyonu ekleme seçeneğini seçin. Bu, bir işleyici ve yapılandırma içeren bir başlangıç dosyası oluşturur.
|
||||
* **Manuel**: Yeni bir `*.logic-function.ts` dosyası oluşturun ve aynı deseni izleyerek `defineLogicFunction()` kullanın.
|
||||
|
||||
### Bir mantık işlevini araç olarak işaretleme
|
||||
@@ -776,7 +776,7 @@ export default defineFrontComponent({
|
||||
|
||||
Yeni ön uç bileşenlerini iki şekilde oluşturabilirsiniz:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new front component.
|
||||
* **Şablondan**: `yarn twenty add` çalıştırın ve yeni bir ön uç bileşeni ekleme seçeneğini seçin.
|
||||
* **Manuel**: Aynı deseni izleyerek yeni bir `.tsx` dosyası oluşturun ve `defineFrontComponent()` kullanın.
|
||||
|
||||
### Beceriler
|
||||
@@ -811,21 +811,21 @@ export default defineSkill({
|
||||
|
||||
Yeni yetenekleri iki şekilde oluşturabilirsiniz:
|
||||
|
||||
* **Scaffolded**: Run `yarn twenty add` and choose the option to add a new skill.
|
||||
* **Şablondan**: `yarn twenty add` çalıştırın ve yeni bir yetenek ekleme seçeneğini seçin.
|
||||
* **Manuel**: Yeni bir dosya oluşturun ve aynı deseni izleyerek `defineSkill()` kullanın.
|
||||
|
||||
### Typed API clients (`twenty-client-sdk`)
|
||||
### Tipli API istemcileri (`twenty-client-sdk`)
|
||||
|
||||
The `twenty-client-sdk` package provides two typed GraphQL clients for interacting with the Twenty API from your logic functions and front components:
|
||||
`twenty-client-sdk` paketi, mantık fonksiyonlarınızdan ve ön uç bileşenlerinizden Twenty API ile etkileşim kurmak için iki tipli GraphQL istemcisi sağlar:
|
||||
|
||||
| İstemci | İçe Aktar | Endpoint | Generated? |
|
||||
| ------------------- | ---------------------------- | ---------------------------------------------- | ---------------------- |
|
||||
| `CoreApiClient` | `twenty-client-sdk/core` | `/graphql` — workspace data (records, objects) | Yes, at dev/build time |
|
||||
| `MetadataApiClient` | `twenty-client-sdk/metadata` | `/metadata` — workspace config, file uploads | No, ships pre-built |
|
||||
| İstemci | İçe Aktar | Uç nokta | Oluşturuldu mu? |
|
||||
| ------------------- | ---------------------------- | ------------------------------------------------------------- | --------------------------------------- |
|
||||
| `CoreApiClient` | `twenty-client-sdk/core` | `/graphql` — çalışma alanı verileri (kayıtlar, nesneler) | Evet, geliştirme/derleme zamanında |
|
||||
| `MetadataApiClient` | `twenty-client-sdk/metadata` | `/metadata` — çalışma alanı yapılandırması, dosya yüklemeleri | Hayır, önceden hazırlanmış olarak gelir |
|
||||
|
||||
#### CoreApiClient
|
||||
|
||||
`CoreApiClient` is the main client for querying and mutating workspace data. It is **generated from your workspace schema** during `yarn twenty dev` or `yarn twenty build`, so it's fully typed to match your objects and fields.
|
||||
`CoreApiClient`, çalışma alanı verilerini sorgulamak ve değiştirmek için ana istemcidir. `yarn twenty dev` veya `yarn twenty build` sırasında çalışma alanı şemanızdan oluşturulur; bu nedenle nesnelerinize ve alanlarınıza uyacak şekilde tamamen tiplendirilmiştir.
|
||||
|
||||
```typescript
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
@@ -859,15 +859,15 @@ const { createCompany } = await client.mutation({
|
||||
});
|
||||
```
|
||||
|
||||
The client uses a selection-set syntax: pass `true` to include a field, use `__args` for arguments, and nest objects for relations. You get full autocompletion and type checking based on your workspace schema.
|
||||
İstemci bir seçim kümesi sözdizimi kullanır: Bir alanı dahil etmek için `true` geçin, bağımsız değişkenler için `__args` kullanın ve ilişkiler için nesneleri iç içe yerleştirin. Çalışma alanı şemanıza göre tam otomatik tamamlama ve tip denetimi elde edersiniz.
|
||||
|
||||
<Note>
|
||||
**CoreApiClient is generated at dev/build time.** If you try to use it without running `yarn twenty dev` or `yarn twenty build` first, it throws an error. The generation happens automatically — the CLI introspects your workspace's GraphQL schema, generates a typed client using `@genql/cli`, writes the generated sources to `node_modules/twenty-client-sdk/dist/core/generated/`, and replaces the stubs in `node_modules/twenty-client-sdk/dist/core.mjs` and `node_modules/twenty-client-sdk/dist/core.cjs`.
|
||||
**CoreApiClient geliştirme/derleme zamanında oluşturulur.** Bunu önce `yarn twenty dev` veya `yarn twenty build` çalıştırmadan kullanmaya çalışırsanız, hata verir. Oluşturma otomatik olarak gerçekleşir — CLI, çalışma alanınızın GraphQL şemasını inceler, `@genql/cli` kullanarak tipli bir istemci üretir, üretilen kaynakları `node_modules/twenty-client-sdk/dist/core/generated/` dizinine yazar ve `node_modules/twenty-client-sdk/dist/core.mjs` ile `node_modules/twenty-client-sdk/dist/core.cjs` içindeki taslakları değiştirir.
|
||||
</Note>
|
||||
|
||||
#### Using CoreSchema for type annotations
|
||||
#### Tür açıklamaları için CoreSchema'yı kullanma
|
||||
|
||||
`CoreSchema` provides TypeScript types matching your workspace objects, useful for typing component state or function parameters:
|
||||
`CoreSchema`, çalışma alanı nesnelerinize uyan TypeScript türleri sağlar; bileşen durumunu veya işlev parametrelerini tiplemek için kullanışlıdır:
|
||||
|
||||
```typescript
|
||||
import { CoreApiClient, CoreSchema } from 'twenty-client-sdk/core';
|
||||
@@ -890,7 +890,7 @@ setCompany(result.company);
|
||||
|
||||
#### MetadataApiClient
|
||||
|
||||
`MetadataApiClient` ships pre-built with the SDK (no generation required). It queries the `/metadata` endpoint for workspace configuration, applications, and file uploads:
|
||||
`MetadataApiClient`, SDK ile birlikte önceden hazırlanmış olarak gelir (oluşturma gerektirmez). Çalışma alanı yapılandırması, uygulamalar ve dosya yüklemeleri için `/metadata` uç noktasını sorgular:
|
||||
|
||||
```typescript
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -912,18 +912,18 @@ const { findManyApplications } = await metadataClient.query({
|
||||
});
|
||||
```
|
||||
|
||||
#### Runtime credentials
|
||||
#### Çalışma zamanı kimlik bilgileri
|
||||
|
||||
When your code runs on Twenty (logic functions or front components), the platform injects credentials as environment variables:
|
||||
Kodunuz Twenty üzerinde çalıştığında (mantık işlevleri veya ön uç bileşenleri), platform kimlik bilgilerini ortam değişkenleri olarak enjekte eder:
|
||||
|
||||
* `TWENTY_API_URL` — Base URL of the Twenty API
|
||||
* `TWENTY_API_KEY` — Short-lived key scoped to your application's default function role
|
||||
* `TWENTY_API_URL` — Twenty API'nin temel URL'si
|
||||
* `TWENTY_API_KEY` — Uygulamanızın varsayılan fonksiyon rolü kapsamına sahip kısa ömürlü anahtar
|
||||
|
||||
You do **not** need to pass these to the clients — they read from `process.env` automatically. The API key's permissions are determined by the role referenced in `defaultRoleUniversalIdentifier` in your `application-config.ts`.
|
||||
Bunları istemcilere iletmeniz gerekmez — otomatik olarak `process.env`'den okurlar. API anahtarının izinleri, `application-config.ts` içinde `defaultRoleUniversalIdentifier` ile referans verilen role göre belirlenir.
|
||||
|
||||
#### Dosya yükleme
|
||||
|
||||
`MetadataApiClient` includes an `uploadFile` method for attaching files to file-type fields. It implements the [GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec):
|
||||
`MetadataApiClient`, dosya türü alanlara dosya eklemek için bir `uploadFile` yöntemi içerir. [GraphQL çok parçalı istek spesifikasyonunu](https://github.com/jaydenseric/graphql-multipart-request-spec) uygular:
|
||||
|
||||
```typescript
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -953,7 +953,7 @@ console.log(uploadedFile);
|
||||
|
||||
Önemli noktalar:
|
||||
|
||||
* Uses the field's `universalIdentifier` (not its workspace-specific ID), so your upload code works across any workspace where your app is installed.
|
||||
* Alan için `universalIdentifier` kullanır (çalışma alanına özgü kimliği değil), böylece yükleme kodunuz uygulamanızın yüklü olduğu herhangi bir çalışma alanında çalışır.
|
||||
* Döndürülen `url`, yüklenen dosyaya erişmek için kullanabileceğiniz imzalı bir URL'dir.
|
||||
|
||||
### Hello World örneği
|
||||
|
||||
Reference in New Issue
Block a user