snapshot of https://github.com/twentyhq/twenty.git (main, 2026-09-17; blobs > 131072B omitted)
Some checks failed
App Prod-Parity E2E Dispatch / dispatch (push) Failing after 10s
CD Storybook UI / build (push) Failing after 3m25s
CD Storybook UI / dispatch (push) Has been skipped
CD deploy main / website-changed-files (push) Successful in 18m8s
CI Agent Skills / changed-files-check (push) Successful in 18m9s
CI Create App E2E minimal / changed-files-check (push) Successful in 24s
CI Create App / changed-files-check (push) Successful in 26s
CI Docs / changed-files-check (push) Successful in 26s
CI Emails / changed-files-check (push) Successful in 28s
CI Example App Hello World / changed-files-check (push) Successful in 23s
CI Front / changed-files-check (push) Has been skipped
CI Example App Postcard / changed-files-check (push) Successful in 27s
CI UI / changed-files-check (push) Has been skipped
CI Utils Test / changed-files-check (push) Successful in 45s
CI Twenty Apps / discover (push) Successful in 1m3s
CD deploy main / deploy-main (push) Failing after 3s
CI Agent Skills / agent-skills-validate (push) Has been skipped
CI Create App / create-app-test (lint) (push) Has been skipped
CI Emails / emails-test (push) Has been skipped
CI Front / front-task (lingui:compile) (push) Has been skipped
CI Front / front-task (lint) (push) Has been skipped
CI Example App Postcard / example-app-postcard (push) Has been skipped
CI UI / ui-task (lint) (push) Has been skipped
CI UI / ui-task (pack-size) (push) Has been skipped
CI UI / ui-task (size) (push) Has been skipped
CI UI / ui-task (test) (push) Has been skipped
CI UI / ui-task (typecheck) (push) Has been skipped
CI Utils Test / utils-test (push) Has been skipped
CI Twenty Apps / ${{ matrix.app.name }} (push) Has been skipped
CI Emails / ci-emails-status-check (push) Successful in 2s
CI Example App Hello World / ci-example-app-hello-world-status-check (push) Successful in 2s
CI Example App Postcard / ci-example-app-postcard-status-check (push) Successful in 3s
CI UI / ui-sb-test (push) Has been skipped
CI Utils Test / ci-utils-test-status-check (push) Successful in 2s
CI Twenty Apps / ci-twenty-apps-status-check (push) Successful in 2s
CI UI / ci-ui-status-check (push) Successful in 2s
CI Desktop / desktop (push) Failing after 1m8s
Push docs to Crowdin / Push documentation to Crowdin (push) Failing after 55s
Push translations to Crowdin / Extract and upload translations (push) Failing after 5s
Push website translations to Crowdin / Extract and upload website translations (push) Failing after 5s
CI Create App / create-app-test (test) (push) Has been skipped
CI Create App / create-app-test (typecheck) (push) Has been skipped
CI Docs / docs-lint (push) Has been skipped
CI Example App Hello World / example-app-hello-world (push) Has been skipped
CI Front / front-task (lingui:extract) (push) Has been skipped
CI Front / front-task (test) (push) Has been skipped
CI Front / front-task (typecheck) (push) Has been skipped
CI UI / ui-sb-build (push) Failing after 1m32s
CI Twenty Apps / ${{ matrix.app.name }} (${{ matrix.server-source }}) (push) Has been skipped
CI Agent Skills / agent-skills-publish (push) Has been skipped
CI Create App / ci-create-app-status-check (push) Successful in 2s
CI Agent Skills / agent-skills-remote-source (push) Has been skipped
CI Create App E2E minimal / create-app-e2e-minimal (push) Has been cancelled
CI E2E Main / e2e-test (push) Has been cancelled
CI Front / front-sb-build (push) Has been cancelled
CI Front / front-build (push) Has been cancelled
CI Create App E2E minimal / ci-create-app-e2e-minimal-status-check (push) Has been cancelled
CI E2E Main / ci-e2e-main-status-check (push) Has been cancelled
CI E2E Main / notify-main-ci-failure (push) Has been cancelled
CI E2E Main / qa-scout-comment (push) Has been cancelled
CI Front / front-sb-test (push) Has been cancelled
CI Front / front-sb-screenshots (push) Has been cancelled
CI Front / ci-front-status-check (push) Has been cancelled
DPA Sub-Processor Sync / sync-subprocessors (push) Failing after 3s
AI Catalog Sync / sync-catalog (push) Failing after 2s

This commit is contained in:
upstream-mirror
2026-09-17 23:28:13 +05:00
commit e7da97194a
32688 changed files with 4208681 additions and 0 deletions

View File

