@nest-omni/core 3.1.1-17 → 3.1.1-19
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/cache/cache-serialization.service.d.ts +4 -11
- package/cache/cache-serialization.service.js +29 -124
- package/cache/cache.constants.d.ts +2 -0
- package/cache/cache.constants.js +5 -0
- package/cache/cache.module.d.ts +2 -0
- package/cache/cache.module.js +49 -3
- package/cache/cache.service.d.ts +3 -1
- package/cache/cache.service.js +32 -4
- package/cache/examples/basic-usage.d.ts +58 -0
- package/cache/examples/basic-usage.js +379 -0
- package/cache/index.d.ts +2 -1
- package/cache/index.js +4 -1
- package/common/boilerplate.polyfill.d.ts +1 -7
- package/common/boilerplate.polyfill.js +1 -1
- package/common/dto/page-options.dto.d.ts +0 -3
- package/common/dto/page-options.dto.js +0 -12
- package/common/examples/paginate-and-map.example.d.ts +14 -0
- package/common/examples/paginate-and-map.example.js +158 -0
- package/decorators/examples/validation-decorators.example.d.ts +69 -0
- package/decorators/examples/validation-decorators.example.js +331 -0
- package/decorators/validator.decorators.d.ts +8 -1
- package/decorators/validator.decorators.js +115 -0
- package/i18n/en_US/validation.json +4 -1
- package/i18n/zh_CN/validation.json +4 -1
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +1 -1
- package/redis-lock/examples/lock-strategy.examples.d.ts +73 -0
- package/redis-lock/examples/lock-strategy.examples.js +387 -0
- package/redis-lock/index.d.ts +2 -2
- package/redis-lock/index.js +4 -1
- package/redis-lock/redis-lock.decorator.d.ts +4 -0
- package/redis-lock/redis-lock.decorator.js +43 -7
- package/redis-lock/redis-lock.service.d.ts +19 -0
- package/redis-lock/redis-lock.service.js +131 -6
- package/setup/bootstrap.setup.d.ts +0 -1
- package/setup/bootstrap.setup.js +0 -1
- package/setup/index.d.ts +0 -1
- package/setup/index.js +0 -1
- package/shared/serviceRegistryModule.js +2 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export declare class ContactDto {
|
|
2
|
+
email?: string;
|
|
3
|
+
phone?: string;
|
|
4
|
+
wechat?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare class SearchDto {
|
|
7
|
+
keyword?: string;
|
|
8
|
+
category?: string;
|
|
9
|
+
tags?: string[];
|
|
10
|
+
}
|
|
11
|
+
export declare class PasswordDto {
|
|
12
|
+
password: string;
|
|
13
|
+
}
|
|
14
|
+
export declare class EmailCheckDto {
|
|
15
|
+
email: string;
|
|
16
|
+
userService?: any;
|
|
17
|
+
}
|
|
18
|
+
export declare class OrderDto {
|
|
19
|
+
orderType: 'standard' | 'express';
|
|
20
|
+
deliveryDate?: Date;
|
|
21
|
+
}
|
|
22
|
+
export declare class DiscountDto {
|
|
23
|
+
discountType: 'percentage' | 'fixed';
|
|
24
|
+
discountValue: number;
|
|
25
|
+
get validatedDiscountValue(): number;
|
|
26
|
+
}
|
|
27
|
+
export declare class UserRegistrationDto {
|
|
28
|
+
username: string;
|
|
29
|
+
password: string;
|
|
30
|
+
confirmPassword: string;
|
|
31
|
+
validatePassword(password: string): boolean;
|
|
32
|
+
validatePasswordMatch(confirmPassword: string): boolean;
|
|
33
|
+
}
|
|
34
|
+
export declare class CreateProductDto {
|
|
35
|
+
name: string;
|
|
36
|
+
sku: string;
|
|
37
|
+
categoryId: string;
|
|
38
|
+
get validatedCategoryId(): string;
|
|
39
|
+
productService?: any;
|
|
40
|
+
categoryService?: any;
|
|
41
|
+
checkSkuUniqueness(sku: string): Promise<boolean>;
|
|
42
|
+
validateCategoryExists(categoryId: string): Promise<boolean>;
|
|
43
|
+
}
|
|
44
|
+
export declare class EmployeeDto {
|
|
45
|
+
name: string;
|
|
46
|
+
personalEmail?: string;
|
|
47
|
+
workEmail?: string;
|
|
48
|
+
phone?: string;
|
|
49
|
+
validatePhoneFormat(phone: string): boolean;
|
|
50
|
+
}
|
|
51
|
+
export declare class PaymentMethodDto {
|
|
52
|
+
paymentType: 'credit_card' | 'bank_transfer' | 'digital_wallet';
|
|
53
|
+
creditCard?: {
|
|
54
|
+
number: string;
|
|
55
|
+
expiryDate: string;
|
|
56
|
+
cvv: string;
|
|
57
|
+
};
|
|
58
|
+
bankAccount?: {
|
|
59
|
+
accountNumber: string;
|
|
60
|
+
routingNumber: string;
|
|
61
|
+
};
|
|
62
|
+
digitalWallet?: {
|
|
63
|
+
provider: string;
|
|
64
|
+
walletId: string;
|
|
65
|
+
};
|
|
66
|
+
validateCreditCard(creditCard: any): boolean;
|
|
67
|
+
validateBankAccount(bankAccount: any): boolean;
|
|
68
|
+
validateDigitalWallet(digitalWallet: any): boolean;
|
|
69
|
+
}
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.PaymentMethodDto = exports.EmployeeDto = exports.CreateProductDto = exports.UserRegistrationDto = exports.DiscountDto = exports.OrderDto = exports.EmailCheckDto = exports.PasswordDto = exports.SearchDto = exports.ContactDto = void 0;
|
|
22
|
+
const class_validator_1 = require("class-validator");
|
|
23
|
+
const swagger_1 = require("@nestjs/swagger");
|
|
24
|
+
const validator_decorators_1 = require("../validator.decorators");
|
|
25
|
+
const field_decorators_1 = require("../field.decorators");
|
|
26
|
+
class ContactDto {
|
|
27
|
+
}
|
|
28
|
+
exports.ContactDto = ContactDto;
|
|
29
|
+
__decorate([
|
|
30
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
31
|
+
(0, class_validator_1.IsEmail)(),
|
|
32
|
+
(0, validator_decorators_1.AtLeastOneField)(['email', 'phone', 'wechat']),
|
|
33
|
+
__metadata("design:type", String)
|
|
34
|
+
], ContactDto.prototype, "email", void 0);
|
|
35
|
+
__decorate([
|
|
36
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
37
|
+
(0, class_validator_1.IsString)(),
|
|
38
|
+
__metadata("design:type", String)
|
|
39
|
+
], ContactDto.prototype, "phone", void 0);
|
|
40
|
+
__decorate([
|
|
41
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
42
|
+
(0, class_validator_1.IsString)(),
|
|
43
|
+
__metadata("design:type", String)
|
|
44
|
+
], ContactDto.prototype, "wechat", void 0);
|
|
45
|
+
class SearchDto {
|
|
46
|
+
}
|
|
47
|
+
exports.SearchDto = SearchDto;
|
|
48
|
+
__decorate([
|
|
49
|
+
(0, field_decorators_1.StringFieldOptional)(),
|
|
50
|
+
(0, validator_decorators_1.AtLeastOneField)(['keyword', 'category', 'tags'], {
|
|
51
|
+
message: 'Please provide at least one search criteria: keyword, category, or tags',
|
|
52
|
+
}),
|
|
53
|
+
__metadata("design:type", String)
|
|
54
|
+
], SearchDto.prototype, "keyword", void 0);
|
|
55
|
+
__decorate([
|
|
56
|
+
(0, field_decorators_1.StringFieldOptional)(),
|
|
57
|
+
__metadata("design:type", String)
|
|
58
|
+
], SearchDto.prototype, "category", void 0);
|
|
59
|
+
__decorate([
|
|
60
|
+
(0, field_decorators_1.StringFieldOptional)({ each: true }),
|
|
61
|
+
__metadata("design:type", Array)
|
|
62
|
+
], SearchDto.prototype, "tags", void 0);
|
|
63
|
+
class PasswordDto {
|
|
64
|
+
}
|
|
65
|
+
exports.PasswordDto = PasswordDto;
|
|
66
|
+
__decorate([
|
|
67
|
+
(0, validator_decorators_1.CustomValidation)((value) => {
|
|
68
|
+
if (!value || value.length < 8)
|
|
69
|
+
return false;
|
|
70
|
+
const hasUppercase = /[A-Z]/.test(value);
|
|
71
|
+
const hasLowercase = /[a-z]/.test(value);
|
|
72
|
+
const hasNumber = /[0-9]/.test(value);
|
|
73
|
+
return hasUppercase && hasLowercase && hasNumber;
|
|
74
|
+
}, {
|
|
75
|
+
message: 'Password must be at least 8 characters with uppercase, lowercase, and number',
|
|
76
|
+
}),
|
|
77
|
+
(0, swagger_1.ApiProperty)(),
|
|
78
|
+
__metadata("design:type", String)
|
|
79
|
+
], PasswordDto.prototype, "password", void 0);
|
|
80
|
+
class EmailCheckDto {
|
|
81
|
+
}
|
|
82
|
+
exports.EmailCheckDto = EmailCheckDto;
|
|
83
|
+
__decorate([
|
|
84
|
+
(0, validator_decorators_1.CustomValidation)((value, args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
85
|
+
const userService = args.object.userService;
|
|
86
|
+
if (!userService) {
|
|
87
|
+
console.warn('UserService not found, skipping email check');
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
90
|
+
const exists = yield userService.checkEmailExists(value);
|
|
91
|
+
return !exists;
|
|
92
|
+
}), {
|
|
93
|
+
message: 'Email already exists in the system',
|
|
94
|
+
}),
|
|
95
|
+
(0, class_validator_1.IsEmail)(),
|
|
96
|
+
(0, swagger_1.ApiProperty)(),
|
|
97
|
+
__metadata("design:type", String)
|
|
98
|
+
], EmailCheckDto.prototype, "email", void 0);
|
|
99
|
+
class OrderDto {
|
|
100
|
+
}
|
|
101
|
+
exports.OrderDto = OrderDto;
|
|
102
|
+
__decorate([
|
|
103
|
+
(0, swagger_1.ApiProperty)({ enum: ['standard', 'express'] }),
|
|
104
|
+
(0, class_validator_1.IsString)(),
|
|
105
|
+
__metadata("design:type", String)
|
|
106
|
+
], OrderDto.prototype, "orderType", void 0);
|
|
107
|
+
__decorate([
|
|
108
|
+
(0, validator_decorators_1.CustomValidation)((value, args) => {
|
|
109
|
+
const object = args.object;
|
|
110
|
+
if (object.orderType === 'express') {
|
|
111
|
+
return value !== null && value !== undefined;
|
|
112
|
+
}
|
|
113
|
+
return true;
|
|
114
|
+
}, {
|
|
115
|
+
message: 'Delivery date is required for express orders',
|
|
116
|
+
}),
|
|
117
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
118
|
+
__metadata("design:type", Date)
|
|
119
|
+
], OrderDto.prototype, "deliveryDate", void 0);
|
|
120
|
+
class DiscountDto {
|
|
121
|
+
get validatedDiscountValue() {
|
|
122
|
+
return this.discountValue;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.DiscountDto = DiscountDto;
|
|
126
|
+
__decorate([
|
|
127
|
+
(0, swagger_1.ApiProperty)(),
|
|
128
|
+
__metadata("design:type", String)
|
|
129
|
+
], DiscountDto.prototype, "discountType", void 0);
|
|
130
|
+
__decorate([
|
|
131
|
+
(0, swagger_1.ApiProperty)(),
|
|
132
|
+
__metadata("design:type", Number)
|
|
133
|
+
], DiscountDto.prototype, "discountValue", void 0);
|
|
134
|
+
__decorate([
|
|
135
|
+
(0, validator_decorators_1.CustomValidation)((value, args) => {
|
|
136
|
+
const object = args.object;
|
|
137
|
+
if (object.discountType === 'percentage') {
|
|
138
|
+
return value >= 0 && value <= 100;
|
|
139
|
+
}
|
|
140
|
+
else if (object.discountType === 'fixed') {
|
|
141
|
+
return value > 0;
|
|
142
|
+
}
|
|
143
|
+
return false;
|
|
144
|
+
}, {
|
|
145
|
+
message: 'Invalid discount value for the selected discount type',
|
|
146
|
+
}),
|
|
147
|
+
__metadata("design:type", Object),
|
|
148
|
+
__metadata("design:paramtypes", [])
|
|
149
|
+
], DiscountDto.prototype, "validatedDiscountValue", null);
|
|
150
|
+
class UserRegistrationDto {
|
|
151
|
+
validatePassword(password) {
|
|
152
|
+
if (!password || password.length < 8)
|
|
153
|
+
return false;
|
|
154
|
+
const hasUppercase = /[A-Z]/.test(password);
|
|
155
|
+
const hasLowercase = /[a-z]/.test(password);
|
|
156
|
+
const hasNumber = /[0-9]/.test(password);
|
|
157
|
+
const hasSpecial = /[!@#$%^&*]/.test(password);
|
|
158
|
+
return hasUppercase && hasLowercase && hasNumber && hasSpecial;
|
|
159
|
+
}
|
|
160
|
+
validatePasswordMatch(confirmPassword) {
|
|
161
|
+
return confirmPassword === this.password;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.UserRegistrationDto = UserRegistrationDto;
|
|
165
|
+
__decorate([
|
|
166
|
+
(0, swagger_1.ApiProperty)(),
|
|
167
|
+
(0, class_validator_1.IsString)(),
|
|
168
|
+
__metadata("design:type", String)
|
|
169
|
+
], UserRegistrationDto.prototype, "username", void 0);
|
|
170
|
+
__decorate([
|
|
171
|
+
(0, validator_decorators_1.CustomValidationMethod)('validatePassword', {
|
|
172
|
+
message: 'Password does not meet security requirements',
|
|
173
|
+
}),
|
|
174
|
+
(0, swagger_1.ApiProperty)(),
|
|
175
|
+
__metadata("design:type", String)
|
|
176
|
+
], UserRegistrationDto.prototype, "password", void 0);
|
|
177
|
+
__decorate([
|
|
178
|
+
(0, validator_decorators_1.CustomValidationMethod)('validatePasswordMatch'),
|
|
179
|
+
(0, swagger_1.ApiProperty)(),
|
|
180
|
+
__metadata("design:type", String)
|
|
181
|
+
], UserRegistrationDto.prototype, "confirmPassword", void 0);
|
|
182
|
+
class CreateProductDto {
|
|
183
|
+
get validatedCategoryId() {
|
|
184
|
+
return this.categoryId;
|
|
185
|
+
}
|
|
186
|
+
checkSkuUniqueness(sku) {
|
|
187
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
188
|
+
if (!this.productService) {
|
|
189
|
+
console.warn('ProductService not found');
|
|
190
|
+
return true;
|
|
191
|
+
}
|
|
192
|
+
const exists = yield this.productService.skuExists(sku);
|
|
193
|
+
return !exists;
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
validateCategoryExists(categoryId) {
|
|
197
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
198
|
+
if (!this.categoryService) {
|
|
199
|
+
console.warn('CategoryService not found');
|
|
200
|
+
return true;
|
|
201
|
+
}
|
|
202
|
+
return yield this.categoryService.exists(categoryId);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
exports.CreateProductDto = CreateProductDto;
|
|
207
|
+
__decorate([
|
|
208
|
+
(0, swagger_1.ApiProperty)(),
|
|
209
|
+
(0, class_validator_1.IsString)(),
|
|
210
|
+
__metadata("design:type", String)
|
|
211
|
+
], CreateProductDto.prototype, "name", void 0);
|
|
212
|
+
__decorate([
|
|
213
|
+
(0, validator_decorators_1.CustomValidationMethod)('checkSkuUniqueness', {
|
|
214
|
+
message: 'SKU already exists',
|
|
215
|
+
}),
|
|
216
|
+
(0, swagger_1.ApiProperty)(),
|
|
217
|
+
__metadata("design:type", String)
|
|
218
|
+
], CreateProductDto.prototype, "sku", void 0);
|
|
219
|
+
__decorate([
|
|
220
|
+
(0, swagger_1.ApiProperty)(),
|
|
221
|
+
__metadata("design:type", String)
|
|
222
|
+
], CreateProductDto.prototype, "categoryId", void 0);
|
|
223
|
+
__decorate([
|
|
224
|
+
(0, validator_decorators_1.CustomValidationMethod)('validateCategoryExists', {
|
|
225
|
+
message: 'Category does not exist',
|
|
226
|
+
}),
|
|
227
|
+
__metadata("design:type", Object),
|
|
228
|
+
__metadata("design:paramtypes", [])
|
|
229
|
+
], CreateProductDto.prototype, "validatedCategoryId", null);
|
|
230
|
+
class EmployeeDto {
|
|
231
|
+
validatePhoneFormat(phone) {
|
|
232
|
+
if (!phone)
|
|
233
|
+
return true;
|
|
234
|
+
const phoneRegex = /^\+?[1-9]\d{1,14}$/;
|
|
235
|
+
return phoneRegex.test(phone);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
exports.EmployeeDto = EmployeeDto;
|
|
239
|
+
__decorate([
|
|
240
|
+
(0, swagger_1.ApiProperty)(),
|
|
241
|
+
(0, class_validator_1.IsString)(),
|
|
242
|
+
__metadata("design:type", String)
|
|
243
|
+
], EmployeeDto.prototype, "name", void 0);
|
|
244
|
+
__decorate([
|
|
245
|
+
(0, validator_decorators_1.CustomValidation)((value) => {
|
|
246
|
+
const workDomains = ['company.com', 'corp.com'];
|
|
247
|
+
const domain = value === null || value === void 0 ? void 0 : value.split('@')[1];
|
|
248
|
+
return !workDomains.includes(domain);
|
|
249
|
+
}, {
|
|
250
|
+
message: 'Personal email should not be from work domains',
|
|
251
|
+
}),
|
|
252
|
+
(0, class_validator_1.IsEmail)(),
|
|
253
|
+
(0, validator_decorators_1.AtLeastOneField)(['personalEmail', 'workEmail']),
|
|
254
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
255
|
+
__metadata("design:type", String)
|
|
256
|
+
], EmployeeDto.prototype, "personalEmail", void 0);
|
|
257
|
+
__decorate([
|
|
258
|
+
(0, validator_decorators_1.CustomValidation)((value) => {
|
|
259
|
+
const workDomains = ['company.com', 'corp.com'];
|
|
260
|
+
const domain = value === null || value === void 0 ? void 0 : value.split('@')[1];
|
|
261
|
+
return workDomains.includes(domain);
|
|
262
|
+
}, {
|
|
263
|
+
message: 'Work email must be from company domains',
|
|
264
|
+
}),
|
|
265
|
+
(0, class_validator_1.IsEmail)(),
|
|
266
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
267
|
+
__metadata("design:type", String)
|
|
268
|
+
], EmployeeDto.prototype, "workEmail", void 0);
|
|
269
|
+
__decorate([
|
|
270
|
+
(0, validator_decorators_1.CustomValidationMethod)('validatePhoneFormat'),
|
|
271
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
272
|
+
__metadata("design:type", String)
|
|
273
|
+
], EmployeeDto.prototype, "phone", void 0);
|
|
274
|
+
class PaymentMethodDto {
|
|
275
|
+
validateCreditCard(creditCard) {
|
|
276
|
+
var _a;
|
|
277
|
+
if (!creditCard)
|
|
278
|
+
return true;
|
|
279
|
+
const number = (_a = creditCard.number) === null || _a === void 0 ? void 0 : _a.replace(/\s/g, '');
|
|
280
|
+
if (!/^\d{13,19}$/.test(number))
|
|
281
|
+
return false;
|
|
282
|
+
let sum = 0;
|
|
283
|
+
let isEven = false;
|
|
284
|
+
for (let i = number.length - 1; i >= 0; i--) {
|
|
285
|
+
let digit = parseInt(number[i], 10);
|
|
286
|
+
if (isEven) {
|
|
287
|
+
digit *= 2;
|
|
288
|
+
if (digit > 9)
|
|
289
|
+
digit -= 9;
|
|
290
|
+
}
|
|
291
|
+
sum += digit;
|
|
292
|
+
isEven = !isEven;
|
|
293
|
+
}
|
|
294
|
+
return sum % 10 === 0;
|
|
295
|
+
}
|
|
296
|
+
validateBankAccount(bankAccount) {
|
|
297
|
+
if (!bankAccount)
|
|
298
|
+
return true;
|
|
299
|
+
const accountValid = /^\d{8,17}$/.test(bankAccount.accountNumber);
|
|
300
|
+
const routingValid = /^\d{9}$/.test(bankAccount.routingNumber);
|
|
301
|
+
return accountValid && routingValid;
|
|
302
|
+
}
|
|
303
|
+
validateDigitalWallet(digitalWallet) {
|
|
304
|
+
var _a;
|
|
305
|
+
if (!digitalWallet)
|
|
306
|
+
return true;
|
|
307
|
+
const validProviders = ['paypal', 'alipay', 'wechat_pay', 'apple_pay'];
|
|
308
|
+
return validProviders.includes((_a = digitalWallet.provider) === null || _a === void 0 ? void 0 : _a.toLowerCase());
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
exports.PaymentMethodDto = PaymentMethodDto;
|
|
312
|
+
__decorate([
|
|
313
|
+
(0, swagger_1.ApiProperty)(),
|
|
314
|
+
__metadata("design:type", String)
|
|
315
|
+
], PaymentMethodDto.prototype, "paymentType", void 0);
|
|
316
|
+
__decorate([
|
|
317
|
+
(0, validator_decorators_1.CustomValidationMethod)('validateCreditCard'),
|
|
318
|
+
(0, validator_decorators_1.AtLeastOneField)(['creditCard', 'bankAccount', 'digitalWallet']),
|
|
319
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
320
|
+
__metadata("design:type", Object)
|
|
321
|
+
], PaymentMethodDto.prototype, "creditCard", void 0);
|
|
322
|
+
__decorate([
|
|
323
|
+
(0, validator_decorators_1.CustomValidationMethod)('validateBankAccount'),
|
|
324
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
325
|
+
__metadata("design:type", Object)
|
|
326
|
+
], PaymentMethodDto.prototype, "bankAccount", void 0);
|
|
327
|
+
__decorate([
|
|
328
|
+
(0, validator_decorators_1.CustomValidationMethod)('validateDigitalWallet'),
|
|
329
|
+
(0, swagger_1.ApiProperty)({ required: false }),
|
|
330
|
+
__metadata("design:type", Object)
|
|
331
|
+
], PaymentMethodDto.prototype, "digitalWallet", void 0);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ValidationOptions } from 'class-validator';
|
|
2
|
-
import { IsPhoneNumber as isPhoneNumber } from 'class-validator';
|
|
2
|
+
import { IsPhoneNumber as isPhoneNumber, ValidationArguments, ValidatorConstraintInterface } from 'class-validator';
|
|
3
3
|
export declare function IsPassword(validationOptions?: ValidationOptions): PropertyDecorator;
|
|
4
4
|
export declare function IsPhoneNumber(validationOptions?: ValidationOptions & {
|
|
5
5
|
region?: Parameters<typeof isPhoneNumber>[0];
|
|
@@ -9,3 +9,10 @@ export declare function IsUndefinable(options?: ValidationOptions): PropertyDeco
|
|
|
9
9
|
export declare function IsEmptyable(options?: ValidationOptions): PropertyDecorator;
|
|
10
10
|
export declare function IsNullable(options?: ValidationOptions): PropertyDecorator;
|
|
11
11
|
export declare function IsHttpUrl(validationOptions?: ValidationOptions): (object: any, propertyName: string) => void;
|
|
12
|
+
export declare class AtLeastOneFieldConstraint implements ValidatorConstraintInterface {
|
|
13
|
+
validate(value: any, args: ValidationArguments): boolean;
|
|
14
|
+
defaultMessage(args: ValidationArguments): string;
|
|
15
|
+
}
|
|
16
|
+
export declare function AtLeastOneField(properties: string[], validationOptions?: ValidationOptions): PropertyDecorator;
|
|
17
|
+
export declare function CustomValidation<T = any>(validationCallback: (value: T, args: ValidationArguments) => boolean | Promise<boolean>, validationOptions?: ValidationOptions): PropertyDecorator;
|
|
18
|
+
export declare function CustomValidationMethod(methodName: string, validationOptions?: ValidationOptions): PropertyDecorator;
|
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
9
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
10
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
11
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
12
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
13
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
14
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
15
|
+
});
|
|
16
|
+
};
|
|
2
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.AtLeastOneFieldConstraint = void 0;
|
|
3
19
|
exports.IsPassword = IsPassword;
|
|
4
20
|
exports.IsPhoneNumber = IsPhoneNumber;
|
|
5
21
|
exports.IsTmpKey = IsTmpKey;
|
|
@@ -7,8 +23,12 @@ exports.IsUndefinable = IsUndefinable;
|
|
|
7
23
|
exports.IsEmptyable = IsEmptyable;
|
|
8
24
|
exports.IsNullable = IsNullable;
|
|
9
25
|
exports.IsHttpUrl = IsHttpUrl;
|
|
26
|
+
exports.AtLeastOneField = AtLeastOneField;
|
|
27
|
+
exports.CustomValidation = CustomValidation;
|
|
28
|
+
exports.CustomValidationMethod = CustomValidationMethod;
|
|
10
29
|
const class_validator_1 = require("class-validator");
|
|
11
30
|
const lodash_1 = require("lodash");
|
|
31
|
+
const nestjs_i18n_1 = require("nestjs-i18n");
|
|
12
32
|
function IsPassword(validationOptions) {
|
|
13
33
|
return (object, propertyName) => {
|
|
14
34
|
(0, class_validator_1.registerDecorator)({
|
|
@@ -76,3 +96,98 @@ function IsHttpUrl(validationOptions) {
|
|
|
76
96
|
});
|
|
77
97
|
};
|
|
78
98
|
}
|
|
99
|
+
let AtLeastOneFieldConstraint = class AtLeastOneFieldConstraint {
|
|
100
|
+
validate(value, args) {
|
|
101
|
+
const object = args.object;
|
|
102
|
+
const [requiredProperties] = args.constraints;
|
|
103
|
+
return requiredProperties.some((property) => {
|
|
104
|
+
const propValue = object[property];
|
|
105
|
+
return (propValue !== null &&
|
|
106
|
+
propValue !== undefined &&
|
|
107
|
+
propValue !== '' &&
|
|
108
|
+
!(Array.isArray(propValue) && propValue.length === 0));
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
defaultMessage(args) {
|
|
112
|
+
const [requiredProperties] = args.constraints;
|
|
113
|
+
return `At least one of the following fields must be provided: ${requiredProperties.join(', ')}`;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
exports.AtLeastOneFieldConstraint = AtLeastOneFieldConstraint;
|
|
117
|
+
exports.AtLeastOneFieldConstraint = AtLeastOneFieldConstraint = __decorate([
|
|
118
|
+
(0, class_validator_1.ValidatorConstraint)({ name: 'atLeastOneField', async: false })
|
|
119
|
+
], AtLeastOneFieldConstraint);
|
|
120
|
+
function AtLeastOneField(properties, validationOptions) {
|
|
121
|
+
return function (object, propertyName) {
|
|
122
|
+
(0, class_validator_1.registerDecorator)({
|
|
123
|
+
target: object.constructor,
|
|
124
|
+
propertyName: propertyName,
|
|
125
|
+
options: Object.assign({ message: (0, nestjs_i18n_1.i18nValidationMessage)('validation.AT_LEAST_ONE_FIELD', {
|
|
126
|
+
properties: properties.join(', '),
|
|
127
|
+
}) }, validationOptions),
|
|
128
|
+
constraints: [properties],
|
|
129
|
+
validator: AtLeastOneFieldConstraint,
|
|
130
|
+
});
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function CustomValidation(validationCallback, validationOptions) {
|
|
134
|
+
return function (object, propertyName) {
|
|
135
|
+
(0, class_validator_1.registerDecorator)({
|
|
136
|
+
name: 'customValidation',
|
|
137
|
+
target: object.constructor,
|
|
138
|
+
propertyName,
|
|
139
|
+
options: Object.assign({ message: (0, nestjs_i18n_1.i18nValidationMessage)('validation.CUSTOM_VALIDATION') }, validationOptions),
|
|
140
|
+
validator: {
|
|
141
|
+
validate(value, args) {
|
|
142
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
143
|
+
try {
|
|
144
|
+
return yield validationCallback(value, args);
|
|
145
|
+
}
|
|
146
|
+
catch (error) {
|
|
147
|
+
console.error('CustomValidation error:', error);
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
},
|
|
152
|
+
defaultMessage(args) {
|
|
153
|
+
return `Validation failed for ${args.property}`;
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
});
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function CustomValidationMethod(methodName, validationOptions) {
|
|
160
|
+
return function (object, propertyName) {
|
|
161
|
+
(0, class_validator_1.registerDecorator)({
|
|
162
|
+
name: 'customValidationMethod',
|
|
163
|
+
target: object.constructor,
|
|
164
|
+
propertyName,
|
|
165
|
+
constraints: [methodName],
|
|
166
|
+
options: Object.assign({ message: (0, nestjs_i18n_1.i18nValidationMessage)('validation.CUSTOM_VALIDATION_METHOD') }, validationOptions),
|
|
167
|
+
validator: {
|
|
168
|
+
validate(value, args) {
|
|
169
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
170
|
+
const [method] = args.constraints;
|
|
171
|
+
const object = args.object;
|
|
172
|
+
if (typeof object[method] !== 'function') {
|
|
173
|
+
console.error(`CustomValidationMethod: Method '${method}' not found on object`);
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
const result = yield object[method](value, args);
|
|
178
|
+
return Boolean(result);
|
|
179
|
+
}
|
|
180
|
+
catch (error) {
|
|
181
|
+
console.error(`CustomValidationMethod error in '${method}':`, error);
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
},
|
|
186
|
+
defaultMessage(args) {
|
|
187
|
+
const [method] = args.constraints;
|
|
188
|
+
return `Validation failed for ${args.property} using method ${method}`;
|
|
189
|
+
},
|
|
190
|
+
},
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
}
|
|
@@ -37,5 +37,8 @@
|
|
|
37
37
|
"IS_IP": "{property} value `{value}` not a valid IP",
|
|
38
38
|
"IS_OBJECT": "{property} value `{value}` not a valid Object",
|
|
39
39
|
"IS_TIME_ZONE": "{property} value `{value}` must be a valid IANA time-zone",
|
|
40
|
-
"IS_LOCALE": "{property} value `{value}` must be a valid locale"
|
|
40
|
+
"IS_LOCALE": "{property} value `{value}` must be a valid locale",
|
|
41
|
+
"AT_LEAST_ONE_FIELD": "At least one of the following fields must be provided: {properties}",
|
|
42
|
+
"CUSTOM_VALIDATION": "Custom validation failed for {property}",
|
|
43
|
+
"CUSTOM_VALIDATION_METHOD": "Validation failed for {property}"
|
|
41
44
|
}
|
|
@@ -37,5 +37,8 @@
|
|
|
37
37
|
"IS_IP": "{property} 值 `{value}` 必须是有效IP",
|
|
38
38
|
"IS_OBJECT": "{property} 值 `{value}` 必须是有效对象",
|
|
39
39
|
"IS_TIME_ZONE": "{property} 值 `{value}` 必须是有效时区",
|
|
40
|
-
"IS_LOCALE": "{property} 值 `{value}` 必须是有效语言"
|
|
40
|
+
"IS_LOCALE": "{property} 值 `{value}` 必须是有效语言",
|
|
41
|
+
"AT_LEAST_ONE_FIELD": "以下字段中至少必须提供一个:{properties}",
|
|
42
|
+
"CUSTOM_VALIDATION": "{property}自定义验证失败",
|
|
43
|
+
"CUSTOM_VALIDATION_METHOD": "{property}验证失败"
|
|
41
44
|
}
|
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -27,6 +27,7 @@ __exportStar(require("./common"), exports);
|
|
|
27
27
|
__exportStar(require("./validator-json"), exports);
|
|
28
28
|
__exportStar(require("./helpers"), exports);
|
|
29
29
|
__exportStar(require("./providers"), exports);
|
|
30
|
+
__exportStar(require("./redis-lock"), exports);
|
|
30
31
|
__exportStar(require("./cache"), exports);
|
|
31
32
|
__exportStar(require("./vault"), exports);
|
|
32
33
|
__exportStar(require("./setup"), exports);
|
package/package.json
CHANGED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { RedisLockService } from '../index';
|
|
2
|
+
export declare class SkipStrategyExample {
|
|
3
|
+
private readonly lockService;
|
|
4
|
+
private readonly logger;
|
|
5
|
+
constructor(lockService: RedisLockService);
|
|
6
|
+
scheduledTask(): Promise<void>;
|
|
7
|
+
processWithSkip(): Promise<{
|
|
8
|
+
skipped: boolean;
|
|
9
|
+
success?: undefined;
|
|
10
|
+
} | {
|
|
11
|
+
success: boolean;
|
|
12
|
+
skipped?: undefined;
|
|
13
|
+
}>;
|
|
14
|
+
processWithRetries(): Promise<{
|
|
15
|
+
skipped: boolean;
|
|
16
|
+
success?: undefined;
|
|
17
|
+
} | {
|
|
18
|
+
success: boolean;
|
|
19
|
+
skipped?: undefined;
|
|
20
|
+
}>;
|
|
21
|
+
private simulateLongRunning;
|
|
22
|
+
}
|
|
23
|
+
export declare class ThrowStrategyExample {
|
|
24
|
+
private readonly lockService;
|
|
25
|
+
private readonly logger;
|
|
26
|
+
constructor(lockService: RedisLockService);
|
|
27
|
+
criticalOperation(): Promise<void>;
|
|
28
|
+
processWithThrow(): Promise<{
|
|
29
|
+
success: boolean;
|
|
30
|
+
}>;
|
|
31
|
+
processPayment(orderId: string, amount: number): Promise<{
|
|
32
|
+
success: boolean;
|
|
33
|
+
}>;
|
|
34
|
+
private processData;
|
|
35
|
+
private chargePayment;
|
|
36
|
+
private updateOrderStatus;
|
|
37
|
+
}
|
|
38
|
+
export declare class WaitStrategyExample {
|
|
39
|
+
private readonly lockService;
|
|
40
|
+
private readonly logger;
|
|
41
|
+
constructor(lockService: RedisLockService);
|
|
42
|
+
sequentialTask(): Promise<void>;
|
|
43
|
+
processWithWaitTimeout(): Promise<{
|
|
44
|
+
timeout: boolean;
|
|
45
|
+
success?: undefined;
|
|
46
|
+
} | {
|
|
47
|
+
success: boolean;
|
|
48
|
+
timeout?: undefined;
|
|
49
|
+
}>;
|
|
50
|
+
processDataSequentially(userId: string, data: any): Promise<{
|
|
51
|
+
success: boolean;
|
|
52
|
+
}>;
|
|
53
|
+
processQueue(queueName: string, item: any): Promise<{
|
|
54
|
+
success: boolean;
|
|
55
|
+
}>;
|
|
56
|
+
runMigration(migrationName: string): Promise<{
|
|
57
|
+
success: boolean;
|
|
58
|
+
}>;
|
|
59
|
+
private processInOrder;
|
|
60
|
+
private validateData;
|
|
61
|
+
private saveData;
|
|
62
|
+
private notifyUser;
|
|
63
|
+
private processQueueItem;
|
|
64
|
+
private executeMigration;
|
|
65
|
+
}
|
|
66
|
+
export declare class CombinedStrategiesExample {
|
|
67
|
+
private readonly lockService;
|
|
68
|
+
private readonly logger;
|
|
69
|
+
constructor(lockService: RedisLockService);
|
|
70
|
+
cleanupOldData(): Promise<void>;
|
|
71
|
+
processPayment(orderId: string): Promise<void>;
|
|
72
|
+
generateReport(reportId: string): Promise<void>;
|
|
73
|
+
}
|