Nuvaka › Geliştirici belgeleri › API başvurusu
API başvurusu
Uygulama her arayüz çerçevesine ve arka plan betiğine global nuvaka nesnesini ekler (API v1). Çağrıların hepsi Promise döner; hatalar code alanı taşıyan Error nesneleridir.
İçindekiler: temel · storage · shared · net · clipboard · files · notes · cloud · pool · friends · mail · connections · push · ui · olaylar · hatalar · SDK paketi
Temel
| Üye | Dönüş | Açıklama |
|---|---|---|
nuvaka.apiVersion | 1 | |
nuvaka.background | boolean | arka planda (QuickJS) true, arayüzde false |
nuvaka.ready | Promise<ctx | null> | arayüzde kabuk bağlanınca { page, locale, theme } ile, arka planda hemen null ile çözülür |
nuvaka.context() | ctx | null | son bağlam (sayfa, dil, tema değişince güncellenir) |
nuvaka.info() | { id, version, trust, dev, grants, appVersion } | trust: community, verified ya da geliştirici modunda dev (sürüm de dev); grants: verilen kapsamlar, ör. { "files.read": true } |
nuvaka.me() | { displayName, language, avatarUrl? } | e-posta ve kullanıcı kimliği verilmez; sunucu çağrısı |
nuvaka.settings.get() | { [key]: value } | manifest settings değerleri (kullanıcı değer vermediyse default) |
nuvaka.on(ad, fn) | aboneliği kaldıran işlev | bkz. olaylar |
nuvaka.off(ad, fn) | ||
nuvaka.call(yöntem, arg) | ham çağrı; ad alanlarını kullan |
nuvaka.storage
Uzantının kendi anahtar-değer deposu (sunucu, cihazlar arası). İzin gerekmez. Anahtar 1–200 karakter, / serbest; değer JSON, en çok 1 MB. Her yazma okunan sürümü taşır (MVCC).
| Çağrı | Dönüş |
|---|---|
get(key) | { value, version } ya da yoksa null |
set(key, value, { version }) | { version } (yeni sürüm). Yeni anahtar için version: 0. |
delete(key, { version }) | silme de okunan sürümü ister |
update(key, fn) | { value, version }; fn(eskiDeğer | undefined) yeni değeri (ya da Promise) döner. undefined dönerse yazmaz ve okunanı (ya da null) döner. Çakışmada en çok 5 deneme. |
list(prefix?, after?) | { items: [{ key, version, size, updatedAt }], next } — değerler gelmez; devamı için next'i after olarak ver |
onChanged(fn) | aboneliği kaldıran işlev. fn(key, { value, version, deleted }); key === null ise uzantının tüm verisi silindi. Yalnız daha yeni sürümler gelir; bu bağlamın kendi yazmaları gelmez. |
Hatalar: if_version_required (sürüm verilmedi), version_conflict (e.data = { current, value }), quota_exceeded.
// Sayfalı liste
let after = ''
do {
const page = await nuvaka.storage.list('summary/', after)
for (const it of page.items) console.log(it.key, it.version, it.size)
after = page.next
} while (after)
nuvaka.shared
Uzantılar arası adlandırılmış değerler. Yazılabilecek adlar manifest shared.exports'ta, okunacaklar shared.imports'ta olmalı.
| Çağrı | Dönüş |
|---|---|
set(name, value, { version }) | { version }; ilk yazmada version: 0, değer ≤ 1 MB |
getOwn(name) | bu uzantının paylaştığı değer: { value, version } ya da null |
get(from, name) | başka uzantının değeri (yalnız değer) ya da null. Kullanıcı shared iznini vermiş ve kaynak uzantı kurulu olmalı. |
nuvaka.net
net izni gerekir. İstek uygulamanın vekilinden geçer: yalnız https ve yalnız manifestteki alan adları. Çerçevede tarayıcının fetch'i CSP ile kapalıdır.
const r = await nuvaka.net.fetch('https://api.github.com/repos/tauri-apps/tauri', {
method: 'GET', // varsayılan GET
headers: { Accept: 'application/vnd.github+json' },
// body: metin ya da Uint8Array/ArrayBuffer
})
r.status; r.ok; r.url; r.headers['content-type'] // başlık adları küçük harf
const data = await r.json() // ya da r.text(), r.arrayBuffer()
- İstek ve yanıt gövdesi en çok 10 MB; bağlantı zaman aşımı 10 sn, toplam 30 sn.
- Yönlendirme en çok 5 ve yalnız izinli adlara; yönlendirmede
AuthorizationveCookiebaşlıkları düşer. - Şu başlıklar gönderilmez:
host,content-length,connection,transfer-encoding,upgrade,proxy-authorization,te,trailer,keep-alive. Yanıttakiset-cookieiletilmez. VarsayılanUser-Agent:NuvakaApps/1. - Özel ağ, loopback, link-local adreslere çözülen adlar reddedilir.
- Hatalar:
permission_required(netizni yok),net_error(izinsiz adres, http, zaman aşımı, boyut…). HTTP 4xx/5xx hata değildir;r.ok'a bak.
nuvaka.clipboard
Bu cihazın sistem panosu. Cihazlar arası pano havuzu için nuvaka.pool.
| Çağrı | İzin | Dönüş |
|---|---|---|
readText() | clipboard: read | metin ya da null |
writeText(text) | clipboard: write | null; metin ≤ 1 MB |
nuvaka.files
Kullanıcının bu cihazda uzantıya açtığı klasörler. root, pick() ya da folders()'ın döndüğü mutlak yoldur; path köke göre görelidir ("notlar/a.txt"). .., mutlak yol ve kökten sembolik bağla çıkış reddedilir.
| Çağrı | İzin | Dönüş |
|---|---|---|
folders() | read | string[] — bu cihazda açılmış klasörler |
pick() | read | klasör seçici açar; seçilen mutlak yol ya da vazgeçilirse null |
list(root, path?) | read | [{ name, dir, size, mtime }] (mtime ms ya da null; sembolik bağlar listelenmez; en çok 5000 öğe) |
readText(root, path) | read | metin (UTF-8; geçersiz baytlar U+FFFD olur) |
readBytes(root, path) | read | Uint8Array |
writeText(root, path, text) | write | null; üst klasörler yoksa oluşturulur |
writeBytes(root, path, bytes) | write | null |
mkdir(root, path) | write | null |
remove(root, path) | write | null; klasör yalnız boşsa silinir |
Okunabilecek en büyük dosya 50 MB. Seçilen klasörün kendisi değiştirilemez ya da silinemez. Hatalar: forbidden (açılmamış klasör ya da kök dışı yol), bad_request (geçersiz yol), io (dosya sistemi hatası), permission_required.
nuvaka.notes
| Çağrı | İzin | Dönüş |
|---|---|---|
list({ q?, folder? }) | read | dizi [{ id, title, content, color, isPinned, createdAt, updatedAt, reminderCount }]; folder verilirse yalnız o klasörün notları ve öğelerde folderId. q başlık/içerikte aramadır ve istemcide (SDK'da) süzülür. |
get(id) | read | { note: { id, title, content, color, isPinned, folderId, createdAt, updatedAt }, images: [{ id, fileName, fileSize }], reminders: [{ id, reminderType, reminderMessage, remindAt, intervalMinutes, maxReminders, sentCount, isActive }] } |
create({ title, content, color? }) | write | oluşan not |
update(id, { title?, content?, color?, isPinned? }) | write | güncel not |
delete(id) | write | { success: true } |
Tarihler ISO 8601 metindir. Not içeriği HTML olabilir; ekrana basarken textContent kullan.
nuvaka.cloud
Kullanıcının Nuvaka bulut dosyaları; yalnız kurulumda uzantıya açtığı klasörler (ya da tümü).
| Çağrı | İzin | Dönüş |
|---|---|---|
roots() | read | { roots: "all" | [{ id, name }] } |
list(folderId?) | read | { items: [{ type: "folder"|"file", id, name, size, contentType, fileId, createdAt, isFrozen, frozenReason, frozenUntil }], breadcrumb: [klasörler], currentFolderId }. folderId verilmezse kök (yalnız roots: "all" ise). |
read(fileId) | read | Uint8Array (dosya kaydındaki fileId) |
upload(folderId, name, bytes, contentType?) | write kritik | { success, file: { id, fileId, fileName, fileSize, contentType, createdAt } }; en çok 100 MB |
delete(fileId) | write kritik | { success: true } |
Kapsam dışı klasör ya da dosya out_of_scope ile reddedilir. Yazma ve silme her seferinde kullanıcıya sorulur.
nuvaka.pool
Hesabın cihazlar arası pano havuzu (nuvaka.clipboard izni).
| Çağrı | İzin | Dönüş |
|---|---|---|
list({ before?, limit? }) | read | { items: [{ id, deviceId, deviceName, kind, mime, fileName, size, hash, createdAt, text, textTruncated, blocks }] } — yeniden eskiye; limit 1–200 (varsayılan 50); before bu kimlikten eskiler |
add(text) | write | eklenen öğe (aynı biçim; text en çok 4096 karakter, fazlası kesilir ve textTruncated: true) |
Havuza ekleme bu cihaz adına yapılır; cihaz senkrona kayıtlı ve etkin değilse çağrı başarısız olur.
nuvaka.friends
list() → { items: [{ username, since }] }. İzin: nuvaka.friends: read.
nuvaka.mail
Hesap bazlı: önce accounts(). nuvaka.mail.read ve .send kritiktir; her kullanımda sorulur.
| Çağrı | İzin | Dönüş |
|---|---|---|
accounts() | read ya da send | { items: [{ id, email, type, isNuvaka }] } (parola yok) |
folders(accountId) | read | dizi [{ name, fullName, unreadCount, totalCount, isInbox, isSent, isDrafts, isTrash, isSpam, children: [aynı biçim] }] |
messages(accountId, { folder?, page?, pageSize? }) | read | { messages: [{ id, uniqueId, from: { name, email }, to: [{ name, email }], subject, date, isRead, hasAttachments, preview, messageId }], totalCount, page, pageSize, unreadCount }; folder varsayılan INBOX, pageSize 1–100 |
get(accountId, folder, uniqueId) | read | { id, uniqueId, from, to, cc, bcc, subject, date, isRead, hasAttachments, textBody, htmlBody, attachments: [{ id, fileName, size, contentType }] } |
send(accountId, { to, cc?, bcc?, subject, body, isHtml?, replyToMessageId? }) | send | { success: true }. to/cc/bcc virgülle ayrılmış metin ya da dizi. Uzantı başına saatte 30; her gönderim kullanıcının bildirimlerine düşer. |
nuvaka.connections
| Çağrı | İzin | Dönüş |
|---|---|---|
list() | list ya da secrets | { items: [{ id, type, name, details: { host, port, username, database … }, createdAt }] } — parola/anahtar alanları ayıklanır |
secret(id) | secrets kritik | { id, type, name, data: { … password / privateKey dahil ham alanlar } }; her çağrı sorulur ve kullanıcının bildirim akışına düşer |
nuvaka.push
nuvaka.push(title, body?) → { success: true }. Kullanıcının tüm cihazlarına bildirim; nuvaka.push izni. title zorunlu. Bildirim sınırına tabidir; kullanıcı sınırı yükseltmezse notify_limit.
nuvaka.ui
| Çağrı | Dönüş |
|---|---|
notify(title, body?) | null. Bu cihazda yerel bildirim; notifications izni; bildirim sınırı (notify_limit). Arka planda da çalışır. |
theme() | { dark, vars } — arayüzde |
page() | açık sayfanın id'si |
locale() | uygulama dili, ör. tr |
onTheme(fn) | tema değişince; aboneliği kaldıran işlev |
onPage(fn) | kullanıcı menüden başka sayfaya geçince; aboneliği kaldıran işlev |
Olaylar
nuvaka.on(ad, fn) ile dinlenir. Arka planda manifest triggers'ta yazılı olaylar gelir; sunucu kaynaklı olaylar ilgili okuma izni yoksa iletilmez.
| Olay | Nerede | Yük |
|---|---|---|
schedule | arka plan | { schedule, at } — at unix saniye |
app.started, app.focused, network.online | arka plan | null |
notes.changed, cloud.fileAdded, mail.received, clipboard.added | arka plan | değişiklik bildirimi (scope, method, path …); veri içermez, API ile yeniden oku |
data.changed | ikisi | { kind, name, version, deleted } — ham olay; storage.onChanged tercih edilir |
theme, page, locale | arayüz | yeni tema / sayfa kimliği / dil |
// background.js
nuvaka.on('schedule', async ({ schedule, at }) => {
console.log('tetiklendi', schedule, new Date(at * 1000).toISOString())
})
nuvaka.on('notes.changed', () => refreshIndex()) // manifest: { "event": "notes.changed" } + nuvaka.notes: read
İşleyicinin döndürdüğü Promise beklenir; işleyicide atılan hata uygulama günlüğüne yazılır ve diğer işleyicileri durdurmaz.
Hatalar
Her hata bir Error'dır: name: "NuvakaError", code, message (Türkçe), gerekirse permission (eksik kapsam) ve data.
| Kod | Anlamı |
|---|---|
permission_required | izin yok ya da geri alındı; e.permission eksik kapsam |
permission_denied | kritik izin onayı reddedildi ya da süresi doldu |
version_conflict | okunan sürüm tutmadı; e.data = { current, value } |
if_version_required | set/delete sürümsüz çağrıldı |
quota_exceeded | depolama kotası doldu |
notify_limit | bildirim sınırı doldu, kullanıcı yükseltmedi |
rate_limited | hız sınırı (dakikada 300 çağrı, saatte 30 mail) |
confirmation_flood | bekleyen onay sayısı 3'ü aştı |
out_of_scope | bulut klasörü uzantıya açılmamış |
not_found | kayıt yok |
forbidden, bad_request, io | yerel dosya hataları |
net_error, network | net.fetch vekil hatası / sunucuya ulaşılamadı |
not_installed, disabled, blocked | uzantı kurulu değil, durdurulmuş ya da engellenmiş |
session_revoked | kullanıcının oturumu kapatıldı |
unknown_method | bilinmeyen çağrı |
Listede olmayan kodlar da gelebilir; bilinmeyen kodu genel hata olarak göster.
SDK paketi (@nuvaka/extension-sdk)
İsteğe bağlıdır. Taşıma kodu içermez; global nuvaka'yı tipler, hataları sınıflara çevirir ve testler için sahte bir nuvaka verir.
npm i -D @nuvaka/extension-sdk
import { nuvaka, PermissionError, VersionConflictError, NotifyLimitError } from '@nuvaka/extension-sdk'
import type { Manifest } from '@nuvaka/extension-sdk'
try {
await nuvaka.push('Merhaba')
} catch (e) {
if (e instanceof NotifyLimitError) { /* sonra dene */ }
}
| Sınıf | Kod |
|---|---|
NuvakaError | taban sınıf (her kod) |
PermissionError | permission_required |
ConfirmationDeniedError | permission_denied (PermissionError alt sınıfı) |
VersionConflictError | version_conflict (current, value) |
QuotaError | quota_exceeded |
NotifyLimitError | notify_limit |
RateLimitError | rate_limited, confirmation_flood |
Paketten alınan nuvaka uygulama dışında (düz tarayıcı, Node) çağrılırsa no_runtime hatası verir. Import etmeden global kullanan kod yalnız tipler için import type {} from '@nuvaka/extension-sdk/global' yazabilir.
Test: sahte nuvaka
import { installMockNuvaka, uninstallMockNuvaka } from '@nuvaka/extension-sdk/testing'
const m = installMockNuvaka({
grants: ['notifications', 'net'], // düz kapsam adları
storage: { count: 1 },
settings: { greeting: 'Merhaba' },
notifyPerMinute: 3,
fetch: (req) => ({ status: 200, body: { ok: true } }),
})
await nuvaka.storage.update('count', (n) => n + 1)
await m.emit('schedule', { schedule: 'every 15m', at: 1790000000 })
m.advance(60_000) // sahte saat (bildirim penceresi)
uninstallMockNuvaka()
Sahte nesne izin denetimini, kritik izin onayını (confirm), MVCC'yi, storage.onChanged'ı, bildirim sınırını ve kotayı taklit eder. nuvaka-ext test uzantı klasöründe vitest çalıştırır.
Nuvaka Apps API v1 · son güncelleme 2026-09-27