Skip to content

nesalia-inc/server

nesalia Logo

@deessejs/server

npm Version Bundle Size Tests Coverage License

A type-safe API layer for Next.js with queries, mutations, and cache invalidation.

Requirements

  • TypeScript 5.0+
  • Node.js 20+

Installation

# Install server
npm install @deessejs/server

# Or using pnpm
pnpm add @deessejs/server

# Or using yarn
yarn add @deessejs/server

Quick Start

import { defineContext, createAPI } from '@deessejs/server'

// Define context
const { t, createAPI } = defineContext({
  context: {
    db: myDatabase,
  },
})

// Define queries
const getUser = t.query({
  args: z.object({ id: z.number() }),
  handler: async (ctx, args) => {
    const user = await ctx.db.users.find(args.id)
    return ok(user, { keys: [['users', { id: args.id }]] })
  }
})

// Define mutations
const createUser = t.mutation({
  args: z.object({ name: z.string(), email: z.string().email() }),
  handler: async (ctx, args) => {
    const user = await ctx.db.users.create(args)
    return ok(user, { invalidate: ['users:list'] })
  }
})

// Create API
const api = createAPI({
  router: t.router({
    users: t.router({
      get: getUser,
      create: createUser,
    }),
  }),
})

export { api }

Features

  • Type-safe - Full TypeScript inference for queries and mutations
  • Queries & Mutations - Define typed API operations
  • Internal Operations - Server-only queries and mutations
  • Cache System - Built-in cache with keys and invalidation
  • Plugin System - Extend context and add routes
  • Event System - Emit and listen to events

Security Model

Server Actions in Next.js are exposed via HTTP and can be called by anyone. This package solves this by separating:

  • query / mutation - Public operations, exposed via HTTP
  • internalQuery / internalMutation - Internal operations, server-only
// Public - exposed via HTTP
const getUser = t.query({ ... })
const createUser = t.mutation({ ... })

// Internal - only callable from server
const deleteUser = t.internalMutation({ ... })
const getAdminStats = t.internalQuery({ ... })

Client-Safe API

Create a separate API that only exposes public operations:

import { createPublicAPI } from '@deessejs/server'

const clientApi = createPublicAPI(api)

// Server: api.users.delete() - Works
// Client: clientApi.users.delete() - TypeScript Error!

Documentation

See the docs/ folder for detailed technical specifications:

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Author

  • Nesalia Inc.

Support

If you discover any security vulnerabilities, please send an e-mail to support@nesalia.com.

License

MIT License - see the LICENSE file for details.

About

TypeScript library for building type-safe APIs with queries, mutations, and cache invalidation

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors