@codenokami/node-api-master 1.4.2 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,368 +1 @@
1
- var __defProp = Object.defineProperty;
2
- var __export = (target, all) => {
3
- for (var name in all)
4
- __defProp(target, name, { get: all[name], enumerable: true });
5
- };
6
-
7
- // src/index.js
8
- import Joi3 from "joi";
9
-
10
- // src/db/connection.js
11
- import mongoose from "mongoose";
12
- var connectDB = async (url) => {
13
- if (!url) {
14
- console.error(
15
- "\u274C Error: MongoDB URL is required to connect to the database."
16
- );
17
- process.exit(1);
18
- }
19
- try {
20
- const conn = await mongoose.connect(url);
21
- console.log(`\u2705 MongoDB Connected: ${conn.connection.host}`);
22
- } catch (error) {
23
- console.error(`\u274C Error: ${error.message}`);
24
- process.exit(1);
25
- }
26
- };
27
- var connection_default = connectDB;
28
-
29
- // src/middleware/auth.js
30
- import jwt from "jsonwebtoken";
31
-
32
- // src/utils/AppError.js
33
- var AppError = class extends Error {
34
- constructor(message, statusCode) {
35
- super(message);
36
- this.statusCode = statusCode;
37
- this.status = `${statusCode}`.startsWith("4") ? "fail" : "error";
38
- this.isOperational = true;
39
- Error.captureStackTrace(this, this.constructor);
40
- }
41
- };
42
- var AppError_default = AppError;
43
-
44
- // src/utils/catchAsync.js
45
- var catchAsync = (fn) => {
46
- return (req, res, next) => {
47
- fn(req, res, next).catch(next);
48
- };
49
- };
50
- var catchAsync_default = catchAsync;
51
-
52
- // src/middleware/auth.js
53
- var auth = (secret = process.env.JWT_SECRET) => catchAsync_default(async (req, res, next) => {
54
- let token;
55
- if (req.headers.authorization && req.headers.authorization.startsWith("Bearer")) {
56
- token = req.headers.authorization.split(" ")[1];
57
- } else if (req.cookies && req.cookies.jwt) {
58
- token = req.cookies.jwt;
59
- }
60
- if (!secret) {
61
- return next(
62
- new AppError_default("JWT Secret is not defined in environment variables", 500)
63
- );
64
- }
65
- if (!token) {
66
- return next(
67
- new AppError_default(
68
- "You are not logged in! Please log in to get access.",
69
- 401
70
- )
71
- );
72
- }
73
- try {
74
- const decoded = jwt.verify(token, secret);
75
- req.user = decoded;
76
- next();
77
- } catch (error) {
78
- return next(
79
- new AppError_default("Invalid token or expired. Please log in again.", 401)
80
- );
81
- }
82
- });
83
- var admin = (req, res, next) => {
84
- if (req.user && req.user.role === "admin") {
85
- next();
86
- } else {
87
- return next(
88
- new AppError_default("You do not have permission to perform this action", 403)
89
- );
90
- }
91
- };
92
-
93
- // src/middleware/validate.js
94
- var validate = (schema) => (req, res, next) => {
95
- const { error, value } = schema.validate(req.body, {
96
- abortEarly: false,
97
- // Error အားလုံးကို တစ်ခါတည်း ပြရန်
98
- allowUnknown: true,
99
- // Schema ထဲမပါတဲ့ field တွေပါလာရင် လက်ခံရန်
100
- stripUnknown: true
101
- // Schema ထဲမပါတဲ့ field တွေကို ဖယ်ထုတ်ပစ်ရန်
102
- });
103
- if (error) {
104
- const errorMessage = error.details.map((detail) => detail.message.replace(/"/g, "")).join(", ");
105
- return next(new AppError_default(errorMessage, 400));
106
- }
107
- req.body = value;
108
- next();
109
- };
110
- var validate_default = validate;
111
-
112
- // src/utils/constants.js
113
- var PORT = process.env.PORT || 5e3;
114
- var STATUS_CODES = {
115
- // --- 2xx Success ---
116
- OK: 200,
117
- // Request အောင်မြင်သည်
118
- CREATED: 201,
119
- // Data အသစ် တည်ဆောက်မှု အောင်မြင်သည်
120
- ACCEPTED: 202,
121
- // လက်ခံရရှိသည် (နောက်မှ အလုပ်လုပ်မည်)
122
- NO_CONTENT: 204,
123
- // အောင်မြင်သည်၊ သို့သော် ပြစရာ Data မရှိ (ဥပမာ- Delete လုပ်ပြီးချိန်)
124
- // --- 3xx Redirection ---
125
- MOVED_PERMANENTLY: 301,
126
- FOUND: 302,
127
- // --- 4xx Client Errors ---
128
- BAD_REQUEST: 400,
129
- // ပေးပို့လိုက်သော Data Format မှားနေသည် (Validation error)
130
- UNAUTHORIZED: 401,
131
- // Login ဝင်ရန် လိုအပ်သည် (သို့မဟုတ် Token မှားသည်)
132
- FORBIDDEN: 403,
133
- // လုပ်ပိုင်ခွင့်မရှိ (ဥပမာ- Admin မဟုတ်ဘဲ Admin panel ဝင်ခြင်း)
134
- NOT_FOUND: 404,
135
- // ရှာဖွေနေသော Resource မရှိပါ
136
- METHOD_NOT_ALLOWED: 405,
137
- // API Method (GET, POST, etc.) မှားနေသည်
138
- CONFLICT: 409,
139
- // Data ထပ်နေသည် (ဥပမာ- ရှိပြီးသား Email နဲ့ Register လုပ်ခြင်း)
140
- UNPROCESSABLE_ENTITY: 422,
141
- // Validation Error များအတွက် အသုံးများသည်
142
- TOO_MANY_REQUESTS: 429,
143
- // API ကို ခဏခဏ ဆက်တိုက်ခေါ်ခြင်း (Rate limiting)
144
- // --- 5xx Server Errors ---
145
- INTERNAL_SERVER_ERROR: 500,
146
- // Server ထဲတွင် Code မှားယွင်းခြင်း
147
- NOT_IMPLEMENTED: 501,
148
- BAD_GATEWAY: 502,
149
- SERVICE_UNAVAILABLE: 503,
150
- // Server ခေတ္တပိတ်ထားသည်
151
- GATEWAY_TIMEOUT: 504,
152
- PORT
153
- };
154
- var constants_default = STATUS_CODES;
155
-
156
- // src/middleware/errorMiddleware.js
157
- var errorMiddleware = (err, req, res, next) => {
158
- err.statusCode = err.statusCode || constants_default.INTERNAL_SERVER_ERROR;
159
- err.status = err.status || "error";
160
- if (process.env.NODE_ENV === "development") {
161
- res.status(err.statusCode).json({
162
- status: err.status,
163
- error: err,
164
- message: err.message,
165
- stack: err.stack
166
- });
167
- } else {
168
- if (err.isOperational) {
169
- res.status(err.statusCode).json({
170
- status: err.status,
171
- message: err.message
172
- });
173
- } else {
174
- console.error("ERROR \u{1F4A5}", err);
175
- res.status(constants_default.INTERNAL_SERVER_ERROR).json({
176
- status: "error",
177
- message: "Something went very wrong!"
178
- });
179
- }
180
- }
181
- };
182
- var errorMiddleware_default = errorMiddleware;
183
-
184
- // src/utils/response.js
185
- var apiResponse = {
186
- // အောင်မြင်တဲ့ response ပေးပို့ရန်
187
- success: (res, data, message = "Success", statusCode = constants_default.OK) => {
188
- return res.status(statusCode).json({
189
- status: "success",
190
- message,
191
- data
192
- });
193
- },
194
- // Error response ပေးပို့ရန် (Operational error များအတွက်)
195
- error: (res, message = "Internal Server Error", statusCode = constants_default.INTERNAL_SERVER_ERROR) => {
196
- return res.status(statusCode).json({
197
- status: "error",
198
- message
199
- });
200
- }
201
- };
202
- var response_default = apiResponse;
203
-
204
- // src/utils/authHelper.js
205
- import bcrypt from "bcryptjs";
206
- import jwt2 from "jsonwebtoken";
207
- var hashPassword = async (password) => {
208
- const salt = await bcrypt.genSalt(10);
209
- return await bcrypt.hash(password, salt);
210
- };
211
- var comparePassword = async (password, hashedPassword) => {
212
- return await bcrypt.compare(password, hashedPassword);
213
- };
214
- var generateToken = (payload, res, options = {}) => {
215
- const secret = options.secret || process.env.JWT_SECRET;
216
- const expiresIn = options.expiresIn || "30d";
217
- const cookieName = options.cookieName || "jwt";
218
- const token = jwt2.sign(payload, secret, {
219
- expiresIn
220
- });
221
- const cookieOptions = {
222
- maxAge: options.maxAge || 30 * 24 * 60 * 60 * 1e3,
223
- // Default 30 days
224
- httpOnly: true,
225
- // JavaScript မှ ဖတ်မရအောင် (Prevent XSS)
226
- sameSite: process.env.NODE_ENV === "production" ? "none" : "lax",
227
- // CSRF Protection
228
- secure: process.env.NODE_ENV === "production",
229
- // Production တွင် HTTPS သုံးမှသာ အလုပ်လုပ်မည်
230
- ...options.extraCookieOptions
231
- // တခြား အပို options များရှိလျှင် ထည့်ရန်
232
- };
233
- res.cookie(cookieName, token, cookieOptions);
234
- return token;
235
- };
236
-
237
- // src/utils/uuid.js
238
- import crypto from "crypto";
239
- var generateUUID = () => {
240
- if (typeof crypto.randomUUID === "function") {
241
- return crypto.randomUUID();
242
- }
243
- return ("10000000-1000-4000-8000" + -1e11).replace(
244
- /[018]/g,
245
- (c) => (c ^ crypto.randomBytes(1).readUInt8() & 15 >> c / 4).toString(16)
246
- );
247
- };
248
- var uuid_default = generateUUID;
249
-
250
- // src/validations/user.schema.js
251
- import Joi from "joi";
252
- var userSchema = {
253
- // Standard Register Schema
254
- register: Joi.object({
255
- username: Joi.string().alphanum().min(3).max(30).required().messages({
256
- "string.min": "Username must be at least 3 characters long",
257
- "any.required": "Username is a required field"
258
- }),
259
- email: Joi.string().email({ minDomainSegments: 2, tlds: { allow: ["com", "net", "org"] } }).required().messages({
260
- "string.email": "Please provide a valid email address"
261
- }),
262
- password: Joi.string().min(8).required().messages({
263
- "string.min": "Password must be at least 8 characters long"
264
- }),
265
- confirmPassword: Joi.any().equal(Joi.ref("password")).required().messages({ "any.only": "Passwords do not match" }),
266
- role: Joi.string().valid("user", "admin").default("user")
267
- }),
268
- // Login Schema
269
- login: Joi.object({
270
- email: Joi.string().email().required(),
271
- password: Joi.string().required()
272
- }),
273
- // Password Update Schema
274
- updatePassword: Joi.object({
275
- currentPassword: Joi.string().required(),
276
- newPassword: Joi.string().min(8).required()
277
- }),
278
- /**
279
- * စိတ်ကြိုက် schema အသစ်ဆောက်ချင်ရင် သုံးရန် (Dynamic Flexibility)
280
- * @param {Object} schemaDefinition - Joi object definition
281
- */
282
- custom: (schemaDefinition) => Joi.object(schemaDefinition)
283
- };
284
- var user_schema_default = userSchema;
285
-
286
- // src/validations/common.schema.js
287
- import Joi2 from "joi";
288
- var commonSchema = {
289
- // MongoDB ObjectId စစ်ဆေးရန် (24 hex characters)
290
- objectId: Joi2.string().regex(/^[0-9a-fA-F]{24}$/).messages({
291
- "string.pattern.base": "Invalid ID format. Must be a valid ObjectId."
292
- }),
293
- // Pagination အတွက် (Query strings)
294
- pagination: Joi2.object({
295
- page: Joi2.number().integer().min(1).default(1),
296
- limit: Joi2.number().integer().min(1).max(100).default(10),
297
- sort: Joi2.string().optional(),
298
- fields: Joi2.string().optional()
299
- })
300
- };
301
- var common_schema_default = commonSchema;
302
-
303
- // src/validations/index.js
304
- var schemas = {
305
- user: user_schema_default,
306
- common: common_schema_default
307
- };
308
- var validations_default = schemas;
309
-
310
- // src/socket/index.js
311
- var socket_exports = {};
312
- __export(socket_exports, {
313
- getIO: () => getIO,
314
- initSocket: () => initSocket
315
- });
316
- import { Server } from "socket.io";
317
- import jwt3 from "jsonwebtoken";
318
- var io;
319
- var socketAuth = (secret) => {
320
- return (socket, next) => {
321
- var _a, _b;
322
- const token = ((_a = socket.handshake.auth) == null ? void 0 : _a.token) || ((_b = socket.handshake.headers) == null ? void 0 : _b.token);
323
- if (!token) {
324
- return next(new Error("Authentication error: Token missing"));
325
- }
326
- try {
327
- const decoded = jwt3.verify(token, secret || process.env.JWT_SECRET);
328
- socket.user = decoded;
329
- next();
330
- } catch (err) {
331
- next(new Error("Authentication error: Invalid token"));
332
- }
333
- };
334
- };
335
- var initSocket = (server, options = {}) => {
336
- io = new Server(server, {
337
- cors: {
338
- origin: options.origin || "*"
339
- },
340
- ...options
341
- });
342
- if (options.authRequired) {
343
- io.use(socketAuth(options.jwtSecret));
344
- }
345
- return io;
346
- };
347
- var getIO = () => {
348
- if (!io) throw new Error("Socket.io not initialized!");
349
- return io;
350
- };
351
- export {
352
- AppError_default as AppError,
353
- Joi3 as Joi,
354
- constants_default as STATUS_CODES,
355
- admin,
356
- response_default as apiResponse,
357
- auth,
358
- catchAsync_default as catchAsync,
359
- comparePassword,
360
- connection_default as connectDB,
361
- errorMiddleware_default as errorMiddleware,
362
- generateToken,
363
- uuid_default as generateUUID,
364
- hashPassword,
365
- validations_default as schemas,
366
- socket_exports as socket,
367
- validate_default as validate
368
- };
1
+ import{a as c}from"./chunk-B3SAPWGT.mjs";import d from"mongoose";var R=async e=>{e||(console.error("\u274C Error: MongoDB URL is required to connect to the database."),process.exit(1));try{let t=await d.connect(e);console.log(`\u2705 MongoDB Connected: ${t.connection.host}`)}catch(t){console.error(`\u274C Error: ${t.message}`),process.exit(1)}},T=R;import O from"jsonwebtoken";var f=e=>(t,o,r)=>{e(t,o,r).catch(r)},m=f;var N=(e=process.env.JWT_SECRET,t={})=>m(async(o,r,n)=>{let a;if(o.headers.authorization&&o.headers.authorization.startsWith("Bearer")?a=o.headers.authorization.split(" ")[1]:o.cookies&&o.cookies[t.cookieName||"jwt"]&&(a=o.cookies[t.cookieName||"jwt"]),!e)return n(new c("JWT Secret is not defined in environment variables",500));if(!a)return n(new c("You are not logged in! Please log in to get access.",401));try{let i=O.verify(a,e);o.user=i,n()}catch{return n(new c("Invalid token or expired. Please log in again.",401))}}),l=(e,t,o)=>{if(e.user&&e.user.role==="admin")o();else return o(new c("You do not have permission to perform this action",403))};var A=process.env.PORT||5e3,S={OK:200,CREATED:201,ACCEPTED:202,NO_CONTENT:204,MOVED_PERMANENTLY:301,FOUND:302,BAD_REQUEST:400,UNAUTHORIZED:401,FORBIDDEN:403,NOT_FOUND:404,METHOD_NOT_ALLOWED:405,CONFLICT:409,UNPROCESSABLE_ENTITY:422,TOO_MANY_REQUESTS:429,INTERNAL_SERVER_ERROR:500,NOT_IMPLEMENTED:501,BAD_GATEWAY:502,SERVICE_UNAVAILABLE:503,GATEWAY_TIMEOUT:504,PORT:A},s=S;var _=(e,t,o,r)=>{e.statusCode=e.statusCode||s.INTERNAL_SERVER_ERROR,e.status=e.status||"error",process.env.NODE_ENV==="development"?o.status(e.statusCode).json({status:e.status,error:e,message:e.message,stack:e.stack}):e.isOperational?o.status(e.statusCode).json({status:e.status,message:e.message}):(console.error("ERROR \u{1F4A5}",e),o.status(s.INTERNAL_SERVER_ERROR).json({status:"error",message:"Something went very wrong!"}))},g=_;var D={success:(e,t,o="Success",r=s.OK)=>e.status(r).json({status:"success",message:o,data:t}),error:(e,t="Internal Server Error",o=s.INTERNAL_SERVER_ERROR)=>e.status(o).json({status:"error",message:t})},h=D;import E from"bcryptjs";import U from"jsonwebtoken";var I=async e=>{let t=await E.genSalt(10);return await E.hash(e,t)},w=async(e,t)=>await E.compare(e,t),C=(e,t,o={})=>{let r=o.secret||process.env.JWT_SECRET,n=o.expiresIn||"30d",a=o.cookieName||"jwt",i=U.sign(e,r,{expiresIn:n}),u={maxAge:o.maxAge||720*60*60*1e3,httpOnly:!0,sameSite:process.env.NODE_ENV==="production"?"none":"lax",secure:process.env.NODE_ENV==="production",...o.extraCookieOptions};return t.cookie(a,i,u),i};import p from"crypto";var x=()=>typeof p.randomUUID=="function"?p.randomUUID():("10000000-1000-4000-8000"+-1e11).replace(/[018]/g,e=>(e^p.randomBytes(1).readUInt8()&15>>e/4).toString(16)),k=x;export{c as AppError,s as STATUS_CODES,l as admin,h as apiResponse,N as auth,m as catchAsync,w as comparePassword,T as connectDB,g as errorMiddleware,C as generateToken,k as generateUUID,I as hashPassword};
@@ -0,0 +1,55 @@
1
+ import { Server } from 'socket.io';
2
+ import jwt from 'jsonwebtoken';
3
+
4
+ let io;
5
+
6
+ /**
7
+ * Socket Authentication Middleware
8
+ */
9
+ const socketAuth = (secret) => {
10
+ return (socket, next) => {
11
+ const token =
12
+ socket.handshake.auth?.token || socket.handshake.headers?.token;
13
+
14
+ if (!token) {
15
+ return next(new Error("Authentication error: Token missing"));
16
+ }
17
+
18
+ try {
19
+ const decoded = jwt.verify(token, secret || process.env.JWT_SECRET);
20
+ socket.user = decoded; // socket ထဲမှာ user data သိမ်းထားမယ်
21
+ next();
22
+ } catch (err) {
23
+ next(new Error("Authentication error: Invalid token"));
24
+ }
25
+ };
26
+ };
27
+
28
+ /**
29
+ * Socket Initialize လုပ်ခြင်း
30
+ */
31
+ const initSocket = (server, options = {}) => {
32
+ io = new Server(server, {
33
+ cors: {
34
+ origin: options.origin || "*",
35
+ },
36
+ ...options,
37
+ });
38
+
39
+ // JWT Middleware ကို အသုံးပြုခြင်း
40
+ if (options.authRequired) {
41
+ io.use(socketAuth(options.jwtSecret));
42
+ }
43
+
44
+ return io;
45
+ };
46
+
47
+ /**
48
+ * Initialize ပြီးသား IO object ကို ပြန်ယူခြင်း
49
+ */
50
+ const getIO = () => {
51
+ if (!io) throw new Error("Socket.io not initialized!");
52
+ return io;
53
+ };
54
+
55
+ export { getIO, initSocket };
@@ -0,0 +1,55 @@
1
+ import { Server } from 'socket.io';
2
+ import jwt from 'jsonwebtoken';
3
+
4
+ let io;
5
+
6
+ /**
7
+ * Socket Authentication Middleware
8
+ */
9
+ const socketAuth = (secret) => {
10
+ return (socket, next) => {
11
+ const token =
12
+ socket.handshake.auth?.token || socket.handshake.headers?.token;
13
+
14
+ if (!token) {
15
+ return next(new Error("Authentication error: Token missing"));
16
+ }
17
+
18
+ try {
19
+ const decoded = jwt.verify(token, secret || process.env.JWT_SECRET);
20
+ socket.user = decoded; // socket ထဲမှာ user data သိမ်းထားမယ်
21
+ next();
22
+ } catch (err) {
23
+ next(new Error("Authentication error: Invalid token"));
24
+ }
25
+ };
26
+ };
27
+
28
+ /**
29
+ * Socket Initialize လုပ်ခြင်း
30
+ */
31
+ const initSocket = (server, options = {}) => {
32
+ io = new Server(server, {
33
+ cors: {
34
+ origin: options.origin || "*",
35
+ },
36
+ ...options,
37
+ });
38
+
39
+ // JWT Middleware ကို အသုံးပြုခြင်း
40
+ if (options.authRequired) {
41
+ io.use(socketAuth(options.jwtSecret));
42
+ }
43
+
44
+ return io;
45
+ };
46
+
47
+ /**
48
+ * Initialize ပြီးသား IO object ကို ပြန်ယူခြင်း
49
+ */
50
+ const getIO = () => {
51
+ if (!io) throw new Error("Socket.io not initialized!");
52
+ return io;
53
+ };
54
+
55
+ export { getIO, initSocket };
package/dist/socket.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var _socketio = require('socket.io');var _jsonwebtoken = require('jsonwebtoken'); var _jsonwebtoken2 = _interopRequireDefault(_jsonwebtoken);var e,s=t=>(r,o)=>{var i,c;let n=((i=r.handshake.auth)==null?void 0:i.token)||((c=r.handshake.headers)==null?void 0:c.token);if(!n)return o(new Error("Authentication error: Token missing"));try{let a=_jsonwebtoken2.default.verify(n,t||process.env.JWT_SECRET);r.user=a,o()}catch (e2){o(new Error("Authentication error: Invalid token"))}},f= exports.initSocket =(t,r={})=>(e=new (0, _socketio.Server)(t,{cors:{origin:r.origin||"*"},...r}),r.authRequired&&e.use(s(r.jwtSecret)),e),w= exports.getIO =()=>{if(!e)throw new Error("Socket.io not initialized!");return e};exports.getIO = w; exports.initSocket = f;
@@ -0,0 +1 @@
1
+ import{Server as h}from"socket.io";import u from"jsonwebtoken";var e,s=t=>(r,o)=>{var i,c;let n=((i=r.handshake.auth)==null?void 0:i.token)||((c=r.handshake.headers)==null?void 0:c.token);if(!n)return o(new Error("Authentication error: Token missing"));try{let a=u.verify(n,t||process.env.JWT_SECRET);r.user=a,o()}catch{o(new Error("Authentication error: Invalid token"))}},f=(t,r={})=>(e=new h(t,{cors:{origin:r.origin||"*"},...r}),r.authRequired&&e.use(s(r.jwtSecret)),e),w=()=>{if(!e)throw new Error("Socket.io not initialized!");return e};export{w as getIO,f as initSocket};
@@ -0,0 +1,101 @@
1
+ import Joi from 'joi';
2
+ export { default as Joi } from 'joi';
3
+ import { A as AppError } from './AppError-ByGDb4IL.mjs';
4
+
5
+ /**
6
+ * Joi Schema Validation Middleware
7
+ * @param {Object} schema - Joi validation schema
8
+ */
9
+ const validate = (schema) => (req, res, next) => {
10
+ // body, query, params အားလုံးကို စစ်လို့ရအောင် req object တစ်ခုလုံးကို schema နဲ့ တိုက်စစ်မယ်
11
+ const { error, value } = schema.validate(req.body, {
12
+ abortEarly: false, // Error အားလုံးကို တစ်ခါတည်း ပြရန်
13
+ allowUnknown: true, // Schema ထဲမပါတဲ့ field တွေပါလာရင် လက်ခံရန်
14
+ stripUnknown: true, // Schema ထဲမပါတဲ့ field တွေကို ဖယ်ထုတ်ပစ်ရန်
15
+ });
16
+
17
+ if (error) {
18
+ // Error message တွေကို စုစည်းပြီး format လုပ်မယ်
19
+ const errorMessage = error.details
20
+ .map((detail) => detail.message.replace(/"/g, ""))
21
+ .join(", ");
22
+
23
+ return next(new AppError(errorMessage, 400));
24
+ }
25
+
26
+ // စစ်ဆေးပြီးသား data (sanitized data) ကို req.body ထဲ ပြန်ထည့်မယ်
27
+ req.body = value;
28
+ next();
29
+ };
30
+
31
+ /**
32
+ * User Validation Schemas
33
+ */
34
+ const userSchema = {
35
+ // Standard Register Schema
36
+ register: Joi.object({
37
+ username: Joi.string().alphanum().min(3).max(30).required().messages({
38
+ "string.min": "Username must be at least 3 characters long",
39
+ "any.required": "Username is a required field",
40
+ }),
41
+ email: Joi.string()
42
+ .email({ minDomainSegments: 2, tlds: { allow: ["com", "net", "org"] } })
43
+ .required()
44
+ .messages({
45
+ "string.email": "Please provide a valid email address",
46
+ }),
47
+ password: Joi.string().min(8).required().messages({
48
+ "string.min": "Password must be at least 8 characters long",
49
+ }),
50
+ confirmPassword: Joi.any()
51
+ .equal(Joi.ref("password"))
52
+ .required()
53
+ .messages({ "any.only": "Passwords do not match" }),
54
+ role: Joi.string().valid("user", "admin").default("user"),
55
+ }),
56
+
57
+ // Login Schema
58
+ login: Joi.object({
59
+ email: Joi.string().email().required(),
60
+ password: Joi.string().required(),
61
+ }),
62
+
63
+ // Password Update Schema
64
+ updatePassword: Joi.object({
65
+ currentPassword: Joi.string().required(),
66
+ newPassword: Joi.string().min(8).required(),
67
+ }),
68
+
69
+ /**
70
+ * စိတ်ကြိုက် schema အသစ်ဆောက်ချင်ရင် သုံးရန် (Dynamic Flexibility)
71
+ * @param {Object} schemaDefinition - Joi object definition
72
+ */
73
+ custom: (schemaDefinition) => Joi.object(schemaDefinition),
74
+ };
75
+
76
+ /**
77
+ * Common Joi Schemas
78
+ */
79
+ const commonSchema = {
80
+ // MongoDB ObjectId စစ်ဆေးရန် (24 hex characters)
81
+ objectId: Joi.string()
82
+ .regex(/^[0-9a-fA-F]{24}$/)
83
+ .messages({
84
+ "string.pattern.base": "Invalid ID format. Must be a valid ObjectId.",
85
+ }),
86
+
87
+ // Pagination အတွက် (Query strings)
88
+ pagination: Joi.object({
89
+ page: Joi.number().integer().min(1).default(1),
90
+ limit: Joi.number().integer().min(1).max(100).default(10),
91
+ sort: Joi.string().optional(),
92
+ fields: Joi.string().optional(),
93
+ }),
94
+ };
95
+
96
+ const schemas = {
97
+ user: userSchema,
98
+ common: commonSchema,
99
+ };
100
+
101
+ export { schemas as default, schemas, validate };
@@ -0,0 +1,101 @@
1
+ import Joi from 'joi';
2
+ export { default as Joi } from 'joi';
3
+ import { A as AppError } from './AppError-ByGDb4IL.js';
4
+
5
+ /**
6
+ * Joi Schema Validation Middleware
7
+ * @param {Object} schema - Joi validation schema
8
+ */
9
+ const validate = (schema) => (req, res, next) => {
10
+ // body, query, params အားလုံးကို စစ်လို့ရအောင် req object တစ်ခုလုံးကို schema နဲ့ တိုက်စစ်မယ်
11
+ const { error, value } = schema.validate(req.body, {
12
+ abortEarly: false, // Error အားလုံးကို တစ်ခါတည်း ပြရန်
13
+ allowUnknown: true, // Schema ထဲမပါတဲ့ field တွေပါလာရင် လက်ခံရန်
14
+ stripUnknown: true, // Schema ထဲမပါတဲ့ field တွေကို ဖယ်ထုတ်ပစ်ရန်
15
+ });
16
+
17
+ if (error) {
18
+ // Error message တွေကို စုစည်းပြီး format လုပ်မယ်
19
+ const errorMessage = error.details
20
+ .map((detail) => detail.message.replace(/"/g, ""))
21
+ .join(", ");
22
+
23
+ return next(new AppError(errorMessage, 400));
24
+ }
25
+
26
+ // စစ်ဆေးပြီးသား data (sanitized data) ကို req.body ထဲ ပြန်ထည့်မယ်
27
+ req.body = value;
28
+ next();
29
+ };
30
+
31
+ /**
32
+ * User Validation Schemas
33
+ */
34
+ const userSchema = {
35
+ // Standard Register Schema
36
+ register: Joi.object({
37
+ username: Joi.string().alphanum().min(3).max(30).required().messages({
38
+ "string.min": "Username must be at least 3 characters long",
39
+ "any.required": "Username is a required field",
40
+ }),
41
+ email: Joi.string()
42
+ .email({ minDomainSegments: 2, tlds: { allow: ["com", "net", "org"] } })
43
+ .required()
44
+ .messages({
45
+ "string.email": "Please provide a valid email address",
46
+ }),
47
+ password: Joi.string().min(8).required().messages({
48
+ "string.min": "Password must be at least 8 characters long",
49
+ }),
50
+ confirmPassword: Joi.any()
51
+ .equal(Joi.ref("password"))
52
+ .required()
53
+ .messages({ "any.only": "Passwords do not match" }),
54
+ role: Joi.string().valid("user", "admin").default("user"),
55
+ }),
56
+
57
+ // Login Schema
58
+ login: Joi.object({
59
+ email: Joi.string().email().required(),
60
+ password: Joi.string().required(),
61
+ }),
62
+
63
+ // Password Update Schema
64
+ updatePassword: Joi.object({
65
+ currentPassword: Joi.string().required(),
66
+ newPassword: Joi.string().min(8).required(),
67
+ }),
68
+
69
+ /**
70
+ * စိတ်ကြိုက် schema အသစ်ဆောက်ချင်ရင် သုံးရန် (Dynamic Flexibility)
71
+ * @param {Object} schemaDefinition - Joi object definition
72
+ */
73
+ custom: (schemaDefinition) => Joi.object(schemaDefinition),
74
+ };
75
+
76
+ /**
77
+ * Common Joi Schemas
78
+ */
79
+ const commonSchema = {
80
+ // MongoDB ObjectId စစ်ဆေးရန် (24 hex characters)
81
+ objectId: Joi.string()
82
+ .regex(/^[0-9a-fA-F]{24}$/)
83
+ .messages({
84
+ "string.pattern.base": "Invalid ID format. Must be a valid ObjectId.",
85
+ }),
86
+
87
+ // Pagination အတွက် (Query strings)
88
+ pagination: Joi.object({
89
+ page: Joi.number().integer().min(1).default(1),
90
+ limit: Joi.number().integer().min(1).max(100).default(10),
91
+ sort: Joi.string().optional(),
92
+ fields: Joi.string().optional(),
93
+ }),
94
+ };
95
+
96
+ const schemas = {
97
+ user: userSchema,
98
+ common: commonSchema,
99
+ };
100
+
101
+ export { schemas as default, schemas, validate };