@pineliner/simple-rest
v1.0.6
Published
Simple REST package with Supabase-style client and Express server
Downloads
13
Readme
Simple REST
A Supabase-style client and Express server package for simple REST queries.
Usage
Client
import { createClient } from '@pineliner/simple-rest/client';
const client = createClient('http://localhost:3000');
// Set authentication token
client.setAuthBearer('your-jwt-token');
// Using the query builder (Supabase-style)
const { data } = await client
.from('users')
.select('id, name, age')
.eq('status', 'active')
.gt('age', 18)
.notIn('role', ['banned', 'deleted'])
.is('verified', true)
.isNot('deleted_at', null)
.order('created_at', 'desc')
.limit(20);
// Authentication methods
client.setAuthBearer('new-token'); // Set/update token
const token = client.getAuthBearer(); // Get current token
client.clearAuth(); // Remove token
// Using raw query
const response = await client.query({
from: "users",
select: ["id", "name", "age"],
where: {
and: [
{ "=": ["status", "active"] },
{ ">": ["age", 18] }
]
},
orderBy: [["created_at", "desc"]],
limit: 20
});Server
import express from 'express';
import { createManager, createResolver, Resolver } from '@pineliner/simple-rest/server';
const app = express();
app.use(express.json());
// Create manager with default '/query' path
const simpleRest = createManager();
// Method 1: Direct resolver registration
simpleRest.resolver('users', async (payload, req) => {
// Implement your users query logic here
return {
data: [],
pagination: null,
success: true
};
});
// Method 2: Using Resolver groups (like Express Router)
const apiV1 = createResolver(); // or new Resolver()
apiV1.resolver('posts')
.select(async (payload, req) => {
// Handle SELECT operations
return { data: [], success: true };
})
.insert(async (payload, req) => {
// Handle INSERT operations
return { data: payload.instruction?.payload, success: true };
})
.update(async (payload, req) => {
// Handle UPDATE operations
return { data: {}, success: true };
})
.delete(async (payload, req) => {
// Handle DELETE operations
return { data: null, success: true };
});
apiV1.resolver('comments', async (payload, req) => {
// Default handler for all operations
return { data: [], success: true };
});
// Register the resolver group with path prefix
simpleRest.use('api/v1', apiV1);
// Method 3: Admin resolvers with different path
const adminResolver = createResolver();
adminResolver.resolver('users')
.select(async (payload, req) => {
// Admin-specific user queries
return { data: [], success: true };
})
.custom('ban', async (payload, req) => {
// Custom ban instruction
return { data: { banned: true }, success: true };
});
adminResolver.resolver('analytics', async (payload, req) => {
// Analytics data
return { data: { metrics: {} }, success: true };
});
// Register admin resolvers
simpleRest.use('admin', adminResolver);
// Apply middleware
app.use(simpleRest.middleware);
app.listen(3000, () => {
console.log('Server running on port 3000');
console.log('Resolvers:', simpleRest.getResolvers());
});Using Grouped Resolvers from Client
import { createClient } from '@pineliner/simple-rest/client';
const client = createClient('http://localhost:3000');
// Access resolvers with path prefixes
// These will query: api/v1/posts, api/v1/comments, admin/users, admin/analytics
// API v1 posts
const posts = await client.from('api/v1/posts').select('*');
const newPost = await client.from('api/v1/posts').insert({ title: 'New Post' });
// API v1 comments
const comments = await client.from('api/v1/comments').select('*');
// Admin users with custom instruction
const adminUsers = await client.from('admin/users').select('*');
const bannedUser = await client.from('admin/users')
.instruction({ name: 'ban', payload: { reason: 'spam' } })
.eq('id', 123);
// Admin analytics
const analytics = await client.from('admin/analytics').select('*');Build
npm run build # Build both client and server
npm run build:client # Build client only
npm run build:server # Build server only