@cepseudo/shared
v1.0.1
Published
Shared types, errors, utilities, validation, and environment helpers for Digital Twin packages
Downloads
187
Maintainers
Readme
@cepseudo/shared
Foundation package for the Digital Twin Framework. Provides shared types, error hierarchy, validation schemas, utilities, and event bus used across all packages.
Layer 0 -- no internal dependencies. Every other @cepseudo/* package depends on this one.
Installation
pnpm add @cepseudo/sharedAPI Overview
Types
Request and response types for building type-safe HTTP handlers.
| Export | Description |
|---|---|
| TypedRequest<P, Q, B> | Generic typed Express request with params, query, and body |
| AuthenticatedTypedRequest | TypedRequest enriched with authenticated user context |
| EndpointHandler | Function signature for route handlers |
| DataRecord | Core data structure for collected/harvested data |
| DataResolver | Function that resolves data for a component |
| UserRepository | Interface for user persistence (implemented in @cepseudo/database) |
| AuthResult, AuthContext, AuthenticatedUser | Authentication-related types |
| HttpMethod | Union type of HTTP methods |
| OpenAPIDocument, OpenAPIDocumentable, ... | OpenAPI 3.x specification types |
| Component, Servable, ScheduleRunnable | Component model interfaces |
| ComponentConfiguration, CollectorConfiguration, ... | Configuration types per component kind |
| EndpointDefinition | Route definition structure |
Pre-built request types (IdParamRequest, AssetUploadRequest, PresignedUploadRequest, etc.) cover common endpoint signatures so you don't have to re-declare params/body shapes.
Errors
A structured error hierarchy extending DigitalTwinError. All errors carry a machine-readable code and an HTTP-friendly statusCode.
| Error | Status | Use case |
|---|---|---|
| ValidationError | 422 | Invalid input data |
| NotFoundError | 404 | Resource not found |
| AuthenticationError | 401 | Missing or invalid credentials |
| AuthorizationError | 403 | Insufficient permissions |
| StorageError | 500 | Object storage failures |
| DatabaseError | 500 | Database operation failures |
| ExternalServiceError | 502 | Third-party API failures |
| ConfigurationError | 500 | Invalid configuration |
| QueueError | 500 | Queue operation failures |
| FileOperationError | 500 | File system failures |
Helpers: isDigitalTwinError(err) type guard, wrapError(err) to normalize unknown errors.
Validation
VineJS-based schemas and validators for common inputs.
| Export | Description |
|---|---|
| paginationSchema | page + limit query params |
| idParamSchema | Numeric :id route param |
| assetUploadSchema, assetUpdateSchema | Asset CRUD payloads |
| presignedUploadRequestSchema | Presigned URL request body |
| validateData(schema, data) | Validate and return typed result or throw |
| safeValidate(schema, data) | Validate and return { success, data?, error? } |
| validateQuery(schema, req) | Validate req.query |
| validateParams(schema, req) | Validate req.params |
| vine | Re-exported VineJS instance for custom schemas |
Utils
| Export | Description |
|---|---|
| Logger | Structured logger with configurable LogLevel |
| safeAsync(fn) | Express-compatible async wrapper (catches and forwards errors) |
| tryAsync<T>(fn) | Returns [error, result] tuple instead of throwing |
| retryAsync(fn, opts) | Retry with configurable attempts and backoff |
| safeCleanup(fn) | Run cleanup logic, swallow errors |
| servableEndpoint(config) | Build an EndpointDefinition from a config object |
| HttpStatus | Enum of HTTP status codes |
| jsonResponse, successResponse, errorResponse, ... | Standardized HTTP response helpers |
Events
| Export | Description |
|---|---|
| EngineEventBus | Typed event emitter for inter-component communication |
| engineEventBus | Singleton instance |
| ComponentEvent | Event payload type |
Environment
| Export | Description |
|---|---|
| Env | Type-safe environment variable access with validation and defaults |
Usage Examples
Type-safe HTTP handlers
import type { TypedRequest, EndpointHandler } from '@cepseudo/shared'
import { successResponse, notFoundResponse } from '@cepseudo/shared'
interface GetSensorParams { id: string }
interface SensorQuery { includeHistory?: string }
const getSensor: EndpointHandler = async (
req: TypedRequest<GetSensorParams, SensorQuery>,
res
) => {
const { id } = req.params
const sensor = await findSensor(id)
if (!sensor) {
return notFoundResponse(res, `Sensor ${id} not found`)
}
return successResponse(res, sensor)
}Error hierarchy
import {
NotFoundError,
ValidationError,
isDigitalTwinError,
wrapError
} from '@cepseudo/shared'
try {
const record = await db.find(id)
if (!record) {
throw new NotFoundError(`Record ${id} does not exist`)
}
} catch (err) {
if (isDigitalTwinError(err)) {
console.error(`[${err.code}] ${err.message} (HTTP ${err.statusCode})`)
} else {
const wrapped = wrapError(err)
console.error('Unexpected error:', wrapped.message)
}
}Validation schemas
import { validateData, paginationSchema, vine } from '@cepseudo/shared'
// Use a built-in schema
const pagination = await validateData(paginationSchema, req.query)
// pagination.page and pagination.limit are typed numbers
// Define a custom schema
const createSensorSchema = vine.compile(
vine.object({
name: vine.string().minLength(1).maxLength(255),
latitude: vine.number().min(-90).max(90),
longitude: vine.number().min(-180).max(180),
})
)
const body = await validateData(createSensorSchema, req.body)Peer Dependencies
| Package | Required | Notes |
|---|---|---|
| ultimate-express | Optional | Only needed if you use HTTP-related types (TypedRequest, response helpers). Omit if you only use errors, validation, or utilities. |
License
MIT