@oxyhq/core 1.0.0 → 1.0.2

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.
Files changed (51) hide show
  1. package/dist/cjs/i18n/locales/ar-SA.json +1 -1
  2. package/dist/cjs/i18n/locales/ca-ES.json +1 -1
  3. package/dist/cjs/i18n/locales/de-DE.json +1 -1
  4. package/dist/cjs/i18n/locales/fr-FR.json +1 -1
  5. package/dist/cjs/i18n/locales/it-IT.json +1 -1
  6. package/dist/cjs/i18n/locales/ja-JP.json +1 -1
  7. package/dist/cjs/i18n/locales/ko-KR.json +1 -1
  8. package/dist/cjs/i18n/locales/pt-PT.json +1 -1
  9. package/dist/cjs/i18n/locales/zh-CN.json +1 -1
  10. package/dist/esm/i18n/locales/ar-SA.json +1 -1
  11. package/dist/esm/i18n/locales/ca-ES.json +1 -1
  12. package/dist/esm/i18n/locales/de-DE.json +1 -1
  13. package/dist/esm/i18n/locales/fr-FR.json +1 -1
  14. package/dist/esm/i18n/locales/it-IT.json +1 -1
  15. package/dist/esm/i18n/locales/ja-JP.json +1 -1
  16. package/dist/esm/i18n/locales/ko-KR.json +1 -1
  17. package/dist/esm/i18n/locales/pt-PT.json +1 -1
  18. package/dist/esm/i18n/locales/zh-CN.json +1 -1
  19. package/package.json +1 -1
  20. package/src/i18n/locales/ar-SA.json +1 -1
  21. package/src/i18n/locales/ca-ES.json +1 -1
  22. package/src/i18n/locales/de-DE.json +1 -1
  23. package/src/i18n/locales/fr-FR.json +1 -1
  24. package/src/i18n/locales/it-IT.json +1 -1
  25. package/src/i18n/locales/ja-JP.json +1 -1
  26. package/src/i18n/locales/ko-KR.json +1 -1
  27. package/src/i18n/locales/pt-PT.json +1 -1
  28. package/src/i18n/locales/zh-CN.json +1 -1
  29. package/src/utils/__tests__/validationUtils.test.ts +236 -0
  30. package/dist/cjs/i18n/locales/locales/ar-SA.json +0 -120
  31. package/dist/cjs/i18n/locales/locales/ca-ES.json +0 -120
  32. package/dist/cjs/i18n/locales/locales/de-DE.json +0 -120
  33. package/dist/cjs/i18n/locales/locales/en-US.json +0 -956
  34. package/dist/cjs/i18n/locales/locales/es-ES.json +0 -944
  35. package/dist/cjs/i18n/locales/locales/fr-FR.json +0 -120
  36. package/dist/cjs/i18n/locales/locales/it-IT.json +0 -120
  37. package/dist/cjs/i18n/locales/locales/ja-JP.json +0 -119
  38. package/dist/cjs/i18n/locales/locales/ko-KR.json +0 -120
  39. package/dist/cjs/i18n/locales/locales/pt-PT.json +0 -120
  40. package/dist/cjs/i18n/locales/locales/zh-CN.json +0 -120
  41. package/dist/esm/i18n/locales/locales/ar-SA.json +0 -120
  42. package/dist/esm/i18n/locales/locales/ca-ES.json +0 -120
  43. package/dist/esm/i18n/locales/locales/de-DE.json +0 -120
  44. package/dist/esm/i18n/locales/locales/en-US.json +0 -956
  45. package/dist/esm/i18n/locales/locales/es-ES.json +0 -944
  46. package/dist/esm/i18n/locales/locales/fr-FR.json +0 -120
  47. package/dist/esm/i18n/locales/locales/it-IT.json +0 -120
  48. package/dist/esm/i18n/locales/locales/ja-JP.json +0 -119
  49. package/dist/esm/i18n/locales/locales/ko-KR.json +0 -120
  50. package/dist/esm/i18n/locales/locales/pt-PT.json +0 -120
  51. package/dist/esm/i18n/locales/locales/zh-CN.json +0 -120
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "عرض {{count}} المزيد",
46
46
  "status": {
47
47
  "accountSwitched": "استخدام {{name}} الآن"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Veure {{count}} més",
46
46
  "status": {
47
47
  "accountSwitched": "Ara utilitzant {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "{{count}} weitere anzeigen",
46
46
  "status": {
47
47
  "accountSwitched": "Verwende jetzt {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Voir {{count}} de plus",
46
46
  "status": {
47
47
  "accountSwitched": "Utilisation de {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Visualizza {{count}} altri",
46
46
  "status": {
47
47
  "accountSwitched": "Ora usando {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "さらに{{count}}件を表示",
46
46
  "status": {
47
47
  "accountSwitched": "{{name}}を使用中"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "{{count}}개 더 보기",
46
46
  "status": {
47
47
  "accountSwitched": "{{name}} 사용 중"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Ver mais {{count}}",
46
46
  "status": {
47
47
  "accountSwitched": "Agora a usar {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "查看更多{{count}}个",
46
46
  "status": {
47
47
  "accountSwitched": "正在使用{{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "عرض {{count}} المزيد",
46
46
  "status": {
47
47
  "accountSwitched": "استخدام {{name}} الآن"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Veure {{count}} més",
46
46
  "status": {
47
47
  "accountSwitched": "Ara utilitzant {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "{{count}} weitere anzeigen",
46
46
  "status": {
47
47
  "accountSwitched": "Verwende jetzt {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Voir {{count}} de plus",
46
46
  "status": {
47
47
  "accountSwitched": "Utilisation de {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Visualizza {{count}} altri",
46
46
  "status": {
47
47
  "accountSwitched": "Ora usando {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "さらに{{count}}件を表示",
46
46
  "status": {
47
47
  "accountSwitched": "{{name}}を使用中"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "{{count}}개 더 보기",
46
46
  "status": {
47
47
  "accountSwitched": "{{name}} 사용 중"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Ver mais {{count}}",
46
46
  "status": {
47
47
  "accountSwitched": "Agora a usar {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "查看更多{{count}}个",
46
46
  "status": {
47
47
  "accountSwitched": "正在使用{{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxyhq/core",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
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",
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "عرض {{count}} المزيد",
46
46
  "status": {
47
47
  "accountSwitched": "استخدام {{name}} الآن"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Veure {{count}} més",
46
46
  "status": {
47
47
  "accountSwitched": "Ara utilitzant {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "{{count}} weitere anzeigen",
46
46
  "status": {
47
47
  "accountSwitched": "Verwende jetzt {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Voir {{count}} de plus",
46
46
  "status": {
47
47
  "accountSwitched": "Utilisation de {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Visualizza {{count}} altri",
46
46
  "status": {
47
47
  "accountSwitched": "Ora usando {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "さらに{{count}}件を表示",
46
46
  "status": {
47
47
  "accountSwitched": "{{name}}を使用中"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "{{count}}개 더 보기",
46
46
  "status": {
47
47
  "accountSwitched": "{{name}} 사용 중"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "Ver mais {{count}}",
46
46
  "status": {
47
47
  "accountSwitched": "Agora a usar {{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -45,7 +45,7 @@
45
45
  "viewAllAccounts": "查看更多{{count}}个",
46
46
  "status": {
47
47
  "accountSwitched": "正在使用{{name}}"
48
- },
48
+ }
49
49
  },
50
50
  "signup": {
51
51
  "welcome": {
@@ -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('&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;');
212
+ expect(sanitizeHTML('Hello & Goodbye')).toBe('Hello &amp; Goodbye');
213
+ expect(sanitizeHTML("It's a test")).toBe('It&#x27;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
+ });
@@ -1,120 +0,0 @@
1
- {
2
- "signin": {
3
- "title": "تسجيل الدخول",
4
- "subtitle": "سجل الدخول للمتابعة",
5
- "addAccountTitle": "إضافة حساب آخر",
6
- "addAccountSubtitle": "تسجيل الدخول بحساب آخر",
7
- "username": {
8
- "label": "اسم المستخدم",
9
- "placeholder": "أدخل اسم المستخدم",
10
- "helper": "3-30 حرفًا، أحرف وأرقام فقط",
11
- "required": "يرجى إدخال اسم المستخدم.",
12
- "minLength": "يجب أن يكون اسم المستخدم 3 أحرف على الأقل."
13
- },
14
- "password": {
15
- "label": "كلمة المرور",
16
- "placeholder": "أدخل كلمة المرور",
17
- "required": "يرجى إدخال كلمة المرور.",
18
- "hint": "أدخل كلمة المرور لتسجيل الدخول"
19
- },
20
- "actions": {
21
- "continue": "متابعة",
22
- "back": "رجوع",
23
- "signIn": "تسجيل الدخول",
24
- "verify": "التحقق",
25
- "openAccountSwitcher": "التبديل إلى حساب آخر",
26
- "openAccountSwitcherSubtitle": "{{count}} حسابات أخرى متاحة",
27
- "openAccountSwitcherSubtitle_singular": "حساب آخر واحد متاح",
28
- "openAccountSwitcherSubtitle_zero": "راجع حساباتك المحفوظة",
29
- "manageAccounts": "إدارة الحسابات المحفوظة",
30
- "manageAccountsSubtitle": "مراجعة الجلسات أو إزالتها أو تسجيل الخروج",
31
- "loadingOtherAccounts": "جاري تحميل الحسابات الأخرى…",
32
- "switchAccountFailed": "لم نتمكن من التبديل بين الحسابات. يرجى المحاولة مرة أخرى."
33
- },
34
- "forgotPrompt": "نسيت كلمة المرور؟",
35
- "security": {
36
- "dataSecure": "بياناتك مشفرة وآمنة"
37
- },
38
- "currentlySignedInAs": "مسجل الدخول حاليًا كـ",
39
- "alreadySignedInWith": "مسجل الدخول بالفعل بـ",
40
- "alreadySignedIn": "مسجل الدخول بالفعل",
41
- "alreadySignedInMessage": "هذا الحساب مسجل الدخول بالفعل. المتابعة بهذا الحساب؟",
42
- "continueWithAccount": "متابعة",
43
- "currentAccount": "الحالي",
44
- "or": "أو",
45
- "viewAllAccounts": "عرض {{count}} المزيد",
46
- "status": {
47
- "accountSwitched": "استخدام {{name}} الآن"
48
- },
49
- },
50
- "signup": {
51
- "welcome": {
52
- "title": "مرحبًا بك في Oxy!",
53
- "subtitle": "أنشئ حسابك في خطوات قليلة",
54
- "haveAccount": "لديك حساب بالفعل؟",
55
- "signInCta": "تسجيل الدخول"
56
- },
57
- "identity": {
58
- "title": "من أنت؟",
59
- "subtitle": "اختر اسم المستخدم وأدخل بريدك الإلكتروني"
60
- },
61
- "username": {
62
- "helper": "3-30 حرفًا، أحرف وأرقام فقط",
63
- "required": "يرجى إدخال اسم مستخدم",
64
- "minLength": "يجب أن يكون اسم المستخدم 3 أحرف على الأقل"
65
- },
66
- "email": {
67
- "required": "يرجى إدخال عنوان بريد إلكتروني",
68
- "invalid": "يرجى إدخال عنوان بريد إلكتروني صالح",
69
- "helper": "لن نشارك بريدك الإلكتروني أبدًا"
70
- },
71
- "security": {
72
- "title": "أمّن حسابك",
73
- "subtitle": "أنشئ كلمة مرور قوية لحماية حسابك"
74
- },
75
- "password": {
76
- "helper": "8 أحرف على الأقل",
77
- "required": "يرجى إدخال كلمة مرور",
78
- "minLength": "يجب أن تكون كلمة المرور 8 أحرف على الأقل",
79
- "confirmRequired": "يرجى تأكيد كلمة المرور",
80
- "mismatch": "كلمات المرور غير متطابقة",
81
- "confirmHint": "أعد إدخال كلمة المرور للتأكيد"
82
- },
83
- "summary": {
84
- "title": "أوشكت على الانتهاء!",
85
- "subtitle": "راجع معلوماتك وأنشئ حسابك",
86
- "sectionTitle": "معلومات الحساب",
87
- "fields": {
88
- "username": "اسم المستخدم",
89
- "email": "البريد الإلكتروني",
90
- "password": "كلمة المرور"
91
- },
92
- "notSet": "غير محدد",
93
- "securityTip": "لمزيد من الأمان، قم بتمكين المصادقة الحيوية من إعدادات الحساب بعد إنشاء حسابك.",
94
- "legalReminder": "بإنشاء حساب، فإنك توافق على شروط الخدمة وسياسة الخصوصية الخاصة بنا."
95
- }
96
- },
97
- "common": {
98
- "actions": {
99
- "back": "رجوع",
100
- "continue": "متابعة",
101
- "next": "التالي",
102
- "getStarted": "ابدأ",
103
- "createAccount": "إنشاء حساب",
104
- "signIn": "تسجيل الدخول",
105
- "verify": "التحقق",
106
- "resetPassword": "إعادة تعيين كلمة المرور"
107
- },
108
- "links": {
109
- "recoverAccount": "استعادة حسابك",
110
- "signUp": "التسجيل"
111
- },
112
- "labels": {
113
- "username": "اسم المستخدم",
114
- "email": "البريد الإلكتروني",
115
- "password": "كلمة المرور",
116
- "confirmPassword": "تأكيد كلمة المرور"
117
- }
118
- }
119
- }
120
-