API Reference
Complete API reference for URPC packages including @unilab/urpc-core, @unilab/urpc-hono, @unilab/urpc, @unilab/urpc-next, @unilab/urpc, and @unilab/uniweb3.
@unilab/urpc-core
Core types and interfaces for the URPC framework.
Repository Operations Arguments
FindManyArgs
Arguments for finding multiple records with advanced query operators.
interface FindManyArgs<T extends Record<string, any>> {
limit?: number;
offset?: number;
where?: WhereConditionWithOperators<T>;
order_by?: Partial<Record<keyof T, "asc" | "desc">>;
include?: {
[key: string]: RelationCallbackMany<T, any>;
};
}
type WhereCondition<T> = {
[K in keyof T]?: T[K];
};
type WhereConditionWithOperators<T> = {
[K in keyof T]?: T[K] | QueryOperators<T[K]>;
};
type QueryOperators<T> = {
$gt?: T;
$gte?: T;
$lt?: T;
$lte?: T;
$eq?: T;
$ne?: T;
$in?: T[];
$nin?: T[];
};
export type RelationCallbackMany<
T extends Record<string, any>,
R extends Record<string, any>
> = (entities: T[]) => Promise<R[]>;
Properties:
limit
- Maximum number of records to returnoffset
- Number of records to skipwhere
- Filter conditions with query operators supportorder_by
- Sort order specificationinclude
- Include related entities using callback functions
Query Operators:
$gt
- Greater than$gte
- Greater than or equal$lt
- Less than$lte
- Less than or equal$eq
- Equal to$ne
- Not equal to$in
- Value in array$nin
- Value not in array
FindOneArgs
Arguments for finding a single record.
interface FindOneArgs<T extends Record<string, any>> {
where: WhereCondition<T>;
include?: {
[key: string]: RelationCallbackSingle<T, any>;
};
}
export type RelationCallbackSingle<T extends Record<string, any>, R extends Record<string, any>> = (
entity: T
) => Promise<R | null>;
Properties:
where
- Filter conditions (required)include
- Include related entities using callback functions
CreationArgs
Arguments for creating a new record.
interface CreationArgs<T extends Record<string, any>> {
data: Partial<T>;
}
Properties:
data
- Data for the new record
UpdateArgs
Arguments for updating an existing record.
interface UpdateArgs<T extends Record<string, any>> {
where: WhereCondition<T>;
data: Partial<T>;
}
Properties:
where
- Filter conditions to identify records to updatedata
- New data for the record
DeletionArgs
Arguments for deleting records.
interface DeletionArgs<T extends Record<string, any>> {
where: WhereCondition<T>;
}
Properties:
where
- Filter conditions to identify records to delete
DataSourceAdapter
Interface that all data source adapters must implement.
interface DataSourceAdapter<T extends Record<string, any>> {
findMany(args?: FindManyArgs<T>): Promise<T[]>;
findOne(args: FindOneArgs<T>): Promise<T | null>;
create(args: CreationArgs<T>): Promise<T>;
update(args: UpdateArgs<T>): Promise<T>;
delete(args: DeletionArgs<T>): Promise<boolean>;
}
Repository
Repository class for interacting with data sources, includes built-in middleware support.
class Repository<T extends Record<string, any>> {
constructor(adapter: DataSourceAdapter<T>);
async findMany(args?: FindManyArgs<T>): Promise<T[]>;
async findOne(args: FindOneArgs<T>): Promise<T | null>;
async create(args: CreationArgs<T>): Promise<T>;
async update(args: UpdateArgs<T>): Promise<T>;
async delete(args: DeletionArgs<T>): Promise<boolean>;
}
Middleware System
Middleware Types
type Middleware<T extends Record<string, any>> = (
context: MiddlewareContext<T>,
next: MiddlewareNext<T>
) => Promise<any>;
type MiddlewareContext<T extends Record<string, any>> = {
operation: "findMany" | "findOne" | "create" | "update" | "delete";
args: any;
result?: any;
metadata?: MiddlewareMetadata;
};
interface MiddlewareMetadata {
entity: string;
source?: string;
context?: {
lang?: string;
};
}
type MiddlewareOptions = {
position?: "before" | "after" | "around";
priority?: number;
name?: string;
required?: {
entities: string[];
};
};
Entity Schema System
Decorators
Entity configuration using decorators for type-safe schema generation.
// Field decorators
const Fields = {
string: (options?: { optional?: boolean; description?: string }) => PropertyDecorator;
number: (options?: { optional?: boolean; description?: string }) => PropertyDecorator;
boolean: (options?: { optional?: boolean; description?: string }) => PropertyDecorator;
date: (options?: { optional?: boolean; description?: string }) => PropertyDecorator;
array: (target: () => any, options?: { optional?: boolean; description?: string }) => PropertyDecorator;
record: (target: () => any, options?: { optional?: boolean; description?: string }) => PropertyDecorator;
};
// Relation decorators
const Relations = {
toOne: (target: () => any, options?: { optional?: boolean }) => PropertyDecorator;
toMany: (target: () => any, options?: { optional?: boolean }) => PropertyDecorator;
};
Schema Generation
function generateSchema(entityClass: any): SchemaObject;
function generateSchemas(entityClasses: any[]): Record<string, SchemaObject>;
Plugin System
Plugin Interface
interface Plugin {
entities?: Record<string, any>[];
adapters?: AdapterRegistration[];
}
interface AdapterRegistration {
source: string;
entity: string;
adapter: DataSourceAdapter<any>;
}
@unilab/urpc-hono
Server-side components for creating URPC API servers using Hono framework.
URPC
Main class for creating and configuring URPC servers with plugin support.
Static Methods
init
Initialize the URPC server with configuration including plugins and middleware.
static init(config: URPCConfig): Hono
Parameters:
config.app
- Optional external Hono app instanceconfig.plugins
- Array of plugins to registerconfig.middleware
- Array of global middleware to apply
Returns: Hono app instance with all routes configured
Example:
import { URPC } from "@unilab/urpc-hono";
import { WalletPlugin } from "@unilab/uniweb3";
import { LoggingMiddleware } from "@unilab/urpc-core/middleware";
const app = URPC.init({
plugins: [WalletPlugin],
middlewares: [LoggingMiddleware]
});
repo
Get or create a repository for a specific data source.
static repo<T extends Record<string, any>>(
options: RepoOptions
): Repository<T>
getApp
Get the current Hono app instance.
static getApp(): Hono
getEntitySchemas
Get all registered entity schemas.
static getEntitySchemas(): Record<string, SchemaObject>
getEntitySources
Get mapping of entities to their available data sources.
static getEntitySources(): Record<string, string[]>
Configuration Interfaces
URPCConfig
Configuration options for initializing URPC server.
interface URPCConfig {
app?: Hono;
plugins?: Plugin[];
middlewares?: Middleware<any>[];
}
Properties:
app
- Optional external Hono app instanceplugins
- Array of plugins containing entities and adaptersmiddlewares
- Array of global middleware to apply
Automatic Route Generation
The URPC server automatically generates REST API endpoints based on registered plugins:
GET /{entity}/list
- Find multiple recordsGET /{entity}/find_one
- Find single recordPOST /{entity}/create
- Create new recordPATCH /{entity}/update
- Update existing recordDELETE /{entity}/delete
- Delete records
All routes require a source
query parameter to specify the data source.
@unilab/urpc
HTTP client library for consuming URPC APIs with relation support.
URPC Client
Main client class for interacting with URPC APIs with automatic relation loading.
Constructor
constructor(config: ClientConfig)
Parameters:
config
- Client configuration options
Instance Methods
createRepositoryProxy
Create a repository proxy for a specific entity and data source.
createRepositoryProxy<T extends Record<string, any>>(
entity: string,
source: string
): Repository<T>
Parameters:
entity
- Name of the entitysource
- Data source identifier
Returns: Repository instance with client-side relation loading support
Static Methods
init
Initialize the global client instance.
static init(config: ClientConfig): void
Parameters:
config
- Client configuration options
Example:
import { URPC } from "@unilab/urpc";
URPC.init({
baseUrl: "http://localhost:3000",
timeout: 10000,
headers: {
Authorization: "Bearer token",
},
});
repo
Create a repository instance using the global client.
interface RepoOptions {
entity: string;
source: string;
}
static repo<T extends Record<string, any>>(
options: RepoOptions
): Repository<T>
Example:
import { URPC } from "@unilab/urpc";
import { WalletEntity } from "@unilab/uniweb3/entities";
const walletRepo = URPC.repo<WalletEntity>({
entity: "wallet",
source: "evm",
});
joinRepo
Create a repository with relation mapping support.
type JoinRepoOptions<
F extends Record<string, any> = Record<string, any>,
L extends Record<string, any> = Record<string, any>
> = RepoOptions & RelationMapping<F, L>
static joinRepo<F extends Record<string, any>, L extends Record<string, any>>(
options: JoinRepoOptions<F, L>
): Repository<F>
Configuration Interfaces
ClientConfig
Configuration options for the URPC client.
interface ClientConfig {
baseUrl: string;
timeout?: number;
headers?: Record<string, string>;
}
Properties:
baseUrl
- Base URL of the URPC server (required)timeout
- Request timeout in milliseconds (default: 5000)headers
- Default headers to include with requests
RelationMapping
Interface for defining entity relationships.
interface RelationMapping<
T extends Record<string, any>,
F extends Record<string, any>
> {
localField: keyof F;
foreignField: keyof T;
}
HttpRequestOptions
Internal interface for HTTP request configuration.
interface HttpRequestOptions {
method: "GET" | "POST" | "PATCH" | "DELETE";
url: string;
params?: Record<string, any>;
data?: any;
headers?: Record<string, string>;
}
ApiResponse
Interface for API response structure.
interface ApiResponse<T = any> {
data: T;
success: boolean;
message?: string;
}
Utility Functions
repo
Global convenience function for creating repository instances.
function repo<T extends Record<string, any>>(
options: RepoOptions
): Repository<T>
joinRepo
Global convenience function for creating repository instances with relation mapping.
function joinRepo<
F extends Record<string, any> = Record<string, any>,
L extends Record<string, any> = Record<string, any>
>(
options: JoinRepoOptions<F, L>
): Repository<F>
Example:
import { repo, URPC } from "@unilab/urpc";
import { WalletEntity } from "@unilab/uniweb3/entities";
// Initialize client first
URPC.init({ baseUrl: "http://localhost:3000" });
// Use the convenience function
const walletRepo = repo<WalletEntity>({
entity: "wallet",
source: "solana",
});
const wallet = await walletRepo.findOne({
where: { address: "11111111111111111111111111111112" }
});
Client-Side Relations
The client automatically handles relation loading by executing callback functions on the client side after fetching the main entity data. This allows for flexible relation definitions without server-side configuration.
@unilab/urpc-next
Next.js integration for URPC with support for both App Router and Pages Router.
URPC
App Router integration (Next.js 13+).
Static Methods
init
Initialize the URPC API handlers for App Router.
static init(config: URPCConfig): URPCAPI
Parameters:
config.plugins
- Array of plugins to registerconfig.middleware
- Array of global middleware to apply
Returns: API handlers object with GET, POST, PATCH, DELETE methods
Example:
// app/api/[...urpc]/route.ts
import { URPC } from "@unilab/urpc-next";
import { WalletPlugin } from "@unilab/uniweb3";
const api = URPC.init({
plugins: [WalletPlugin]
});
export const { GET, POST, PATCH, DELETE } = api;
repo
Get or create a repository for a specific data source.
static repo<T extends Record<string, any>>(
options: RepoOptions
): Repository<T>
URPC
Pages Router integration (Next.js 12+).
Static Methods
init
Initialize the URPC API handler for Pages Router.
static init(config: URPCConfig): (req: NextApiRequest, res: NextApiResponse) => Promise<void>
Example:
// pages/api/[...urpc].ts
import { URPC } from "@unilab/urpc-next";
import { WalletPlugin } from "@unilab/uniweb3";
export default URPC.init({
plugins: [WalletPlugin]
});
Configuration Interfaces
URPC API
Interface for App Router API handlers.
interface URPCAPI {
GET: RouteHandler;
POST: RouteHandler;
PATCH: RouteHandler;
DELETE: RouteHandler;
}
URPCConfig
Configuration options for Next.js integration.
interface URPCConfig {
plugins?: Plugin[];
middlewares?: Middleware<any>[];
}
@unilab/urpc
Lightweight browser-only client library for URPC without HTTP functionality.
URPC
Browser-optimized client for local data sources.
Static Methods
repo
Create a repository instance for browser environments.
static repo<T extends Record<string, any>>(
options: RepoOptions
): Repository<T>
joinRepo
Create a repository with relation mapping for browser environments.
static joinRepo<F extends Record<string, any>, L extends Record<string, any>>(
options: JoinRepoOptions<F, L>
): Repository<F>
Utility Functions
repo
Global convenience function for browser repository creation.
function repo<T extends Record<string, any>>(
options: RepoOptions
): Repository<T>
joinRepo
Global convenience function for browser repository with relations.
function joinRepo<F extends Record<string, any>, L extends Record<string, any>>(
options: JoinRepoOptions<F, L>
): Repository<F>
@unilab/uniweb3
Unified blockchain data adapters and entities for Web3 integration.
Entities
WalletEntity
Entity for blockchain wallet data.
import { Fields } from "@unilab/urpc-core";
class TokenEntity {
@Fields.string()
symbol = "";
@Fields.number()
decimals = 0;
}
export class WalletEntity {
@Fields.string()
address = "";
@Fields.string()
balance = "";
@Fields.string()
network = "";
@Fields.record(() => TokenEntity, {
optional: true,
})
token?: TokenEntity = new TokenEntity();
}
Adapters
EVMAdapter
Ethereum Virtual Machine adapter for EVM-compatible chains.
class EVMAdapter extends BaseAdapter<WalletEntity> {
// Implements all DataSourceAdapter methods for EVM chains
}
SolanaAdapter
Solana blockchain adapter.
class SolanaAdapter extends BaseAdapter<WalletEntity> {
// Implements all DataSourceAdapter methods for Solana
}
Plugins
WalletPlugin
Complete plugin configuration for wallet functionality.
const WalletPlugin: Plugin = {
entities: [WalletEntity],
adapters: [
{ source: "evm", entity: "wallet", adapter: new EVMAdapter() },
{ source: "solana", entity: "wallet", adapter: new SolanaAdapter() }
]
};
API Routes
The URPC server automatically generates the following REST API endpoints when adapters are registered:
GET /{entity}/list
Find multiple records with advanced filtering.
Query Parameters:
source
(required) - Data source identifierlimit
- Maximum number of records to returnoffset
- Number of records to skipwhere
- JSON filter conditions with query operatorsorder_by
- JSON sort specification
Example:
GET /wallet/list?source=evm&limit=10&where={"balance":{"$gt":"1000000000000000000"}}
GET /{entity}/find_one
Find a single record.
Query Parameters:
source
(required) - Data source identifierwhere
(required) - JSON filter conditions
Example:
GET /wallet/find_one?source=solana&where={"address":"11111111111111111111111111111112"}
POST /{entity}/create
Create a new record.
Query Parameters:
source
(required) - Data source identifier
Request Body:
{
"data": {
"address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
"balance": "5000000000",
"network": "bitcoin"
}
}
PATCH /{entity}/update
Update an existing record.
Query Parameters:
source
(required) - Data source identifier
Request Body:
{
"where": {
"address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
},
"data": {
"balance": "6000000000"
}
}
DELETE /{entity}/delete
Delete records.
Query Parameters:
source
(required) - Data source identifierwhere
(required) - JSON filter conditions
Example:
DELETE /wallet/delete?source=evm&where={"balance":"0"}
Usage Examples
Hono Server Setup
import { URPC } from "@unilab/urpc-hono";
import { WalletPlugin } from "@unilab/uniweb3";
import { LoggingMiddleware } from "@unilab/urpc-core/middleware";
const app = URPC.init({
plugins: [WalletPlugin],
middlewares: [LoggingMiddleware]
});
export default {
port: 3000,
fetch: app.fetch,
};
Next.js App Router Setup
// app/api/[...urpc]/route.ts
import { URPC } from "@unilab/urpc-next";
import { WalletPlugin } from "@unilab/uniweb3";
const api = URPC.init({
plugins: [WalletPlugin]
});
export const { GET, POST, PATCH, DELETE } = api;
Client Usage with Relations
import { URPC, repo } from "@unilab/urpc";
import { WalletEntity } from "@unilab/uniweb3/entities";
// Initialize client
URPC.init({
baseUrl: "http://localhost:3000",
timeout: 10000,
});
// Query with relations
const wallets = await repo<WalletEntity>({
entity: "wallet",
source: "solana",
}).findMany({
where: {
balance: { $gt: "1000000000000000000" }
},
include: {
transactions: async (wallets) => {
// Load related transactions
return await repo("transaction", "solana").findMany({
where: { wallet_address: { $in: wallets.map(w => w.address) } }
});
}
}
});
Custom Entity and Adapter
import { Fields, Relations, DataSourceAdapter } from "@unilab/urpc-core";
// Define entity with decorators
class UserEntity {
@Fields.string()
id = "";
@Fields.string()
name = "";
@Fields.string({ optional: true })
email = "";
@Relations.toMany(() => PostEntity)
posts?: PostEntity[];
}
// Implement custom adapter
class DatabaseAdapter extends BaseAdapter<UserEntity> {
async findMany(args?: FindManyArgs<UserEntity>): Promise<UserEntity[]> {
// Database query implementation
return [];
}
async findOne(args: FindOneArgs<UserEntity>): Promise<UserEntity | null> {
// Database query implementation
return null;
}
}
// Create plugin
const UserPlugin: Plugin = {
entities: [UserEntity],
adapters: [
{ source: "database", entity: "user", adapter: new DatabaseAdapter() }
]
};
Browser-Only Usage
import { repo } from "@unilab/urpc";
import { LocalStorageAdapter } from "./local-storage-adapter";
// Browser-only repository without HTTP
const localRepo = repo("todos", new LocalStorageAdapter());
const todos = await localRepo.findMany({
where: { completed: false },
order_by: { created_at: "desc" }
});
Middleware Usage
import { useGlobalMiddleware } from "@unilab/urpc-core";
// Add logging middleware
useGlobalMiddleware(async (context, next) => {
console.log(`${context.operation} started:`, context.args);
const result = await next();
console.log(`${context.operation} completed:`, result);
return result;
}, {
name: "logger",
position: "around",
priority: 1
});
// Add caching middleware
useGlobalMiddleware(async (context, next) => {
if (context.operation === "findMany") {
const cacheKey = JSON.stringify(context.args);
const cached = cache.get(cacheKey);
if (cached) return cached;
const result = await next();
cache.set(cacheKey, result);
return result;
}
return next();
}, {
name: "cache",
position: "around",
priority: 2
});
Error Handling
All endpoints return consistent error responses:
{
"error": "Error message describing what went wrong"
}
Common HTTP status codes:
400
- Bad Request (missing required parameters, invalid JSON)404
- Not Found (unknown entity or source)500
- Internal Server Error (adapter errors, database errors)