postgre-types
v1.0.3
Published
Type-safe validation library for PostgreSQL and Node.js Express with ORM-like features. Provides runtime type checking, query parameter parsing, and request body validation with TypeScript support.
Downloads
208
Maintainers
Readme
postgre-types
A powerful, type-safe validation library for Node.js and Express applications. Provides runtime type checking, request validation, and automatic type conversion with full TypeScript support.
English | 한국어
✨ Features
- 🔒 Full Type Safety - Complete TypeScript type inference and validation
- 🎯 Request Body Validation - Validate
req.bodywithparseWithTypeGuard - 🔍 Query & Params Parsing - Auto-parse and validate
req.queryandreq.paramswithparseQueryParams - 🎨 40+ Predefined Patterns - Email, phone, URL, and more validation patterns
- 🔄 Automatic Type Conversion - String to number, boolean, array, date conversion
- ✅ Comprehensive Validation - min/max, pattern, enum, nullable support
- 🚀 Zero Dependencies - Lightweight and fast
- 📝 Clear Error Messages - Detailed validation error reporting
📦 Installation
npm install postgre-types
# or
yarn add postgre-types
# or
pnpm add postgre-types🚀 Quick Start
1. Request Body Validation with parseWithTypeGuard
import { parseWithTypeGuard } from "postgre-types";
interface UserCreate {
email: string;
password: string;
name: string | null;
}
// Define validation schema
const isUserCreate = parseWithTypeGuard<UserCreate>({
email: {
type: "string",
isNull: false,
pattern: "email", // Built-in email pattern
},
password: {
type: "string",
isNull: false,
min: 8,
},
name: {
type: "string",
isNull: true,
},
});
// Use in Express route
app.post("/users", (req, res) => {
if (!isUserCreate(req.body)) {
return res.status(400).json({
error: isUserCreate.errorMessage(),
});
}
// Type-safe! req.body is now UserCreate
const user = req.body as UserCreate;
// ... create user
});2. Query & Params Validation with parseQueryParams
import { parseQueryParams } from "postgre-types";
// Define query/params schema
const getUserParams = parseQueryParams<{
userId: number;
page?: number;
limit?: number;
}>({
userId: {
type: "number",
isNull: false,
},
page: {
type: "number",
isNull: true,
default: 1,
min: 1,
},
limit: {
type: "number",
isNull: true,
default: 10,
min: 1,
max: 100,
},
});
// Use in Express route
app.get("/users/:userId", (req, res) => {
// Automatically parse and validate query + params
const params = getUserParams(req.query, req.params);
if (!params) {
return res.status(400).json({
error: getUserParams.errorMessage(),
});
}
// Type-safe! params.userId is number (auto-converted from string)
const users = await getUsers(params.userId, params.page, params.limit);
res.json(users);
});📖 API Reference
parseWithTypeGuard<T>(schema)
Validates request body data against a schema.
Returns: TypeGuard<T>
(data: any): boolean- Validate data, returns true/false.errorMessage(): string | null- Get formatted error message.getErrors(): ValidationError[]- Get detailed error array.validate(data: any): ValidationResult- Get full validation result
Example:
const isPostCreate = parseWithTypeGuard<PostCreate>({
title: {
type: "string",
isNull: false,
min: 1,
max: 200,
},
content: {
type: "string",
isNull: false,
},
tags: {
type: "array",
isNull: false,
arrayOf: "string",
},
published: {
type: "boolean",
isNull: false,
},
});parseQueryParams<T>(schema)
Parses and validates query parameters and route params with automatic type conversion.
Returns: QueryParamsGuard<T>
(query: any, params?: any): T | null- Parse and validate, returns data or null.errorMessage(): string | null- Get formatted error message.getErrors(): ValidationError[]- Get detailed error array.validate(query, params): ValidationResult & { data: T | null }- Get full result
Example:
const getPostsParams = parseQueryParams<{
page: number;
limit: number;
sort: string;
status?: string;
}>({
page: {
type: "number",
default: 1,
min: 1,
},
limit: {
type: "number",
default: 10,
min: 1,
max: 100,
},
sort: {
type: "string",
default: "createdAt",
enum: ["createdAt", "updatedAt", "title"],
},
status: {
type: "string",
isNull: true,
enum: ["draft", "published"],
},
});🎨 Field Schema Options
Common Options
| Option | Type | Description |
| --------- | ---------------- | --------------------------------------------------------------------------------------------- |
| type | PostgreSQLType | Required. Data type: "string", "number", "boolean", "date", "array", "object" |
| isNull | boolean | Allow null/undefined values (default: true) |
| enum | any[] | Restrict to specific values |
| default | any | Default value (only for parseQueryParams) |
Type-Specific Options
String
{
type: "string",
min: 3, // Minimum length
max: 50, // Maximum length
pattern: "email" // Predefined pattern or custom RegExp
}Number
{
type: "number",
min: 0, // Minimum value
max: 100 // Maximum value
}Array
{
type: "array",
arrayOf: "string" // Element type
}Object
{
type: "object",
properties: { // Nested schema
name: { type: "string", isNull: false }
}
}🎯 Predefined Patterns
Use built-in validation patterns by passing a string key:
Email & Authentication
pattern: "email"; // [email protected]
pattern: "password"; // 8+ chars, letters + numbers
pattern: "passwordStrong"; // 8+ chars, letters + numbers + special chars
pattern: "username"; // 3-20 alphanumeric + underscorePhone Numbers
pattern: "phoneKR"; // 010-1234-5678
pattern: "phoneKRNoHyphen"; // 01012345678
pattern: "phoneUS"; // (123) 456-7890Web & URLs
pattern: "url"; // https://example.com
pattern: "slug"; // my-blog-post
pattern: "hexColor"; // #FF5733Dates & Time
pattern: "dateYYYYMMDD"; // 2024-12-31
pattern: "dateDDMMYYYY"; // 31/12/2024
pattern: "time24"; // 23:59
pattern: "time24WithSeconds"; // 23:59:59Numbers & Codes
pattern: "numbersOnly"; // 12345
pattern: "alphanumeric"; // abc123
pattern: "uuid"; // 550e8400-e29b-41d4-a716-446655440000
pattern: "mongoObjectId"; // 507f1f77bcf86cd799439011Location
pattern: "postalCodeKR"; // 12345
pattern: "zipCodeUS"; // 12345 or 12345-6789
pattern: "ipv4"; // 192.168.0.1
pattern: "latitude"; // 37.5665
pattern: "longitude"; // 126.9780Korean Specific
pattern: "koreanOnly"; // 홍길동
pattern: "residentRegistrationKR"; // 900101-1234567Financial
pattern: "creditCard"; // 1234-5678-9012-3456
pattern: "ssnUS"; // 123-45-6789Developer Tools
pattern: "semver"; // 1.0.0 or 1.0.0-alpha.1
pattern: "base64"; // SGVsbG8gV29ybGQ=
pattern: "fileExtension"; // .jpgCustom Pattern
pattern: /^[A-Z]{3}-\d{4}$/; // Custom RegExp: ABC-1234See all 40+ patterns: Patterns.ts
💡 Advanced Examples
Complex Validation Schema
interface UserRegistration {
email: string;
password: string;
username: string;
age: number;
phone: string;
website?: string;
tags: string[];
settings: {
newsletter: boolean;
theme: string;
};
}
const isUserRegistration = parseWithTypeGuard<UserRegistration>({
email: {
type: "string",
isNull: false,
pattern: "email",
},
password: {
type: "string",
isNull: false,
min: 8,
max: 100,
pattern: "passwordStrong",
},
username: {
type: "string",
isNull: false,
min: 3,
max: 20,
pattern: "username",
},
age: {
type: "number",
isNull: false,
min: 18,
max: 120,
},
phone: {
type: "string",
isNull: false,
pattern: "phoneKR",
},
website: {
type: "string",
isNull: true,
pattern: "url",
},
tags: {
type: "array",
isNull: false,
arrayOf: "string",
},
settings: {
type: "object",
isNull: false,
properties: {
newsletter: { type: "boolean", isNull: false },
theme: {
type: "string",
isNull: false,
enum: ["light", "dark", "auto"],
},
},
},
});Query Parameters with Defaults
const getAnalyticsParams = parseQueryParams<{
startDate: string;
endDate: string;
metrics: string[];
groupBy: string;
format: string;
}>({
startDate: {
type: "string",
isNull: false,
pattern: "dateYYYYMMDD",
},
endDate: {
type: "string",
isNull: false,
pattern: "dateYYYYMMDD",
},
metrics: {
type: "array",
isNull: false,
arrayOf: "string",
},
groupBy: {
type: "string",
isNull: true,
enum: ["day", "week", "month"],
default: "day",
},
format: {
type: "string",
isNull: true,
enum: ["json", "csv", "excel"],
default: "json",
},
});
// URL: /analytics?startDate=2024-01-01&endDate=2024-12-31&metrics=views,clicks
app.get("/analytics", (req, res) => {
const params = getAnalyticsParams(req.query, req.params);
if (!params) {
return res.status(400).json({
error: getAnalyticsParams.errorMessage(),
});
}
// params.groupBy = "day" (default applied)
// params.format = "json" (default applied)
// params.metrics = ["views", "clicks"] (auto-converted to array)
});Error Handling
const result = isUserCreate.validate(req.body);
if (!result.isValid) {
// Detailed error information
result.errors.forEach((error) => {
console.log(`Field: ${error.field}`);
console.log(`Message: ${error.message}`);
console.log(`Value: ${error.value}`);
console.log(`Expected: ${error.expectedType}`);
});
// Formatted error message
return res.status(400).json({
error: isUserCreate.errorMessage(),
// Example output:
// [email] Field 'email' has an invalid format.
// [password] Field 'password' must be at least 8 characters long.
});
}🔧 Type Conversion (parseQueryParams)
Query parameters and route params are always strings. parseQueryParams automatically converts them:
// URL: /users/123?page=2&limit=20&active=true&tags=javascript,typescript
// Input (all strings):
// req.params = { userId: "123" }
// req.query = { page: "2", limit: "20", active: "true", tags: "javascript,typescript" }
const params = getUserParams(req.query, req.params);
// Output (converted types):
// {
// userId: 123, // string → number
// page: 2, // string → number
// limit: 20, // string → number
// active: true, // string → boolean
// tags: ["javascript", "typescript"] // string → array
// }📝 TypeScript Support
Full TypeScript support with type inference:
import { parseWithTypeGuard, parseQueryParams, Patterns } from 'postgre-types';
// Type inference works automatically
const isUser = parseWithTypeGuard<User>({ ... });
const getParams = parseQueryParams<Params>({ ... });
// Access predefined patterns
if (Patterns.email.test(email)) {
console.log('Valid email!');
}🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
📄 License
MIT © suhyun751207
🔗 Links
📚 Related Projects
- postgre-records - Type-safe PostgreSQL ORM
