@simpleapps-com/augur-api
Version:
TypeScript client library for Augur microservices API endpoints
203 lines • 7.99 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.SchemaUtils = exports.CommonErrorSchemas = exports.ValidationErrorResponseSchema = exports.ErrorResponseSchema = exports.ValidationErrorResponseDataSchema = exports.ValidationErrorDetailSchema = exports.ErrorResponseDataSchema = exports.mysqlDatetimeSchema = void 0;
const zod_1 = require("zod");
/**
* Custom Zod schema for MySQL datetime format
* Matches format: YYYY-MM-DD HH:mm:ss
*/
const mysqlDatetimeSchema = () => zod_1.z
.string()
.regex(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/, 'Invalid MySQL datetime format. Expected: YYYY-MM-DD HH:mm:ss');
exports.mysqlDatetimeSchema = mysqlDatetimeSchema;
/**
* Standard error response data structure
* Matches the BaseResponse pattern but for error scenarios
*/
exports.ErrorResponseDataSchema = zod_1.z.object({
/** Error code identifier */
code: zod_1.z.string(),
/** Human-readable error message */
message: zod_1.z.string(),
/** Optional error details for debugging */
details: zod_1.z.record(zod_1.z.unknown()).optional(),
/** Timestamp of when the error occurred */
timestamp: zod_1.z.string().optional(),
/** Request ID for tracking */
requestId: zod_1.z.string().optional(),
});
/**
* Validation error details schema
* Used when request parameters or body fail validation
*/
exports.ValidationErrorDetailSchema = zod_1.z.object({
/** Field path that failed validation */
field: zod_1.z.string(),
/** Validation error message */
message: zod_1.z.string(),
/** Error code (e.g., 'required', 'invalid_type', 'too_small') */
code: zod_1.z.string(),
/** Value that was received */
received: zod_1.z.unknown().optional(),
/** Value that was expected */
expected: zod_1.z.unknown().optional(),
});
/**
* Validation error response data schema
* Extends the base error response with validation-specific details
*/
exports.ValidationErrorResponseDataSchema = exports.ErrorResponseDataSchema.extend({
/** Array of validation errors */
validationErrors: zod_1.z.array(exports.ValidationErrorDetailSchema),
});
/**
* Standard error response schema following BaseResponse pattern
* All error responses MUST use this 8-field structure
*/
exports.ErrorResponseSchema = zod_1.z.object({
count: zod_1.z.literal(0), // Always 0 for error responses
data: exports.ErrorResponseDataSchema,
message: zod_1.z.string(), // High-level error message
options: zod_1.z.record(zod_1.z.unknown()).default({}),
params: zod_1.z.record(zod_1.z.unknown()).default({}),
status: zod_1.z.number().int().min(400).max(599), // HTTP error status codes only
total: zod_1.z.literal(0), // Always 0 for error responses
totalResults: zod_1.z.literal(0), // Always 0 for error responses
});
/**
* Validation error response schema following BaseResponse pattern
* Used specifically for request validation failures (HTTP 400)
*/
exports.ValidationErrorResponseSchema = zod_1.z.object({
count: zod_1.z.literal(0),
data: exports.ValidationErrorResponseDataSchema,
message: zod_1.z.string(),
options: zod_1.z.record(zod_1.z.unknown()).default({}),
params: zod_1.z.record(zod_1.z.unknown()).default({}),
status: zod_1.z.literal(400), // Always 400 for validation errors
total: zod_1.z.literal(0),
totalResults: zod_1.z.literal(0),
});
/**
* Common HTTP error response schemas
* These provide standardized error responses for common HTTP status codes
*/
exports.CommonErrorSchemas = {
/** HTTP 400 - Bad Request (validation errors) */
400: exports.ValidationErrorResponseSchema,
/** HTTP 401 - Unauthorized (authentication required) */
401: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(401),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('AUTHENTICATION_REQUIRED'),
}),
}),
/** HTTP 403 - Forbidden (insufficient permissions) */
403: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(403),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('INSUFFICIENT_PERMISSIONS'),
}),
}),
/** HTTP 404 - Not Found (resource not found) */
404: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(404),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('RESOURCE_NOT_FOUND'),
}),
}),
/** HTTP 409 - Conflict (resource already exists or conflict) */
409: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(409),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('RESOURCE_CONFLICT'),
}),
}),
/** HTTP 422 - Unprocessable Entity (business logic errors) */
422: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(422),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('BUSINESS_LOGIC_ERROR'),
}),
}),
/** HTTP 429 - Too Many Requests (rate limiting) */
429: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(429),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('RATE_LIMIT_EXCEEDED'),
details: zod_1.z
.object({
retryAfter: zod_1.z.number().optional(),
limit: zod_1.z.number().optional(),
remaining: zod_1.z.number().optional(),
resetTime: zod_1.z.string().optional(),
})
.optional(),
}),
}),
/** HTTP 500 - Internal Server Error */
500: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(500),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('INTERNAL_SERVER_ERROR'),
}),
}),
/** HTTP 502 - Bad Gateway (upstream service error) */
502: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(502),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('UPSTREAM_SERVICE_ERROR'),
}),
}),
/** HTTP 503 - Service Unavailable (temporary outage) */
503: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(503),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('SERVICE_UNAVAILABLE'),
details: zod_1.z
.object({
retryAfter: zod_1.z.number().optional(),
maintenanceWindow: zod_1.z.string().optional(),
})
.optional(),
}),
}),
/** HTTP 504 - Gateway Timeout (upstream timeout) */
504: exports.ErrorResponseSchema.extend({
status: zod_1.z.literal(504),
data: exports.ErrorResponseDataSchema.extend({
code: zod_1.z.literal('UPSTREAM_TIMEOUT'),
}),
}),
};
/**
* Simple schema utilities for common patterns
*/
class SchemaUtils {
/**
* Create pagination parameters schema
*/
static createPaginatedParamsSchema(additionalFields, defaultLimit = 20) {
const baseFields = {
limit: zod_1.z.coerce.number().int().min(1).max(1000).optional().default(defaultLimit),
offset: zod_1.z.coerce.number().int().min(0).optional().default(0),
orderBy: zod_1.z.string().optional(),
q: zod_1.z.string().optional(),
};
return zod_1.z.object({
...baseFields,
...additionalFields,
});
}
/**
* Create search parameters schema
*/
static createSearchParamsSchema(additionalFields) {
return this.createPaginatedParamsSchema({
searchType: zod_1.z.enum(['query', 'category', 'brand']).optional().default('query'),
...additionalFields,
});
}
}
exports.SchemaUtils = SchemaUtils;
//# sourceMappingURL=schema-utils.js.map