@etsoo/shared 1.1.80 → 1.1.82

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 CHANGED
@@ -15,6 +15,20 @@ Using yarn:
15
15
  $ yarn add @etsoo/shared
16
16
  ```
17
17
 
18
+ ## ActionResult / IActionResult, IdActionResult, DynamicActionResult
19
+ |Name|Description|
20
+ |---:|---|
21
+ |static create|Create a result from error|
22
+ |data|Result data|
23
+ |detail|Details|
24
+ |errors|Result errors|
25
+ |field|Related field|
26
+ |ok|Success or failure|
27
+ |status|Status code|
28
+ |title|Title|
29
+ |traceId|Trace id|
30
+ |type|Type|
31
+
18
32
  ## storage
19
33
  Storage interface and browser storage implementation
20
34
 
@@ -161,6 +175,7 @@ DOM/window related utilities
161
175
  |Name|Description|
162
176
  |---:|---|
163
177
  |clearFormData|Clear form data|
178
+ |CultureMatch|Culture match case Enum|
164
179
  |dataAs|Cast data as template format|
165
180
  |detectedCountry|Current detected country|
166
181
  |detectedCulture|Current detected culture|
@@ -229,11 +229,25 @@ test('Tests for getCulture', () => {
229
229
  { name: 'en', label: 'English', resources: {} }
230
230
  ];
231
231
 
232
- expect(DomUtils.getCulture(cultures, 'zh-CN')?.name).toBe('zh-Hans');
233
- expect(DomUtils.getCulture(cultures, 'zh-Hans-CN')?.name).toBe('zh-Hans');
234
- expect(DomUtils.getCulture(cultures, 'zh-Hans-HK')?.name).toBe('zh-Hans');
235
- expect(DomUtils.getCulture(cultures, 'zh-SG')?.name).toBe('zh-Hans');
236
- expect(DomUtils.getCulture(cultures, 'en-GB')?.name).toBe('en');
232
+ const [culture1, match1] = DomUtils.getCulture(cultures, 'zh-CN');
233
+ expect(culture1?.name).toBe('zh-Hans');
234
+ expect(match1).toBe(DomUtils.CultureMatch.Compatible);
235
+
236
+ const [culture2] = DomUtils.getCulture(cultures, 'zh-Hans-CN');
237
+ expect(culture2?.name).toBe('zh-Hans');
238
+
239
+ const [culture3] = DomUtils.getCulture(cultures, 'zh-Hans-HK');
240
+ expect(culture3?.name).toBe('zh-Hans');
241
+
242
+ const [culture4] = DomUtils.getCulture(cultures, 'zh-SG');
243
+ expect(culture4?.name).toBe('zh-Hans');
244
+
245
+ const [culture5] = DomUtils.getCulture(cultures, 'en-GB');
246
+ expect(culture5?.name).toBe('en');
247
+
248
+ const [culture6, match6] = DomUtils.getCulture(cultures, 'fr-CA');
249
+ expect(culture6?.name).toBe('zh-Hans');
250
+ expect(match6).toBe(DomUtils.CultureMatch.Default);
237
251
  });
238
252
 
239
253
  test('Tests for getLocationKey', () => {
@@ -0,0 +1,11 @@
1
+ import { IActionResult } from './IActionResult';
2
+ /**
3
+ * Action result
4
+ */
5
+ export declare class ActionResult {
6
+ /**
7
+ * Create a result from error
8
+ * @returns Action result interface
9
+ */
10
+ static create<D extends object = {}>(error: Error): IActionResult<D>;
11
+ }
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionResult = void 0;
4
+ /**
5
+ * Action result
6
+ */
7
+ class ActionResult {
8
+ /**
9
+ * Create a result from error
10
+ * @returns Action result interface
11
+ */
12
+ static create(error) {
13
+ // If the error has status / statusCode
14
+ const status = 'status' in error
15
+ ? error.status
16
+ : 'statusCode' in error
17
+ ? error.statusCode
18
+ : undefined;
19
+ // Result
20
+ const result = {
21
+ status: typeof status === 'number' ? status : undefined,
22
+ ok: false,
23
+ type: error.name,
24
+ title: error.message
25
+ };
26
+ // Return
27
+ return result;
28
+ }
29
+ }
30
+ exports.ActionResult = ActionResult;
@@ -62,6 +62,15 @@ export declare namespace DomUtils {
62
62
  * @returns Object
63
63
  */
64
64
  function formDataToObject(form: IFormData): Record<string, FormDataFieldValue | FormDataFieldValue[]>;
65
+ /**
66
+ * Culture match case Enum
67
+ */
68
+ enum CultureMatch {
69
+ Exact = 0,
70
+ Compatible = 1,
71
+ SamePart = 2,
72
+ Default = 3
73
+ }
65
74
  /**
66
75
  * Get the available culture definition
67
76
  * @param items Available cultures
@@ -74,14 +83,14 @@ export declare namespace DomUtils {
74
83
  * Current detected culture
75
84
  */
76
85
  compatibleNames?: string[] | undefined;
77
- }>[], culture: string) => Readonly<{
86
+ }>[], culture: string) => [Readonly<{
78
87
  name: string;
79
88
  label: string;
80
89
  resources: T; /**
81
90
  * Current detected culture
82
91
  */
83
92
  compatibleNames?: string[] | undefined;
84
- }> | undefined;
93
+ }> | undefined, CultureMatch];
85
94
  /**
86
95
  * Get input value depending on its type
87
96
  * @param input HTML input
@@ -268,6 +268,16 @@ var DomUtils;
268
268
  return dic;
269
269
  }
270
270
  DomUtils.formDataToObject = formDataToObject;
271
+ /**
272
+ * Culture match case Enum
273
+ */
274
+ let CultureMatch;
275
+ (function (CultureMatch) {
276
+ CultureMatch[CultureMatch["Exact"] = 0] = "Exact";
277
+ CultureMatch[CultureMatch["Compatible"] = 1] = "Compatible";
278
+ CultureMatch[CultureMatch["SamePart"] = 2] = "SamePart";
279
+ CultureMatch[CultureMatch["Default"] = 3] = "Default";
280
+ })(CultureMatch = DomUtils.CultureMatch || (DomUtils.CultureMatch = {}));
271
281
  /**
272
282
  * Get the available culture definition
273
283
  * @param items Available cultures
@@ -275,12 +285,12 @@ var DomUtils;
275
285
  */
276
286
  DomUtils.getCulture = (items, culture) => {
277
287
  if (items.length === 0) {
278
- return undefined;
288
+ return [undefined, CultureMatch.Exact];
279
289
  }
280
290
  // Exact match
281
291
  const exactMatch = items.find((item) => item.name === culture);
282
292
  if (exactMatch)
283
- return exactMatch;
293
+ return [exactMatch, CultureMatch.Exact];
284
294
  // Compatible match
285
295
  const compatibleMatch = items.find((item) => {
286
296
  var _a;
@@ -288,14 +298,14 @@ var DomUtils;
288
298
  culture.startsWith(item + '-');
289
299
  });
290
300
  if (compatibleMatch)
291
- return compatibleMatch;
301
+ return [compatibleMatch, CultureMatch.Compatible];
292
302
  // Same part, like zh-CN and zh-HK
293
303
  const samePart = culture.split('-')[0];
294
304
  const samePartMatch = items.find((item) => item.name.startsWith(samePart));
295
305
  if (samePartMatch)
296
- return samePartMatch;
306
+ return [samePartMatch, CultureMatch.SamePart];
297
307
  // Default
298
- return items[0];
308
+ return [items[0], CultureMatch.Default];
299
309
  };
300
310
  /**
301
311
  * Get input value depending on its type
@@ -0,0 +1,59 @@
1
+ import { DataTypes } from './DataTypes';
2
+ /**
3
+ * Result errors
4
+ * Indexable type
5
+ */
6
+ export interface IResultErrors {
7
+ readonly [key: string]: string[];
8
+ }
9
+ /**
10
+ * Operation result interface
11
+ */
12
+ export interface IActionResult<D extends object = {}> {
13
+ /**
14
+ * Status code
15
+ */
16
+ readonly status?: number;
17
+ /**
18
+ * Result data
19
+ */
20
+ readonly data?: D;
21
+ /**
22
+ * Result errors
23
+ */
24
+ readonly errors?: IResultErrors;
25
+ /**
26
+ * Title
27
+ */
28
+ title?: string;
29
+ /**
30
+ * Detail
31
+ */
32
+ detail?: string;
33
+ /**
34
+ * Trace id
35
+ */
36
+ traceId?: string;
37
+ /**
38
+ * Type
39
+ */
40
+ type?: string;
41
+ /**
42
+ * Field name
43
+ */
44
+ field?: string;
45
+ /**
46
+ * Success or not
47
+ */
48
+ readonly ok: boolean;
49
+ }
50
+ /**
51
+ * Action result with id data
52
+ */
53
+ export type IdActionResult<T extends DataTypes.IdType = number> = IActionResult<{
54
+ id: T;
55
+ }>;
56
+ /**
57
+ * Action result with dynamic data
58
+ */
59
+ export type DynamicActionResult = IActionResult<Record<string, any>>;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,11 @@
1
+ import { IActionResult } from './IActionResult';
2
+ /**
3
+ * Action result
4
+ */
5
+ export declare class ActionResult {
6
+ /**
7
+ * Create a result from error
8
+ * @returns Action result interface
9
+ */
10
+ static create<D extends object = {}>(error: Error): IActionResult<D>;
11
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Action result
3
+ */
4
+ export class ActionResult {
5
+ /**
6
+ * Create a result from error
7
+ * @returns Action result interface
8
+ */
9
+ static create(error) {
10
+ // If the error has status / statusCode
11
+ const status = 'status' in error
12
+ ? error.status
13
+ : 'statusCode' in error
14
+ ? error.statusCode
15
+ : undefined;
16
+ // Result
17
+ const result = {
18
+ status: typeof status === 'number' ? status : undefined,
19
+ ok: false,
20
+ type: error.name,
21
+ title: error.message
22
+ };
23
+ // Return
24
+ return result;
25
+ }
26
+ }
@@ -62,6 +62,15 @@ export declare namespace DomUtils {
62
62
  * @returns Object
63
63
  */
64
64
  function formDataToObject(form: IFormData): Record<string, FormDataFieldValue | FormDataFieldValue[]>;
65
+ /**
66
+ * Culture match case Enum
67
+ */
68
+ enum CultureMatch {
69
+ Exact = 0,
70
+ Compatible = 1,
71
+ SamePart = 2,
72
+ Default = 3
73
+ }
65
74
  /**
66
75
  * Get the available culture definition
67
76
  * @param items Available cultures
@@ -74,14 +83,14 @@ export declare namespace DomUtils {
74
83
  * Current detected culture
75
84
  */
76
85
  compatibleNames?: string[] | undefined;
77
- }>[], culture: string) => Readonly<{
86
+ }>[], culture: string) => [Readonly<{
78
87
  name: string;
79
88
  label: string;
80
89
  resources: T; /**
81
90
  * Current detected culture
82
91
  */
83
92
  compatibleNames?: string[] | undefined;
84
- }> | undefined;
93
+ }> | undefined, CultureMatch];
85
94
  /**
86
95
  * Get input value depending on its type
87
96
  * @param input HTML input
@@ -265,6 +265,16 @@ export var DomUtils;
265
265
  return dic;
266
266
  }
267
267
  DomUtils.formDataToObject = formDataToObject;
268
+ /**
269
+ * Culture match case Enum
270
+ */
271
+ let CultureMatch;
272
+ (function (CultureMatch) {
273
+ CultureMatch[CultureMatch["Exact"] = 0] = "Exact";
274
+ CultureMatch[CultureMatch["Compatible"] = 1] = "Compatible";
275
+ CultureMatch[CultureMatch["SamePart"] = 2] = "SamePart";
276
+ CultureMatch[CultureMatch["Default"] = 3] = "Default";
277
+ })(CultureMatch = DomUtils.CultureMatch || (DomUtils.CultureMatch = {}));
268
278
  /**
269
279
  * Get the available culture definition
270
280
  * @param items Available cultures
@@ -272,12 +282,12 @@ export var DomUtils;
272
282
  */
273
283
  DomUtils.getCulture = (items, culture) => {
274
284
  if (items.length === 0) {
275
- return undefined;
285
+ return [undefined, CultureMatch.Exact];
276
286
  }
277
287
  // Exact match
278
288
  const exactMatch = items.find((item) => item.name === culture);
279
289
  if (exactMatch)
280
- return exactMatch;
290
+ return [exactMatch, CultureMatch.Exact];
281
291
  // Compatible match
282
292
  const compatibleMatch = items.find((item) => {
283
293
  var _a;
@@ -285,14 +295,14 @@ export var DomUtils;
285
295
  culture.startsWith(item + '-');
286
296
  });
287
297
  if (compatibleMatch)
288
- return compatibleMatch;
298
+ return [compatibleMatch, CultureMatch.Compatible];
289
299
  // Same part, like zh-CN and zh-HK
290
300
  const samePart = culture.split('-')[0];
291
301
  const samePartMatch = items.find((item) => item.name.startsWith(samePart));
292
302
  if (samePartMatch)
293
- return samePartMatch;
303
+ return [samePartMatch, CultureMatch.SamePart];
294
304
  // Default
295
- return items[0];
305
+ return [items[0], CultureMatch.Default];
296
306
  };
297
307
  /**
298
308
  * Get input value depending on its type
@@ -0,0 +1,59 @@
1
+ import { DataTypes } from './DataTypes';
2
+ /**
3
+ * Result errors
4
+ * Indexable type
5
+ */
6
+ export interface IResultErrors {
7
+ readonly [key: string]: string[];
8
+ }
9
+ /**
10
+ * Operation result interface
11
+ */
12
+ export interface IActionResult<D extends object = {}> {
13
+ /**
14
+ * Status code
15
+ */
16
+ readonly status?: number;
17
+ /**
18
+ * Result data
19
+ */
20
+ readonly data?: D;
21
+ /**
22
+ * Result errors
23
+ */
24
+ readonly errors?: IResultErrors;
25
+ /**
26
+ * Title
27
+ */
28
+ title?: string;
29
+ /**
30
+ * Detail
31
+ */
32
+ detail?: string;
33
+ /**
34
+ * Trace id
35
+ */
36
+ traceId?: string;
37
+ /**
38
+ * Type
39
+ */
40
+ type?: string;
41
+ /**
42
+ * Field name
43
+ */
44
+ field?: string;
45
+ /**
46
+ * Success or not
47
+ */
48
+ readonly ok: boolean;
49
+ }
50
+ /**
51
+ * Action result with id data
52
+ */
53
+ export type IdActionResult<T extends DataTypes.IdType = number> = IActionResult<{
54
+ id: T;
55
+ }>;
56
+ /**
57
+ * Action result with dynamic data
58
+ */
59
+ export type DynamicActionResult = IActionResult<Record<string, any>>;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/shared",
3
- "version": "1.1.80",
3
+ "version": "1.1.82",
4
4
  "description": "TypeScript shared utilities and functions",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -54,17 +54,17 @@
54
54
  },
55
55
  "homepage": "https://github.com/ETSOO/Shared#readme",
56
56
  "devDependencies": {
57
- "@types/jest": "^29.2.3",
57
+ "@types/jest": "^29.2.4",
58
58
  "@types/lodash.isequal": "^4.5.6",
59
- "@typescript-eslint/eslint-plugin": "^5.45.0",
60
- "@typescript-eslint/parser": "^5.45.0",
61
- "eslint": "^8.29.0",
59
+ "@typescript-eslint/eslint-plugin": "^5.46.1",
60
+ "@typescript-eslint/parser": "^5.46.1",
61
+ "eslint": "^8.30.0",
62
62
  "eslint-config-airbnb-base": "^15.0.0",
63
63
  "eslint-plugin-import": "^2.26.0",
64
64
  "jest": "^29.3.1",
65
65
  "jest-environment-jsdom": "^29.3.1",
66
66
  "ts-jest": "^29.0.3",
67
- "typescript": "^4.9.3"
67
+ "typescript": "^4.9.4"
68
68
  },
69
69
  "dependencies": {
70
70
  "lodash.isequal": "^4.5.0"
@@ -0,0 +1,31 @@
1
+ import { IActionResult } from './IActionResult';
2
+
3
+ /**
4
+ * Action result
5
+ */
6
+ export class ActionResult {
7
+ /**
8
+ * Create a result from error
9
+ * @returns Action result interface
10
+ */
11
+ static create<D extends object = {}>(error: Error) {
12
+ // If the error has status / statusCode
13
+ const status =
14
+ 'status' in error
15
+ ? error.status
16
+ : 'statusCode' in error
17
+ ? error.statusCode
18
+ : undefined;
19
+
20
+ // Result
21
+ const result: IActionResult<D> = {
22
+ status: typeof status === 'number' ? status : undefined,
23
+ ok: false,
24
+ type: error.name,
25
+ title: error.message
26
+ };
27
+
28
+ // Return
29
+ return result;
30
+ }
31
+ }
package/src/DomUtils.ts CHANGED
@@ -307,6 +307,16 @@ export namespace DomUtils {
307
307
  return dic;
308
308
  }
309
309
 
310
+ /**
311
+ * Culture match case Enum
312
+ */
313
+ export enum CultureMatch {
314
+ Exact,
315
+ Compatible,
316
+ SamePart,
317
+ Default
318
+ }
319
+
310
320
  /**
311
321
  * Get the available culture definition
312
322
  * @param items Available cultures
@@ -315,14 +325,14 @@ export namespace DomUtils {
315
325
  export const getCulture = <T extends DataTypes.StringRecord>(
316
326
  items: DataTypes.CultureDefinition<T>[],
317
327
  culture: string
318
- ) => {
328
+ ): [DataTypes.CultureDefinition<T> | undefined, CultureMatch] => {
319
329
  if (items.length === 0) {
320
- return undefined;
330
+ return [undefined, CultureMatch.Exact];
321
331
  }
322
332
 
323
333
  // Exact match
324
334
  const exactMatch = items.find((item) => item.name === culture);
325
- if (exactMatch) return exactMatch;
335
+ if (exactMatch) return [exactMatch, CultureMatch.Exact];
326
336
 
327
337
  // Compatible match
328
338
  const compatibleMatch = items.find(
@@ -330,17 +340,17 @@ export namespace DomUtils {
330
340
  item.compatibleNames?.includes(culture) ||
331
341
  culture.startsWith(item + '-')
332
342
  );
333
- if (compatibleMatch) return compatibleMatch;
343
+ if (compatibleMatch) return [compatibleMatch, CultureMatch.Compatible];
334
344
 
335
345
  // Same part, like zh-CN and zh-HK
336
346
  const samePart = culture.split('-')[0];
337
347
  const samePartMatch = items.find((item) =>
338
348
  item.name.startsWith(samePart)
339
349
  );
340
- if (samePartMatch) return samePartMatch;
350
+ if (samePartMatch) return [samePartMatch, CultureMatch.SamePart];
341
351
 
342
352
  // Default
343
- return items[0];
353
+ return [items[0], CultureMatch.Default];
344
354
  };
345
355
 
346
356
  /**
@@ -0,0 +1,72 @@
1
+ import { DataTypes } from './DataTypes';
2
+
3
+ /**
4
+ * Result errors
5
+ * Indexable type
6
+ */
7
+ export interface IResultErrors {
8
+ readonly [key: string]: string[];
9
+ }
10
+
11
+ /**
12
+ * Operation result interface
13
+ */
14
+ export interface IActionResult<D extends object = {}> {
15
+ /**
16
+ * Status code
17
+ */
18
+ readonly status?: number;
19
+
20
+ /**
21
+ * Result data
22
+ */
23
+ readonly data?: D;
24
+
25
+ /**
26
+ * Result errors
27
+ */
28
+ readonly errors?: IResultErrors;
29
+
30
+ /**
31
+ * Title
32
+ */
33
+ title?: string;
34
+
35
+ /**
36
+ * Detail
37
+ */
38
+ detail?: string;
39
+
40
+ /**
41
+ * Trace id
42
+ */
43
+ traceId?: string;
44
+
45
+ /**
46
+ * Type
47
+ */
48
+ type?: string;
49
+
50
+ /**
51
+ * Field name
52
+ */
53
+ field?: string;
54
+
55
+ /**
56
+ * Success or not
57
+ */
58
+ readonly ok: boolean;
59
+ }
60
+
61
+ /**
62
+ * Action result with id data
63
+ */
64
+ export type IdActionResult<T extends DataTypes.IdType = number> =
65
+ IActionResult<{
66
+ id: T;
67
+ }>;
68
+
69
+ /**
70
+ * Action result with dynamic data
71
+ */
72
+ export type DynamicActionResult = IActionResult<Record<string, any>>;