Skip to content

NeaByteLab/Deserve-VE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Deserve-VE

Deserve with DVE: file-based routes, server-side templates, session auth, form validation.

Deno Deserve License

Deserve-VE preview

Features

  • Routes = files. One file in routes becomes one URL. No config.
  • DVE templates. Server-side views with variables, conditionals, loops, partials.
  • Shared layout. Head, nav, footer as partials. Reuse everywhere.
  • Session auth. Signed cookies guard the account page and switch the navbar.
  • Form validation. Contracts check signup and login before the handler runs.
  • Static assets. CSS and images in public folder, served at /assets.
  • Deno only. No Node or bundler. UI from Bootstrap CDN.

Installation

Clone and run:

git clone https://github.com/NeaByteLab/Deserve-VE.git
cd Deserve-VE
deno install

Quick Start

Run the server:

deno task start

Open http://localhost:8000. All pages are server-rendered with DVE.

Development (watch):

deno task dev

Restarts when main.ts or routes/ change. For view/CSS changes, refresh the browser.

Tip

Set SESSION_SECRET to a 32-character string in production. A development fallback is used when the variable is unset.

Routes

Every file in routes/ exports HTTP method handlers and maps to one URL.

Method Path Auth What it does
GET / public Home page
GET /about public About page with conditional content
GET /dashboard public Stats, table, and list
GET /items public List rendered with #each
GET /hello public Minimal single-variable page
GET /signup public Sign up form
POST /signup public Validate the form, show the created summary
GET /login public Login form
POST /login public Validate, open a session, redirect to account
GET /account session Account page, redirects guests to login
POST /logout session Clear the session, redirect home

Session Auth

main.ts registers session middleware once, so every handler reaches the session through context state:

router.use(Mware.session({ cookieSecret }))
  • Read the current session with ctx.getState('session'). It is null for guests.
  • Open a session with ctx.getState('setSession'), called after a valid login.
  • Clear a session with ctx.getState('clearSession'), called on logout.

The navbar reads session to switch between Login/Sign Up and Account/Logout, and /account redirects to /login when no session exists.

Form Validation

Contracts live in schemas/ and run inside the POST handler with Validator.check. A failing contract throws, and the handler reads the reasons off error.cause to re-render the form with messages:

import { Validator } from '@neabyte/deserve'
import { loginContract } from '@schemas/login.ts'

// Throws when the form fails a rule
const data = Validator.check(loginContract, body as FormData)
Contract Checks
signupContract Name min 2 chars, email contains @, password min 8 chars
loginContract Email required and valid, password required

Project Structure

Deserve-VE/
├── main.ts                 # Router, session, static, serve
├── deno.json               # Tasks, import aliases
├── public/
│   └── css/
│       └── style.css       # Sticky footer + overrides
├── schemas/
│   ├── login.ts            # Login form contract
│   └── signup.ts           # Sign up form contract
├── routes/
│   ├── index.ts            # Home
│   ├── about.ts            # About (conditional content)
│   ├── dashboard.ts        # Stats, table, list (complex DVE)
│   ├── items.ts            # List with #each
│   ├── hello.ts            # Minimal DVE
│   ├── signup.ts           # GET form, POST validate
│   ├── login.ts            # GET form, POST validate + session
│   ├── account.ts          # Session-guarded page
│   └── logout.ts           # POST clears session
└── views/
    ├── home.dve
    ├── about.dve
    ├── dashboard.dve
    ├── items.dve
    ├── hello.dve
    ├── signup.dve
    ├── login.dve
    ├── account.dve
    └── partials/
        ├── head.dve        # Meta, title, CSS
        ├── header.dve      # Navbar (session-aware)
        └── footer.dve      # Copyright (year from route)

DVE in This Repo

Page DVE use
Home Variables, partials
About {{#if showExtra}}
Items {{#each items as item}}, @index
Dashboard Multiple #each, #if, nested data
Hello Single variable
Login {{#if hasErrors}}, error list
Signup {{#if created}}, error list
Account Session variable

Templates use Bootstrap 5 (CDN) for layout and components; narrative copy is lorem ipsum.

Import Aliases

deno.json maps three folders so imports stay short:

Alias Folder
@routes/ ./routes/
@schemas/ ./schemas/
@views/ ./views/

Tasks

Task Description
deno task start Run server (no watch)
deno task dev Run server with file watch

References

  • Deserve (JSR) - HTTP server, file-based routing, DVE rendering, session, validation, static middleware
  • Deserve docs - Router, views, ctx.render(), session, validation, static

License

This project is licensed under the MIT license. See the LICENSE file for details.