3a-ecommerce-utils 1.0.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/README.md +163 -0
- package/dist/chunk-PEAZVBSD.mjs +597 -0
- package/dist/client-DYGi_pyp.d.mts +87 -0
- package/dist/client-DYGi_pyp.d.ts +87 -0
- package/dist/index.d.mts +496 -0
- package/dist/index.d.ts +496 -0
- package/dist/index.js +17707 -0
- package/dist/index.mjs +17043 -0
- package/dist/validation/server.d.mts +50 -0
- package/dist/validation/server.d.ts +50 -0
- package/dist/validation/server.js +518 -0
- package/dist/validation/server.mjs +168 -0
- package/package.json +69 -0
- package/src/api/address.queries.ts +96 -0
- package/src/api/category.queries.ts +85 -0
- package/src/api/coupon.queries.ts +120 -0
- package/src/api/dashboard.queries.ts +35 -0
- package/src/api/errorHandler.ts +164 -0
- package/src/api/graphqlClient.ts +113 -0
- package/src/api/index.ts +10 -0
- package/src/api/logger.client.ts +89 -0
- package/src/api/logger.ts +135 -0
- package/src/api/order.queries.ts +211 -0
- package/src/api/product.queries.ts +144 -0
- package/src/api/review.queries.ts +56 -0
- package/src/api/user.queries.ts +232 -0
- package/src/assets/3A.png +0 -0
- package/src/assets/index.ts +1 -0
- package/src/assets.d.ts +29 -0
- package/src/auth.ts +176 -0
- package/src/config/jest.backend.config.js +42 -0
- package/src/config/jest.frontend.config.js +50 -0
- package/src/config/postcss.config.js +6 -0
- package/src/config/tailwind.config.ts +70 -0
- package/src/config/tsconfig.base.json +36 -0
- package/src/config/vite.config.ts +86 -0
- package/src/config/vitest.base.config.ts +74 -0
- package/src/config/webpack.base.config.ts +126 -0
- package/src/constants/index.ts +312 -0
- package/src/cookies.ts +104 -0
- package/src/helpers.ts +400 -0
- package/src/index.ts +32 -0
- package/src/validation/client.ts +287 -0
- package/src/validation/index.ts +3 -0
- package/src/validation/server.ts +32 -0
|
@@ -0,0 +1,597 @@
|
|
|
1
|
+
var __create = Object.create;
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
8
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
9
|
+
}) : x)(function(x) {
|
|
10
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
11
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
12
|
+
});
|
|
13
|
+
var __commonJS = (cb, mod) => function __require2() {
|
|
14
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
15
|
+
};
|
|
16
|
+
var __export = (target, all) => {
|
|
17
|
+
for (var name in all)
|
|
18
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
19
|
+
};
|
|
20
|
+
var __copyProps = (to, from, except, desc) => {
|
|
21
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
22
|
+
for (let key of __getOwnPropNames(from))
|
|
23
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
24
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
25
|
+
}
|
|
26
|
+
return to;
|
|
27
|
+
};
|
|
28
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
29
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
30
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
31
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
32
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
33
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
34
|
+
mod
|
|
35
|
+
));
|
|
36
|
+
|
|
37
|
+
// src/constants/index.ts
|
|
38
|
+
var SHELL_APP_URL = "http://localhost:3000";
|
|
39
|
+
var ADMIN_APP_URL = "http://localhost:3001";
|
|
40
|
+
var SELLER_APP_URL = "http://localhost:3002";
|
|
41
|
+
var STOREFRONT_APP_URL = "http://localhost:3003";
|
|
42
|
+
var PORT_CONFIG = {
|
|
43
|
+
AUTH_SERVICE: 3011,
|
|
44
|
+
CATEGORY_SERVICE: 3012,
|
|
45
|
+
COUPON_SERVICE: 3013,
|
|
46
|
+
PRODUCT_SERVICE: 3014,
|
|
47
|
+
ORDER_SERVICE: 3015,
|
|
48
|
+
GRAPHQL_GATEWAY: 4e3,
|
|
49
|
+
STOREFRONT_APP: 3e3,
|
|
50
|
+
ADMIN_APP: 3001,
|
|
51
|
+
SELLER_APP: 3002,
|
|
52
|
+
SHELL_APP: 3003
|
|
53
|
+
};
|
|
54
|
+
var SERVICE_URLS = {
|
|
55
|
+
AUTH_SERVICE: `http://localhost:${PORT_CONFIG.AUTH_SERVICE}`,
|
|
56
|
+
CATEGORY_SERVICE: `http://localhost:${PORT_CONFIG.CATEGORY_SERVICE}`,
|
|
57
|
+
COUPON_SERVICE: `http://localhost:${PORT_CONFIG.COUPON_SERVICE}`,
|
|
58
|
+
PRODUCT_SERVICE: `http://localhost:${PORT_CONFIG.PRODUCT_SERVICE}`,
|
|
59
|
+
ORDER_SERVICE: `http://localhost:${PORT_CONFIG.ORDER_SERVICE}`,
|
|
60
|
+
GRAPHQL_GATEWAY: `http://localhost:${PORT_CONFIG.GRAPHQL_GATEWAY}/graphql`,
|
|
61
|
+
AUTH_API: `http://localhost:${PORT_CONFIG.AUTH_SERVICE}/api`,
|
|
62
|
+
CATEGORY_API: `http://localhost:${PORT_CONFIG.CATEGORY_SERVICE}/api`,
|
|
63
|
+
COUPON_API: `http://localhost:${PORT_CONFIG.COUPON_SERVICE}/api`,
|
|
64
|
+
PRODUCT_API: `http://localhost:${PORT_CONFIG.PRODUCT_SERVICE}/api`,
|
|
65
|
+
ORDER_API: `http://localhost:${PORT_CONFIG.ORDER_SERVICE}/api`
|
|
66
|
+
};
|
|
67
|
+
var DATABASE_CONFIG = {
|
|
68
|
+
MONGODB_URI: "mongodb+srv://admin:admin@cluster0.wei5wdz.mongodb.net/ecommerce?appName=Cluster0",
|
|
69
|
+
REDIS_URL: "redis://localhost:6379"
|
|
70
|
+
};
|
|
71
|
+
var DEFAULT_CORS_ORIGINS = [
|
|
72
|
+
"http://localhost:3000",
|
|
73
|
+
"http://localhost:3001",
|
|
74
|
+
"http://localhost:3002",
|
|
75
|
+
"http://localhost:3003"
|
|
76
|
+
];
|
|
77
|
+
var JWT_CONFIG = {
|
|
78
|
+
ACCESS_TOKEN_EXPIRY: "1h",
|
|
79
|
+
REFRESH_TOKEN_EXPIRY: "7d",
|
|
80
|
+
PASSWORD_MIN_LENGTH: 8,
|
|
81
|
+
PASSWORD_PATTERN: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$/
|
|
82
|
+
};
|
|
83
|
+
var PAGINATION = {
|
|
84
|
+
DEFAULT_PAGE: 1,
|
|
85
|
+
DEFAULT_LIMIT: 10,
|
|
86
|
+
DEFAULT_PAGE_SIZE: 20,
|
|
87
|
+
MAX_PAGE_SIZE: 100,
|
|
88
|
+
MIN_PAGE_SIZE: 1,
|
|
89
|
+
DEFAULT_SORT_BY: "createdAt",
|
|
90
|
+
DEFAULT_SORT_ORDER: "DESC"
|
|
91
|
+
};
|
|
92
|
+
var PRODUCT_CONFIG = {
|
|
93
|
+
MIN_PRICE: 0,
|
|
94
|
+
MAX_PRICE: 999999.99,
|
|
95
|
+
MIN_STOCK: 0,
|
|
96
|
+
MAX_RATING: 5,
|
|
97
|
+
MIN_RATING: 0,
|
|
98
|
+
DEFAULT_RATING: 0,
|
|
99
|
+
MAX_IMAGE_SIZE: 5 * 1024 * 1024,
|
|
100
|
+
// 5MB
|
|
101
|
+
ALLOWED_IMAGE_TYPES: ["image/jpeg", "image/png", "image/webp"]
|
|
102
|
+
};
|
|
103
|
+
var ORDER_CONFIG = {
|
|
104
|
+
TAX_RATE: 0.1,
|
|
105
|
+
// 10% tax
|
|
106
|
+
SHIPPING_COST_STANDARD: 50,
|
|
107
|
+
SHIPPING_COST_EXPRESS: 150,
|
|
108
|
+
SHIPPING_COST_OVERNIGHT: 300,
|
|
109
|
+
MIN_ORDER_AMOUNT: 0,
|
|
110
|
+
MAX_ORDER_ITEMS: 1e3
|
|
111
|
+
};
|
|
112
|
+
var COUPON_CONFIG = {
|
|
113
|
+
CODE_LENGTH: 6,
|
|
114
|
+
CODE_UPPERCASE: true,
|
|
115
|
+
MAX_DISCOUNT_PERCENTAGE: 100,
|
|
116
|
+
MAX_DISCOUNT_FIXED: 999999.99,
|
|
117
|
+
MIN_PURCHASE_REQUIRED: 0
|
|
118
|
+
};
|
|
119
|
+
var API_ENDPOINTS = {
|
|
120
|
+
AUTH: {
|
|
121
|
+
LOGIN: "/api/auth/login",
|
|
122
|
+
REGISTER: "/api/auth/register",
|
|
123
|
+
LOGOUT: "/api/auth/logout",
|
|
124
|
+
PROFILE: "/api/auth/profile",
|
|
125
|
+
REFRESH: "/api/auth/refresh",
|
|
126
|
+
VERIFY: "/api/auth/verify"
|
|
127
|
+
},
|
|
128
|
+
PRODUCTS: {
|
|
129
|
+
LIST: "/api/products",
|
|
130
|
+
CREATE: "/api/products",
|
|
131
|
+
GET: "/api/products/:id",
|
|
132
|
+
UPDATE: "/api/products/:id",
|
|
133
|
+
DELETE: "/api/products/:id",
|
|
134
|
+
SEARCH: "/api/products/search"
|
|
135
|
+
},
|
|
136
|
+
ORDERS: {
|
|
137
|
+
LIST: "/api/orders",
|
|
138
|
+
CREATE: "/api/orders",
|
|
139
|
+
GET: "/api/orders/:id",
|
|
140
|
+
UPDATE: "/api/orders/:id",
|
|
141
|
+
CANCEL: "/api/orders/:id/cancel",
|
|
142
|
+
TRACK: "/api/orders/:id/track"
|
|
143
|
+
},
|
|
144
|
+
CATEGORIES: {
|
|
145
|
+
LIST: "/api/categories",
|
|
146
|
+
CREATE: "/api/categories",
|
|
147
|
+
GET: "/api/categories/:id",
|
|
148
|
+
UPDATE: "/api/categories/:id",
|
|
149
|
+
DELETE: "/api/categories/:id"
|
|
150
|
+
},
|
|
151
|
+
COUPONS: {
|
|
152
|
+
LIST: "/api/coupons",
|
|
153
|
+
CREATE: "/api/coupons",
|
|
154
|
+
GET: "/api/coupons/:id",
|
|
155
|
+
UPDATE: "/api/coupons/:id",
|
|
156
|
+
DELETE: "/api/coupons/:id",
|
|
157
|
+
VALIDATE: "/api/coupons/validate/:code"
|
|
158
|
+
}
|
|
159
|
+
};
|
|
160
|
+
var HTTP_STATUS = {
|
|
161
|
+
OK: 200,
|
|
162
|
+
CREATED: 201,
|
|
163
|
+
NO_CONTENT: 204,
|
|
164
|
+
BAD_REQUEST: 400,
|
|
165
|
+
UNAUTHORIZED: 401,
|
|
166
|
+
FORBIDDEN: 403,
|
|
167
|
+
NOT_FOUND: 404,
|
|
168
|
+
CONFLICT: 409,
|
|
169
|
+
UNPROCESSABLE_ENTITY: 422,
|
|
170
|
+
INTERNAL_SERVER_ERROR: 500,
|
|
171
|
+
SERVICE_UNAVAILABLE: 503
|
|
172
|
+
};
|
|
173
|
+
var ERROR_MESSAGES = {
|
|
174
|
+
// Auth errors
|
|
175
|
+
UNAUTHORIZED: "Unauthorized access",
|
|
176
|
+
FORBIDDEN: "Forbidden access",
|
|
177
|
+
NO_TOKEN: "No token provided. Access denied.",
|
|
178
|
+
INVALID_TOKEN: "Invalid or expired token",
|
|
179
|
+
INVALID_CREDENTIALS: "Invalid email or password",
|
|
180
|
+
USER_EXISTS: "User with this email already exists",
|
|
181
|
+
USER_NOT_FOUND: "User not found",
|
|
182
|
+
ACCOUNT_DEACTIVATED: "Account is deactivated. Please contact support.",
|
|
183
|
+
EMAIL_PASSWORD_MISMATCH: "Email and password does not match.",
|
|
184
|
+
// General errors
|
|
185
|
+
NOT_FOUND: "Resource not found",
|
|
186
|
+
VALIDATION_FAILED: "Validation failed",
|
|
187
|
+
INTERNAL_ERROR: "Internal server error",
|
|
188
|
+
SERVICE_UNAVAILABLE: "Service temporarily unavailable",
|
|
189
|
+
FAILED_TO_FETCH: "Failed to fetch data",
|
|
190
|
+
// Product errors
|
|
191
|
+
PRODUCT_NOT_FOUND: "Product not found",
|
|
192
|
+
INSUFFICIENT_STOCK: "Insufficient stock available",
|
|
193
|
+
FAILED_TO_GET_PRODUCTS: "Failed to get products",
|
|
194
|
+
FAILED_TO_CREATE_PRODUCT: "Failed to create product",
|
|
195
|
+
FAILED_TO_UPDATE_PRODUCT: "Failed to update product",
|
|
196
|
+
FAILED_TO_DELETE_PRODUCT: "Failed to delete product",
|
|
197
|
+
// Category errors
|
|
198
|
+
CATEGORY_NOT_FOUND: "Category not found",
|
|
199
|
+
FAILED_TO_GET_CATEGORIES: "Failed to get categories",
|
|
200
|
+
FAILED_TO_CREATE_CATEGORY: "Failed to create category",
|
|
201
|
+
FAILED_TO_UPDATE_CATEGORY: "Failed to update category",
|
|
202
|
+
FAILED_TO_DELETE_CATEGORY: "Failed to delete category",
|
|
203
|
+
// Order errors
|
|
204
|
+
ORDER_NOT_FOUND: "Order not found",
|
|
205
|
+
INVALID_ORDER_STATUS: "Invalid order status",
|
|
206
|
+
FAILED_TO_GET_ORDERS: "Failed to get orders",
|
|
207
|
+
FAILED_TO_CREATE_ORDER: "Failed to create order",
|
|
208
|
+
FAILED_TO_UPDATE_ORDER: "Failed to update order",
|
|
209
|
+
// Coupon errors
|
|
210
|
+
INVALID_COUPON: "Invalid or expired coupon",
|
|
211
|
+
COUPON_NOT_FOUND: "Coupon not found",
|
|
212
|
+
COUPON_EXPIRED: "Coupon has expired",
|
|
213
|
+
COUPON_LIMIT_REACHED: "Coupon usage limit reached",
|
|
214
|
+
FAILED_TO_GET_COUPONS: "Failed to get coupons",
|
|
215
|
+
FAILED_TO_CREATE_COUPON: "Failed to create coupon",
|
|
216
|
+
FAILED_TO_UPDATE_COUPON: "Failed to update coupon",
|
|
217
|
+
FAILED_TO_DELETE_COUPON: "Failed to delete coupon",
|
|
218
|
+
// Review errors
|
|
219
|
+
REVIEW_NOT_FOUND: "Review not found",
|
|
220
|
+
DUPLICATE_REVIEW: "You have already reviewed this product",
|
|
221
|
+
OWN_REVIEW_ONLY: "You can only delete your own reviews",
|
|
222
|
+
FAILED_TO_GET_REVIEWS: "Failed to get reviews",
|
|
223
|
+
FAILED_TO_CREATE_REVIEW: "Failed to create review",
|
|
224
|
+
FAILED_TO_DELETE_REVIEW: "Failed to delete review",
|
|
225
|
+
// Address errors
|
|
226
|
+
ADDRESS_NOT_FOUND: "Address not found",
|
|
227
|
+
FAILED_TO_GET_ADDRESSES: "Failed to get addresses"
|
|
228
|
+
};
|
|
229
|
+
var SUCCESS_MESSAGES = {
|
|
230
|
+
// General
|
|
231
|
+
CREATED: "Resource created successfully",
|
|
232
|
+
UPDATED: "Resource updated successfully",
|
|
233
|
+
DELETED: "Resource deleted successfully",
|
|
234
|
+
FETCHED: "Data fetched successfully",
|
|
235
|
+
// Auth
|
|
236
|
+
USER_REGISTERED: "User registered successfully",
|
|
237
|
+
LOGIN_SUCCESS: "Login successful",
|
|
238
|
+
LOGOUT_SUCCESS: "Logout successful",
|
|
239
|
+
PROFILE_UPDATED: "Profile updated successfully",
|
|
240
|
+
PASSWORD_CHANGED: "Password changed successfully",
|
|
241
|
+
// Product
|
|
242
|
+
PRODUCT_CREATED: "Product created successfully",
|
|
243
|
+
PRODUCT_UPDATED: "Product updated successfully",
|
|
244
|
+
PRODUCT_DELETED: "Product deleted successfully",
|
|
245
|
+
// Category
|
|
246
|
+
CATEGORY_CREATED: "Category created successfully",
|
|
247
|
+
CATEGORY_UPDATED: "Category updated successfully",
|
|
248
|
+
CATEGORY_DELETED: "Category deleted successfully",
|
|
249
|
+
// Order
|
|
250
|
+
ORDER_PLACED: "Order placed successfully",
|
|
251
|
+
ORDER_UPDATED: "Order updated successfully",
|
|
252
|
+
ORDER_CANCELLED: "Order cancelled successfully",
|
|
253
|
+
// Coupon
|
|
254
|
+
COUPON_CREATED: "Coupon created successfully",
|
|
255
|
+
COUPON_UPDATED: "Coupon updated successfully",
|
|
256
|
+
COUPON_DELETED: "Coupon deleted successfully",
|
|
257
|
+
COUPON_APPLIED: "Coupon applied successfully",
|
|
258
|
+
// Review
|
|
259
|
+
REVIEW_SUBMITTED: "Review submitted successfully",
|
|
260
|
+
REVIEW_DELETED: "Review deleted successfully",
|
|
261
|
+
// Payment
|
|
262
|
+
PAYMENT_SUCCESSFUL: "Payment processed successfully"
|
|
263
|
+
};
|
|
264
|
+
var CACHE_CONFIG = {
|
|
265
|
+
DASHBOARD_STATS_TTL: 3e4,
|
|
266
|
+
// 30 seconds
|
|
267
|
+
DASHBOARD_STATS_REFETCH: 6e4,
|
|
268
|
+
// 1 minute
|
|
269
|
+
PRODUCTS_TTL: 6e4,
|
|
270
|
+
// 1 minute
|
|
271
|
+
CATEGORIES_TTL: 12e4,
|
|
272
|
+
// 2 minutes
|
|
273
|
+
USER_PROFILE_TTL: 3e5,
|
|
274
|
+
// 5 minutes
|
|
275
|
+
ORDERS_TTL: 3e4
|
|
276
|
+
// 30 seconds
|
|
277
|
+
};
|
|
278
|
+
var TIMEOUT_CONFIG = {
|
|
279
|
+
API_REQUEST: 3e4,
|
|
280
|
+
// 30 seconds
|
|
281
|
+
DATABASE: 1e4,
|
|
282
|
+
// 10 seconds
|
|
283
|
+
GRAPHQL: 15e3
|
|
284
|
+
// 15 seconds
|
|
285
|
+
};
|
|
286
|
+
var REGEX_PATTERNS = {
|
|
287
|
+
EMAIL: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
|
288
|
+
PHONE: /^[\d\-\s()]{10,}$/,
|
|
289
|
+
POSTAL_CODE: /^\d{5,6}$/,
|
|
290
|
+
COUPON_CODE: /^[A-Z0-9]{6,20}$/,
|
|
291
|
+
PRODUCT_SKU: /^[A-Z0-9\-]{3,20}$/,
|
|
292
|
+
URL: /^(https?:\/\/)?([\da-z.-]+)\.([a-z.]{2,6})([/\w.-]*)*\/?$/
|
|
293
|
+
};
|
|
294
|
+
var ENV_PRESETS = {
|
|
295
|
+
DEVELOPMENT: {
|
|
296
|
+
corsOrigins: DEFAULT_CORS_ORIGINS,
|
|
297
|
+
logLevel: "debug",
|
|
298
|
+
apiTimeout: TIMEOUT_CONFIG.API_REQUEST
|
|
299
|
+
},
|
|
300
|
+
PRODUCTION: {
|
|
301
|
+
corsOrigins: ["https://ecommerce.example.com", "https://admin.ecommerce.example.com"],
|
|
302
|
+
logLevel: "info",
|
|
303
|
+
apiTimeout: TIMEOUT_CONFIG.API_REQUEST
|
|
304
|
+
},
|
|
305
|
+
TESTING: {
|
|
306
|
+
corsOrigins: ["http://localhost:*"],
|
|
307
|
+
logLevel: "error",
|
|
308
|
+
apiTimeout: TIMEOUT_CONFIG.API_REQUEST
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
// src/validation/client.ts
|
|
313
|
+
var isValidEmail = (email) => {
|
|
314
|
+
return REGEX_PATTERNS.EMAIL.test(email);
|
|
315
|
+
};
|
|
316
|
+
var validateEmail = (email) => {
|
|
317
|
+
if (!email || email.trim() === "") {
|
|
318
|
+
return { valid: false, error: "Email is required" };
|
|
319
|
+
}
|
|
320
|
+
if (!isValidEmail(email)) {
|
|
321
|
+
return { valid: false, error: "Invalid email format" };
|
|
322
|
+
}
|
|
323
|
+
if (email.length > 255) {
|
|
324
|
+
return { valid: false, error: "Email is too long" };
|
|
325
|
+
}
|
|
326
|
+
return { valid: true };
|
|
327
|
+
};
|
|
328
|
+
var isValidPassword = (password) => {
|
|
329
|
+
return JWT_CONFIG.PASSWORD_PATTERN.test(password);
|
|
330
|
+
};
|
|
331
|
+
var validatePassword = (password) => {
|
|
332
|
+
if (!password) {
|
|
333
|
+
return { valid: false, error: "Password is required" };
|
|
334
|
+
}
|
|
335
|
+
if (password.length < JWT_CONFIG.PASSWORD_MIN_LENGTH) {
|
|
336
|
+
return {
|
|
337
|
+
valid: false,
|
|
338
|
+
error: `Password must be at least ${JWT_CONFIG.PASSWORD_MIN_LENGTH} characters`
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
if (!isValidPassword(password)) {
|
|
342
|
+
return {
|
|
343
|
+
valid: false,
|
|
344
|
+
error: "Password must contain uppercase, lowercase, number, and special character (@$!%*?&)"
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
return { valid: true };
|
|
348
|
+
};
|
|
349
|
+
var validateName = (name) => {
|
|
350
|
+
if (!name || name.trim() === "") {
|
|
351
|
+
return { valid: false, error: "Name is required" };
|
|
352
|
+
}
|
|
353
|
+
if (name.length < 2) {
|
|
354
|
+
return { valid: false, error: "Name must be at least 2 characters" };
|
|
355
|
+
}
|
|
356
|
+
if (name.length > 100) {
|
|
357
|
+
return { valid: false, error: "Name is too long" };
|
|
358
|
+
}
|
|
359
|
+
if (!/^[a-zA-Z\s'-]+$/.test(name)) {
|
|
360
|
+
return {
|
|
361
|
+
valid: false,
|
|
362
|
+
error: "Name can only contain letters, spaces, hyphens, and apostrophes"
|
|
363
|
+
};
|
|
364
|
+
}
|
|
365
|
+
return { valid: true };
|
|
366
|
+
};
|
|
367
|
+
var isValidPhone = (phone) => {
|
|
368
|
+
return REGEX_PATTERNS.PHONE.test(phone);
|
|
369
|
+
};
|
|
370
|
+
var validatePhone = (phone) => {
|
|
371
|
+
if (!phone) {
|
|
372
|
+
return { valid: false, error: "Phone number is required" };
|
|
373
|
+
}
|
|
374
|
+
if (!isValidPhone(phone)) {
|
|
375
|
+
return { valid: false, error: "Invalid phone number format" };
|
|
376
|
+
}
|
|
377
|
+
return { valid: true };
|
|
378
|
+
};
|
|
379
|
+
var isValidPostalCode = (postalCode) => {
|
|
380
|
+
return REGEX_PATTERNS.POSTAL_CODE.test(postalCode);
|
|
381
|
+
};
|
|
382
|
+
var validatePostalCode = (postalCode) => {
|
|
383
|
+
if (!postalCode) {
|
|
384
|
+
return { valid: false, error: "Postal code is required" };
|
|
385
|
+
}
|
|
386
|
+
if (!isValidPostalCode(postalCode)) {
|
|
387
|
+
return { valid: false, error: "Invalid postal code format" };
|
|
388
|
+
}
|
|
389
|
+
return { valid: true };
|
|
390
|
+
};
|
|
391
|
+
var isValidCouponCode = (code) => {
|
|
392
|
+
return REGEX_PATTERNS.COUPON_CODE.test(code);
|
|
393
|
+
};
|
|
394
|
+
var validateCouponCode = (code) => {
|
|
395
|
+
if (!code) {
|
|
396
|
+
return { valid: false, error: "Coupon code is required" };
|
|
397
|
+
}
|
|
398
|
+
if (!isValidCouponCode(code)) {
|
|
399
|
+
return { valid: false, error: "Invalid coupon code format (6-20 alphanumeric characters)" };
|
|
400
|
+
}
|
|
401
|
+
return { valid: true };
|
|
402
|
+
};
|
|
403
|
+
var validatePrice = (price) => {
|
|
404
|
+
const numPrice = parseFloat(price);
|
|
405
|
+
if (isNaN(numPrice)) {
|
|
406
|
+
return { valid: false, error: "Price must be a valid number" };
|
|
407
|
+
}
|
|
408
|
+
if (numPrice < 0) {
|
|
409
|
+
return { valid: false, error: "Price cannot be negative" };
|
|
410
|
+
}
|
|
411
|
+
if (numPrice > 999999.99) {
|
|
412
|
+
return { valid: false, error: "Price exceeds maximum allowed value" };
|
|
413
|
+
}
|
|
414
|
+
return { valid: true };
|
|
415
|
+
};
|
|
416
|
+
var validateQuantity = (qty) => {
|
|
417
|
+
const numQty = parseInt(qty, 10);
|
|
418
|
+
if (isNaN(numQty)) {
|
|
419
|
+
return { valid: false, error: "Quantity must be a valid number" };
|
|
420
|
+
}
|
|
421
|
+
if (numQty < 0) {
|
|
422
|
+
return { valid: false, error: "Quantity cannot be negative" };
|
|
423
|
+
}
|
|
424
|
+
if (!Number.isInteger(numQty)) {
|
|
425
|
+
return { valid: false, error: "Quantity must be a whole number" };
|
|
426
|
+
}
|
|
427
|
+
return { valid: true };
|
|
428
|
+
};
|
|
429
|
+
var validateRating = (rating) => {
|
|
430
|
+
const numRating = parseFloat(rating);
|
|
431
|
+
if (isNaN(numRating)) {
|
|
432
|
+
return { valid: false, error: "Rating must be a valid number" };
|
|
433
|
+
}
|
|
434
|
+
if (numRating < 0 || numRating > 5) {
|
|
435
|
+
return { valid: false, error: "Rating must be between 0 and 5" };
|
|
436
|
+
}
|
|
437
|
+
return { valid: true };
|
|
438
|
+
};
|
|
439
|
+
var validateDiscountPercentage = (discount) => {
|
|
440
|
+
const numDiscount = parseFloat(discount);
|
|
441
|
+
if (isNaN(numDiscount)) {
|
|
442
|
+
return { valid: false, error: "Discount must be a valid number" };
|
|
443
|
+
}
|
|
444
|
+
if (numDiscount < 0 || numDiscount > 100) {
|
|
445
|
+
return { valid: false, error: "Discount percentage must be between 0 and 100" };
|
|
446
|
+
}
|
|
447
|
+
return { valid: true };
|
|
448
|
+
};
|
|
449
|
+
var validatePagination = (page, limit) => {
|
|
450
|
+
const numPage = parseInt(page, 10) || 1;
|
|
451
|
+
const numLimit = parseInt(limit, 10) || 10;
|
|
452
|
+
if (numPage < 1) {
|
|
453
|
+
return { valid: false, error: "Page must be greater than 0" };
|
|
454
|
+
}
|
|
455
|
+
if (numLimit < 1) {
|
|
456
|
+
return { valid: false, error: "Limit must be greater than 0" };
|
|
457
|
+
}
|
|
458
|
+
if (numLimit > 100) {
|
|
459
|
+
return { valid: false, error: "Limit cannot exceed 100" };
|
|
460
|
+
}
|
|
461
|
+
return { valid: true, page: numPage, limit: numLimit };
|
|
462
|
+
};
|
|
463
|
+
var isValidObjectId = (id) => {
|
|
464
|
+
return /^[0-9a-fA-F]{24}$/.test(id);
|
|
465
|
+
};
|
|
466
|
+
var validateObjectId = (id, fieldName = "ID") => {
|
|
467
|
+
if (!id) {
|
|
468
|
+
return { valid: false, error: `${fieldName} is required` };
|
|
469
|
+
}
|
|
470
|
+
if (!isValidObjectId(id)) {
|
|
471
|
+
return { valid: false, error: `Invalid ${fieldName} format` };
|
|
472
|
+
}
|
|
473
|
+
return { valid: true };
|
|
474
|
+
};
|
|
475
|
+
var isValidUrl = (url) => {
|
|
476
|
+
return REGEX_PATTERNS.URL.test(url);
|
|
477
|
+
};
|
|
478
|
+
var validateUrl = (url) => {
|
|
479
|
+
if (!url) {
|
|
480
|
+
return { valid: false, error: "URL is required" };
|
|
481
|
+
}
|
|
482
|
+
if (!isValidUrl(url)) {
|
|
483
|
+
return { valid: false, error: "Invalid URL format" };
|
|
484
|
+
}
|
|
485
|
+
return { valid: true };
|
|
486
|
+
};
|
|
487
|
+
var isValidSku = (sku) => {
|
|
488
|
+
return REGEX_PATTERNS.PRODUCT_SKU.test(sku);
|
|
489
|
+
};
|
|
490
|
+
var validateSku = (sku) => {
|
|
491
|
+
if (!sku) {
|
|
492
|
+
return { valid: false, error: "SKU is required" };
|
|
493
|
+
}
|
|
494
|
+
if (!isValidSku(sku)) {
|
|
495
|
+
return {
|
|
496
|
+
valid: false,
|
|
497
|
+
error: "Invalid SKU format (3-20 alphanumeric characters with hyphens)"
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
return { valid: true };
|
|
501
|
+
};
|
|
502
|
+
var validateDate = (date) => {
|
|
503
|
+
const dateObj = new Date(date);
|
|
504
|
+
if (isNaN(dateObj.getTime())) {
|
|
505
|
+
return { valid: false, error: "Invalid date format" };
|
|
506
|
+
}
|
|
507
|
+
return { valid: true };
|
|
508
|
+
};
|
|
509
|
+
var validateDateRange = (startDate, endDate) => {
|
|
510
|
+
const start = new Date(startDate);
|
|
511
|
+
const end = new Date(endDate);
|
|
512
|
+
if (isNaN(start.getTime())) {
|
|
513
|
+
return { valid: false, error: "Invalid start date" };
|
|
514
|
+
}
|
|
515
|
+
if (isNaN(end.getTime())) {
|
|
516
|
+
return { valid: false, error: "Invalid end date" };
|
|
517
|
+
}
|
|
518
|
+
if (start > end) {
|
|
519
|
+
return { valid: false, error: "Start date must be before end date" };
|
|
520
|
+
}
|
|
521
|
+
return { valid: true };
|
|
522
|
+
};
|
|
523
|
+
var batchValidate = (validations) => {
|
|
524
|
+
const errors = [];
|
|
525
|
+
for (const validation of validations) {
|
|
526
|
+
if (!validation.valid && validation.error) {
|
|
527
|
+
errors.push(validation.error);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return {
|
|
531
|
+
valid: errors.length === 0,
|
|
532
|
+
errors
|
|
533
|
+
};
|
|
534
|
+
};
|
|
535
|
+
|
|
536
|
+
// ../types/dist/index.mjs
|
|
537
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
538
|
+
LogLevel2["DEBUG"] = "DEBUG";
|
|
539
|
+
LogLevel2["INFO"] = "INFO";
|
|
540
|
+
LogLevel2["WARN"] = "WARN";
|
|
541
|
+
LogLevel2["ERROR"] = "ERROR";
|
|
542
|
+
return LogLevel2;
|
|
543
|
+
})(LogLevel || {});
|
|
544
|
+
|
|
545
|
+
export {
|
|
546
|
+
__require,
|
|
547
|
+
__commonJS,
|
|
548
|
+
__export,
|
|
549
|
+
__toESM,
|
|
550
|
+
SHELL_APP_URL,
|
|
551
|
+
ADMIN_APP_URL,
|
|
552
|
+
SELLER_APP_URL,
|
|
553
|
+
STOREFRONT_APP_URL,
|
|
554
|
+
PORT_CONFIG,
|
|
555
|
+
SERVICE_URLS,
|
|
556
|
+
DATABASE_CONFIG,
|
|
557
|
+
DEFAULT_CORS_ORIGINS,
|
|
558
|
+
JWT_CONFIG,
|
|
559
|
+
PAGINATION,
|
|
560
|
+
PRODUCT_CONFIG,
|
|
561
|
+
ORDER_CONFIG,
|
|
562
|
+
COUPON_CONFIG,
|
|
563
|
+
API_ENDPOINTS,
|
|
564
|
+
HTTP_STATUS,
|
|
565
|
+
ERROR_MESSAGES,
|
|
566
|
+
SUCCESS_MESSAGES,
|
|
567
|
+
CACHE_CONFIG,
|
|
568
|
+
TIMEOUT_CONFIG,
|
|
569
|
+
REGEX_PATTERNS,
|
|
570
|
+
ENV_PRESETS,
|
|
571
|
+
LogLevel,
|
|
572
|
+
isValidEmail,
|
|
573
|
+
validateEmail,
|
|
574
|
+
isValidPassword,
|
|
575
|
+
validatePassword,
|
|
576
|
+
validateName,
|
|
577
|
+
isValidPhone,
|
|
578
|
+
validatePhone,
|
|
579
|
+
isValidPostalCode,
|
|
580
|
+
validatePostalCode,
|
|
581
|
+
isValidCouponCode,
|
|
582
|
+
validateCouponCode,
|
|
583
|
+
validatePrice,
|
|
584
|
+
validateQuantity,
|
|
585
|
+
validateRating,
|
|
586
|
+
validateDiscountPercentage,
|
|
587
|
+
validatePagination,
|
|
588
|
+
isValidObjectId,
|
|
589
|
+
validateObjectId,
|
|
590
|
+
isValidUrl,
|
|
591
|
+
validateUrl,
|
|
592
|
+
isValidSku,
|
|
593
|
+
validateSku,
|
|
594
|
+
validateDate,
|
|
595
|
+
validateDateRange,
|
|
596
|
+
batchValidate
|
|
597
|
+
};
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-safe validation utilities
|
|
3
|
+
* These can be used in both frontend and backend
|
|
4
|
+
*/
|
|
5
|
+
declare const isValidEmail: (email: string) => boolean;
|
|
6
|
+
declare const validateEmail: (email: string) => {
|
|
7
|
+
valid: boolean;
|
|
8
|
+
error?: string;
|
|
9
|
+
};
|
|
10
|
+
declare const isValidPassword: (password: string) => boolean;
|
|
11
|
+
declare const validatePassword: (password: string) => {
|
|
12
|
+
valid: boolean;
|
|
13
|
+
error?: string;
|
|
14
|
+
};
|
|
15
|
+
declare const validateName: (name: string) => {
|
|
16
|
+
valid: boolean;
|
|
17
|
+
error?: string;
|
|
18
|
+
};
|
|
19
|
+
declare const isValidPhone: (phone: string) => boolean;
|
|
20
|
+
declare const validatePhone: (phone: string) => {
|
|
21
|
+
valid: boolean;
|
|
22
|
+
error?: string;
|
|
23
|
+
};
|
|
24
|
+
declare const isValidPostalCode: (postalCode: string) => boolean;
|
|
25
|
+
declare const validatePostalCode: (postalCode: string) => {
|
|
26
|
+
valid: boolean;
|
|
27
|
+
error?: string;
|
|
28
|
+
};
|
|
29
|
+
declare const isValidCouponCode: (code: string) => boolean;
|
|
30
|
+
declare const validateCouponCode: (code: string) => {
|
|
31
|
+
valid: boolean;
|
|
32
|
+
error?: string;
|
|
33
|
+
};
|
|
34
|
+
declare const validatePrice: (price: any) => {
|
|
35
|
+
valid: boolean;
|
|
36
|
+
error?: string;
|
|
37
|
+
};
|
|
38
|
+
declare const validateQuantity: (qty: any) => {
|
|
39
|
+
valid: boolean;
|
|
40
|
+
error?: string;
|
|
41
|
+
};
|
|
42
|
+
declare const validateRating: (rating: any) => {
|
|
43
|
+
valid: boolean;
|
|
44
|
+
error?: string;
|
|
45
|
+
};
|
|
46
|
+
declare const validateDiscountPercentage: (discount: any) => {
|
|
47
|
+
valid: boolean;
|
|
48
|
+
error?: string;
|
|
49
|
+
};
|
|
50
|
+
declare const validatePagination: (page: any, limit: any) => {
|
|
51
|
+
valid: boolean;
|
|
52
|
+
error?: string;
|
|
53
|
+
page?: number;
|
|
54
|
+
limit?: number;
|
|
55
|
+
};
|
|
56
|
+
declare const isValidObjectId: (id: string) => boolean;
|
|
57
|
+
declare const validateObjectId: (id: string, fieldName?: string) => {
|
|
58
|
+
valid: boolean;
|
|
59
|
+
error?: string;
|
|
60
|
+
};
|
|
61
|
+
declare const isValidUrl: (url: string) => boolean;
|
|
62
|
+
declare const validateUrl: (url: string) => {
|
|
63
|
+
valid: boolean;
|
|
64
|
+
error?: string;
|
|
65
|
+
};
|
|
66
|
+
declare const isValidSku: (sku: string) => boolean;
|
|
67
|
+
declare const validateSku: (sku: string) => {
|
|
68
|
+
valid: boolean;
|
|
69
|
+
error?: string;
|
|
70
|
+
};
|
|
71
|
+
declare const validateDate: (date: any) => {
|
|
72
|
+
valid: boolean;
|
|
73
|
+
error?: string;
|
|
74
|
+
};
|
|
75
|
+
declare const validateDateRange: (startDate: any, endDate: any) => {
|
|
76
|
+
valid: boolean;
|
|
77
|
+
error?: string;
|
|
78
|
+
};
|
|
79
|
+
declare const batchValidate: (validations: Array<{
|
|
80
|
+
valid: boolean;
|
|
81
|
+
error?: string;
|
|
82
|
+
}>) => {
|
|
83
|
+
valid: boolean;
|
|
84
|
+
errors: string[];
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
export { isValidPassword as a, validatePassword as b, validateName as c, isValidPhone as d, validatePhone as e, isValidPostalCode as f, validatePostalCode as g, isValidCouponCode as h, isValidEmail as i, validateCouponCode as j, validatePrice as k, validateQuantity as l, validateRating as m, validateDiscountPercentage as n, validatePagination as o, isValidObjectId as p, validateObjectId as q, isValidUrl as r, validateUrl as s, isValidSku as t, validateSku as u, validateEmail as v, validateDate as w, validateDateRange as x, batchValidate as y };
|