@ortha/server-utils
v0.0.4
Published
Shared server utilities — error response building, cursor-based pagination, SQL helpers, and a generic filter service for Sequelize. Used by all server domain plugins for consistent error handling, pagination, and query filtering.
Downloads
390
Readme
@ortha/server-utils
Shared server utilities — error response building, cursor-based pagination, SQL helpers, and a generic filter service for Sequelize. Used by all server domain plugins for consistent error handling, pagination, and query filtering.
Installation
Internal monorepo dependency — import directly:
import {
buildErrorResponse,
filterService,
encodeCursor,
decodeCursor,
escapeLikeValue
} from '@ortha/server-utils';Usage
Error responses
import { buildErrorResponse, withErrorDetail } from '@ortha/server-utils';
// Build structured error response
const error = buildErrorResponse({
statusCode: 400,
code: 'VALIDATION_ERROR',
message: 'Invalid input'
});
// Add field-level details
withErrorDetail(error, {
code: 'REQUIRED',
path: 'email',
message: 'Email is required'
});Filter service
import { filterService } from '@ortha/server-utils';
const service = filterService({
httpErrors: fastify.httpErrors,
allowedFields: ['email', 'name', 'isActive'],
allowedIncludes: {
UserProject: {
model: models.UserProject,
fields: ['projectId']
}
}
});
// Parse client-provided filter JSON into Sequelize where clause
const { where, includes } = service.parseAndValidate(request.query.filter);Pagination
import { encodeCursor, decodeCursor } from '@ortha/server-utils';
// Encode a cursor from a record's created date + ID
const cursor = encodeCursor({ createdAt, id });
// Decode cursor for the next query
const { createdAt, id } = decodeCursor(cursorString);SQL helpers
import { escapeLikeValue, opToSql } from '@ortha/server-utils';
// Escape special characters for LIKE queries
const safe = escapeLikeValue('user%input'); // 'user\\%input'
// Convert Sequelize Op to raw SQL for subqueries
const sql = opToSql(Op.eq); // '='API Reference
Error Utilities
| Export | Kind | Description |
| ---------------------- | -------- | ------------------------------------------- |
| buildErrorResponse() | function | Create structured error response object |
| withErrorDetail() | function | Add field-level detail to an error response |
Pagination
| Export | Kind | Description |
| ---------------- | -------- | ------------------------------------------------- |
| encodeCursor() | function | Encode record fields into an opaque cursor string |
| decodeCursor() | function | Decode cursor string back into record fields |
SQL Helpers
| Export | Kind | Description |
| ------------------- | -------- | -------------------------------------------------------- |
| escapeLikeValue() | function | Escapes %, _, \\ for safe SQL LIKE queries |
| opToSql() | function | Converts Sequelize operator symbols to raw SQL fragments |
Filter Service
| Export | Kind | Description |
| --------------------- | ------- | ------------------------------------------------------------------------ |
| filterService() | factory | Generic filter parser — validates client JSON filters into Sequelize ops |
| FilterService | type | Service interface returned by filterService() |
| FilterServiceDeps | type | Dependencies: httpErrors, allowedFields, optional allowedIncludes |
| ParsedFilter | type | Result of parseAndValidate (where + includes) |
| ParsedInclude | type | Single relation-based $exists filter entry |
| IncludeFilterConfig | type | Config for an allowed relation in $exists filters |
| AllowedIncludes | type | Map of relation names to IncludeFilterConfig |
Internal Structure
src/lib/
├── errors/index.ts # Error response builders
├── pagination/index.ts # Cursor-based pagination helpers
├── escapeLikeValue/index.ts # SQL LIKE escape utility
├── opToSql/index.ts # Sequelize Op → raw SQL converter
└── filterService/index.ts # Generic filter parsing and validationKey Patterns
filterServiceis parameterised: callers passallowedFieldsand optionalallowedIncludesat construction time.opToSqlis a pure function used for buildingEXISTS/NOT EXISTSsubqueries.filterServicesupports$existsfiltering on relations with dynamic field conditions.- Error responses follow a consistent structure with
statusCode,code,message, anddetails[].
Building
nx build server-utils