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

ÜyeDönüşAçıklama
nuvaka.apiVersion1
nuvaka.backgroundbooleanarka planda (QuickJS) true, arayüzde false
nuvaka.readyPromise<ctx | null>arayüzde kabuk bağlanınca { page, locale, theme } ile, arka planda hemen null ile çözülür
nuvaka.context()ctx | nullson 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şlevbkz. 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 Authorization ve Cookie başlıkları düşer.
  • Şu başlıklar gönderilmez: host, content-length, connection, transfer-encoding, upgrade, proxy-authorization, te, trailer, keep-alive. Yanıttaki set-cookie iletilmez. Varsayılan User-Agent: NuvakaApps/1.
  • Özel ağ, loopback, link-local adreslere çözülen adlar reddedilir.
  • Hatalar: permission_required (net izni 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ıİzinDönüş
readText()clipboard: readmetin ya da null
writeText(text)clipboard: writenull; 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ıİzinDönüş
folders()readstring[] — bu cihazda açılmış klasörler
pick()readklasö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)readmetin (UTF-8; geçersiz baytlar U+FFFD olur)
readBytes(root, path)readUint8Array
writeText(root, path, text)writenull; üst klasörler yoksa oluşturulur
writeBytes(root, path, bytes)writenull
mkdir(root, path)writenull
remove(root, path)writenull; 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ıİzinDönüş
list({ q?, folder? })readdizi [{ 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? })writeoluşan not
update(id, { title?, content?, color?, isPinned? })writegü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ıİzinDö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)readUint8Array (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ıİzinDö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)writeeklenen öğ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ıİzinDönüş
accounts()read ya da send{ items: [{ id, email, type, isNuvaka }] } (parola yok)
folders(accountId)readdizi [{ 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ıİzinDö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.

OlayNeredeYük
schedulearka plan{ schedule, at } — at unix saniye
app.started, app.focused, network.onlinearka plannull
notes.changed, cloud.fileAdded, mail.received, clipboard.addedarka plandeğişiklik bildirimi (scope, method, path …); veri içermez, API ile yeniden oku
data.changedikisi{ kind, name, version, deleted } — ham olay; storage.onChanged tercih edilir
theme, page, localearayüzyeni 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.

KodAnlamı
permission_requiredizin yok ya da geri alındı; e.permission eksik kapsam
permission_deniedkritik izin onayı reddedildi ya da süresi doldu
version_conflictokunan sürüm tutmadı; e.data = { current, value }
if_version_requiredset/delete sürümsüz çağrıldı
quota_exceededdepolama kotası doldu
notify_limitbildirim sınırı doldu, kullanıcı yükseltmedi
rate_limitedhız sınırı (dakikada 300 çağrı, saatte 30 mail)
confirmation_floodbekleyen onay sayısı 3'ü aştı
out_of_scopebulut klasörü uzantıya açılmamış
not_foundkayıt yok
forbidden, bad_request, ioyerel dosya hataları
net_error, networknet.fetch vekil hatası / sunucuya ulaşılamadı
not_installed, disabled, blockeduzantı kurulu değil, durdurulmuş ya da engellenmiş
session_revokedkullanıcının oturumu kapatıldı
unknown_methodbilinmeyen ç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ıfKod
NuvakaErrortaban sınıf (her kod)
PermissionErrorpermission_required
ConfirmationDeniedErrorpermission_denied (PermissionError alt sınıfı)
VersionConflictErrorversion_conflict (current, value)
QuotaErrorquota_exceeded
NotifyLimitErrornotify_limit
RateLimitErrorrate_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