i18n - docs translations (#20366)
Created by Github action Co-authored-by: github-actions <github-actions@twenty.com>
This commit is contained in:
committed by
GitHub
parent
24e64350ee
commit
95bc8aea28
@@ -1,15 +1,15 @@
|
||||
---
|
||||
title: Application Config
|
||||
description: Declare your app's identity, default role, variables, and marketplace metadata with defineApplication.
|
||||
title: Uygulama Yapılandırması
|
||||
description: Uygulamanızın kimliğini, varsayılan rolünü, değişkenlerini ve pazar yeri meta verilerini `defineApplication` ile bildirin.
|
||||
icon: rocket
|
||||
---
|
||||
|
||||
Every app must have exactly one `defineApplication` call. It declares:
|
||||
Her uygulamanın, tam olarak bir adet `defineApplication` çağrısı olması gerekir. Bu çağrı şunları bildirir:
|
||||
|
||||
* **Identity** — universal identifier, display name, description.
|
||||
* **Permissions** — which role its logic functions and front components run under.
|
||||
* **Variables** *(optional)* — key–value pairs exposed to your code as environment variables.
|
||||
* **Pre-install / post-install hooks** *(optional)* — see [Logic Functions](/l/tr/developers/extend/apps/logic/logic-functions).
|
||||
* **Kimlik** — evrensel tanımlayıcı, görünen ad, açıklama.
|
||||
* **İzinler** — mantık fonksiyonlarının ve ön uç bileşenlerinin hangi rol altında çalıştığı.
|
||||
* **Değişkenler** *(isteğe bağlı)* — kodunuza ortam değişkenleri olarak sunulan anahtar–değer çiftleri.
|
||||
* **Kurulum öncesi / kurulum sonrası kancalar** *(isteğe bağlı)* — bkz. [Mantık Fonksiyonları](/l/tr/developers/extend/apps/logic/logic-functions).
|
||||
|
||||
```ts src/application-config.ts
|
||||
import { defineApplication } from 'twenty-sdk/define';
|
||||
@@ -31,35 +31,35 @@ export default defineApplication({
|
||||
});
|
||||
```
|
||||
|
||||
Notes:
|
||||
Notlar:
|
||||
|
||||
* `universalIdentifier` fields are deterministic IDs you own. Generate them once and keep them stable across syncs.
|
||||
* `applicationVariables` become environment variables for your functions and front components (e.g., `DEFAULT_RECIPIENT_NAME` is available as `process.env.DEFAULT_RECIPIENT_NAME`).
|
||||
* `defaultRoleUniversalIdentifier` must reference a role defined with [`defineRole()`](/l/tr/developers/extend/apps/config/roles).
|
||||
* Pre-install and post-install functions are detected automatically during the manifest build — you do not need to reference them in `defineApplication()`.
|
||||
* `universalIdentifier` alanları, size ait deterministik kimliklerdir. Bunları bir kez oluşturun ve senkronizasyonlar boyunca kararlı tutun.
|
||||
* `applicationVariables`, fonksiyonlarınız ve ön uç bileşenleriniz için ortam değişkenlerine dönüşür (örn. `DEFAULT_RECIPIENT_NAME`, `process.env.DEFAULT_RECIPIENT_NAME` olarak kullanılabilir).
|
||||
* `defaultRoleUniversalIdentifier`, [`defineRole()`](/l/tr/developers/extend/apps/config/roles) ile tanımlanmış bir role referans vermelidir.
|
||||
* Kurulum öncesi ve kurulum sonrası fonksiyonlar manifest derlemesi sırasında otomatik olarak algılanır — bunlara `defineApplication()` içinde referans vermeniz gerekmez.
|
||||
|
||||
## Default function role
|
||||
## Varsayılan fonksiyon rolü
|
||||
|
||||
The `defaultRoleUniversalIdentifier` controls what the app's logic functions and front components can access:
|
||||
`defaultRoleUniversalIdentifier`, uygulamanın mantık fonksiyonlarının ve ön uç bileşenlerinin nelere erişebileceğini kontrol eder:
|
||||
|
||||
* The runtime token injected as `TWENTY_APP_ACCESS_TOKEN` is derived from this role.
|
||||
* The typed API client is restricted to the permissions granted to that role.
|
||||
* Follow least-privilege: declare only the permissions your functions need.
|
||||
* `TWENTY_APP_ACCESS_TOKEN` olarak enjekte edilen çalışma zamanı belirteci bu rolden türetilir.
|
||||
* Türlendirilmiş API istemcisi, o role tanınan izinlerle sınırlandırılır.
|
||||
* En az ayrıcalık ilkesini izleyin: yalnızca fonksiyonlarınızın ihtiyaç duyduğu izinleri bildirin.
|
||||
|
||||
When you scaffold a new app, the CLI creates a starter role file at `src/roles/default-role.ts`. See [Roles & Permissions](/l/tr/developers/extend/apps/config/roles) for the full reference.
|
||||
Yeni bir uygulama iskeleti oluşturduğunuzda, CLI `src/roles/default-role.ts` konumunda başlangıç bir rol dosyası oluşturur. Tam başvuru için bkz. [Roller ve İzinler](/l/tr/developers/extend/apps/config/roles).
|
||||
|
||||
## Marketplace metadata
|
||||
## Pazaryeri meta verileri
|
||||
|
||||
If you plan to [publish your app](/l/tr/developers/extend/apps/operations/publishing), these optional fields control how it appears in the marketplace:
|
||||
Eğer [uygulamanızı yayımlamayı](/l/tr/developers/extend/apps/operations/publishing) planlıyorsanız, bu isteğe bağlı alanlar uygulamanızın pazaryerinde nasıl görüneceğini kontrol eder:
|
||||
|
||||
| Field | Description |
|
||||
| ------------------ | -------------------------------------------------------------------------------------------------------------------- |
|
||||
| `author` | Author or company name |
|
||||
| `category` | App category for marketplace filtering |
|
||||
| `logoUrl` | Path to your app logo (e.g., `public/logo.png`) |
|
||||
| `screenshots` | Array of screenshot paths (e.g., `public/screenshot-1.png`) |
|
||||
| `aboutDescription` | Longer markdown description for the "About" tab. If omitted, the marketplace uses the package's `README.md` from npm |
|
||||
| `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` | Uygulamanızın logosuna giden yol (örn. `public/logo.png`) |
|
||||
| `screenshots` | Ekran görüntüsü yollarının dizisi (örn. `public/screenshot-1.png`) |
|
||||
| `aboutDescription` | "Hakkında" sekmesi için daha uzun bir markdown açıklaması. Belirtilmezse, pazaryeri npm'deki paketin `README.md` dosyasını kullanır |
|
||||
| `websiteUrl` | Web sitenize bağlantı |
|
||||
| `termsUrl` | Hizmet Koşulları'na bağlantı |
|
||||
| `emailSupport` | Destek e-posta adresi |
|
||||
| `issueReportUrl` | Sorun izleyicisine bağlantı |
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
---
|
||||
title: Install Hooks
|
||||
description: Run logic before or after the install — seed data, back up records, validate the upgrade.
|
||||
icon: wrench
|
||||
title: Kurulum Kancaları
|
||||
description: Kurulumdan önce veya sonra mantığı çalıştırın — veri tohumlayın, kayıtları yedekleyin, yükseltmeyi doğrulayın.
|
||||
icon: anahtar
|
||||
---
|
||||
|
||||
Install hooks are special logic functions that run during the install or upgrade lifecycle. They share the same handler runtime as regular [logic functions](/l/tr/developers/extend/apps/logic/logic-functions) and receive an `InstallPayload`, but they're declared with their own define functions — `definePostInstallLogicFunction()` and `definePreInstallLogicFunction()` — and live outside the normal trigger model (HTTP, cron, database events).
|
||||
Kurulum kancaları, kurulum veya yükseltme yaşam döngüsü sırasında çalışan özel mantık işlevleridir. Bunlar, normal [mantık işlevleri](/l/tr/developers/extend/apps/logic/logic-functions) ile aynı işleyici çalışma zamanını paylaşır ve bir `InstallPayload` alırlar, ancak kendi tanımlama işlevleri — `definePostInstallLogicFunction()` ve `definePreInstallLogicFunction()` — ile bildirilirler ve normal tetikleyici modelinin (HTTP, cron, veritabanı olayları) dışında yaşarlar.
|
||||
|
||||
Each app may define **at most one pre-install** and **at most one post-install** function. The manifest build will error if more than one of either is detected.
|
||||
Her uygulama **en fazla bir kurulum öncesi** ve **en fazla bir kurulum sonrası** işlev tanımlayabilir. Her ikisinden de birden fazla tespit edilirse manifest oluşturma hataya düşer.
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
@@ -20,9 +20,9 @@ Each app may define **at most one pre-install** and **at most one post-install**
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="definePostInstallLogicFunction" description="Runs after the workspace metadata migration is applied">
|
||||
<Accordion title="definePostInstallLogicFunction" description="Çalışma alanı üstveri (metadata) geçişi uygulanıp tamamlandıktan sonra çalışır">
|
||||
|
||||
A post-install function runs automatically once your app has finished installing on a workspace. The server executes it **after** the app's metadata has been synchronized and the SDK client has been generated, so the workspace is fully ready to use and the new schema is in place. Typical use cases include seeding default data, creating initial records, configuring workspace settings, or provisioning resources on third-party services.
|
||||
Kurulum sonrası işlev, uygulamanız bir çalışma alanına kurulmasını tamamladıktan sonra otomatik olarak çalışır. Sunucu, uygulamanın meta verileri senkronize edildikten ve SDK istemcisi oluşturulduktan **sonra** bunu yürütür; böylece çalışma alanı tamamen kullanıma hazırdır ve yeni şema kullanıma alınmıştır. Tipik kullanım örnekleri arasında varsayılan verilerin tohumlanması, başlangıç kayıtlarının oluşturulması, çalışma alanı ayarlarının yapılandırılması veya üçüncü taraf hizmetlerde kaynak sağlanması yer alır.
|
||||
|
||||
```ts src/logic-functions/post-install.ts
|
||||
import { definePostInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
|
||||
@@ -42,30 +42,30 @@ export default definePostInstallLogicFunction({
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the post-install function at any time using the CLI:
|
||||
Ayrıca kurulum sonrası işlevi istediğiniz zaman CLI kullanarak manuel olarak çalıştırabilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty exec --postInstall
|
||||
```
|
||||
|
||||
Key points:
|
||||
* Post-install functions use `definePostInstallLogicFunction()` — a specialized variant that omits trigger settings (`cronTriggerSettings`, `databaseEventTriggerSettings`, `httpRouteTriggerSettings`, `toolTriggerSettings`, `workflowActionTriggerSettings`).
|
||||
* The handler receives an `InstallPayload` with `{ previousVersion?: string; newVersion: string }` — `newVersion` is the version being installed, and `previousVersion` is the version that was previously installed (or `undefined` on a fresh install). Use these values to distinguish fresh installs from upgrades and to run version-specific migration logic.
|
||||
* **When the hook runs**: on fresh installs only, by default. Pass `shouldRunOnVersionUpgrade: true` if you also want it to run when the app is upgraded from a previous version. When omitted, the flag defaults to `false` and upgrades skip the hook.
|
||||
* **Execution model — async by default, sync opt-in**: the `shouldRunSynchronously` flag controls *how* post-install is executed.
|
||||
* `shouldRunSynchronously: false` *(default)* — the hook is **enqueued on the message queue** with `retryLimit: 3` and runs asynchronously in a worker. The install response returns as soon as the job is enqueued, so a slow or failing handler does not block the caller. The worker will retry up to three times. **Use this for long-running jobs** — seeding large datasets, calling slow third-party APIs, provisioning external resources, anything that might exceed a reasonable HTTP response window.
|
||||
* `shouldRunSynchronously: true` — the hook is executed **inline during the install flow** (same executor as pre-install). The install request blocks until the handler finishes, and if it throws, the install caller receives a `POST_INSTALL_ERROR`. No automatic retries. **Use this for fast, must-complete-before-response work** — for example, emitting a validation error to the user, or quick setup that the client will rely on immediately after the install call returns. Keep in mind the metadata migration has already been applied by the time post-install runs, so a sync-mode failure does **not** roll back the schema changes — it only surfaces the error.
|
||||
* Make sure your handler is idempotent. In async mode the queue may retry up to three times; in either mode the hook may run again on upgrades when `shouldRunOnVersionUpgrade: true`.
|
||||
* The environment variables `APPLICATION_ID`, `APP_ACCESS_TOKEN`, and `API_URL` are available inside the handler (same as any other logic function), so you can call the Twenty API with an application access token scoped to your app.
|
||||
* Only one post-install function is allowed per application. The manifest build will error if more than one is detected.
|
||||
* The function's `universalIdentifier`, `shouldRunOnVersionUpgrade`, and `shouldRunSynchronously` are automatically attached to the application manifest under the `postInstallLogicFunction` field during the build — you do not need to reference them in [`defineApplication()`](/l/tr/developers/extend/apps/config/application).
|
||||
* The default timeout is set to 300 seconds (5 minutes) to allow for longer setup tasks like data seeding.
|
||||
* **Not executed in dev mode**: when an app is registered locally (via `yarn twenty dev`), the server skips the install flow entirely and syncs files directly through the CLI watcher — so post-install never runs in dev mode, regardless of `shouldRunSynchronously`. Use `yarn twenty exec --postInstall` to trigger it manually against a running workspace.
|
||||
Önemli noktalar:
|
||||
* Kurulum sonrası işlevler `definePostInstallLogicFunction()` kullanır — tetikleyici ayarlarını atlayan (`cronTriggerSettings`, `databaseEventTriggerSettings`, `httpRouteTriggerSettings`, `toolTriggerSettings`, `workflowActionTriggerSettings`) özel bir varyanttır.
|
||||
* İşleyici, `{ previousVersion?: string; newVersion: string }` içeren bir `InstallPayload` alır — `newVersion`, yüklenen sürümdür; `previousVersion` ise daha önce yüklü olan sürümdür (veya ilk kurulumda `undefined`). Bu değerleri ilk kurulumları yükseltmelerden ayırt etmek ve sürüme özgü geçiş (migration) mantığını çalıştırmak için kullanın.
|
||||
* **Kanca ne zaman çalışır**: varsayılan olarak yalnızca ilk kurulumlarda. Uygulama önceki bir sürümden yükseltildiğinde de çalışmasını istiyorsanız `shouldRunOnVersionUpgrade: true` geçin. Belirtilmediğinde, bayrak varsayılan olarak `false` olur ve yükseltmeler kancayı atlar.
|
||||
* **Yürütme modeli — varsayılan olarak eşzamansız, isteğe bağlı senkron**: `shouldRunSynchronously` bayrağı kurulum sonrası işlemin *nasıl* yürütüldüğünü kontrol eder.
|
||||
* `shouldRunSynchronously: false` *(varsayılan)* — kanca, `retryLimit: 3` ile **mesaj kuyruğuna alınır** ve bir worker içinde eşzamansız çalışır. İş kuyruğa alınır alınmaz kurulum yanıtı döner; dolayısıyla yavaşlayan veya hata veren bir işleyici çağıranı engellemez. Worker en fazla üç kez yeniden deneyecektir. **Bunu uzun süre çalışan işler için kullanın** — büyük veri kümelerini tohumlama, yavaş üçüncü taraf API'lerini çağırma, harici kaynakları sağlama; makul bir HTTP yanıt süresini aşabilecek her şey.
|
||||
* `shouldRunSynchronously: true` — kanca **kurulum akışı sırasında satır içi** olarak yürütülür (kurulum öncesi ile aynı yürütücü). İşleyici bitene kadar kurulum isteği engellenir; hata fırlatırsa, kurulum çağıranı bir `POST_INSTALL_ERROR` alır. Otomatik yeniden deneme yok. **Bunu, yanıt dönmeden mutlaka tamamlanması gereken hızlı işler için kullanın** — örneğin, kullanıcıya bir doğrulama hatası iletmek veya kurulum çağrısı döner dönmez istemcinin ihtiyaç duyacağı hızlı bir kurulum yapmak. Kurulum sonrası çalıştığında, üstveri (metadata) geçişinin zaten uygulanmış olduğunu unutmayın; bu nedenle, senkron moddaki bir hata şema değişikliklerini **geri almaz** — yalnızca hatayı görünür kılar.
|
||||
* İşleyicinizin idempotent olduğundan emin olun. Eşzamansız modda kuyruk en fazla üç kez yeniden deneyebilir; her iki modda da `shouldRunOnVersionUpgrade: true` iken yükseltmelerde kanca tekrar çalışabilir.
|
||||
* Ortam değişkenleri `APPLICATION_ID`, `APP_ACCESS_TOKEN` ve `API_URL` işleyici içinde kullanılabilir (diğer mantık işlevlerinde olduğu gibi), böylece uygulamanıza özel kapsamda bir uygulama erişim belirteciyle Twenty API'sini çağırabilirsiniz.
|
||||
* Uygulama başına yalnızca bir kurulum sonrası işlevine izin verilir. Birden fazla tespit edilirse manifest oluşturma hataya düşer.
|
||||
* İşlevin `universalIdentifier`, `shouldRunOnVersionUpgrade` ve `shouldRunSynchronously` değerleri, derleme sırasında uygulama manifestine `postInstallLogicFunction` alanı altında otomatik olarak eklenir — bunlara [`defineApplication()`](/l/tr/developers/extend/apps/config/application) içinde 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.
|
||||
* **Geliştirme modunda çalıştırılmaz**: bir uygulama yerel olarak kaydedildiğinde (`yarn twenty dev` aracılığıyla), sunucu kurulum akışını tamamen atlar ve dosyaları doğrudan CLI watcher üzerinden eşitler — bu nedenle, `shouldRunSynchronously` ne olursa olsun, kurulum sonrası geliştirme modunda hiç çalışmaz. Çalışan bir çalışma alanında bunu elle tetiklemek için `yarn twenty exec --postInstall` kullanın.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="definePreInstallLogicFunction" description="Runs before the workspace metadata migration is applied">
|
||||
<Accordion title="definePreInstallLogicFunction" description="Çalışma alanı üstveri (metadata) geçişi uygulanmadan önce çalışır">
|
||||
|
||||
A pre-install function runs automatically during installation, **before the workspace metadata migration is applied**. It shares the same payload shape as post-install (`InstallPayload`), but it is positioned earlier in the install flow so it can prepare state that the upcoming migration depends on — typical uses include backing up data, validating compatibility with the new schema, or archiving records that are about to be restructured or dropped.
|
||||
Kurulum öncesi işlev, kurulum sırasında otomatik olarak çalışır ve **çalışma alanı üstveri (metadata) geçişi uygulanmadan önce** yürütülür. Kurulum sonrası ile (`InstallPayload`) aynı yük (payload) biçimini paylaşır, ancak kurulum akışında daha erken konumlandığından yaklaşan geçişin bağlı olduğu durumu hazırlayabilir — tipik kullanımlar arasında verileri yedeklemek, yeni şemayla uyumluluğu doğrulamak veya yeniden yapılandırılacak ya da kaldırılacak kayıtları arşivlemek yer alır.
|
||||
|
||||
```ts src/logic-functions/pre-install.ts
|
||||
import { definePreInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
|
||||
@@ -84,35 +84,35 @@ export default definePreInstallLogicFunction({
|
||||
});
|
||||
```
|
||||
|
||||
You can also manually execute the pre-install function at any time using the CLI:
|
||||
Ayrıca kurulum öncesi işlevi istediğiniz zaman CLI kullanarak manuel olarak çalıştırabilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty exec --preInstall
|
||||
```
|
||||
|
||||
Key points:
|
||||
* Pre-install functions use `definePreInstallLogicFunction()` — same specialized config as post-install, just attached to a different lifecycle slot.
|
||||
* Both pre- and post-install handlers receive the same `InstallPayload` type: `{ previousVersion?: string; newVersion: string }`. Import it once and reuse it for both hooks.
|
||||
* **When the hook runs**: positioned just before the workspace metadata migration (`synchronizeFromManifest`). Before executing, the server runs a purely additive "pared-down sync" that registers the **new** version's pre-install function in the workspace metadata — nothing else is touched — and then executes it. Because this sync is additive-only, the previous version's objects, fields, and data are still intact when your handler runs: you can safely read and back up pre-migration state.
|
||||
* **Execution model**: pre-install is executed **synchronously** and **blocks the install**. If the handler throws, the install is aborted before any schema changes are applied — the workspace stays on the previous version in a consistent state. This is intentional: pre-install is your last chance to refuse a risky upgrade.
|
||||
* As with post-install, only one pre-install function is allowed per application. It is attached to the application manifest under `preInstallLogicFunction` automatically during the build.
|
||||
* **Not executed in dev mode**: same as post-install — the install flow is skipped entirely for locally-registered apps, so pre-install never runs under `yarn twenty dev`. Use `yarn twenty exec --preInstall` to trigger it manually.
|
||||
Önemli noktalar:
|
||||
* Kurulum öncesi işlevler `definePreInstallLogicFunction()` kullanır — kurulum sonrasıyla aynı özel yapılandırma, sadece yaşam döngüsünde farklı bir yuvaya eklenir.
|
||||
* Hem kurulum öncesi hem de kurulum sonrası işleyiciler aynı `InstallPayload` türünü alır: `{ previousVersion?: string; newVersion: string }`. Bunu bir kez içe aktarın ve her iki kanca için yeniden kullanın.
|
||||
* **Kanca ne zaman çalışır**: çalışma alanı üstveri (metadata) geçişinden hemen önce konumlandırılır (`synchronizeFromManifest`). Çalıştırmadan önce, sunucu yalnızca ekleyici bir "indirgenmiş eşitleme" yürütür; bu, çalışma alanı üstverisinde **yeni** sürümün kurulum öncesi işlevini kaydeder — başka hiçbir şeye dokunulmaz — ve ardından bunu yürütür. Bu eşitleme yalnızca ekleyici olduğundan, işleyiciniz çalıştığında önceki sürümün nesneleri, alanları ve verileri hâlâ sağlamdır: geçiş öncesi durumu güvenle okuyabilir ve yedekleyebilirsiniz.
|
||||
* **Yürütme modeli**: kurulum öncesi **senkron** olarak yürütülür ve **kurulumu bloklar**. İşleyici bir hata fırlatırsa, herhangi bir şema değişikliği uygulanmadan önce kurulum iptal edilir — çalışma alanı, tutarlı bir durumda önceki sürümde kalır. Bu kasıtlıdır: kurulum öncesi, riskli bir yükseltmeyi reddetmek için son şansınızdır.
|
||||
* Kurulum sonrası ile aynı şekilde, uygulama başına yalnızca bir kurulum öncesi işlevine izin verilir. Derleme sırasında uygulama manifestine `preInstallLogicFunction` altında otomatik olarak eklenir.
|
||||
* **Geliştirme modunda çalıştırılmaz**: kurulum sonrasında olduğu gibi — yerel olarak kaydedilen uygulamalarda kurulum akışı tamamen atlanır, bu nedenle `yarn twenty dev` altında kurulum öncesi hiç çalışmaz. Bunu elle tetiklemek için `yarn twenty exec --preInstall` kullanın.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Pre-install vs post-install: when to use which" description="Choosing the right install hook">
|
||||
<Accordion title="Kurulum öncesi vs kurulum sonrası: hangisini ne zaman kullanmalı" description="Doğru kurulum kancasını seçme">
|
||||
|
||||
Both hooks are part of the same install flow and receive the same `InstallPayload`. The difference is **when** they run relative to the workspace metadata migration, and that changes what data they can safely touch.
|
||||
Her iki kanca da aynı kurulum akışının parçasıdır ve aynı `InstallPayload`'ı alır. Fark, çalışma alanı üstveri (metadata) geçişine göre **ne zaman** çalıştıklarıdır ve bu, güvenle erişebilecekleri verileri değiştirir.
|
||||
|
||||
Pre-install is always **synchronous** (it blocks the install and can abort it). Post-install is **asynchronous by default** — enqueued on a worker with automatic retries — but can opt into synchronous execution with `shouldRunSynchronously: true`. See the `definePostInstallLogicFunction` accordion above for when to use each mode.
|
||||
Kurulum öncesi her zaman **senkron**dur (kurulumu bloke eder ve iptal edebilir). Kurulum sonrası **varsayılan olarak asenkron**dur — otomatik yeniden denemelerle bir worker üzerinde kuyruğa alınır — ancak `shouldRunSynchronously: true` ile senkron yürütmeye geçebilir. Her modun ne zaman kullanılacağı için yukarıdaki `definePostInstallLogicFunction` akordeonuna bakın.
|
||||
|
||||
**Use `post-install` for anything that needs the new schema to exist.** This is the common case:
|
||||
**Yeni şemanın mevcut olmasını gerektiren her şey için `post-install` kullanın.** Bu yaygın durumdur:
|
||||
|
||||
* Seeding default data (creating initial records, default views, demo content) against newly-added objects and fields.
|
||||
* Registering webhooks with third-party services now that the app has its credentials.
|
||||
* Calling your own API to finish setup that depends on the synchronized metadata.
|
||||
* Idempotent "ensure this exists" logic that should reconcile state on every upgrade — combine with `shouldRunOnVersionUpgrade: true`.
|
||||
* Yeni eklenen nesne ve alanlara karşı varsayılan verileri tohumlama (ilk kayıtları, varsayılan görünümleri, demo içeriği oluşturma).
|
||||
* Uygulamanın kimlik bilgileri artık mevcut olduğuna göre, üçüncü taraf hizmetlerle webhook'ları kaydetmek.
|
||||
* Eşitlenmiş üstveriye (metadata) bağlı kurulumu tamamlamak için kendi API'nizi çağırmak.
|
||||
* Her yükseltmede durumu uzlaştırması gereken idempotent "bu mevcut olsun" mantığı — `shouldRunOnVersionUpgrade: true` ile birleştirin.
|
||||
|
||||
Example — seed a default `PostCard` record after install:
|
||||
Örnek — kurulumdan sonra varsayılan bir `PostCard` kaydı tohumlama:
|
||||
|
||||
```ts src/logic-functions/post-install.ts
|
||||
import { definePostInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
|
||||
@@ -137,14 +137,14 @@ export default definePostInstallLogicFunction({
|
||||
});
|
||||
```
|
||||
|
||||
**Use `pre-install` when a migration would otherwise destroy or corrupt existing data.** Because pre-install runs against the *previous* schema and its failure rolls back the upgrade, it is the right place for anything risky:
|
||||
**Bir geçiş mevcut verileri aksi takdirde silecek veya bozacaksa `pre-install` kullanın.** Kurulum öncesi *önceki* şemaya karşı çalıştığı ve hatalandığında yükseltmeyi geri aldığı için, riskli olan her şey için doğru yerdir:
|
||||
|
||||
* **Backing up data that is about to be dropped or restructured** — e.g. you are removing a field in v2 and need to copy its values into another field or export them to storage before the migration runs.
|
||||
* **Archiving records that a new constraint would invalidate** — e.g. a field is becoming `NOT NULL` and you need to delete or fix rows with null values first.
|
||||
* **Validating compatibility and refusing the upgrade if the current data cannot be migrated cleanly** — throw from the handler and the install aborts with no changes applied. This is safer than discovering the incompatibility mid-migration.
|
||||
* **Renaming or rekeying data** ahead of a schema change that would lose the association.
|
||||
* **Kaldırılmak veya yeniden yapılandırılmak üzere olan verileri yedekleme** — örn. v2'de bir alanı kaldırıyorsunuz ve geçiş çalışmadan önce değerlerini başka bir alana kopyalamanız veya depolamaya aktarmanız gerekiyor.
|
||||
* **Yeni bir kısıtın geçersiz kılacağı kayıtları arşivleme** — örn. bir alan `NOT NULL` oluyor ve önce null değerli satırları silmeniz veya düzeltmeniz gerekiyor.
|
||||
* **Uyumluluğu doğrulama ve mevcut veriler temiz bir şekilde geçirilemiyorsa yükseltmeyi reddetme** — işleyiciden hata fırlatın ve kurulum, herhangi bir değişiklik uygulanmadan iptal edilir. Bu, uyumsuzluğu geçişin ortasında keşfetmekten daha güvenlidir.
|
||||
* İlişkilendirmeyi kaybettirecek bir şema değişikliğinden önce **verileri yeniden adlandırma veya yeniden anahtarlama**.
|
||||
|
||||
Example — archive records before a destructive migration:
|
||||
Örnek — yıkıcı bir geçişten önce kayıtları arşivleme:
|
||||
|
||||
```ts src/logic-functions/pre-install.ts
|
||||
import { definePreInstallLogicFunction, type InstallPayload } from 'twenty-sdk/define';
|
||||
@@ -186,20 +186,20 @@ export default definePreInstallLogicFunction({
|
||||
});
|
||||
```
|
||||
|
||||
**Rule of thumb:**
|
||||
**Kural olarak:**
|
||||
|
||||
| You want to... | Use |
|
||||
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| Seed default data, configure the workspace, register external resources | `post-install` |
|
||||
| Run long-running seeding or third-party calls that shouldn't block the install response | `post-install` (default — `shouldRunSynchronously: false`, with worker retries) |
|
||||
| Run fast setup that the caller will rely on immediately after the install call returns | `post-install` with `shouldRunSynchronously: true` |
|
||||
| Read or back up data that the upcoming migration would lose | `pre-install` |
|
||||
| Reject an upgrade that would corrupt existing data | `pre-install` (throw from the handler) |
|
||||
| Run reconciliation on every upgrade | `post-install` with `shouldRunOnVersionUpgrade: true` |
|
||||
| Do one-off setup on the first install only | `post-install` with `shouldRunOnVersionUpgrade: false` (default) |
|
||||
| Şunu yapmak istiyorsunuz... | Kullan |
|
||||
| ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- |
|
||||
| Varsayılan verileri tohumlamak, çalışma alanını yapılandırmak, harici kaynakları kaydetmek | `post-install` |
|
||||
| Kurulum yanıtını engellememesi gereken uzun süreli tohumlama veya üçüncü taraf çağrılarını çalıştırmak | `post-install` (varsayılan — `shouldRunSynchronously: false`, worker yeniden denemeleriyle) |
|
||||
| Kurulum çağrısı döner dönmez çağıranın güveneceği hızlı kurulumu çalıştırmak | `post-install` ile `shouldRunSynchronously: true` |
|
||||
| Yaklaşan geçişin kaybedeceği verileri okumak veya yedeklemek | `pre-install` |
|
||||
| Mevcut verileri bozacak bir yükseltmeyi reddetmek | `pre-install` (işleyiciden hata fırlatmak) |
|
||||
| Her yükseltmede uzlaştırma çalıştırmak | `post-install` ile `shouldRunOnVersionUpgrade: true` |
|
||||
| Yalnızca ilk kurulumda tek seferlik kurulum yapmak | `post-install` ile `shouldRunOnVersionUpgrade: false` (varsayılan) |
|
||||
|
||||
<Note>
|
||||
If in doubt, default to **post-install**. Only reach for pre-install when the migration itself is destructive and you need to intercept the previous state before it is gone.
|
||||
Emin değilseniz, varsayılan olarak **kurulum sonrası**nı tercih edin. Yalnızca geçişin kendisi yıkıcıysa ve önceki durum yok olmadan önce onu yakalamanız gerekiyorsa kurulum öncesine başvurun.
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Overview
|
||||
description: Configure the app itself — its identity, default permissions, and what runs at install time.
|
||||
title: Genel Bakış
|
||||
description: Uygulamanın kendisini yapılandırın — kimliğini, varsayılan izinlerini ve kurulum sırasında nelerin çalıştığını.
|
||||
icon: screwdriver-wrench
|
||||
---
|
||||
|
||||
A Twenty app's **config layer** is what describes the app *to the platform* — its identity, the permissions it holds, and the code that runs during install or upgrade. These declarations don't add new data shapes or runtime behavior; they tell Twenty *who the app is* and *how to set it up*.
|
||||
Bir Twenty uygulamasının **config katmanı**, uygulamayı *platforma tanımlar* — kimliğini, sahip olduğu izinleri ve kurulum veya yükseltme sırasında çalışan kodu açıklar. Bu deklarasyonlar yeni veri biçimleri veya çalışma zamanı davranışı eklemez; Twenty’ye *uygulamanın kim olduğunu* ve *nasıl kurulacağını* söyler.
|
||||
|
||||
```text
|
||||
┌────────────────────────────────────────────────────────┐
|
||||
@@ -26,26 +26,26 @@ A Twenty app's **config layer** is what describes the app *to the platform* —
|
||||
└──────────────────────────────────┘
|
||||
```
|
||||
|
||||
## In this section
|
||||
## Bu bölümde
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Application Config" icon="rocket" href="/l/tr/developers/extend/apps/config/application">
|
||||
`defineApplication` — identity, default role, variables, marketplace metadata.
|
||||
<Card title="Uygulama Yapılandırması" icon="rocket" href="/l/tr/developers/extend/apps/config/application">
|
||||
`defineApplication` — kimlik, varsayılan rol, değişkenler, marketplace metaverisi.
|
||||
</Card>
|
||||
<Card title="Roles & Permissions" icon="shield-halved" href="/l/tr/developers/extend/apps/config/roles">
|
||||
`defineRole` — declare what your app's logic functions can read and write.
|
||||
<Card title="Roller ve İzinler" icon="shield-halved" href="/l/tr/developers/extend/apps/config/roles">
|
||||
`defineRole` — uygulamanızın mantık fonksiyonlarının neleri okuyup yazabildiğini tanımlayın.
|
||||
</Card>
|
||||
<Card title="Install Hooks" icon="wrench" href="/l/tr/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` and `definePostInstallLogicFunction` — back up data, seed defaults, validate upgrades.
|
||||
<Card title="Kurulum Kancaları" icon="anahtar" href="/l/tr/developers/extend/apps/config/install-hooks">
|
||||
`definePreInstallLogicFunction` ve `definePostInstallLogicFunction` — verileri yedekleyin, varsayılanları tohumlayın, yükseltmeleri doğrulayın.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## How the pieces relate
|
||||
## Parçaların birbiriyle ilişkisi
|
||||
|
||||
* **Application** is the entry point. Every app has exactly one `defineApplication()` call, and it points at one **Role** as its default.
|
||||
* The **Role** controls what the app's logic functions and front components can read and write. Follow least-privilege: only grant the permissions your code actually needs.
|
||||
* **Install Hooks** run during install or upgrade — pre-install before the metadata migration (so it can refuse a risky upgrade), post-install after the migration (so it can seed default data against the new schema).
|
||||
* **Application** giriş noktasıdır. Her uygulamada tam olarak bir `defineApplication()` çağrısı vardır ve bu çağrı bir **Role**’a varsayılan olarak işaret eder.
|
||||
* **Role**, uygulamanın mantık fonksiyonlarının ve ön bileşenlerinin neleri okuyup yazabildiğini kontrol eder. En az ayrıcalık ilkesini izleyin: kodunuzun gerçekten ihtiyaç duyduğu izinleri verin.
|
||||
* **Install Hooks**, kurulum veya yükseltme sırasında çalışır — ön kurulum, metadata migrasyonundan önce (böylece riskli bir yükseltmeyi reddedebilir), son kurulum migrasyondan sonra (böylece yeni şemaya karşı varsayılan verileri tohumlayabilir).
|
||||
|
||||
<Note>
|
||||
Install hooks share the [logic function](/l/tr/developers/extend/apps/logic/logic-functions) runtime — same handler signature, same environment variables, same typed API client — but they're declared with their own define functions and live outside the regular trigger model (HTTP, cron, database events).
|
||||
Kurulum kancaları, [mantık fonksiyonu](/l/tr/developers/extend/apps/logic/logic-functions) çalışma zamanını paylaşır — aynı handler imzası, aynı ortam değişkenleri, aynı türlendirilmiş API istemcisi — ancak kendi define fonksiyonlarıyla deklare edilir ve normal tetikleyici modelinin (HTTP, cron, veritabanı olayları) dışında yaşarlar.
|
||||
</Note>
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
---
|
||||
title: Public Assets
|
||||
description: Ship static files — images, icons, fonts — alongside your app via the public/ folder.
|
||||
title: Genel varlıklar
|
||||
description: Uygulamanızla birlikte public/ klasörü aracılığıyla statik dosyalar — görseller, simgeler, yazı tipleri — dağıtın.
|
||||
icon: folder-open
|
||||
---
|
||||
|
||||
The `public/` folder at the root of your app holds static files — images, icons, fonts, or any other assets your app needs at runtime. These files are automatically included in builds, synced during dev mode, and uploaded to the server.
|
||||
Uygulamanızın kökündeki `public/` klasörü, statik dosyaları barındırır — görseller, simgeler, yazı tipleri veya uygulamanızın çalışma zamanında ihtiyaç duyduğu diğer varlıklar. Bu dosyalar derlemelere otomatik olarak dahil edilir, geliştirme modunda senkronize edilir ve sunucuya yüklenir.
|
||||
|
||||
Files placed in `public/` are:
|
||||
`public/` içine yerleştirilen dosyalar şunlardır:
|
||||
|
||||
* **Publicly accessible** — once synced to the server, assets are served at a public URL. No authentication is needed to access them.
|
||||
* **Available in front components** — use asset URLs to display images, icons, or any media inside your React components.
|
||||
* **Available in logic functions** — reference asset URLs in emails, API responses, or any server-side logic.
|
||||
* **Used for marketplace metadata** — the `logoUrl` and `screenshots` fields in `defineApplication()` reference files from this folder (e.g., `public/logo.png`). These are displayed in the marketplace when your app is published.
|
||||
* **Auto-synced in dev mode** — when you add, update, or delete a file in `public/`, it is synced to the server automatically. No restart needed.
|
||||
* **Included in builds** — `yarn twenty build` bundles all public assets into the distribution output.
|
||||
* **Herkese açık olarak erişilebilir** — sunucuya senkronize edildikten sonra varlıklar genel bir URL'den sunulur. Onlara erişmek için kimlik doğrulama gerekmez.
|
||||
* **Ön uç bileşenlerinde kullanılabilir** — React bileşenlerinizin içinde görseller, simgeler veya herhangi bir medyayı göstermek için varlık URL'lerini kullanın.
|
||||
* **Mantık işlevlerinde kullanılabilir** — e-postalarda, API yanıtlarında veya herhangi bir sunucu tarafı mantıkta varlık URL'lerine referans verin.
|
||||
* **Pazar yeri üst verileri için kullanılır** — `defineApplication()` içindeki `logoUrl` ve `screenshots` alanları bu klasördeki dosyalara referans verir (örn. `public/logo.png`). Bunlar, uygulamanız yayımlandığında pazar yerinde görüntülenir.
|
||||
* **Geliştirme modunda otomatik senkronize edilir** — `public/` içinde bir dosya eklediğinizde, güncellediğinizde veya sildiğinizde otomatik olarak sunucuya senkronize edilir. Yeniden başlatma gerekmez.
|
||||
* **Derlemelere dahil edilir** — `yarn twenty build`, tüm genel varlıkları dağıtım çıktısına paketler.
|
||||
|
||||
## Accessing public assets with `getPublicAssetUrl`
|
||||
## `getPublicAssetUrl` ile genel varlıklara erişme
|
||||
|
||||
Use the `getPublicAssetUrl` helper from `twenty-sdk` to get the full URL of a file in your `public/` directory. It works in both **logic functions** and **front components**.
|
||||
`twenty-sdk` içindeki `getPublicAssetUrl` yardımcı işlevini kullanarak `public/` dizininizdeki bir dosyanın tam URL'sini alın. Hem **mantık işlevlerinde** hem de **ön uç bileşenlerinde** çalışır.
|
||||
|
||||
**In a logic function:**
|
||||
**Bir mantık işlevinde:**
|
||||
|
||||
```ts src/logic-functions/send-invoice.ts
|
||||
import { defineLogicFunction, getPublicAssetUrl } from 'twenty-sdk/define';
|
||||
@@ -44,7 +44,7 @@ export default defineLogicFunction({
|
||||
});
|
||||
```
|
||||
|
||||
**In a front component:**
|
||||
**Bir ön uç bileşeninde:**
|
||||
|
||||
```tsx src/front-components/company-card.tsx
|
||||
import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk/define';
|
||||
@@ -56,4 +56,4 @@ export default defineFrontComponent(() => {
|
||||
});
|
||||
```
|
||||
|
||||
The `path` argument is relative to your app's `public/` folder. Both `getPublicAssetUrl('logo.png')` and `getPublicAssetUrl('public/logo.png')` resolve to the same URL — the `public/` prefix is stripped automatically if present.
|
||||
`path` bağımsız değişkeni, uygulamanızın `public/` klasörüne göre görelidir. Hem `getPublicAssetUrl('logo.png')` hem de `getPublicAssetUrl('public/logo.png')` aynı URL'ye çözümlenir — `public/` öneki varsa otomatik olarak kaldırılır.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Roles & Permissions
|
||||
description: Declare what objects and fields your app's logic functions and front components can read and write.
|
||||
title: Roller ve İzinler
|
||||
description: Uygulamanızın mantık fonksiyonlarının ve ön bileşenlerinin hangi nesne ve alanları okuyup yazabileceğini belirtin.
|
||||
icon: shield-halved
|
||||
---
|
||||
|
||||
A **role** is a permission set: which objects an app can read or write, which fields it can see, and which platform-level capabilities it can use. Every app's logic functions and front components inherit the permissions of the role declared as `defaultRoleUniversalIdentifier` in [`defineApplication`](/l/tr/developers/extend/apps/config/application).
|
||||
Bir **rol**, bir izin kümesidir: bir uygulamanın hangi nesneleri okuyup yazabileceğini, hangi alanları görebileceğini ve hangi platform düzeyindeki yetenekleri kullanabileceğini tanımlar. Her uygulamanın mantık fonksiyonları ve ön bileşenleri, [`defineApplication`](/l/tr/developers/extend/apps/config/application) içinde `defaultRoleUniversalIdentifier` olarak beyan edilen rolün izinlerini devralır.
|
||||
|
||||
```ts src/roles/restricted-company-role.ts
|
||||
import {
|
||||
@@ -49,9 +49,9 @@ export default defineRole({
|
||||
});
|
||||
```
|
||||
|
||||
## The default function role
|
||||
## Varsayılan fonksiyon rolü
|
||||
|
||||
When you scaffold a new app, the CLI creates a default role file:
|
||||
Yeni bir uygulama iskeleti oluşturduğunuzda, CLI varsayılan bir rol dosyası oluşturur:
|
||||
|
||||
```ts src/roles/default-role.ts
|
||||
import { defineRole, PermissionFlag } from 'twenty-sdk/define';
|
||||
@@ -77,14 +77,14 @@ export default defineRole({
|
||||
});
|
||||
```
|
||||
|
||||
This role's `universalIdentifier` is referenced from `application-config.ts` as `defaultRoleUniversalIdentifier`:
|
||||
Bu rolün `universalIdentifier` değeri, `application-config.ts` içinde `defaultRoleUniversalIdentifier` olarak referans verilir:
|
||||
|
||||
* **`*.role.ts`** declares what the role can do.
|
||||
* **`application-config.ts`** points to that role so your functions inherit its permissions.
|
||||
* **`*.role.ts`** rolün neler yapabileceğini beyan eder.
|
||||
* **`application-config.ts`** bu role işaret eder, böylece fonksiyonlarınız onun izinlerini devralır.
|
||||
|
||||
## Best practices
|
||||
## En İyi Uygulamalar
|
||||
|
||||
* Start from the scaffolded role, then progressively restrict it — the default grants broad read access, which is rarely what you want in production.
|
||||
* Replace `objectPermissions` and `fieldPermissions` with the exact objects and fields your functions actually need.
|
||||
* `permissionFlags` control access to platform-level capabilities. Keep them minimal.
|
||||
* See a working example: [`hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
|
||||
* Oluşturulmuş (scaffolded) rolden başlayın ve ardından giderek kısıtlayın — varsayılan rol geniş okuma erişimi verir; bu ise üretim ortamında nadiren isteyeceğiniz bir şeydir.
|
||||
* `objectPermissions` ve `fieldPermissions` değerlerini, fonksiyonlarınızın gerçekten ihtiyaç duyduğu nesne ve alanlarla değiştirin.
|
||||
* `permissionFlags`, platform düzeyindeki yeteneklere erişimi kontrol eder. Bunları asgari düzeyde tutun.
|
||||
* Çalışan bir örnek için bkz.: [`hello-world/src/roles/function-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/hello-world/src/roles/function-role.ts).
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Extending Objects
|
||||
description: Add fields to standard Twenty objects (Person, Company, …) or to objects from other apps using defineField.
|
||||
title: Nesneleri Genişletme
|
||||
description: Standart Twenty nesnelerine (Person, Company, …) alanlar ekleyin veya `defineField` kullanarak diğer uygulamalardaki nesnelere alan ekleyin.
|
||||
icon: wand-magic-sparkles
|
||||
---
|
||||
|
||||
Use `defineField()` to add a field to an object you don't own — a standard Twenty object like Person or Company, or an object shipped by another installed app. Unlike inline fields declared inside [`defineObject`](/l/tr/developers/extend/apps/data/objects), standalone fields require an `objectUniversalIdentifier` to specify which object they extend.
|
||||
Sahibi olmadığınız bir nesneye alan eklemek için `defineField()` kullanın — Person veya Company gibi standart bir Twenty nesnesi ya da başka bir yüklü uygulama tarafından sağlanan bir nesne. [`defineObject`](/l/tr/developers/extend/apps/data/objects) içinde tanımlanan satır içi alanların aksine, bağımsız alanlar, hangi nesneyi genişlettiklerini belirtmek için bir `objectUniversalIdentifier` gerektirir.
|
||||
|
||||
```ts src/fields/company-loyalty-tier.field.ts
|
||||
import { defineField, FieldType } from 'twenty-sdk/define';
|
||||
@@ -24,9 +24,9 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
## Key points
|
||||
## Önemli noktalar
|
||||
|
||||
* `objectUniversalIdentifier` identifies the target object. For standard Twenty objects, import the constant from `twenty-sdk`:
|
||||
* `objectUniversalIdentifier` hedef nesneyi tanımlar. Standart Twenty nesneleri için sabiti `twenty-sdk` içinden içe aktarın:
|
||||
|
||||
```ts
|
||||
import { STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS } from 'twenty-sdk/define';
|
||||
@@ -37,12 +37,12 @@ export default defineField({
|
||||
// …
|
||||
```
|
||||
|
||||
* When defining fields **inline inside `defineObject()`**, you do **not** need `objectUniversalIdentifier` — it's inherited from the parent object.
|
||||
* Alanları **`defineObject()` içinde satır içi tanımlarken**, `objectUniversalIdentifier`'a **ihtiyaç duymazsınız** — üst nesneden devralınır.
|
||||
|
||||
* `defineField()` is the only way to add fields to objects you didn't create with `defineObject()`.
|
||||
* `defineField()`, `defineObject()` ile oluşturmadığınız nesnelere alan eklemenin tek yoludur.
|
||||
|
||||
* File location is up to you. The convention is `src/fields/\<name>.field.ts`, but the SDK detects fields anywhere in `src/`.
|
||||
* Dosya konumu size bağlıdır. Genel kabul gören yapı `src/fields/\<name>.field.ts` şeklindedir, ancak SDK `src/` içinde herhangi bir yerdeki alanları algılar.
|
||||
|
||||
## Adding a relation to an existing object
|
||||
## Mevcut bir nesneye ilişki ekleme
|
||||
|
||||
To add a relation field (e.g. linking your custom object to a standard `Person`), use `defineField()` with `FieldType.RELATION`. The pattern is the same as for inline relations but with `objectUniversalIdentifier` set explicitly. See [Relations](/l/tr/developers/extend/apps/data/relations) for the bidirectional pattern.
|
||||
Bir ilişki alanı eklemek için (örneğin özel nesnenizi standart bir `Person` nesnesine bağlamak), `FieldType.RELATION` ile `defineField()` kullanın. Desen, satır içi ilişkilerle aynıdır ancak `objectUniversalIdentifier` açıkça ayarlanır. Çift yönlü desen için [Relations](/l/tr/developers/extend/apps/data/relations) bölümüne bakın.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Nesneler
|
||||
description: Declare new record types — custom tables with their own fields — using defineObject.
|
||||
description: defineObject kullanarak, kendi alanlarına sahip özel tablolar olan yeni kayıt türlerini bildirin.
|
||||
icon: tablo
|
||||
---
|
||||
|
||||
Custom **objects** are new record types your app adds to a workspace — Post Card, Invoice, Subscription, anything specific to your domain. Each object declares its schema (fields, relations, default values) and a stable universal identifier that survives across syncs and deploys.
|
||||
Özel **nesneler**, uygulamanızın bir çalışma alanına eklediği yeni kayıt türleridir — Kartpostal, Fatura, Abonelik, alanınıza özgü herhangi bir şey. Her nesne kendi şemasını (alanlar, ilişkiler, varsayılan değerler) ve eşitlemeler ve dağıtımlar boyunca korunan, kararlı bir evrensel tanımlayıcıyı bildirir.
|
||||
|
||||
```ts src/objects/post-card.object.ts
|
||||
import { defineObject, FieldType } from 'twenty-sdk/define';
|
||||
@@ -79,15 +79,15 @@ 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.
|
||||
* Inline fields defined here do **not** need an `objectUniversalIdentifier` — it's inherited from the parent object. Use [`defineField()`](/l/tr/developers/extend/apps/data/extending-objects) to add fields to objects you don't own.
|
||||
* You can scaffold new objects with `yarn twenty add object`, which guides you through naming, fields, and relationships. See [Architecture → Scaffolding entities](/l/tr/developers/extend/apps/getting-started/scaffolding).
|
||||
* Burada tanımlanan satır içi alanların bir `objectUniversalIdentifier`'a **ihtiyacı yoktur** — üst nesneden devralınır. Sahibi olmadığınız nesnelere alan eklemek için [`defineField()`](/l/tr/developers/extend/apps/data/extending-objects) kullanın.
|
||||
* `yarn twenty add object` kullanarak, adlandırma, alanlar ve ilişkiler konusunda sizi yönlendirerek yeni nesneler oluşturabilirsiniz. [Mimari → Varlık iskeleti oluşturma](/l/tr/developers/extend/apps/getting-started/scaffolding) bölümüne bakın.
|
||||
|
||||
<Note>
|
||||
**Base fields are added automatically.** When you define a custom object, Twenty creates standard fields like `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy`, and `deletedAt` for you. You don't need to declare them in your `fields` array — only your custom fields. You can override a default field by declaring one with the same name, but this is rarely a good idea.
|
||||
**Temel alanlar otomatik olarak eklenir.** Özel bir nesne tanımladığınızda Twenty, sizin için `id`, `name`, `createdAt`, `updatedAt`, `createdBy`, `updatedBy` ve `deletedAt` gibi standart alanlar oluşturur. Bunları `fields` dizinizde bildirmenize gerek yok — yalnızca özel alanlarınızı. Aynı ada sahip bir alan bildirerek varsayılan bir alanı geçersiz kılabilirsiniz, ancak bu nadiren iyi bir fikirdir.
|
||||
</Note>
|
||||
|
||||
## Sırada ne var
|
||||
|
||||
* **Connect this object to others** — see [Relations](/l/tr/developers/extend/apps/data/relations) for the bidirectional relation pattern.
|
||||
* **Add fields to objects from other apps** — see [Extending Objects](/l/tr/developers/extend/apps/data/extending-objects) for `defineField()`.
|
||||
* **Display this object in the UI** — see [Views](/l/tr/developers/extend/apps/layout/views) and [Navigation Menu Items](/l/tr/developers/extend/apps/layout/navigation-menu-items) to put it in the sidebar.
|
||||
* **Bu nesneyi diğerlerine bağlayın** — çift yönlü ilişki modeli için [İlişkiler](/l/tr/developers/extend/apps/data/relations) bölümüne bakın.
|
||||
* **Diğer uygulamalardaki nesnelere alanlar ekleyin** — `defineField()` için [Nesimleri Genişletme](/l/tr/developers/extend/apps/data/extending-objects) bölümüne bakın.
|
||||
* **Bu nesneyi arayüzde görüntüleyin** — kenar çubuğuna yerleştirmek için [Görünümler](/l/tr/developers/extend/apps/layout/views) ve [Gezinme Menüsü Öğeleri](/l/tr/developers/extend/apps/layout/navigation-menu-items) bölümlerine bakın.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Overview
|
||||
description: Shape the data your app adds to a workspace — objects, fields, and relations.
|
||||
title: Genel Bakış
|
||||
description: Uygulamanızın bir çalışma alanına eklediği verileri şekillendirin — nesneler, alanlar ve ilişkiler.
|
||||
icon: database
|
||||
---
|
||||
|
||||
A Twenty app's **data layer** is the data your app *adds* to a workspace — the new record types it declares, the columns it adds to existing objects, and how those records connect to each other.
|
||||
Bir Twenty uygulamasının **veri katmanı**, uygulamanızın bir çalışma alanına *eklediği* veridir — bildirdiği yeni kayıt türleri, mevcut nesnelere eklediği sütunlar ve bu kayıtların birbirine nasıl bağlandığı.
|
||||
|
||||
```text
|
||||
┌──────────────────────────────────────────────────┐
|
||||
@@ -23,30 +23,30 @@ A Twenty app's **data layer** is the data your app *adds* to a workspace — the
|
||||
└──────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## In this section
|
||||
## Bu bölümde
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Objects" icon="table" href="/l/tr/developers/extend/apps/data/objects">
|
||||
`defineObject` — declare new record types with their own fields.
|
||||
<Card title="Nesneler" icon="tablo" href="/l/tr/developers/extend/apps/data/objects">
|
||||
`defineObject` — kendi alanlarına sahip yeni kayıt türleri bildirin.
|
||||
</Card>
|
||||
<Card title="Extending Objects" icon="wand-magic-sparkles" href="/l/tr/developers/extend/apps/data/extending-objects">
|
||||
`defineField` — add fields to standard or other apps' objects.
|
||||
<Card title="Nesneleri Genişletme" icon="wand-magic-sparkles" href="/l/tr/developers/extend/apps/data/extending-objects">
|
||||
`defineField` — standart nesnelere veya diğer uygulamaların nesnelerine alanlar ekleyin.
|
||||
</Card>
|
||||
<Card title="Relations" icon="diagram-project" href="/l/tr/developers/extend/apps/data/relations">
|
||||
Bidirectional `MANY_TO_ONE` / `ONE_TO_MANY` connections between objects.
|
||||
<Card title="İlişkiler" icon="diagram-project" href="/l/tr/developers/extend/apps/data/relations">
|
||||
Nesneler arasında çift yönlü `MANY_TO_ONE` / `ONE_TO_MANY` bağlantıları.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Entities at a glance
|
||||
## Varlıklara genel bakış
|
||||
|
||||
| Entity | Purpose | Defined with |
|
||||
| ------------ | ----------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
||||
| **Object** | A new custom record type (e.g. PostCard, Invoice) with its own fields | `defineObject()` |
|
||||
| **Field** | A column on an object. Standalone fields can extend objects you didn't create (e.g. add `loyaltyTier` to Company) | `defineField()` |
|
||||
| **Relation** | A bidirectional link between two objects — both sides declared as fields | `defineField()` with `FieldType.RELATION` |
|
||||
| Varlık | Amaç | Şununla tanımlanır |
|
||||
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- |
|
||||
| **Nesne** | Kendi alanlarına sahip yeni bir özel kayıt türü (ör. PostCard, Invoice) | `defineObject()` |
|
||||
| **Alan** | Bir nesne üzerindeki sütun. Bağımsız alanlar, oluşturmadığınız nesneleri genişletebilir (ör. Company nesnesine `loyaltyTier` ekleyin) | `defineField()` |
|
||||
| **Relation** | İki nesne arasında, her iki tarafı da alan olarak bildirilmiş çift yönlü bir bağlantı | `defineField()` ile `FieldType.RELATION` |
|
||||
|
||||
The SDK detects these via AST analysis at build time, so file organization is up to you — the convention is `src/objects/` and `src/fields/`. Stable `universalIdentifier` UUIDs tie everything together across deploys.
|
||||
SDK bunları derleme zamanında AST analiziyle algılar, bu yüzden dosya organizasyonu size kalmıştır — kullanılan gelenek `src/objects/` ve `src/fields/` dizinleridir. Kararlı `universalIdentifier` UUID’leri, dağıtımlar arasında her şeyi birbirine bağlar.
|
||||
|
||||
<Note>
|
||||
Looking for **Application Config** or **Roles & Permissions**? Those describe the app itself rather than the data it adds — they live under [Config](/l/tr/developers/extend/apps/config/overview). Looking for **Connections** (Linear, GitHub, Slack OAuth)? Those exist to be called *from* logic functions and live under [Logic](/l/tr/developers/extend/apps/logic/connections).
|
||||
**Application Config** veya **Roles & Permissions** mı arıyorsunuz? Bunlar, ekledikleri verilerden çok uygulamanın kendisini tanımlar — [Config](/l/tr/developers/extend/apps/config/overview) altında bulunurlar. **Connections** (Linear, GitHub, Slack OAuth) mı arıyorsunuz? Bunlar, mantık fonksiyonları *içinden* çağrılmak için vardır ve [Logic](/l/tr/developers/extend/apps/logic/connections) altında bulunurlar.
|
||||
</Note>
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
---
|
||||
title: İlişkiler
|
||||
description: Connect objects together with bidirectional MANY_TO_ONE / ONE_TO_MANY relations.
|
||||
description: Nesneleri çift yönlü MANY_TO_ONE / ONE_TO_MANY ilişkilerle birbirine bağlayın.
|
||||
icon: diagram-project
|
||||
---
|
||||
|
||||
Relations connect two objects together. In Twenty, relations are always **bidirectional** — every relation has two sides, and each side is declared as a field that references the other.
|
||||
İlişkiler iki nesneyi birbirine bağlar. Twenty'de ilişkiler her zaman **çift yönlüdür** — her ilişkinin iki tarafı vardır ve her taraf diğeriyle ilişkili alan olarak tanımlanır.
|
||||
|
||||
| İ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 | No (the inverse side) |
|
||||
| `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
|
||||
|
||||
A `PostCard` can be sent to many `PostCardRecipient` records. Each recipient belongs to exactly one post card.
|
||||
Bir `PostCard` birçok `PostCardRecipient` kaydına gönderilebilir. 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):
|
||||
|
||||
```ts src/fields/post-card-recipients-on-post-card.field.ts
|
||||
import { defineField, FieldType, RelationType } from 'twenty-sdk/define';
|
||||
@@ -51,7 +51,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):
|
||||
|
||||
```ts src/fields/post-card-on-post-card-recipient.field.ts
|
||||
import { defineField, FieldType, RelationType, OnDeleteAction } from 'twenty-sdk/define';
|
||||
@@ -81,12 +81,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. 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ğerinde 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:
|
||||
|
||||
```ts src/fields/person-on-self-hosting-user.field.ts
|
||||
import {
|
||||
@@ -120,20 +120,20 @@ export default defineField({
|
||||
});
|
||||
```
|
||||
|
||||
## Relation field properties
|
||||
## İlişki alanı özellikleri
|
||||
|
||||
| Property | Required | Description |
|
||||
| ------------------------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------- |
|
||||
| `type` | Yes | Must be `FieldType.RELATION` |
|
||||
| `relationTargetObjectMetadataUniversalIdentifier` | Yes | The `universalIdentifier` of the target object |
|
||||
| `relationTargetFieldMetadataUniversalIdentifier` | Yes | The `universalIdentifier` of the matching field on the target object |
|
||||
| `universalSettings.relationType` | Yes | `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
|
||||
## Satır içi ilişki alanları
|
||||
|
||||
You can also declare a relation directly inside [`defineObject`](/l/tr/developers/extend/apps/data/objects). When inline, omit `objectUniversalIdentifier` — it's inherited from the parent object:
|
||||
Bir ilişkiyi doğrudan [`defineObject`](/l/tr/developers/extend/apps/data/objects) içinde de tanımlayabilirsiniz. Satır içi olduğunda, `objectUniversalIdentifier`'ı atlayın — üst nesneden devralınır:
|
||||
|
||||
```ts
|
||||
export default defineObject({
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
title: Concepts
|
||||
description: How Twenty apps work — entity model, sandboxing, and the install lifecycle.
|
||||
title: Kavramlar
|
||||
description: Twenty uygulamalarının nasıl çalıştığı — varlık modeli, korumalı alan (sandboxing) ve kurulum yaşam döngüsü.
|
||||
icon: sitemap
|
||||
---
|
||||
|
||||
Twenty apps are TypeScript packages that extend your workspace with custom objects, logic, UI components, and AI capabilities. They run on the Twenty platform with full sandboxing and permission controls.
|
||||
Twenty uygulamaları, çalışma alanınızı özel nesneler, mantık, UI bileşenleri ve yapay zekâ yetenekleriyle genişleten TypeScript paketleridir. Tam korumalı alan ve izin kontrolleriyle Twenty platformunda çalışırlar.
|
||||
|
||||
## How apps work
|
||||
## Uygulamalar nasıl çalışır
|
||||
|
||||
An app is a collection of **entities** declared using `defineEntity()` functions from the `twenty-sdk` package. The SDK detects these declarations via AST analysis at build time and produces a **manifest** — a complete description of what your app adds to a workspace. These functions validate your configuration at build time and provide IDE autocompletion and type safety.
|
||||
Bir uygulama, `twenty-sdk` paketindeki `defineEntity()` işlevleri kullanılarak bildirilen **varlıklar** koleksiyonudur. SDK, bu bildirimleri derleme sırasında AST analiziyle algılar ve bir **manifest** üretir — uygulamanızın bir çalışma alanına neler eklediğinin eksiksiz bir açıklaması. Bu fonksiyonlar, derleme zamanında yapılandırmanızı doğrular ve IDE otomatik tamamlama ile tür güvenliği sağlar.
|
||||
|
||||
```
|
||||
your-app/
|
||||
@@ -29,35 +29,35 @@ your-app/
|
||||
```
|
||||
|
||||
<Note>
|
||||
**File organization is up to you.** Entity detection is AST-based — the SDK finds `export default defineEntity(...)` calls regardless of where the file lives. The folder structure above is a convention, not a requirement.
|
||||
**Dosya organizasyonu size kalmış.** Varlık algılama AST tabanlıdır — dosyanın nerede bulunduğundan bağımsız olarak SDK `export default defineEntity(...)` çağrılarını bulur. Yukarıdaki klasör yapısı bir gelenektir, zorunluluk değildir.
|
||||
</Note>
|
||||
|
||||
## Entity types
|
||||
## Varlık türleri
|
||||
|
||||
| Entity | Purpose | Docs |
|
||||
| ------------------------ | ------------------------------------------ | ----------------------------------------------------------------------------- |
|
||||
| **Application** | App identity, default role, variables | [Application Config](/l/tr/developers/extend/apps/config/application) |
|
||||
| **Role** | Permission sets on objects and fields | [Roles & Permissions](/l/tr/developers/extend/apps/config/roles) |
|
||||
| **Object** | Custom record types with fields | [Objects](/l/tr/developers/extend/apps/data/objects) |
|
||||
| **Field** | Add fields to objects from other apps | [Extending Objects](/l/tr/developers/extend/apps/data/extending-objects) |
|
||||
| **Relation** | Bidirectional links between objects | [Relations](/l/tr/developers/extend/apps/data/relations) |
|
||||
| **Logic Function** | Server-side TypeScript with triggers | [Logic Functions](/l/tr/developers/extend/apps/logic/logic-functions) |
|
||||
| **Skill** | Reusable AI agent instructions | [Skills & Agents](/l/tr/developers/extend/apps/logic/skills-and-agents) |
|
||||
| **Agent** | AI assistants with custom prompts | [Skills & Agents](/l/tr/developers/extend/apps/logic/skills-and-agents) |
|
||||
| **Connection Provider** | OAuth credentials for third-party APIs | [Connections](/l/tr/developers/extend/apps/logic/connections) |
|
||||
| **View** | Pre-configured record list views | [Views](/l/tr/developers/extend/apps/layout/views) |
|
||||
| **Navigation Menu Item** | Custom sidebar entries | [Navigation Menu Items](/l/tr/developers/extend/apps/layout/navigation-menu-items) |
|
||||
| **Page Layout** | Tabs and widgets on a record's detail page | [Page Layouts](/l/tr/developers/extend/apps/layout/page-layouts) |
|
||||
| **Front Component** | Sandboxed React UI inside Twenty | [Front Components](/l/tr/developers/extend/apps/layout/front-components) |
|
||||
| **Command Menu Item** | Quick actions and Cmd+K entries | [Command Menu Items](/l/tr/developers/extend/apps/layout/command-menu-items) |
|
||||
| Varlık | Amaç | Belgeler |
|
||||
| ------------------------ | -------------------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| **Uygulama** | Uygulama kimliği, varsayılan rol, değişkenler | [Application Config](/l/tr/developers/extend/apps/config/application) |
|
||||
| **Rol** | Nesneler ve alanlar üzerindeki izin kümeleri | [Roller ve İzinler](/l/tr/developers/extend/apps/config/roles) |
|
||||
| **Object** | Alanlara sahip özel kayıt türleri | [Nesneler](/l/tr/developers/extend/apps/data/objects) |
|
||||
| **Alan** | Diğer uygulamalardaki nesnelere alan ekleyin | [Nesneleri Genişletme](/l/tr/developers/extend/apps/data/extending-objects) |
|
||||
| **İlişki** | Nesneler arasındaki çift yönlü bağlantılar | [İlişkiler](/l/tr/developers/extend/apps/data/relations) |
|
||||
| **Mantık İşlevi** | Tetikleyicilerle sunucu tarafı TypeScript | [Mantıksal İşlevler](/l/tr/developers/extend/apps/logic/logic-functions) |
|
||||
| **Beceri** | Yeniden kullanılabilir yapay zekâ temsilcisi yönergeleri | [Beceriler ve Temsilciler](/l/tr/developers/extend/apps/logic/skills-and-agents) |
|
||||
| **Temsilci** | Özel istemlere sahip yapay zekâ asistanları | [Beceriler ve Temsilciler](/l/tr/developers/extend/apps/logic/skills-and-agents) |
|
||||
| **Bağlantı sağlayıcısı** | Üçüncü taraf API'ler için OAuth kimlik bilgileri | [Bağlantılar](/l/tr/developers/extend/apps/logic/connections) |
|
||||
| **Görünüm** | Önceden yapılandırılmış kayıt listesi görünümleri | [Görünümler](/l/tr/developers/extend/apps/layout/views) |
|
||||
| **Gezinme Menüsü Öğesi** | Özel kenar çubuğu öğeleri | [Gezinme Menüsü Öğeleri](/l/tr/developers/extend/apps/layout/navigation-menu-items) |
|
||||
| **Sayfa Düzeni** | Bir kaydın ayrıntı sayfasındaki sekmeler ve widget'lar | [Sayfa Düzenleri](/l/tr/developers/extend/apps/layout/page-layouts) |
|
||||
| **Ön Uç Bileşeni** | Twenty içinde korumalı alandaki React kullanıcı arayüzü | [Ön Uç Bileşenleri](/l/tr/developers/extend/apps/layout/front-components) |
|
||||
| **Komut menüsü öğesi** | Hızlı işlemler ve Cmd+K girişleri | [Komut Menüsü Öğeleri](/l/tr/developers/extend/apps/layout/command-menu-items) |
|
||||
|
||||
## Sandboxing
|
||||
## Korumalı alan
|
||||
|
||||
* **Logic functions** run in isolated Node.js processes on the server. They only access data through the typed API client, scoped to the app's role permissions.
|
||||
* **Front components** run in Web Workers using Remote DOM — sandboxed from the main page but rendering native DOM elements (not iframes). They communicate with Twenty via a message-passing host API.
|
||||
* **Permissions** are enforced at the API level. The runtime token (`TWENTY_APP_ACCESS_TOKEN`) is derived from the role defined in `defineApplication()`.
|
||||
* **Mantık işlevleri** sunucuda yalıtılmış Node.js işlemlerinde çalışır. Verilere yalnızca, kapsamı uygulamanın rol izinleriyle sınırlandırılmış tipli API istemcisi üzerinden erişirler.
|
||||
* **Ön uç bileşenleri**, Remote DOM kullanan Web Worker'larda çalışır — ana sayfadan yalıtılmıştır ancak yerel DOM öğelerini (iframe'ler değil) oluşturur. Twenty ile mesaj iletimi yapan bir ana makine API'si aracılığıyla iletişim kurarlar.
|
||||
* **İzinler**, API düzeyinde uygulanır. Çalışma zamanı belirteci (`TWENTY_APP_ACCESS_TOKEN`), `defineApplication()` içinde tanımlanan rolden türetilir.
|
||||
|
||||
## App lifecycle
|
||||
## Uygulama yaşam döngüsü
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
@@ -76,26 +76,26 @@ your-app/
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
* **`yarn twenty dev`** — watches your source files and live-syncs changes to a connected Twenty server. The typed API client is regenerated automatically when the schema changes.
|
||||
* **`yarn twenty build`** — compiles TypeScript, bundles logic functions and front components with esbuild, and produces a manifest.
|
||||
* **Pre/post-install hooks** — optional functions that run during installation. See [Install Hooks](/l/tr/developers/extend/apps/config/install-hooks) for details.
|
||||
* **`yarn twenty dev`** — kaynak dosyalarınızı izler ve bağlı bir Twenty sunucusuna değişiklikleri canlı olarak senkronize eder. Şema değiştiğinde tipli API istemcisi otomatik olarak yeniden oluşturulur.
|
||||
* **`yarn twenty build`** — TypeScript'i derler, mantık işlevlerini ve ön uç bileşenlerini esbuild ile paketler ve bir manifest üretir.
|
||||
* **Kurulum öncesi/sonrası kancaları** — kurulum sırasında çalışan isteğe bağlı işlevler. Ayrıntılar için [Kurulum Kancaları](/l/tr/developers/extend/apps/config/install-hooks) bölümüne bakın.
|
||||
|
||||
## Next steps
|
||||
## Sonraki adımlar
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Config" icon="screwdriver-wrench" href="/l/tr/developers/extend/apps/config/overview">
|
||||
Application identity, default role, and install hooks.
|
||||
<Card title="Yapılandırma" icon="screwdriver-wrench" href="/l/tr/developers/extend/apps/config/overview">
|
||||
Uygulama kimliği, varsayılan rol ve kurulum kancaları.
|
||||
</Card>
|
||||
<Card title="Data" icon="database" href="/l/tr/developers/extend/apps/data/overview">
|
||||
Objects, fields, and bidirectional relations.
|
||||
<Card title="Veri" icon="database" href="/l/tr/developers/extend/apps/data/overview">
|
||||
Nesneler, alanlar ve çift yönlü ilişkiler.
|
||||
</Card>
|
||||
<Card title="Logic" icon="bolt" href="/l/tr/developers/extend/apps/logic/overview">
|
||||
Logic functions, skills, agents, and OAuth connections.
|
||||
<Card title="Mantık" icon="bolt" href="/l/tr/developers/extend/apps/logic/overview">
|
||||
Mantık işlevleri, beceriler, ajanlar ve OAuth bağlantıları.
|
||||
</Card>
|
||||
<Card title="Layout" icon="table-columns" href="/l/tr/developers/extend/apps/layout/overview">
|
||||
Views, navigation, page layouts, front components.
|
||||
<Card title="Düzen" icon="table-columns" href="/l/tr/developers/extend/apps/layout/overview">
|
||||
Görünümler, gezinme, sayfa düzenleri, ön uç bileşenleri.
|
||||
</Card>
|
||||
<Card title="Operations" icon="rocket" href="/l/tr/developers/extend/apps/operations/overview">
|
||||
CLI, testing, remotes, CI, and publishing your app.
|
||||
<Card title="İşlemler" icon="rocket" href="/l/tr/developers/extend/apps/operations/overview">
|
||||
CLI, test, uzak depolar, CI ve uygulamanızı yayımlama.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -1,61 +1,61 @@
|
||||
---
|
||||
title: Local Server
|
||||
description: Manage the local Twenty Docker server — start, stop, upgrade, parallel test instance, and manual SDK setup.
|
||||
title: Yerel Sunucu
|
||||
description: Yerel Twenty Docker sunucusunu yönetin — başlatın, durdurun, yükseltin, paralel test örneği çalıştırın ve el ile SDK kurulumu yapın.
|
||||
icon: server
|
||||
---
|
||||
|
||||
## Managing the local server
|
||||
## Yerel sunucuyu yönetme
|
||||
|
||||
Use `yarn twenty server` to control the local Twenty container:
|
||||
Yerel Twenty konteynerini kontrol etmek için `yarn twenty server` kullanın:
|
||||
|
||||
| Command | What it does |
|
||||
| -------------------------------------- | -------------------------------------------- |
|
||||
| `yarn twenty server start` | Start the server (pulls the image if needed) |
|
||||
| `yarn twenty server start --port 3030` | Start on a custom port |
|
||||
| `yarn twenty server stop` | Stop the server (preserves data) |
|
||||
| `yarn twenty server status` | Show URL, version, and login credentials |
|
||||
| `yarn twenty server logs` | Stream server logs |
|
||||
| `yarn twenty server reset` | Wipe data and start fresh |
|
||||
| `yarn twenty server upgrade` | Pull the latest `twenty-app-dev` image |
|
||||
| `yarn twenty server upgrade 2.2.0` | Upgrade to a specific version |
|
||||
| Komut | Ne yapar |
|
||||
| -------------------------------------- | --------------------------------------------------------- |
|
||||
| `yarn twenty server start` | Sunucuyu başlatır (gerekirse imajı çeker) |
|
||||
| `yarn twenty server start --port 3030` | Özel bir portta başlatır |
|
||||
| `yarn twenty server stop` | Sunucuyu durdurur (verileri korur) |
|
||||
| `yarn twenty server status` | URL'yi, sürümü ve oturum açma kimlik bilgilerini gösterir |
|
||||
| `yarn twenty server logs` | Sunucu günlüklerini akış olarak iletir |
|
||||
| `yarn twenty server reset` | Verileri siler ve sıfırdan başlatır |
|
||||
| `yarn twenty server upgrade` | En güncel `twenty-app-dev` imajını çeker |
|
||||
| `yarn twenty server upgrade 2.2.0` | Belirli bir sürüme yükseltin |
|
||||
|
||||
Data persists across restarts in two Docker volumes (`twenty-app-dev-data` for PostgreSQL, `twenty-app-dev-storage` for files). Use `reset` to wipe everything.
|
||||
Veriler, yeniden başlatmalar arasında iki Docker biriminde kalıcıdır (PostgreSQL için `twenty-app-dev-data`, dosyalar için `twenty-app-dev-storage`). Her şeyi silmek için `reset` kullanın.
|
||||
|
||||
## Upgrading the server image
|
||||
## Sunucu imajını yükseltme
|
||||
|
||||
`yarn twenty server upgrade` pulls the latest image, compares digests, and only recreates the container if anything actually changed. Volumes are preserved — only the container is replaced. If a new image was pulled and the container was running, the upgrade automatically starts a new container; run `yarn twenty server start` afterward to wait for it to become healthy.
|
||||
`yarn twenty server upgrade`, en güncel imajı çeker, özetleri karşılaştırır ve yalnızca gerçekten bir şey değiştiyse konteyneri yeniden oluşturur. Birimler korunur — yalnızca konteyner değiştirilir. Yeni bir imaj çekildiyse ve konteyner çalışıyorsa, yükseltme otomatik olarak yeni bir konteyner başlatır; sağlıklı hale gelmesini beklemek için ardından `yarn twenty server start` çalıştırın.
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server upgrade # Latest
|
||||
yarn twenty server upgrade 2.2.0 # Specific version
|
||||
```
|
||||
|
||||
Verify the running version with `yarn twenty server status` (it shows the `APP_VERSION` baked into the container).
|
||||
`yarn twenty server status` ile çalışan sürümü doğrulayabilirsiniz (konteynere gömülü `APP_VERSION` değerini gösterir).
|
||||
|
||||
## Running a parallel test instance
|
||||
## Paralel bir test örneği çalıştırma
|
||||
|
||||
Pass `--test` to any `server` command to manage a second, fully isolated instance — useful for integration tests or experiments without touching your main dev data:
|
||||
`server` komutlarının herhangi birine `--test` parametresini vererek ikinci, tamamen yalıtılmış bir örneği yönetin — entegrasyon testlerini çalıştırmak veya ana geliştirme verilerinize dokunmadan denemeler yapmak için kullanışlıdır:
|
||||
|
||||
| Command | What it does |
|
||||
| ----------------------------------- | ----------------------------------------------- |
|
||||
| `yarn twenty server start --test` | Start the test instance (defaults to port 2021) |
|
||||
| `yarn twenty server stop --test` | Stop it |
|
||||
| `yarn twenty server status --test` | Show its status |
|
||||
| `yarn twenty server logs --test` | Stream its logs |
|
||||
| `yarn twenty server reset --test` | Wipe its data |
|
||||
| `yarn twenty server upgrade --test` | Upgrade its image |
|
||||
| Komut | Ne yapar |
|
||||
| ----------------------------------- | ------------------------------------------------------------- |
|
||||
| `yarn twenty server start --test` | Test örneğini başlatır (varsayılan bağlantı noktası 2021'dir) |
|
||||
| `yarn twenty server stop --test` | Durdurun |
|
||||
| `yarn twenty server status --test` | Durumunu gösterin |
|
||||
| `yarn twenty server logs --test` | Günlüklerini akış olarak izleyin |
|
||||
| `yarn twenty server reset --test` | Verilerini silin |
|
||||
| `yarn twenty server upgrade --test` | İmajını yükseltin |
|
||||
|
||||
The test instance has its own container (`twenty-app-dev-test`), volumes (`twenty-app-dev-test-data`, `twenty-app-dev-test-storage`), and config — it runs alongside your main instance without conflicts. Combine `--test` with `--port` to override 2021.
|
||||
Test örneği, kendine ait bir Docker konteynerinde (`twenty-app-dev-test`), ayrılmış birimlerle (`twenty-app-dev-test-data`, `twenty-app-dev-test-storage`) ve yapılandırmayla çalışır; böylece ana örneğinizle çakışma olmadan paralel olarak çalışabilir. Varsayılan 2021'i geçersiz kılmak için `--test` ile `--port`'u birlikte kullanın.
|
||||
|
||||
## Manual setup (without the scaffolder)
|
||||
## Manuel kurulum (iskelet oluşturucu olmadan)
|
||||
|
||||
Skip the scaffolder if you're adding the SDK to an existing project:
|
||||
SDK'yı mevcut bir projeye ekliyorsanız iskelet oluşturma adımını atlayın:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add twenty-sdk twenty-client-sdk
|
||||
```
|
||||
|
||||
Add the script to `package.json`:
|
||||
`package.json` dosyasına betiği ekleyin:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -65,8 +65,8 @@ Add the script to `package.json`:
|
||||
}
|
||||
```
|
||||
|
||||
You can now run `yarn twenty dev`, `yarn twenty server start`, and the rest.
|
||||
Artık `yarn twenty dev`, `yarn twenty server start` ve diğerlerini çalıştırabilirsiniz.
|
||||
|
||||
<Note>
|
||||
Don't install `twenty-sdk` globally — pin it per project so each app uses its own version.
|
||||
`twenty-sdk`'yi global olarak kurmayın — her uygulama kendi sürümünü kullansın diye proje bazında sabitleyin.
|
||||
</Note>
|
||||
|
||||
+12
-12
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Project Structure
|
||||
description: What's inside a scaffolded Twenty app — files, folders, and what each one does.
|
||||
title: Proje yapısı
|
||||
description: Önceden hazırlanmış bir Twenty uygulamasının içinde neler var — dosyalar, klasörler ve her birinin ne yaptığı.
|
||||
icon: folder-tree
|
||||
---
|
||||
|
||||
A new app generated by `npx create-twenty-app` looks like this:
|
||||
`npx create-twenty-app` ile oluşturulan yeni bir uygulama şöyle görünür:
|
||||
|
||||
```text filename="my-twenty-app/"
|
||||
my-twenty-app/
|
||||
@@ -25,16 +25,16 @@ my-twenty-app/
|
||||
README.md, LLMS.md
|
||||
```
|
||||
|
||||
## Key files
|
||||
## Temel dosyalar
|
||||
|
||||
| File / Folder | Purpose |
|
||||
| ---------------------------------------- | -------------------------------------------------------------- |
|
||||
| `src/application-config.ts` | **Required.** The main configuration file for your app. |
|
||||
| `src/default-role.ts` | Default role controlling what your logic functions can access. |
|
||||
| `src/constants/universal-identifiers.ts` | Auto-generated UUIDs and metadata (display name, description). |
|
||||
| `src/__tests__/` | Integration tests (setup + example test). |
|
||||
| `public/` | Static assets (images, fonts) served with your app. |
|
||||
| Dosya / Klasör | Amaç |
|
||||
| ---------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| `src/application-config.ts` | **Gerekli.** Uygulamanızın ana yapılandırma dosyası. |
|
||||
| `src/default-role.ts` | Mantık işlevlerinizin neye erişebileceğini denetleyen varsayılan rol. |
|
||||
| `src/constants/universal-identifiers.ts` | Otomatik oluşturulan UUID'ler ve meta veriler (görünen ad, açıklama). |
|
||||
| `src/__tests__/` | Entegrasyon testleri (kurulum + örnek test). |
|
||||
| `public/` | Uygulamanızla birlikte sunulan statik varlıklar (görüntüler, yazı tipleri). |
|
||||
|
||||
<Note>
|
||||
**File organization is up to you.** The folders above are conventions — the SDK detects entities via AST analysis on `export default defineEntity(...)` calls regardless of where the file lives.
|
||||
**Dosya organizasyonu size kalmış.** Yukarıdaki klasörler birer konvansiyondur — SDK, dosyanın nerede olduğundan bağımsız olarak `export default defineEntity(...)` çağrılarını AST analizi yoluyla algılar.
|
||||
</Note>
|
||||
|
||||
@@ -1,184 +1,184 @@
|
||||
---
|
||||
title: Quick Start
|
||||
title: Hızlı Başlangıç
|
||||
icon: rocket
|
||||
description: Create your first Twenty app in minutes.
|
||||
description: İlk Twenty uygulamanızı dakikalar içinde oluşturun.
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
## Ön Gereksinimler
|
||||
|
||||
* **Node.js 24+** — [Download](https://nodejs.org/)
|
||||
* **Yarn 4** — bundled with Node via Corepack. Enable it: `corepack enable`
|
||||
* **Docker** — [Download](https://www.docker.com/products/docker-desktop/). Needed to run a local Twenty server. Skip if you already have Twenty running elsewhere.
|
||||
* **Node.js 24+** — [Buradan indirin](https://nodejs.org/)
|
||||
* **Yarn 4** — Corepack aracılığıyla Node ile birlikte gelir. Etkinleştirin: `corepack enable`
|
||||
* **Docker** — [Buradan indirin](https://www.docker.com/products/docker-desktop/). Yerel bir Twenty sunucusunu çalıştırmak için gereklidir. Zaten başka bir yerde Twenty çalıştırıyorsanız atlayın.
|
||||
|
||||
Building a Twenty app has three phases. The scaffolder collapses them into one happy-path command, but each phase is a separate concept — when something fails, knowing which phase you're in tells you what to fix.
|
||||
Bir Twenty uygulaması oluşturmanın üç aşaması vardır. İskelet oluşturucu bunları tek bir sorunsuz akış komutuna indirger, ancak her aşama ayrı bir kavramdır — bir şeyler başarısız olduğunda hangi aşamada olduğunuzu bilmek neyi düzeltmeniz gerektiğini söyler.
|
||||
|
||||
| Phase | What you do | Tool | Result |
|
||||
| ------------------- | ---------------------------------- | ----------------------------- | ----------------------------- |
|
||||
| **1. Scaffold** | Generate the app's source code | `npx create-twenty-app` | A TypeScript project on disk |
|
||||
| **2. Run a server** | Start a Twenty server to sync into | Docker + `yarn twenty server` | A running Twenty instance |
|
||||
| **3. Sync** | Live-sync your code to the server | `yarn twenty dev` | Your changes appear in the UI |
|
||||
| Aşama | Ne yaparsınız | Araç | Sonuç |
|
||||
| ---------------------------- | ------------------------------------------------- | ----------------------------- | ---------------------------------- |
|
||||
| **1. İskelet Oluşturma** | Uygulamanın kaynak kodunu oluşturun | `npx create-twenty-app` | Diskte bir TypeScript projesi |
|
||||
| **2. Bir sunucu çalıştırma** | Eşitleme yapacağınız bir Twenty sunucusu başlatın | Docker + `yarn twenty server` | Çalışan bir Twenty örneği |
|
||||
| **3. Eşitleme** | Kodunuzu sunucuya canlı olarak eşitleyin | `yarn twenty dev` | Değişiklikleriniz arayüzde görünür |
|
||||
|
||||
---
|
||||
|
||||
## Phase 1 — Scaffold your project
|
||||
## Aşama 1 — Projenizin iskeletini oluşturun
|
||||
|
||||
Create a new app from the template:
|
||||
Şablondan yeni bir uygulama oluşturun:
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app
|
||||
```
|
||||
|
||||
You'll be prompted for a name and description — press **Enter** for the defaults. This generates a TypeScript project in `my-twenty-app/` with a starter `application-config.ts`, a default role, a CI workflow, and an integration test.
|
||||
Sizden bir ad ve açıklama istenir — varsayılanlar için **Enter** tuşuna basın. Bu, `my-twenty-app/` içinde bir başlangıç `application-config.ts`, varsayılan bir rol, bir CI iş akışı ve bir entegrasyon testi ile bir TypeScript projesi oluşturur.
|
||||
|
||||
**After this phase:** you have an app's source code on your machine. It isn't running yet — that's Phase 2.
|
||||
**Bu aşamadan sonra:** makinenizde uygulamanın kaynak kodu bulunur. Henüz çalışmıyor — bu, 2. Aşama.
|
||||
|
||||
---
|
||||
|
||||
## Phase 2 — Run a local Twenty server
|
||||
## Aşama 2 — Yerel bir Twenty sunucusu çalıştırın
|
||||
|
||||
Your app needs a Twenty server to sync into. The server is a full Twenty instance — UI, GraphQL API, PostgreSQL — running locally in Docker. Your local code uploads its definitions to that server, which makes them appear in the UI.
|
||||
Uygulamanızın eşitleme yapacağı bir Twenty sunucusuna ihtiyacı vardır. Sunucu, Docker içinde yerel olarak çalışan tam bir Twenty örneğidir — UI, GraphQL API, PostgreSQL. Yerel kodunuz tanımlarını bu sunucuya yükler; bu da onların arayüzde görünmesini sağlar.
|
||||
|
||||
The scaffolder offers to start one for you:
|
||||
İskelet oluşturucu sizin için bir tane başlatmayı teklif eder:
|
||||
|
||||
> **Would you like to set up a local Twenty instance?**
|
||||
> **Yerel bir Twenty örneği kurmak ister misiniz?**
|
||||
|
||||
* **Yes (recommended)** — pulls the `twentycrm/twenty-app-dev` Docker image and starts it on port `2020`. Make sure Docker is running first.
|
||||
* **No** — choose this if you already have a Twenty server you want to connect to. You can wire it up later with `yarn twenty remote add`.
|
||||
* **Evet (önerilir)** — `twentycrm/twenty-app-dev` Docker imajını çeker ve `2020` portunda başlatır. Önce Docker'ın çalıştığından emin olun.
|
||||
* **Hayır** — Zaten bağlanmak istediğiniz bir Twenty sunucunuz varsa bunu seçin. Bunu daha sonra `yarn twenty remote add` ile bağlayabilirsiniz.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Should start local instance?" />
|
||||
<img src="/images/docs/developers/extends/apps/start-instance.png" alt="Yerel örnek başlatılsın mı?" />
|
||||
</div>
|
||||
|
||||
Once the server is up, a browser opens for sign-in. Use the pre-seeded demo account:
|
||||
Sunucu çalışır duruma geldiğinde, oturum açmak için bir tarayıcı açılır. Önceden eklenmiş demo hesabını kullanın:
|
||||
|
||||
* **Email:** `tim@apple.dev`
|
||||
* **Password:** `tim@apple.dev`
|
||||
* **E-posta:** `tim@apple.dev`
|
||||
* **Parola:** `tim@apple.dev`
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty login screen" />
|
||||
<img src="/images/docs/developers/extends/apps/login.png" alt="Twenty oturum açma ekranı" />
|
||||
</div>
|
||||
|
||||
Click **Authorize** on the next screen — this gives the CLI access to your workspace.
|
||||
Sonraki ekranda **Authorize**'a tıklayın — bu işlem CLI'nin çalışma alanınıza erişmesine izin verir.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI authorization screen" />
|
||||
<img src="/images/docs/developers/extends/apps/authorize.png" alt="Twenty CLI yetkilendirme ekranı" />
|
||||
</div>
|
||||
|
||||
Your terminal will confirm everything is set up.
|
||||
Terminaliniz her şeyin kurulduğunu onaylayacaktır.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="App scaffolded successfully" />
|
||||
<img src="/images/docs/developers/extends/apps/scaffolded.png" alt="Uygulama iskeleti başarıyla oluşturuldu" />
|
||||
</div>
|
||||
|
||||
**After this phase:** you have a running Twenty server at [http://localhost:2020](http://localhost:2020) with your CLI authorized to sync to it.
|
||||
**Bu aşamadan sonra:** [http://localhost:2020](http://localhost:2020) adresinde çalışan bir Twenty sunucunuz ve ona eşitleme yapmak için yetkilendirilmiş bir CLI'ınız olur.
|
||||
|
||||
<Note>
|
||||
If Docker isn't installed or running, the scaffolder will tell you the right start command for your OS. Once Docker is up, you can resume with `yarn twenty server start` — no need to re-scaffold.
|
||||
Docker yüklü değilse veya çalışmıyorsa, iskelet oluşturucu işletim sisteminiz için doğru başlatma komutunu söyleyecektir. Docker çalışır duruma geldiğinde, `yarn twenty server start` ile devam edebilirsiniz — yeniden iskelet oluşturmaya gerek yok.
|
||||
</Note>
|
||||
|
||||
---
|
||||
|
||||
## Phase 3 — Sync your changes
|
||||
## Aşama 3 — Değişikliklerinizi eşitleyin
|
||||
|
||||
This is the inner loop you'll spend most of your time in.
|
||||
Zamanınızın çoğunu geçireceğiniz iç döngü budur.
|
||||
|
||||
```bash filename="Terminal"
|
||||
cd my-twenty-app
|
||||
yarn twenty dev
|
||||
```
|
||||
|
||||
This watches `src/`, rebuilds on every change, and syncs the result to the server. Edit a file, save, and within a second the server reflects the change. You'll see a live status panel in your terminal.
|
||||
Bu, `src/` dizinini izler, her değişiklikte yeniden oluşturur ve sonucu sunucuya eşitler. Bir dosyayı düzenleyin, kaydedin; bir saniye içinde sunucu değişikliği yansıtır. Terminalinizde canlı bir durum paneli göreceksiniz.
|
||||
|
||||
For more detailed output (build logs, sync requests, error traces), add `--verbose`.
|
||||
Daha ayrıntılı çıktı (derleme günlükleri, eşitleme istekleri, hata izleri) için `--verbose` ekleyin.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/dev.png" alt="Dev mode terminal output" />
|
||||
<img src="/images/docs/developers/extends/apps/dev.png" alt="Geliştirme modu terminal çıktısı" />
|
||||
</div>
|
||||
|
||||
Open [http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer). You should see your app under **Your Apps**.
|
||||
[http://localhost:2020/settings/applications#developer](http://localhost:2020/settings/applications#developer) adresini açın. Uygulamanızı **Your Apps** altında görmelisiniz.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps list showing My twenty app" />
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-1.png" alt="Your Apps listesinde My twenty app gösteriliyor" />
|
||||
</div>
|
||||
|
||||
Click **My twenty app** to see its **application registration** — a server-level record describing your app (name, identifier, OAuth credentials, source). One registration can be installed across multiple workspaces on the same server.
|
||||
**My twenty app**'e tıklayarak **application registration**'ı görüntüleyin — uygulamanızı tanımlayan (ad, tanımlayıcı, OAuth kimlik bilgileri, kaynak) sunucu düzeyinde bir kayıttır. Tek bir kayıt, aynı sunucudaki birden çok çalışma alanına kurulabilir.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Application registration details" />
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-2.png" alt="Uygulama kaydı ayrıntıları" />
|
||||
</div>
|
||||
|
||||
Click **View installed app** to see the workspace install. The **About** tab shows version and management options.
|
||||
Çalışma alanındaki kurulumu görmek için **View installed app**'e tıklayın. **About** sekmesi sürümü ve yönetim seçeneklerini gösterir.
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Installed app" />
|
||||
<img src="/images/docs/developers/extends/apps/app-in-ui-3.png" alt="Yüklü uygulama" />
|
||||
</div>
|
||||
|
||||
**After this phase:** you have a live development loop. Edit any file in `src/` and it appears in the UI.
|
||||
**Bu aşamadan sonra:** canlı bir geliştirme döngünüz olur. `src/` içindeki herhangi bir dosyayı düzenleyin; arayüzde görünür.
|
||||
|
||||
### One-shot sync for CI and scripts
|
||||
### CI ve betikler için tek seferlik eşitleme
|
||||
|
||||
Pass `--once` to run a single build + sync and exit — same pipeline, no watcher:
|
||||
Tek bir derleme + eşitleme çalıştırıp çıkmak için `--once` parametresini geçin — aynı ardışık düzen, izleyici yok:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty dev --once
|
||||
```
|
||||
|
||||
| Command | Behavior | When to use |
|
||||
| ------------------------ | ------------------------------------------------------------- | ---------------------------------------------------- |
|
||||
| `yarn twenty dev` | Watches and re-syncs on every change. Runs until you stop it. | Interactive local development. |
|
||||
| `yarn twenty dev --once` | Single build + sync, exits `0` on success, `1` on failure. | CI, pre-commit hooks, AI agents, scripted workflows. |
|
||||
| Komut | Davranış | Ne zaman kullanılmalı |
|
||||
| ------------------------ | ----------------------------------------------------------------------- | --------------------------------------------------------------- |
|
||||
| `yarn twenty dev` | Her değişiklikte izler ve yeniden eşitler. Siz durdurana kadar çalışır. | Etkileşimli yerel geliştirme. |
|
||||
| `yarn twenty dev --once` | Tek derleme + eşitleme; başarıda `0`, başarısızlıkta `1` ile çıkar. | CI, pre-commit kancaları, AI ajanları, betiklenmiş iş akışları. |
|
||||
|
||||
Both modes need a server in development mode and an authenticated remote.
|
||||
Her iki mod da geliştirme modunda bir sunucuya ve kimliği doğrulanmış bir uzak uca ihtiyaç duyar.
|
||||
|
||||
<Warning>
|
||||
Dev mode is only available on Twenty instances running in development (`NODE_ENV=development`). Production instances reject dev sync requests — use `yarn twenty deploy` to deploy to production servers. See [Publishing](/l/tr/developers/extend/apps/operations/publishing).
|
||||
Geliştirme modu yalnızca geliştirme ortamında (`NODE_ENV=development`) çalışan Twenty örneklerinde kullanılabilir. Üretim örnekleri, geliştirme eşitleme isteklerini reddeder — üretim sunucularına dağıtmak için `yarn twenty deploy` kullanın. Bkz. [Publishing](/l/tr/developers/extend/apps/operations/publishing).
|
||||
</Warning>
|
||||
|
||||
---
|
||||
|
||||
## Starting from an example
|
||||
## Bir örnekten başlayın
|
||||
|
||||
Use `--example` to start with a more complete project (custom objects, fields, logic functions, front components):
|
||||
Daha kapsamlı bir projeyle başlamak için `--example` kullanın (özel nesneler, alanlar, mantık işlevleri, ön uç bileşenleri):
|
||||
|
||||
```bash filename="Terminal"
|
||||
npx create-twenty-app@latest my-twenty-app --example postcard
|
||||
```
|
||||
|
||||
Examples live in [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples). You can also scaffold individual entities into an existing project with `yarn twenty add` — see [Scaffolding](/l/tr/developers/extend/apps/getting-started/scaffolding).
|
||||
Örnekler [twenty-apps/examples](https://github.com/twentyhq/twenty/tree/main/packages/twenty-apps/examples) dizininde yer alır. Ayrıca `yarn twenty add` ile mevcut bir projeye tek tek varlıklar için iskelet oluşturabilirsiniz — bkz. [Scaffolding](/l/tr/developers/extend/apps/getting-started/scaffolding).
|
||||
|
||||
---
|
||||
|
||||
## What you can build
|
||||
## Oluşturabilecekleriniz
|
||||
|
||||
Apps are composed of **entities** — each defined as a TypeScript file with a single `export default`:
|
||||
Uygulamalar **varlıklardan** oluşur — her biri tek bir `export default` içeren bir TypeScript dosyası olarak tanımlanır:
|
||||
|
||||
| Entity | What it does |
|
||||
| ---------------------- | ----------------------------------------------------------------------------------- |
|
||||
| **Objects & Fields** | Custom data models (Post Card, Invoice, etc.) with typed fields |
|
||||
| **Logic functions** | Server-side TypeScript triggered by HTTP routes, cron schedules, or database events |
|
||||
| **Front components** | React components that render inside Twenty's UI (side panel, widgets, command menu) |
|
||||
| **Skills & Agents** | AI capabilities — reusable instructions and autonomous assistants |
|
||||
| **Views & Navigation** | Pre-configured list views and sidebar menu items |
|
||||
| **Page layouts** | Custom record detail pages with tabs and widgets |
|
||||
| Varlık | Ne yapar |
|
||||
| ------------------------- | --------------------------------------------------------------------------------------------------------- |
|
||||
| **Nesneler ve Alanlar** | Özel veri modelleri (Post Card, Invoice vb.) tipli alanlarla |
|
||||
| **Mantıksal işlevler** | HTTP rotaları, cron zamanlamaları veya veritabanı olayları tarafından tetiklenen sunucu tarafı TypeScript |
|
||||
| **Ön uç bileşenleri** | Twenty'nin arayüzünde görüntülenen React bileşenleri (yan panel, widget'lar, komut menüsü) |
|
||||
| **Beceriler ve Aracılar** | Yapay zeka yetenekleri — yeniden kullanılabilir yönergeler ve otonom asistanlar |
|
||||
| **Görünümler ve Gezinme** | Önceden yapılandırılmış liste görünümleri ve kenar çubuğu menü öğeleri |
|
||||
| **Sayfa düzenleri** | Sekmeler ve widget'lar içeren özel kayıt ayrıntı sayfaları |
|
||||
|
||||
Full reference: [Concepts](/l/tr/developers/extend/apps/getting-started/concepts).
|
||||
Tam başvuru: [Concepts](/l/tr/developers/extend/apps/getting-started/concepts).
|
||||
|
||||
## Next steps
|
||||
## Sonraki adımlar
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Config" icon="screwdriver-wrench" href="/l/tr/developers/extend/apps/config/overview">
|
||||
Application identity, default role, install hooks, public assets.
|
||||
<Card title="Yapılandırma" icon="screwdriver-wrench" href="/l/tr/developers/extend/apps/config/overview">
|
||||
Uygulama kimliği, varsayılan rol, kurulum kancaları, genel varlıklar.
|
||||
</Card>
|
||||
<Card title="Data" icon="database" href="/l/tr/developers/extend/apps/data/overview">
|
||||
Objects, fields, and bidirectional relations.
|
||||
<Card title="Veri" icon="database" href="/l/tr/developers/extend/apps/data/overview">
|
||||
Nesneler, alanlar ve çift yönlü ilişkiler.
|
||||
</Card>
|
||||
<Card title="Logic" icon="bolt" href="/l/tr/developers/extend/apps/logic/overview">
|
||||
Logic functions, skills, agents, and OAuth connections.
|
||||
<Card title="Mantık" icon="bolt" href="/l/tr/developers/extend/apps/logic/overview">
|
||||
Mantık fonksiyonları, beceriler, aracılar ve OAuth bağlantıları.
|
||||
</Card>
|
||||
<Card title="Layout" icon="table-columns" href="/l/tr/developers/extend/apps/layout/overview">
|
||||
Views, navigation, page layouts, front components.
|
||||
<Card title="Düzen" icon="table-columns" href="/l/tr/developers/extend/apps/layout/overview">
|
||||
Görünümler, gezinme, sayfa düzenleri, ön bileşenler.
|
||||
</Card>
|
||||
<Card title="Operations" icon="rocket" href="/l/tr/developers/extend/apps/operations/overview">
|
||||
CLI, testing, remotes, CI, and publishing your app.
|
||||
<Card title="İşlemler" icon="rocket" href="/l/tr/developers/extend/apps/operations/overview">
|
||||
CLI, test, uzaklar, CI ve uygulamanızı yayımlama.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
---
|
||||
title: Scaffolding
|
||||
description: Generate entity files interactively with yarn twenty add — objects, fields, views, logic functions, and more.
|
||||
title: İskelet Oluşturma
|
||||
description: Yarn ile etkileşimli olarak Twenty nesneleri, alanları, görünümleri, mantık fonksiyonlarını ve daha fazlasını ekleyerek varlık dosyaları oluşturun.
|
||||
icon: wand-magic-sparkles
|
||||
---
|
||||
|
||||
Instead of creating entity files by hand, use the interactive scaffolder:
|
||||
Varlık dosyalarını elle oluşturmak yerine etkileşimli iskelet oluşturucuyu kullanın:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty add
|
||||
```
|
||||
|
||||
It prompts you to pick an entity type and walks you through the required fields, then writes a ready-to-use file with a stable `universalIdentifier` and the correct `defineEntity()` call.
|
||||
Bir varlık türü seçmeniz için sizi yönlendirir ve gerekli alanlarda adım adım ilerlemenizi sağlar, ardından sabit bir `universalIdentifier` ve doğru `defineEntity()` çağrısıyla kullanıma hazır bir dosya yazar.
|
||||
|
||||
You can also pass the entity type directly to skip the first prompt:
|
||||
İlk istemi atlamak için varlık türünü doğrudan da geçebilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty add object
|
||||
@@ -20,38 +20,38 @@ yarn twenty add logicFunction
|
||||
yarn twenty add frontComponent
|
||||
```
|
||||
|
||||
## Available entity types
|
||||
## Kullanılabilir varlık türleri
|
||||
|
||||
| Entity type | Command | Generated file |
|
||||
| Varlık türü | Komut | Oluşturulan dosya |
|
||||
| -------------------- | ------------------------------------ | ------------------------------------------------------- |
|
||||
| Object | `yarn twenty add object` | `src/objects/\<name>.ts` |
|
||||
| Field | `yarn twenty add field` | `src/fields/\<name>.ts` |
|
||||
| Logic function | `yarn twenty add logicFunction` | `src/logic-functions/\<name>.ts` |
|
||||
| Front component | `yarn twenty add frontComponent` | `src/front-components/\<name>.tsx` |
|
||||
| Role | `yarn twenty add role` | `src/roles/\<name>.ts` |
|
||||
| Skill | `yarn twenty add skill` | `src/skills/\<name>.ts` |
|
||||
| Agent | `yarn twenty add agent` | `src/agents/\<name>.ts` |
|
||||
| View | `yarn twenty add view` | `src/views/\<name>.ts` |
|
||||
| Navigation menu item | `yarn twenty add navigationMenuItem` | `src/navigation-menu-items/\<name>.ts` |
|
||||
| Page layout | `yarn twenty add pageLayout` | `src/page-layouts/\<name>.ts` |
|
||||
| Nesne | `yarn twenty add object` | `src/objects/\<name>.ts` |
|
||||
| Alan | `yarn twenty add field` | `src/fields/\<name>.ts` |
|
||||
| Mantık işlevi | `yarn twenty add logicFunction` | `src/logic-functions/\<name>.ts` |
|
||||
| Ön uç bileşeni | `yarn twenty add frontComponent` | `src/front-components/\<name>.tsx` |
|
||||
| Rol | `yarn twenty add role` | `src/roles/\<name>.ts` |
|
||||
| Beceri | `yarn twenty add skill` | `src/skills/\<name>.ts` |
|
||||
| Temsilci | `yarn twenty add agent` | `src/agents/\<name>.ts` |
|
||||
| Görünüm | `yarn twenty add view` | `src/views/\<name>.ts` |
|
||||
| Gezinme menüsü öğesi | `yarn twenty add navigationMenuItem` | `src/navigation-menu-items/\<name>.ts` |
|
||||
| Sayfa düzeni | `yarn twenty add pageLayout` | `src/page-layouts/\<name>.ts` |
|
||||
|
||||
## What the scaffolder generates
|
||||
## İskelet oluşturucunun ürettikleri
|
||||
|
||||
Each entity type has its own template. For example, `yarn twenty add object` asks for:
|
||||
Her varlık türünün kendi şablonu vardır. Örneğin, `yarn twenty add object` şunları sorar:
|
||||
|
||||
1. **Name (singular)** — e.g., `invoice`
|
||||
2. **Name (plural)** — e.g., `invoices`
|
||||
3. **Label (singular)** — auto-populated from the name (e.g., `Invoice`)
|
||||
4. **Label (plural)** — auto-populated (e.g., `Invoices`)
|
||||
5. **Create a view and navigation item?** — if you answer yes, the scaffolder also generates a matching view and sidebar link for the new object.
|
||||
1. **Ad (tekil)** — ör. `invoice`
|
||||
2. **Ad (çoğul)** — ör. `invoices`
|
||||
3. **Etiket (tekil)** — adından otomatik doldurulur (ör. `Invoice`)
|
||||
4. **Etiket (çoğul)** — otomatik doldurulur (ör. `Invoices`)
|
||||
5. **Bir görünüm ve gezinme öğesi oluşturulsun mu?** — evet derseniz, iskelet oluşturucu yeni nesne için eşleşen bir görünüm ve kenar çubuğu bağlantısı da üretir.
|
||||
|
||||
Other entity types have simpler prompts — most only ask for a name.
|
||||
Diğer varlık türlerinin istemleri daha basittir — çoğu yalnızca bir ad sorar.
|
||||
|
||||
The `field` entity type is more detailed: it asks for the field name, label, type (from a list of all available field types like `TEXT`, `NUMBER`, `SELECT`, `RELATION`, etc.), and the target object's `universalIdentifier`.
|
||||
`field` varlık türü daha ayrıntılıdır: alan adını, etiketi, türü (`TEXT`, `NUMBER`, `SELECT`, `RELATION` vb. gibi mevcut tüm alan türlerinin listesinden) ve hedef nesnenin `universalIdentifier` değerini sorar.
|
||||
|
||||
## Custom output path
|
||||
## Özel çıktı yolu
|
||||
|
||||
Use the `--path` flag to place the generated file in a custom location:
|
||||
`--path` bayrağını kullanarak oluşturulan dosyayı özel bir konuma yerleştirin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty add logicFunction --path src/custom-folder
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Command Menu Items
|
||||
description: Surface front components as quick actions and command menu (Cmd+K) entries with defineCommandMenuItem.
|
||||
title: Komut menüsü öğeleri
|
||||
description: Ön bileşenleri hızlı işlemler ve komut menüsü (Cmd+K) girdileri olarak `defineCommandMenuItem` ile sunun.
|
||||
icon: terminal
|
||||
---
|
||||
|
||||
A **command menu item** is the bridge between the user and a [front component](/l/tr/developers/extend/apps/layout/front-components). It registers the component in Twenty's command menu (Cmd+K) and, optionally, as a pinned quick-action button in the top-right corner of the page.
|
||||
Bir **komut menüsü öğesi**, kullanıcı ile bir [ön bileşen](/l/tr/developers/extend/apps/layout/front-components) arasında köprü görevi görür. Bu, bileşeni Twenty'nin komut menüsüne (Cmd+K) ve isteğe bağlı olarak sayfanın sağ üst köşesindeki sabitlenmiş bir hızlı işlem düğmesi olarak kaydeder.
|
||||
|
||||
```ts src/command-menu-items/open-dashboard.command-menu-item.ts
|
||||
import { defineCommandMenuItem } from 'twenty-sdk/define';
|
||||
@@ -20,25 +20,25 @@ export default defineCommandMenuItem({
|
||||
});
|
||||
```
|
||||
|
||||
## Configuration fields
|
||||
## Yapılandırma alanları
|
||||
|
||||
| Field | Required | Description |
|
||||
| --------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `universalIdentifier` | Yes | Stable unique ID for the command |
|
||||
| `label` | Yes | Full label shown in the command menu (Cmd+K) |
|
||||
| `frontComponentUniversalIdentifier` | Yes | The `universalIdentifier` of the front component this command opens |
|
||||
| `shortLabel` | No | Shorter label displayed on the pinned quick-action button |
|
||||
| `icon` | No | Icon name displayed next to the label (e.g. `'IconBolt'`, `'IconSend'`) |
|
||||
| `isPinned` | No | When `true`, shows the command as a quick-action button in the top-right corner of the page |
|
||||
| `availabilityType` | No | Controls where the command appears: `'GLOBAL'` (always available), `'RECORD_SELECTION'` (only when records are selected), or `'FALLBACK'` (shown when no other commands match) |
|
||||
| `availabilityObjectUniversalIdentifier` | No | Restrict the command to pages of a specific object type (e.g. only on Company records) |
|
||||
| `conditionalAvailabilityExpression` | No | A boolean expression that dynamically controls visibility (see below) |
|
||||
| Alan | Zorunlu | Açıklama |
|
||||
| --------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `universalIdentifier` | Evet | Komut için kalıcı benzersiz kimlik |
|
||||
| `label` | Evet | Komut menüsünde (Cmd+K) gösterilen tam etiket |
|
||||
| `frontComponentUniversalIdentifier` | Evet | Bu komutun açtığı ön bileşenin `universalIdentifier` değeri |
|
||||
| `shortLabel` | Hayır | Sabitlenmiş hızlı işlem düğmesinde görüntülenen daha kısa etiket |
|
||||
| `icon` | Hayır | Etiketin yanında görüntülenen simge adı (örn. `'IconBolt'`, `'IconSend'`) |
|
||||
| `isPinned` | Hayır | `true` olduğunda, komutu sayfanın sağ üst köşesinde bir hızlı işlem düğmesi olarak gösterir |
|
||||
| `availabilityType` | Hayır | Komutun nerede görüneceğini kontrol eder: `'GLOBAL'` (her zaman kullanılabilir), `'RECORD_SELECTION'` (yalnızca kayıtlar seçiliyken) veya `'FALLBACK'` (başka hiçbir komut eşleşmediğinde gösterilir) |
|
||||
| `availabilityObjectUniversalIdentifier` | Hayır | Komutu belirli bir nesne türünün sayfalarıyla sınırlandırın (örn. yalnızca Company kayıtlarında) |
|
||||
| `conditionalAvailabilityExpression` | Hayır | Görünürlüğü dinamik olarak kontrol eden bir boolean ifade (aşağıya bakın) |
|
||||
|
||||
## Headless commands
|
||||
## Arayüzsüz komutlar
|
||||
|
||||
A command menu item paired with a [headless front component](/l/tr/developers/extend/apps/layout/front-components#headless-vs-non-headless) is the idiomatic way to ship a one-click action — run code, navigate, or confirm and execute. The Front Components page covers the [SDK Command components](/l/tr/developers/extend/apps/layout/front-components#sdk-command-components) (`Command`, `CommandLink`, `CommandModal`, `CommandOpenSidePanelPage`) that handle the action-and-unmount pattern.
|
||||
Bir [arayüzsüz ön bileşen](/l/tr/developers/extend/apps/layout/front-components#headless-vs-non-headless) ile eşleştirilmiş bir komut menüsü öğesi, tek tıklamayla bir eylem sunmanın — kod çalıştırma, gezinme veya onaylayıp yürütme — yaygın kullanılan biçimidir. Ön Bileşenler sayfası, eylem-ve-kaldırma modelini yöneten [SDK Command bileşenlerini](/l/tr/developers/extend/apps/layout/front-components#sdk-command-components) (`Command`, `CommandLink`, `CommandModal`, `CommandOpenSidePanelPage`) kapsar.
|
||||
|
||||
A typical flow:
|
||||
Tipik bir akış:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
@@ -79,9 +79,9 @@ export default defineCommandMenuItem({
|
||||
});
|
||||
```
|
||||
|
||||
## Conditional availability expressions
|
||||
## Koşullu kullanılabilirlik ifadeleri
|
||||
|
||||
The `conditionalAvailabilityExpression` field lets you control when a command is visible based on the current page context. Import typed variables and operators from `twenty-sdk` to build expressions:
|
||||
`conditionalAvailabilityExpression` alanı, geçerli sayfa bağlamına göre bir komutun ne zaman görünür olacağını kontrol etmenizi sağlar. İfadeler oluşturmak için `twenty-sdk`'den türlendirilmiş değişkenleri ve operatörleri içe aktarın:
|
||||
|
||||
```ts src/command-menu-items/bulk-update.command-menu-item.ts
|
||||
import { defineCommandMenuItem } from 'twenty-sdk/define';
|
||||
@@ -103,42 +103,42 @@ export default defineCommandMenuItem({
|
||||
});
|
||||
```
|
||||
|
||||
### Context variables
|
||||
### Bağlam değişkenleri
|
||||
|
||||
These represent the current state of the page:
|
||||
Bunlar sayfanın mevcut durumunu temsil eder:
|
||||
|
||||
| Variable | Type | Description |
|
||||
| ------------------------------ | --------- | ---------------------------------------------------------------- |
|
||||
| `pageType` | `string` | Current page type (e.g. `'RecordIndexPage'`, `'RecordShowPage'`) |
|
||||
| `isInSidePanel` | `boolean` | Whether the component is rendered in a side panel |
|
||||
| `numberOfSelectedRecords` | `number` | Number of currently selected records |
|
||||
| `isSelectAll` | `boolean` | Whether "select all" is active |
|
||||
| `selectedRecords` | `array` | The selected record objects |
|
||||
| `favoriteRecordIds` | `array` | IDs of favorited records |
|
||||
| `objectPermissions` | `object` | Permissions for the current object type |
|
||||
| `targetObjectReadPermissions` | `object` | Read permissions for the target object |
|
||||
| `targetObjectWritePermissions` | `object` | Write permissions for the target object |
|
||||
| `featureFlags` | `object` | Active feature flags |
|
||||
| `objectMetadataItem` | `object` | Metadata of the current object type |
|
||||
| `hasAnySoftDeleteFilterOnView` | `boolean` | Whether the current view has a soft-delete filter |
|
||||
| Değişken | Tür | Açıklama |
|
||||
| ------------------------------ | --------- | ----------------------------------------------------------------- |
|
||||
| `pageType` | `string` | Geçerli sayfa türü (örn. `'RecordIndexPage'`, `'RecordShowPage'`) |
|
||||
| `isInSidePanel` | `boolean` | Bileşenin bir yan panelde oluşturulup oluşturulmadığı |
|
||||
| `numberOfSelectedRecords` | `number` | Şu anda seçili kayıt sayısı |
|
||||
| `isSelectAll` | `boolean` | "tümünü seç" seçeneğinin etkin olup olmadığı |
|
||||
| `selectedRecords` | `array` | Seçili kayıt nesneleri |
|
||||
| `favoriteRecordIds` | `array` | Favorilere eklenen kayıtların ID'leri |
|
||||
| `objectPermissions` | `object` | Geçerli nesne türü için izinler |
|
||||
| `targetObjectReadPermissions` | `object` | Hedef nesne için okuma izinleri |
|
||||
| `targetObjectWritePermissions` | `object` | Hedef nesne için yazma izinleri |
|
||||
| `featureFlags` | `object` | Etkin özellik bayrakları |
|
||||
| `objectMetadataItem` | `object` | Geçerli nesne türünün üst verileri |
|
||||
| `hasAnySoftDeleteFilterOnView` | `boolean` | Geçerli görünümde soft-delete filtresi olup olmadığı |
|
||||
|
||||
### Operators
|
||||
### Operatörler
|
||||
|
||||
Combine variables into boolean expressions:
|
||||
Değişkenleri boolean ifadelere dönüştürmek için birleştirin:
|
||||
|
||||
| Operator | Description |
|
||||
| ----------------------------------- | ----------------------------------------------------------------- |
|
||||
| `isDefined(value)` | `true` if the value is not null/undefined |
|
||||
| `isNonEmptyString(value)` | `true` if the value is a non-empty string |
|
||||
| `includes(array, value)` | `true` if the array contains the value |
|
||||
| `includesEvery(array, prop, value)` | `true` if every item's property includes the value |
|
||||
| `every(array, prop)` | `true` if the property is truthy on every item |
|
||||
| `everyDefined(array, prop)` | `true` if the property is defined on every item |
|
||||
| `everyEquals(array, prop, value)` | `true` if the property equals the value on every item |
|
||||
| `some(array, prop)` | `true` if the property is truthy on at least one item |
|
||||
| `someDefined(array, prop)` | `true` if the property is defined on at least one item |
|
||||
| `someEquals(array, prop, value)` | `true` if the property equals the value on at least one item |
|
||||
| `someNonEmptyString(array, prop)` | `true` if the property is a non-empty string on at least one item |
|
||||
| `none(array, prop)` | `true` if the property is falsy on every item |
|
||||
| `noneDefined(array, prop)` | `true` if the property is undefined on every item |
|
||||
| `noneEquals(array, prop, value)` | `true` if the property does not equal the value on any item |
|
||||
| Operatör | Açıklama |
|
||||
| ----------------------------------- | --------------------------------------------------------- |
|
||||
| `isDefined(value)` | Değer null/undefined değilse `true` |
|
||||
| `isNonEmptyString(value)` | Değer boş olmayan bir string ise `true` |
|
||||
| `includes(array, value)` | Dizi değeri içeriyorsa `true` |
|
||||
| `includesEvery(array, prop, value)` | Her bir öğenin özelliği değeri içeriyorsa `true` |
|
||||
| `every(array, prop)` | Özellik her öğede truthy ise `true` |
|
||||
| `everyDefined(array, prop)` | Özellik her öğede tanımlıysa `true` |
|
||||
| `everyEquals(array, prop, value)` | Özellik her öğede değere eşitse `true` |
|
||||
| `some(array, prop)` | Özellik en az bir öğede truthy ise `true` |
|
||||
| `someDefined(array, prop)` | Özellik en az bir öğede tanımlıysa `true` |
|
||||
| `someEquals(array, prop, value)` | Özellik en az bir öğede değere eşitse `true` |
|
||||
| `someNonEmptyString(array, prop)` | Özellik en az bir öğede boş olmayan bir string ise `true` |
|
||||
| `none(array, prop)` | Özellik her öğede falsy ise `true` |
|
||||
| `noneDefined(array, prop)` | Özellik her öğede tanımsızsa `true` |
|
||||
| `noneEquals(array, prop, value)` | Özellik hiçbir öğede değere eşit değilse `true` |
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
---
|
||||
title: Front Components
|
||||
description: Build React components that render inside Twenty's UI with sandboxed isolation.
|
||||
title: Ön uç bileşenleri
|
||||
description: Twenty'nin UI'si içinde, korumalı alan (sandbox) izolasyonu ile görüntülenen React bileşenleri oluşturun.
|
||||
icon: window-maximize
|
||||
---
|
||||
|
||||
Front components are React components that render directly inside Twenty's UI. They run in an **isolated Web Worker** using Remote DOM — your code is sandboxed but renders natively in the page, not in an iframe.
|
||||
Ön uç bileşenler, Twenty'nin UI'si içinde doğrudan görüntülenen React bileşenleridir. Remote DOM kullanan izole bir Web Worker içinde çalışırlar — kodunuz izole bir ortamda (sandbox) çalışır ancak bir iframe içinde değil, sayfada yerel olarak işlenir.
|
||||
|
||||
## Where front components can be used
|
||||
## Ön uç bileşenlerinin kullanılabileceği yerler
|
||||
|
||||
Front components can render in two locations within Twenty:
|
||||
Ön uç bileşenler, Twenty içinde iki konumda işlenebilir:
|
||||
|
||||
* **Side panel** — Non-headless front components open in the right-hand side panel. This is the default behavior when a front component is triggered from the command menu.
|
||||
* **Widgets (dashboards and record pages)** — Front components can be embedded as widgets inside [page layouts](/l/tr/developers/extend/apps/layout/page-layouts). When configuring a dashboard or a record page layout, users can add a front component widget.
|
||||
* **Yan panel** — Headless olmayan ön uç bileşenler, sağ taraftaki yan panelde açılır. Bir ön uç bileşeni komut menüsünden tetiklendiğinde varsayılan davranış budur.
|
||||
* **Widget'lar (panolar ve kayıt sayfaları)** — Ön uç bileşenler, [sayfa düzenleri](/l/tr/developers/extend/apps/layout/page-layouts) içinde widget olarak gömülebilir. Bir pano veya kayıt sayfası düzeni yapılandırılırken kullanıcılar bir ön uç bileşen widget'ı ekleyebilir.
|
||||
|
||||
A front component on its own isn't reachable from the UI — you need to *surface* it. The two ways to do that are:
|
||||
Tek başına bir ön uç bileşenine kullanıcı arayüzünden erişilemez — onu görünür hâle getirmeniz gerekir. Bunu yapmanın iki yolu vardır:
|
||||
|
||||
* **Pair it with a [command menu item](/l/tr/developers/extend/apps/layout/command-menu-items)** — registers it in the command menu (Cmd+K) and, optionally, as a pinned quick-action.
|
||||
* **Embed it as a widget in a [page layout](/l/tr/developers/extend/apps/layout/page-layouts)** — places it on a record's detail page or dashboard.
|
||||
* **Onu bir [komut menüsü öğesi](/l/tr/developers/extend/apps/layout/command-menu-items) ile eşleştirin** — komut menüsüne (Cmd+K) ve isteğe bağlı olarak sabitlenmiş hızlı işlem olarak kaydeder.
|
||||
* **Onu bir [sayfa düzeni](/l/tr/developers/extend/apps/layout/page-layouts) içinde widget olarak gömün** — bir kaydın ayrıntı sayfasına veya panosuna yerleştirir.
|
||||
|
||||
## Basic example
|
||||
## Basit örnek
|
||||
|
||||
The quickest way to see a front component in action is to pair it with a [`defineCommandMenuItem`](/l/tr/developers/extend/apps/layout/command-menu-items), so it appears as a quick-action button in the top-right corner of the page:
|
||||
Bir ön uç bileşenini çalışır halde görmenin en hızlı yolu, onu [`defineCommandMenuItem`](/l/tr/developers/extend/apps/layout/command-menu-items) ile eşleştirmektir; böylece sayfanın sağ üst köşesinde bir hızlı işlem düğmesi olarak görünür:
|
||||
|
||||
```tsx src/front-components/hello-world.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
@@ -56,35 +56,35 @@ export default defineCommandMenuItem({
|
||||
});
|
||||
```
|
||||
|
||||
After syncing with `yarn twenty dev` (or running a one-shot `yarn twenty dev --once`), the quick action appears in the top-right corner of the page:
|
||||
`yarn twenty dev` ile senkronize ettikten sonra (veya tek seferlik bir `yarn twenty dev --once` çalıştırdıktan sonra), hızlı işlem sayfanın sağ üst köşesinde görünür:
|
||||
|
||||
<div style={{textAlign: 'center'}}>
|
||||
<img src="/images/docs/developers/extends/apps/quick-action.png" alt="Quick action button in the top-right corner" />
|
||||
<img src="/images/docs/developers/extends/apps/quick-action.png" alt="Sağ üst köşedeki hızlı işlem düğmesi" />
|
||||
</div>
|
||||
|
||||
Click it to render the component inline.
|
||||
Bileşeni satır içi işlemek için üzerine tıklayın.
|
||||
|
||||
## Configuration fields
|
||||
## Yapılandırma alanları
|
||||
|
||||
| Field | Required | Description |
|
||||
| --------------------- | -------- | ------------------------------------------------------------ |
|
||||
| `universalIdentifier` | Yes | Stable unique ID for this component |
|
||||
| `component` | Yes | A React component function |
|
||||
| `name` | No | Display name |
|
||||
| `description` | No | Description of what the component does |
|
||||
| `isHeadless` | No | Set to `true` if the component has no visible UI (see below) |
|
||||
| Alan | Zorunlu | Açıklama |
|
||||
| --------------------- | ------- | ------------------------------------------------------------------------------------- |
|
||||
| `universalIdentifier` | Evet | Bu bileşen için kalıcı benzersiz kimlik |
|
||||
| `component` | Evet | Bir React bileşen fonksiyonu |
|
||||
| `name` | Hayır | Görünen Ad |
|
||||
| `description` | Hayır | Bileşenin ne yaptığına dair açıklama |
|
||||
| `isHeadless` | Hayır | Bileşenin görünür bir kullanıcı arayüzü yoksa `true` olarak ayarlayın (aşağıya bakın) |
|
||||
|
||||
## Placing a front component on a page
|
||||
## Bir ön uç bileşenini bir sayfaya yerleştirme
|
||||
|
||||
Beyond commands, you can embed a front component directly into a record page by adding it as a widget in a **page layout**. See [Page Layouts](/l/tr/developers/extend/apps/layout/page-layouts) for details.
|
||||
Komutların ötesinde, bir ön uç bileşenini bir **sayfa düzeninde** widget olarak ekleyerek doğrudan bir kayıt sayfasına gömebilirsiniz. Ayrıntılar için [Sayfa Düzenleri](/l/tr/developers/extend/apps/layout/page-layouts) bölümüne bakın.
|
||||
|
||||
## Headless vs non-headless
|
||||
## Headless ve headless olmayan
|
||||
|
||||
Front components come in two rendering modes controlled by the `isHeadless` option:
|
||||
Ön uç bileşenler, `isHeadless` seçeneğiyle kontrol edilen iki işleme kipiyle gelir:
|
||||
|
||||
**Non-headless (default)** — The component renders a visible UI. When triggered from the command menu it opens in the side panel. This is the default behavior when `isHeadless` is `false` or omitted.
|
||||
**Headless olmayan (varsayılan)** — Bileşen görünür bir kullanıcı arayüzü (UI) oluşturur. Komut menüsünden tetiklendiğinde yan panelde açılır. `isHeadless` `false` olduğunda veya belirtilmediğinde bu varsayılan davranıştır.
|
||||
|
||||
**Headless (`isHeadless: true`)** — The component mounts invisibly in the background. It does not open the side panel. Headless components are designed for actions that execute logic and then unmount themselves — for example, running an async task, navigating to a page, or showing a confirmation modal. They pair naturally with the SDK Command components described below.
|
||||
**Headless (`isHeadless: true`)** — Bileşen arka planda görünmez şekilde bağlanır. Yan paneli açmaz. Headless bileşenler, mantığı çalıştırıp ardından kendilerini kaldıran eylemler için tasarlanmıştır — örneğin, bir async görevi çalıştırma, bir sayfaya gitme veya bir onay modalı gösterme. Aşağıda açıklanan SDK Command bileşenleriyle doğal olarak eşleşirler.
|
||||
|
||||
```tsx src/front-components/sync-tracker.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
@@ -110,20 +110,20 @@ export default defineFrontComponent({
|
||||
});
|
||||
```
|
||||
|
||||
Because the component returns `null`, Twenty skips rendering a container for it — no empty space appears in the layout. The component still has access to all hooks and the host communication API.
|
||||
Bileşen `null` döndürdüğü için, Twenty bunun için bir kapsayıcı oluşturmayı atlar — düzende boş alan görünmez. Bileşen yine de tüm hook'lara ve host iletişim API'sine erişime sahiptir.
|
||||
|
||||
## SDK Command components
|
||||
## SDK Command bileşenleri
|
||||
|
||||
The `twenty-sdk` package provides four Command helper components designed for headless front components. Each component executes an action on mount, handles errors by showing a snackbar notification, and automatically unmounts the front component when done.
|
||||
`twenty-sdk` paketi, headless ön uç bileşenler için tasarlanmış dört Command yardımcı bileşeni sağlar. Her bileşen bağlandığında bir eylem yürütür, hataları bir snackbar bildirimi göstererek ele alır ve tamamlandığında ön bileşeni otomatik olarak kaldırır.
|
||||
|
||||
Import them from `twenty-sdk/command`:
|
||||
Bunları `twenty-sdk/command` içinden içe aktarın:
|
||||
|
||||
* **`Command`** — Runs an async callback via the `execute` prop.
|
||||
* **`CommandLink`** — Navigates to an app path. Props: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — Opens a confirmation modal. If the user confirms, executes the `execute` callback. Props: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — Opens a specific side panel page. Props: `page`, `pageTitle`, `pageIcon`.
|
||||
* **`Command`** — `execute` prop'u aracılığıyla async bir geri çağrıyı çalıştırır.
|
||||
* **`CommandLink`** — Bir uygulama yoluna gider. Props: `to`, `params`, `queryParams`, `options`.
|
||||
* **`CommandModal`** — Bir onay modalı açar. Kullanıcı onaylarsa `execute` geri çağrısını yürütür. Props: `title`, `subtitle`, `execute`, `confirmButtonText`, `confirmButtonAccent`.
|
||||
* **`CommandOpenSidePanelPage`** — Belirli bir yan panel sayfasını açar. Props: `page`, `pageTitle`, `pageIcon`.
|
||||
|
||||
Here is a full example of a headless front component using `Command` to run an action from the command menu:
|
||||
`Command` kullanarak komut menüsünden bir eylem çalıştıran headless bir ön uç bileşenin tam örneği:
|
||||
|
||||
```tsx src/front-components/run-action.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
@@ -165,7 +165,7 @@ export default defineCommandMenuItem({
|
||||
});
|
||||
```
|
||||
|
||||
And an example using `CommandModal` to ask for confirmation before executing:
|
||||
Ve yürütmeden önce onay istemek için `CommandModal` kullanan bir örnek:
|
||||
|
||||
```tsx src/front-components/delete-draft.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
@@ -196,9 +196,9 @@ export default defineFrontComponent({
|
||||
});
|
||||
```
|
||||
|
||||
## Accessing runtime context
|
||||
## Çalışma zamanı bağlamına erişme
|
||||
|
||||
Inside your component, use SDK hooks to access the current user, record, and component instance:
|
||||
Bileşeninizin içinde, geçerli kullanıcıya, kayda ve bileşen örneğine erişmek için SDK hook'larını kullanın:
|
||||
|
||||
```tsx src/front-components/record-info.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
@@ -229,31 +229,31 @@ export default defineFrontComponent({
|
||||
});
|
||||
```
|
||||
|
||||
Available hooks:
|
||||
Kullanılabilir hook'lar:
|
||||
|
||||
| Hook | Returns | Description |
|
||||
| --------------------------------------------- | ------------------ | ---------------------------------------------------------- |
|
||||
| `useUserId()` | `string` or `null` | The current user's ID |
|
||||
| `useSelectedRecordIds()` | `string[]` | All selected record IDs (empty array if none selected) |
|
||||
| `useRecordId()` | `string` or `null` | **Deprecated.** Use `useSelectedRecordIds()` instead |
|
||||
| `useFrontComponentId()` | `string` | This component instance's ID |
|
||||
| `useFrontComponentExecutionContext(selector)` | varies | Access the full execution context with a selector function |
|
||||
| Hook | Döndürür | Açıklama |
|
||||
| --------------------------------------------- | -------------------- | -------------------------------------------------------------------------- |
|
||||
| `useUserId()` | `string` veya `null` | Geçerli kullanıcının ID'si |
|
||||
| `useSelectedRecordIds()` | `string[]` | Tüm seçili kayıt kimlikleri (hiçbiri seçilmediyse boş dizi) |
|
||||
| `useRecordId()` | `string` veya `null` | **Kullanımdan kaldırıldı.** Bunun yerine `useSelectedRecordIds()` kullanın |
|
||||
| `useFrontComponentId()` | `string` | Bu bileşen örneğinin ID'si |
|
||||
| `useFrontComponentExecutionContext(selector)` | değişir | Bir seçici işlevle tam yürütme bağlamına erişin |
|
||||
|
||||
## Host communication API
|
||||
## Host iletişim API'si
|
||||
|
||||
Front components can trigger navigation, modals, and notifications using functions from `twenty-sdk`:
|
||||
Ön uç bileşenleri, `twenty-sdk`'deki işlevleri kullanarak gezinmeyi, modalları ve bildirimleri tetikleyebilir:
|
||||
|
||||
| Function | Description |
|
||||
| ----------------------------------------------- | ----------------------------- |
|
||||
| `navigate(to, params?, queryParams?, options?)` | Navigate to a page in the app |
|
||||
| `openSidePanelPage(params)` | Open a side panel |
|
||||
| `closeSidePanel()` | Close the side panel |
|
||||
| `openCommandConfirmationModal(params)` | Show a confirmation dialog |
|
||||
| `enqueueSnackbar(params)` | Show a toast notification |
|
||||
| `unmountFrontComponent()` | Unmount the component |
|
||||
| `updateProgress(progress)` | Update a progress indicator |
|
||||
| Fonksiyon | Açıklama |
|
||||
| ----------------------------------------------- | ---------------------------------- |
|
||||
| `navigate(to, params?, queryParams?, options?)` | Uygulamada bir sayfaya git |
|
||||
| `openSidePanelPage(params)` | Bir yan panel aç |
|
||||
| `closeSidePanel()` | Yan paneli kapat |
|
||||
| `openCommandConfirmationModal(params)` | Bir onay iletişim kutusu göster |
|
||||
| `enqueueSnackbar(params)` | Bir toast bildirimi göster |
|
||||
| `unmountFrontComponent()` | Bileşeni kaldır (unmount) |
|
||||
| `updateProgress(progress)` | Bir ilerleme göstergesini güncelle |
|
||||
|
||||
Here is an example that uses the host API to show a snackbar and close the side panel after an action completes:
|
||||
Bir eylem tamamlandıktan sonra bir snackbar göstermek ve yan paneli kapatmak için host API'sini kullanan bir örnek:
|
||||
|
||||
```tsx src/front-components/archive-record.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
@@ -298,9 +298,9 @@ export default defineFrontComponent({
|
||||
});
|
||||
```
|
||||
|
||||
### Working with multiple records
|
||||
### Birden çok kayıtla çalışma
|
||||
|
||||
Use `useSelectedRecordIds()` to handle multiple selected records. This is useful for bulk operations:
|
||||
Birden çok seçili kaydı yönetmek için `useSelectedRecordIds()` kullanın. Bu, toplu işlemler için kullanışlıdır:
|
||||
|
||||
```tsx src/front-components/bulk-export.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
@@ -353,9 +353,9 @@ export default defineFrontComponent({
|
||||
});
|
||||
```
|
||||
|
||||
## Public assets
|
||||
## Genel varlıklar
|
||||
|
||||
Front components can access files from the app's `public/` directory using `getPublicAssetUrl`:
|
||||
Ön uç bileşenleri, `getPublicAssetUrl` kullanarak uygulamanın `public/` dizinindeki dosyalara erişebilir:
|
||||
|
||||
```tsx
|
||||
import { defineFrontComponent, getPublicAssetUrl } from 'twenty-sdk/define';
|
||||
@@ -369,18 +369,18 @@ export default defineFrontComponent({
|
||||
});
|
||||
```
|
||||
|
||||
See the [public assets section](/l/tr/developers/extend/apps/config/public-assets) for details.
|
||||
Ayrıntılar için [genel varlıklar bölümüne](/l/tr/developers/extend/apps/config/public-assets) bakın.
|
||||
|
||||
## Styling
|
||||
## Stil
|
||||
|
||||
Front components support multiple styling approaches. You can use:
|
||||
Ön uç bileşenleri birden fazla biçimlendirme yaklaşımını destekler. Şunları kullanabilirsiniz:
|
||||
|
||||
* **Inline styles** — `style={{ color: 'red' }}`
|
||||
* **Twenty UI components** — import from `twenty-sdk/ui` (Button, Tag, Status, Chip, Avatar, and more)
|
||||
* **Emotion** — CSS-in-JS with `@emotion/react`
|
||||
* **Styled-components** — `styled.div` patterns
|
||||
* **Tailwind CSS** — utility classes
|
||||
* **Any CSS-in-JS library** compatible with React
|
||||
* **Satır içi stiller** — `style={{ color: 'red' }}`
|
||||
* **Twenty UI bileşenleri** — `twenty-sdk/ui` içinden içe aktarın (Button, Tag, Status, Chip, Avatar ve daha fazlası)
|
||||
* **Emotion** — `@emotion/react` ile CSS-in-JS
|
||||
* **Styled-components** — `styled.div` kalıpları
|
||||
* **Tailwind CSS** — yardımcı sınıflar
|
||||
* **React ile uyumlu herhangi bir CSS-in-JS kitaplığı**
|
||||
|
||||
```tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Navigation Menu Items
|
||||
description: Add custom entries to the workspace sidebar — links to saved views or external URLs.
|
||||
title: Gezinme Menüsü Öğeleri
|
||||
description: Çalışma alanı kenar çubuğuna özel öğeler ekleyin — kaydedilmiş görünümlere veya harici URL’lere bağlantılar.
|
||||
icon: bars
|
||||
---
|
||||
|
||||
A **navigation menu item** is an entry in the left sidebar. Use `defineNavigationMenuItem()` to ship custom sidebar links — typically one per [view](/l/tr/developers/extend/apps/layout/views) you ship — or to point at external URLs.
|
||||
Bir **gezinme menüsü öğesi**, sol kenar çubuğundaki bir öğedir. Özel kenar çubuğu bağlantıları sunmak için `defineNavigationMenuItem()` kullanın — genellikle sunduğunuz her [görünüm](/l/tr/developers/extend/apps/layout/views) için bir tane — veya harici URL’lere işaret etmek için kullanın.
|
||||
|
||||
```ts src/navigation-menu-items/example-navigation-menu-item.ts
|
||||
import { defineNavigationMenuItem, NavigationMenuItemType } from 'twenty-sdk/define';
|
||||
@@ -23,22 +23,22 @@ export default defineNavigationMenuItem({
|
||||
|
||||
## Önemli noktalar
|
||||
|
||||
* `type` determines what the menu item links to. Each type pairs with a specific identifier field:
|
||||
* `type`, menü öğesinin neye bağlantı verdiğini belirler. Her tür, belirli bir tanımlayıcı alanıyla eşleşir:
|
||||
|
||||
| Tür | Ne yapar | Required field |
|
||||
| ------------------------------------ | ------------------------------------ | ----------------------------------------------------------------------------- |
|
||||
| `NavigationMenuItemType.VIEW` | Opens a saved view | `viewUniversalIdentifier` |
|
||||
| `NavigationMenuItemType.LINK` | Opens an external URL | `link` |
|
||||
| `NavigationMenuItemType.FOLDER` | Groups nested items under a label | `name` (and child items reference the folder via `folderUniversalIdentifier`) |
|
||||
| `NavigationMenuItemType.OBJECT` | Opens an object's default index page | `targetObjectUniversalIdentifier` |
|
||||
| `NavigationMenuItemType.PAGE_LAYOUT` | Opens a standalone page layout | `pageLayoutUniversalIdentifier` |
|
||||
| Tür | Ne yapar | Zorunlu alan |
|
||||
| ------------------------------------ | ------------------------------------------------ | -------------------------------------------------------------------------------------- |
|
||||
| `NavigationMenuItemType.VIEW` | Kaydedilmiş bir görünümü açar | `viewUniversalIdentifier` |
|
||||
| `NavigationMenuItemType.LINK` | Harici bir URL açar | `link` |
|
||||
| `NavigationMenuItemType.FOLDER` | İç içe geçmiş öğeleri bir etiket altında gruplar | `name` (ve alt öğeler klasöre `folderUniversalIdentifier` aracılığıyla referans verir) |
|
||||
| `NavigationMenuItemType.OBJECT` | Bir nesnenin varsayılan indeks sayfasını açar | `targetObjectUniversalIdentifier` |
|
||||
| `NavigationMenuItemType.PAGE_LAYOUT` | Bağımsız bir sayfa düzeni açar | `pageLayoutUniversalIdentifier` |
|
||||
|
||||
* `position` controls ordering in the sidebar.
|
||||
* `position`, kenar çubuğundaki sıralamayı kontrol eder.
|
||||
|
||||
* `icon` and `color` are optional and customize how the entry looks.
|
||||
* `icon` ve `color` isteğe bağlıdır ve öğenin görünümünü özelleştirir.
|
||||
|
||||
* `folderUniversalIdentifier` is also available on any item to nest it inside a `FOLDER`-type parent.
|
||||
* `folderUniversalIdentifier`, herhangi bir öğede de mevcuttur ve onu bir `FOLDER` türü üst öğenin içine yerleştirmek için kullanılır.
|
||||
|
||||
<Note>
|
||||
**Common pitfall:** creating an object without an associated view + navigation menu item makes that object invisible to users. Unless it's a technical/internal object, every custom object should have a default view *and* a sidebar entry pointing at it.
|
||||
**Yaygın hata:** bir görünüm ve gezinme menüsü öğesiyle ilişkilendirilmemiş bir nesne oluşturmak, o nesneyi kullanıcılar için görünmez yapar. Teknik/içsel bir nesne olmadığı sürece, her özel nesnenin varsayılan bir görünümü *ve* ona işaret eden bir kenar çubuğu öğesi olmalıdır.
|
||||
</Note>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Overview
|
||||
description: Place your app inside Twenty's UI — sidebar entries, saved views, record page tabs, and sandboxed React components.
|
||||
title: Genel Bakış
|
||||
description: Uygulamanızı Twenty'nin UI'sinin içine yerleştirin — kenar çubuğu girişleri, kaydedilmiş görünümler, kayıt sayfası sekmeleri ve yalıtılmış React bileşenleri.
|
||||
icon: table-columns
|
||||
---
|
||||
|
||||
A Twenty app's **layout layer** is everything the user sees: where the app surfaces in the sidebar, which list views it ships, how its record detail pages are arranged, and which custom React components render inside those pages.
|
||||
Bir Twenty uygulamasının **düzen katmanı**, kullanıcının gördüğü her şeydir: uygulamanın kenar çubuğunda nerede göründüğü, hangi liste görünümlerini sunduğu, kayıt detay sayfalarının nasıl düzenlendiği ve bu sayfaların içinde hangi özel React bileşenlerinin oluşturulduğu.
|
||||
|
||||
```text
|
||||
Sidebar Record list Record detail page
|
||||
@@ -23,34 +23,34 @@ A Twenty app's **layout layer** is everything the user sees: where the app surfa
|
||||
and filters └─────────────────────┘
|
||||
```
|
||||
|
||||
## In this section
|
||||
## Bu bölümde
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Views" icon="list" href="/l/tr/developers/extend/apps/layout/views">
|
||||
`defineView` — saved list configurations: visible columns, filters, groups.
|
||||
<Card title="Görünümler" icon="liste" href="/l/tr/developers/extend/apps/layout/views">
|
||||
`defineView` — kaydedilmiş liste yapılandırmaları: görünür sütunlar, filtreler, gruplar.
|
||||
</Card>
|
||||
<Card title="Navigation Menu Items" icon="bars" href="/l/tr/developers/extend/apps/layout/navigation-menu-items">
|
||||
`defineNavigationMenuItem` — sidebar entries pointing at views or external URLs.
|
||||
<Card title="Gezinme Menüsü Öğeleri" icon="bars" href="/l/tr/developers/extend/apps/layout/navigation-menu-items">
|
||||
`defineNavigationMenuItem` — görünümlere veya harici URL'lere işaret eden kenar çubuğu girişleri.
|
||||
</Card>
|
||||
<Card title="Page Layouts" icon="table-columns" href="/l/tr/developers/extend/apps/layout/page-layouts">
|
||||
`definePageLayout` and `definePageLayoutTab` — tabs and widgets on a record's detail page.
|
||||
<Card title="Sayfa Düzenleri" icon="table-columns" href="/l/tr/developers/extend/apps/layout/page-layouts">
|
||||
`definePageLayout` ve `definePageLayoutTab` — bir kaydın detay sayfasındaki sekmeler ve bileşenler.
|
||||
</Card>
|
||||
<Card title="Front Components" icon="window-maximize" href="/l/tr/developers/extend/apps/layout/front-components">
|
||||
`defineFrontComponent` — sandboxed React components that render inside Twenty.
|
||||
<Card title="Ön uç bileşenleri" icon="window-maximize" href="/l/tr/developers/extend/apps/layout/front-components">
|
||||
`defineFrontComponent` — Twenty içinde oluşturulan yalıtılmış React bileşenleri.
|
||||
</Card>
|
||||
<Card title="Command Menu Items" icon="terminal" href="/l/tr/developers/extend/apps/layout/command-menu-items">
|
||||
`defineCommandMenuItem` — register front components as Cmd+K entries and quick actions.
|
||||
<Card title="Komut Menüsü Öğeleri" icon="terminal" href="/l/tr/developers/extend/apps/layout/command-menu-items">
|
||||
`defineCommandMenuItem` — ön bileşenleri Cmd+K girişleri ve hızlı eylemler olarak kaydedin.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Where the app surfaces
|
||||
## Uygulamanın göründüğü yerler
|
||||
|
||||
| Surface | What it controls | Entity |
|
||||
| --------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------- |
|
||||
| **Sidebar** | A custom entry linking to a saved view or external URL | `defineNavigationMenuItem` |
|
||||
| **Record list** | A saved configuration for an object — visible columns, order, filters, groups | `defineView` |
|
||||
| **Record detail page** | The tabs and widgets on a record page (your own object's, or a standard one) | `definePageLayout`, `definePageLayoutTab` |
|
||||
| **Inside any of the above** | A custom React widget — buttons, forms, dashboards, integrations | `defineFrontComponent` |
|
||||
| **Command menu (Cmd+K)** | A pinned quick action or hidden command | `defineCommandMenuItem` |
|
||||
| Yüzey | Neyi kontrol eder | Varlık |
|
||||
| ------------------------------------------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
||||
| **Kenar çubuğu** | Kaydedilmiş bir görünüme veya harici bir URL'ye bağlanan özel bir giriş | `defineNavigationMenuItem` |
|
||||
| **Kayıt listesi** | Bir nesne için kaydedilmiş yapılandırma — görünür sütunlar, sıralama, filtreler, gruplar | `defineView` |
|
||||
| **Kayıt detay sayfası** | Bir kayıt sayfasındaki sekmeler ve bileşenler (kendi nesnenize ait veya standart bir nesneye ait) | `definePageLayout`, `definePageLayoutTab` |
|
||||
| **Yukarıdakilerin herhangi birinin içinde** | Özel bir React bileşeni — butonlar, formlar, panolar, entegrasyonlar | `defineFrontComponent` |
|
||||
| **Komut menüsü (Cmd+K)** | Sabitlenmiş bir hızlı eylem veya gizli komut | `defineCommandMenuItem` |
|
||||
|
||||
Front components run inside an isolated Web Worker using Remote DOM — they render *natively* in the page (not inside an iframe), but cannot reach the host page or DOM directly. Communication with Twenty happens through a message-passing host API.
|
||||
Ön bileşenler, Remote DOM kullanan yalıtılmış bir Web Worker içinde çalışır — sayfada *yerel* olarak oluşturulurlar (bir iframe içinde değil), ancak ana sayfaya veya DOM'a doğrudan erişemezler. Twenty ile iletişim, mesaj iletimi yapan bir ana makine API'si aracılığıyla gerçekleşir.
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
---
|
||||
title: Page Layouts
|
||||
description: Customize record detail pages — tabs, widgets, and where front components render — using definePageLayout and definePageLayoutTab.
|
||||
title: Sayfa Düzenleri
|
||||
description: definePageLayout ve definePageLayoutTab kullanarak kayıt detay sayfalarını; sekmeleri, widget’ları ve front bileşenlerin nerede render edileceğini özelleştirin.
|
||||
icon: table-columns
|
||||
---
|
||||
|
||||
A **page layout** controls how a record's detail page is arranged: which tabs appear and what widgets they contain. Use `definePageLayout()` to declare a layout for an object you own, or `definePageLayoutTab()` to add a single tab to a layout that already exists (yours or a standard Twenty one).
|
||||
Bir **sayfa düzeni**, bir kaydın detay sayfasının nasıl düzenlendiğini kontrol eder: hangi sekmelerin görüneceğini ve hangi widget’ları içerdiklerini. Sahibi olduğunuz bir nesne için bir düzen tanımlamak amacıyla `definePageLayout()` kullanın veya halihazırda var olan bir düzene (size ait veya standart bir Twenty düzenine) tek bir sekme eklemek için `definePageLayoutTab()` kullanın.
|
||||
|
||||
| Use case | Entity |
|
||||
| ---------------------------------------------------------------------- | --------------------- |
|
||||
| Define the entire layout for a record page on an object you own | `definePageLayout` |
|
||||
| Add one tab to an existing layout (your own object, or a standard one) | `definePageLayoutTab` |
|
||||
| Kullanım alanı | Varlık |
|
||||
| ------------------------------------------------------------------------------ | --------------------- |
|
||||
| Sahibi olduğunuz bir nesnedeki bir kayıt sayfası için tüm düzeni tanımlayın | `definePageLayout` |
|
||||
| Var olan bir düzene bir sekme ekleyin (kendi nesneniz veya standart bir nesne) | `definePageLayoutTab` |
|
||||
|
||||
## definePageLayout
|
||||
|
||||
Use this when you own the entire detail page — typically for a custom object you defined yourself.
|
||||
Tüm detay sayfasına sahip olduğunuz durumlarda bunu kullanın — genellikle kendiniz tanımladığınız özel bir nesne için.
|
||||
|
||||
```ts src/page-layouts/example-record-page-layout.ts
|
||||
import { definePageLayout, PageLayoutTabLayoutMode } from 'twenty-sdk/define';
|
||||
@@ -49,17 +49,17 @@ export default definePageLayout({
|
||||
});
|
||||
```
|
||||
|
||||
### Key points
|
||||
### Önemli noktalar
|
||||
|
||||
* `type` is typically `'RECORD_PAGE'` to customize the detail view of a specific object.
|
||||
* `objectUniversalIdentifier` specifies which object this layout applies to.
|
||||
* Each `tab` defines a section of the page with a `title`, `position`, and `layoutMode` (`CANVAS` for free-form layout).
|
||||
* Each `widget` inside a tab can render a [front component](/l/tr/developers/extend/apps/layout/front-components), a relation list, or other built-in widget types.
|
||||
* `position` on tabs controls their order. Use higher values (e.g., 50) to place custom tabs after built-in ones.
|
||||
* `type` genellikle belirli bir nesnenin ayrıntı görünümünü özelleştirmek için `'RECORD_PAGE'` olur.
|
||||
* `objectUniversalIdentifier`, bu düzenin hangi nesneye uygulanacağını belirtir.
|
||||
* Her `tab`, bir `title`, `position` ve `layoutMode` ile sayfanın bir bölümünü tanımlar (serbest biçimli düzen için `CANVAS`).
|
||||
* Bir sekmenin içindeki her `widget`, bir [front bileşeni](/l/tr/developers/extend/apps/layout/front-components), bir ilişki listesi veya diğer yerleşik widget türlerini render edebilir.
|
||||
* Sekmelerdeki `position`, sıralarını kontrol eder. Özel sekmeleri yerleşik olanların sonrasına yerleştirmek için daha yüksek değerler kullanın (ör. 50).
|
||||
|
||||
## definePageLayoutTab
|
||||
|
||||
Use this when you only want to **add** a tab to an existing layout — for example, an analytics tab on the standard Company page, or an AI summary tab attached to your own object's layout.
|
||||
Bunu yalnızca mevcut bir düzene **sekme eklemek** istediğinizde kullanın — örneğin, standart Company sayfasında bir analitik sekmesi veya kendi nesnenizin düzenine eklenmiş bir yapay zeka özeti sekmesi.
|
||||
|
||||
```ts src/page-layouts/example-extra-tab.ts
|
||||
import {
|
||||
@@ -94,9 +94,9 @@ export default definePageLayoutTab({
|
||||
});
|
||||
```
|
||||
|
||||
### Key points
|
||||
### Önemli noktalar
|
||||
|
||||
* `pageLayoutUniversalIdentifier` is **required** and must point to a page layout that already exists at install time — either a standard Twenty layout or one defined by your own app. Cross-app references to layouts owned by another installed app are not supported today. When the parent layout is missing, installation fails with a clear validation error.
|
||||
* `widgets` are scoped to this tab only — they reference [front components](/l/tr/developers/extend/apps/layout/front-components), views, etc. exactly like widgets defined inline in `definePageLayout`.
|
||||
* `position` controls ordering against existing tabs on the targeted layout. Pick a value that places your tab where you want it relative to built-in tabs.
|
||||
* Use this instead of `definePageLayout` when you only want to add to an existing layout. Use `definePageLayout` when you own the entire layout.
|
||||
* `pageLayoutUniversalIdentifier` **zorunludur** ve kurulum anında zaten var olan bir sayfa düzenini işaret etmelidir — standart bir Twenty düzeni veya kendi uygulamanız tarafından tanımlanan bir düzen olabilir. Başka yüklü bir uygulamaya ait düzenlere uygulamalar arası referanslar bugün desteklenmemektedir. Üst düzen eksik olduğunda, kurulum net bir doğrulama hatasıyla başarısız olur.
|
||||
* `widgets` yalnızca bu sekmeyle sınırlıdır — satır içi olarak `definePageLayout` içinde tanımlanan widget’larda olduğu gibi, [front bileşenlerine](/l/tr/developers/extend/apps/layout/front-components), görünümlere vb. tam olarak aynı şekilde referans verirler.
|
||||
* `position`, hedeflenen düzende mevcut sekmelere göre sıralamayı kontrol eder. Yerleşik sekmelere göre sekmenizi istediğiniz konuma yerleştirecek bir değer seçin.
|
||||
* Yalnızca mevcut bir düzene ekleme yapmak istediğinizde `definePageLayout` yerine bunu kullanın. Tüm düzene sahip olduğunuzda `definePageLayout` kullanın.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Views
|
||||
description: Ship pre-configured saved views — column order, filters, groups — for objects in your app.
|
||||
title: Görünümler
|
||||
description: Uygulamanızdaki nesneler için sütun sırası, filtreler, gruplar gibi önceden yapılandırılmış kaydedilmiş görünümleri yayınlayın.
|
||||
icon: list
|
||||
---
|
||||
|
||||
A **view** is a saved configuration for how records of an object are displayed: which fields appear, their order, whether they're visible, and any filters or groups applied. Use `defineView()` to ship pre-configured views with your app — typically a default index view for each custom object you create.
|
||||
Bir **görünüm**, bir nesnenin kayıtlarının nasıl görüntüleneceğine ilişkin kaydedilmiş bir yapılandırmadır: hangi alanların görüneceği, sıraları, görünür olup olmadıkları ve uygulanan tüm filtreler veya gruplar. Uygulamanızla birlikte önceden yapılandırılmış görünümler yayınlamak için `defineView()` kullanın — genellikle oluşturduğunuz her özel nesne için varsayılan bir indeks görünümü şeklinde olur.
|
||||
|
||||
```ts src/views/example-view.ts
|
||||
import { defineView, ViewKey } from 'twenty-sdk/define';
|
||||
@@ -30,14 +30,14 @@ export default defineView({
|
||||
});
|
||||
```
|
||||
|
||||
## Key points
|
||||
## Önemli noktalar
|
||||
|
||||
* `objectUniversalIdentifier` specifies which object this view applies to. It can be a custom object you defined or a standard Twenty object.
|
||||
* `key` determines the view type — `ViewKey.INDEX` is the main list view for the object.
|
||||
* `fields` controls which columns appear and in what order. Each field references a `fieldMetadataUniversalIdentifier`.
|
||||
* You can also declare `filters`, `filterGroups`, `groups`, and `fieldGroups` for advanced configurations.
|
||||
* `position` controls ordering when multiple views exist for the same object.
|
||||
* `objectUniversalIdentifier`, bu görünümün hangi nesneye uygulanacağını belirtir. Bu, tanımladığınız özel bir nesne veya standart bir Twenty nesnesi olabilir.
|
||||
* `key`, görünüm türünü belirler — `ViewKey.INDEX`, nesne için ana liste görünümüdür.
|
||||
* `fields`, hangi sütunların görüneceğini ve hangi sırayla görüneceğini kontrol eder. Her alan bir `fieldMetadataUniversalIdentifier` öğesine referans verir.
|
||||
* Daha gelişmiş yapılandırmalar için `filters`, `filterGroups`, `groups` ve `fieldGroups` da bildirebilirsiniz.
|
||||
* `position`, aynı nesne için birden fazla görünüm olduğunda sıralamayı kontrol eder.
|
||||
|
||||
## How views show up in the UI
|
||||
## Görünümlerin kullanıcı arayüzünde görüntülenme şekli
|
||||
|
||||
A view by itself isn't reachable from the sidebar. To make it appear there, pair it with a [navigation menu item](/l/tr/developers/extend/apps/layout/navigation-menu-items) of type `VIEW` that points at the view's `universalIdentifier`. That's the canonical pattern: every custom object typically ships a default view + a sidebar entry that opens it.
|
||||
Tek başına bir görünüm, kenar çubuğundan erişilebilir değildir. Orada görünmesini sağlamak için, türü `VIEW` olan ve görünümün `universalIdentifier` değerini işaret eden bir [navigasyon menüsü öğesi](/l/tr/developers/extend/apps/layout/navigation-menu-items) ile eşleştirin. Bu, standart örüntüdür: her özel nesne genellikle varsayılan bir görünüm ve bunu açan bir kenar çubuğu girdisiyle birlikte sunulur.
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
---
|
||||
title: Connections
|
||||
description: Let your app act on a user's behalf in third-party services via OAuth.
|
||||
title: Bağlantılar
|
||||
description: Uygulamanızın, OAuth aracılığıyla üçüncü taraf hizmetlerde kullanıcı adına işlem yapmasına izin verin.
|
||||
icon: plug
|
||||
---
|
||||
|
||||
Connections are credentials a user holds for an external service (Linear, GitHub, Slack, ...). Your app declares **how** those credentials are obtained — a **connection provider** — and consumes them at runtime to make authenticated calls to the third-party API.
|
||||
Bağlantılar, bir kullanıcının harici bir hizmet için (Linear, GitHub, Slack, ...) sahip olduğu kimlik bilgileridir. Uygulamanız bu kimlik bilgilerinin **nasıl** elde edildiğini — bir **bağlantı sağlayıcısı** — bildirir ve çalışma zamanında üçüncü taraf API'sine kimlik doğrulamalı çağrılar yapmak için bunları kullanır.
|
||||
|
||||
Today only OAuth 2.0 is supported. Future credential types (personal access tokens, API keys, basic auth) will plug into the same surface — apps already using `defineConnectionProvider({ type: 'oauth', ... })` won't need to migrate.
|
||||
Bugün yalnızca OAuth 2.0 destekleniyor. Gelecekteki kimlik bilgisi türleri (kişisel erişim belirteçleri, API anahtarları, basic auth) aynı yüzeye bağlanacak — halihazırda `defineConnectionProvider({ type: 'oauth', ... })` kullanan uygulamaların geçiş yapması gerekmeyecek.
|
||||
|
||||
<AccordionGroup>
|
||||
|
||||
<Accordion title="defineConnectionProvider" description="Declare how your app's connections are obtained">
|
||||
<Accordion title="defineConnectionProvider" description="Uygulamanızın bağlantılarının nasıl elde edildiğini belirtin">
|
||||
|
||||
A connection provider describes the OAuth handshake your app needs. The user clicks "Add connection" in your app's settings, completes the provider's consent screen, and a `ConnectedAccount` row is created in their workspace.
|
||||
Bir bağlantı sağlayıcısı, uygulamanızın ihtiyaç duyduğu OAuth el sıkışmasını açıklar. Kullanıcı, uygulamanızın ayarlarında "Bağlantı ekle"ye tıklar, sağlayıcının izin ekranını tamamlar ve çalışma alanında bir `ConnectedAccount` satırı oluşturulur.
|
||||
|
||||
A working setup needs **two files** — the connection provider, and a matching `serverVariables` declaration on `defineApplication` that holds the OAuth client credentials.
|
||||
Çalışan bir kurulum **iki dosya** gerektirir — bağlantı sağlayıcısı ve OAuth istemci kimlik bilgilerini tutan `defineApplication` üzerindeki eşleşen bir `serverVariables` bildirimi.
|
||||
|
||||
```ts src/connection-providers/linear-connection.ts
|
||||
import { defineConnectionProvider } from 'twenty-sdk/define';
|
||||
@@ -71,16 +71,16 @@ export default defineApplication({
|
||||
});
|
||||
```
|
||||
|
||||
Key points:
|
||||
Önemli noktalar:
|
||||
|
||||
* `name` is the unique identifier string used in `listConnections({ providerName })` (kebab-case, must match `^[a-z][a-z0-9-]*$`).
|
||||
* `displayName` shows in the per-app settings tab and in the AI tool list.
|
||||
* `clientIdVariable` / `clientSecretVariable` are **names**, not values — they must match keys declared in `defineApplication.serverVariables`. The actual `client_id` and `client_secret` are entered by the server admin through the app registration UI, never committed to your repo.
|
||||
* Use `serverVariables` (not `applicationVariables`) — OAuth credentials are server-wide and one OAuth app per Twenty server.
|
||||
* Until both `serverVariables` are filled in, the per-app settings tab shows a "needs server admin" hint and the "Add connection" button is disabled.
|
||||
* `type: 'oauth'` is the only supported value today. The discriminator is forward-compatible: future types (`'pat'`, `'api-key'`, ...) will add new sub-config blocks alongside `oauth`.
|
||||
* `name`, `listConnections({ providerName })` içinde kullanılan benzersiz tanımlayıcı dizedir (kebab-case, `^[a-z][a-z0-9-]*$` ile eşleşmelidir).
|
||||
* `displayName` uygulama başına ayarlar sekmesinde ve Yapay Zeka araç listesinde gösterilir.
|
||||
* `clientIdVariable` / `clientSecretVariable` değer değil, **isimdir** — `defineApplication.serverVariables` içinde bildirilen anahtarlarla eşleşmelidir. Gerçek `client_id` ve `client_secret`, sunucu yöneticisi tarafından uygulama kayıt arayüzü üzerinden girilir; deponuza asla commit edilmez.
|
||||
* `serverVariables` kullanın (`applicationVariables` değil) — OAuth kimlik bilgileri sunucu genelidir ve her Twenty sunucusu için bir OAuth uygulaması vardır.
|
||||
* Her iki `serverVariables` da doldurulana kadar, uygulama başına ayarlar sekmesi "sunucu yöneticisine ihtiyaç var" ipucunu gösterir ve "Bağlantı ekle" düğmesi devre dışı bırakılır.
|
||||
* `type: 'oauth'` bugün desteklenen tek değerdir. Ayırt edici alan ileriye dönük uyumludur: gelecekteki türler (`'pat'`, `'api-key'`, ...) `oauth` yanında yeni alt yapılandırma blokları eklenecektir.
|
||||
|
||||
The OAuth callback URL your provider needs to whitelist is:
|
||||
Sağlayıcınızın beyaz listeye alması gereken OAuth geri çağrı URL'si şudur:
|
||||
|
||||
```
|
||||
https://<your-twenty-server>/apps/oauth/callback
|
||||
@@ -88,9 +88,9 @@ https://<your-twenty-server>/apps/oauth/callback
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="listConnections / getConnection" description="Use connections from a logic function">
|
||||
<Accordion title="listConnections / getConnection" description="Bir mantık işlevinden bağlantıları kullanın">
|
||||
|
||||
Inside a logic function handler, `listConnections({ providerName })` returns this app's `ConnectedAccount` rows for the given provider, with refreshed access tokens.
|
||||
Bir mantık işlevi işleyicisi içinde, `listConnections({ providerName })`, verilen sağlayıcı için bu uygulamanın `ConnectedAccount` satırlarını, yenilenmiş erişim belirteçleriyle döndürür.
|
||||
|
||||
```ts src/logic-functions/handlers/create-linear-issue-handler.ts
|
||||
import { listConnections } from 'twenty-sdk/logic-function';
|
||||
@@ -135,34 +135,34 @@ export const createLinearIssueHandler = async (input: {
|
||||
};
|
||||
```
|
||||
|
||||
Each connection has:
|
||||
Her bağlantı şunlara sahiptir:
|
||||
|
||||
| Field | Description |
|
||||
| ----------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| `id` | Unique row id; pass to `getConnection(id)` to refetch a single one |
|
||||
| `visibility` | `'user'` (private to one workspace member) or `'workspace'` (shared with all members) |
|
||||
| `scopes` | OAuth permissions granted by the upstream provider (distinct from `visibility` — those are unrelated) |
|
||||
| `userWorkspaceId` | The owner's userWorkspace id — useful for picking "the request user's connection" in HTTP-route triggers |
|
||||
| `accessToken` | Fresh OAuth access token (refreshed automatically if expired) |
|
||||
| `name` / `handle` | The connection's display name (auto-derived at OAuth callback, user-renameable) |
|
||||
| `authFailedAt` | Set when the most recent refresh failed; the user must reconnect |
|
||||
| Alan | Açıklama |
|
||||
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `id` | Tekil satır kimliği; tek bir tanesini yeniden getirmek için `getConnection(id)` işlevine iletin |
|
||||
| `visibility` | `'user'` (bir çalışma alanı üyesine özel) veya `'workspace'` (tüm üyelerle paylaşılan) |
|
||||
| `scopes` | Üst sağlayıcı tarafından verilen OAuth izinleri (`visibility` ile karıştırılmamalıdır — bunlar ilişkili değildir) |
|
||||
| `userWorkspaceId` | Sahibinin userWorkspace kimliği — HTTP rota tetikleyicilerinde "istek kullanıcısının bağlantısını" seçmek için kullanışlıdır |
|
||||
| `accessToken` | Yeni OAuth erişim belirteci (süresi dolmuşsa otomatik olarak yenilenir) |
|
||||
| `name` / `handle` | Bağlantının görünen adı (OAuth geri çağrısında otomatik türetilir, kullanıcı tarafından yeniden adlandırılabilir) |
|
||||
| `authFailedAt` | En son yenileme başarısız olduğunda ayarlanır; kullanıcı yeniden bağlanmalıdır |
|
||||
|
||||
Key points:
|
||||
Önemli noktalar:
|
||||
|
||||
* Pass `{ providerName }` to filter by provider; omit it to get all connections this app owns across all providers.
|
||||
* The server transparently refreshes the access token before returning. Your handler always sees a usable token (or `authFailedAt` set).
|
||||
* `getConnection(id)` is the single-row equivalent.
|
||||
* Sağlayıcıya göre filtrelemek için `{ providerName }` iletin; bu uygulamanın tüm sağlayıcılardaki tüm bağlantılarını almak için bunu atlayın.
|
||||
* Sunucu, döndürmeden önce erişim belirtecini şeffaf bir şekilde yeniler. İşleyiciniz her zaman kullanılabilir bir belirteç görür (veya `authFailedAt` ayarlanmıştır).
|
||||
* `getConnection(id)`, tek satırlık karşılığıdır.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Per-user vs workspace-shared visibility" description="How users choose between private and shared credentials">
|
||||
<Accordion title="Kullanıcıya özel ve çalışma alanı paylaşımlı görünürlük" description="Kullanıcıların özel ve paylaşılan kimlik bilgileri arasında nasıl seçim yaptığı">
|
||||
|
||||
When a user clicks "Add connection," they're prompted to pick a visibility:
|
||||
Bir kullanıcı "Bağlantı ekle"ye tıkladığında, bir görünürlük seçmesi istenir:
|
||||
|
||||
* **Just for me** — the credential is private to the connecting user. Any logic function called on their behalf (HTTP-route trigger with `isAuthRequired: true`) sees it; cron triggers and database events do not.
|
||||
* **Workspace shared** — any workspace member can use the credential. Cron / database triggers also see it, since they have no request user.
|
||||
* **Yalnızca benim için** — kimlik bilgisi, bağlanan kullanıcıya özeldir. Adlarına çağrılan herhangi bir mantık işlevi (`isAuthRequired: true` ile HTTP rota tetikleyicisi) bunu görür; cron tetikleyicileri ve veritabanı olayları görmez.
|
||||
* **Çalışma alanı paylaşımlı** — herhangi bir çalışma alanı üyesi bu kimlik bilgisini kullanabilir. Cron / veritabanı tetikleyicileri de görür, çünkü istek kullanıcısı yoktur.
|
||||
|
||||
Use the right one for each handler:
|
||||
Her işleyici için doğru olanı kullanın:
|
||||
|
||||
```ts
|
||||
// HTTP-route trigger — prefer the request user's own connection.
|
||||
@@ -174,19 +174,19 @@ const conn =
|
||||
const conn = connections.find((c) => c.visibility === 'workspace');
|
||||
```
|
||||
|
||||
Multiple connections per (user, provider) are allowed, so the same user can hold "Personal Linear" and "Work Linear" side by side.
|
||||
Kullanıcı ve sağlayıcı başına birden çok bağlantıya izin verilir; böylece aynı kullanıcı "Personal Linear" ve "Work Linear" bağlantılarını yan yana tutabilir.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="One-time provider setup" description="Register your OAuth app with the third-party service">
|
||||
<Accordion title="Tek seferlik sağlayıcı kurulumu" description="OAuth uygulamanızı üçüncü taraf hizmete kaydedin">
|
||||
|
||||
For each connection provider, the server admin needs to register an OAuth app at the third party first.
|
||||
Her bağlantı sağlayıcısı için, sunucu yöneticisinin önce üçüncü tarafta bir OAuth uygulaması kaydetmesi gerekir.
|
||||
|
||||
1. Go to the provider's developer settings (e.g. https://linear.app/settings/api/applications/new).
|
||||
2. Set the **Redirect URI** to `\<SERVER_URL>/apps/oauth/callback`.
|
||||
3. Copy the generated **Client ID** and **Client Secret**.
|
||||
4. Open the installed app in Twenty as a server admin → set the values on the corresponding `serverVariables`.
|
||||
5. Workspace members can then add connections from the per-app **Connections** section.
|
||||
1. Sağlayıcının geliştirici ayarlarına gidin (örn. https://linear.app/settings/api/applications/new).
|
||||
2. **Redirect URI**'yi `\<SERVER_URL>/apps/oauth/callback` olarak ayarlayın.
|
||||
3. Oluşturulan **Client ID** ve **Client Secret**'ı kopyalayın.
|
||||
4. Yüklü uygulamayı Twenty'de bir sunucu yöneticisi olarak açın → karşılık gelen `serverVariables` üzerinde değerleri ayarlayın.
|
||||
5. Ardından çalışma alanı üyeleri, uygulama başına **Bağlantılar** bölümünden bağlantılar ekleyebilir.
|
||||
|
||||
</Accordion>
|
||||
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
---
|
||||
title: Logic Functions
|
||||
description: Define server-side TypeScript functions with HTTP, cron, and database event triggers.
|
||||
title: Mantıksal işlevler
|
||||
description: Sunucu tarafı TypeScript işlevlerini HTTP, cron ve veritabanı olay tetikleyicileriyle tanımlayın.
|
||||
icon: bolt
|
||||
---
|
||||
|
||||
Logic functions are server-side TypeScript functions that run on the Twenty platform. They can be triggered by HTTP requests, cron schedules, or database events — and can also be exposed as tools for AI agents.
|
||||
Mantık işlevleri, Twenty platformunda çalışan sunucu tarafı TypeScript işlevleridir. HTTP istekleri, cron zamanlamaları veya veritabanı olayları tarafından tetiklenebilirler — ve ayrıca yapay zekâ ajanları için araçlar olarak sunulabilirler.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="defineLogicFunction" description="Define logic functions and their triggers">
|
||||
<Accordion title="defineLogicFunction" description="Mantık fonksiyonlarını ve tetikleyicilerini tanımlayın">
|
||||
|
||||
Each function file uses `defineLogicFunction()` to export a configuration with a handler and optional triggers.
|
||||
Her fonksiyon dosyası, bir işleyici ve isteğe bağlı tetikleyiciler içeren bir yapılandırmayı dışa aktarmak için `defineLogicFunction()` kullanır.
|
||||
|
||||
```ts src/logic-functions/createPostCard.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk/define';
|
||||
@@ -50,15 +50,15 @@ export default defineLogicFunction({
|
||||
});
|
||||
```
|
||||
|
||||
Available trigger types:
|
||||
* **httpRoute**: Exposes your function on an HTTP path and method **under the `/s/` endpoint**:
|
||||
> e.g. `path: '/post-card/create'` is callable at `https://your-twenty-server.com/s/post-card/create`
|
||||
* **cron**: Runs your function on a schedule using a CRON expression.
|
||||
* **databaseEvent**: Runs on workspace object lifecycle events. When the event operation is `updated`, specific fields to listen to can be specified in the `updatedFields` array. If left undefined or empty, any update will trigger the function.
|
||||
> e.g. `person.updated`, `*.created`, `company.*`
|
||||
Kullanılabilir tetikleyici türleri:
|
||||
* **httpRoute**: Fonksiyonunuzu bir HTTP yolu ve yöntemiyle **`/s/` uç noktasının altında** kullanıma sunar:
|
||||
> örn. `path: '/post-card/create'` `https://your-twenty-server.com/s/post-card/create` adresinden çağrılabilir
|
||||
* **cron**: Bir CRON ifadesi kullanarak fonksiyonunuzu bir zamanlamayla çalıştırır.
|
||||
* **databaseEvent**: Çalışma alanı nesnesi yaşam döngüsü olaylarında çalışır. Olay işlemi `updated` olduğunda, dinlenecek belirli alanlar `updatedFields` dizisinde belirtilebilir. Tanımsız veya boş bırakılırsa, herhangi bir güncelleme fonksiyonu tetikler.
|
||||
> örn. `person.updated`, `*.created`, `company.*`
|
||||
|
||||
<Note>
|
||||
You can also manually execute a function using the CLI:
|
||||
Bir fonksiyonu CLI kullanarak manuel olarak da çalıştırabilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty exec -n create-new-post-card -p '{"key": "value"}'
|
||||
@@ -68,18 +68,18 @@ yarn twenty exec -n create-new-post-card -p '{"key": "value"}'
|
||||
yarn twenty exec -y e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
```
|
||||
|
||||
You can watch logs with:
|
||||
Günlükleri şu şekilde izleyebilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty logs
|
||||
```
|
||||
</Note>
|
||||
|
||||
#### Route trigger payload
|
||||
#### Rota tetikleyicisi yükü
|
||||
|
||||
When a route trigger invokes your logic function, it receives a `RoutePayload` object that follows the
|
||||
[AWS HTTP API v2 format](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html).
|
||||
Import the `RoutePayload` type from `twenty-sdk`:
|
||||
Bir rota tetikleyicisi mantık fonksiyonunuzu çağırdığında,
|
||||
[AWS HTTP API v2 formatını](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-develop-integrations-lambda.html) izleyen bir `RoutePayload` nesnesi alır.
|
||||
`RoutePayload` türünü `twenty-sdk` içinden içe aktarın:
|
||||
|
||||
```ts
|
||||
import { defineLogicFunction, type RoutePayload } from 'twenty-sdk/define';
|
||||
@@ -92,24 +92,24 @@ const handler = async (event: RoutePayload) => {
|
||||
};
|
||||
```
|
||||
|
||||
The `RoutePayload` type has the following structure:
|
||||
`RoutePayload` türünün yapısı şu şekildedir:
|
||||
|
||||
| Property | Type | Description | Example |
|
||||
| ---------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| `headers` | `Record\<string, string \| undefined>` | HTTP headers (only those listed in `forwardedRequestHeaders`) | see section below |
|
||||
| `queryStringParameters` | `Record\<string, string \| undefined>` | Query string parameters (multiple values joined with commas) | `/users?ids=1&ids=2&ids=3&name=Alice` -> `{ ids: '1,2,3', name: 'Alice' }` |
|
||||
| `pathParameters` | `Record\<string, string \| undefined>` | Path parameters extracted from the route pattern | `/users/:id`, `/users/123` -> `{ id: '123' }` |
|
||||
| `body` | `object \| null` | Parsed request body (JSON) | `{ id: 1 }` -> `{ id: 1 }` |
|
||||
| `rawBody` | `string \| undefined` | Original UTF-8 request body, before JSON parsing. Useful for verifying HMAC-style webhook signatures (e.g. GitHub's `X-Hub-Signature-256`, Stripe). `undefined` when the runtime did not preserve it. | |
|
||||
| `isBase64Encoded` | `boolean` | Whether the body is base64 encoded | |
|
||||
| `requestContext.http.method` | `string` | HTTP method (GET, POST, PUT, PATCH, DELETE) | |
|
||||
| `requestContext.http.path` | `string` | Raw request path | |
|
||||
| Özellik | Tür | Açıklama | Örnek |
|
||||
| ---------------------------- | ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| `headers` | `Record\<string, string \| undefined>` | HTTP başlıkları (`forwardedRequestHeaders` içinde listelenenlerle sınırlı) | aşağıdaki bölüme bakın |
|
||||
| `queryStringParameters` | `Record\<string, string \| undefined>` | Sorgu dizesi parametreleri (birden çok değer virgülle birleştirilir) | `/users?ids=1&ids=2&ids=3&name=Alice` -> `{ ids: '1,2,3', name: 'Alice' }` |
|
||||
| `pathParameters` | `Record\<string, string \| undefined>` | Rota deseninden çıkarılan yol parametreleri | `/users/:id`, `/users/123` -> `{ id: '123' }` |
|
||||
| `body` | `object \| null` | Ayrıştırılmış istek gövdesi (JSON) | `{ id: 1 }` -> `{ id: 1 }` |
|
||||
| `rawBody` | `string \| undefined` | JSON ayrıştırılmadan önceki özgün UTF-8 istek gövdesi. HMAC tarzı webhook imzalarını doğrulamak için kullanışlıdır (ör. GitHub'ın `X-Hub-Signature-256`, Stripe). Çalışma zamanı onu korumadığında `undefined` olur. | |
|
||||
| `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 | |
|
||||
|
||||
|
||||
#### forwardedRequestHeaders
|
||||
|
||||
By default, HTTP headers from incoming requests are **not** passed to your logic function for security reasons.
|
||||
To access specific headers, list them in the `forwardedRequestHeaders` array:
|
||||
Varsayılan olarak, güvenlik nedenleriyle gelen isteklerden HTTP başlıkları mantık fonksiyonunuza **aktarılmaz**.
|
||||
Belirli başlıklara erişmek için bunları `forwardedRequestHeaders` dizisinde listeleyin:
|
||||
|
||||
```ts
|
||||
export default defineLogicFunction({
|
||||
@@ -125,7 +125,7 @@ export default defineLogicFunction({
|
||||
});
|
||||
```
|
||||
|
||||
In your handler, access the forwarded headers like this:
|
||||
İşleyicinizde, iletilen başlıklara şu şekilde erişin:
|
||||
|
||||
```ts
|
||||
const handler = async (event: RoutePayload) => {
|
||||
@@ -138,17 +138,17 @@ const handler = async (event: RoutePayload) => {
|
||||
```
|
||||
|
||||
<Note>
|
||||
Header names are normalized to lowercase. Access them using lowercase keys (e.g., `event.headers['content-type']`).
|
||||
Başlık adları küçük harfe normalize edilir. Onlara küçük harfli anahtarlarla erişin (örneğin, `event.headers['content-type']`).
|
||||
</Note>
|
||||
|
||||
#### Exposing a function as an AI tool or workflow action
|
||||
#### Bir işlevi bir yapay zekâ aracı veya iş akışı eylemi olarak kullanıma sunma
|
||||
|
||||
Logic functions can be exposed on two surfaces, each with its own trigger:
|
||||
Mantık işlevleri, her birinin kendi tetikleyicisi olacak şekilde iki yerde kullanılabilir hâle getirilebilir:
|
||||
|
||||
* **`toolTriggerSettings`** — makes the function discoverable by Twenty's AI features (chat, MCP, function calling). Uses standard JSON Schema, the format LLMs natively understand.
|
||||
* **`workflowActionTriggerSettings`** — makes the function appear as a step in the visual workflow builder. Uses Twenty's rich `InputSchema` so the builder can render proper field editors, variable pickers, and labels.
|
||||
* **`toolTriggerSettings`** — işlevi Twenty'nin yapay zekâ özellikleri (sohbet, MCP, işlev çağırma) tarafından bulunabilir hâle getirir. Standart JSON Şeması'nı kullanır; LLM'lerin doğal olarak anladığı biçimdir.
|
||||
* **`workflowActionTriggerSettings`** — işlevin görsel iş akışı oluşturucusunda bir adım olarak görünmesini sağlar. Oluşturucunun uygun alan düzenleyicilerini, değişken seçicilerini ve etiketleri oluşturabilmesi için Twenty'nin zengin `InputSchema`'sını kullanır.
|
||||
|
||||
A function can opt into one, the other, or both. They sit alongside `cronTriggerSettings`, `databaseEventTriggerSettings`, and `httpRouteTriggerSettings` — same pattern, same shape.
|
||||
Bir işlev bunlardan birini, diğerini veya her ikisini de tercih edebilir. Bunlar, `cronTriggerSettings`, `databaseEventTriggerSettings` ve `httpRouteTriggerSettings` ile birlikte yer alır — aynı desen, aynı biçim.
|
||||
|
||||
```ts src/logic-functions/enrich-company.logic-function.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk/define';
|
||||
@@ -182,10 +182,10 @@ export default defineLogicFunction({
|
||||
});
|
||||
```
|
||||
|
||||
Key points:
|
||||
Önemli noktalar:
|
||||
|
||||
* A function can mix surfaces — declare both `toolTriggerSettings` and `workflowActionTriggerSettings` to expose it in chat AND in the workflow builder.
|
||||
* `toolTriggerSettings.inputSchema` and `workflowActionTriggerSettings.inputSchema` are both optional. When omitted, the manifest builder infers them from the handler source code (JSON Schema for the AI tool, Twenty's `InputSchema` for the workflow action). Provide one explicitly when you want richer typing — for example, with `FieldMetadataType`-aware fields like `CURRENCY` or `RELATION` for the workflow builder, or with `description` fields the AI agent can read:
|
||||
* Bir işlev yüzeyleri karıştırabilir — onu sohbette VE iş akışı oluşturucusunda kullanıma sunmak için hem `toolTriggerSettings` hem de `workflowActionTriggerSettings` bildirin.
|
||||
* `toolTriggerSettings.inputSchema` ve `workflowActionTriggerSettings.inputSchema` ikisi de isteğe bağlıdır. Atlandığında, manifest oluşturucu bunları işleyici kaynak kodundan çıkarır (yapay zekâ aracı için JSON Şeması, iş akışı eylemi için Twenty'nin `InputSchema`'sı). Daha zengin tipleme istediğinizde birini açıkça belirtin — örneğin, iş akışı oluşturucu için `FieldMetadataType`'ı bilen `CURRENCY` veya `RELATION` gibi alanlarla ya da yapay zekâ aracısının okuyabileceği `description` alanlarıyla:
|
||||
|
||||
```ts
|
||||
export default defineLogicFunction({
|
||||
@@ -210,29 +210,29 @@ export default defineLogicFunction({
|
||||
```
|
||||
|
||||
<Note>
|
||||
**Write a good `description`.** AI agents rely on the function's `description` field to decide when to use the tool. Be specific about what the tool does and when it should be called.
|
||||
**İyi bir `description` yazın.** AI ajanları, aracı ne zaman kullanacaklarına karar vermek için işlevin `description` alanına güvenir. Aracın ne yaptığını ve ne zaman çağrılması gerektiğini açıkça belirtin.
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
<Note>
|
||||
**Install hooks** — pre-install and post-install handlers — share this runtime but are declared with their own define functions and don't take trigger settings. See [Install Hooks](/l/tr/developers/extend/apps/config/install-hooks) for `definePreInstallLogicFunction` and `definePostInstallLogicFunction`.
|
||||
**Yükleme kancaları** — ön yükleme ve yükleme sonrası işleyiciler — bu çalışma zamanını paylaşır ancak kendi tanımlama işlevleriyle bildirilir ve tetikleyici ayarlarını almaz. `definePreInstallLogicFunction` ve `definePostInstallLogicFunction` için [Yükleme Kancaları](/l/tr/developers/extend/apps/config/install-hooks) bölümüne bakın.
|
||||
</Note>
|
||||
|
||||
## 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 tip tanımlı iki GraphQL istemcisi sağlar.
|
||||
|
||||
| Client | Import | 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 |
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="CoreApiClient" description="Query and mutate workspace data (records, objects)">
|
||||
<Accordion title="CoreApiClient" description="Çalışma alanı verilerini sorgulayın ve değiştirin (kayıtlar, nesneler)">
|
||||
|
||||
`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 is 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 tiplenmiştir.
|
||||
|
||||
```ts
|
||||
import { CoreApiClient } from 'twenty-client-sdk/core';
|
||||
@@ -269,15 +269,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 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 and generates a typed client using `@genql/cli`.
|
||||
**CoreApiClient geliştirme/derleme zamanında oluşturulur.** Bunu önce `yarn twenty dev` veya `yarn twenty build` çalıştırmadan kullanırsanız, bir hata verir. Oluşturma otomatik olarak gerçekleşir — CLI, çalışma alanınızın GraphQL şemasını inceler ve `@genql/cli` kullanarak tiplenmiş bir istemci üretir.
|
||||
</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:
|
||||
|
||||
```ts
|
||||
import { CoreApiClient, CoreSchema } from 'twenty-client-sdk/core';
|
||||
@@ -299,9 +299,9 @@ setCompany(result.company);
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="MetadataApiClient" description="Workspace config, applications, and file uploads">
|
||||
<Accordion title="MetadataApiClient" description="Çalışma alanı yapılandırması, uygulamalar ve dosya yüklemeleri">
|
||||
|
||||
`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.
|
||||
|
||||
```ts
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -328,9 +328,9 @@ const { objects } = await metadataClient.query({
|
||||
});
|
||||
```
|
||||
|
||||
#### Uploading files
|
||||
#### Dosya yükleme
|
||||
|
||||
`MetadataApiClient` includes an `uploadFile` method for attaching files to file-type fields:
|
||||
`MetadataApiClient`, dosya türündeki alanlara dosya eklemek için bir `uploadFile` yöntemi içerir:
|
||||
|
||||
```ts
|
||||
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
|
||||
@@ -351,25 +351,25 @@ console.log(uploadedFile);
|
||||
// { id: '...', path: '...', size: 12345, createdAt: '...', url: 'https://...' }
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| ---------------------------------- | -------- | --------------------------------------------------------------- |
|
||||
| `fileBuffer` | `Buffer` | The raw file contents |
|
||||
| `filename` | `string` | The name of the file (used for storage and display) |
|
||||
| `contentType` | `string` | MIME type (defaults to `application/octet-stream` if omitted) |
|
||||
| `fieldMetadataUniversalIdentifier` | `string` | The `universalIdentifier` of the file-type field on your object |
|
||||
| Parametre | Tür | Açıklama |
|
||||
| ---------------------------------- | -------- | --------------------------------------------------------------------------------- |
|
||||
| `fileBuffer` | `Buffer` | Dosyanın ham içeriği |
|
||||
| `filename` | `string` | Dosyanın adı (depolama ve görüntüleme için kullanılır) |
|
||||
| `contentType` | `string` | MIME türü (belirtilmezse varsayılan olarak `application/octet-stream` kullanılır) |
|
||||
| `fieldMetadataUniversalIdentifier` | `string` | Nesnenizdeki dosya türü alanının `universalIdentifier` değeri |
|
||||
|
||||
Key points:
|
||||
* Uses the field's `universalIdentifier` (not its workspace-specific ID), so your upload code works across any workspace where your app is installed.
|
||||
* The returned `url` is a signed URL you can use to access the uploaded file.
|
||||
Önemli noktalar:
|
||||
* 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.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
<Note>
|
||||
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_APP_ACCESS_TOKEN` — Short-lived key scoped to your application's default function role
|
||||
* `TWENTY_API_URL` — Twenty API'nin temel URL'si
|
||||
* `TWENTY_APP_ACCESS_TOKEN` — Uygulamanızın varsayılan işlev rolü kapsamında kısa ömürlü bir 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.
|
||||
</Note>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Overview
|
||||
description: Server-side TypeScript that runs inside Twenty — triggered by HTTP routes, cron schedules, database events, AI tools, or workflow actions.
|
||||
title: Genel Bakış
|
||||
description: Twenty içinde çalışan sunucu tarafı TypeScript — HTTP rotaları, cron zamanlamaları, veritabanı olayları, yapay zeka araçları veya iş akışı aksiyonları tarafından tetiklenir.
|
||||
icon: bolt
|
||||
---
|
||||
|
||||
A Twenty app's **logic layer** is the code that *runs* — server-side TypeScript handlers reacting to HTTP requests, cron schedules, and record changes; AI skills and agents that live inside the workspace; and OAuth connections that let your functions act on a user's behalf in third-party services.
|
||||
Bir Twenty uygulamasının **mantık katmanı**, *çalışan* koddur — HTTP isteklerine, cron zamanlamalarına ve kayıt değişikliklerine tepki veren sunucu tarafı TypeScript işleyicileri; çalışma alanının içinde yaşayan yapay zeka yetenekleri ve ajanları; ve işlevlerinizin üçüncü taraf servislerde bir kullanıcının adına hareket etmesini sağlayan OAuth bağlantıları.
|
||||
|
||||
```text
|
||||
┌─ HTTP route ──┐
|
||||
@@ -22,34 +22,34 @@ A Twenty app's **logic layer** is the code that *runs* — server-side TypeScrip
|
||||
└────────────────────────────┘
|
||||
```
|
||||
|
||||
## In this section
|
||||
## Bu bölümde
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Logic Functions" icon="bolt" href="/l/tr/developers/extend/apps/logic/logic-functions">
|
||||
The core building block — trigger types, payloads, and the typed API client.
|
||||
<Card title="Mantıksal işlevler" icon="bolt" href="/l/tr/developers/extend/apps/logic/logic-functions">
|
||||
Temel yapı taşı — tetikleyici türleri, payload'lar ve tür güvenli API istemcisi.
|
||||
</Card>
|
||||
<Card title="Skills & Agents" icon="robot" href="/l/tr/developers/extend/apps/logic/skills-and-agents">
|
||||
Reusable AI agent instructions and assistants with custom system prompts.
|
||||
<Card title="Beceriler ve Ajanlar" icon="robot" href="/l/tr/developers/extend/apps/logic/skills-and-agents">
|
||||
Yeniden kullanılabilir yapay zeka ajan talimatları ve özel sistem komutlarına sahip asistanlar.
|
||||
</Card>
|
||||
<Card title="Connections" icon="plug" href="/l/tr/developers/extend/apps/logic/connections">
|
||||
OAuth credentials your app holds for third-party services — Linear, GitHub, Slack, and more.
|
||||
<Card title="Bağlantılar" icon="plug" href="/l/tr/developers/extend/apps/logic/connections">
|
||||
Uygulamanızın üçüncü taraf servisler — Linear, GitHub, Slack ve daha fazlası — için tuttuğu OAuth kimlik bilgileri.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Trigger types at a glance
|
||||
## Tetikleyici türlerine genel bakış
|
||||
|
||||
A logic function picks one or more triggers — every entry below is a separate field on `defineLogicFunction()`:
|
||||
Bir mantık fonksiyonu bir veya daha fazla tetikleyici seçer — aşağıdaki her giriş, `defineLogicFunction()` üzerinde ayrı bir alandır:
|
||||
|
||||
| Trigger | When it runs | Setting |
|
||||
| ------------------- | ---------------------------------------------------------- | ------------------------------- |
|
||||
| **HTTP route** | A request hits your `/s/\<path>` endpoint | `httpRouteTriggerSettings` |
|
||||
| **Cron** | A CRON expression matches | `cronTriggerSettings` |
|
||||
| **Database event** | A workspace record is created, updated, or deleted | `databaseEventTriggerSettings` |
|
||||
| **AI tool** | A Twenty AI feature decides to call your function | `toolTriggerSettings` |
|
||||
| **Workflow action** | A workflow step invokes your function | `workflowActionTriggerSettings` |
|
||||
| Tetikleyici | Ne zaman çalışır | Ayar |
|
||||
| --------------------- | ---------------------------------------------------------------------------- | ------------------------------- |
|
||||
| **HTTP rotası** | Bir istek `/s/\<path>` endpoint'inize ulaşır | `httpRouteTriggerSettings` |
|
||||
| **Cron** | Bir CRON ifadesi eşleştiğinde | `cronTriggerSettings` |
|
||||
| **Veritabanı olayı** | Bir çalışma alanı kaydı oluşturulduğunda, güncellendiğinde veya silindiğinde | `databaseEventTriggerSettings` |
|
||||
| **Yapay zeka aracı** | Bir Twenty yapay zeka özelliği, fonksiyonunuzu çağırmaya karar verdiğinde | `toolTriggerSettings` |
|
||||
| **İş Akışı Aksiyonu** | Bir iş akışı adımı fonksiyonunuzu çağırdığında | `workflowActionTriggerSettings` |
|
||||
|
||||
Functions run sandboxed in isolated Node.js processes and access the workspace through a typed API client scoped to the role declared on [`defineApplication()`](/l/tr/developers/extend/apps/config/application).
|
||||
Fonksiyonlar, izole Node.js süreçlerinde sandbox içinde çalışır ve çalışma alanına, [`defineApplication()`](/l/tr/developers/extend/apps/config/application) üzerinde beyan edilen role göre kapsamlandırılmış tür güvenli bir API istemcisi aracılığıyla erişir.
|
||||
|
||||
<Note>
|
||||
**Install-time hooks** — code that runs before or after the install — share this runtime but use their own define functions and live under [Config → Install Hooks](/l/tr/developers/extend/apps/config/install-hooks).
|
||||
**Yükleme zamanı kancaları** — yüklemeden önce veya sonra çalışan kod — bu çalışma zamanını paylaşır ancak kendi define fonksiyonlarını kullanır ve [Config → Install Hooks](/l/tr/developers/extend/apps/config/install-hooks) altında bulunur.
|
||||
</Note>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
---
|
||||
title: Skills & Agents
|
||||
description: Define AI skills and agents for your app.
|
||||
title: Beceriler ve Ajanlar
|
||||
description: Uygulamanız için yapay zekâ yetenekleri ve ajanları tanımlayın.
|
||||
icon: robot
|
||||
---
|
||||
|
||||
<Warning>
|
||||
Skills and agents are currently in alpha. The feature works but is still evolving.
|
||||
Beceriler ve ajanlar şu anda alfa aşamasında. Özellik işlevsel ancak hâlâ gelişmekte.
|
||||
</Warning>
|
||||
|
||||
Apps can define AI capabilities that live inside the workspace — reusable skill instructions and agents with custom system prompts.
|
||||
Uygulamalar, çalışma alanı içinde yer alan yapay zekâ yeteneklerini — yeniden kullanılabilir yetenek yönergeleri ve özel sistem istemlerine sahip ajanları — tanımlayabilir.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="defineSkill" description="Define AI agent skills">
|
||||
<Accordion title="defineSkill" description="Yapay zekâ ajanı yeteneklerini tanımlayın">
|
||||
|
||||
Skills define reusable instructions and capabilities that AI agents can use within your workspace. Use `defineSkill()` to define skills with built-in validation:
|
||||
Yetenekler, yapay zekâ ajanlarının çalışma alanınızda kullanabileceği yeniden kullanılabilir yönergeleri ve kabiliyetleri tanımlar. Yerleşik doğrulamayla yetenekleri tanımlamak için `defineSkill()` kullanın:
|
||||
|
||||
```ts src/skills/example-skill.ts
|
||||
import { defineSkill } from 'twenty-sdk/define';
|
||||
@@ -32,17 +32,17 @@ export default defineSkill({
|
||||
});
|
||||
```
|
||||
|
||||
Key points:
|
||||
* `name` is a unique identifier string for the skill (kebab-case recommended).
|
||||
* `label` is the human-readable display name shown in the UI.
|
||||
* `content` contains the skill instructions — this is the text the AI agent uses.
|
||||
* `icon` (optional) sets the icon displayed in the UI.
|
||||
* `description` (optional) provides additional context about the skill's purpose.
|
||||
Önemli noktalar:
|
||||
* `name`, yetenek için benzersiz bir tanımlayıcı dizedir (kebab-case önerilir).
|
||||
* `label`, UI'de gösterilen, insan tarafından okunabilir addır.
|
||||
* `content`, yetenek yönergelerini içerir — bu, yapay zekâ ajanının kullandığı metindir.
|
||||
* `icon` (isteğe bağlı), UI'de gösterilen simgeyi ayarlar.
|
||||
* `description` (isteğe bağlı), yeteneğin amacı hakkında ek bağlam sağlar.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="defineAgent" description="Define AI agents with custom prompts">
|
||||
<Accordion title="defineAgent" description="Özel istemlerle yapay zekâ ajanları tanımlayın">
|
||||
|
||||
Agents are AI assistants that live inside your workspace. Use `defineAgent()` to create agents with a custom system prompt:
|
||||
Ajanlar, çalışma alanınız içinde bulunan yapay zekâ asistanlarıdır. Özel bir sistem istemiyle ajanlar oluşturmak için `defineAgent()` kullanın:
|
||||
|
||||
```ts src/agents/example-agent.ts
|
||||
import { defineAgent } from 'twenty-sdk/define';
|
||||
@@ -57,13 +57,13 @@ export default defineAgent({
|
||||
});
|
||||
```
|
||||
|
||||
Key points:
|
||||
* `name` is the unique identifier string for the agent (kebab-case recommended).
|
||||
* `label` is the display name shown in the UI.
|
||||
* `prompt` is the system prompt that defines the agent's behavior.
|
||||
* `description` (optional) provides context about what the agent does.
|
||||
* `icon` (optional) sets the icon displayed in the UI.
|
||||
* `modelId` (optional) overrides the default AI model used by the agent.
|
||||
Önemli noktalar:
|
||||
* `name`, ajan için benzersiz bir tanımlayıcı dizedir (kebab-case önerilir).
|
||||
* `label`, UI'de gösterilen görünen addır.
|
||||
* `prompt`, ajanın davranışını tanımlayan sistem istemidir.
|
||||
* `description` (isteğe bağlı), ajanın ne yaptığı hakkında bağlam sağlar.
|
||||
* `icon` (isteğe bağlı), UI'de gösterilen simgeyi ayarlar.
|
||||
* `modelId` (isteğe bağlı), ajanın kullandığı varsayılan yapay zekâ modelini geçersiz kılar.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
title: CLI
|
||||
description: yarn twenty commands for executing functions, streaming logs, managing app installations, and switching remotes.
|
||||
description: fonksiyonları çalıştırmak, günlükleri akış olarak izlemek, uygulama kurulumlarını yönetmek ve uzak depolar arasında geçiş yapmak için yarn twenty komutları.
|
||||
icon: terminal
|
||||
---
|
||||
|
||||
Beyond `dev`, `build`, `add`, and `typecheck`, the `yarn twenty` CLI provides commands for executing functions, viewing logs, and managing app installations.
|
||||
`dev`, `build`, `add` ve `typecheck` dışında, `yarn twenty` CLI, fonksiyonları çalıştırma, günlükleri görüntüleme ve uygulama kurulumlarını yönetme komutları sağlar.
|
||||
|
||||
## Executing functions (`yarn twenty exec`)
|
||||
## Fonksiyonları çalıştırma (`yarn twenty exec`)
|
||||
|
||||
Run a logic function manually without triggering it via HTTP, cron, or database event:
|
||||
Bir mantık fonksiyonunu HTTP, cron veya veritabanı olayıyla tetiklemeden manuel olarak çalıştırın:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Execute by function name
|
||||
@@ -24,9 +24,9 @@ yarn twenty exec -n create-new-post-card -p '{"name": "Hello"}'
|
||||
yarn twenty exec --postInstall
|
||||
```
|
||||
|
||||
## Viewing function logs (`yarn twenty logs`)
|
||||
## Fonksiyon günlüklerini görüntüleme (`yarn twenty logs`)
|
||||
|
||||
Stream execution logs for your app's logic functions:
|
||||
Uygulamanızın mantık fonksiyonlarının yürütme günlüklerini akış olarak alın:
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Stream all function logs
|
||||
@@ -40,12 +40,12 @@ yarn twenty logs -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
|
||||
```
|
||||
|
||||
<Note>
|
||||
This is different from `yarn twenty server logs`, which shows the Docker container logs. `yarn twenty logs` shows your app's function execution logs from the Twenty server.
|
||||
Bu, Docker konteyner günlüklerini gösteren `yarn twenty server logs` komutundan farklıdır. `yarn twenty logs`, uygulamanızın fonksiyon yürütme günlüklerini Twenty sunucusundan gösterir.
|
||||
</Note>
|
||||
|
||||
## Uninstalling an app (`yarn twenty uninstall`)
|
||||
## Bir uygulamayı kaldırma (`yarn twenty uninstall`)
|
||||
|
||||
Remove your app from the active workspace:
|
||||
Uygulamanızı etkin çalışma alanından kaldırın:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty uninstall
|
||||
@@ -54,9 +54,9 @@ yarn twenty uninstall
|
||||
yarn twenty uninstall --yes
|
||||
```
|
||||
|
||||
## Managing remotes
|
||||
## Uzakları yönetme
|
||||
|
||||
A **remote** is a Twenty server that your app connects to. During setup, the scaffolder creates one for you automatically. You can add more remotes or switch between them at any time.
|
||||
Bir **uzak**, uygulamanızın bağlandığı Twenty sunucusudur. Kurulum sırasında iskelet oluşturucu sizin için otomatik olarak bir tane oluşturur. Dilediğiniz zaman daha fazla uzak ekleyebilir veya aralarında geçiş yapabilirsiniz.
|
||||
|
||||
```bash filename="Terminal"
|
||||
# Add a new remote (opens a browser for OAuth login)
|
||||
@@ -75,4 +75,4 @@ yarn twenty remote list
|
||||
yarn twenty remote switch <name>
|
||||
```
|
||||
|
||||
Your credentials are stored in `~/.twenty/config.json`.
|
||||
Kimlik bilgileriniz `~/.twenty/config.json` içinde saklanır.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
---
|
||||
title: Overview
|
||||
description: Build, test, and ship your app — CLI commands, integration tests, CI, and publishing to a server or to npm.
|
||||
title: Genel Bakış
|
||||
description: Uygulamanızı oluşturun, test edin ve yayınlayın — CLI komutları, entegrasyon testleri, CI ve bir sunucuya veya npm'e yayınlama.
|
||||
icon: rocket
|
||||
---
|
||||
|
||||
The **operations layer** is everything you do *to* your app rather than *with* it: invoking CLI commands, running integration tests against a real Twenty server, configuring CI, and shipping releases — either as a tarball deployed to a single server or as an npm package listed in the marketplace.
|
||||
**Operasyon katmanı**, uygulamanızla *birlikte* yaptıklarınızdan ziyade, uygulamanıza *karşı* yaptığınız her şeydir: CLI komutlarını çalıştırmak, gerçek bir Twenty sunucusuna karşı entegrasyon testleri yürütmek, CI yapılandırmak ve sürümleri yayınlamak — tek bir sunucuya dağıtılan bir tarball olarak veya pazarda listelenen bir npm paketi olarak.
|
||||
|
||||
```text
|
||||
develop ─▶ test ─▶ build ─▶ deploy / publish
|
||||
@@ -14,16 +14,16 @@ The **operations layer** is everything you do *to* your app rather than *with* i
|
||||
dev build yarn twenty publish (npm → marketplace)
|
||||
```
|
||||
|
||||
## In this section
|
||||
## Bu bölümde
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="CLI" icon="terminal" href="/l/tr/developers/extend/apps/operations/cli">
|
||||
`yarn twenty` reference — exec, logs, uninstall, remotes.
|
||||
`yarn twenty` başvurusu — exec, logs, uninstall, remotes.
|
||||
</Card>
|
||||
<Card title="Testing" icon="flask" href="/l/tr/developers/extend/apps/operations/testing">
|
||||
Vitest setup, integration tests, type checking, CI workflow.
|
||||
<Card title="Test" icon="flask" href="/l/tr/developers/extend/apps/operations/testing">
|
||||
Vitest kurulumu, entegrasyon testleri, tür denetimi, CI iş akışı.
|
||||
</Card>
|
||||
<Card title="Publishing" icon="upload" href="/l/tr/developers/extend/apps/operations/publishing">
|
||||
Build, deploy a tarball, publish to npm, install.
|
||||
<Card title="Yayımlama" icon="yükle" href="/l/tr/developers/extend/apps/operations/publishing">
|
||||
Oluşturun, bir tarball dağıtın, npm'e yayınlayın, yükleyin.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
---
|
||||
title: Publishing
|
||||
icon: upload
|
||||
description: Distribute your Twenty app to the marketplace or deploy it internally.
|
||||
title: Yayımlama
|
||||
icon: yükle
|
||||
description: Twenty uygulamanızı pazaryerine sunun ya da dahili olarak dağıtın.
|
||||
---
|
||||
|
||||
## Overview
|
||||
## Genel Bakış
|
||||
|
||||
Once your app is [built and tested locally](/l/tr/developers/extend/apps/getting-started/concepts), you have two paths for distributing it:
|
||||
Uygulamanız [yerelde derlenip test edildikten sonra](/l/tr/developers/extend/apps/getting-started/concepts), dağıtım için iki yolunuz vardır:
|
||||
|
||||
* **Deploy a tarball** — upload your app directly to a specific Twenty server for internal or private use.
|
||||
* **Publish to npm** — list your app in the Twenty marketplace for any workspace to discover and install.
|
||||
* **Bir tar arşivi dağıtın** — uygulamanızı dahili veya özel kullanım için doğrudan belirli bir Twenty sunucusuna yükleyin.
|
||||
* **npm’ye yayımlama** — uygulamanızı Twenty pazaryerinde listeleyin; böylece herhangi bir çalışma alanı keşfedip yükleyebilir.
|
||||
|
||||
Both paths start from the same **build** step.
|
||||
Her iki yol da aynı **build** adımından başlar.
|
||||
|
||||
## Building your app
|
||||
## Uygulamanızı derleme
|
||||
|
||||
Run the build command to compile your app and generate a distribution-ready `manifest.json`:
|
||||
Uygulamanızı derlemek ve dağıtıma hazır bir `manifest.json` oluşturmak için build komutunu çalıştırın:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty build
|
||||
```
|
||||
|
||||
This compiles TypeScript sources, transpiles logic functions and front components, and writes everything to `.twenty/output/`. Add `--tarball` to also produce a `.tgz` package for manual distribution or the deploy command.
|
||||
Bu işlem TypeScript kaynaklarını derler, mantık işlevlerini ve ön uç bileşenlerini transpile eder ve her şeyi `.twenty/output/` konumuna yazar. El ile dağıtım veya deploy komutu için bir `.tgz` paketini de üretmek amacıyla `--tarball` ekleyin.
|
||||
|
||||
## Deploying to a server (tarball)
|
||||
## Sunucuya dağıtım (tarball)
|
||||
|
||||
For apps you don't want publicly available — proprietary tools, enterprise-only integrations, or experimental builds — you can deploy a tarball directly to a Twenty server.
|
||||
Genel kullanıma açık olmasını istemediğiniz uygulamalar — sahipli araçlar, yalnızca kurumsal entegrasyonlar veya deneysel derlemeler — için bir tarball’ı doğrudan bir Twenty sunucusuna dağıtabilirsiniz.
|
||||
|
||||
### Prerequisites
|
||||
### Ön Gereksinimler
|
||||
|
||||
Before deploying, you need a configured remote pointing to the target server. Remotes store the server URL and authentication credentials locally in `~/.twenty/config.json`.
|
||||
Dağıtmadan önce, hedef sunucuyu işaret eden yapılandırılmış bir remote’a ihtiyacınız vardır. Remote’lar sunucu URL’sini ve kimlik doğrulama bilgilerini yerel olarak `~/.twenty/config.json` içinde saklar.
|
||||
|
||||
Add a remote:
|
||||
Bir remote ekleyin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty remote add --api-url https://your-twenty-server.com --as production
|
||||
```
|
||||
|
||||
### Deploying
|
||||
### Dağıtım
|
||||
|
||||
Build and upload your app to the server in one step:
|
||||
Uygulamanızı tek adımda derleyip sunucuya yükleyin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty deploy
|
||||
@@ -47,39 +47,39 @@ yarn twenty deploy
|
||||
# yarn twenty deploy --remote production
|
||||
```
|
||||
|
||||
### Sharing a deployed app
|
||||
### Dağıtılmış bir uygulamayı paylaşma
|
||||
|
||||
<Warning>
|
||||
Sharing private (tarball) apps across workspaces is an **Enterprise** feature. The **Distribution** tab will show an upgrade prompt instead of the share controls until your workspace has a valid Enterprise key. See [Settings > Admin Panel > Enterprise](/settings/admin-panel#enterprise) to activate it.
|
||||
Özel (tarball) uygulamaları çalışma alanları arasında paylaşma bir **Kurumsal** özelliktir. **Dağıtım** sekmesi, çalışma alanınız geçerli bir Kurumsal anahtara sahip olana kadar paylaşım kontrolleri yerine bir yükseltme istemi gösterecektir. Etkinleştirmek için [Ayarlar > Yönetim Paneli > Kurumsal](/settings/admin-panel#enterprise) bölümüne gidin.
|
||||
</Warning>
|
||||
|
||||
Tarball apps are not listed in the public marketplace, so other workspaces on the same server won't discover them by browsing. Once your workspace is on the Enterprise plan, you can share a deployed app like this:
|
||||
Tarball uygulamaları genel pazar yerinde listelenmez; bu nedenle aynı sunucudaki diğer çalışma alanları gezinerek onları keşfedemez. Çalışma alanınız Kurumsal planda olduğunda, yayınlanmış bir uygulamayı şu şekilde paylaşabilirsiniz:
|
||||
|
||||
1. Go to **Settings > Applications > Registrations** and open your app
|
||||
2. In the **Distribution** tab, click **Copy share link**
|
||||
3. Share this link with users on other workspaces — it takes them directly to the app's install page
|
||||
1. **Ayarlar > Uygulamalar > Kayıtlar** bölümüne gidin ve uygulamanızı açın
|
||||
2. **Dağıtım** sekmesinde, **Paylaşım bağlantısını kopyala**’ya tıklayın
|
||||
3. Bu bağlantıyı diğer çalışma alanlarındaki kullanıcılarla paylaşın — onları doğrudan uygulamanın yükleme sayfasına götürür
|
||||
|
||||
The share link uses the server's base URL (without any workspace subdomain) so it works for any workspace on the server.
|
||||
Paylaşım bağlantısı, sunucunun temel URL’sini (herhangi bir çalışma alanı alt alan adı olmadan) kullanır; böylece sunucudaki herhangi bir çalışma alanı için çalışır.
|
||||
|
||||
### Version management
|
||||
### Sürüm yönetimi
|
||||
|
||||
When updating an already deployed tarball app, the server requires the `version` in `package.json` to be **strictly higher** (per [semver](https://semver.org) ordering) than the currently deployed version. Re-deploying the same version, or pushing a lower one, is rejected before the tarball is stored — you'll see a `VERSION_ALREADY_EXISTS` error from the CLI.
|
||||
Halihazırda dağıtılmış bir tarball uygulamasını güncellerken, sunucu `package.json` içindeki `version` değerinin, şu anda dağıtılmış sürümden ([semver](https://semver.org) sıralamasına göre) **kesinlikle daha yüksek** olmasını gerektirir. Aynı sürümü yeniden dağıtmak veya daha düşük bir sürümü göndermek, tarball depolanmadan önce reddedilir — CLI'de `VERSION_ALREADY_EXISTS` hatasını görürsünüz.
|
||||
|
||||
To release an update:
|
||||
Bir güncelleme yayımlamak için:
|
||||
|
||||
1. Bump the `version` field in your `package.json` (e.g. `1.2.3` → `1.2.4`, `1.3.0`, or `2.0.0`)
|
||||
2. Run `yarn twenty deploy` (or `yarn twenty deploy --remote production`)
|
||||
3. Workspaces that have the app installed will see the upgrade available in their settings
|
||||
1. `package.json` içindeki `version` alanını artırın (ör. `1.2.3` → `1.2.4`, `1.3.0` veya `2.0.0`)
|
||||
2. `yarn twenty deploy` (veya `yarn twenty deploy --remote production`) komutunu çalıştırın
|
||||
3. Uygulamayı kurmuş olan çalışma alanları, ayarlarında mevcut güncellemeyi görecektir
|
||||
|
||||
<Note>
|
||||
Pre-release tags work as expected: bumping `1.0.0-rc.1` → `1.0.0-rc.2` is allowed, and a final release like `1.0.0` is correctly recognized as higher than `1.0.0-rc.5`. The version in `package.json` must itself be a valid semver string.
|
||||
Ön sürüm etiketleri beklendiği gibi çalışır: `1.0.0-rc.1` → `1.0.0-rc.2` sürümünü artırmak mümkündür ve `1.0.0` gibi nihai bir sürüm, `1.0.0-rc.5` sürümünden daha yüksek olarak doğru şekilde tanınır. `package.json` içindeki sürümün kendisi geçerli bir semver dizesi olmalıdır.
|
||||
</Note>
|
||||
|
||||
{/* TODO: add screenshot of the Upgrade button */}
|
||||
|
||||
### Server version compatibility
|
||||
### Sunucu sürümü uyumluluğu
|
||||
|
||||
If your app uses a feature introduced in a specific Twenty server version (for example, OAuth providers added in v2.3.0), you should declare the minimum server version your app requires using the `engines.twenty` field in `package.json`:
|
||||
Uygulamanız belirli bir Twenty sunucu sürümünde sunulan bir özelliği kullanıyorsa (örneğin, v2.3.0'da eklenen OAuth sağlayıcıları), uygulamanızın gerektirdiği en düşük sunucu sürümünü `package.json` içindeki `engines.twenty` alanını kullanarak belirtmelisiniz:
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -92,83 +92,83 @@ If your app uses a feature introduced in a specific Twenty server version (for e
|
||||
}
|
||||
```
|
||||
|
||||
The value is a standard [semver range](https://github.com/npm/node-semver#ranges). Common patterns:
|
||||
Değer, standart bir [semver aralığı](https://github.com/npm/node-semver#ranges)dır. Yaygın Kalıplar:
|
||||
|
||||
| Range | Meaning |
|
||||
| ---------------------------------- | ------------------------------------------ |
|
||||
| `>=2.3.0` | Any server from 2.3.0 onward |
|
||||
| `>=2.3.0 \<3.0.0` | 2.3.0 or later, but below the next major |
|
||||
| `^2.3.0` | Same as `>=2.3.0 \<3.0.0` |
|
||||
| Aralık | Anlam |
|
||||
| ---------------------------------- | --------------------------------------------------------- |
|
||||
| `>=2.3.0` | 2.3.0'dan itibaren herhangi bir sunucu |
|
||||
| `>=2.3.0 \<3.0.0` | 2.3.0 veya sonrası, ancak bir sonraki ana sürümün altında |
|
||||
| `^2.3.0` | `>=2.3.0 \<3.0.0` ile aynı |
|
||||
|
||||
**What happens at deploy and install time:**
|
||||
**Dağıtım ve yükleme sırasında ne olur:**
|
||||
|
||||
* If `engines.twenty` is set and the target server's version does not satisfy the range, the deploy (tarball upload) or install is rejected with a `SERVER_VERSION_INCOMPATIBLE` error and a message indicating both the required range and the actual server version.
|
||||
* If `engines.twenty` is **not set**, the app is accepted on any server version (backward-compatible with existing apps).
|
||||
* If the server has no `APP_VERSION` configured, the check is skipped.
|
||||
* `engines.twenty` ayarlanmışsa ve hedef sunucunun sürümü aralığı karşılamıyorsa, dağıtım (tarball yüklemesi) veya yükleme, gerekli aralığı ve gerçek sunucu sürümünü belirten bir mesajla birlikte `SERVER_VERSION_INCOMPATIBLE` hatasıyla reddedilir.
|
||||
* `engines.twenty` **ayarlı değilse**, uygulama herhangi bir sunucu sürümünde kabul edilir (mevcut uygulamalarla geriye dönük uyumludur).
|
||||
* Sunucuda `APP_VERSION` yapılandırılmamışsa, denetim atlanır.
|
||||
|
||||
<Note>
|
||||
The server is the authoritative check — it validates `engines.twenty` on both tarball upload and workspace install. If you deploy a tarball out-of-band or install from the marketplace, the server still enforces compatibility.
|
||||
Nihai denetim sunucudadır — hem tarball yüklemesinde hem de çalışma alanı (workspace) kurulumunda `engines.twenty`'yi doğrular. Bir tarball'ı bant dışı dağıtırsanız veya marketplace'ten kurarsanız, sunucu yine de uyumluluğu zorunlu kılar.
|
||||
</Note>
|
||||
|
||||
## Automated CI/CD (scaffolded workflows)
|
||||
## Otomatik CI/CD (hazır şablonlu iş akışları)
|
||||
|
||||
Apps generated with `create-twenty-app` ship with two GitHub Actions workflows out of the box, under `.github/workflows/`. They are ready to run as soon as you push the repo to GitHub — no extra setup is needed for CI, and CD only requires a single secret.
|
||||
`create-twenty-app` ile oluşturulan uygulamalar, kutudan çıktığı gibi `.github/workflows/` altında iki GitHub Actions iş akışıyla gelir. Depoyu GitHub’a iter itmez çalışmaya hazırdır — CI için ek bir kurulum gerekmez ve CD yalnızca tek bir gizli anahtar gerektirir.
|
||||
|
||||
### CI — `ci.yml`
|
||||
|
||||
Runs integration tests on every push to `main` and every pull request.
|
||||
Entegrasyon testlerini `main` dalına yapılan her itmede ve her çekme isteğinde otomatik olarak çalıştırır.
|
||||
|
||||
**What it does:**
|
||||
**Ne yapar:**
|
||||
|
||||
1. Checks out your app's source.
|
||||
2. Spawns an isolated Twenty test instance using the `twentyhq/twenty/.github/actions/spawn-twenty-app-dev-test@main` composite action (the CI equivalent of `yarn twenty server start --test`).
|
||||
3. Enables Corepack, sets up Node.js from your `.nvmrc`, and installs dependencies with `yarn install --immutable`.
|
||||
4. Runs `yarn test`, passing `TWENTY_API_URL` and `TWENTY_API_KEY` from the spawned instance so your tests can talk to a real server.
|
||||
1. Uygulamanızın kaynak kodunu alır.
|
||||
2. `twentyhq/twenty/.github/actions/spawn-twenty-app-dev-test@main` bileşik eylemini kullanarak yalıtılmış bir Twenty test örneği başlatır (CI'daki `yarn twenty server start --test` eşdeğeri).
|
||||
3. Corepack’i etkinleştirir, `.nvmrc` dosyanızdan Node.js'i kurar ve bağımlılıkları `yarn install --immutable` ile yükler.
|
||||
4. Oluşturulan örnekten `TWENTY_API_URL` ve `TWENTY_API_KEY` değerlerini aktararak `yarn test`i çalıştırır; böylece testleriniz gerçek bir sunucuyla haberleşebilir.
|
||||
|
||||
**Config knobs:**
|
||||
**Yapılandırma seçenekleri:**
|
||||
|
||||
* `TWENTY_VERSION` (env, defaults to `latest`) — pin the Twenty server version used in CI by editing this in `ci.yml`.
|
||||
* Concurrency is grouped by `github.ref` and cancels in-progress runs on new pushes.
|
||||
* `TWENTY_VERSION` (ortam, varsayılanı `latest`) — CI’da kullanılan Twenty sunucu sürümünü `ci.yml` içinde bunu düzenleyerek sabitleyin.
|
||||
* Eşzamanlılık `github.ref` bazında gruplanır ve yeni itmelerde devam eden çalışmaları iptal eder.
|
||||
|
||||
No secrets are required — the test instance is ephemeral and lives only for the duration of the job.
|
||||
Gizli anahtar gerekmez — test örneği geçicidir ve yalnızca iş süresi boyunca çalışır.
|
||||
|
||||
### CD — `cd.yml`
|
||||
|
||||
Deploys your app to a configured Twenty server on every push to `main`, and optionally from a pull request when the `deploy` label is applied.
|
||||
`main` dalına yapılan her itmede uygulamanızı yapılandırılmış bir Twenty sunucusuna dağıtır ve isteğe bağlı olarak `deploy` etiketi uygulandığında bir çekme isteğinden de dağıtım yapar.
|
||||
|
||||
**What it does:**
|
||||
**Ne yapar:**
|
||||
|
||||
1. Checks out the PR head (for labeled PRs) or the pushed commit.
|
||||
2. Runs `twentyhq/twenty/.github/actions/deploy-twenty-app@main` — the CI equivalent of `yarn twenty deploy`.
|
||||
3. Runs `twentyhq/twenty/.github/actions/install-twenty-app@main` so the newly deployed version is installed into the target workspace.
|
||||
1. Etiketli PR'ler için PR'in head commit'ini ya da itilen commit'i alır.
|
||||
2. `twentyhq/twenty/.github/actions/deploy-twenty-app@main` çalıştırır — `yarn twenty deploy` komutunun CI eşdeğeridir.
|
||||
3. `twentyhq/twenty/.github/actions/install-twenty-app@main` eylemini çalıştırır; böylece yeni dağıtılan sürüm hedef çalışma alanına kurulur.
|
||||
|
||||
**Required configuration:**
|
||||
**Gerekli yapılandırma:**
|
||||
|
||||
| Setting | Where | Purpose |
|
||||
| ----------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
||||
| `TWENTY_DEPLOY_URL` | `env` in `cd.yml` (defaults to `http://localhost:3000`) | The Twenty server to deploy to. Change this to your real server URL before first use. |
|
||||
| `TWENTY_DEPLOY_API_KEY` | GitHub repo **Settings → Secrets and variables → Actions** | API key with deploy permission on the target server. |
|
||||
| Ayar | Koşul | Amaç |
|
||||
| ----------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------- |
|
||||
| `TWENTY_DEPLOY_URL` | `cd.yml` içinde `env` (varsayılan: `http://localhost:3000`) | Dağıtımın yapılacağı Twenty sunucusu. İlk kullanımdan önce bunu gerçek sunucu URL'nizle değiştirin. |
|
||||
| `TWENTY_DEPLOY_API_KEY` | GitHub deposu **Settings → Secrets and variables → Actions** | Hedef sunucuda dağıtım iznine sahip API anahtarı. |
|
||||
|
||||
<Note>
|
||||
The default `TWENTY_DEPLOY_URL` of `http://localhost:3000` is a placeholder — it will not reach anything from a GitHub-hosted runner. Update it to your server's public URL (or use a self-hosted runner with network access) before enabling CD.
|
||||
Varsayılan `TWENTY_DEPLOY_URL` olan `http://localhost:3000` bir yer tutucudur — GitHub barındırmalı bir çalıştırıcıdan hiçbir yere erişemez. CD'yi etkinleştirmeden önce bunu sunucunuzun genel URL'siyle güncelleyin (veya ağ erişimi olan öz barındırılan bir çalıştırıcı kullanın).
|
||||
</Note>
|
||||
|
||||
**Triggering a preview deploy from a PR:**
|
||||
**Bir PR'den bir önizleme dağıtımını tetikleme:**
|
||||
|
||||
Add the `deploy` label to a pull request. The `if:` guard in `cd.yml` will run the job for that PR using the PR's head commit, letting you validate a change on the target server before merging.
|
||||
Bir çekme isteğine `deploy` etiketini ekleyin. `cd.yml` içindeki `if:` koruması, ilgili PR için işi PR'in head commit'ini kullanarak çalıştırır; böylece birleştirmeden önce hedef sunucuda değişikliği doğrulayabilirsiniz.
|
||||
|
||||
### Pinning the reusable actions
|
||||
### Yeniden kullanılabilir eylemleri sabitleme
|
||||
|
||||
Both workflows reference reusable actions at `@main`, so action updates in the `twentyhq/twenty` repo are picked up automatically. If you want deterministic builds, replace `@main` with a commit SHA or release tag on each `uses:` line.
|
||||
Her iki iş akışı da `@main` üzerindeki yeniden kullanılabilir eylemlere başvurur; bu nedenle `twentyhq/twenty` deposundaki eylem güncellemeleri otomatik olarak alınır. Deterministik derlemeler istiyorsanız, her `uses:` satırında `@main` ifadesini bir commit SHA'sı veya sürüm etiketiyle değiştirin.
|
||||
|
||||
## Publishing to npm
|
||||
## npm’ye yayımlama
|
||||
|
||||
Publishing to npm makes your app discoverable in the Twenty marketplace. Any Twenty workspace can browse, install, and upgrade marketplace apps directly from the UI.
|
||||
npm’ye yayımlamak, uygulamanızın Twenty pazaryerinde keşfedilebilir olmasını sağlar. Herhangi bir Twenty çalışma alanı, pazaryeri uygulamalarına doğrudan arayüzden göz atabilir, yükleyebilir ve güncelleyebilir.
|
||||
|
||||
### Requirements
|
||||
### Gereksinimler
|
||||
|
||||
* An [npm](https://www.npmjs.com) account
|
||||
* The `twenty-app` keyword in your `package.json` `keywords` array (add it manually — it is not included by default in the `create-twenty-app` template)
|
||||
* Bir [npm](https://www.npmjs.com) hesabı
|
||||
* `package.json` içindeki `keywords` dizinizdeki `twenty-app` anahtar sözcüğü (elle ekleyin — varsayılan olarak `create-twenty-app` şablonunda yer almaz)
|
||||
|
||||
```json filename="package.json"
|
||||
{
|
||||
@@ -178,9 +178,9 @@ Publishing to npm makes your app discoverable in the Twenty marketplace. Any Twe
|
||||
}
|
||||
```
|
||||
|
||||
### Marketplace metadata
|
||||
### Pazaryeri meta verileri
|
||||
|
||||
The `defineApplication()` config supports optional fields that control how your app appears in the marketplace. Use `logoUrl` and `screenshots` to reference images from the `public/` folder:
|
||||
`defineApplication()` yapılandırması, uygulamanızın pazar yerinde nasıl görüneceğini kontrol eden isteğe bağlı alanları destekler. `public/` klasöründeki görsellere başvurmak için `logoUrl` ve `screenshots` kullanın:
|
||||
|
||||
```ts src/application-config.ts
|
||||
export default defineApplication({
|
||||
@@ -196,33 +196,33 @@ export default defineApplication({
|
||||
});
|
||||
```
|
||||
|
||||
See the [defineApplication accordion](/l/tr/developers/extend/apps/config/application#marketplace-metadata) in the Building Apps page for the full list of marketplace fields (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, etc.).
|
||||
Pazar yeri alanlarının tam listesi için Uygulama Oluşturma sayfasındaki [defineApplication akordeonu](/l/tr/developers/extend/apps/config/application#marketplace-metadata)'na bakın (`author`, `category`, `aboutDescription`, `websiteUrl`, `termsUrl`, vb.).
|
||||
|
||||
#### Recommended screenshot dimensions
|
||||
#### Önerilen ekran görüntüsü boyutları
|
||||
|
||||
The marketplace renders `screenshots` in a fixed `8:5` container (for example, `1600×1000 px`).
|
||||
Marketplace, `screenshots`'ı sabit `8:5` oranlı bir kapsayıcıda görüntüler (örneğin, `1600×1000 px`).
|
||||
|
||||
<Note>
|
||||
Screenshots of any aspect ratio are displayed in full and are never cropped, but anything significantly taller or narrower than `8:5` will show empty bands on the sides.
|
||||
Herhangi bir en-boy oranındaki ekran görüntüleri eksiksiz görüntülenir ve asla kırpılmaz, ancak `8:5`'ten belirgin ölçüde daha uzun veya daha dar olanlarda yanlarda boş bantlar görünür.
|
||||
</Note>
|
||||
|
||||
### Publish
|
||||
### Yayımla
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish
|
||||
```
|
||||
|
||||
To publish under a specific dist-tag (e.g., `beta` or `next`):
|
||||
Belirli bir dist-tag altında yayımlamak için (ör. `beta` veya `next`):
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty publish --tag beta
|
||||
```
|
||||
|
||||
### How marketplace discovery works
|
||||
### Pazar yerinde keşif nasıl çalışır
|
||||
|
||||
The Twenty server syncs its marketplace catalog from the npm registry **every hour**.
|
||||
Twenty sunucusu pazar yeri kataloğunu npm kayıt defterinden **her saat** eşitler.
|
||||
|
||||
You can trigger the sync immediately instead of waiting:
|
||||
Beklemek yerine eşitlemeyi hemen tetikleyebilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty server catalog-sync
|
||||
@@ -230,15 +230,15 @@ yarn twenty server catalog-sync
|
||||
# yarn twenty server catalog-sync --remote production
|
||||
```
|
||||
|
||||
The metadata shown in the marketplace comes from your `defineApplication()` config — fields like `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl`, and `termsUrl`.
|
||||
Pazar yerinde gösterilen meta veriler, `defineApplication()` yapılandırmanızdan gelir — `displayName`, `description`, `author`, `category`, `logoUrl`, `screenshots`, `aboutDescription`, `websiteUrl` ve `termsUrl` gibi alanlar.
|
||||
|
||||
<Note>
|
||||
If your app does not define an `aboutDescription` in `defineApplication()`, the marketplace will automatically use your package's `README.md` from npm as the about page content. This means you can maintain a single README for both npm and the Twenty marketplace. If you want a different description in the marketplace, explicitly set `aboutDescription`.
|
||||
Uygulamanız `defineApplication()` içinde bir `aboutDescription` tanımlamıyorsa, pazaryeri, hakkında sayfasının içeriği olarak paketinizin npm'deki `README.md` dosyasını otomatik olarak kullanır. Bu, hem npm hem de Twenty pazaryeri için tek bir README dosyası kullanabileceğiniz anlamına gelir. Pazaryerinde farklı bir açıklama istiyorsanız, `aboutDescription` değerini açıkça ayarlayın.
|
||||
</Note>
|
||||
|
||||
### CI publishing
|
||||
### CI üzerinden yayımlama
|
||||
|
||||
Use this GitHub Actions workflow to publish automatically on every release (uses [OIDC](https://docs.npmjs.com/trusted-publishers)):
|
||||
Her sürümde otomatik olarak yayımlamak için bu GitHub Actions iş akışını kullanın ([OIDC](https://docs.npmjs.com/trusted-publishers) kullanır):
|
||||
|
||||
```yaml filename=".github/workflows/publish.yml"
|
||||
name: Publish
|
||||
@@ -265,31 +265,31 @@ jobs:
|
||||
working-directory: .twenty/output
|
||||
```
|
||||
|
||||
For other CI systems (GitLab CI, CircleCI, etc.), the same three commands apply: `yarn install`, `yarn twenty build`, then `npm publish` from `.twenty/output`.
|
||||
Diğer CI sistemleri (GitLab CI, CircleCI, vb.) için de aynı üç komut geçerlidir: `yarn install`, `yarn twenty build` ve ardından `.twenty/output` dizininden `npm publish`.
|
||||
|
||||
<Note>
|
||||
**npm provenance** is optional but recommended. Publishing with `--provenance` adds a trust badge to your npm listing, letting users verify the package was built from a specific commit in a public CI pipeline. See the [npm provenance docs](https://docs.npmjs.com/generating-provenance-statements) for setup instructions.
|
||||
**npm provenance** isteğe bağlıdır ancak önerilir. `--provenance` ile yayımlamak, npm listenize bir güven rozeti ekler ve kullanıcıların paketin herkese açık bir CI ardışık düzenindeki belirli bir commit’ten oluşturulduğunu doğrulamasını sağlar. Kurulum talimatları için [npm provenance belgelerine](https://docs.npmjs.com/generating-provenance-statements) bakın.
|
||||
</Note>
|
||||
|
||||
## Installing apps
|
||||
## Uygulamaları yükleme
|
||||
|
||||
Once an app is published (npm) or deployed (tarball), workspaces can install it through the UI.
|
||||
Bir uygulama yayımlandığında (npm) veya dağıtıldığında (tarball), çalışma alanları onu kullanıcı arayüzü (UI) üzerinden yükleyebilir.
|
||||
|
||||
Go to the **Settings > Applications** page in Twenty, where both marketplace and tarball-deployed apps can be browsed and installed.
|
||||
Twenty içinde **Ayarlar > Uygulamalar** sayfasına gidin; burada hem pazar yerindeki hem de tarball ile dağıtılmış uygulamalar görüntülenip yüklenebilir.
|
||||
|
||||
{/* TODO: add screenshot of the UI when the app is registered */}
|
||||
|
||||
You can also install apps from the command line:
|
||||
Uygulamaları komut satırından da yükleyebilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty install
|
||||
```
|
||||
|
||||
<Note>
|
||||
The server enforces semver versioning on install, mirroring the rules on deploy:
|
||||
Sunucu, kurulum sırasında semver sürümlemesini zorunlu kılar ve dağıtımdaki kuralları yansıtır:
|
||||
|
||||
* Installing the same version that is already installed in your workspace is rejected with an `APP_ALREADY_INSTALLED` error.
|
||||
* Installing a lower version than the one currently installed is rejected with a `CANNOT_DOWNGRADE_APPLICATION` error.
|
||||
* Çalışma alanınızda zaten yüklü olanla aynı sürümün kurulumu, `APP_ALREADY_INSTALLED` hatasıyla reddedilir.
|
||||
* Halihazırda yüklü olandan daha düşük bir sürümü kurmak, `CANNOT_DOWNGRADE_APPLICATION` hatasıyla reddedilir.
|
||||
|
||||
To install a newer version, deploy or publish it first, then re-run `yarn twenty install`.
|
||||
Daha yeni bir sürümü kurmak için önce onu dağıtın veya yayımlayın, ardından `yarn twenty install` komutunu yeniden çalıştırın.
|
||||
</Note>
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
---
|
||||
title: Testing
|
||||
description: Vitest setup, integration tests against a real Twenty server, type checking, and CI with GitHub Actions.
|
||||
title: Test
|
||||
description: Vitest kurulumu, gerçek bir Twenty sunucusuna karşı tümleştirme testleri, tür denetimi ve GitHub Actions ile CI.
|
||||
icon: flask
|
||||
---
|
||||
|
||||
The SDK provides programmatic APIs that let you build, deploy, install, and uninstall your app from test code. Combined with [Vitest](https://vitest.dev/) and the typed API clients, you can write integration tests that verify your app works end-to-end against a real Twenty server.
|
||||
SDK, test kodundan uygulamanızı derlemenize, dağıtmanıza, yüklemenize ve kaldırmanıza olanak tanıyan programatik API'ler sağlar. Tiplenmiş API istemcileriyle birlikte [Vitest](https://vitest.dev/) kullanarak, uygulamanızın gerçek bir Twenty sunucusunda uçtan uca çalıştığını doğrulayan entegrasyon testleri yazabilirsiniz.
|
||||
|
||||
## Using npm packages
|
||||
## npm paketlerini kullanma
|
||||
|
||||
You can install and use any npm package in your app. Both logic functions and front components are bundled with [esbuild](https://esbuild.github.io/), which inlines all dependencies into the output — no `node_modules` are needed at runtime.
|
||||
Uygulamanızda herhangi bir npm paketini yükleyip kullanabilirsiniz. Hem mantık işlevleri hem de ön uç bileşenleri, tüm bağımlılıkları çıktıya satır içi olarak ekleyen [esbuild](https://esbuild.github.io/) ile paketlenir — çalışma zamanında `node_modules` gerekmez.
|
||||
|
||||
### Installing a package
|
||||
### Bir paketi yükleme
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add axios
|
||||
```
|
||||
|
||||
Then import it in your code:
|
||||
Ardından kodunuza içe aktarın:
|
||||
|
||||
```ts src/logic-functions/fetch-data.ts
|
||||
import { defineLogicFunction } from 'twenty-sdk/define';
|
||||
@@ -37,7 +37,7 @@ export default defineLogicFunction({
|
||||
});
|
||||
```
|
||||
|
||||
The same works for front components:
|
||||
Aynısı ön uç bileşenleri için de geçerlidir:
|
||||
|
||||
```tsx src/front-components/chart.tsx
|
||||
import { defineFrontComponent } from 'twenty-sdk/define';
|
||||
@@ -54,25 +54,25 @@ export default defineFrontComponent({
|
||||
});
|
||||
```
|
||||
|
||||
### How bundling works
|
||||
### Paketleme nasıl çalışır
|
||||
|
||||
The build step uses esbuild to produce a single self-contained file per logic function and per front component. All imported packages are inlined into the bundle.
|
||||
Derleme adımı, her mantık işlevi ve her ön uç bileşeni için tek bir bağımsız dosya üretmek üzere esbuild kullanır. Tüm içe aktarılan paketler pakete satır içi eklenir.
|
||||
|
||||
**Logic functions** run in a Node.js environment. Node built-in modules (`fs`, `path`, `crypto`, `http`, etc.) are available and do not need to be installed.
|
||||
**Mantık işlevleri**, Node.js ortamında çalışır. Node yerleşik modülleri (`fs`, `path`, `crypto`, `http` vb.) kullanılabilir ve kurulmaları gerekmez.
|
||||
|
||||
**Front components** run in a Web Worker. Node built-in modules are **not** available — only browser APIs and npm packages that work in a browser environment.
|
||||
**Ön uç bileşenleri**, bir Web Worker içinde çalışır. Node'un yerleşik modülleri **kullanılamaz** — yalnızca tarayıcı ortamında çalışan tarayıcı API'leri ve npm paketleri kullanılabilir.
|
||||
|
||||
Both environments have `twenty-client-sdk/core` and `twenty-client-sdk/metadata` available as pre-provided modules — these are not bundled but resolved at runtime by the server.
|
||||
Her iki ortamda da `twenty-client-sdk/core` ve `twenty-client-sdk/metadata` önceden sağlanmış modüller olarak mevcuttur — bunlar paketlenmez, ancak çalışma zamanında sunucu tarafından çözülür.
|
||||
|
||||
## Setup
|
||||
## Kurulum
|
||||
|
||||
The scaffolded app already includes Vitest. If you set it up manually, install the dependencies:
|
||||
İskelet aracıyla oluşturulan uygulama zaten Vitest'i içerir. Manuel kurulum yaparsanız, bağımlılıkları yükleyin:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn add -D vitest vite-tsconfig-paths
|
||||
```
|
||||
|
||||
Create a `vitest.config.ts` at the root of your app:
|
||||
Uygulamanızın kök dizininde bir `vitest.config.ts` oluşturun:
|
||||
|
||||
```ts vitest.config.ts
|
||||
import tsconfigPaths from 'vite-tsconfig-paths';
|
||||
@@ -98,7 +98,7 @@ export default defineConfig({
|
||||
});
|
||||
```
|
||||
|
||||
Create a setup file that verifies the server is reachable before tests run:
|
||||
Testler çalışmadan önce sunucuya erişilebildiğini doğrulayan bir kurulum dosyası oluşturun:
|
||||
|
||||
```ts src/__tests__/setup-test.ts
|
||||
import * as fs from 'fs';
|
||||
@@ -138,22 +138,22 @@ beforeAll(async () => {
|
||||
});
|
||||
```
|
||||
|
||||
## Programmatic SDK APIs
|
||||
## Programatik SDK API'leri
|
||||
|
||||
The `twenty-sdk/cli` subpath exports functions you can call directly from test code:
|
||||
`twenty-sdk/cli` alt yolu, test kodundan doğrudan çağırabileceğiniz fonksiyonları dışa aktarır:
|
||||
|
||||
| Function | Description |
|
||||
| -------------- | ------------------------------------------- |
|
||||
| `appBuild` | Build the app and optionally pack a tarball |
|
||||
| `appDeploy` | Upload a tarball to the server |
|
||||
| `appInstall` | Install the app on the active workspace |
|
||||
| `appUninstall` | Uninstall the app from the active workspace |
|
||||
| Fonksiyon | Açıklama |
|
||||
| -------------- | ----------------------------------------------------------------- |
|
||||
| `appBuild` | Uygulamayı derleyin ve isteğe bağlı olarak bir tarball paketleyin |
|
||||
| `appDeploy` | Bir tarball'ı sunucuya yükleyin |
|
||||
| `appInstall` | Uygulamayı etkin çalışma alanına yükleyin |
|
||||
| `appUninstall` | Uygulamayı etkin çalışma alanından kaldırın |
|
||||
|
||||
Each function returns a result object with `success: boolean` and either `data` or `error`.
|
||||
Her fonksiyon, `success: boolean` ile birlikte `data` veya `error` içeren bir sonuç nesnesi döndürür.
|
||||
|
||||
## Writing an integration test
|
||||
## Bir entegrasyon testi yazma
|
||||
|
||||
Here is a full example that builds, deploys, and installs the app, then verifies it appears in the workspace:
|
||||
İşte uygulamayı derleyen, dağıtan ve yükleyen; ardından çalışma alanında göründüğünü doğrulayan tam bir örnek:
|
||||
|
||||
```ts src/__tests__/app-install.integration-test.ts
|
||||
import { APPLICATION_UNIVERSAL_IDENTIFIER } from 'src/application-config';
|
||||
@@ -216,40 +216,40 @@ describe('App installation', () => {
|
||||
});
|
||||
```
|
||||
|
||||
## Running tests
|
||||
## Testleri çalıştırma
|
||||
|
||||
Make sure your local Twenty server is running, then:
|
||||
Yerel Twenty sunucunuzun çalıştığından emin olun, ardından:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn test
|
||||
```
|
||||
|
||||
Or in watch mode during development:
|
||||
Veya geliştirme sırasında izleme modunda:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn test:watch
|
||||
```
|
||||
|
||||
## Type checking
|
||||
## Tip denetimi
|
||||
|
||||
You can also run type checking on your app without running tests:
|
||||
Ayrıca testleri çalıştırmadan uygulamanızda tip denetimi çalıştırabilirsiniz:
|
||||
|
||||
```bash filename="Terminal"
|
||||
yarn twenty typecheck
|
||||
```
|
||||
|
||||
This runs `tsc --noEmit` and reports any type errors.
|
||||
Bu, `tsc --noEmit` komutunu çalıştırır ve tüm tip hatalarını raporlar.
|
||||
|
||||
## CI with GitHub Actions
|
||||
## GitHub Actions ile CI
|
||||
|
||||
The scaffolder generates a ready-to-use GitHub Actions workflow at `.github/workflows/ci.yml`. It runs your integration tests automatically on every push to `main` and on pull requests.
|
||||
İskelet oluşturucu, `.github/workflows/ci.yml` konumunda kullanıma hazır bir GitHub Actions iş akışı üretir. Entegrasyon testlerinizi `main` dalına yapılan her itmede ve çekme isteklerinde otomatik olarak çalıştırır.
|
||||
|
||||
The workflow:
|
||||
İş akışı:
|
||||
|
||||
1. Checks out your code
|
||||
2. Spins up a temporary Twenty server using the `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` action
|
||||
3. Installs dependencies with `yarn install --immutable`
|
||||
4. Runs `yarn test` with `TWENTY_API_URL` and `TWENTY_API_KEY` injected from the action outputs
|
||||
1. Kodunuzu çalışma alanına alır
|
||||
2. `twentyhq/twenty/.github/actions/spawn-twenty-docker-image` eylemini kullanarak geçici bir Twenty sunucusu başlatır
|
||||
3. `yarn install --immutable` ile bağımlılıkları kurar
|
||||
4. Eylem çıktılarından enjekte edilen `TWENTY_API_URL` ve `TWENTY_API_KEY` ile `yarn test` çalıştırır
|
||||
|
||||
```yaml .github/workflows/ci.yml
|
||||
name: CI
|
||||
@@ -296,6 +296,6 @@ jobs:
|
||||
TWENTY_API_KEY: ${{ steps.twenty.outputs.access-token }}
|
||||
```
|
||||
|
||||
You don't need to configure any secrets — the `spawn-twenty-docker-image` action starts an ephemeral Twenty server directly in the runner and outputs the connection details. The `GITHUB_TOKEN` secret is provided automatically by GitHub.
|
||||
Herhangi bir gizli değişken yapılandırmanız gerekmez — `spawn-twenty-docker-image` eylemi, koşucu içinde doğrudan geçici bir Twenty sunucusu başlatır ve bağlantı ayrıntılarını çıktı olarak verir. `GITHUB_TOKEN` gizli değişkeni GitHub tarafından otomatik olarak sağlanır.
|
||||
|
||||
To pin a specific Twenty version instead of `latest`, change the `TWENTY_VERSION` environment variable at the top of the workflow.
|
||||
`latest` yerine belirli bir Twenty sürümünü sabitlemek için iş akışının başındaki `TWENTY_VERSION` ortam değişkenini değiştirin.
|
||||
|
||||
Reference in New Issue
Block a user