@servemate/dto
Version:
Type-safe DTO package for ServeMate types and Zod validation. Shared across server and client.
271 lines • 11.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OrderMeta = exports.PrepareItems = exports.OrderIds = exports.OrderUpdateItemsSchema = exports.OrderUpdateProps = exports.OrderFullSingleSchema = exports.OrderCreateSchema = exports.foodAndDrinkSchema = exports.OrderSearchSchema = exports.OrderSchema = exports.orderItemSchema = exports.OrderSortOptions = exports.PaymentStatus = exports.Allergies = void 0;
const zod_1 = require("zod");
const enums_1 = require("./enums");
/**
* Order-related enums
*/
exports.Allergies = {
GLUTEN: 'GLUTEN',
DAIRY: 'DAIRY',
EGG: 'EGG',
PEANUT: 'PEANUT',
TREENUT: 'TREENUT',
FISH: 'FISH',
SHELLFISH: 'SHELLFISH',
SOY: 'SOY',
SESAME: 'SESAME',
CELERY: 'CELERY',
MUSTARD: 'MUSTARD',
LUPIN: 'LUPIN',
SULPHITES: 'SULPHITES',
MOLLUSCS: 'MOLLUSCS',
};
exports.PaymentStatus = {
NONE: 'NONE',
PAID: 'PAID',
REFUNDED: 'REFUNDED',
CANCELED: 'CANCELLED',
PENDING: 'PENDING',
};
exports.OrderSortOptions = {
ID: 'id',
TABLE_NUMBER: 'tableNumber',
GUEST_NUMBER: 'guestsCount',
ORDER_TIME: 'orderTime',
UPDATED_AT: 'updatedAt',
STATUS: 'status',
};
/**
* Order-related schemas
*/
const baseItemSchema = zod_1.z.object({
id: zod_1.z.number().int().positive(),
price: zod_1.z.number().nonnegative(),
discount: zod_1.z.number().default(0),
itemId: zod_1.z.number().int().positive(),
finalPrice: zod_1.z.number().default(0),
specialRequest: zod_1.z.string().nullable(),
allergies: zod_1.z.array(zod_1.z.nativeEnum(exports.Allergies)).default([]),
printed: zod_1.z.boolean().default(false),
fired: zod_1.z.boolean().default(false),
guestNumber: zod_1.z.number().int().positive(),
paymentStatus: zod_1.z.nativeEnum(exports.PaymentStatus).default(exports.PaymentStatus.NONE),
});
const foodItemSchema = baseItemSchema.extend({
foodItem: zod_1.z.object({
name: zod_1.z.string(),
id: zod_1.z.number(),
}),
});
const drinkItemSchema = baseItemSchema.extend({
drinkItem: zod_1.z.object({
name: zod_1.z.string(),
id: zod_1.z.number(),
}),
});
exports.orderItemSchema = baseItemSchema.extend({
foodItem: zod_1.z
.object({
name: zod_1.z.string(),
id: zod_1.z.number(),
})
.optional(),
drinkItem: zod_1.z
.object({
name: zod_1.z.string(),
id: zod_1.z.number(),
})
.optional(),
});
const guestItemsBaseSchema = zod_1.z.object({
guestNumber: zod_1.z.number().int().positive(),
items: zod_1.z.array(baseItemSchema.extend({ id: zod_1.z.number().optional(), guestNumber: zod_1.z.number().optional() })),
});
const createGuestItemsSchema = zod_1.z.object({
guestNumber: zod_1.z.number().int().positive(),
items: zod_1.z.array(baseItemSchema.omit({ id: true, guestNumber: true })),
});
exports.OrderSchema = zod_1.z.object({
id: zod_1.z.coerce.number().int().positive(),
tableNumber: zod_1.z.coerce.number().int().positive(),
orderNumber: zod_1.z.coerce.number().int().positive(),
guestsCount: zod_1.z.coerce.number().int().positive(),
orderTime: zod_1.z.date(),
updatedAt: zod_1.z.date(),
allergies: zod_1.z.array(zod_1.z.nativeEnum(exports.Allergies)).optional(),
serverId: zod_1.z.coerce.number().int().positive(),
totalAmount: zod_1.z.coerce.number().int().nonnegative().default(0),
status: zod_1.z.nativeEnum(enums_1.OrderState).default(enums_1.OrderState.RECEIVED),
comments: zod_1.z.string().optional().nullable(),
completionTime: zod_1.z.date().optional().nullable(),
discount: zod_1.z.number().default(0),
tip: zod_1.z.number().default(0),
shiftId: zod_1.z.string().optional().nullable(),
});
/**
* Schema for searching orders.
*
* This schema validates the search parameters for querying orders.
*
* @property {number} [id] - The unique identifier of the order. Must be a positive integer.
* @property {number} [tableNumber] - The table number associated with the order. Must be a positive integer.
* @property {number} [guestNumber] - The number of guests for the order. Must be a positive integer.
* @property {Allergies[]} allergies - An array of allergies associated with the order. Defaults to an empty array.
* @property {string} [server] - The server's identifier. If provided, it will be coerced to an integer.
* @property {OrderState} [status] - The status of the order. If provided, it will be transformed to uppercase and validated against the OrderState enum.
* @property {number} [page=1] - The page number for pagination. Must be a positive integer. Defaults to 1.
* @property {number} [pageSize=10] - The number of items per page for pagination. Must be a positive integer and cannot exceed 100. Defaults to 10.
* @property {OrderSortOptions} [sortBy=OrderSortOptions.ID] - The field by which to sort the results. Defaults to OrderSortOptions.ID.
* @property {'asc' | 'desc'} [sortOrder='asc'] - The order in which to sort the results. Defaults to 'asc'.
* @property {boolean} [meta=false] - A flag indicating whether to include metadata in the response. Defaults to false.
*/
exports.OrderSearchSchema = zod_1.z.object({
id: zod_1.z.coerce.number().int().positive().optional(),
tableNumbers: zod_1.z.preprocess(val => {
if (typeof val === 'string') {
const items = val.split(',').map(item => parseInt(item.trim())).filter(item => item !== undefined || !isNaN(item));
return items.length > 0 ? items : undefined;
}
if (Array.isArray(val)) {
return val.map(item => {
const num = typeof item === 'string' ? parseInt(item) : item;
return isNaN(num) ? undefined : num;
});
}
return undefined;
}, zod_1.z.optional(zod_1.z.array(zod_1.z.coerce.number().int().positive()))),
guestsCount: zod_1.z.coerce.number().int().positive().optional(),
allergies: zod_1.z.preprocess((val) => {
if (typeof val === 'string') {
// Разбиваем строку по запятым, очищаем от пробелов и приводим к верхнему регистру
const items = val
.split(',')
.map((item) => item.trim().toUpperCase())
.filter((item) => item !== '');
return items.length > 0 ? items : undefined;
}
if (Array.isArray(val)) {
// Если массив, приводим каждый элемент к верхнему регистру
return val.map((item) => (typeof item === 'string' ? item.toUpperCase() : item));
}
return undefined;
}, zod_1.z.optional(zod_1.z.array(zod_1.z.nativeEnum(exports.Allergies)))),
serverId: zod_1.z
.string()
.optional()
.transform((server) => (server ? parseInt(server) : undefined)),
serverName: zod_1.z.string().optional(),
status: zod_1.z
.string()
.transform((status) => status === null || status === void 0 ? void 0 : status.toUpperCase())
.pipe(zod_1.z.nativeEnum(enums_1.OrderState))
.optional(),
minAmount: zod_1.z.coerce.number().int().positive().optional(),
maxAmount: zod_1.z.coerce.number().int().positive().optional(),
page: zod_1.z.coerce.number().int().positive().optional().default(1),
pageSize: zod_1.z.coerce.number().int().positive().max(100).optional().default(10),
sortBy: zod_1.z
.enum(Object.values(exports.OrderSortOptions))
.default(exports.OrderSortOptions.ID),
sortOrder: zod_1.z.enum(['asc', 'desc']).optional().default('asc'),
});
exports.foodAndDrinkSchema = zod_1.z.object({
foodItemId: zod_1.z.number().int().positive(),
quantity: zod_1.z.number().int().positive(),
price: zod_1.z.number().nonnegative(),
guestNumber: zod_1.z.number().int().positive(),
});
exports.OrderCreateSchema = exports.OrderSchema.omit({
id: true,
orderNumber: true,
orderTime: true,
updatedAt: true,
tip: true,
shiftId: true,
})
.extend({
foodItems: zod_1.z.array(guestItemsBaseSchema).default([]),
drinkItems: zod_1.z.array(guestItemsBaseSchema).default([]),
})
.refine((order) => (order.foodItems && order.foodItems.length > 0) ||
(order.drinkItems && order.drinkItems.length > 0), {
message: 'At least one of foodItems or drinkItems must be provided',
path: ['foodItems', 'drinkItems'],
});
exports.OrderFullSingleSchema = exports.OrderSchema.omit({
orderNumber: true,
}).extend({
server: zod_1.z.object({
name: zod_1.z.string(),
id: zod_1.z.number(),
}),
foodItems: zod_1.z.array(guestItemsBaseSchema),
drinkItems: zod_1.z.array(guestItemsBaseSchema),
});
exports.OrderUpdateProps = exports.OrderSchema.omit({
orderNumber: true,
orderTime: true,
updatedAt: true,
shiftId: true,
serverId: true,
completionTime: true,
id: true,
})
.partial()
.refine((order) => Object.keys(order).length > 0, {
message: 'At least one property must be provided',
path: [
'order',
'paymentStatus',
'orderTime',
'updatedAt',
'shiftId',
'serverId',
'completionTime',
'id',
],
});
exports.OrderUpdateItemsSchema = zod_1.z
.object({
foodItems: zod_1.z.array(createGuestItemsSchema).default([]),
drinkItems: zod_1.z.array(createGuestItemsSchema).default([]),
})
.refine((data) => data.foodItems.length > 0 || data.drinkItems.length > 0, {
message: 'At least one of foodItems or drinkItems must be provided',
});
exports.OrderIds = zod_1.z.object({
ids: zod_1.z.array(zod_1.z.coerce.number().int().positive()).min(1, 'At least one order item ID is required'),
});
exports.PrepareItems = zod_1.z.object({
foodItems: zod_1.z.array(foodItemSchema.partial()).default([]),
drinkItems: zod_1.z.array(drinkItemSchema.partial()).default([]),
});
exports.OrderMeta = zod_1.z.object({
statuses: zod_1.z.array(zod_1.z.nativeEnum(enums_1.OrderState)),
allergies: zod_1.z.array(zod_1.z.nativeEnum(exports.Allergies)),
maxGuests: zod_1.z.number().int().positive(),
prices: zod_1.z.object({
min: zod_1.z.number().int().nonnegative(),
max: zod_1.z.number().int().nonnegative(),
}),
dates: zod_1.z.object({
min: zod_1.z.string().datetime(),
max: zod_1.z.string().datetime(),
}),
tableNumbers: zod_1.z.array(zod_1.z.coerce.number().int().positive()),
filtered: zod_1.z.object({
maxGuests: zod_1.z.number().int().positive(),
prices: zod_1.z.object({
min: zod_1.z.number().int().nonnegative(),
max: zod_1.z.number().int().nonnegative(),
}),
dates: zod_1.z.object({
min: zod_1.z.string().datetime(),
max: zod_1.z.string().datetime(),
}),
tableNumbers: zod_1.z.array(zod_1.z.coerce.number().int().positive()),
}),
});
//# sourceMappingURL=orders.dto.js.map