@oxyhq/core 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/i18n/locales/locales/ar-SA.json +1 -1
- package/dist/cjs/i18n/locales/locales/ca-ES.json +1 -1
- package/dist/cjs/i18n/locales/locales/de-DE.json +1 -1
- package/dist/cjs/i18n/locales/locales/fr-FR.json +1 -1
- package/dist/cjs/i18n/locales/locales/it-IT.json +1 -1
- package/dist/cjs/i18n/locales/locales/ja-JP.json +1 -1
- package/dist/cjs/i18n/locales/locales/ko-KR.json +1 -1
- package/dist/cjs/i18n/locales/locales/pt-PT.json +1 -1
- package/dist/cjs/i18n/locales/locales/zh-CN.json +1 -1
- package/dist/esm/i18n/locales/locales/ar-SA.json +1 -1
- package/dist/esm/i18n/locales/locales/ca-ES.json +1 -1
- package/dist/esm/i18n/locales/locales/de-DE.json +1 -1
- package/dist/esm/i18n/locales/locales/fr-FR.json +1 -1
- package/dist/esm/i18n/locales/locales/it-IT.json +1 -1
- package/dist/esm/i18n/locales/locales/ja-JP.json +1 -1
- package/dist/esm/i18n/locales/locales/ko-KR.json +1 -1
- package/dist/esm/i18n/locales/locales/pt-PT.json +1 -1
- package/dist/esm/i18n/locales/locales/zh-CN.json +1 -1
- package/package.json +2 -2
- package/src/i18n/locales/ar-SA.json +1 -1
- package/src/i18n/locales/ca-ES.json +1 -1
- package/src/i18n/locales/de-DE.json +1 -1
- package/src/i18n/locales/fr-FR.json +1 -1
- package/src/i18n/locales/it-IT.json +1 -1
- package/src/i18n/locales/ja-JP.json +1 -1
- package/src/i18n/locales/ko-KR.json +1 -1
- package/src/i18n/locales/pt-PT.json +1 -1
- package/src/i18n/locales/zh-CN.json +1 -1
- package/src/utils/__tests__/validationUtils.test.ts +236 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oxyhq/core",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "OxyHQ SDK Foundation — API client, authentication, cryptographic identity, and shared utilities",
|
|
5
5
|
"main": "dist/cjs/index.js",
|
|
6
6
|
"module": "dist/esm/index.js",
|
|
@@ -81,4 +81,4 @@
|
|
|
81
81
|
"@types/node": "^20.19.9",
|
|
82
82
|
"typescript": "^5.9.2"
|
|
83
83
|
}
|
|
84
|
-
}
|
|
84
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isRequiredString,
|
|
3
|
+
isRequiredNumber,
|
|
4
|
+
isRequiredBoolean,
|
|
5
|
+
isValidArray,
|
|
6
|
+
isValidObject,
|
|
7
|
+
isValidEmail,
|
|
8
|
+
isValidUsername,
|
|
9
|
+
isValidPassword,
|
|
10
|
+
isValidUUID,
|
|
11
|
+
isValidDate,
|
|
12
|
+
isValidFileSize,
|
|
13
|
+
isValidFileType,
|
|
14
|
+
sanitizeString,
|
|
15
|
+
sanitizeHTML,
|
|
16
|
+
validateAndSanitizeUserInput
|
|
17
|
+
} from '../validationUtils';
|
|
18
|
+
|
|
19
|
+
describe('Validation Utils', () => {
|
|
20
|
+
describe('isRequiredString', () => {
|
|
21
|
+
it('should return true for valid non-empty strings', () => {
|
|
22
|
+
expect(isRequiredString('hello')).toBe(true);
|
|
23
|
+
expect(isRequiredString(' hello ')).toBe(true); // trims whitespace
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('should return false for invalid or empty strings', () => {
|
|
27
|
+
expect(isRequiredString('')).toBe(false);
|
|
28
|
+
expect(isRequiredString(' ')).toBe(false); // only whitespace
|
|
29
|
+
expect(isRequiredString(null)).toBe(false);
|
|
30
|
+
expect(isRequiredString(undefined)).toBe(false);
|
|
31
|
+
expect(isRequiredString(123)).toBe(false);
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe('isRequiredNumber', () => {
|
|
36
|
+
it('should return true for valid numbers', () => {
|
|
37
|
+
expect(isRequiredNumber(123)).toBe(true);
|
|
38
|
+
expect(isRequiredNumber(0)).toBe(true);
|
|
39
|
+
expect(isRequiredNumber(-456)).toBe(true);
|
|
40
|
+
expect(isRequiredNumber(3.14)).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should return false for invalid numbers', () => {
|
|
44
|
+
expect(isRequiredNumber(Number.NaN)).toBe(false);
|
|
45
|
+
expect(isRequiredNumber('123')).toBe(false);
|
|
46
|
+
expect(isRequiredNumber(null)).toBe(false);
|
|
47
|
+
expect(isRequiredNumber(undefined)).toBe(false);
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('isRequiredBoolean', () => {
|
|
52
|
+
it('should return true for boolean values', () => {
|
|
53
|
+
expect(isRequiredBoolean(true)).toBe(true);
|
|
54
|
+
expect(isRequiredBoolean(false)).toBe(true);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should return false for non-boolean values', () => {
|
|
58
|
+
expect(isRequiredBoolean('true')).toBe(false);
|
|
59
|
+
expect(isRequiredBoolean(1)).toBe(false);
|
|
60
|
+
expect(isRequiredBoolean(0)).toBe(false);
|
|
61
|
+
expect(isRequiredBoolean(null)).toBe(false);
|
|
62
|
+
expect(isRequiredBoolean(undefined)).toBe(false);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
describe('isValidArray', () => {
|
|
67
|
+
it('should return true for arrays', () => {
|
|
68
|
+
expect(isValidArray([])).toBe(true);
|
|
69
|
+
expect(isValidArray([1, 2, 3])).toBe(true);
|
|
70
|
+
expect(isValidArray(['a', 'b'])).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should return false for non-arrays', () => {
|
|
74
|
+
expect(isValidArray({})).toBe(false);
|
|
75
|
+
expect(isValidArray('[]')).toBe(false);
|
|
76
|
+
expect(isValidArray(null)).toBe(false);
|
|
77
|
+
expect(isValidArray(undefined)).toBe(false);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
describe('isValidObject', () => {
|
|
82
|
+
it('should return true for plain objects', () => {
|
|
83
|
+
expect(isValidObject({})).toBe(true);
|
|
84
|
+
expect(isValidObject({ key: 'value' })).toBe(true);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('should return false for non-objects', () => {
|
|
88
|
+
expect(isValidObject([])).toBe(false);
|
|
89
|
+
expect(isValidObject(null)).toBe(false);
|
|
90
|
+
expect(isValidObject(undefined)).toBe(false);
|
|
91
|
+
expect(isValidObject('object')).toBe(false);
|
|
92
|
+
expect(isValidObject(123)).toBe(false);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('isValidEmail', () => {
|
|
97
|
+
it('should return true for valid email addresses', () => {
|
|
98
|
+
expect(isValidEmail('test@example.com')).toBe(true);
|
|
99
|
+
expect(isValidEmail('user.name+tag@domain.co.uk')).toBe(true);
|
|
100
|
+
expect(isValidEmail('simple@test.io')).toBe(true);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should return false for invalid email addresses', () => {
|
|
104
|
+
expect(isValidEmail('invalid-email')).toBe(false);
|
|
105
|
+
expect(isValidEmail('test@')).toBe(false);
|
|
106
|
+
expect(isValidEmail('@domain.com')).toBe(false);
|
|
107
|
+
expect(isValidEmail('test.domain.com')).toBe(false);
|
|
108
|
+
expect(isValidEmail('')).toBe(false);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('isValidUsername', () => {
|
|
113
|
+
it('should return true for valid usernames', () => {
|
|
114
|
+
expect(isValidUsername('user123')).toBe(true);
|
|
115
|
+
expect(isValidUsername('test_user')).toBe(true);
|
|
116
|
+
expect(isValidUsername('john-doe')).toBe(true);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
it('should return false for invalid usernames', () => {
|
|
120
|
+
expect(isValidUsername('')).toBe(false);
|
|
121
|
+
expect(isValidUsername('a')).toBe(false); // too short
|
|
122
|
+
expect(isValidUsername('ab')).toBe(false); // too short
|
|
123
|
+
expect(isValidUsername('user@domain')).toBe(false); // invalid characters
|
|
124
|
+
expect(isValidUsername('user with spaces')).toBe(false); // spaces
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
describe('isValidPassword', () => {
|
|
129
|
+
it('should return true for valid passwords', () => {
|
|
130
|
+
expect(isValidPassword('password123')).toBe(true);
|
|
131
|
+
expect(isValidPassword('mySecurePass')).toBe(true);
|
|
132
|
+
expect(isValidPassword('12345678')).toBe(true);
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('should return false for invalid passwords', () => {
|
|
136
|
+
expect(isValidPassword('')).toBe(false);
|
|
137
|
+
expect(isValidPassword('short')).toBe(false); // too short
|
|
138
|
+
expect(isValidPassword('1234567')).toBe(false); // too short
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
describe('isValidUUID', () => {
|
|
143
|
+
it('should return true for valid UUIDs', () => {
|
|
144
|
+
expect(isValidUUID('123e4567-e89b-12d3-a456-426614174000')).toBe(true);
|
|
145
|
+
expect(isValidUUID('550e8400-e29b-41d4-a716-446655440000')).toBe(true);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
it('should return false for invalid UUIDs', () => {
|
|
149
|
+
expect(isValidUUID('invalid-uuid')).toBe(false);
|
|
150
|
+
expect(isValidUUID('123-456-789')).toBe(false);
|
|
151
|
+
expect(isValidUUID('')).toBe(false);
|
|
152
|
+
});
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
describe('isValidDate', () => {
|
|
156
|
+
it('should return true for valid date strings', () => {
|
|
157
|
+
expect(isValidDate('2024-01-01')).toBe(true);
|
|
158
|
+
expect(isValidDate('2024-12-31T23:59:59.999Z')).toBe(true);
|
|
159
|
+
expect(isValidDate('January 1, 2024')).toBe(true);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('should return false for invalid date strings', () => {
|
|
163
|
+
expect(isValidDate('invalid-date')).toBe(false);
|
|
164
|
+
expect(isValidDate('2024-13-01')).toBe(false); // invalid month
|
|
165
|
+
expect(isValidDate('')).toBe(false);
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
describe('isValidFileSize', () => {
|
|
170
|
+
const maxSize = 1024 * 1024; // 1MB
|
|
171
|
+
|
|
172
|
+
it('should return true for valid file sizes', () => {
|
|
173
|
+
expect(isValidFileSize(1024, maxSize)).toBe(true);
|
|
174
|
+
expect(isValidFileSize(maxSize, maxSize)).toBe(true);
|
|
175
|
+
expect(isValidFileSize(1, maxSize)).toBe(true);
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
it('should return false for invalid file sizes', () => {
|
|
179
|
+
expect(isValidFileSize(0, maxSize)).toBe(false);
|
|
180
|
+
expect(isValidFileSize(-1, maxSize)).toBe(false);
|
|
181
|
+
expect(isValidFileSize(maxSize + 1, maxSize)).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
describe('isValidFileType', () => {
|
|
186
|
+
const allowedTypes = ['jpg', 'png', 'gif', 'pdf'];
|
|
187
|
+
|
|
188
|
+
it('should return true for allowed file types', () => {
|
|
189
|
+
expect(isValidFileType('image.jpg', allowedTypes)).toBe(true);
|
|
190
|
+
expect(isValidFileType('document.PDF', allowedTypes)).toBe(true); // case insensitive
|
|
191
|
+
expect(isValidFileType('photo.png', allowedTypes)).toBe(true);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
it('should return false for disallowed file types', () => {
|
|
195
|
+
expect(isValidFileType('script.js', allowedTypes)).toBe(false);
|
|
196
|
+
expect(isValidFileType('data.txt', allowedTypes)).toBe(false);
|
|
197
|
+
expect(isValidFileType('noextension', allowedTypes)).toBe(false);
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
describe('sanitizeString', () => {
|
|
202
|
+
it('should trim whitespace and remove dangerous characters', () => {
|
|
203
|
+
expect(sanitizeString(' hello ')).toBe('hello');
|
|
204
|
+
expect(sanitizeString('hello<script>alert("xss")</script>world')).toBe('helloalert("xss")world');
|
|
205
|
+
expect(sanitizeString('normal text')).toBe('normal text');
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
describe('sanitizeHTML', () => {
|
|
210
|
+
it('should escape HTML characters', () => {
|
|
211
|
+
expect(sanitizeHTML('<script>alert("xss")</script>')).toBe('<script>alert("xss")</script>');
|
|
212
|
+
expect(sanitizeHTML('Hello & Goodbye')).toBe('Hello & Goodbye');
|
|
213
|
+
expect(sanitizeHTML("It's a test")).toBe('It's a test');
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
describe('validateAndSanitizeUserInput', () => {
|
|
218
|
+
it('should validate and sanitize email input', () => {
|
|
219
|
+
expect(validateAndSanitizeUserInput(' test@example.com ', 'email')).toBe('test@example.com');
|
|
220
|
+
expect(validateAndSanitizeUserInput('invalid-email', 'email')).toBeNull();
|
|
221
|
+
expect(validateAndSanitizeUserInput(123, 'email')).toBeNull();
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
it('should validate and sanitize username input', () => {
|
|
225
|
+
expect(validateAndSanitizeUserInput(' testuser ', 'username')).toBe('testuser');
|
|
226
|
+
expect(validateAndSanitizeUserInput('ab', 'username')).toBeNull(); // too short
|
|
227
|
+
expect(validateAndSanitizeUserInput(123, 'username')).toBeNull();
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
it('should validate and sanitize string input', () => {
|
|
231
|
+
expect(validateAndSanitizeUserInput(' hello world ', 'string')).toBe('hello world');
|
|
232
|
+
expect(validateAndSanitizeUserInput('', 'string')).toBeNull();
|
|
233
|
+
expect(validateAndSanitizeUserInput(123, 'string')).toBeNull();
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
});
|