Versi 1.0.2, 47 paket

Aplikasi backend dengan TypeScript, bagian-bagiannya sudah diputuskan.

Routing, validasi, lapisan database, CLI dan 47 paket yang memakai satu container dan satu file config. Bertipe dari param route sampai body response.

$ npx @samveys/console new my-app
Request sungguhan ke server ini
$ curl -i http://samveys.sadata.dev/_demo/subscribe \
    -H 'content-type: application/json' \
    -d '{"name":"Ada","email":"ada@","role":"backend"}'
HTTP/1.1 422 Unprocessable Entity
content-type: application/problem+json
x-request-id: fde02d2a-6833-4e33-97b3-1056f870ef9a
 
{
  "code": "SVS_E042",
  "title": "Validation failed",
  "errors": [{ "pointer": "#/body/email" }]
}
paket resmi
47
driver HTTP: node, Fastify, Hono
3
engine database & pencarian
10
eval / new Function di template
0
kasus WebSocket Autobahn lolos
301

Yang kamu dapat tanpa memasang apa-apa lagi

Semua ini sudah termasuk di paket yang dipakai proyek baru.

Routing bertipe, tanpa regex

Segmen literal, :param, segmen opsional dan wildcard. Nama param diambil dari pola, jadi salah ketik di params.id jadi error saat kompilasi, bukan 500.

@samveys/http

Validasi di setiap sisi

Schema body, query dan params mengikuti Standard Schema v1. Handler menerima tipe hasil parsing; kegagalan menjadi 422 Problem Details dengan JSON pointer.

@samveys/validator

Header keamanan langsung aktif

CSP, X-Frame-Options, Referrer-Policy dan HSTS lewat HTTPS, batas body 1 MiB, batas waktu handler 30 detik, data request tanpa prototype, dan header internal dibuang.

secure by default

Container, plugin, hook

Container IoC dengan inject(), provider dan siklus hidup plugin. Setiap fitur adalah plugin yang didaftarkan di samveys.config.ts — dan setiap plugin bisa diganti.

@samveys/core

SSE dan WebSocket, tanpa dependensi

sse() mengalirkan event dengan resume lewat Last-Event-ID dan ping keep-alive. Server RFC 6455 berjalan di port yang sama dengan daftar origin yang diizinkan, auth, dan pesan yang divalidasi schema.

realtime

Template dikompilasi jadi modul

File .tpl.html ala Blade dengan layout, section dan <x-components> dikompilasi menjadi modul ES. Ekspresi diparsing, tidak pernah dievaluasi, dan akses ke constructor ditolak.

@samveys/template

Test tanpa port

createTestApp() menjalankan app baru untuk setiap test dengan klien HTTP in-process, waktu palsu, event palsu dan perekam hook — dan membersihkan dirinya sendiri lewat await using.

@samveys/testing

CLI svs

Disediakan oleh @samveys/console dan dipasang per proyek. new, serve --watch, generator make:*, route:list, route:types, explain SVS_E042, check, build --docker dan REPL. Perintah buatanmu memakai defineCommand yang sama.

@samveys/console

Tracing di atas diagnostics_channel

Setiap request berjalan di dalam samveys:http.request dengan atribut span ala OpenTelemetry. APM bisa berlangganan tanpa meng-import satu modul Samveys pun.

observability

Seperti apa kodenya

Tujuh file pendek dari proyek sungguhan. Semua API di sini ada di versi 1.0.

File route dimuat secara lazy dari samveys.config.ts. Tipe param berasal dari polanya sendiri.

app/routes.ts
import { defineController, defineRoutes, get, post } from '@samveys/http'

const users = defineController('users', {
  prefix: '/users',
  routes: {
    show: get('/:id', ({ params }) => ({ id: params.id })),
    create: post('/', ({ response }) => response.created({ created: true })),
  },
})

export default defineRoutes((router) => {
  router.get('/ping', () => 'pong')
  router.controller(users)
})

Lapisan HTTP

