@vigneshreddy/cms-sdk 1.0.14 → 1.0.15
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 +122 -37
- package/dist/src/circuit-breaker.d.ts +97 -0
- package/dist/src/circuit-breaker.js +162 -0
- package/dist/src/client.d.ts +3 -3
- package/dist/src/client.js +37 -12
- package/dist/src/constants/constants.d.ts +128 -0
- package/dist/src/constants/constants.js +182 -0
- package/dist/src/constants.d.ts +128 -0
- package/dist/src/constants.js +182 -0
- package/dist/src/errors.d.ts +1 -0
- package/dist/src/errors.js +20 -4
- package/dist/src/funcs/api.d.ts +192 -0
- package/dist/src/funcs/api.js +276 -0
- package/dist/src/funcs/base.d.ts +46 -0
- package/dist/src/funcs/base.js +40 -0
- package/dist/src/funcs/common.d.ts +20 -0
- package/dist/src/funcs/common.js +103 -0
- package/dist/src/funcs/configuration.d.ts +87 -0
- package/dist/src/funcs/configuration.js +37 -0
- package/dist/src/funcs/index.d.ts +4 -0
- package/dist/src/funcs/index.js +20 -0
- package/dist/src/index.d.ts +5 -0
- package/dist/src/index.js +28 -1
- package/dist/src/rate-limiter.d.ts +74 -0
- package/dist/src/rate-limiter.js +109 -0
- package/dist/src/validation.d.ts +119 -0
- package/dist/src/validation.js +196 -0
- package/dist/src/validations/validation.d.ts +119 -0
- package/dist/src/validations/validation.js +196 -0
- package/package.json +7 -2
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SalePayloadSchema = exports.LeadPayloadSchema = exports.CMSConfigSchema = void 0;
|
|
4
|
+
exports.validateLeadPayload = validateLeadPayload;
|
|
5
|
+
exports.validateSalePayload = validateSalePayload;
|
|
6
|
+
exports.validateCMSConfig = validateCMSConfig;
|
|
7
|
+
exports.sanitizeForLogging = sanitizeForLogging;
|
|
8
|
+
exports.redactApiKey = redactApiKey;
|
|
9
|
+
/**
|
|
10
|
+
* Input validation schemas using Zod
|
|
11
|
+
* Ensures all incoming data is sanitized and valid
|
|
12
|
+
*/
|
|
13
|
+
const zod_1 = require("zod");
|
|
14
|
+
const constants_1 = require("./constants");
|
|
15
|
+
exports.CMSConfigSchema = zod_1.z.object({
|
|
16
|
+
apiKey: zod_1.z
|
|
17
|
+
.string()
|
|
18
|
+
.min(1, constants_1.ERROR_MESSAGES.API_KEY_REQUIRED)
|
|
19
|
+
.refine((key) => constants_1.VALIDATION_CONSTRAINTS.API_KEY.PATTERN.test(key), constants_1.ERROR_MESSAGES.API_KEY_INVALID_FORMAT),
|
|
20
|
+
baseUrl: zod_1.z
|
|
21
|
+
.string()
|
|
22
|
+
.url(constants_1.ERROR_MESSAGES.BASE_URL_INVALID)
|
|
23
|
+
.optional(),
|
|
24
|
+
timeout: zod_1.z
|
|
25
|
+
.number()
|
|
26
|
+
.int()
|
|
27
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.TIMEOUT.MIN_MS, constants_1.ERROR_MESSAGES.TIMEOUT_TOO_LOW)
|
|
28
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.TIMEOUT.MAX_MS, constants_1.ERROR_MESSAGES.TIMEOUT_TOO_HIGH)
|
|
29
|
+
.optional(),
|
|
30
|
+
maxRetries: zod_1.z
|
|
31
|
+
.number()
|
|
32
|
+
.int()
|
|
33
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.MAX_RETRIES.MIN, constants_1.ERROR_MESSAGES.MAX_RETRIES_NEGATIVE)
|
|
34
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.MAX_RETRIES.MAX, constants_1.ERROR_MESSAGES.MAX_RETRIES_TOO_HIGH)
|
|
35
|
+
.optional(),
|
|
36
|
+
retryDelayMs: zod_1.z
|
|
37
|
+
.number()
|
|
38
|
+
.int()
|
|
39
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.RETRY_DELAY.MIN_MS, constants_1.ERROR_MESSAGES.RETRY_DELAY_TOO_LOW)
|
|
40
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.RETRY_DELAY.MAX_MS, constants_1.ERROR_MESSAGES.RETRY_DELAY_TOO_HIGH)
|
|
41
|
+
.optional(),
|
|
42
|
+
retryMaxDelayMs: zod_1.z
|
|
43
|
+
.number()
|
|
44
|
+
.int()
|
|
45
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.RETRY_MAX_DELAY.MIN_MS, constants_1.ERROR_MESSAGES.RETRY_MAX_DELAY_TOO_LOW)
|
|
46
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.RETRY_MAX_DELAY.MAX_MS, constants_1.ERROR_MESSAGES.RETRY_MAX_DELAY_TOO_HIGH)
|
|
47
|
+
.optional(),
|
|
48
|
+
retryOnStatuses: zod_1.z
|
|
49
|
+
.array(zod_1.z.number().int().min(100).max(599))
|
|
50
|
+
.optional(),
|
|
51
|
+
retryOnNetworkError: zod_1.z.boolean().optional(),
|
|
52
|
+
});
|
|
53
|
+
// Lead payload validation
|
|
54
|
+
exports.LeadPayloadSchema = zod_1.z.object({
|
|
55
|
+
clickId: zod_1.z
|
|
56
|
+
.string()
|
|
57
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CLICK_ID.MIN)
|
|
58
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CLICK_ID.MAX)
|
|
59
|
+
.optional(),
|
|
60
|
+
eventName: zod_1.z
|
|
61
|
+
.string()
|
|
62
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.EVENT_NAME.MIN, constants_1.ERROR_MESSAGES.EVENT_NAME_REQUIRED)
|
|
63
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.EVENT_NAME.MAX, constants_1.ERROR_MESSAGES.EVENT_NAME_TOO_LONG),
|
|
64
|
+
customerExternalId: zod_1.z
|
|
65
|
+
.string()
|
|
66
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EXTERNAL_ID.MIN, constants_1.ERROR_MESSAGES.CUSTOMER_EXTERNAL_ID_REQUIRED)
|
|
67
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EXTERNAL_ID.MAX, constants_1.ERROR_MESSAGES.CUSTOMER_EXTERNAL_ID_TOO_LONG),
|
|
68
|
+
timestamp: zod_1.z
|
|
69
|
+
.string()
|
|
70
|
+
.datetime()
|
|
71
|
+
.optional(),
|
|
72
|
+
customerId: zod_1.z
|
|
73
|
+
.string()
|
|
74
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_ID.MAX)
|
|
75
|
+
.optional(),
|
|
76
|
+
customerName: zod_1.z
|
|
77
|
+
.string()
|
|
78
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_NAME.MAX)
|
|
79
|
+
.optional(),
|
|
80
|
+
customerEmail: zod_1.z
|
|
81
|
+
.string()
|
|
82
|
+
.email(constants_1.ERROR_MESSAGES.CUSTOMER_EMAIL_INVALID)
|
|
83
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EMAIL.MAX, constants_1.ERROR_MESSAGES.CUSTOMER_EMAIL_TOO_LONG)
|
|
84
|
+
.optional(),
|
|
85
|
+
customerAvatar: zod_1.z
|
|
86
|
+
.string()
|
|
87
|
+
.url(constants_1.ERROR_MESSAGES.CUSTOMER_AVATAR_INVALID)
|
|
88
|
+
.optional(),
|
|
89
|
+
mode: zod_1.z
|
|
90
|
+
.enum(["deferred"])
|
|
91
|
+
.optional(),
|
|
92
|
+
});
|
|
93
|
+
// Sale payload validation
|
|
94
|
+
exports.SalePayloadSchema = zod_1.z.object({
|
|
95
|
+
clickId: zod_1.z
|
|
96
|
+
.string()
|
|
97
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CLICK_ID.MIN)
|
|
98
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CLICK_ID.MAX)
|
|
99
|
+
.optional(),
|
|
100
|
+
eventName: zod_1.z
|
|
101
|
+
.string()
|
|
102
|
+
.optional(),
|
|
103
|
+
invoiceId: zod_1.z
|
|
104
|
+
.string()
|
|
105
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.INVOICE_ID.MIN, constants_1.ERROR_MESSAGES.INVOICE_ID_REQUIRED)
|
|
106
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.INVOICE_ID.MAX, constants_1.ERROR_MESSAGES.INVOICE_ID_TOO_LONG),
|
|
107
|
+
amount: zod_1.z
|
|
108
|
+
.number()
|
|
109
|
+
.int()
|
|
110
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.AMOUNT.MIN, constants_1.ERROR_MESSAGES.AMOUNT_NEGATIVE),
|
|
111
|
+
currency: zod_1.z
|
|
112
|
+
.string()
|
|
113
|
+
.length(constants_1.VALIDATION_CONSTRAINTS.CURRENCY.LENGTH, constants_1.ERROR_MESSAGES.CURRENCY_INVALID_LENGTH)
|
|
114
|
+
.regex(constants_1.VALIDATION_CONSTRAINTS.CURRENCY.PATTERN, constants_1.ERROR_MESSAGES.CURRENCY_INVALID_FORMAT)
|
|
115
|
+
.optional(),
|
|
116
|
+
timestamp: zod_1.z
|
|
117
|
+
.string()
|
|
118
|
+
.datetime()
|
|
119
|
+
.optional(),
|
|
120
|
+
customerId: zod_1.z
|
|
121
|
+
.string()
|
|
122
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_ID.MAX)
|
|
123
|
+
.optional(),
|
|
124
|
+
customerExternalId: zod_1.z
|
|
125
|
+
.string()
|
|
126
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EXTERNAL_ID.MAX)
|
|
127
|
+
.optional(),
|
|
128
|
+
customerName: zod_1.z
|
|
129
|
+
.string()
|
|
130
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_NAME.MAX)
|
|
131
|
+
.optional(),
|
|
132
|
+
customerEmail: zod_1.z
|
|
133
|
+
.string()
|
|
134
|
+
.email(constants_1.ERROR_MESSAGES.CUSTOMER_EMAIL_INVALID)
|
|
135
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EMAIL.MAX, constants_1.ERROR_MESSAGES.CUSTOMER_EMAIL_TOO_LONG)
|
|
136
|
+
.optional(),
|
|
137
|
+
mode: zod_1.z
|
|
138
|
+
.enum(["deferred"])
|
|
139
|
+
.optional(),
|
|
140
|
+
});
|
|
141
|
+
/**
|
|
142
|
+
* Validates input data and throws detailed error if invalid
|
|
143
|
+
*/
|
|
144
|
+
function validateLeadPayload(data) {
|
|
145
|
+
return exports.LeadPayloadSchema.parse(data);
|
|
146
|
+
}
|
|
147
|
+
function validateSalePayload(data) {
|
|
148
|
+
return exports.SalePayloadSchema.parse(data);
|
|
149
|
+
}
|
|
150
|
+
function validateCMSConfig(data) {
|
|
151
|
+
return exports.CMSConfigSchema.parse(data);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Sanitizes sensitive data for logging/errors
|
|
155
|
+
* Removes API keys, tokens, and other credentials
|
|
156
|
+
*/
|
|
157
|
+
function sanitizeForLogging(obj) {
|
|
158
|
+
if (!obj || typeof obj !== "object") {
|
|
159
|
+
return obj;
|
|
160
|
+
}
|
|
161
|
+
if (Array.isArray(obj)) {
|
|
162
|
+
return obj.map((item) => sanitizeForLogging(item));
|
|
163
|
+
}
|
|
164
|
+
const sanitized = {};
|
|
165
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
166
|
+
const lowerKey = key.toLowerCase();
|
|
167
|
+
// Mask sensitive field names
|
|
168
|
+
if (constants_1.SENSITIVE_FIELDS.PATTERNS.some((field) => lowerKey.includes(field))) {
|
|
169
|
+
sanitized[key] = typeof value === "string" ? constants_1.SENSITIVE_FIELDS.REDACTION_PLACEHOLDER : value;
|
|
170
|
+
}
|
|
171
|
+
else if (typeof value === "object" && value !== null) {
|
|
172
|
+
sanitized[key] = sanitizeForLogging(value);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
sanitized[key] = value;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return sanitized;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Redacts API key from error messages
|
|
182
|
+
*/
|
|
183
|
+
function redactApiKey(message, apiKey) {
|
|
184
|
+
if (!apiKey)
|
|
185
|
+
return message;
|
|
186
|
+
// Replace the full key and common patterns
|
|
187
|
+
const patterns = [
|
|
188
|
+
apiKey,
|
|
189
|
+
apiKey.substring(0, 3) + "***" + apiKey.substring(apiKey.length - 3),
|
|
190
|
+
];
|
|
191
|
+
let result = message;
|
|
192
|
+
for (const pattern of patterns) {
|
|
193
|
+
result = result.replace(new RegExp(pattern, "g"), constants_1.SENSITIVE_FIELDS.API_KEY_REDACTION);
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation schemas using Zod
|
|
3
|
+
* Ensures all incoming data is sanitized and valid
|
|
4
|
+
*/
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
export declare const CMSConfigSchema: z.ZodObject<{
|
|
7
|
+
apiKey: z.ZodEffects<z.ZodString, string, string>;
|
|
8
|
+
baseUrl: z.ZodOptional<z.ZodString>;
|
|
9
|
+
timeout: z.ZodOptional<z.ZodNumber>;
|
|
10
|
+
maxRetries: z.ZodOptional<z.ZodNumber>;
|
|
11
|
+
retryDelayMs: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
retryMaxDelayMs: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
retryOnStatuses: z.ZodOptional<z.ZodArray<z.ZodNumber, "many">>;
|
|
14
|
+
retryOnNetworkError: z.ZodOptional<z.ZodBoolean>;
|
|
15
|
+
}, "strip", z.ZodTypeAny, {
|
|
16
|
+
apiKey: string;
|
|
17
|
+
timeout?: number | undefined;
|
|
18
|
+
baseUrl?: string | undefined;
|
|
19
|
+
maxRetries?: number | undefined;
|
|
20
|
+
retryDelayMs?: number | undefined;
|
|
21
|
+
retryMaxDelayMs?: number | undefined;
|
|
22
|
+
retryOnStatuses?: number[] | undefined;
|
|
23
|
+
retryOnNetworkError?: boolean | undefined;
|
|
24
|
+
}, {
|
|
25
|
+
apiKey: string;
|
|
26
|
+
timeout?: number | undefined;
|
|
27
|
+
baseUrl?: string | undefined;
|
|
28
|
+
maxRetries?: number | undefined;
|
|
29
|
+
retryDelayMs?: number | undefined;
|
|
30
|
+
retryMaxDelayMs?: number | undefined;
|
|
31
|
+
retryOnStatuses?: number[] | undefined;
|
|
32
|
+
retryOnNetworkError?: boolean | undefined;
|
|
33
|
+
}>;
|
|
34
|
+
export type CMSConfigInput = z.infer<typeof CMSConfigSchema>;
|
|
35
|
+
export declare const LeadPayloadSchema: z.ZodObject<{
|
|
36
|
+
clickId: z.ZodOptional<z.ZodString>;
|
|
37
|
+
eventName: z.ZodString;
|
|
38
|
+
customerExternalId: z.ZodString;
|
|
39
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
40
|
+
customerId: z.ZodOptional<z.ZodString>;
|
|
41
|
+
customerName: z.ZodOptional<z.ZodString>;
|
|
42
|
+
customerEmail: z.ZodOptional<z.ZodString>;
|
|
43
|
+
customerAvatar: z.ZodOptional<z.ZodString>;
|
|
44
|
+
mode: z.ZodOptional<z.ZodEnum<["deferred"]>>;
|
|
45
|
+
}, "strip", z.ZodTypeAny, {
|
|
46
|
+
eventName: string;
|
|
47
|
+
customerExternalId: string;
|
|
48
|
+
clickId?: string | undefined;
|
|
49
|
+
timestamp?: string | undefined;
|
|
50
|
+
customerId?: string | undefined;
|
|
51
|
+
customerName?: string | undefined;
|
|
52
|
+
customerEmail?: string | undefined;
|
|
53
|
+
customerAvatar?: string | undefined;
|
|
54
|
+
mode?: "deferred" | undefined;
|
|
55
|
+
}, {
|
|
56
|
+
eventName: string;
|
|
57
|
+
customerExternalId: string;
|
|
58
|
+
clickId?: string | undefined;
|
|
59
|
+
timestamp?: string | undefined;
|
|
60
|
+
customerId?: string | undefined;
|
|
61
|
+
customerName?: string | undefined;
|
|
62
|
+
customerEmail?: string | undefined;
|
|
63
|
+
customerAvatar?: string | undefined;
|
|
64
|
+
mode?: "deferred" | undefined;
|
|
65
|
+
}>;
|
|
66
|
+
export type LeadPayloadInput = z.infer<typeof LeadPayloadSchema>;
|
|
67
|
+
export declare const SalePayloadSchema: z.ZodObject<{
|
|
68
|
+
clickId: z.ZodOptional<z.ZodString>;
|
|
69
|
+
eventName: z.ZodOptional<z.ZodString>;
|
|
70
|
+
invoiceId: z.ZodString;
|
|
71
|
+
amount: z.ZodNumber;
|
|
72
|
+
currency: z.ZodOptional<z.ZodString>;
|
|
73
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
74
|
+
customerId: z.ZodOptional<z.ZodString>;
|
|
75
|
+
customerExternalId: z.ZodOptional<z.ZodString>;
|
|
76
|
+
customerName: z.ZodOptional<z.ZodString>;
|
|
77
|
+
customerEmail: z.ZodOptional<z.ZodString>;
|
|
78
|
+
mode: z.ZodOptional<z.ZodEnum<["deferred"]>>;
|
|
79
|
+
}, "strip", z.ZodTypeAny, {
|
|
80
|
+
invoiceId: string;
|
|
81
|
+
amount: number;
|
|
82
|
+
clickId?: string | undefined;
|
|
83
|
+
eventName?: string | undefined;
|
|
84
|
+
customerExternalId?: string | undefined;
|
|
85
|
+
timestamp?: string | undefined;
|
|
86
|
+
customerId?: string | undefined;
|
|
87
|
+
customerName?: string | undefined;
|
|
88
|
+
customerEmail?: string | undefined;
|
|
89
|
+
mode?: "deferred" | undefined;
|
|
90
|
+
currency?: string | undefined;
|
|
91
|
+
}, {
|
|
92
|
+
invoiceId: string;
|
|
93
|
+
amount: number;
|
|
94
|
+
clickId?: string | undefined;
|
|
95
|
+
eventName?: string | undefined;
|
|
96
|
+
customerExternalId?: string | undefined;
|
|
97
|
+
timestamp?: string | undefined;
|
|
98
|
+
customerId?: string | undefined;
|
|
99
|
+
customerName?: string | undefined;
|
|
100
|
+
customerEmail?: string | undefined;
|
|
101
|
+
mode?: "deferred" | undefined;
|
|
102
|
+
currency?: string | undefined;
|
|
103
|
+
}>;
|
|
104
|
+
export type SalePayloadInput = z.infer<typeof SalePayloadSchema>;
|
|
105
|
+
/**
|
|
106
|
+
* Validates input data and throws detailed error if invalid
|
|
107
|
+
*/
|
|
108
|
+
export declare function validateLeadPayload(data: unknown): LeadPayloadInput;
|
|
109
|
+
export declare function validateSalePayload(data: unknown): SalePayloadInput;
|
|
110
|
+
export declare function validateCMSConfig(data: unknown): CMSConfigInput;
|
|
111
|
+
/**
|
|
112
|
+
* Sanitizes sensitive data for logging/errors
|
|
113
|
+
* Removes API keys, tokens, and other credentials
|
|
114
|
+
*/
|
|
115
|
+
export declare function sanitizeForLogging(obj: any): any;
|
|
116
|
+
/**
|
|
117
|
+
* Redacts API key from error messages
|
|
118
|
+
*/
|
|
119
|
+
export declare function redactApiKey(message: string, apiKey?: string): string;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SalePayloadSchema = exports.LeadPayloadSchema = exports.CMSConfigSchema = void 0;
|
|
4
|
+
exports.validateLeadPayload = validateLeadPayload;
|
|
5
|
+
exports.validateSalePayload = validateSalePayload;
|
|
6
|
+
exports.validateCMSConfig = validateCMSConfig;
|
|
7
|
+
exports.sanitizeForLogging = sanitizeForLogging;
|
|
8
|
+
exports.redactApiKey = redactApiKey;
|
|
9
|
+
/**
|
|
10
|
+
* Input validation schemas using Zod
|
|
11
|
+
* Ensures all incoming data is sanitized and valid
|
|
12
|
+
*/
|
|
13
|
+
const zod_1 = require("zod");
|
|
14
|
+
const constants_1 = require("../constants/constants");
|
|
15
|
+
exports.CMSConfigSchema = zod_1.z.object({
|
|
16
|
+
apiKey: zod_1.z
|
|
17
|
+
.string()
|
|
18
|
+
.min(1, constants_1.ERROR_MESSAGES.API_KEY_REQUIRED)
|
|
19
|
+
.refine((key) => constants_1.VALIDATION_CONSTRAINTS.API_KEY.PATTERN.test(key), constants_1.ERROR_MESSAGES.API_KEY_INVALID_FORMAT),
|
|
20
|
+
baseUrl: zod_1.z
|
|
21
|
+
.string()
|
|
22
|
+
.url(constants_1.ERROR_MESSAGES.BASE_URL_INVALID)
|
|
23
|
+
.optional(),
|
|
24
|
+
timeout: zod_1.z
|
|
25
|
+
.number()
|
|
26
|
+
.int()
|
|
27
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.TIMEOUT.MIN_MS, constants_1.ERROR_MESSAGES.TIMEOUT_TOO_LOW)
|
|
28
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.TIMEOUT.MAX_MS, constants_1.ERROR_MESSAGES.TIMEOUT_TOO_HIGH)
|
|
29
|
+
.optional(),
|
|
30
|
+
maxRetries: zod_1.z
|
|
31
|
+
.number()
|
|
32
|
+
.int()
|
|
33
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.MAX_RETRIES.MIN, constants_1.ERROR_MESSAGES.MAX_RETRIES_NEGATIVE)
|
|
34
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.MAX_RETRIES.MAX, constants_1.ERROR_MESSAGES.MAX_RETRIES_TOO_HIGH)
|
|
35
|
+
.optional(),
|
|
36
|
+
retryDelayMs: zod_1.z
|
|
37
|
+
.number()
|
|
38
|
+
.int()
|
|
39
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.RETRY_DELAY.MIN_MS, constants_1.ERROR_MESSAGES.RETRY_DELAY_TOO_LOW)
|
|
40
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.RETRY_DELAY.MAX_MS, constants_1.ERROR_MESSAGES.RETRY_DELAY_TOO_HIGH)
|
|
41
|
+
.optional(),
|
|
42
|
+
retryMaxDelayMs: zod_1.z
|
|
43
|
+
.number()
|
|
44
|
+
.int()
|
|
45
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.RETRY_MAX_DELAY.MIN_MS, constants_1.ERROR_MESSAGES.RETRY_MAX_DELAY_TOO_LOW)
|
|
46
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.RETRY_MAX_DELAY.MAX_MS, constants_1.ERROR_MESSAGES.RETRY_MAX_DELAY_TOO_HIGH)
|
|
47
|
+
.optional(),
|
|
48
|
+
retryOnStatuses: zod_1.z
|
|
49
|
+
.array(zod_1.z.number().int().min(100).max(599))
|
|
50
|
+
.optional(),
|
|
51
|
+
retryOnNetworkError: zod_1.z.boolean().optional(),
|
|
52
|
+
});
|
|
53
|
+
// Lead payload validation
|
|
54
|
+
exports.LeadPayloadSchema = zod_1.z.object({
|
|
55
|
+
clickId: zod_1.z
|
|
56
|
+
.string()
|
|
57
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CLICK_ID.MIN)
|
|
58
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CLICK_ID.MAX)
|
|
59
|
+
.optional(),
|
|
60
|
+
eventName: zod_1.z
|
|
61
|
+
.string()
|
|
62
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.EVENT_NAME.MIN, constants_1.ERROR_MESSAGES.EVENT_NAME_REQUIRED)
|
|
63
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.EVENT_NAME.MAX, constants_1.ERROR_MESSAGES.EVENT_NAME_TOO_LONG),
|
|
64
|
+
customerExternalId: zod_1.z
|
|
65
|
+
.string()
|
|
66
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EXTERNAL_ID.MIN, constants_1.ERROR_MESSAGES.CUSTOMER_EXTERNAL_ID_REQUIRED)
|
|
67
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EXTERNAL_ID.MAX, constants_1.ERROR_MESSAGES.CUSTOMER_EXTERNAL_ID_TOO_LONG),
|
|
68
|
+
timestamp: zod_1.z
|
|
69
|
+
.string()
|
|
70
|
+
.datetime()
|
|
71
|
+
.optional(),
|
|
72
|
+
customerId: zod_1.z
|
|
73
|
+
.string()
|
|
74
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_ID.MAX)
|
|
75
|
+
.optional(),
|
|
76
|
+
customerName: zod_1.z
|
|
77
|
+
.string()
|
|
78
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_NAME.MAX)
|
|
79
|
+
.optional(),
|
|
80
|
+
customerEmail: zod_1.z
|
|
81
|
+
.string()
|
|
82
|
+
.email(constants_1.ERROR_MESSAGES.CUSTOMER_EMAIL_INVALID)
|
|
83
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EMAIL.MAX, constants_1.ERROR_MESSAGES.CUSTOMER_EMAIL_TOO_LONG)
|
|
84
|
+
.optional(),
|
|
85
|
+
customerAvatar: zod_1.z
|
|
86
|
+
.string()
|
|
87
|
+
.url(constants_1.ERROR_MESSAGES.CUSTOMER_AVATAR_INVALID)
|
|
88
|
+
.optional(),
|
|
89
|
+
mode: zod_1.z
|
|
90
|
+
.enum(["deferred"])
|
|
91
|
+
.optional(),
|
|
92
|
+
});
|
|
93
|
+
// Sale payload validation
|
|
94
|
+
exports.SalePayloadSchema = zod_1.z.object({
|
|
95
|
+
clickId: zod_1.z
|
|
96
|
+
.string()
|
|
97
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CLICK_ID.MIN)
|
|
98
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CLICK_ID.MAX)
|
|
99
|
+
.optional(),
|
|
100
|
+
eventName: zod_1.z
|
|
101
|
+
.string()
|
|
102
|
+
.optional(),
|
|
103
|
+
invoiceId: zod_1.z
|
|
104
|
+
.string()
|
|
105
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.INVOICE_ID.MIN, constants_1.ERROR_MESSAGES.INVOICE_ID_REQUIRED)
|
|
106
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.INVOICE_ID.MAX, constants_1.ERROR_MESSAGES.INVOICE_ID_TOO_LONG),
|
|
107
|
+
amount: zod_1.z
|
|
108
|
+
.number()
|
|
109
|
+
.int()
|
|
110
|
+
.min(constants_1.VALIDATION_CONSTRAINTS.AMOUNT.MIN, constants_1.ERROR_MESSAGES.AMOUNT_NEGATIVE),
|
|
111
|
+
currency: zod_1.z
|
|
112
|
+
.string()
|
|
113
|
+
.length(constants_1.VALIDATION_CONSTRAINTS.CURRENCY.LENGTH, constants_1.ERROR_MESSAGES.CURRENCY_INVALID_LENGTH)
|
|
114
|
+
.regex(constants_1.VALIDATION_CONSTRAINTS.CURRENCY.PATTERN, constants_1.ERROR_MESSAGES.CURRENCY_INVALID_FORMAT)
|
|
115
|
+
.optional(),
|
|
116
|
+
timestamp: zod_1.z
|
|
117
|
+
.string()
|
|
118
|
+
.datetime()
|
|
119
|
+
.optional(),
|
|
120
|
+
customerId: zod_1.z
|
|
121
|
+
.string()
|
|
122
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_ID.MAX)
|
|
123
|
+
.optional(),
|
|
124
|
+
customerExternalId: zod_1.z
|
|
125
|
+
.string()
|
|
126
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EXTERNAL_ID.MAX)
|
|
127
|
+
.optional(),
|
|
128
|
+
customerName: zod_1.z
|
|
129
|
+
.string()
|
|
130
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_NAME.MAX)
|
|
131
|
+
.optional(),
|
|
132
|
+
customerEmail: zod_1.z
|
|
133
|
+
.string()
|
|
134
|
+
.email(constants_1.ERROR_MESSAGES.CUSTOMER_EMAIL_INVALID)
|
|
135
|
+
.max(constants_1.VALIDATION_CONSTRAINTS.STRING_FIELDS.CUSTOMER_EMAIL.MAX, constants_1.ERROR_MESSAGES.CUSTOMER_EMAIL_TOO_LONG)
|
|
136
|
+
.optional(),
|
|
137
|
+
mode: zod_1.z
|
|
138
|
+
.enum(["deferred"])
|
|
139
|
+
.optional(),
|
|
140
|
+
});
|
|
141
|
+
/**
|
|
142
|
+
* Validates input data and throws detailed error if invalid
|
|
143
|
+
*/
|
|
144
|
+
function validateLeadPayload(data) {
|
|
145
|
+
return exports.LeadPayloadSchema.parse(data);
|
|
146
|
+
}
|
|
147
|
+
function validateSalePayload(data) {
|
|
148
|
+
return exports.SalePayloadSchema.parse(data);
|
|
149
|
+
}
|
|
150
|
+
function validateCMSConfig(data) {
|
|
151
|
+
return exports.CMSConfigSchema.parse(data);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Sanitizes sensitive data for logging/errors
|
|
155
|
+
* Removes API keys, tokens, and other credentials
|
|
156
|
+
*/
|
|
157
|
+
function sanitizeForLogging(obj) {
|
|
158
|
+
if (!obj || typeof obj !== "object") {
|
|
159
|
+
return obj;
|
|
160
|
+
}
|
|
161
|
+
if (Array.isArray(obj)) {
|
|
162
|
+
return obj.map((item) => sanitizeForLogging(item));
|
|
163
|
+
}
|
|
164
|
+
const sanitized = {};
|
|
165
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
166
|
+
const lowerKey = key.toLowerCase();
|
|
167
|
+
// Mask sensitive field names
|
|
168
|
+
if (constants_1.SENSITIVE_FIELDS.PATTERNS.some((field) => lowerKey.includes(field))) {
|
|
169
|
+
sanitized[key] = typeof value === "string" ? constants_1.SENSITIVE_FIELDS.REDACTION_PLACEHOLDER : value;
|
|
170
|
+
}
|
|
171
|
+
else if (typeof value === "object" && value !== null) {
|
|
172
|
+
sanitized[key] = sanitizeForLogging(value);
|
|
173
|
+
}
|
|
174
|
+
else {
|
|
175
|
+
sanitized[key] = value;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return sanitized;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Redacts API key from error messages
|
|
182
|
+
*/
|
|
183
|
+
function redactApiKey(message, apiKey) {
|
|
184
|
+
if (!apiKey)
|
|
185
|
+
return message;
|
|
186
|
+
// Replace the full key and common patterns
|
|
187
|
+
const patterns = [
|
|
188
|
+
apiKey,
|
|
189
|
+
apiKey.substring(0, 3) + "***" + apiKey.substring(apiKey.length - 3),
|
|
190
|
+
];
|
|
191
|
+
let result = message;
|
|
192
|
+
for (const pattern of patterns) {
|
|
193
|
+
result = result.replace(new RegExp(pattern, "g"), constants_1.SENSITIVE_FIELDS.API_KEY_REDACTION);
|
|
194
|
+
}
|
|
195
|
+
return result;
|
|
196
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vigneshreddy/cms-sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.15",
|
|
4
4
|
"description": "Official TypeScript SDK for CutMeShort CMS API",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
],
|
|
18
18
|
"scripts": {
|
|
19
19
|
"build": "tsc -p tsconfig.json",
|
|
20
|
-
"test": "vitest"
|
|
20
|
+
"test": "vitest",
|
|
21
|
+
"audit": "npm audit --audit-level=moderate",
|
|
22
|
+
"security-check": "npm audit && npm ls"
|
|
21
23
|
},
|
|
22
24
|
"keywords": [
|
|
23
25
|
"cutmeshort",
|
|
@@ -42,6 +44,9 @@
|
|
|
42
44
|
},
|
|
43
45
|
"author": "Vignesh Reddy",
|
|
44
46
|
"license": "MIT",
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"zod": "^3.22.0"
|
|
49
|
+
},
|
|
45
50
|
"devDependencies": {
|
|
46
51
|
"typescript": "^5.7.0",
|
|
47
52
|
"vitest": "^4.0.18"
|