@alphabite/medusa-reviews
Version:
Alphabite's Medusa Reviews Plugin
156 lines • 10.6 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const http_1 = require("@medusajs/framework/http");
const validators_1 = require("@medusajs/medusa/api/utils/validators");
const multer_1 = __importDefault(require("multer"));
const route_1 = require("./admin/reviews/route");
const route_2 = require("./admin/reviews/status/route");
const validators_2 = require("./store/products/reviews/validators");
const validators_3 = require("./store/reviews/product/[id]/validators");
const validators_4 = require("./store/reviews/validators");
const ALLOWED_MIME_TYPES = [
"image/jpeg",
"image/png",
"image/webp",
"image/gif",
];
const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
const MAX_FILES = 5;
const upload = (0, multer_1.default)({
storage: multer_1.default.memoryStorage(),
limits: {
fileSize: MAX_FILE_SIZE,
files: MAX_FILES,
},
fileFilter: (_req, file, cb) => {
if (ALLOWED_MIME_TYPES.includes(file.mimetype)) {
cb(null, true);
}
else {
cb(new Error(`Invalid file type: ${file.mimetype}. Only JPEG, PNG, WebP, and GIF are allowed.`));
}
},
});
// Simple IP-based rate limiter for upload endpoint
const uploadRateLimit = new Map();
const RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000; // 15 minutes
const RATE_LIMIT_MAX = 10; // max 10 upload requests per window
const rateLimitUpload = (req, res, next) => {
const ip = req.ip ?? req.socket.remoteAddress ?? "unknown";
const now = Date.now();
const entry = uploadRateLimit.get(ip);
if (!entry || now > entry.resetAt) {
uploadRateLimit.set(ip, { count: 1, resetAt: now + RATE_LIMIT_WINDOW_MS });
return next();
}
if (entry.count >= RATE_LIMIT_MAX) {
return res
.status(429)
.json({ message: "Too many upload requests. Please try again later." });
}
entry.count++;
return next();
};
exports.default = (0, http_1.defineMiddlewares)({
routes: [
//----Create review-----//
{
matcher: "/store/reviews",
method: ["POST"],
bodyParser: { sizeLimit: "10mb" },
middlewares: [
(0, http_1.authenticate)("customer", ["session", "bearer"]),
(0, http_1.validateAndTransformBody)(validators_4.CreateReviewInputSchema),
],
},
//----List reviews-----//
{
matcher: "/store/products/reviews",
method: ["GET"],
middlewares: [
(0, http_1.authenticate)("customer", ["bearer"], {
allowUnauthenticated: true,
allowUnregistered: true,
}),
(0, http_1.validateAndTransformQuery)((0, validators_1.createFindParams)().extend(validators_2.ListReviewsQuerySchema.shape), {
defaults: ["customer.first_name", "customer.last_name"],
isList: true,
}),
],
},
//----List product reviews-----//
{
matcher: "/store/reviews/product/:id",
method: ["GET"],
middlewares: [
(0, http_1.authenticate)("customer", ["bearer"], {
allowUnauthenticated: true,
allowUnregistered: true,
}),
(0, http_1.validateAndTransformQuery)((0, validators_1.createFindParams)().extend(validators_3.ListProductReviewsQuerySchema.shape), {
defaults: ["customer.first_name", "customer.last_name"],
isList: true,
}),
],
},
//----Get Aggregate counts of product reviews-----//
{
matcher: "/store/reviews/product/:id/aggregate-counts",
method: ["GET"],
},
//----Delete product review-----//
{
matcher: "/store/reviews/:id",
method: ["DELETE"],
middlewares: [(0, http_1.authenticate)("customer", ["bearer"])],
},
//----Admin list reviews-----//
{
matcher: "/admin/reviews",
method: ["GET"],
middlewares: [
(0, http_1.validateAndTransformQuery)(route_1.GetAdminReviewsSchema, {
isList: true,
defaults: [
"id",
"title",
"content",
"rating",
"product_id",
"customer_id",
"status",
"created_at",
"updated_at",
"product.*",
],
}),
],
},
//----Admin change reviews status-----//
{
matcher: "/admin/reviews/status",
method: ["POST"],
middlewares: [
(0, http_1.validateAndTransformBody)(route_2.PostAdminUpdateReviewsStatusSchema),
],
},
{
matcher: "/store/reviews/files/images/upload",
method: "POST",
bodyParser: false,
middlewares: [
rateLimitUpload,
// @ts-ignore
upload.array("files", MAX_FILES),
(0, http_1.authenticate)("customer", ["bearer"], {
allowUnauthenticated: true,
allowUnregistered: true,
}),
],
},
],
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlkZGxld2FyZXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBpL21pZGRsZXdhcmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsbURBS2tDO0FBTWxDLHNFQUF5RTtBQUN6RSxvREFBNEI7QUFDNUIsaURBQThEO0FBQzlELHdEQUFrRjtBQUNsRixvRUFBNkU7QUFDN0Usd0VBQXdGO0FBQ3hGLDJEQUFxRTtBQUVyRSxNQUFNLGtCQUFrQixHQUFHO0lBQ3pCLFlBQVk7SUFDWixXQUFXO0lBQ1gsWUFBWTtJQUNaLFdBQVc7Q0FDWixDQUFDO0FBQ0YsTUFBTSxhQUFhLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQyxNQUFNO0FBQzdDLE1BQU0sU0FBUyxHQUFHLENBQUMsQ0FBQztBQUVwQixNQUFNLE1BQU0sR0FBRyxJQUFBLGdCQUFNLEVBQUM7SUFDcEIsT0FBTyxFQUFFLGdCQUFNLENBQUMsYUFBYSxFQUFFO0lBQy9CLE1BQU0sRUFBRTtRQUNOLFFBQVEsRUFBRSxhQUFhO1FBQ3ZCLEtBQUssRUFBRSxTQUFTO0tBQ2pCO0lBQ0QsVUFBVSxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsRUFBRTtRQUM3QixJQUFJLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQztZQUMvQyxFQUFFLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2pCLENBQUM7YUFBTSxDQUFDO1lBQ04sRUFBRSxDQUNBLElBQUksS0FBSyxDQUNQLHNCQUFzQixJQUFJLENBQUMsUUFBUSw4Q0FBOEMsQ0FDbEYsQ0FDRixDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7Q0FDRixDQUFDLENBQUM7QUFFSCxtREFBbUQ7QUFDbkQsTUFBTSxlQUFlLEdBQUcsSUFBSSxHQUFHLEVBQThDLENBQUM7QUFDOUUsTUFBTSxvQkFBb0IsR0FB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