Semua yang disentuh sebuah request ada di beberapa file yang sudah pasti. Ini letak masing-masing, lalu setiap bagian dengan kode asli.

samveys.config.ts Mendaftarkan http({ port, routes, middleware, securityHeaders, … }) bersama semua plugin lain.
bin/server.ts createApp(config) → app.run() → createHttpServer(app) → server.listen(). svs serve menjalankan file ini.
app/routes.ts defineRoutes((router) => …): file route yang dimuat http() secara lazy. Tambahkan file lain ke array routes.
app/controllers/*.ts defineController(name, { prefix, use, routes }): route bernama yang dikelompokkan di bawah satu prefix.
app/middleware/*.ts (ctx, next) => Response: di level global, group, controller atau route.

Route dan params

Pola berupa literal, :param, :param? dan wildcard * di akhir. Tanpa regular expression, jadi sebuah pola selalu berarti satu hal.

app/routes.ts
import { defineRoutes } from '@samveys/http'

export default defineRoutes((router) => {
  router.get('/ping', () => 'pong')                    // text/plain
  router.get('/users/:id', ({ params }) => ({ id: params.id }))
  router.get('/posts/:slug?', ({ params }) => ({ slug: params.slug ?? 'latest' }))
  router.get('/files/*path', ({ params }) => ({ path: params.path }))
  router.delete('/users/:id', () => undefined)         // 204 No Content
})
  • params.id bertipe sesuai pola; params.nope jadi error saat kompilasi.
  • Route statis dicocokkan sebelum params, params sebelum wildcard.
  • Pola regex menghasilkan SVS_E045, method + pola ganda menghasilkan SVS_E046, keduanya saat boot.

Route server ini, langsung

Dibaca dari router.list(): router yang sama yang dicetak svs route:list. Tambahkan route dan route itu muncul di sini.

MethodPolaParamsDivalidasi
GET / — —
GET /docs — —
GET /docs/:section/:slug section, slug —
GET /api — —
GET /api/:package package —
GET /ecosystem — —
GET /benchmarks — —
GET /support — —
GET /assets/:file file —
POST /_demo/subscribe — body
GET /_demo/stream — —
GET /_demo/explain — query
GET /ping — —
GET /health/live — —
GET /health/ready — —

Error berupa Problem Details

Setiap error framework berupa application/problem+json (RFC 9457) dengan code yang tetap dan requestId.

StatusKodeKapan
404 SVS_E040 Tidak ada route yang cocok dengan path.
405 SVS_E041 Path ada untuk method lain; header Allow mendaftarkannya.
422 SVS_E042 params, query atau body tidak lolos schema-nya.
413 SVS_E043 Body melebihi bodyLimit (1 MiB secara default).
400 SVS_E047 Body tidak bisa diparsing, param tidak aman (mis. ../ yang di-encode) atau redirect tidak aman.
415 SVS_E048 Schema body menerima content type yang tidak bisa diparsing.
503 SVS_E044 Handler berjalan melewati requestTimeout; ctx.signal dibatalkan.
500 SVS_E049 Error yang tidak tertangani; detail hanya tampil saat debug aktif.
500 SVS_E050 Output handler tidak lolos schema response.

Perintah svs

21 perintah bawaan, 23 lagi dari paket, dan perintah buatanmu sendiri dengan defineCommand() yang sama.

pnpm svs about
$ pnpm svs about
property      value
------------  ---------------
Application   samveys-landing
Environment   local
Debug         true
API Version   1.0.0
Node Version  v26.13.0
Plugins       4
Bindings      10

Output asli svs di proyek ini. Tambahkan --json ke perintah apa pun untuk satu dokumen yang bisa dibaca mesin.

Perintah bawaan

21 perintah

Proyek

3
  • svs new <name> [--kit=api] [--dir <dir>] Membuat proyek dari starter kit.
  • svs add <package> [--dry-run] [--yes] Memasang paket dan menerapkan recipe-nya ke samveys.config.ts.
  • svs upgrade --to <version> [--dry-run] Memindahkan @samveys/* ke major baru dan menjalankan codemod-nya.

Jalankan dan rilis

3
  • svs serve [--watch] [--entry <file>] Menjalankan bin/server.ts dari .ts dengan .env dimuat; --watch me-restart saat ada perubahan.
  • svs build [--out dist] [--docker] [--sea] Mengompilasi ke JS biasa di dist/; --docker menulis Dockerfile, --sea satu binary.
  • svs start [--permission --allow-write storage] Menjalankan hasil build produksi, bisa di bawah permission model Node.

Generator

6
  • svs make:controller <Name> app/controllers/<name>.ts beserta test-nya.
  • svs make:middleware <name> app/middleware/<name>.ts beserta test-nya.
  • svs make:command <name:part> app/commands/<name>.ts beserta test-nya.
  • svs make:provider <Name> app/providers/<name>.ts beserta test-nya.
  • svs make:test <name> tests/<name>.test.ts yang menjalankan app dengan createTestApp.
  • svs make:plugin <name> [--dir <dir>] Kerangka paket plugin yang bisa dipublikasikan.

Periksa dan debug

9
  • svs route:list [--json] Setiap route yang terpasang beserta nama dan middleware-nya.
  • svs route:types Menulis .samveys/types/routes.d.ts untuk route() yang bertipe.
  • svs about Environment, versi, jumlah plugin dan binding.
  • svs plugin:list Plugin sesuai urutan boot beserta hook, extension dan binding-nya.
  • svs config:show [path] Konfigurasi akhir dengan rahasia disamarkan.
  • svs env:check Memvalidasi variabel environment terhadap definisinya.
  • svs check [--deploy] [--skip <id>] Pemeriksaan sistem dan deployment (APP_KEY, debug, database…).
  • svs explain <SVS_Exxx> Arti sebuah kode error dan cara memperbaikinya.
  • svs repl REPL dengan app, container dan db yang sudah di-boot.

Ditambahkan oleh paket

23 perintah

Daftarkan plugin-nya di samveys.config.ts dan perintahnya muncul di svs --help.

PaketPerintah
@samveys/database migratemigrate:rollbackmigrate:statusdb:seeddb:wipedb:import-laravel
@samveys/orm make:modelmake:migrationmodel:showmodel:prune
@samveys/queue queue:workqueue:failedqueue:retry
@samveys/scheduler schedule:runschedule:list
@samveys/openapi generate:openapigenerate:clientopenapi:diff
@samveys/env-crypt env:encryptenv:decrypt
@samveys/auth make:auth
@samveys/inspector inspector:prune
@samveys/mcp mcp

Perintah buatanmu sendiri

app/commands/report-daily.ts
import { defineCommand } from '@samveys/console'

export const reportDailyCommand = defineCommand('report:daily', {
  description: 'Print yesterday’s signups',
  args: [{ name: 'team', description: 'Team slug', required: false }],
  flags: {
    days: { type: 'number', description: 'How many days back', default: 1 },
    dry: { type: 'boolean', description: 'Do not send the email', short: 'd' },
  },
  async run({ args, flags, output, app }) {
    const booted = await app()                 // boots samveys.config.ts only when asked
    const db = booted.container.make('db')     // the same binding request handlers use
    const since = new Date(Date.now() - flags.days * 86_400_000).toISOString()
    const signups = await db.from('users').where('created_at', '>', since).count()
    output.table([{ team: args.team ?? 'all', days: flags.days, signups }])
    output.result({ signups })                 // what --json prints
    return 0                                   // exit code
  },
})
  • svs make:command report:daily menulis file ini dan sebuah test.
  • Nama berupa bagian huruf kecil yang disambung ":" (selain itu SVS_E061).
  • output.table() / success() / warn() / error() / result(); --json mencetak satu dokumen JSON.

Langsung: svs explain di dalam request HTTP

GET /_demo/explain?code=… menjalankan createKernel().run(['explain', code, '--json']) dari @samveys/console di proses server ini. Kode divalidasi lebih dulu oleh schema query.

svs explain
$ svs explain SVS_E044 --json
// tekan Jalankan

Satu app di balik keduanya

bin/server.ts melayani request dan svs menjalankan perintah, tapi keduanya mem-boot samveys.config.ts yang sama.

pnpm devsvs serve → bin/server.ts
createHttpServer(app)mendengarkan, menjalankan kernel per request
samveys.config.ts createApp → register → boot
pluginscontainerrouteshooks
pnpm svs <command>createKernel().run(argv)
await app()di-boot sekali, dimatikan setelahnya

Satu config

svs dan bin/server.ts sama-sama memuat samveys.config.ts dan mem-boot plugin yang sama.

Route yang sama

http() memasang route saat app:booted, jadi svs route:list menampilkan persis yang dilayani server.

Container yang sama

app() di sebuah perintah dan handler request mengambil binding yang sama: db, cache, mail…

Plugin menambah keduanya

Satu plugin bisa menambahkan route, middleware, field ctx.* dan perintah svs sekaligus.

Perjalanan sebuah request

Setiap request melewati jalur yang sama di kernel, driver apa pun yang membawanya: node:http, Fastify atau Hono.

  1. Request

    Header internal x-samveys-* dan x-middleware-subrequest dibuang; request diberi id.

  2. Hook http:request

    Plugin bisa mencegat dan menghentikan request dengan Response-nya sendiri sebelum routing.

  3. Router

    Route statis dulu, lalu param, lalu wildcard. Tidak cocok → 404 SVS_E040.

  4. Middleware

    Global → group → controller → route, lalu dibalik urutannya setelah next() selesai.

  5. Validasi

    params, query dan body diperiksa bersamaan; semua masalah dikembalikan dalam satu 422.

  6. Handler

    Berjalan dengan ctx.signal, dibatalkan saat klien putus atau waktu habis (503 SVS_E044).

  7. Schema response

    Output divalidasi dan key yang tidak dikenal dibuang; output tidak valid menjadi 500 SVS_E050.

  8. Finalisasi

    Header keamanan digabungkan, lalu dikompresi zstd → brotli → gzip, dialirkan, tidak pernah ditampung.

Coba langsung ke server ini

Form dan stream di bawah memanggil route di server yang merender halaman ini.

Validasi → Problem Details

POST /_demo/subscribe dengan body schema.object(). Kosongkan sebuah field atau tulis email yang salah untuk mendapat 422.

Belum ada request
// body response muncul di sini

Server-Sent Events

GET /_demo/stream mengalirkan metrik proses ini setiap detik lewat sse(), dengan id event untuk resume.

uptime
—
RSS
—
heap
—
id event
—
Dilayani driver fastify di Node v26.13.0
event: metrics …

Bagian lain dari situs ini

  • Dokumentasi

    Panduan, tutorial dan README setiap paket, di satu tempat.

  • API

    Setiap ekspor publik dari setiap paket, lengkap dengan signature-nya.

  • Ekosistem

    Semua paket, versinya dan perintah yang ditambahkannya.

  • Benchmark

    Throughput dan latensi, diukur dengan metode yang dipublikasikan.

  • Bantuan

    Versi, laporan keamanan, pemecahan masalah dan kontak.

Dari laptop kosong sampai API berjalan

Belum ada yang terpasang? Mulai dari langkah 1. Setiap langkah menyebutkan di mana harus dijalankan.

Sebenarnya svs itu apa?

svs bukan program yang sudah kamu punya. Itu adalah perintah yang ada di dalam paket npm @samveys/console. Di mesin yang masih kosong, mengetik svs menghasilkan “command not found”. Dapatkan lewat npx @samveys/console untuk membuat proyek; setelah pnpm install setiap proyek punya salinannya sendiri di node_modules/.bin, jadi kamu menjalankannya sebagai pnpm svs ….

  1. Cek Node dan pnpm

    sekali per mesin
    $ node -v && pnpm -v

    Node harus 26.13.0 atau lebih baru, pnpm 12. Belum ada pnpm? Jalankan npm i -g pnpm@12 (Node 26 tidak lagi menyertakan Corepack).

  2. Arahkan @samveys/* ke registry-nya

    sekali per mesin
    $ npm config set @samveys:registry https://registry.sadata.dev/api/packages/sadata/npm/

    Menambahkan satu baris ke ~/.npmrc. Registry bisa dibaca tanpa token. Lewati langkah ini dan npx menjawab 404, karena @samveys/* tidak ada di registry npm publik.

  3. Buat proyek

    folder mana saja
    $ npx @samveys/console new my-app

    Di mesin baru belum ada svs global. npx mengunduh @samveys/console, paket yang membawa perintah svs, lalu menjalankan perintah new-nya sekali.

  4. Install dan test

    di dalam my-app/
    $ cd my-app && pnpm install && pnpm test

    Memasang @samveys/console sebagai devDependency. Mulai dari sini, svs ada di node_modules/.bin proyek ini.

  5. Jalankan dev server

    di dalam my-app/
    $ pnpm dev

    Sama dengan pnpm svs serve --watch: memuat .env, mengatur APP_ENV=local, restart saat file berubah. Buka http://localhost:3000/ping → pong.

  6. Rilis

    di dalam my-app/
    $ pnpm svs build --docker

    dist/ plus Dockerfile multi-stage tanpa root. Konfigurasi tetap di environment, tidak pernah di hasil build.

Cara memanggil svs, tergantung kamu ada di mana

Kamu ada diJalankanContoh
Di luar proyek (belum ada svs)npx @samveys/console <command>npx @samveys/console new my-app
Di dalam proyekpnpm svs <command>pnpm svs make:model Note --migration
Di dalam proyek, dengan npmnpx svs <command>npx svs route:list
svs langsung di mana saja (opsional)npm i -g @samveys/consolesvs new my-app

npx menjawab 404? Langkah 2 terlewat: @samveys/* tidak ada di registry npm publik, hanya di https://registry.sadata.dev/api/packages/sadata/npm/.

Pertanyaan umum

Aku mengetik svs dan dapat “command not found”. Kenapa?

svs bukan program global; itu bin dari paket @samveys/console. Di luar proyek, jalankan lewat npx @samveys/console …. Di dalam proyek ia adalah devDependency, jadi pakai pnpm svs … atau npx svs …. Kalau npx menjawab 404, jalankan dulu langkah sekali-saja npm config set @samveys:registry. Mau svs langsung di mana saja? npm i -g @samveys/console.

Versi Node.js berapa yang dibutuhkan?

Node.js 26 LTS (26.13.0 atau lebih baru). Tidak ada polyfill atau jalur kompatibilitas; devEngines sengaja membuat instalasi gagal di versi yang lebih lama.

Apakah TypeScript harus dikompilasi saat development?

Tidak. Development menjalankan file .ts langsung di Node 26 dengan sintaks erasable saja. svs build menghasilkan dist/ saat kamu deploy.

Bisakah tetap memakai Fastify atau Hono?

Bisa. @samveys/fastify dan @samveys/hono adalah driver HTTP: keduanya membawa transport sementara kernel Samveys tetap memegang routing, middleware dan error. Ketiga driver lolos suite conformance 29 kasus yang sama.

Seberapa aman template-nya?

Template dikompilasi menjadi modul ES dan dimuat dengan import(). Ekspresi adalah subset yang diparsing — tanpa assignment, tanpa new, tanpa fungsi — dan akses ke constructor, prototype dan __* ditolak saat kompilasi dan saat berjalan.

Bagaimana cara menambah paket opsional?

Pasang paketnya, lalu daftarkan plugin-nya di samveys.config.ts. svs add punya recipe untuk http, validator dan testing saat ini.

Siapa yang boleh memakai Samveys?

Samveys adalah perangkat lunak milik perusahaan dan internal: karyawan dan kontraktor PT Teknologi Sada Indonesia, hanya untuk pekerjaan perusahaan.

Mulai proyek

Satu perintah membuat folder, config, sebuah test dan Dockerfile.

$ npx @samveys/console new my-app