@@ -0,0 +1,131 @@
---
title: CLI
description: Fonksiyonları çalıştırmak, günlükleri akış olarak izlemek, uygulama kurulumlarını yönetmek ve uzaklar arasında geçiş yapmak için yarn twenty komutları.
icon: terminal
---
`yarn twenty` CLI, uygulama ile ilgili her şey için arayüzünüzdür. Tam komut listesi:
| Komut | Ne yapar | Şurada belgelenmiştir |
| ----------------------------------------------- | ------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `dev` | Kaynak dosyaları izleyin ve değişiklikleri gerçek zamanlı olarak eşitleyin | [Hızlı Başlangıç](/l/tr/developers/extend/apps/getting-started/quick-start) |
| `plan` | Meta veri değişikliklerini uygulamadan önizleyin | [Senkronizasyon ve kurtarma](/l/tr/developers/extend/apps/operations/sync-and-recovery#previewing-changes-plan) |
| `apply` | Planı gösterdikten sonra meta veri değişikliklerini uygulayın | [Senkronizasyon ve kurtarma](/l/tr/developers/extend/apps/operations/sync-and-recovery) |
| `dev:build` | Uygulamayı derleyin ve API istemcisini oluşturun (`.tgz` paketlemek için `--tarball`) | [Yayınlama](/l/tr/developers/extend/apps/operations/publishing) |
| `dev:typecheck` | TypeScript tür kontrolünü çalıştırın | [Testing](/l/tr/developers/extend/apps/operations/testing) |
| `dev:add` | Yeni bir varlık iskeleti oluşturun | [İskele oluşturma](/l/tr/developers/extend/apps/getting-started/scaffolding) |
| `dev:generate-client` | Türlendirilmiş API istemcisini yeniden oluşturun | bu sayfa |
| `dev:function:exec` / `dev:function:logs` | Fonksiyonları çalıştırın ve günlüklerini akış halinde alın | bu sayfa |
| `dev:translations-extract` | Çevrilebilir dizeleri `locales/` kataloglarına çıkarın | [Çeviriler](/l/tr/developers/extend/apps/operations/translations) |
| `dev:catalog-sync` | Pazar yeri katalog eşitlemesini tetikleyin | [Yayınlama](/l/tr/developers/extend/apps/operations/publishing#how-marketplace-discovery-works) |
| `app:publish` / `app:install` / `app:uninstall` | Sürüm yaşam döngüsü | [Yayınlama](/l/tr/developers/extend/apps/operations/publishing) ve bu sayfa |
| `docker:*` | Yerel Twenty sunucu konteynerini yönetin | [Yerel Sunucu](/l/tr/developers/extend/apps/getting-started/local-server) |
| `remote:*` | Sunucu bağlantılarını yönetin | bu sayfa |
Her komut, varsayılan yerine belirli bir uzak sunucuyu hedeflemek için `-r, --remote \<name>` parametresini kabul eder.
## Fonksiyonları çalıştırma (`yarn twenty dev:function:exec`)
Bir mantık fonksiyonunu HTTP, cron veya veritabanı olayıyla tetiklemeden manuel olarak çalıştırın:
```bash filename="Terminal"
# Execute by function name
yarn twenty dev:function:exec -n create-new-post-card
# Execute by universalIdentifier
yarn twenty dev:function:exec -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
# Pass a JSON payload
yarn twenty dev:function:exec -n create-new-post-card -p '{"name": "Hello"}'
# Execute the install and uninstall hooks
yarn twenty dev:function:exec --postInstall
yarn twenty dev:function:exec --preInstall
yarn twenty dev:function:exec --uninstall
```
## Fonksiyon günlüklerini görüntüleme (`yarn twenty dev:function:logs`)
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
yarn twenty dev:function:logs
# Filter by function name
yarn twenty dev:function:logs -n create-new-post-card
# Filter by universalIdentifier
yarn twenty dev:function:logs -u e56d363b-0bdc-4d8a-a393-6f0d1c75bdcf
```
<Note>
Bu, Docker konteyner günlüklerini gösteren `yarn twenty docker:logs` komutundan farklıdır. `yarn twenty dev:function:logs`, uygulamanızın fonksiyon yürütme günlüklerini Twenty sunucusundan gösterir.
</Note>
## Tiplendirilmiş istemciyi oluşturma (`yarn twenty dev:generate-client`)
Bir uygulamayı oluşturup eşitlemeden, etkin uzak sunucunun şemasından tiplendirilmiş API istemcisini (`twenty-client-sdk`) yeniden oluşturun. Bunu, Twenty örneğinizle iletişim kuran — örneğin ayrı bir depoda bulunan bir arka uç hizmeti — herhangi bir projede tiplendirilmiş bir istemci edinmek için kullanın:
```bash filename="Terminal"
# In your project (no Twenty app definition required)
yarn add twenty-sdk twenty-client-sdk
# Connect to the Twenty instance to generate the client from
yarn twenty remote:add
# Generate the typed client into node_modules/twenty-client-sdk
yarn twenty dev:generate-client
```
Ardından istemciyi kodunuza içe aktarın:
```typescript
import { CoreApiClient } from 'twenty-client-sdk/core';
```
Oluşturulan türleri yenilemek için veri modeliniz her değiştiğinde komutu yeniden çalıştırın.
<Note>
İstemci `node_modules` içinde oluşturulur, bu nedenle kodunuzla birlikte commit edilmez. Her kurulumdan sonra (örneğin bir `postinstall` betiğinde veya CI içinde) `yarn twenty dev:generate-client` komutunu çalıştırın.
</Note>
## Bir uygulamayı kaldırma (`yarn twenty app:uninstall`)
Uygulamanızı etkin çalışma alanından kaldırın:
```bash filename="Terminal"
yarn twenty app:uninstall
# Skip the confirmation prompt
yarn twenty app:uninstall --yes
```
## Uzakları yönetme
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)
yarn twenty remote:add
# Connect to a local Twenty server (auto-detects port 2020 or 3000)
yarn twenty remote:add --local
# Add a remote non-interactively (useful for CI)
yarn twenty remote:add --url https://your-twenty-server.com --api-key $TWENTY_API_KEY --as my-remote
# List all configured remotes
yarn twenty remote:list
# Set the active remote
yarn twenty remote:use <name>
# Check that the active remote's authentication is still valid
yarn twenty remote:status
# Remove a remote
yarn twenty remote:remove <name>
```
Kimlik bilgileriniz `~/.twenty/config.json` içinde saklanır.

View File

@@ -0,0 +1,32 @@
---
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
---
**Operasyon katmanı**, uygulamayı *kullanarak* yaptıklarınızdan ziyade, uygulamanız *üzerinde* yaptığınız her şeyi kapsar: CLI komutlarını çağırmak, gerçek bir Twenty sunucusunda entegrasyon testleri çalıştırmak, CI'yi yapılandırmak ve sürümleri yayımlamak — tek bir sunucuya dağıtılan bir tarball olarak ya da pazaryerinde listelenen bir npm paketi olarak.
```text
develop ─▶ test ─▶ build ─▶ deploy / publish
─────── ──── ───── ─────────────────
yarn yarn yarn yarn twenty app:publish --private (tarball → one server)
twenty test twenty
dev dev:build yarn twenty app:publish (npm → marketplace)
```
## Bu bölümde
<CardGroup cols={2}>
<Card title="CLI" icon="terminal" href="/l/tr/developers/extend/apps/operations/cli">
`yarn twenty` referansı — exec, logs, uninstall, remotes.
</Card>
<Card title="Senkronizasyon ve kurtarma" icon="compass" href="/l/tr/developers/extend/apps/operations/sync-and-recovery">
Hangi komut ne zaman, senkronizasyon diff'ini okuma ve kurtarma basamakları.
</Card>
<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="Yayımlama" icon="upload" href="/l/tr/developers/extend/apps/operations/publishing">
Oluşturun, bir tarball dağıtın, npm'e yayınlayın, yükleyin.
</Card>
</CardGroup>

View File

@@ -0,0 +1,293 @@
---
title: Yayımlama
icon: upload
description: Twenty uygulamanızı pazaryerine sunun ya da dahili olarak dağıtın.
---
## Genel Bakış
Uygulamanız [yerelde derlenip test edildikten sonra](/l/tr/developers/extend/apps/getting-started/concepts), dağıtım için iki yolunuz vardır:
* **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.
Her iki yol da aynı **build** adımından başlar.
## Uygulamanızı derleme
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 dev:build
```
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 yayımlama komutu için bir `.tgz` paketini de üretmek amacıyla `--tarball` ekleyin.
## Sunucuya dağıtım (tarball)
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.
### Ön Gereksinimler
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.
Bir remote ekleyin:
```bash filename="Terminal"
yarn twenty remote:add --url https://your-twenty-server.com --as production
```
### Dağıtım
Uygulamanızı tek adımda derleyip sunucuya yükleyin:
```bash filename="Terminal"
yarn twenty app:publish --private
# To deploy to a specific remote:
# yarn twenty app:publish --private --remote production
```
### Dağıtılmış bir uygulamayı paylaşma
Tarball uygulamaları genel pazar yerinde listelenmez; bu nedenle aynı sunucudaki diğer çalışma alanları gezinerek onları keşfedemez. Dağıtılmış bir uygulamayı paylaşmak için:
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
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.
### Sürüm yönetimi
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.
Bir güncelleme yayımlamak için:
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 app:publish --private` (veya `yarn twenty app:publish --private --remote production`) komutunu çalıştırın
3. Uygulamanın yüklü olduğu ve (uygulamanın Ayarlar sekmesinde) otomatik yükseltmeyi etkinleştirmiş çalışma alanları, arka planda otomatik olarak yükseltilir; diğerleri ise ayarlarında mevcut yükseltmeyi görecektir
<Note>
Ö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 */}
### Sunucu sürümü uyumluluğu
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"
{
"name": "twenty-my-app",
"version": "1.0.0",
"engines": {
"node": "^24.5.0",
"twenty": ">=2.3.0"
}
}
```
Değer, standart bir [semver aralığı](https://github.com/npm/node-semver#ranges)dır. Yaygın Kalıplar:
| 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ı |
**Dağıtım ve yükleme sırasında ne olur:**
* `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>
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>
## Otomatik CI/CD (hazır şablonlu iş akışları)
`create-twenty-app` ile oluşturulan uygulamalar, kutudan çıktığı gibi `.github/workflows/` altında üç GitHub Actions iş akışıyla gelir. CI herhangi bir kurulum gerektirmez, CD tek bir secret gerektirir ve npm’e yayımlamak tek seferlik bir npm Trusted Publisher kurulumu gerektirir.
### CI — `ci.yml`
Entegrasyon testlerini `main` dalına yapılan her itmede ve her çekme isteğinde otomatik olarak çalıştırır.
**Ne yapar:**
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 docker:start --test` eşdeğeridir).
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.
**Yapılandırma seçenekleri:**
* `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.
Gizli anahtar gerekmez — test örneği geçicidir ve yalnızca iş süresi boyunca çalışır.
### CD — `cd.yml`
`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.
**Ne yapar:**
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 app:publish --private` 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.
**Gerekli yapılandırma:**
| Ayar | Nerede | 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>
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>
**Bir PR'den bir önizleme dağıtımını tetikleme:**
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.
### Yayımla — `publish.yml`
Bir sürüm etiketi (örn. `v1.0.0`) gönderdiğinizde veya Actions sekmesinden iş akışını manuel olarak çalıştırdığınızda, uygulamanızı provenance ile npm’e yayımlar.
**Ne yapar:**
1. Uygulamanızı alır, Node.js’i kurar ve npm’i günceller (güvenilir yayımlama için npm 11.5.1 veya üstü gereklidir).
2. `yarn twenty app:publish` komutunu çalıştırır; bu komut uygulamayı der ve `.twenty/output`’u npm’e yayımlar. CI ortamında otomatik olarak `--provenance` ve `--access public` ekler; bu nedenle iş akışında hiçbir bayrağa gerek yoktur.
**Tek seferlik kurulum:**
npmjs.com’da paketinizin sayfasını açın > **Settings → Trusted Publisher** bölümüne gidin ve bu depoyu `publish.yml` iş akışıyla kaydedin ([npm trusted publishing belgelerine](https://docs.npmjs.com/trusted-publishers) bakın). Provenance ile yayımlama, paketi hangi GitHub deposunun oluşturduğunu doğrular; ayrıca Twenty pazaryerinde uygulamanızın sahipliğini bu şekilde talep edersiniz.
<Note>
npm yalnızca **herkese açık** kaynak depolarından gelen provenansı kabul eder. Özel bir depodan yayınlarsanız, npm OIDC provenans paketini `E422 ... Desteklenmeyen GitHub Actions kaynak deposu görünürlüğü: "private"` hatası. Özel bir depodan yayınlamak için, yayın adımının `env` bölümünde `TWENTY_APP_PUBLISH_DISABLE_PROVENANCE: 'true'` ayarını yaparak provenansı devre dışı bırakın (hazırlanmış `publish.yml` içinde yorum satırı olarak eklenmiş bir ipucu bulunur):
```yaml filename=".github/workflows/publish.yml"
- name: Publish to npm
env:
TWENTY_APP_PUBLISH_DISABLE_PROVENANCE: 'true'
run: yarn twenty app:publish
```
</Note>
### Yeniden kullanılabilir eylemleri sabitleme
`ci.yml` ve `cd.yml` iş akışları, `@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.
## npm’ye yayımlama
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.
### Gereksinimler
* 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"
{
"name": "twenty-app-postcard-sender",
"version": "1.0.0",
"keywords": ["twenty-app"]
}
```
### Pazaryeri meta verileri
`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 `logo` ve `galleryImages` kullanın:
```ts src/application-config.ts
export default defineApplication({
universalIdentifier: '...',
displayName: 'My App',
description: 'A great app',
logo: 'public/logo.png',
galleryImages: [
'public/screenshot-1.png',
'public/screenshot-2.png',
],
});
```
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.).
#### Önerilen galeri görseli boyutları
Marketplace, `galleryImages`'ı sabit `8:5` oranlı bir kapsayıcıda görüntüler (örneğin, `1600×1000 px`).
<Note>
Herhangi bir en-boy oranındaki galeri görselleri 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>
#### Görsel boyut sınırı
`logo` ve her bir `galleryImages` dosyasının boyutu **10 MB**'ı aşmamalıdır. Pazar yeri yayınladığınız varlıkları yeniden barındırdığında daha büyük dosyalar atlanır, bu nedenle görüntülenmezler.
### Yayımla
```bash filename="Terminal"
yarn twenty app:publish
```
Belirli bir dist-tag altında yayımlamak için (ör. `beta` veya `next`):
```bash filename="Terminal"
yarn twenty app:publish --tag beta
```
### Pazar yerinde keşif nasıl çalışır
Twenty sunucusu pazar yeri kataloğunu npm kayıt defterinden **her saat** eşitler.
Beklemek yerine eşitlemeyi hemen tetikleyebilirsiniz:
```bash filename="Terminal"
yarn twenty dev:catalog-sync
# To target a specific remote:
# yarn twenty dev:catalog-sync --remote production
```
Pazaryerinde gösterilen meta veriler, `defineApplication()` yapılandırmanızdan gelir — yukarıdaki [Pazaryeri meta verileri](#marketplace-metadata) bölümüne bakın.
<Note>
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 üzerinden yayımlama
Yukarıda açıklanan, şablon olarak sağlanan `publish.yml` iş akışı sürüm etiketlerinde provenance ile npm’e otomatik olarak yayımlar. `yarn twenty app:publish`, CI içinde çalıştığında sizin için `--provenance` ve `--access public` eklediği için, iş akışının herhangi bir npm bayrağına ihtiyacı yoktur — yalnızca tek seferlik güvenilir yayımlayıcı kurulumuna ihtiyaç duyar.
Diğer CI sistemleri (GitLab CI, CircleCI vb.) için önce `yarn install`, ardından `yarn twenty app:publish` komutunu çalıştırın. Ortam bir OIDC jetonu oluşturabildiğinde provenance üretilir, aksi durumda ise otomatik olarak atlanır.
<Note>
**npm provenance**, 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. Ayrıca Twenty pazaryerinde uygulamanızın sahipliğini talep etmenizi de sağlar. Ayrıntılar için [npm provenance belgelerine](https://docs.npmjs.com/generating-provenance-statements) bakın.
</Note>
## Uygulamaları yükleme
Bir uygulama yayımlandığında (npm) veya dağıtıldığında (tarball), çalışma alanları onu kullanıcı arayüzü (UI) üzerinden yükleyebilir.
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 */}
Uygulamaları komut satırından da yükleyebilirsiniz:
```bash filename="Terminal"
yarn twenty app:install
```
<Note>
Sunucu, kurulum sırasında semver sürümlemesini zorunlu kılar ve dağıtımdaki kuralları yansıtır:
* Ç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.
Daha yeni bir sürümü kurmak için önce onu dağıtın veya yayımlayın, ardından `yarn twenty app:install` komutunu yeniden çalıştırın.
</Note>

View File

@@ -0,0 +1,126 @@
---
title: Senkronizasyon ve kurtarma
description: Hangi komutu ne zaman kullanmanız gerektiği, senkronizasyon çıktısının nasıl okunacağı ve yerel üst veriler sapmaya başladığında — tam sıfırlamaya ulaşmadan önce — uygulanacak bir kurtarma merdiveni.
icon: compass
---
Yerel uygulama geliştirme **senkronizasyon** etrafında döner: CLI manifestinizi yeniden oluşturur ve sunucu, onu çalışma alanınızda hâlihazırda bulunan üst verilerle karşılaştırarak yalnızca aradaki farkı uygular. Bu sayfa, hangi komuta başvurmanız gerektiğini, bir senkronizasyonun neleri değiştirdiğini nasıl okuyacağınızı ve yerel durum tutarsız göründüğünde — sırayla — ne yapmanız gerektiğini açıklar.
## Hangi komut, ne zaman
<Note>
Günlük yerel yinelemelerde neredeyse her zaman `yarn twenty dev` kullanmak istersiniz. Dağıtım ve yayımlama, sürümleri göndermek içindir, yerel döngü için **değil**.
</Note>
| Şunu yapmak istiyorsunuz… | Komut | Notlar |
| ---------------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Canlı senkronizasyonla yerelde yineleyin | `yarn twenty dev` | Dosyalarınızı izler ve her değişiklikte senkronize eder. |
| Bir kez senkronize et ve çık (CI, betikler, kancalar) | `yarn twenty apply` | Tek bir derleme + senkronizasyon yapar ve ardından çıkar. Yıkıcı değişiklik onayını atlamak için `--force` ekleyin. |
| Değişiklikleri **uygulamadan** önizleyin | `yarn twenty plan` | Farkı hesaplar ve yazdırır; hiçbir şey yazmaz. |
| Uygulamayı çalışma alanından kaldırın | `yarn twenty app:uninstall` | İstemi atlamak için `--yes` ekleyin. |
| Bir tarball'ı sunucuya gönderin | `yarn twenty app:publish --private` | `package.json` içinde **kesin olarak daha yüksek** bir sürüm gerektirir — bkz. [Publishing](/l/tr/developers/extend/apps/operations/publishing). |
| Pazaryerine (npm) yayımlayın | `yarn twenty app:publish` | — |
| Dağıtılmış bir sürümü yükleyin / yükseltin | `yarn twenty app:install` | Şu anda dağıtılmış olan sürümü yükler. |
| Yerel sunucuyu silin ve temiz bir şekilde yeniden başlatın | `yarn twenty docker:reset` | Yerel verilerin **tamamını** siler — son çare. |
<Note>
`yarn twenty dev --once` ve `yarn twenty dev --once --dry-run`, `yarn twenty apply` ve `yarn twenty plan` için kullanımdan kaldırılmış takma adlar olsalar da hâlâ çalışırlar.
</Note>
### Yerel senkronizasyon için sürüm artırmaya gerek yoktur
Sıkı artan `version` kuralı (dağıtımda `VERSION_ALREADY_EXISTS`, yüklemede `APP_ALREADY_INSTALLED` / `CANNOT_DOWNGRADE_APPLICATION`) **`app:publish` / `app:install`** için — yani yayın yolu için — geçerlidir. `yarn twenty dev`, manifestinizi yerinde senkronize eder ve hiçbir zaman bir sürüm değişikliği gerektirmez, bu yüzden yineleme yapmak için `package.json` dosyasına dokunmanız gerekmez. Yerel bir değişikliği test etmek için kendinizi sürümü artırırken buluyorsanız, ihtiyacınız olan geliştirme döngüsü yerine yayın yolunu kullanıyorsunuz demektir.
## Senkronizasyon çıktısını okuma
Her senkronizasyon, uyguladığı (veya `plan` ile uygulayacağı) üst veri değişikliklerini, Terraform tarzında — varlık başına bir blok olacak şekilde, öznitelikleriyle birlikte ve ardından bir özet satırıyla yazdırır:
```text filename="Terminal"
# objectMetadata "rocket" will be created
+ icon = "IconRocket"
+ labelSingular = "Rocket"
+ ...
# fieldMetadata "launchedAt" will be updated
~ isNullable = false -> true
Plan: 2 to add, 1 to change, 1 to destroy.
✓ Synced My App (4 files)
```
Bu, ilk tanı aracınızdır: tam olarak hangi nesnelerin, alanların ve düzenlerin değiştiğini size bildirir; böylece bir senkronizasyonun beklediğiniz gibi davranıp davranmadığını, arayüzü kontrol etmeden önce doğrulayabilirsiniz.
Yıkıcı değişiklikler (`to destroy`), neyi kaldırdıklarıyla birlikte listelenir (ör. `objectMetadata "auditNote" — drops the table and all its rows`) ve etkileşimli onay gerektirir ya da betiklerde `--force` kullanılmasını gerektirir.
Bir senkronizasyon tek bir varlıkta başarısız olduğunda, hata mesajı sorunlu varlığı ve onun `universalIdentifier` değerini adlandırır, örneğin:
```text
Migration action 'create' for 'fieldMetadata' (universalIdentifier: 2020...4337) failed
```
Bu tanımlayıcıyı, çakışanın hangisi olduğunu tahmin etmek yerine, manifestinizdeki (ve gerekirse çalışma alanındaki) varlığı bulmak için kullanın.
## Değişiklikleri önizleme (plan)
`yarn twenty plan`, manifestinizi derler, sunucudan geçiş planını ister ve onu — **hiçbir şeyi uygulamadan** — yazdırır. Bu, ona taahhüt etmeden önce "Bu senkronizasyon neyi değiştirir?" sorusunu yanıtlamanın güvenli yoludur.
```bash filename="Terminal"
yarn twenty plan
```
```text filename="Terminal"
Building manifest...
Computing metadata plan (read-only, nothing will be applied)...
# fieldMetadata "crewCapacity" will be created
+ ...
Plan: 1 to add, 1 to change, 0 to destroy.
✓ Plan complete for My App — no changes were applied
```
Bir plan:
* **Hiçbir şey yazmaz** — üst veri geçişi, uygulama kaydı güncellemesi, varsayılan rol/sekme değişiklikleri ve API istemcisi oluşturma işlemleri yapılmaz.
* Gerçek bir senkronizasyonun uygulayacağı **aynı farkı** döndürür; böylece oluşturulan/güncellenen/silinen varlıkları en baştan inceleyebilirsiniz.
* Riskli bir değişiklikten önce, bir yapay zekâ tarafından oluşturulan değişikliği gözden geçirirken veya beklenmedik bir değişiklik gerçekleşmek üzereyse betiğin başarısız olması gereken durumlarda kullanışlıdır.
<Note>
Bir plan yalnızca **üst veri** değişikliklerini önizler ve uygulamanın en az bir kez senkronize edilmiş olmasını gerektirir (böylece çalışma alanı ondan haberdar olur). Hiç senkronize edilmemiş bir uygulamaya karşı çalıştırırsanız, sunucu uygulamanın yüklü olmadığını bildirir — önce bir kez `yarn twenty dev` çalıştırın.
</Note>
## Kurtarma merdiveni
Yerel üst veriler hatalı görünüyorsa, bu adımları sırayla uygulayın ve engeliniz kalkar kalkmaz durun. Her adım bir öncekinden daha yıkıcıdır.
1. **Yeniden senkronize edin.** `yarn twenty apply` komutunu tekrar çalıştırın. Senkronizasyonlar idempotenttir — temiz bir manifesti yeniden çalıştırmak güvenlidir ve çoğu zaman geçici bir aksaklığı giderir.
2. **Planı önizleyin.** Bir sonraki senkronizasyonun tam olarak neyi değiştirmeyi amaçladığını, uygulamadan görmek için `yarn twenty plan` komutunu çalıştırın.
3. **Adlandırılmış hatayı okuyun.** Bir senkronizasyon başarısız olursa, iletideki üst veri türünü ve `universalIdentifier` değerini not alın (yukarıya bakın) ve manifestinizdeki o varlığı bulun. Bir çakışma genellikle yinelenen veya tekrar kullanılan bir tanımlayıcıya işaret eder.
4. **Kaldırın ve yeniden yükleyin.** `yarn twenty app:uninstall` komutunu çalıştırın, ardından yeniden senkronize edin (`yarn twenty dev`). Bu, uygulamanın üst verilerini temiz bir başlangıçtan yeniden oluşturur ve çalışma alanınızın geri kalanını olduğu gibi bırakır.
5. **Tam sıfırlama (son çare).** `yarn twenty docker:reset` komutunu çalıştırın, ardından yeniden tohumlayın ve yeniden senkronize edin.
<Warning>
`yarn twenty docker:reset`, yerel örneğinizdeki verilerin **tamamını** siler — tüm çalışma alanlarını, kayıtları ve uygulamaları. Yalnızca önceki adımlar başarısız olduktan sonra kullanın.
</Warning>
<Note>
Bir üst veri hatasıyla mı karşılaştınız? Lütfen [issue açın](https://github.com/twentyhq/twenty/issues/new/choose) ve başarısız olan geçiş iletisini (üst veri türü ve `universalIdentifier` ile birlikte), senkronizasyondan gelen `Metadata changes` çıktısını ve çalıştırdığınız komutları ekleyin.
</Note>
## Tek bir çalışma alanında eşzamanlı senkronizasyonlardan kaçının
Senkronizasyon, üst veri geçişlerini uygular. Aynı çalışma alanına karşı aynı anda birden çok senkronizasyon, dağıtım veya yükleme işlemi çalıştırmak — örneğin, birden çok terminal veya paralel yineleme yapan yapay zekâ ajanları — bu geçişlerin iç içe geçmesine ve üst verilerin kısmen uygulanmış bir durumda kalmasına neden olabilir.
Sunucu, bunu önlemek için çalışma alanı başına senkronizasyonları sıralı hâle getirir, ancak yine de hassas üst veri işlemlerini aynı anda tetiklemek yerine **tek bir** süreç üzerinden geçirmeniz gerekir. Geliştirmeyi birden fazla ajanla orkestre ediyorsanız, onların senkronizasyon/dağıtım/yükleme çağrılarını tek bir kuyruğa yönlendirin ki aynı anda yalnızca biri çalışsın.
## Hataları birbirinden ayırma
Bir şeyler ters gittiğinde, üst veri farkı ve adlandırılmış hatalar, hatanın nerede oluştuğunu belirlemenizi sağlar:
* **Manifest derleme hatası** — CLI, senkronizasyondan önce başarısız olur (`MANIFEST_BUILD_FAILED`, `TYPECHECK_FAILED`); uygulama kaynağınızı düzeltin.
* **Senkronizasyon / geçiş hatası** — derleme başarılı olur ancak farkı uygulama işlemi, varlığı ve `universalIdentifier` değerini adlandırarak başarısız olur; çakışan üst veriyi düzeltin.
* **Bağımlılık boyutu hatası** — senkronizasyon veya kurulum, uygulamanın üretim `dependencies` bağımlılıklarının çalışma zamanı katmanı olarak kurulamayacak kadar büyük olması nedeniyle başarısız olur (`LOGIC_FUNCTION_DEPENDENCIES_SIZE_EXCEEDED`); mantık fonksiyonlarınızın çalışma zamanında içe aktarmadığı paketleri (UI kitaplıkları, geliştirme araçları) `devDependencies` içine taşıyın.
* **Uygulama kodu çalışma zamanı hatası** — senkronizasyon başarılı olur ancak mantık fonksiyonlarınız veya bileşenleriniz çalışma zamanında beklenmedik şekilde davranır; [function logs](/l/tr/developers/extend/apps/operations/cli) bölümünü kontrol edin.
* **Yerel örnek durumu** — yukarıdakilerin hiçbiri geçerli değil ve çalışma alanı hâlâ hatalı görünüyorsa; kurtarma merdiveninde aşağı doğru ilerleyin.

View File

@@ -0,0 +1,264 @@
---
title: Test
description: Vitest kurulumu, gerçek bir Twenty sunucusunda entegrasyon testleri, tip denetimi ve GitHub Actions ile CI.
icon: flask
---
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.
## npm paketlerini kullanma
Uygulamanızda herhangi bir npm paketini yükleyip kullanabilirsiniz. Hem mantık işlevleri hem de ön uç bileşenleri, bağımlılıklarını çıktıya satır içi olarak ekleyen [esbuild](https://esbuild.github.io/) ile paketlenir — çalışma zamanında `node_modules` gerekmez.
### Bir paketi yükleme
```bash filename="Terminal"
yarn add axios
```
Ardından kodunuza içe aktarın:
```ts src/logic-functions/fetch-data.ts
import { defineLogicFunction } from 'twenty-sdk/define';
import axios from 'axios';
const handler = async (): Promise<any> => {
const { data } = await axios.get('https://api.example.com/data');
return { data };
};
export default defineLogicFunction({
universalIdentifier: '...',
name: 'fetch-data',
description: 'Fetches data from an external API',
timeoutSeconds: 10,
handler,
});
```
Aynısı ön uç bileşenleri için de geçerlidir:
```tsx src/front-components/chart.tsx
import { defineFrontComponent } from 'twenty-sdk/define';
import { format } from 'date-fns';
const DateWidget = () => {
return <p>Today is {format(new Date(), 'MMMM do, yyyy')}</p>;
};
export default defineFrontComponent({
universalIdentifier: '...',
name: 'date-widget',
component: DateWidget,
});
```
### Paketleme nasıl çalışır
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. İçe aktarılan paketler, aşağıda listelenenler hariç paketin içine satır içi olarak eklenir.
**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.
**Ö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 npm paketleri kullanılabilir. Korumalı alanın *kısmi* bir DOM uyguladığını unutmayın; bu nedenle bir paket hatasız derlenip çalışma zamanında yine de başarısız olabilir. Bkz. [Geçerli kısıtlamalar](/l/tr/developers/extend/apps/layout/front-components#current-limitations).
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.
Ön uç bileşenleri ayrıca bir [paylaşılan bağımlılıklar paketi](/l/tr/developers/extend/apps/layout/front-components#sharing-dependencies-across-front-components) aracılığıyla bağımlılıkları paylaşabilir. Uygulamanın package.json dosyasındaki `frontComponentSharedDependencies` alanında listelenen paketler, ayrı bir dosyaya bir kez derlenir ve her bir bileşene satır içi olarak eklenmek yerine çalışma zamanında buradan yüklenir; bu nedenle, yalnızca paylaşılan paketleri içe aktaran bir bileşen, neredeyse hiç kendi bağımlılık kodunu taşımaz.
## Kurulum
İ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
```
Uygulamanızın kök dizininde bir `vitest.config.ts` oluşturun:
```ts vitest.config.ts
import tsconfigPaths from 'vite-tsconfig-paths';
import { defineConfig } from 'vitest/config';
const TWENTY_API_URL = process.env.TWENTY_API_URL ?? 'http://localhost:2020';
const TWENTY_API_KEY = process.env.TWENTY_API_KEY ?? '<the pre-seeded local dev key>';
// Make env vars available to globalSetup (test.env only applies to workers)
process.env.TWENTY_API_URL = TWENTY_API_URL;
process.env.TWENTY_API_KEY = TWENTY_API_KEY;
export default defineConfig({
plugins: [
tsconfigPaths({
projects: ['tsconfig.spec.json'],
ignoreConfigErrors: true,
}),
],
test: {
testTimeout: 120_000,
hookTimeout: 120_000,
fileParallelism: false,
include: ['src/**/*.integration-test.ts'],
globalSetup: ['src/__tests__/global-setup.ts'],
env: {
TWENTY_API_URL,
TWENTY_API_KEY,
},
},
});
```
Sunucunun erişilebilir olduğunu doğrulayan, SDK için bir test yapılandırması (`~/.twenty/config.test.json`) yazan ve testler çalışmadan önce uygulamayı eşitleyen genel bir kurulum dosyası oluşturun:
```ts src/__tests__/global-setup.ts
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { appDevOnce, appUninstall } from 'twenty-sdk/cli';
const APP_PATH = process.cwd();
const CONFIG_DIR = path.join(os.homedir(), '.twenty');
export async function setup() {
const apiUrl = process.env.TWENTY_API_URL!;
const apiKey = process.env.TWENTY_API_KEY!;
// Verify the server is running
const response = await fetch(`${apiUrl}/healthz`);
if (!response.ok) {
throw new Error(`Twenty server is not reachable at ${apiUrl}.`);
}
// Write the SDK's test config (the CLI reads config.test.json when NODE_ENV=test)
fs.mkdirSync(CONFIG_DIR, { recursive: true });
fs.writeFileSync(
path.join(CONFIG_DIR, 'config.test.json'),
JSON.stringify({
remotes: { local: { apiUrl, apiKey } },
defaultRemote: 'local',
}, null, 2),
);
// Start from a clean slate, then sync the app
await appUninstall({ appPath: APP_PATH }).catch(() => {});
const result = await appDevOnce({ appPath: APP_PATH });
if (!result.success) {
throw new Error(`Dev sync failed: ${result.error?.message}`);
}
}
export async function teardown() {
await appUninstall({ appPath: APP_PATH });
}
```
## Programatik SDK API'leri
`twenty-sdk/cli` alt yolu, test kodundan doğrudan çağırabileceğiniz fonksiyonları dışa aktarır:
| Fonksiyon | Açıklama |
| -------------- | --------------------------------------------------------------------------- |
| `appBuild` | Uygulamayı derleyin ve isteğe bağlı olarak bir tarball paketleyin |
| `appDeploy` | Bir tarball'ı sunucuya yükleyin |
| `appDevOnce` | Uygulamayı bir kez oluşturun ve eşitleyin (`yarn twenty apply` ile aynıdır) |
| `appInstall` | Uygulamayı etkin çalışma alanına yükleyin |
| `appUninstall` | Uygulamayı etkin çalışma alanından kaldırın |
Her fonksiyon, `success: boolean` ile birlikte `data` veya `error` içeren bir sonuç nesnesi döndürür.
## Bir entegrasyon testi yazma
İş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';
import { appBuild, appDeploy, appInstall, appUninstall } from 'twenty-sdk/cli';
import { MetadataApiClient } from 'twenty-client-sdk/metadata';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
const APP_PATH = process.cwd();
describe('App installation', () => {
beforeAll(async () => {
const buildResult = await appBuild({
appPath: APP_PATH,
tarball: true,
onProgress: (message: string) => console.log(`[build] ${message}`),
});
if (!buildResult.success) {
throw new Error(`Build failed: ${buildResult.error?.message}`);
}
const deployResult = await appDeploy({
tarballPath: buildResult.data.tarballPath!,
onProgress: (message: string) => console.log(`[deploy] ${message}`),
});
if (!deployResult.success) {
throw new Error(`Deploy failed: ${deployResult.error?.message}`);
}
const installResult = await appInstall({ appPath: APP_PATH });
if (!installResult.success) {
throw new Error(`Install failed: ${installResult.error?.message}`);
}
});
afterAll(async () => {
await appUninstall({ appPath: APP_PATH });
});
it('should find the installed app in the workspace', async () => {
const metadataClient = new MetadataApiClient();
const result = await metadataClient.query({
findManyApplications: {
id: true,
name: true,
universalIdentifier: true,
},
});
const installedApp = result.findManyApplications.find(
(app: { universalIdentifier: string }) =>
app.universalIdentifier === APPLICATION_UNIVERSAL_IDENTIFIER,
);
expect(installedApp).toBeDefined();
});
});
```
## Testleri çalıştırma
Yerel Twenty sunucunuzun çalıştığından emin olun, ardından:
```bash filename="Terminal"
yarn test
```
Veya geliştirme sırasında izleme modunda:
```bash filename="Terminal"
yarn test:watch
```
## Tip denetimi
Ayrıca testleri çalıştırmadan uygulamanızda tip denetimi çalıştırabilirsiniz:
```bash filename="Terminal"
yarn twenty dev:typecheck
```
Bu, uygulamanızın `tsconfig.json` dosyasına göre `tsc --noEmit` komutunu çalıştırır ve tüm tip hatalarını raporlar. İskelet olarak oluşturulan uygulamalar ayrıca test dosyalarını da kapsayan (`tsconfig.spec.json`) bir `yarn typecheck` betiği ile birlikte gelir.
## GitHub Actions ile CI
İskelet oluşturucu, `.github/workflows/ci.yml` konumunda kullanıma hazır bir iş akışı üretir. `main` dalına yapılan her itmede ve her çekme isteğinde, çalıştırıcı içinde geçici bir Twenty sunucusu başlatır (`twentyhq/twenty/.github/actions/spawn-twenty-app-dev-test` eylemi aracılığıyla) ve ardından `yarn lint`, `yarn typecheck`, `yarn test:unit` ve `yarn test` komutlarını, `TWENTY_API_URL` / `TWENTY_API_KEY` bu sunucuyu işaret edecek şekilde çalıştırır. Herhangi bir gizli bilgi gerekmez ve iş akışının en üstündeki `TWENTY_VERSION` ortam değişkeni aracılığıyla sunucu sürümünü sabitleyebilirsiniz.
Üç iskelet iş akışının (`ci.yml`, `cd.yml` dağıtım hattı ve npm yayınlama için `publish.yml`) eksiksiz adım adım anlatımı için [Yayınlama → Otomatik CI/CD](/l/tr/developers/extend/apps/operations/publishing#automated-cicd-scaffolded-workflows) bölümüne bakın.

View File

@@ -0,0 +1,128 @@
---
title: Çeviriler
description: Uygulamanızı birden çok dilde yayınlayın — manifest etiketlerini ve kullanıcı arayüzü (UI) dizelerini tek bir yerel ayar kataloğu üzerinden çevirin.
icon: language
---
Twenty uygulamaları **İngilizce** olarak oluşturulur: kaynak ve manifestinizdeki dizeler İngilizce kaynak metindir, `en` çevirdiğiniz kaynak yerel ayarıdır ve çevrilmeden bırakılan herhangi bir yerel ayar buna geri döner.
Uygulamanızda iki tür çevrilebilir metin vardır ve her ikisi de aynı `locales/` kataloğundan geçer:
* **Manifest etiketleri** — nesne ve alan adları, görünüm başlıkları, menü öğeleri ve uygulamanızın üst verilerinde (metadata) tanımlanan diğer dizeler.
* **Ön bileşen dizeleri** — React ön bileşenlerinizin render ettiği UI metni.
Çevrilebilir dizeleri işaretlersiniz, bunları yerel başına kataloglara çıkarırsınız,
bu katalogları çevirirsiniz ve build, geçerli kullanıcı için
herhangi bir ek bağlantıya gerek kalmadan doğru dili sunar.
## Ön bileşen dizelerini işaretleme
Çeviri yardımcılarını `twenty-sdk/front-component` içinden içe aktarın:
```tsx
import { Trans, t, msg, useTranslate } from 'twenty-sdk/front-component';
const STATUSES = [
{ id: 'draft', label: msg('Draft') },
{ id: 'sent', label: msg('Sent') },
];
const Card = ({ count, name }: { count: number; name: string }) => {
const { t } = useTranslate();
return (
<section>
{/* Static text — reactive to the user's locale */}
<Trans>Loading postcard…</Trans>
{/* Disambiguate identical sources with a context */}
<Trans context="card-title">Untitled</Trans>
{/* Interpolation: pass values explicitly */}
<p>{t('Hi {name}', { name })}</p>
<p>{t('Saved {count} cards', { count })}</p>
{/* Resolve a lazily-declared descriptor */}
<ul>{STATUSES.map((s) => <li key={s.id}>{t(s.label)}</li>)}</ul>
</section>
);
};
```
### Ne zaman hangisi kullanılmalı
* **`Trans`** — JSX içindeki statik metin. Değişkelerin yerleştirilmesi için `message` ve `values` prop'larını kullanın (`Trans message="Hi {name}" values={{ name }}`);
çocukların içine doğrudan yerleştirme statik olarak çıkarılamaz.
* **`useTranslate().t`** — bir bileşen içindeki dinamik dizeler. Kullanıcı dili değiştirdiğinde
yeniden render edilir. Render içinde bunu tercih edin.
* **`t(...)`** (doğrudan içe aktarılır) — bileşen render'ının içinde olmasına gerek olmadan,
event handler'lar, yardımcı fonksiyonlar ve modül kapsamı dahil **her yerde** kullanılabilen erken çeviri.
* **`msg(...)`** — veri olarak (sabitler, yapılandırma) bildirilen dizeler için ertelenmiş bir tanımlayıcı. Bunu daha sonra `t(descriptor)` ile çözün.
### Bağlam
Aynı kaynak dize farklı şekilde çevrildiğinde bunları ayırt etmek için `context` geçirin:
```tsx
t({ message: 'Open', context: 'door' });
t({ message: 'Open', context: 'window' });
<Trans context="card-title">Untitled</Trans>
```
Bağlamsal dizeler, yerel ayar kataloglarında bağlamlarına göre anahtarlanmış bir grup olarak görünür: `"\<context>": { "\<message>": "\<translation>" }`. Manifest etiketleri, tasarım gereği bağlamsaldır — her biri, oynadığı meta veri rolünü taşır (`objectMetadata.labelSingular`, `fieldMetadata.label`, `view.name`, …); dolayısıyla aynı kelime, bir nesne adı olarak ve bir görünüm adı olarak farklı şekilde çevrilebilir.
## Çıkarma ve çeviri
extract komutunu uygulama dizininizden çalıştırın:
```bash
twenty dev:translations-extract # collect strings into locales/en.json
twenty dev:translations-extract --locale fr-FR # also scaffold a target locale
```
Çıkarma işlemi, manifest etiketlerinizi ve ön bileşen kaynaklarınızdan gelen `t()`/`msg()`/`Trans`
dizelerini, kaynak dizeyi anahtar olarak kullanarak `locales/\<locale>.json` içine toplar. Çevirileri doldurun:
```json
// locales/fr-FR.json
{
"Loading postcard…": "Chargement de la carte…",
"Hi {name}": "Bonjour {name}",
"Saved {count} cards": "{count} cartes enregistrées",
"door": {
"Open": "Ouvrir"
},
"objectMetadata.labelSingular": {
"Postcard": "Carte postale"
}
}
```
Bağlamdan bağımsız dizeler düz girdilerdir; bağlamsal dizeler — her bir manifest etiketi de dahil olmak üzere — bağlam anahtarlarının altında iç içe yerleştirilir.
`{name}` gibi yer tutucular çalışma zamanında değiştirilir — bunları çeviride koruyun. Boş bırakılan herhangi bir dize, kaynak metne geri döner.
## Nasıl çalışır
`twenty dev:build`, katalogları derler ve geçerli kullanıcı için doğru dili sunar:
manifest etiketleri sunucu tarafında çözülür ve ön bileşen
katalogları her bileşen paketine gömülür. Çalışma zamanında bir bileşen, yereli yürütme bağlamından (ana makinenin geçerli dili) okur
ve her dizeyi kataloğuna göre çözer; bir çeviri eksik olduğunda
kaynak metne geri döner. Ana makinede dilin değiştirilmesi, `Trans` ve
`useTranslate().t` dizelerini canlı olarak yeniden render eder.
Manifest etiketleri, her senkronizasyonda — `twenty dev:build`, `twenty apply`
ve sürekli `twenty dev` izleme işlemi de dahil olmak üzere — derlenir; bu nedenle bir yerel ayar dosyasını düzenleyip
senkronize etmek, yeni metni görmek için yeterlidir. Ön uç bileşen katalogları, derleme sırasında
her bileşen paketine dahil edilir; dolayısıyla bunlardan birini değiştirmek yine de
`twenty dev:build`'in yeniden çalıştırılması (ve yeniden dağıtım) anlamına gelir.
`Trans` metin alt öğeleri birden fazla satıra yayılabilir — boşluklar, JSX'in boşlukları daraltma biçimiyle aynı şekilde daraltılır; bu nedenle her ikisi de `Welcome back` anahtarına dönüştürülür:
```tsx
<Trans>Welcome back</Trans>
<Trans>
Welcome
back
</Trans>
```