dff-util 1.3.7 → 1.3.8
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 +1021 -698
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/main/api-call.d.ts +6 -0
- package/dist/main/api-call.js +79 -0
- package/dist/main/const-type.d.ts +1 -1
- package/dist/main/countries.d.ts +1 -1
- package/dist/main/countries.js +2 -2
- package/dist/main/util.d.ts +0 -2
- package/dist/main/util.js +2 -58
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,26 +1,72 @@
|
|
|
1
|
-
|
|
1
|
+
# dff-util
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
Http calls
|
|
3
|
+
Utilities for HTTP requests, JWT tokens, application constants, shared types, text formatting, and data conversion.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
>>>> url = url.startsWith('http') ? url : Http.API_BASE_URL + url;
|
|
5
|
+
Select a topic below to view its reference and examples.
|
|
8
6
|
|
|
9
|
-
|
|
7
|
+
**[Utilities](#utilities)**
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
| | | | | | | |
|
|
10
|
+
| :--- | :--- | :--- | :--- | :--- | :--- | :--- |
|
|
11
|
+
| [AppRandomString](#general-utilities) | [AppUniqueCode](#general-utilities) | [AppCodeByType](#general-utilities) | [AppCode](#general-utilities) | [AppDaysBack](#general-utilities) | [AppAddDays](#general-utilities) | [AppUUID4](#general-utilities) |
|
|
12
|
+
| [TruncateText](#text-and-date-formatting) | [DateTime24HrFormat](#text-and-date-formatting) | [DateTime12HrFormat](#text-and-date-formatting) | [DateAndTime](#text-and-date-formatting) | [TimeAgo](#text-and-date-formatting) | [toCamelCase](#case-conversion-and-object-mapping) | [toSnakeCase](#case-conversion-and-object-mapping) |
|
|
13
|
+
| [toLowerCase](#case-conversion-and-object-mapping) | [toUpperCase](#case-conversion-and-object-mapping) | [toPascalCase](#case-conversion-and-object-mapping) | [toViewMapper](#case-conversion-and-object-mapping) | [toEntityMapper](#case-conversion-and-object-mapping) | [toSchemaMapper](#case-conversion-and-object-mapping) | [QueryCond](#query-conditions-querycond) |
|
|
12
14
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
**[Http](#http)**
|
|
16
|
+
|
|
17
|
+
| | | | | | |
|
|
18
|
+
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
19
|
+
| [Get](#json-requests) | [Post](#json-requests) | [Put](#json-requests) | [Delete](#json-requests) | [Token](#retrieve-a-token) | [FormUpload](#multipart-form-upload) |
|
|
20
|
+
| [CloudUpload](#upload-a-file-directly) | [FileDownload](#download-a-file) | [HttpHeaders](#headers-and-request-ids) | [BaseHeaders](#headers-and-request-ids) | [RespType](#response-formats) | [ErrorWrapper](#handle-errors) |
|
|
21
|
+
|
|
22
|
+
**[Call Api](#call-api)**
|
|
23
|
+
|
|
24
|
+
| | | |
|
|
25
|
+
| :--- | :--- | :--- |
|
|
26
|
+
| [CallHbs](#handlebars-rendering-callhbs) | [CallLangText](#language-translation-calllangtext) | [CallCurrencyConvert](#currency-conversion-callcurrencyconvert) |
|
|
27
|
+
|
|
28
|
+
**[Tokens and encryption](#tokens-and-encryption)**
|
|
29
|
+
|
|
30
|
+
| | | | | | |
|
|
31
|
+
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
32
|
+
| [JwtEncode](#encode-a-token) | [JwtDecode](#decode-a-token) | [JwtVerify](#verify-a-token-with-a-secret) | [JwtValid](#check-token-expiration) | [Encrypt](#encryption-and-encoding) | [Decrypt](#encryption-and-encoding) |
|
|
33
|
+
| [EncodeBase64](#base64-url-and-safe-encoding) | [DecodeBase64](#base64-url-and-safe-encoding) | [EncodeURL](#base64-url-and-safe-encoding) | [DecodeURL](#base64-url-and-safe-encoding) | [SafeEncode](#base64-url-and-safe-encoding) | [SafeDecode](#base64-url-and-safe-encoding) |
|
|
34
|
+
|
|
35
|
+
**[Language and country reference](#language-and-country-reference)**
|
|
36
|
+
|
|
37
|
+
| | | | | | |
|
|
38
|
+
| :--- | :--- | :--- | :--- | :--- | :--- |
|
|
39
|
+
| [LangCountryCode](#language-and-country-lookup-langcountrycode) | [CountryType](#country-data-countrytype) | [Countries](#country-list) | [LanguageType](#language-metadata-languagetype) | [LangCountryType](#language-and-country-metadata-langcountrytype) | [AllLanguageCodesType](#supported-language-codes-alllanguagecodestype) |
|
|
40
|
+
|
|
41
|
+
**[Shared types](#shared-types)**
|
|
42
|
+
|
|
43
|
+
| | | | | |
|
|
44
|
+
| :--- | :--- | :--- | :--- | :--- |
|
|
45
|
+
| [LangDirType](#common-types) | [OrderType](#common-types) | [ThemeType](#common-types) | [UnixTimestampType](#common-types) | [OptionType](#common-types) |
|
|
46
|
+
| [FileType](#common-types) | [ResponseType](#request-and-response-types) | [SearchType](#request-and-response-types) | [KeyValueType](#request-and-response-types) | [JsonValueType](#request-and-response-types) |
|
|
47
|
+
| [RequestBodyType](#request-and-response-types) | [RequestQueryType](#request-and-response-types) | [RequestByIdType](#request-and-response-types) | [SessionUser](#session-user-sessionuser) | [SessionInfo](#session-information-sessioninfo) |
|
|
48
|
+
|
|
49
|
+
**[Constants and validation](#constants-and-validation)**
|
|
50
|
+
|
|
51
|
+
| | | |
|
|
52
|
+
| :--- | :--- | :--- |
|
|
53
|
+
| [ConstValue](#constants-constvalue) | [ConstMessages](#application-messages-constmessages) | [RegExp](#regular-expressions-regexp) |
|
|
54
|
+
|
|
55
|
+
## Utilities
|
|
56
|
+
|
|
57
|
+
### General utilities
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// Generate a random string with the given length and character set.
|
|
15
61
|
AppRandomString(length, charset);
|
|
16
62
|
|
|
17
|
-
|
|
63
|
+
// Generate an uppercase code.
|
|
18
64
|
AppUniqueCode();
|
|
19
65
|
|
|
20
|
-
|
|
66
|
+
// Generate an uppercase key using a type or generated suffix.
|
|
21
67
|
AppCodeByType(name, type);
|
|
22
68
|
|
|
23
|
-
|
|
69
|
+
// Convert a name to an uppercase key with underscore separators.
|
|
24
70
|
AppCode(name);
|
|
25
71
|
|
|
26
72
|
AppDaysBack(date, addDays, isDays);
|
|
@@ -30,505 +76,642 @@ AppAddDays(date, addDays, isDays);
|
|
|
30
76
|
AppUUID4();
|
|
31
77
|
```
|
|
32
78
|
|
|
33
|
-
|
|
79
|
+
### Text and date formatting
|
|
34
80
|
|
|
35
|
-
|
|
81
|
+
Available helpers:
|
|
36
82
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
83
|
+
- `TruncateText`
|
|
84
|
+
- `DateTime24HrFormat`
|
|
85
|
+
- `DateTime12HrFormat`
|
|
86
|
+
- `DateAndTime`
|
|
87
|
+
- `TimeAgo`
|
|
40
88
|
|
|
41
|
-
|
|
89
|
+
### Case conversion and object mapping
|
|
42
90
|
|
|
91
|
+
#### String case conversion
|
|
92
|
+
|
|
93
|
+
| Function | Purpose | Input → output examples |
|
|
94
|
+
| :--- | :--- | :--- |
|
|
95
|
+
| `toCamelCase` | Join words in camel case | `user_name` → `userName`; `user-name` → `userName`; `User Name` → `userName`; `USER_NAME` → `uSERNAME` |
|
|
96
|
+
| `toSnakeCase` | Separate words with underscores and lowercase | `userName` → `user_name`; `UserName` → `user_name`; `user name` → `user_name`; `user-name` → `user_name` |
|
|
97
|
+
| `toLowerCase` | Convert word separators to underscores and lowercase | `user-name` → `user_name`; `userName` → `user__name`; `UserName` → `user__name` |
|
|
98
|
+
| `toUpperCase` | Convert word separators to underscores and uppercase | `user-name` → `USER_NAME`; `user name` → `USER_NAME`; `userName` → `USER__NAME`; `UserName` → `USER__NAME` |
|
|
99
|
+
| `toPascalCase` | Capitalize each separated word and join | `user_name` → `UserName`; `user name` → `UserName`; `user-name` → `UserName`; `USER_NAME` → `UserName` |
|
|
100
|
+
|
|
101
|
+
These examples reflect the current implementation. `toCamelCase` preserves internal uppercase letters; `toLowerCase` and `toUpperCase` can produce double underscores before uppercase letters.
|
|
102
|
+
|
|
103
|
+
#### Object mapping
|
|
104
|
+
|
|
105
|
+
| Function | Key conversion | Example input | Example output |
|
|
106
|
+
| :--- | :--- | :--- | :--- |
|
|
107
|
+
| `toViewMapper` | Convert keys to camel case and `_id` to `id` recursively | `{ _id: 'abc123', user_name: 'prasad', address_info: { city_name: 'hyderabad' } }` | `{ id: 'abc123', userName: 'prasad', addressInfo: { cityName: 'hyderabad' } }` |
|
|
108
|
+
| `toEntityMapper` | Convert keys to snake case recursively; preserve `id` | `{ id: 'abc123', userName: 'prasad', addressInfo: { cityName: 'hyderabad' } }` | `{ id: 'abc123', user_name: 'prasad', address_info: { city_name: 'hyderabad' } }` |
|
|
109
|
+
| `toSchemaMapper` | Convert top-level `id` to `_id` and keys to snake case; nested values use `toEntityMapper` | `{ id: 'abc123', userName: 'prasad', addressInfo: { cityName: 'hyderabad' } }` | `{ _id: 'abc123', user_name: 'prasad', address_info: { city_name: 'hyderabad' } }` |
|
|
110
|
+
|
|
111
|
+
All three preserve language maps whose keys are recognized language codes. Primitive and non-plain-object values are returned unchanged. `toViewMapper` and `toEntityMapper` process array items recursively; `toSchemaMapper` uses `toEntityMapper` for array items, so their `id` keys remain `id`.
|
|
112
|
+
|
|
113
|
+
### Query conditions (QueryCond)
|
|
114
|
+
|
|
115
|
+
Parse a filter expression into an array of conditions. The example below includes comparison, membership, null, range, text, and existence filters.
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
const got = QueryCond(input);
|
|
119
|
+
|
|
120
|
+
example:
|
|
121
|
+
QueryCond input: isApproved=true,status!=false,age>18,score<100,height>=170,weight<=80,type=["accept","inprogress"],type!=["accept","inprogress"],role in ["admin","editor"],role not in ["admin","editor"],role notin ["admin","editor"],deletedAt is null,deletedAt is not null,deletedAt isnull,updatedAt isnotnull,deletedAt=null,deletedAt!=null,age between [18,30],createdAt between 2020-01-01..2020-01-31,name like "Jo%",email ilike "%@gmail.com",title contains "hello",code startswith "AB",code endswith "99",path regex "^/api/.*$",archivedAt,!archivedAt,name="a,b",meta={"a":1,"b":true},tags=["x,y","z"]
|
|
122
|
+
QueryCond output: [
|
|
123
|
+
{
|
|
124
|
+
"key": "isApproved",
|
|
125
|
+
"opt": "=",
|
|
126
|
+
"value": true
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"key": "status",
|
|
130
|
+
"opt": "!=",
|
|
131
|
+
"value": false
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"key": "age",
|
|
135
|
+
"opt": ">",
|
|
136
|
+
"value": 18
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
"key": "score",
|
|
140
|
+
"opt": "<",
|
|
141
|
+
"value": 100
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"key": "height",
|
|
145
|
+
"opt": ">=",
|
|
146
|
+
"value": 170
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
"key": "weight",
|
|
150
|
+
"opt": "<=",
|
|
151
|
+
"value": 80
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"key": "type",
|
|
155
|
+
"opt": "in",
|
|
156
|
+
"value": [
|
|
157
|
+
"accept",
|
|
158
|
+
"inprogress"
|
|
159
|
+
]
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
"key": "type",
|
|
163
|
+
"opt": "not in",
|
|
164
|
+
"value": [
|
|
165
|
+
"accept",
|
|
166
|
+
"inprogress"
|
|
167
|
+
]
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
"key": "role",
|
|
171
|
+
"opt": "in",
|
|
172
|
+
"value": [
|
|
173
|
+
"admin",
|
|
174
|
+
"editor"
|
|
175
|
+
]
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"key": "role",
|
|
179
|
+
"opt": "not in",
|
|
180
|
+
"value": [
|
|
181
|
+
"admin",
|
|
182
|
+
"editor"
|
|
183
|
+
]
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
"key": "role",
|
|
187
|
+
"opt": "not in",
|
|
188
|
+
"value": [
|
|
189
|
+
"admin",
|
|
190
|
+
"editor"
|
|
191
|
+
]
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"key": "deletedAt",
|
|
195
|
+
"opt": "is null",
|
|
196
|
+
"value": null
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
"key": "deletedAt",
|
|
200
|
+
"opt": "is not null",
|
|
201
|
+
"value": null
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
"key": "deletedAt",
|
|
205
|
+
"opt": "is null",
|
|
206
|
+
"value": null
|
|
207
|
+
},
|
|
208
|
+
{
|
|
209
|
+
"key": "updatedAt",
|
|
210
|
+
"opt": "is not null",
|
|
211
|
+
"value": null
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
"key": "deletedAt",
|
|
215
|
+
"opt": "is null",
|
|
216
|
+
"value": null
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"key": "deletedAt",
|
|
220
|
+
"opt": "is not null",
|
|
221
|
+
"value": null
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
"key": "age",
|
|
225
|
+
"opt": "between",
|
|
226
|
+
"value": [
|
|
227
|
+
18,
|
|
228
|
+
30
|
|
229
|
+
]
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"key": "createdAt",
|
|
233
|
+
"opt": "between",
|
|
234
|
+
"value": [
|
|
235
|
+
"2020-01-01",
|
|
236
|
+
"2020-01-31"
|
|
237
|
+
]
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"key": "name",
|
|
241
|
+
"opt": "like",
|
|
242
|
+
"value": "Jo%"
|
|
243
|
+
},
|
|
244
|
+
{
|
|
245
|
+
"key": "email",
|
|
246
|
+
"opt": "ilike",
|
|
247
|
+
"value": "%@gmail.com"
|
|
248
|
+
},
|
|
249
|
+
{
|
|
250
|
+
"key": "title",
|
|
251
|
+
"opt": "contains",
|
|
252
|
+
"value": "hello"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
"key": "code",
|
|
256
|
+
"opt": "startswith",
|
|
257
|
+
"value": "AB"
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"key": "code",
|
|
261
|
+
"opt": "endswith",
|
|
262
|
+
"value": "99"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
"key": "path",
|
|
266
|
+
"opt": "regex",
|
|
267
|
+
"value": "^/api/.*$"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"key": "archivedAt",
|
|
271
|
+
"opt": "exists",
|
|
272
|
+
"value": true
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"key": "archivedAt",
|
|
276
|
+
"opt": "exists",
|
|
277
|
+
"value": false
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
"key": "name",
|
|
281
|
+
"opt": "=",
|
|
282
|
+
"value": "a,b"
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"key": "meta",
|
|
286
|
+
"opt": "=",
|
|
287
|
+
"value": {
|
|
288
|
+
"a": 1,
|
|
289
|
+
"b": true
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
"key": "tags",
|
|
294
|
+
"opt": "in",
|
|
295
|
+
"value": [
|
|
296
|
+
"x,y",
|
|
297
|
+
"z"
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
]
|
|
43
301
|
```
|
|
44
|
-
JwtDecode(token);
|
|
45
|
-
```
|
|
46
302
|
|
|
47
|
-
|
|
303
|
+
## Http
|
|
304
|
+
|
|
305
|
+
### HTTP requests
|
|
48
306
|
|
|
307
|
+
`Http` provides static helpers built on `fetch` for JSON requests, token retrieval, uploads, and downloads. Use a runtime that provides `fetch`, `FormData`, and `File` for the corresponding operations. Examples using `await` belong in an async function or a module that supports top-level await.
|
|
308
|
+
|
|
309
|
+
#### Configuration
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { Http, HttpHeaders, RespType } from 'dff-util';
|
|
313
|
+
|
|
314
|
+
Http.API_BASE_URL = 'https://api.example.com'; // Default: empty string
|
|
315
|
+
Http.TOKEN_URL = '/apisix/plugin/jwt/sign'; // Default token endpoint
|
|
316
|
+
|
|
317
|
+
// Create a fresh headers object for each request.
|
|
318
|
+
const createHeaders = () => ({
|
|
319
|
+
...HttpHeaders,
|
|
320
|
+
authorization: 'Bearer YOUR_ACCESS_TOKEN',
|
|
321
|
+
});
|
|
49
322
|
```
|
|
50
|
-
|
|
323
|
+
|
|
324
|
+
`Get`, `Post`, `Put`, `Delete`, and `FormUpload` prepend `API_BASE_URL` unless the URL starts with `http`. Paths are concatenated directly, so use a base URL without a trailing slash and a path beginning with `/`.
|
|
325
|
+
|
|
326
|
+
`Token` always joins `API_BASE_URL` and `TOKEN_URL`. `CloudUpload` and `FileDownload` use the supplied URL directly.
|
|
327
|
+
|
|
328
|
+
#### Methods
|
|
329
|
+
|
|
330
|
+
| Method | Arguments, in order | Result |
|
|
331
|
+
| :--- | :--- | :--- |
|
|
332
|
+
| `Get` | `url, params, headers, type = RespType.JSON` | Parsed response |
|
|
333
|
+
| `Post` | `url, data, headers, type = RespType.JSON` | Parsed response |
|
|
334
|
+
| `Put` | `url, data, headers, type = RespType.JSON` | Parsed response |
|
|
335
|
+
| `Delete` | `url, params, headers, type = RespType.JSON` | Parsed response |
|
|
336
|
+
| `Token` | `sessionInfo, appKey, apiKey?, type = RespType.TEXT` | Token text by default |
|
|
337
|
+
| `FormUpload` | `url, file, isHeadersAddMultiForm = false, data = {}, headers = BaseHeaders, method = 'PUT', type = RespType.JSON` | Parsed response |
|
|
338
|
+
| `CloudUpload` | `fullUrl, file, headers = null, method = 'PUT'` | Raw `Response` |
|
|
339
|
+
| `FileDownload` | `fullUrl, params, headers = HttpHeaders, method = 'GET'` | `Blob` |
|
|
340
|
+
|
|
341
|
+
For `Get` and `Delete`, pass `null` when no query parameters are needed. For the four JSON request methods, pass `null` for headers to use `HttpHeaders`; these positional arguments are required in the TypeScript signatures. Upload methods accept `'POST'` or `'PUT'`.
|
|
342
|
+
|
|
343
|
+
#### Headers and request IDs
|
|
344
|
+
|
|
345
|
+
- `HttpHeaders` contains `Content-Type: application/json`, plus `authorization` and `request-id` initialized to `null`.
|
|
346
|
+
- `BaseHeaders` contains the same authorization and request ID fields without a content type, for multipart uploads.
|
|
347
|
+
- Custom headers replace the defaults; spread `HttpHeaders` when you want to retain the JSON content type.
|
|
348
|
+
- Each helper assigns `request-id` when the supplied header value is missing or falsy. An existing ID is preserved.
|
|
349
|
+
- Headers are mutated when an ID is assigned. Reusing a headers object, including the shared defaults, can reuse that ID. Pass a fresh object for each request when you want distinct IDs.
|
|
350
|
+
|
|
351
|
+
#### JSON requests
|
|
352
|
+
|
|
353
|
+
```typescript
|
|
354
|
+
const users = await Http.Get(
|
|
355
|
+
'/users',
|
|
356
|
+
{ limit: 10, skip: 0, searchTerm: 'Jane Doe' },
|
|
357
|
+
createHeaders(),
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
const user = await Http.Get('/users/123', null, createHeaders());
|
|
361
|
+
|
|
362
|
+
const created = await Http.Post(
|
|
363
|
+
'/users',
|
|
364
|
+
{ name: 'Jane Doe', email: 'jane@example.com' },
|
|
365
|
+
createHeaders(),
|
|
366
|
+
);
|
|
367
|
+
|
|
368
|
+
const updated = await Http.Put(
|
|
369
|
+
'/users/123',
|
|
370
|
+
{ name: 'Jane Smith' },
|
|
371
|
+
createHeaders(),
|
|
372
|
+
);
|
|
373
|
+
|
|
374
|
+
// TEXT also works for an endpoint returning an empty success body.
|
|
375
|
+
const deleted = await Http.Delete(
|
|
376
|
+
'/users/123',
|
|
377
|
+
null,
|
|
378
|
+
createHeaders(),
|
|
379
|
+
RespType.TEXT,
|
|
380
|
+
);
|
|
51
381
|
```
|
|
52
382
|
|
|
53
|
-
|
|
383
|
+
`Get` and `Delete` serialize parameters with `URLSearchParams` and append `?` followed by the query string. Supply a URL without an existing query string when passing `params`. `Post` and `Put` serialize `data` with `JSON.stringify`.
|
|
384
|
+
|
|
385
|
+
#### Response formats
|
|
54
386
|
|
|
387
|
+
| Value | Response parser | Returned value |
|
|
388
|
+
| :--- | :--- | :--- |
|
|
389
|
+
| `RespType.JSON` | `response.json()` | Parsed JSON |
|
|
390
|
+
| `RespType.TEXT` | `response.text()` | String |
|
|
391
|
+
| `RespType.BLOB` | `response.blob()` | `Blob` |
|
|
392
|
+
| `RespType.FORM_DATA` | `response.formData()` | `FormData` |
|
|
393
|
+
| `RespType.ARRAY_BUFFER` | `response.arrayBuffer()` | `ArrayBuffer` |
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
const text = await Http.Get('/health', null, createHeaders(), RespType.TEXT);
|
|
397
|
+
const image = await Http.Get('/image', null, createHeaders(), RespType.BLOB);
|
|
55
398
|
```
|
|
56
|
-
|
|
399
|
+
|
|
400
|
+
JSON is the default for ordinary requests and form uploads. Select a matching format for other response bodies; an empty response cannot be parsed as JSON. These helpers return the parsed body directly, without adding a `ResponseType` wrapper.
|
|
401
|
+
|
|
402
|
+
#### Retrieve a token
|
|
403
|
+
|
|
404
|
+
```typescript
|
|
405
|
+
const token = await Http.Token(
|
|
406
|
+
{ id: 'user-123', roles: ['user'] },
|
|
407
|
+
'YOUR_APP_KEY',
|
|
408
|
+
'YOUR_API_KEY',
|
|
409
|
+
);
|
|
57
410
|
```
|
|
58
411
|
|
|
59
|
-
|
|
412
|
+
`Token` sends a GET request to the configured token endpoint with `key` and a JSON-serialized `payload` in the query string. It sets `X-API-KEY` to the supplied API key, or an empty string when omitted, and returns text by default.
|
|
413
|
+
|
|
414
|
+
#### Handle errors
|
|
60
415
|
|
|
416
|
+
For ordinary requests, token retrieval, and form uploads, non-success HTTP responses and response-parsing failures are caught and wrapped. The rejected value is a plain object:
|
|
417
|
+
|
|
418
|
+
```typescript
|
|
419
|
+
try {
|
|
420
|
+
await Http.Post('/users', { name: 'Jane' }, createHeaders());
|
|
421
|
+
} catch (failure: any) {
|
|
422
|
+
console.error('Request URL:', failure.url);
|
|
423
|
+
console.error('Request ID:', failure.requestId);
|
|
424
|
+
console.error('Message:', failure.error.message);
|
|
425
|
+
console.error('Original message:', failure.error.main_message);
|
|
426
|
+
console.error('Submitted body:', failure.body); // Post and Put only
|
|
427
|
+
}
|
|
61
428
|
```
|
|
62
|
-
import { JwtEncode, JwtVerify, JwtDecode, JwtValid } from '../src/index';
|
|
63
429
|
|
|
64
|
-
|
|
65
|
-
const secret = 'your-secret-key';
|
|
66
|
-
const payload = { userId: '123', role: 'admin' };
|
|
430
|
+
`Http.ErrorWrapper(errorData)` copies the error fields and sets `message` from `internal_message`, then `message`, then `ConstKeys.INVALID_DATA`. It sets `main_message` from the original `message`, or the same fallback. Plain-text error responses may therefore appear as the fallback message rather than their original text.
|
|
67
431
|
|
|
68
|
-
|
|
69
|
-
const token = await JwtEncode(payload, secret, 3600);
|
|
70
|
-
console.log('Encoded JWT Token:', token);
|
|
432
|
+
`CloudUpload` returns the raw response without checking `response.ok`; check it yourself. `FileDownload` reads the body as a blob without checking the status, so an HTTP error body can also be returned as a blob. Both wrap caught fetch/read failures with `url`, `requestId`, and `error`.
|
|
71
433
|
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
const verifiedPayload = await JwtVerify(token, secret);
|
|
75
|
-
console.log('Verified Payload:', verifiedPayload);
|
|
76
|
-
} catch (error: any) {
|
|
77
|
-
console.error('Verification Error:', error.message);
|
|
78
|
-
}
|
|
434
|
+
### File uploads and downloads
|
|
79
435
|
|
|
80
|
-
|
|
81
|
-
const decodedPayload = JwtDecode(token);
|
|
82
|
-
console.log('Decoded Payload (without verification):', decodedPayload);
|
|
436
|
+
#### Multipart form upload
|
|
83
437
|
|
|
84
|
-
|
|
85
|
-
const isValid = JwtValid(token);
|
|
86
|
-
console.log('Is JWT valid:', isValid);
|
|
87
|
-
};
|
|
438
|
+
`FormUpload` sends the file in a multipart field named `file`. Additional fields with non-null, non-undefined values are appended from `data`.
|
|
88
439
|
|
|
89
|
-
|
|
440
|
+
```typescript
|
|
441
|
+
import { BaseHeaders, Http } from 'dff-util';
|
|
90
442
|
|
|
443
|
+
// Browser example: obtain a File from a file input.
|
|
444
|
+
const input = document.querySelector<HTMLInputElement>('#file-input');
|
|
445
|
+
const file = input?.files?.[0];
|
|
446
|
+
|
|
447
|
+
if (file) {
|
|
448
|
+
const result = await Http.FormUpload(
|
|
449
|
+
'/files',
|
|
450
|
+
file,
|
|
451
|
+
false,
|
|
452
|
+
{ folder: 'documents' },
|
|
453
|
+
{ ...BaseHeaders, authorization: 'Bearer YOUR_ACCESS_TOKEN' },
|
|
454
|
+
'POST',
|
|
455
|
+
);
|
|
456
|
+
console.log(result);
|
|
457
|
+
}
|
|
91
458
|
```
|
|
92
459
|
|
|
93
|
-
|
|
460
|
+
Keep `isHeadersAddMultiForm` set to `false` and omit `Content-Type` so `fetch` supplies the multipart boundary. Setting this flag to `true` adds `multipart/form-data` when no content type is supplied, but does not add the boundary. The default upload method is `PUT`; the example explicitly uses `POST`.
|
|
94
461
|
|
|
95
|
-
|
|
96
|
-
ConstValue = {
|
|
97
|
-
// Logical operators
|
|
98
|
-
AND: '&&',
|
|
99
|
-
OR: '||',
|
|
100
|
-
NOT: '!',
|
|
101
|
-
|
|
102
|
-
// Common special characters
|
|
103
|
-
AT: '@',
|
|
104
|
-
HASH: '#',
|
|
105
|
-
DOLLAR: '$',
|
|
106
|
-
PERCENT: '%',
|
|
107
|
-
CARET: '^',
|
|
108
|
-
AMPERSAND: '&',
|
|
109
|
-
ASTERISK: '*',
|
|
110
|
-
TILDE: '~',
|
|
111
|
-
COLON: ':',
|
|
112
|
-
SEMICOLON: ';',
|
|
113
|
-
DOUBLE_QUOTE: '"',
|
|
114
|
-
SINGLE_QUOTE: "'",
|
|
115
|
-
COMMA: ',',
|
|
116
|
-
PERIOD: '.',
|
|
117
|
-
SLASH: '/',
|
|
118
|
-
QUESTION_MARK: '?',
|
|
119
|
-
PLUS: '+',
|
|
120
|
-
UNDERSCORE: '_',
|
|
121
|
-
HYPHEN: '-',
|
|
122
|
-
EQUALS: '=',
|
|
123
|
-
BACKSLASH: '\\',
|
|
124
|
-
PIPE: '|',
|
|
125
|
-
|
|
126
|
-
// Space
|
|
127
|
-
SPACE: ' ',
|
|
128
|
-
EMPTY: '',
|
|
129
|
-
|
|
130
|
-
// Other
|
|
131
|
-
TRUE: 'true',
|
|
132
|
-
FALSE: 'false',
|
|
133
|
-
NULL: 'null',
|
|
134
|
-
UNDEFINED: 'undefined',
|
|
135
|
-
|
|
136
|
-
STR_AND: 'AND',
|
|
137
|
-
STR_OR: 'OR',
|
|
138
|
-
STR_NOT: 'NOT',
|
|
462
|
+
#### Upload a file directly
|
|
139
463
|
|
|
140
|
-
|
|
141
|
-
DESC: 'DESC',
|
|
464
|
+
`CloudUpload` sends the file itself as the request body, using its MIME type as the default `Content-Type`. Supply the complete destination URL.
|
|
142
465
|
|
|
143
|
-
|
|
144
|
-
|
|
466
|
+
```typescript
|
|
467
|
+
async function uploadFile(uploadUrl: string, file: File) {
|
|
468
|
+
const response = await Http.CloudUpload(uploadUrl, file);
|
|
469
|
+
if (!response.ok) {
|
|
470
|
+
throw new Error(`Upload failed: ${response.status}`);
|
|
471
|
+
}
|
|
472
|
+
return response;
|
|
473
|
+
}
|
|
474
|
+
```
|
|
145
475
|
|
|
146
|
-
|
|
147
|
-
PM: 'PM',
|
|
476
|
+
Custom headers replace the default file content type. The destination must accept the headers sent by the helper, including `request-id`.
|
|
148
477
|
|
|
149
|
-
|
|
150
|
-
DARK: 'dark',
|
|
478
|
+
#### Download a file
|
|
151
479
|
|
|
152
|
-
|
|
153
|
-
"Jan",
|
|
154
|
-
"Feb",
|
|
155
|
-
"Mar",
|
|
156
|
-
"Apr",
|
|
157
|
-
"May",
|
|
158
|
-
"Jun",
|
|
159
|
-
"Jul",
|
|
160
|
-
"Aug",
|
|
161
|
-
"Sep",
|
|
162
|
-
"Oct",
|
|
163
|
-
"Nov",
|
|
164
|
-
"Dec",
|
|
165
|
-
],
|
|
480
|
+
`FileDownload` returns a `Blob`; it does not save the file to disk or trigger a browser download.
|
|
166
481
|
|
|
167
|
-
|
|
482
|
+
```typescript
|
|
483
|
+
const fileBlob = await Http.FileDownload(
|
|
484
|
+
'https://api.example.com/files/report.pdf',
|
|
485
|
+
null,
|
|
486
|
+
{ authorization: 'Bearer YOUR_ACCESS_TOKEN' },
|
|
487
|
+
);
|
|
168
488
|
```
|
|
169
489
|
|
|
170
|
-
|
|
490
|
+
To reject non-success HTTP statuses before returning a blob, use `Get` with `RespType.BLOB`:
|
|
171
491
|
|
|
492
|
+
```typescript
|
|
493
|
+
const fileBlob = await Http.Get(
|
|
494
|
+
'/files/report.pdf',
|
|
495
|
+
null,
|
|
496
|
+
{ authorization: 'Bearer YOUR_ACCESS_TOKEN' },
|
|
497
|
+
RespType.BLOB,
|
|
498
|
+
);
|
|
172
499
|
```
|
|
173
|
-
RegExp = {
|
|
174
|
-
// Matches any non-alphanumeric characters
|
|
175
|
-
NON_ALPHA_NUMERIC: /[^\w\s]/g,
|
|
176
500
|
|
|
177
|
-
|
|
178
|
-
DIGITS_ONLY: /^\d+$/,
|
|
501
|
+
## Call Api
|
|
179
502
|
|
|
180
|
-
|
|
181
|
-
ALPHABETS_ONLY: /^[a-zA-Z]+$/,
|
|
503
|
+
These helpers are defined in `src/main/api-call.ts` and exported from `dff-util`. All three use synchronous `XMLHttpRequest`: they return values directly and throw errors synchronously. No `await` is needed. Browser XHR support and server CORS permission are required; requests block while waiting.
|
|
182
504
|
|
|
183
|
-
|
|
184
|
-
ALPHA_NUMERIC: /^[a-zA-Z0-9]+$/,
|
|
505
|
+
The former names `Hbs`, `LangText`, and `CurrencyConvert` are now `CallHbs`, `CallLangText`, and `CallCurrencyConvert`. Import them from `dff-util` or `main/api-call` instead of `main/util`.
|
|
185
506
|
|
|
186
|
-
|
|
187
|
-
EMAIL: /^[\w.%+-]+@[a-zA-Z\d.-]+\.[a-zA-Z]{2,}$/,
|
|
507
|
+
### Handlebars rendering (CallHbs)
|
|
188
508
|
|
|
189
|
-
|
|
190
|
-
URL: /^(https?:\/\/)?([\w.-]+)\.([a-z]{2,6}\.?)(\/[\w.-]*)*\/?$/i,
|
|
509
|
+
`CallHbs` renders inline templates through `https://hbs.rndpro.in`, using the same request format as the HBS service. It uses synchronous `XMLHttpRequest` and sends the template and data to that service. It returns directly, without a Promise. Standard Node.js does not provide `XMLHttpRequest`.
|
|
191
510
|
|
|
192
|
-
|
|
193
|
-
PHONE_US: /^(\(\d{3}\)\s?|\d{3}[-.\s]?)?\d{3}[-.\s]?\d{4}$/,
|
|
511
|
+
Synchronous requests block the browser while waiting and are deprecated on the main thread. The service must permit your browser origin and JSON POST requests through CORS. See [synchronous XHR limitations](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest_API/Synchronous_and_Asynchronous_Requests).
|
|
194
512
|
|
|
195
|
-
|
|
196
|
-
|
|
513
|
+
| Call | Endpoint | Return type |
|
|
514
|
+
| :--- | :--- | :--- |
|
|
515
|
+
| `CallHbs(template, data)` | `POST /render` | `string` |
|
|
516
|
+
| `CallHbs(template, items, true)` | `POST /multi` | `string[]` |
|
|
197
517
|
|
|
198
|
-
|
|
199
|
-
WHITESPACE: /\s+/g,
|
|
518
|
+
The TypeScript return type is `string | string[]`; the table shows the result for each mode.
|
|
200
519
|
|
|
201
|
-
|
|
202
|
-
HTML_TAG: /<\/?[\w\s="/.':;#-\/\?]+>/gi,
|
|
520
|
+
#### Supported inputs and rendering modes
|
|
203
521
|
|
|
204
|
-
|
|
205
|
-
IPV4: /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/,
|
|
522
|
+
Based on the `dff-hbs` service in the local `hbs` repository (`src/models.rs`, `src/controller.rs`, and `src/service.rs`). The client accepts objects or arrays of objects; the server model itself accepts any JSON value.
|
|
206
523
|
|
|
207
|
-
|
|
208
|
-
|
|
524
|
+
| Input or mode | Type | Behavior / example |
|
|
525
|
+
| :--- | :--- | :--- |
|
|
526
|
+
| `template` | `string` | Inline Handlebars text, such as `Hello, {{name}}!`; not a registered template name |
|
|
527
|
+
| `data` with `multi = false` (default) | `RequestBodyType` | One object used as the template context: `{ name: 'Prasad' }` |
|
|
528
|
+
| `data` with `multi = false` | `RequestBodyType[]` | One array context; iterate using `{{#each this}}{{name}}{{/each}}` |
|
|
529
|
+
| `data` with `multi = true` | `RequestBodyType[]` | Render the same template for each object in one `/multi` request |
|
|
530
|
+
| Object property values | JSON string, number, boolean, null, object, or array | Nested data is supported, for example `{ user: { name: 'Prasad' }, active: true }` |
|
|
531
|
+
| Single result | `string` | Rendered text from `/render` |
|
|
532
|
+
| Batch result | `string[]` | Rendered strings in input order from `/multi`; an empty array returns `[]` |
|
|
209
533
|
|
|
210
|
-
|
|
211
|
-
TIME_HH_MM: /^([01]\d|2[0-3]):([0-5]\d)$/,
|
|
534
|
+
#### Template helper reference
|
|
212
535
|
|
|
213
|
-
|
|
214
|
-
ISO_DATETIME: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/,
|
|
536
|
+
The service registers `handlebars_misc_helpers::string_helpers` and `handlebars_switch::SwitchHelper`. The following string helpers are listed in the HBS repository's README. Use these expressions inside the `template` argument; they apply to both rendering modes.
|
|
215
537
|
|
|
216
|
-
|
|
217
|
-
|
|
538
|
+
| Helper | Purpose | Template expression | Example (input → output) |
|
|
539
|
+
| :--- | :--- | :--- | :--- |
|
|
540
|
+
| `replace` | Replace text | `{{replace name "old" "new"}}` | `Hello old` → `Hello new` |
|
|
541
|
+
| `to_lower_case` | Lowercase text | `{{to_lower_case name}}` | `Admin` → `admin` |
|
|
542
|
+
| `to_upper_case` | Uppercase text | `{{to_upper_case name}}` | `Admin` → `ADMIN` |
|
|
543
|
+
| `to_camel_case` | camelCase | `{{to_camel_case name}}` | `admin_user` → `adminUser` |
|
|
544
|
+
| `to_pascal_case` | PascalCase | `{{to_pascal_case name}}` | `admin_user` → `AdminUser` |
|
|
545
|
+
| `to_snake_case` | snake_case | `{{to_snake_case name}}` | `AdminUser` → `admin_user` |
|
|
546
|
+
| `to_screaming_snake_case` | SCREAMING_SNAKE_CASE | `{{to_screaming_snake_case name}}` | `AdminUser` → `ADMIN_USER` |
|
|
547
|
+
| `to_kebab_case` | kebab-case | `{{to_kebab_case name}}` | `AdminUser` → `admin-user` |
|
|
548
|
+
| `to_train_case` | Train-Case | `{{to_train_case name}}` | `admin_user` → `Admin-User` |
|
|
549
|
+
| `to_sentence_case` | Sentence case | `{{to_sentence_case name}}` | `admin_user` → `Admin user` |
|
|
550
|
+
| `to_title_case` | Title Case | `{{to_title_case name}}` | `admin_user` → `Admin User` |
|
|
551
|
+
| `to_class_case` | Class-name conversion | `{{to_class_case name}}` | `admin_users` → `AdminUser` |
|
|
552
|
+
| `to_table_case` | Table-name conversion | `{{to_table_case name}}` | `AdminUser` → `admin_users` |
|
|
553
|
+
| `to_plural` | Pluralize a word | `{{to_plural name}}` | `user` → `users` |
|
|
554
|
+
| `to_singular` | Singularize a word | `{{to_singular name}}` | `users` → `user` |
|
|
555
|
+
| `to_foreign_key` | Foreign-key name conversion | `{{to_foreign_key name}}` | `AdminUser` → `admin_user_id` |
|
|
556
|
+
| `demodulize` | Remove module qualification | `{{demodulize "Test::Foo::Bar"}}` | `Test::Foo::Bar` → `Bar` |
|
|
557
|
+
| `ordinalize` | Convert a number to ordinal text | `{{ordinalize "9"}}` | `9` → `9th` |
|
|
558
|
+
| `deordinalize` | Remove ordinal suffix | `{{deordinalize "9th"}}` | `9th` → `9` |
|
|
559
|
+
| `trim` | Remove surrounding whitespace | `{{trim name}}` | `" Admin "` → `"Admin"` |
|
|
560
|
+
| `trim_start` | Remove leading whitespace | `{{trim_start name}}` | `" Admin "` → `"Admin "` |
|
|
561
|
+
| `trim_end` | Remove trailing whitespace | `{{trim_end name}}` | `" Admin "` → `" Admin"` |
|
|
562
|
+
| `unquote` | Remove surrounding quotes | `{{unquote name}}` | `"Admin"` → `Admin` |
|
|
563
|
+
| `quote` | Add quotes using the default delimiter | `{{quote "" name}}` | `Admin` → `"Admin"` |
|
|
564
|
+
| `first_non_empty` | Select the first nonempty value | `{{first_non_empty nickname name "Guest"}}` | `nickname: "", name: "Admin"` → `Admin` |
|
|
565
|
+
| `switch`, `case`, `default` | Choose output based on a value | `{{#switch access}}{{#case "admin"}}Admin{{/case}}{{#default}}User{{/default}}{{/switch}}` | `access: "admin"` → `Admin`; `access: "user"` → `User` |
|
|
218
566
|
|
|
219
|
-
|
|
220
|
-
UUID_V4: /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
|
|
567
|
+
Helpers can be nested, for example `{{to_upper_case (first_non_empty nickname name "Guest")}}`.
|
|
221
568
|
|
|
222
|
-
// Matches non-ASCII characters
|
|
223
|
-
NON_ASCII: /[^\x00-\x7F]/g,
|
|
224
569
|
|
|
225
|
-
|
|
226
|
-
LINE_BREAK: /\r?\n/g,
|
|
570
|
+
Quote examples show the helper value before any HTML escaping. The registered helper is `quote`; the HBS repository README calls it `enquote`, but its dependency registers `quote`.
|
|
227
571
|
|
|
228
|
-
|
|
229
|
-
AMOUNT_DECIMAL: /^\d+(\.\d{1,2})?$/,
|
|
572
|
+
#### Render a single template
|
|
230
573
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
574
|
+
```typescript
|
|
575
|
+
import { CallHbs } from 'dff-util';
|
|
576
|
+
|
|
577
|
+
const rendered = CallHbs('Hello, {{to_pascal_case name}}!', {
|
|
578
|
+
name: 'prasad',
|
|
579
|
+
});
|
|
580
|
+
console.log(rendered); // Hello, Prasad!
|
|
234
581
|
```
|
|
235
582
|
|
|
236
|
-
|
|
583
|
+
#### Render multiple data items in one request
|
|
237
584
|
|
|
238
|
-
```
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
type?: string;
|
|
246
|
-
requestId?: string;
|
|
247
|
-
token?: string;
|
|
248
|
-
iat?: number;
|
|
249
|
-
exp?: number;
|
|
250
|
-
key: string;
|
|
251
|
-
};
|
|
585
|
+
```typescript
|
|
586
|
+
const rendered = CallHbs(
|
|
587
|
+
'Hello, {{to_pascal_case name}}!',
|
|
588
|
+
[{ name: 'prasad' }, { name: 'monika' }],
|
|
589
|
+
true,
|
|
590
|
+
);
|
|
591
|
+
console.log(rendered); // ['Hello, Prasad!', 'Hello, Monika!']
|
|
252
592
|
```
|
|
253
593
|
|
|
254
|
-
|
|
594
|
+
The third argument defaults to `false`. Set it to `true` to render the same template once per array item, preserving order. An empty batch returns `[]`. With `false`, an array is treated as a single template context, for example with `{{#each this}}`.
|
|
255
595
|
|
|
256
|
-
|
|
257
|
-
export type SessionUser = {
|
|
258
|
-
id: string;
|
|
259
|
-
email?: string;
|
|
260
|
-
mobile?: string;
|
|
261
|
-
name?: string;
|
|
262
|
-
roles: string[];
|
|
263
|
-
type?: string;
|
|
264
|
-
};
|
|
265
|
-
```
|
|
596
|
+
Both endpoints receive JSON in the form `{ template, data }`. Templates can use the string helpers and `switch` helper registered by HBS. Data must be a JSON object or an array of JSON objects; batch rendering requires an array of objects. Empty templates are allowed. Omitting `multi` is equivalent to passing `false`.
|
|
266
597
|
|
|
598
|
+
#### Handle failures
|
|
267
599
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
currencyCode: string; // ISO 4217 currency code
|
|
276
|
-
currency: string; // Currency symbol
|
|
277
|
-
telCode: number; // Numeric only (no +)
|
|
278
|
-
flag: string; // Emoji flag
|
|
279
|
-
};
|
|
600
|
+
```typescript
|
|
601
|
+
try {
|
|
602
|
+
const result = CallHbs('Hello, {{name}}!', { name: 'Prasad' });
|
|
603
|
+
console.log(result);
|
|
604
|
+
} catch (error) {
|
|
605
|
+
console.error(error instanceof Error ? error.message : error);
|
|
606
|
+
}
|
|
280
607
|
```
|
|
281
608
|
|
|
282
|
-
|
|
283
|
-
```
|
|
284
|
-
const countriesList = countries;
|
|
609
|
+
Non-success HTTP responses throw an error containing the status and response text. The service returns `400` for invalid requests and `500` for rendering failures; a failing batch reports the item index and rejects the entire batch. Network, CORS, and JSON-parsing errors propagate to the caller. Successful batch responses are checked to ensure they contain an array of strings.
|
|
285
610
|
|
|
286
|
-
|
|
287
|
-
```
|
|
288
|
-
## LangDirType, OrderType, ThemeType, UnixTimestampType, OptionType, FileType
|
|
289
|
-
```
|
|
290
|
-
export type LangDirType = "ltr" | "rtl";
|
|
291
|
-
export type OrderType = "ASC" | "DESC";
|
|
292
|
-
export type ThemeType = "light" | "dark";
|
|
293
|
-
export type UnixTimestampType = number & { __brand: "UnixTimestamp" };
|
|
611
|
+
### Language translation (CallLangText)
|
|
294
612
|
|
|
295
|
-
|
|
296
|
-
label: string;
|
|
297
|
-
key: string | number;
|
|
298
|
-
disabled?: boolean;
|
|
299
|
-
icon?: string;
|
|
300
|
-
lang?: Record<string, string>;
|
|
301
|
-
};
|
|
613
|
+
`CallLangText(text, sourceLocale, targetLocale)` returns the translated text as a `string`.
|
|
302
614
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
mimetype: string;
|
|
306
|
-
url: string;
|
|
307
|
-
};
|
|
308
|
-
```
|
|
309
|
-
## LanguageType
|
|
310
|
-
```
|
|
311
|
-
export type LanguageType = {
|
|
312
|
-
lang: string; // Locale code (e.g., en-US, hi-IN)
|
|
313
|
-
code: string; // ISO 639-1 language code (e.g., en, hi)
|
|
314
|
-
country: string; // ISO 3166-1 alpha-2 country code (e.g., US, IN)
|
|
315
|
-
name: string; // English name of the language
|
|
316
|
-
dir: "ltr" | "rtl"; // Text direction
|
|
317
|
-
locale: string; // Native name of the language
|
|
318
|
-
};
|
|
319
|
-
```
|
|
320
|
-
## LangCountryType
|
|
321
|
-
```
|
|
322
|
-
export type LangCountryType = {
|
|
323
|
-
lang: string; // Locale code (e.g., en-US, hi-IN)
|
|
324
|
-
country: string; // ISO 3166-1 alpha-2 country code (e.g., US, IN)
|
|
325
|
-
name: string; // English name of the language
|
|
326
|
-
locale: string; // Native name of the language
|
|
327
|
-
currencyCode: string; // ISO 4217 currency code
|
|
328
|
-
currency: string; // Currency symbol
|
|
329
|
-
telCode: number; // Numeric only (no +)
|
|
330
|
-
flag: string; // Emoji flag
|
|
331
|
-
dir: "ltr" | "rtl"; // Text direction
|
|
332
|
-
};
|
|
333
|
-
```
|
|
615
|
+
```typescript
|
|
616
|
+
import { CallLangText } from 'dff-util';
|
|
334
617
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
error?: any;
|
|
341
|
-
total?: number;
|
|
342
|
-
skip?: number;
|
|
343
|
-
limit?: number;
|
|
344
|
-
meta?: {
|
|
345
|
-
traceId?: string | number;
|
|
346
|
-
timestamp?: string | number;
|
|
347
|
-
duration?: number;
|
|
348
|
-
};
|
|
618
|
+
try {
|
|
619
|
+
const translated = CallLangText('Hello, how are you?', 'en-US', 'te-IN');
|
|
620
|
+
console.log(translated);
|
|
621
|
+
} catch (error) {
|
|
622
|
+
console.error(error instanceof Error ? error.message : error);
|
|
349
623
|
}
|
|
624
|
+
```
|
|
350
625
|
|
|
351
|
-
|
|
352
|
-
limit?: number;
|
|
353
|
-
skip?: number;
|
|
354
|
-
orderBy?: string;
|
|
355
|
-
order?: 'ASC' | 'DESC';
|
|
356
|
-
searchTerm?: string;
|
|
357
|
-
active?: boolean;
|
|
358
|
-
filters?: string;
|
|
359
|
-
};
|
|
626
|
+
Uses `https://lingva.ml/api/v1`, taking the two-letter language prefix from each locale. Text is URL-encoded. Empty inputs, invalid language codes, unsuccessful HTTP responses, and service-reported errors throw.
|
|
360
627
|
|
|
361
|
-
|
|
362
|
-
|
|
628
|
+
### Currency conversion (CallCurrencyConvert)
|
|
629
|
+
|
|
630
|
+
`CallCurrencyConvert(fromCurrency, toCurrency)` returns the exchange rate as a `number`: the target-currency value of one source-currency unit.
|
|
631
|
+
|
|
632
|
+
```typescript
|
|
633
|
+
import { CallCurrencyConvert } from 'dff-util';
|
|
634
|
+
|
|
635
|
+
try {
|
|
636
|
+
const rate = CallCurrencyConvert('INR', 'USD');
|
|
637
|
+
console.log(rate);
|
|
638
|
+
console.log(CallCurrencyConvert('USD', 'USD')); // 1; no HTTP request
|
|
639
|
+
} catch (error) {
|
|
640
|
+
console.error(error instanceof Error ? error.message : error);
|
|
363
641
|
}
|
|
642
|
+
```
|
|
364
643
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
644
|
+
Uses `https://api.frankfurter.dev/v1/latest`. Missing inputs, unsuccessful HTTP responses, and missing or nonnumeric rates throw. Network and JSON-parsing errors propagate to the caller.
|
|
645
|
+
|
|
646
|
+
## Tokens and encryption
|
|
647
|
+
|
|
648
|
+
### JWT tokens
|
|
649
|
+
|
|
650
|
+
#### Encode a token
|
|
371
651
|
|
|
652
|
+
Sign a payload with a secret key. `expiresIn` is measured in seconds and defaults to `86400` (one day).
|
|
653
|
+
|
|
654
|
+
```typescript
|
|
655
|
+
JwtEncode(data, secret, expiresIn);
|
|
372
656
|
```
|
|
373
657
|
|
|
658
|
+
#### Decode a token
|
|
374
659
|
|
|
660
|
+
```typescript
|
|
661
|
+
JwtDecode(token);
|
|
662
|
+
```
|
|
375
663
|
|
|
376
|
-
|
|
664
|
+
#### Verify a token with a secret
|
|
377
665
|
|
|
666
|
+
```typescript
|
|
667
|
+
JwtVerify(token, secret);
|
|
378
668
|
```
|
|
379
|
-
export const ConstMessages = {
|
|
380
|
-
// Validation messages
|
|
381
|
-
REQUIRED: 'Required',
|
|
382
|
-
MIN_LENGTH_REQUIRED: 'Minimum length required',
|
|
383
|
-
MAX_LENGTH_EXCEED: 'Maximum length exceeded',
|
|
384
|
-
INVALID_DATA: 'Invalid data',
|
|
385
|
-
FIELD_MUST_BE_NUMERIC: 'This field must be numeric',
|
|
386
|
-
FIELD_MUST_BE_ALPHABETIC: 'This field must contain only letters',
|
|
387
|
-
FIELD_MUST_BE_ALPHANUMERIC: 'This field must contain only letters and numbers',
|
|
388
|
-
INVALID_EMAIL: 'Invalid email format',
|
|
389
|
-
INVALID_PHONE: 'Invalid phone number',
|
|
390
|
-
PASSWORD_TOO_WEAK: 'Password is too weak',
|
|
391
|
-
PASSWORDS_DO_NOT_MATCH: 'Passwords do not match',
|
|
392
|
-
INVALID_DATE_FORMAT: 'Invalid date format',
|
|
393
|
-
DATE_OUT_OF_RANGE: 'Date is out of acceptable range',
|
|
394
|
-
VALUE_TOO_LOW: 'Value is too low',
|
|
395
|
-
VALUE_TOO_HIGH: 'Value is too high',
|
|
396
|
-
EXCEEDS_MAX_CHARACTERS: 'Exceeds maximum character limit',
|
|
397
|
-
INVALID_URL: 'Invalid URL format',
|
|
398
|
-
INVALID_ZIP_CODE: 'Invalid zip/postal code',
|
|
399
|
-
ONLY_POSITIVE_NUMBERS: 'Only positive numbers are allowed',
|
|
400
|
-
INVALID_CREDIT_CARD: 'Invalid credit card number',
|
|
401
|
-
INVALID_FILE_TYPE: 'Unsupported file type',
|
|
402
|
-
FILE_TOO_LARGE: 'File size exceeds the maximum limit',
|
|
403
669
|
|
|
404
|
-
|
|
405
|
-
SUCCESS: 'Operation completed successfully',
|
|
406
|
-
SAVED_SUCCESSFULLY: 'Data saved successfully',
|
|
407
|
-
UPDATED_SUCCESSFULLY: 'Data updated successfully',
|
|
408
|
-
DELETED_SUCCESSFULLY: 'Data deleted successfully',
|
|
409
|
-
SUBMITTED_SUCCESSFULLY: 'Form submitted successfully',
|
|
410
|
-
EMAIL_SENT: 'Email sent successfully',
|
|
411
|
-
PASSWORD_CHANGED: 'Password changed successfully',
|
|
412
|
-
LOGGED_IN: 'Logged in successfully',
|
|
413
|
-
LOGGED_OUT: 'Logged out successfully',
|
|
414
|
-
UPLOAD_SUCCESSFUL: 'File uploaded successfully',
|
|
415
|
-
PAYMENT_SUCCESSFUL: 'Payment processed successfully',
|
|
416
|
-
DATA_FETCHED: 'Data fetched successfully',
|
|
417
|
-
DATA_LOADED: 'Data loaded successfully',
|
|
418
|
-
ACTION_COMPLETED: 'Action completed successfully',
|
|
419
|
-
|
|
420
|
-
// Error messages
|
|
421
|
-
WENT_WRONG: 'Something went wrong, please try again',
|
|
422
|
-
NOT_FOUND: 'Requested resource not found',
|
|
423
|
-
UNAUTHORIZED: 'You are not authorized to perform this action',
|
|
424
|
-
FORBIDDEN: 'Access to this resource is forbidden',
|
|
425
|
-
SERVER_ERROR: 'Internal server error, please contact support',
|
|
426
|
-
CONNECTION_ERROR: 'Unable to connect, please check your internet connection',
|
|
427
|
-
TIMEOUT_ERROR: 'The request timed out, please try again later',
|
|
428
|
-
VALIDATION_FAILED: 'Validation failed, please check the input',
|
|
429
|
-
DUPLICATE_ENTRY: 'Duplicate entry, please provide unique data',
|
|
430
|
-
SESSION_EXPIRED: 'Your session has expired, please log in again',
|
|
431
|
-
INVALID_SESSION: 'Invalid session, please authenticate',
|
|
432
|
-
RATE_LIMIT_EXCEEDED: 'Too many requests, please try again later',
|
|
433
|
-
RESOURCE_LOCKED: 'This resource is currently locked',
|
|
434
|
-
DATA_CORRUPTED: 'Data is corrupted',
|
|
435
|
-
SERVICE_UNAVAILABLE: 'Service is currently unavailable',
|
|
436
|
-
PAYMENT_FAILED: 'Payment failed, please check your details',
|
|
437
|
-
OPERATION_FAILED: 'Operation failed, please try again',
|
|
438
|
-
ACCESS_DENIED: 'Access denied',
|
|
439
|
-
INVALID_CREDENTIALS: 'Invalid credentials, please try again',
|
|
440
|
-
INVALID_TOKEN: 'Invalid token, please try again',
|
|
441
|
-
USER_NOT_FOUND: 'User not found, please try again',
|
|
442
|
-
PASSWORD_RESET_FAILED: 'Password reset failed, please try again',
|
|
670
|
+
#### Check token expiration
|
|
443
671
|
|
|
444
|
-
|
|
445
|
-
NO_DATA_FOUND: 'No data found',
|
|
446
|
-
NO_RECORD_FOUND: 'No record found',
|
|
447
|
-
NO_RECORDS_FOUND: 'No records found',
|
|
448
|
-
NO_RECORDS_MATCHED: 'No records matched your search criteria',
|
|
449
|
-
NO_RECORDS_MATCHED_FILTER: 'No records matched your filter criteria',
|
|
450
|
-
LOADING: 'Loading, please wait...',
|
|
451
|
-
FETCHING_DATA: 'Fetching data, please wait...',
|
|
452
|
-
PROCESSING: 'Processing your request...',
|
|
453
|
-
PLEASE_WAIT: 'Please wait...',
|
|
454
|
-
NO_RESULTS_FOUND: 'No results found',
|
|
455
|
-
NO_DATA_AVAILABLE: 'No data available',
|
|
456
|
-
SEARCHING: 'Searching...',
|
|
457
|
-
REDIRECTING: 'Redirecting, please wait...',
|
|
458
|
-
CONNECTING: 'Connecting, please wait...',
|
|
459
|
-
LOGGING_OUT: 'Logging out, please wait...',
|
|
460
|
-
LOGGING_IN: 'Logging in, please wait...',
|
|
461
|
-
PREPARING_DOWNLOAD: 'Preparing your download...',
|
|
462
|
-
CHECKING_UPDATES: 'Checking for updates...',
|
|
672
|
+
`JwtValid` checks whether the token can be decoded and has expired; use `JwtVerify` to verify its signature.
|
|
463
673
|
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
CONFIRM_SUBMIT: 'Do you want to submit this form?',
|
|
468
|
-
CONFIRM_LOGOUT: 'Are you sure you want to log out?',
|
|
469
|
-
CONFIRM_ACTION: 'Are you sure you want to proceed?',
|
|
470
|
-
CONFIRM_CLOSE: 'Are you sure you want to close this window?',
|
|
471
|
-
CONFIRM_CANCEL: 'Do you want to cancel this action?',
|
|
472
|
-
CONFIRM_RESTART: 'Do you want to restart the process?',
|
|
674
|
+
```typescript
|
|
675
|
+
JwtValid(token);
|
|
676
|
+
```
|
|
473
677
|
|
|
474
|
-
|
|
475
|
-
UNSAVED_CHANGES: 'You have unsaved changes. Do you want to discard them?',
|
|
476
|
-
LOW_BATTERY: 'Battery level is low, please connect your charger',
|
|
477
|
-
HIGH_USAGE: 'High system usage detected',
|
|
478
|
-
INCOMPLETE_FORM: 'The form is incomplete',
|
|
479
|
-
LIMIT_REACHED: 'You have reached the maximum limit',
|
|
480
|
-
OUTDATED_VERSION: 'You are using an outdated version of the application',
|
|
678
|
+
#### Example
|
|
481
679
|
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
GOODBYE: 'Goodbye, have a great day!',
|
|
485
|
-
HELLO: 'Hello, how can we help you today?',
|
|
486
|
-
THANK_YOU: 'Thank you for using our service',
|
|
487
|
-
TRY_AGAIN: 'Please try again',
|
|
488
|
-
UNDER_MAINTENANCE: 'The system is under maintenance, please check back later',
|
|
489
|
-
FEATURE_COMING_SOON: 'This feature is coming soon',
|
|
490
|
-
CONTACT_SUPPORT: 'If the issue persists, please contact support',
|
|
491
|
-
UPDATING: 'Updating, please wait...',
|
|
492
|
-
INSTALLING: 'Installing, please wait...',
|
|
493
|
-
RESTART_REQUIRED: 'A restart is required to apply changes',
|
|
494
|
-
RESTARTING: 'Restarting, please wait...',
|
|
495
|
-
LOADING_DATA: 'Loading data, please wait...',
|
|
496
|
-
SAVING: 'Saving, please wait...',
|
|
497
|
-
};
|
|
680
|
+
```typescript
|
|
681
|
+
import { JwtEncode, JwtVerify, JwtDecode, JwtValid } from '../src/index';
|
|
498
682
|
|
|
499
|
-
|
|
683
|
+
const runJwtExamples = async () => {
|
|
684
|
+
const secret = 'your-secret-key';
|
|
685
|
+
const payload = { userId: '123', role: 'admin' };
|
|
500
686
|
|
|
501
|
-
|
|
687
|
+
// 1. Encode a JWT
|
|
688
|
+
const token = await JwtEncode(payload, secret, 3600);
|
|
689
|
+
console.log('Encoded JWT Token:', token);
|
|
502
690
|
|
|
503
|
-
|
|
504
|
-
|
|
691
|
+
// 2. Verify the JWT
|
|
692
|
+
try {
|
|
693
|
+
const verifiedPayload = await JwtVerify(token, secret);
|
|
694
|
+
console.log('Verified Payload:', verifiedPayload);
|
|
695
|
+
} catch (error: any) {
|
|
696
|
+
console.error('Verification Error:', error.message);
|
|
697
|
+
}
|
|
505
698
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
699
|
+
// 3. Decode the JWT without verification
|
|
700
|
+
const decodedPayload = JwtDecode(token);
|
|
701
|
+
console.log('Decoded Payload (without verification):', decodedPayload);
|
|
509
702
|
|
|
510
|
-
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
console.log(filePath);
|
|
514
|
-
const main = async () => {
|
|
515
|
-
const data = await fs.readFile(filePath);
|
|
516
|
-
const resp = await Http.Upload(
|
|
517
|
-
url,
|
|
518
|
-
new File([data], filePath, {
|
|
519
|
-
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
520
|
-
lastModified: Date.now(),
|
|
521
|
-
}),
|
|
522
|
-
);
|
|
523
|
-
console.log('Http.Upload :: ', resp);
|
|
703
|
+
// 4. Check if the JWT is valid
|
|
704
|
+
const isValid = JwtValid(token);
|
|
705
|
+
console.log('Is JWT valid:', isValid);
|
|
524
706
|
};
|
|
525
707
|
|
|
526
|
-
|
|
708
|
+
runJwtExamples();
|
|
709
|
+
|
|
527
710
|
```
|
|
528
711
|
|
|
529
|
-
|
|
712
|
+
### Encryption and encoding
|
|
530
713
|
|
|
531
|
-
```
|
|
714
|
+
```typescript
|
|
532
715
|
const hexStringToArrayBuffer = (hex: string) => {
|
|
533
716
|
const hexMatches = hex.match(/.{1,2}/g) || [];
|
|
534
717
|
const typedArray = new Uint8Array(hexMatches.map((byte) => parseInt(byte, 16)));
|
|
@@ -547,7 +730,7 @@ export const Decrypt = async (text: string, key: string) => {
|
|
|
547
730
|
};
|
|
548
731
|
```
|
|
549
732
|
|
|
550
|
-
```
|
|
733
|
+
```typescript
|
|
551
734
|
import * as crypto from 'crypto';
|
|
552
735
|
export const Encrypt = (text: string, key: string) => {
|
|
553
736
|
const iv = crypto.randomBytes(16);
|
|
@@ -558,7 +741,7 @@ export const Encrypt = (text: string, key: string) => {
|
|
|
558
741
|
};
|
|
559
742
|
```
|
|
560
743
|
|
|
561
|
-
```
|
|
744
|
+
```typescript
|
|
562
745
|
// ts-node test/test.ts
|
|
563
746
|
import crypto from 'crypto';
|
|
564
747
|
|
|
@@ -580,12 +763,16 @@ const main = async () => {
|
|
|
580
763
|
|
|
581
764
|
main();
|
|
582
765
|
|
|
583
|
-
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
#### Base64, URL, and safe encoding
|
|
769
|
+
|
|
770
|
+
```typescript
|
|
584
771
|
|
|
585
772
|
// Base64
|
|
586
773
|
const text = "Hello World!";
|
|
587
|
-
const encodedBase64 =
|
|
588
|
-
const decodedBase64 =
|
|
774
|
+
const encodedBase64 = EncodeBase64(text); // "SGVsbG8gV29ybGQh"
|
|
775
|
+
const decodedBase64 = DecodeBase64(encodedBase64); // "Hello World!"
|
|
589
776
|
|
|
590
777
|
console.log(encodedBase64, decodedBase64);
|
|
591
778
|
|
|
@@ -593,77 +780,108 @@ console.log(encodedBase64, decodedBase64);
|
|
|
593
780
|
const url = "https://example.com/query?name=John Doe&city=New York";
|
|
594
781
|
|
|
595
782
|
// First encode
|
|
596
|
-
const encodedURL1 =
|
|
783
|
+
const encodedURL1 = EncodeURL(url);
|
|
597
784
|
console.log(encodedURL1);
|
|
598
785
|
// Output: "https%3A%2F%2Fexample.com%2Fquery%3Fname%3DJohn%20Doe%26city%3DNew%20York"
|
|
599
786
|
|
|
600
787
|
// Encode again (idempotent)
|
|
601
|
-
const encodedURL2 =
|
|
788
|
+
const encodedURL2 = EncodeURL(encodedURL1);
|
|
602
789
|
console.log(encodedURL2 === encodedURL1); // true ✅
|
|
603
790
|
|
|
604
791
|
// Decode
|
|
605
|
-
const decodedURL1 =
|
|
792
|
+
const decodedURL1 = DecodeURL(encodedURL1);
|
|
606
793
|
console.log(decodedURL1); // "https://example.com/query?name=John Doe&city=New York"
|
|
607
794
|
|
|
608
795
|
// Decode again (idempotent)
|
|
609
|
-
const decodedURL2 =
|
|
796
|
+
const decodedURL2 = DecodeURL(decodedURL1);
|
|
610
797
|
console.log(decodedURL2 === decodedURL1); // true ✅
|
|
611
798
|
|
|
612
799
|
const original = "Hello World! @#$% 😊";
|
|
613
800
|
|
|
614
801
|
// Encode
|
|
615
|
-
const safe =
|
|
802
|
+
const safe = SafeEncode(original);
|
|
616
803
|
console.log(safe);
|
|
617
804
|
// Output: "U0dWc2JHOGdWMjl5YkdRPQ%3D%3D"
|
|
618
805
|
|
|
619
806
|
// Decode
|
|
620
|
-
const decoded =
|
|
807
|
+
const decoded = SafeDecode(safe);
|
|
621
808
|
console.log(decoded);
|
|
622
809
|
// Output: "Hello World! @#$% 😊"
|
|
623
810
|
|
|
624
811
|
// Multiple encode/decode calls (idempotent)
|
|
625
|
-
console.log(
|
|
812
|
+
console.log(SafeEncode(SafeDecode(safe)) === safe); // true
|
|
813
|
+
|
|
814
|
+
```
|
|
626
815
|
|
|
816
|
+
## Language and country reference
|
|
627
817
|
|
|
818
|
+
### Language and country lookup (LangCountryCode)
|
|
628
819
|
|
|
629
|
-
|
|
820
|
+
Look up country and language metadata locally without an API request.
|
|
630
821
|
|
|
631
|
-
|
|
822
|
+
```typescript
|
|
823
|
+
import { LangCountryCode } from 'dff-util';
|
|
824
|
+
|
|
825
|
+
const country = LangCountryCode('en-US');
|
|
826
|
+
console.log(country);
|
|
632
827
|
```
|
|
633
|
-
// bun run src/tests/util.ts
|
|
634
828
|
|
|
635
|
-
|
|
829
|
+
### Country data (CountryType)
|
|
636
830
|
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
831
|
+
```typescript
|
|
832
|
+
export type CountryType = {
|
|
833
|
+
code: string; // ISO 3166-1 alpha-2
|
|
834
|
+
name: string; // English country name
|
|
835
|
+
locale: string; // Native/local language name
|
|
836
|
+
googleNames: string[]; // Common names
|
|
837
|
+
currencyCode: string; // ISO 4217 currency code
|
|
838
|
+
currency: string; // Currency symbol
|
|
839
|
+
telCode: number; // Numeric only (no +)
|
|
840
|
+
flag: string; // Emoji flag
|
|
641
841
|
};
|
|
842
|
+
```
|
|
642
843
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
}
|
|
844
|
+
#### Country list
|
|
845
|
+
```typescript
|
|
846
|
+
import { Countries } from 'dff-util';
|
|
647
847
|
|
|
648
|
-
const
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
848
|
+
const countriesList = Countries;
|
|
849
|
+
|
|
850
|
+
// Countries is a CountryType[] containing country metadata.
|
|
851
|
+
```
|
|
652
852
|
|
|
653
|
-
|
|
853
|
+
### Language metadata (LanguageType)
|
|
654
854
|
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
855
|
+
```typescript
|
|
856
|
+
export type LanguageType = {
|
|
857
|
+
lang: string; // Locale code (e.g., en-US, hi-IN)
|
|
858
|
+
code: string; // ISO 639-1 language code (e.g., en, hi)
|
|
859
|
+
country: string; // ISO 3166-1 alpha-2 country code (e.g., US, IN)
|
|
860
|
+
name: string; // English name of the language
|
|
861
|
+
dir: "ltr" | "rtl"; // Text direction
|
|
862
|
+
locale: string; // Native name of the language
|
|
659
863
|
};
|
|
864
|
+
```
|
|
660
865
|
|
|
661
|
-
|
|
866
|
+
### Language and country metadata (LangCountryType)
|
|
662
867
|
|
|
868
|
+
```typescript
|
|
869
|
+
export type LangCountryType = {
|
|
870
|
+
lang: string; // Locale code (e.g., en-US, hi-IN)
|
|
871
|
+
country: string; // ISO 3166-1 alpha-2 country code (e.g., US, IN)
|
|
872
|
+
name: string; // English name of the language
|
|
873
|
+
locale: string; // Native name of the language
|
|
874
|
+
currencyCode: string; // ISO 4217 currency code
|
|
875
|
+
currency: string; // Currency symbol
|
|
876
|
+
telCode: number; // Numeric only (no +)
|
|
877
|
+
flag: string; // Emoji flag
|
|
878
|
+
dir: "ltr" | "rtl"; // Text direction
|
|
879
|
+
};
|
|
663
880
|
```
|
|
664
881
|
|
|
665
|
-
###
|
|
666
|
-
|
|
882
|
+
### Supported language codes (AllLanguageCodesType)
|
|
883
|
+
|
|
884
|
+
```typescript
|
|
667
885
|
export type AllLanguageCodesType =
|
|
668
886
|
| "ps-AF"
|
|
669
887
|
| "sq-AL"
|
|
@@ -875,263 +1093,368 @@ export type AllLanguageCodesType =
|
|
|
875
1093
|
| "en-ZW";
|
|
876
1094
|
```
|
|
877
1095
|
|
|
878
|
-
|
|
1096
|
+
## Shared types
|
|
1097
|
+
|
|
1098
|
+
### Common types
|
|
1099
|
+
|
|
1100
|
+
```typescript
|
|
1101
|
+
export type LangDirType = "ltr" | "rtl";
|
|
1102
|
+
export type OrderType = "ASC" | "DESC";
|
|
1103
|
+
export type ThemeType = "light" | "dark";
|
|
1104
|
+
export type UnixTimestampType = number & { __brand: "UnixTimestamp" };
|
|
1105
|
+
|
|
1106
|
+
export type OptionType = {
|
|
1107
|
+
label: string;
|
|
1108
|
+
key: string | number;
|
|
1109
|
+
disabled?: boolean;
|
|
1110
|
+
icon?: string;
|
|
1111
|
+
lang?: Record<string, string>;
|
|
1112
|
+
};
|
|
879
1113
|
|
|
880
|
-
|
|
1114
|
+
export type FileType = {
|
|
1115
|
+
filename: string;
|
|
1116
|
+
mimetype: string;
|
|
1117
|
+
url: string;
|
|
1118
|
+
};
|
|
881
1119
|
```
|
|
882
|
-
toCamelCase("user_name") // "userName"
|
|
883
|
-
toCamelCase("user-name") // "userName"
|
|
884
|
-
toCamelCase("User Name") // "userName"
|
|
885
|
-
toCamelCase("USER_NAME") // "userName"
|
|
886
|
-
|
|
887
|
-
toSnakeCase("userName") // "user_name"
|
|
888
|
-
toSnakeCase("UserName") // "user_name"
|
|
889
|
-
toSnakeCase("user name") // "user_name"
|
|
890
|
-
toSnakeCase("user-name") // "user_name"
|
|
891
|
-
|
|
892
|
-
toLowerCase("userName") // "user_name"
|
|
893
|
-
toLowerCase("UserName") // "user_name"
|
|
894
|
-
toLowerCase("user-name") // "user_name"
|
|
895
|
-
|
|
896
|
-
toUpperCase("userName") // "USER_NAME"
|
|
897
|
-
toUpperCase("user name") // "USER_NAME"
|
|
898
|
-
toUpperCase("user-name") // "USER_NAME"
|
|
899
|
-
toUpperCase("UserName") // "USER_NAME"
|
|
900
|
-
|
|
901
|
-
toPascalCase("user_name") // "UserName"
|
|
902
|
-
toPascalCase("user name") // "UserName"
|
|
903
|
-
toPascalCase("user-name") // "UserName"
|
|
904
|
-
toPascalCase("USER_NAME") // "UserName"
|
|
905
|
-
|
|
906
|
-
input:
|
|
907
|
-
const mongoDoc = {
|
|
908
|
-
_id: 'abc123',
|
|
909
|
-
user_name: 'prasad',
|
|
910
|
-
address_info: {
|
|
911
|
-
city_name: 'hyderabad'
|
|
912
|
-
}
|
|
913
|
-
};
|
|
914
|
-
|
|
915
|
-
toViewMapper(mongoDoc) -->
|
|
916
|
-
{
|
|
917
|
-
id: 'abc123',
|
|
918
|
-
userName: 'prasad',
|
|
919
|
-
addressInfo: {
|
|
920
|
-
cityName: 'hyderabad'
|
|
921
|
-
}
|
|
922
|
-
}
|
|
923
1120
|
|
|
1121
|
+
### Request and response types
|
|
924
1122
|
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
1123
|
+
```typescript
|
|
1124
|
+
export type ResponseType = {
|
|
1125
|
+
status?: string | number;
|
|
1126
|
+
data?: any;
|
|
1127
|
+
error?: any;
|
|
1128
|
+
total?: number;
|
|
1129
|
+
skip?: number;
|
|
1130
|
+
limit?: number;
|
|
1131
|
+
meta?: {
|
|
1132
|
+
requestId?: string | number;
|
|
1133
|
+
timestamp?: string | number;
|
|
1134
|
+
duration?: number;
|
|
1135
|
+
};
|
|
931
1136
|
}
|
|
932
1137
|
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
1138
|
+
export type SearchType = {
|
|
1139
|
+
limit?: number;
|
|
1140
|
+
skip?: number;
|
|
1141
|
+
orderBy?: string;
|
|
1142
|
+
order?: 'ASC' | 'DESC';
|
|
1143
|
+
searchTerm?: string;
|
|
1144
|
+
active?: boolean;
|
|
1145
|
+
filters?: string;
|
|
1146
|
+
};
|
|
941
1147
|
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
_id: 'abc123',
|
|
945
|
-
user_name: 'prasad',
|
|
946
|
-
address_info: {
|
|
947
|
-
city_name: 'hyderabad'
|
|
948
|
-
}
|
|
1148
|
+
export type KeyValueType = {
|
|
1149
|
+
[key: string]: any;
|
|
949
1150
|
}
|
|
950
1151
|
|
|
1152
|
+
export type JsonValueType = string | number | boolean | null | JsonValueType[] | { [key: string]: JsonValueType };
|
|
1153
|
+
export type RequestBodyType = Record<string, JsonValueType>;
|
|
1154
|
+
export type RequestQueryType = Record<string, string | number | boolean | null>;
|
|
1155
|
+
export type RequestByIdType = {
|
|
1156
|
+
id: string | number;
|
|
1157
|
+
};
|
|
1158
|
+
|
|
951
1159
|
```
|
|
952
1160
|
|
|
1161
|
+
### Session user (SessionUser)
|
|
1162
|
+
|
|
1163
|
+
```typescript
|
|
1164
|
+
export type SessionUser = {
|
|
1165
|
+
id: string;
|
|
1166
|
+
email?: string;
|
|
1167
|
+
mobile?: string;
|
|
1168
|
+
name?: string;
|
|
1169
|
+
roles: string[];
|
|
1170
|
+
type?: string;
|
|
1171
|
+
};
|
|
953
1172
|
```
|
|
954
|
-
const got = QueryCond(input);
|
|
955
1173
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1174
|
+
### Session information (SessionInfo)
|
|
1175
|
+
|
|
1176
|
+
```typescript
|
|
1177
|
+
export type SessionInfo = {
|
|
1178
|
+
id: string;
|
|
1179
|
+
email?: string;
|
|
1180
|
+
mobile?: string;
|
|
1181
|
+
name?: string;
|
|
1182
|
+
roles: string[];
|
|
1183
|
+
type?: string;
|
|
1184
|
+
requestId?: string;
|
|
1185
|
+
token?: string;
|
|
1186
|
+
iat?: number;
|
|
1187
|
+
exp?: number;
|
|
1188
|
+
key: string;
|
|
1189
|
+
};
|
|
1190
|
+
```
|
|
1191
|
+
|
|
1192
|
+
## Constants and validation
|
|
1193
|
+
|
|
1194
|
+
### Constants (ConstValue)
|
|
1195
|
+
|
|
1196
|
+
```typescript
|
|
1197
|
+
ConstValue = {
|
|
1198
|
+
// Logical operators
|
|
1199
|
+
AND: '&&',
|
|
1200
|
+
OR: '||',
|
|
1201
|
+
NOT: '!',
|
|
1202
|
+
|
|
1203
|
+
// Common special characters
|
|
1204
|
+
AT: '@',
|
|
1205
|
+
HASH: '#',
|
|
1206
|
+
DOLLAR: '$',
|
|
1207
|
+
PERCENT: '%',
|
|
1208
|
+
CARET: '^',
|
|
1209
|
+
AMPERSAND: '&',
|
|
1210
|
+
ASTERISK: '*',
|
|
1211
|
+
TILDE: '~',
|
|
1212
|
+
COLON: ':',
|
|
1213
|
+
SEMICOLON: ';',
|
|
1214
|
+
DOUBLE_QUOTE: '"',
|
|
1215
|
+
SINGLE_QUOTE: "'",
|
|
1216
|
+
COMMA: ',',
|
|
1217
|
+
PERIOD: '.',
|
|
1218
|
+
SLASH: '/',
|
|
1219
|
+
QUESTION_MARK: '?',
|
|
1220
|
+
PLUS: '+',
|
|
1221
|
+
UNDERSCORE: '_',
|
|
1222
|
+
HYPHEN: '-',
|
|
1223
|
+
EQUALS: '=',
|
|
1224
|
+
BACKSLASH: '\\',
|
|
1225
|
+
PIPE: '|',
|
|
1226
|
+
|
|
1227
|
+
// Space
|
|
1228
|
+
SPACE: ' ',
|
|
1229
|
+
EMPTY: '',
|
|
1230
|
+
|
|
1231
|
+
// Other
|
|
1232
|
+
TRUE: 'true',
|
|
1233
|
+
FALSE: 'false',
|
|
1234
|
+
NULL: 'null',
|
|
1235
|
+
UNDEFINED: 'undefined',
|
|
1236
|
+
|
|
1237
|
+
STR_AND: 'AND',
|
|
1238
|
+
STR_OR: 'OR',
|
|
1239
|
+
STR_NOT: 'NOT',
|
|
1240
|
+
|
|
1241
|
+
ASC: 'ASC',
|
|
1242
|
+
DESC: 'DESC',
|
|
1243
|
+
|
|
1244
|
+
LTR: 'ltr',
|
|
1245
|
+
RTL: 'rtl',
|
|
1246
|
+
|
|
1247
|
+
AM: 'AM',
|
|
1248
|
+
PM: 'PM',
|
|
1249
|
+
|
|
1250
|
+
LIGHT: 'light',
|
|
1251
|
+
DARK: 'dark',
|
|
1252
|
+
|
|
1253
|
+
MonthNames: [
|
|
1254
|
+
"Jan",
|
|
1255
|
+
"Feb",
|
|
1256
|
+
"Mar",
|
|
1257
|
+
"Apr",
|
|
1258
|
+
"May",
|
|
1259
|
+
"Jun",
|
|
1260
|
+
"Jul",
|
|
1261
|
+
"Aug",
|
|
1262
|
+
"Sep",
|
|
1263
|
+
"Oct",
|
|
1264
|
+
"Nov",
|
|
1265
|
+
"Dec",
|
|
1266
|
+
],
|
|
1267
|
+
|
|
1268
|
+
};
|
|
1269
|
+
```
|
|
1270
|
+
|
|
1271
|
+
### Application messages (ConstMessages)
|
|
1272
|
+
|
|
1273
|
+
```typescript
|
|
1274
|
+
export const ConstMessages = {
|
|
1275
|
+
// Validation messages
|
|
1276
|
+
REQUIRED: 'Required',
|
|
1277
|
+
MIN_LENGTH_REQUIRED: 'Minimum length required',
|
|
1278
|
+
MAX_LENGTH_EXCEED: 'Maximum length exceeded',
|
|
1279
|
+
INVALID_DATA: 'Invalid data',
|
|
1280
|
+
FIELD_MUST_BE_NUMERIC: 'This field must be numeric',
|
|
1281
|
+
FIELD_MUST_BE_ALPHABETIC: 'This field must contain only letters',
|
|
1282
|
+
FIELD_MUST_BE_ALPHANUMERIC: 'This field must contain only letters and numbers',
|
|
1283
|
+
INVALID_EMAIL: 'Invalid email format',
|
|
1284
|
+
INVALID_PHONE: 'Invalid phone number',
|
|
1285
|
+
PASSWORD_TOO_WEAK: 'Password is too weak',
|
|
1286
|
+
PASSWORDS_DO_NOT_MATCH: 'Passwords do not match',
|
|
1287
|
+
INVALID_DATE_FORMAT: 'Invalid date format',
|
|
1288
|
+
DATE_OUT_OF_RANGE: 'Date is out of acceptable range',
|
|
1289
|
+
VALUE_TOO_LOW: 'Value is too low',
|
|
1290
|
+
VALUE_TOO_HIGH: 'Value is too high',
|
|
1291
|
+
EXCEEDS_MAX_CHARACTERS: 'Exceeds maximum character limit',
|
|
1292
|
+
INVALID_URL: 'Invalid URL format',
|
|
1293
|
+
INVALID_ZIP_CODE: 'Invalid zip/postal code',
|
|
1294
|
+
ONLY_POSITIVE_NUMBERS: 'Only positive numbers are allowed',
|
|
1295
|
+
INVALID_CREDIT_CARD: 'Invalid credit card number',
|
|
1296
|
+
INVALID_FILE_TYPE: 'Unsupported file type',
|
|
1297
|
+
FILE_TOO_LARGE: 'File size exceeds the maximum limit',
|
|
1298
|
+
|
|
1299
|
+
// Success messages
|
|
1300
|
+
SUCCESS: 'Operation completed successfully',
|
|
1301
|
+
SAVED_SUCCESSFULLY: 'Data saved successfully',
|
|
1302
|
+
UPDATED_SUCCESSFULLY: 'Data updated successfully',
|
|
1303
|
+
DELETED_SUCCESSFULLY: 'Data deleted successfully',
|
|
1304
|
+
SUBMITTED_SUCCESSFULLY: 'Form submitted successfully',
|
|
1305
|
+
EMAIL_SENT: 'Email sent successfully',
|
|
1306
|
+
PASSWORD_CHANGED: 'Password changed successfully',
|
|
1307
|
+
LOGGED_IN: 'Logged in successfully',
|
|
1308
|
+
LOGGED_OUT: 'Logged out successfully',
|
|
1309
|
+
UPLOAD_SUCCESSFUL: 'File uploaded successfully',
|
|
1310
|
+
PAYMENT_SUCCESSFUL: 'Payment processed successfully',
|
|
1311
|
+
DATA_FETCHED: 'Data fetched successfully',
|
|
1312
|
+
DATA_LOADED: 'Data loaded successfully',
|
|
1313
|
+
ACTION_COMPLETED: 'Action completed successfully',
|
|
1314
|
+
|
|
1315
|
+
// Error messages
|
|
1316
|
+
WENT_WRONG: 'Something went wrong, please try again',
|
|
1317
|
+
NOT_FOUND: 'Requested resource not found',
|
|
1318
|
+
UNAUTHORIZED: 'You are not authorized to perform this action',
|
|
1319
|
+
FORBIDDEN: 'Access to this resource is forbidden',
|
|
1320
|
+
SERVER_ERROR: 'Internal server error, please contact support',
|
|
1321
|
+
CONNECTION_ERROR: 'Unable to connect, please check your internet connection',
|
|
1322
|
+
TIMEOUT_ERROR: 'The request timed out, please try again later',
|
|
1323
|
+
VALIDATION_FAILED: 'Validation failed, please check the input',
|
|
1324
|
+
DUPLICATE_ENTRY: 'Duplicate entry, please provide unique data',
|
|
1325
|
+
SESSION_EXPIRED: 'Your session has expired, please log in again',
|
|
1326
|
+
INVALID_SESSION: 'Invalid session, please authenticate',
|
|
1327
|
+
RATE_LIMIT_EXCEEDED: 'Too many requests, please try again later',
|
|
1328
|
+
RESOURCE_LOCKED: 'This resource is currently locked',
|
|
1329
|
+
DATA_CORRUPTED: 'Data is corrupted',
|
|
1330
|
+
SERVICE_UNAVAILABLE: 'Service is currently unavailable',
|
|
1331
|
+
PAYMENT_FAILED: 'Payment failed, please check your details',
|
|
1332
|
+
OPERATION_FAILED: 'Operation failed, please try again',
|
|
1333
|
+
ACCESS_DENIED: 'Access denied',
|
|
1334
|
+
INVALID_CREDENTIALS: 'Invalid credentials, please try again',
|
|
1335
|
+
INVALID_TOKEN: 'Invalid token, please try again',
|
|
1336
|
+
USER_NOT_FOUND: 'User not found, please try again',
|
|
1337
|
+
PASSWORD_RESET_FAILED: 'Password reset failed, please try again',
|
|
1338
|
+
|
|
1339
|
+
// Informational Messages
|
|
1340
|
+
NO_DATA_FOUND: 'No data found',
|
|
1341
|
+
NO_RECORD_FOUND: 'No record found',
|
|
1342
|
+
NO_RECORDS_FOUND: 'No records found',
|
|
1343
|
+
NO_RECORDS_MATCHED: 'No records matched your search criteria',
|
|
1344
|
+
NO_RECORDS_MATCHED_FILTER: 'No records matched your filter criteria',
|
|
1345
|
+
LOADING: 'Loading, please wait...',
|
|
1346
|
+
FETCHING_DATA: 'Fetching data, please wait...',
|
|
1347
|
+
PROCESSING: 'Processing your request...',
|
|
1348
|
+
PLEASE_WAIT: 'Please wait...',
|
|
1349
|
+
NO_RESULTS_FOUND: 'No results found',
|
|
1350
|
+
NO_DATA_AVAILABLE: 'No data available',
|
|
1351
|
+
SEARCHING: 'Searching...',
|
|
1352
|
+
REDIRECTING: 'Redirecting, please wait...',
|
|
1353
|
+
CONNECTING: 'Connecting, please wait...',
|
|
1354
|
+
LOGGING_OUT: 'Logging out, please wait...',
|
|
1355
|
+
LOGGING_IN: 'Logging in, please wait...',
|
|
1356
|
+
PREPARING_DOWNLOAD: 'Preparing your download...',
|
|
1357
|
+
CHECKING_UPDATES: 'Checking for updates...',
|
|
1358
|
+
|
|
1359
|
+
// Confirmation Messages
|
|
1360
|
+
CONFIRM_DELETE: 'Are you sure you want to delete this?',
|
|
1361
|
+
CONFIRM_SAVE: 'Do you want to save changes?',
|
|
1362
|
+
CONFIRM_SUBMIT: 'Do you want to submit this form?',
|
|
1363
|
+
CONFIRM_LOGOUT: 'Are you sure you want to log out?',
|
|
1364
|
+
CONFIRM_ACTION: 'Are you sure you want to proceed?',
|
|
1365
|
+
CONFIRM_CLOSE: 'Are you sure you want to close this window?',
|
|
1366
|
+
CONFIRM_CANCEL: 'Do you want to cancel this action?',
|
|
1367
|
+
CONFIRM_RESTART: 'Do you want to restart the process?',
|
|
1368
|
+
|
|
1369
|
+
// Warning Messages
|
|
1370
|
+
UNSAVED_CHANGES: 'You have unsaved changes. Do you want to discard them?',
|
|
1371
|
+
LOW_BATTERY: 'Battery level is low, please connect your charger',
|
|
1372
|
+
HIGH_USAGE: 'High system usage detected',
|
|
1373
|
+
INCOMPLETE_FORM: 'The form is incomplete',
|
|
1374
|
+
LIMIT_REACHED: 'You have reached the maximum limit',
|
|
1375
|
+
OUTDATED_VERSION: 'You are using an outdated version of the application',
|
|
1376
|
+
|
|
1377
|
+
// General Messages
|
|
1378
|
+
WELCOME: 'Welcome to the application',
|
|
1379
|
+
GOODBYE: 'Goodbye, have a great day!',
|
|
1380
|
+
HELLO: 'Hello, how can we help you today?',
|
|
1381
|
+
THANK_YOU: 'Thank you for using our service',
|
|
1382
|
+
TRY_AGAIN: 'Please try again',
|
|
1383
|
+
UNDER_MAINTENANCE: 'The system is under maintenance, please check back later',
|
|
1384
|
+
FEATURE_COMING_SOON: 'This feature is coming soon',
|
|
1385
|
+
CONTACT_SUPPORT: 'If the issue persists, please contact support',
|
|
1386
|
+
UPDATING: 'Updating, please wait...',
|
|
1387
|
+
INSTALLING: 'Installing, please wait...',
|
|
1388
|
+
RESTART_REQUIRED: 'A restart is required to apply changes',
|
|
1389
|
+
RESTARTING: 'Restarting, please wait...',
|
|
1390
|
+
LOADING_DATA: 'Loading data, please wait...',
|
|
1391
|
+
SAVING: 'Saving, please wait...',
|
|
1392
|
+
};
|
|
1393
|
+
|
|
1394
|
+
```
|
|
1395
|
+
|
|
1396
|
+
### Regular expressions (RegExp)
|
|
1397
|
+
|
|
1398
|
+
```typescript
|
|
1399
|
+
RegExp = {
|
|
1400
|
+
// Matches any non-alphanumeric characters
|
|
1401
|
+
NON_ALPHA_NUMERIC: /[^\w\s]/g,
|
|
1402
|
+
|
|
1403
|
+
// Matches only numeric digits (0-9)
|
|
1404
|
+
DIGITS_ONLY: /^\d+$/,
|
|
1405
|
+
|
|
1406
|
+
// Matches only alphabets (case-insensitive)
|
|
1407
|
+
ALPHABETS_ONLY: /^[a-zA-Z]+$/,
|
|
1408
|
+
|
|
1409
|
+
// Matches alphanumeric characters (letters and digits)
|
|
1410
|
+
ALPHA_NUMERIC: /^[a-zA-Z0-9]+$/,
|
|
1411
|
+
|
|
1412
|
+
// Matches an email address
|
|
1413
|
+
EMAIL: /^[\w.%+-]+@[a-zA-Z\d.-]+\.[a-zA-Z]{2,}$/,
|
|
1414
|
+
|
|
1415
|
+
// Matches a URL
|
|
1416
|
+
URL: /^(https?:\/\/)?([\w.-]+)\.([a-z]{2,6}\.?)(\/[\w.-]*)*\/?$/i,
|
|
1417
|
+
|
|
1418
|
+
// Matches a US phone number (formats like (123) 456-7890, 123-456-7890, etc.)
|
|
1419
|
+
PHONE_US: /^(\(\d{3}\)\s?|\d{3}[-.\s]?)?\d{3}[-.\s]?\d{4}$/,
|
|
1420
|
+
|
|
1421
|
+
// Matches a password with at least one lowercase, one uppercase, one digit, and one special character
|
|
1422
|
+
STRONG_PASSWORD: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,}$/,
|
|
1423
|
+
|
|
1424
|
+
// Matches whitespace characters
|
|
1425
|
+
WHITESPACE: /\s+/g,
|
|
1426
|
+
|
|
1427
|
+
// Matches any HTML tags
|
|
1428
|
+
HTML_TAG: /<\/?[\w\s="/.':;#-\/\?]+>/gi,
|
|
1429
|
+
|
|
1430
|
+
// Matches IPv4 addresses
|
|
1431
|
+
IPV4: /^(25[0-5]|2[0-4]\d|1?\d?\d)(\.(25[0-5]|2[0-4]\d|1?\d?\d)){3}$/,
|
|
1432
|
+
|
|
1433
|
+
// Matches dates in YYYY-MM-DD format
|
|
1434
|
+
DATE_YYYY_MM_DD: /^\d{4}-\d{2}-\d{2}$/,
|
|
1435
|
+
|
|
1436
|
+
// Matches time in HH:MM 24-hour format
|
|
1437
|
+
TIME_HH_MM: /^([01]\d|2[0-3]):([0-5]\d)$/,
|
|
1438
|
+
|
|
1439
|
+
// Matches ISO 8601 datetime format (e.g., 2023-08-15T13:45:30Z, 2023-08-15T13:45:30+05:30)
|
|
1440
|
+
ISO_DATETIME: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:\d{2})$/,
|
|
1441
|
+
|
|
1442
|
+
// Matches a hexadecimal color code
|
|
1443
|
+
HEX_COLOR: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,
|
|
1444
|
+
|
|
1445
|
+
// Matches a UUID (version 4)
|
|
1446
|
+
UUID_V4: /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i,
|
|
1447
|
+
|
|
1448
|
+
// Matches non-ASCII characters
|
|
1449
|
+
NON_ASCII: /[^\x00-\x7F]/g,
|
|
1450
|
+
|
|
1451
|
+
// Matches line breaks (newlines)
|
|
1452
|
+
LINE_BREAK: /\r?\n/g,
|
|
1453
|
+
|
|
1454
|
+
// Matches amounts in decimal format (e.g., 123.45, 0.99, 1000)
|
|
1455
|
+
AMOUNT_DECIMAL: /^\d+(\.\d{1,2})?$/,
|
|
1456
|
+
|
|
1457
|
+
// Matches percentages from 0-100 or in decimal format (e.g., 25%, 99.99%, 100, 0.5)
|
|
1458
|
+
PERCENTAGE: /^(100(\.0{1,2})?|0|0?\.\d{1,2}|[1-9]?\d(\.\d{1,2})?)%?$/,
|
|
1459
|
+
};
|
|
1460
|
+
```
|