nextpay-querystring
v1.0.7
Published
Thư viện QueryString của NextPay - Chuyển đổi QueryString thành điều kiện select cho MongoDB và MySQL với kiểm soát bảo mật
Maintainers
Readme
nextpay-querystring
Thư viện QueryString của NextPay - Chuyển đổi QueryString thành điều kiện select cho MongoDB và MySQL với kiểm soát bảo mật và tránh SQL injection.
🚀 Tính năng
- ✅ Chuyển đổi QueryString thành MongoDB criteria
- ✅ Chuyển đổi QueryString thành MySQL WHERE clause
- ✅ Hỗ trợ nhiều loại operator:
==,!=,>,>=,<,<=,IN,NIN,BETWEEN,LIKE - ✅ Validation field và data type
- ✅ Bảo mật chống SQL injection
- ✅ Hỗ trợ TypeScript
- ✅ Lightweight và performant
📦 Cài đặt
npm install nextpay-querystring🎯 Cách sử dụng
Import thư viện
// ✅ sử dụng cho mongodb
import { toMongoCriteria, FieldDescription, DataType } from 'nextpay-querystring';
// ✅ sử dụng cho Mysql
import { toMySqlCriteria, FieldDescription, DataType } from 'nextpay-querystring';Khai báo Field Descriptions
const fieldDescriptions: FieldDescription[] = [
{
field: '_id',
required: true,
dataType: DataType.STRING,
maxOccurrence: 5,
mapTo: '_id',
},
{
field: 'title',
required: true,
dataType: DataType.STRING,
maxOccurrence: 5,
mapTo: 'title',
},
{
field: 'status',
required: true,
dataType: DataType.STRING,
maxOccurrence: 5,
mapTo: 'status',
},
{
field: 'createdAt',
required: true,
dataType: DataType.DATE,
maxOccurrence: 5,
mapTo: 'createdAt',
},
{
field: 'isActive',
required: true,
dataType: DataType.BOOLEAN,
maxOccurrence: 5,
mapTo: 'isActive',
},
];Sử dụng với MongoDB
const queryString = "{title} == '''MACQ''' AND {status} IN ['''OPEN''', '''ON-HOLD'''] AND {isActive} == true";
const mongoCriteria = toMongoCriteria(queryString, fieldDescriptions);
const whereCondition = JSON.parse(mongoCriteria);
// Kết quả: {title: "MACQ", status: {$in: ["OPEN", "ON-HOLD"]}, isActive: true}
const result = await collection.find(whereCondition);Sử dụng với MySQL
const queryString = "{title} == '''MACQ''' AND {status} IN ['''OPEN''', '''ON-HOLD'''] AND {isActive} == true";
const mysqlCriteria = toMySqlCriteria(queryString, fieldDescriptions);
// Kết quả: title = 'MACQ' AND status IN ('OPEN', 'ON-HOLD') AND isActive = true
const result = await connection.query(`SELECT * FROM table WHERE ${mysqlCriteria}`);Ví dụ hoàn chỉnh với Grouping
import { toMongoCriteria, toMySqlCriteria, FieldDescription, DataType } from 'nextpay-querystring';
const fieldDescriptions: FieldDescription[] = [
{
field: 'status',
required: true,
dataType: DataType.STRING,
maxOccurrence: 5,
mapTo: 'status',
},
{
field: 'id',
required: true,
dataType: DataType.INTEGER,
maxOccurrence: 5,
mapTo: 'id',
},
{
field: 'title',
required: true,
dataType: DataType.STRING,
maxOccurrence: 5,
mapTo: 'title',
},
{
field: 'category',
required: false,
dataType: DataType.STRING,
maxOccurrence: 5,
mapTo: 'category',
},
];
// Query với grouping
const queryString = "{status} == '''ACTIVE''' AND ({id} == 1 OR {title} LIKE '''admin''') AND ({priority} >= 3 OR {category} == '''VIP''')";
// MongoDB
const mongoResult = toMongoCriteria(queryString, fieldDescriptions);
const mongoCriteria = JSON.parse(mongoResult);
console.log('MongoDB:', mongoCriteria);
// Output: {
// $and: [
// { status: 'ACTIVE' },
// { $or: [{ id: 1 }, { title: { $regex: 'admin', $options: 'i' } }] },
// { $or: [{ priority: { $gte: 3 } }, { category: 'VIP' }] }
// ]
// }
// MySQL
const mysqlResult = toMySqlCriteria(queryString, fieldDescriptions);
console.log('MySQL:', mysqlResult);
// Output: (status = "ACTIVE") AND ((id = 1) OR (title LIKE %"admin"%)) AND ((priority >= 3) OR (category = "VIP"))📝 Quy tắc viết QueryString
Format cơ bản
{<tên-field>} <operator> <value>Các loại giá trị
| Kiểu dữ liệu | Cú pháp | Ví dụ |
|-------------|---------|-------|
| String | '''value''' | {title} == '''MACQ''' |
| Number | value | {id} == 1 |
| Boolean | true/false | {isActive} == true |
| Date | #value# | {createdAt} == #2025-01-15# |
Các operator được hỗ trợ
Comparison Operators
==- Equals!=- Not equals===- Triple equals>- Greater than>=- Greater than or equal<- Less than<=- Less than or equal
Array Operators
IN- In arrayNIN- Not in arrayBETWEEN- Between rangeNBETWEEN- Not between range
String Operators
like%- Starts withlike- Contains%like- Ends withnlike- Not containsnlike%- Not starts with%nlike- Not ends with
NULL Operators
is_null- Is nullis_not_null- Is not null
Logical Operators
AND- Logical ANDOR- Logical ORNOT- Logical NOT
Ví dụ phức tạp
const complexQuery = `
{title} == '''MACQ''' AND
{id} == 1 AND
{status} IN ['''OPEN''', '''ON-HOLD'''] AND
{isPrivate} == true AND
{dueDate} == #2025-08-25# AND
{description} like '''important'''
`;Ví dụ với Negative Operators
// String negative operators
const negativeStringQuery = `
{title} nlike '''admin''' AND
{description} nlike% '''draft''' AND
{filename} %nlike '''.tmp'''
`;
// Range negative operator
const negativeRangeQuery = `
{priority} nbetween [1, 5] AND
{createdAt} nbetween [#2024-01-01#, #2024-12-31#]
`;
// Complex negative query
const complexNegativeQuery = `
{title} nlike '''admin''' AND
{status} nbetween ['''DELETED''', '''ARCHIVED'''] AND
({priority} >= 3 OR {category} == '''VIP''')
`;
// NULL operators
const nullQuery = `
{title} is_not_null AND
{description} is_null AND
{priority} >= 3
`;
// Complex query with NULL operators
const complexNullQuery = `
({title} is_null OR {description} is_not_null) AND
{status} == '''ACTIVE''' AND
{priority} is_not_null
`;
// BETWEEN operator examples
const betweenQuery = `
{priority} between [1, 5] AND
{createdAt} between [#2024-01-01#, #2024-12-31#] AND
{status} between ['''ACTIVE''', '''PENDING''']
`;Ví dụ với Grouping/Parentheses
// ✅ Simple OR group
const orGroup = "({id} == 1 OR {id} == 2)";
// ✅ AND với OR group
const andWithOr = "{status} == '''ACTIVE''' AND ({id} == 1 OR {title} LIKE '''tan''')";
// ✅ Nested groups
const nestedGroups = "({status} == '''ACTIVE''' AND ({id} == 1 OR {id} == 2)) OR ({category} == '''VIP''')";
// ✅ Multiple groups
const multipleGroups = "({id} == 1 OR {id} == 2) AND ({status} == '''ACTIVE''' OR {status} == '''PENDING''')";
// ✅ Group với IN operator
const groupWithIn = "({id} == 1 OR {id} == 2) AND {status} IN ['''ACTIVE''', '''PENDING''']";
// ✅ Complex nested groups
const complexNested = "({status} == '''ACTIVE''' AND ({id} == 1 OR {id} == 2)) AND ({priority} >= 3 OR ({category} == '''VIP''' AND {isActive} == true))";🔧 Data Types
enum DataType {
STRING, // String values
INTEGER, // Integer numbers
DOUBLE, // Decimal numbers
BOOLEAN, // true/false
DATE, // Date values
}🛡️ Bảo mật
- Field Validation: Chỉ cho phép sử dụng các field đã được khai báo
- Data Type Validation: Kiểm tra kiểu dữ liệu phù hợp
- SQL Injection Prevention: Escape và validate tất cả input
- Occurrence Limit: Giới hạn số lần xuất hiện của mỗi field
🧪 Testing
# Chạy tests
npm test
# Chạy tests với watch mode
npm run test:watch
# Chạy tests với coverage
npm test -- --coverage📦 Exports
Functions
toMongoCriteria(queryString: string, fieldDescriptions: FieldDescription[]): string- Chuyển đổi QueryString thành MongoDB criteriatoMySqlCriteria(queryString: string, fieldDescriptions: FieldDescription[]): string- Chuyển đổi QueryString thành MySQL WHERE clause
Types & Interfaces
FieldDescription- Interface cho field descriptionFieldDescriptionContainer- Class container cho field descriptionsDataType- Enum cho các kiểu dữ liệu (STRING, INTEGER, DOUBLE, BOOLEAN, DATE)
Backward Compatibility
FieldDescriptionType- Alias cho FieldDescription
📚 API Reference
toMongoCriteria(queryString: string, fieldDescriptions: FieldDescription[]): string
Chuyển đổi QueryString thành MongoDB criteria dạng JSON string.
toMySqlCriteria(queryString: string, fieldDescriptions: FieldDescription[]): string
Chuyển đổi QueryString thành MySQL WHERE clause.
FieldDescription
interface FieldDescription {
readonly field: string; // Tên field trong QueryString
readonly required: boolean; // Field có bắt buộc không
readonly dataType: DataType; // Kiểu dữ liệu
readonly maxOccurrence: number; // Số lần xuất hiện tối đa
readonly mapTo: string; // Tên field trong database
}👨💻 Tác giả
- Username: Mvtcode - Tanmv - MacTan
- Email: [email protected]
🤝 Contributing
- Fork project
- Tạo feature branch (
git checkout -b feature/AmazingFeature) - Commit changes (
git commit -m 'Add some AmazingFeature') - Push to branch (
git push origin feature/AmazingFeature) - Tạo Pull Request
📄 License
MIT License - xem file LICENSE để biết thêm chi tiết.
🆘 Support
Nếu gặp vấn đề, vui lòng tạo issue tại GitHub Issues.
