@finema/core 3.21.0 → 3.23.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/dist/module.d.mts +2 -0
  2. package/dist/module.json +2 -2
  3. package/dist/module.mjs +16 -2
  4. package/dist/runtime/components/App.vue +1 -1
  5. package/dist/runtime/components/DevToolsWindow/index.vue +1 -1
  6. package/dist/runtime/components/Dialog/index.d.vue.ts +1 -4
  7. package/dist/runtime/components/Dialog/index.vue +9 -10
  8. package/dist/runtime/components/Dialog/index.vue.d.ts +1 -4
  9. package/dist/runtime/components/Empty.d.vue.ts +0 -1
  10. package/dist/runtime/components/Empty.vue +6 -2
  11. package/dist/runtime/components/Empty.vue.d.ts +0 -1
  12. package/dist/runtime/components/FlexDeck/index.vue +86 -81
  13. package/dist/runtime/components/Form/FieldWrapper.vue +14 -14
  14. package/dist/runtime/components/Form/Fields.vue +10 -10
  15. package/dist/runtime/components/Form/InputCheckbox/index.vue +20 -19
  16. package/dist/runtime/components/Form/InputCheckboxGroup/index.vue +2 -1
  17. package/dist/runtime/components/Form/InputComponent/index.vue +2 -1
  18. package/dist/runtime/components/Form/InputCurrency/index.vue +51 -50
  19. package/dist/runtime/components/Form/InputDateTime/date_time_field.types.d.ts +1 -1
  20. package/dist/runtime/components/Form/InputDateTime/index.vue +69 -64
  21. package/dist/runtime/components/Form/InputDateTimeRange/date_range_time_field.types.d.ts +1 -1
  22. package/dist/runtime/components/Form/InputDateTimeRange/index.vue +62 -57
  23. package/dist/runtime/components/Form/InputMonth/index.vue +10 -5
  24. package/dist/runtime/components/Form/InputMonth/types.d.ts +1 -1
  25. package/dist/runtime/components/Form/InputNumber/index.vue +22 -21
  26. package/dist/runtime/components/Form/InputRadio/index.d.vue.ts +1 -1
  27. package/dist/runtime/components/Form/InputRadio/index.vue +2 -1
  28. package/dist/runtime/components/Form/InputRadio/index.vue.d.ts +1 -1
  29. package/dist/runtime/components/Form/InputRating/index.vue +2 -1
  30. package/dist/runtime/components/Form/InputSearch/index.vue +7 -2
  31. package/dist/runtime/components/Form/InputSelect/index.vue +112 -111
  32. package/dist/runtime/components/Form/InputSelectMultiple/index.vue +120 -119
  33. package/dist/runtime/components/Form/InputTags/index.vue +56 -55
  34. package/dist/runtime/components/Form/InputText/index.vue +88 -87
  35. package/dist/runtime/components/Form/InputTextarea/index.vue +20 -19
  36. package/dist/runtime/components/Form/InputTime/index.vue +45 -40
  37. package/dist/runtime/components/Form/InputTime/types.d.ts +1 -1
  38. package/dist/runtime/components/Form/InputToggle/index.vue +19 -18
  39. package/dist/runtime/components/Form/InputUploadDropzone/index.d.vue.ts +1 -4
  40. package/dist/runtime/components/Form/InputUploadDropzone/index.vue +40 -35
  41. package/dist/runtime/components/Form/InputUploadDropzone/index.vue.d.ts +1 -4
  42. package/dist/runtime/components/Form/InputUploadDropzone/types.d.ts +2 -2
  43. package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.d.vue.ts +0 -5
  44. package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue +63 -58
  45. package/dist/runtime/components/Form/InputUploadDropzoneAuto/index.vue.d.ts +0 -5
  46. package/dist/runtime/components/Form/InputUploadDropzoneAuto/types.d.ts +3 -3
  47. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.d.vue.ts +0 -5
  48. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.vue +69 -60
  49. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/index.vue.d.ts +0 -5
  50. package/dist/runtime/components/Form/InputUploadDropzoneAutoMultiple/types.d.ts +3 -3
  51. package/dist/runtime/components/Form/InputUploadImageAuto/index.d.vue.ts +1 -6
  52. package/dist/runtime/components/Form/InputUploadImageAuto/index.vue +63 -58
  53. package/dist/runtime/components/Form/InputUploadImageAuto/index.vue.d.ts +1 -6
  54. package/dist/runtime/components/Form/InputUploadImageAuto/types.d.ts +3 -3
  55. package/dist/runtime/components/Form/InputWYSIWYG/EditorImageUploadNode.vue +18 -18
  56. package/dist/runtime/components/Form/InputWYSIWYG/EditorLinkPopover.vue +65 -65
  57. package/dist/runtime/components/Form/InputWYSIWYG/README.md +96 -96
  58. package/dist/runtime/components/Form/InputWYSIWYG/index.vue +43 -42
  59. package/dist/runtime/components/Form/fileState/EmptyState.vue +21 -21
  60. package/dist/runtime/components/Form/fileState/FailedState.vue +37 -33
  61. package/dist/runtime/components/Form/fileState/LoadingState.vue +24 -24
  62. package/dist/runtime/components/Form/fileState/MultipleFilesState.d.vue.ts +4 -4
  63. package/dist/runtime/components/Form/fileState/MultipleFilesState.vue +79 -75
  64. package/dist/runtime/components/Form/fileState/MultipleFilesState.vue.d.ts +4 -4
  65. package/dist/runtime/components/Form/fileState/PreviewModal.vue +23 -23
  66. package/dist/runtime/components/Form/fileState/SuccessState.d.vue.ts +2 -2
  67. package/dist/runtime/components/Form/fileState/SuccessState.vue +8 -4
  68. package/dist/runtime/components/Form/fileState/SuccessState.vue.d.ts +2 -2
  69. package/dist/runtime/components/Form/fileState/useFilePicker.d.ts +34 -0
  70. package/dist/runtime/components/Form/fileState/useFilePicker.js +48 -0
  71. package/dist/runtime/components/Form/fileState/useFileState.d.ts +7 -9
  72. package/dist/runtime/components/Form/fileState/useFileState.js +40 -120
  73. package/dist/runtime/components/Form/fileState/useUploadImageState.d.ts +7 -8
  74. package/dist/runtime/components/Form/fileState/useUploadImageState.js +28 -300
  75. package/dist/runtime/components/Form/fileState/useUploadState.d.ts +11 -7
  76. package/dist/runtime/components/Form/fileState/useUploadState.js +58 -131
  77. package/dist/runtime/components/Form/fileState/useUploadStateMultiple.d.ts +12 -18
  78. package/dist/runtime/components/Form/fileState/useUploadStateMultiple.js +89 -222
  79. package/dist/runtime/components/Form/index.vue +5 -5
  80. package/dist/runtime/components/Form/types.d.ts +2 -0
  81. package/dist/runtime/components/Image.vue +28 -28
  82. package/dist/runtime/components/Loader.d.vue.ts +1 -0
  83. package/dist/runtime/components/Loader.vue.d.ts +1 -0
  84. package/dist/runtime/components/Table/Base.d.vue.ts +15 -1
  85. package/dist/runtime/components/Table/Base.vue +118 -118
  86. package/dist/runtime/components/Table/Base.vue.d.ts +15 -1
  87. package/dist/runtime/components/Table/ColumnDate.vue +1 -1
  88. package/dist/runtime/components/Table/ColumnDateTime.vue +1 -1
  89. package/dist/runtime/components/Table/ColumnImage.vue +4 -4
  90. package/dist/runtime/components/Table/ColumnText.d.vue.ts +2 -3
  91. package/dist/runtime/components/Table/ColumnText.vue +11 -11
  92. package/dist/runtime/components/Table/ColumnText.vue.d.ts +2 -3
  93. package/dist/runtime/components/Table/Pagination.vue +70 -67
  94. package/dist/runtime/components/Table/Simple.vue +19 -19
  95. package/dist/runtime/components/Table/index.d.vue.ts +1 -1
  96. package/dist/runtime/components/Table/index.vue +37 -33
  97. package/dist/runtime/components/Table/index.vue.d.ts +1 -1
  98. package/dist/runtime/composables/loaderList.d.ts +2 -1
  99. package/dist/runtime/composables/loaderList.js +2 -1
  100. package/dist/runtime/composables/loaderObject.d.ts +2 -1
  101. package/dist/runtime/composables/loaderObject.js +2 -1
  102. package/dist/runtime/composables/loaderPage.js +194 -344
  103. package/dist/runtime/composables/useConfig.js +4 -3
  104. package/dist/runtime/composables/useDialog.js +5 -1
  105. package/dist/runtime/composables/useForm.d.ts +1 -1
  106. package/dist/runtime/composables/useForm.js +1 -1
  107. package/dist/runtime/composables/useMessages.d.ts +10 -0
  108. package/dist/runtime/composables/useMessages.js +10 -0
  109. package/dist/runtime/helpers/apiPageHelper.d.ts +0 -1
  110. package/dist/runtime/helpers/uploadCore.d.ts +54 -0
  111. package/dist/runtime/helpers/uploadCore.js +84 -0
  112. package/dist/runtime/i18n/valibot.d.ts +5 -68
  113. package/dist/runtime/i18n/valibot.js +33 -29
  114. package/dist/runtime/locale/en.d.ts +2 -0
  115. package/dist/runtime/locale/en.js +42 -0
  116. package/dist/runtime/locale/index.d.ts +7 -0
  117. package/dist/runtime/locale/index.js +8 -0
  118. package/dist/runtime/locale/th.d.ts +43 -0
  119. package/dist/runtime/locale/th.js +42 -0
  120. package/dist/runtime/server/tsconfig.json +3 -3
  121. package/dist/runtime/theme/dialog.js +1 -1
  122. package/dist/runtime/utils/ParamHelper.js +1 -1
  123. package/dist/runtime/utils/StringHelper.js +1 -4
  124. package/dist/runtime/utils/TimeHelper.js +2 -2
  125. package/dist/runtime/utils/lodash.js +2 -2
  126. package/package.json +20 -12
@@ -54,7 +54,6 @@ export interface IUsePageLoader<T> {
54
54
  status: IStatus;
55
55
  item: T | null;
56
56
  options: IAPIOptions;
57
- value: (id: string, opts?: any) => Promise<void>;
58
57
  };
59
58
  add: {
60
59
  status: IStatus;
@@ -0,0 +1,54 @@
1
+ import type { IFileValue } from '../components/Form/types.js';
2
+ import { type ICoreMessages } from '../locale/index.js';
3
+ export declare enum UploadState {
4
+ EMPTY = "empty",
5
+ UPLOADING = "uploading",
6
+ SUCCESS = "success",
7
+ ERROR = "error"
8
+ }
9
+ export interface IFileRules {
10
+ accept?: string | string[];
11
+ /** In KB */
12
+ maxSize?: number;
13
+ }
14
+ export interface IDimensionRules {
15
+ width?: number;
16
+ height?: number;
17
+ minWidth?: number;
18
+ minHeight?: number;
19
+ maxWidth?: number;
20
+ maxHeight?: number;
21
+ aspectRatio?: number;
22
+ aspectRatioTolerance?: number;
23
+ }
24
+ export interface IFileResponseKeys {
25
+ responseURL?: string;
26
+ responsePath?: string;
27
+ responseName?: string;
28
+ responseSize?: string;
29
+ responseID?: string;
30
+ }
31
+ type UploadMessages = ICoreMessages['upload'];
32
+ export declare const parseAccept: (accept: IFileRules["accept"]) => string[];
33
+ /**
34
+ * Accepts extensions (".jpg", "jpg"), wildcards ("image/*") and exact MIME types ("application/pdf")
35
+ */
36
+ export declare const isAcceptedFileType: (file: Pick<File, "name" | "type">, acceptedTypes: string[]) => boolean;
37
+ export declare const formatMaxSize: (maxSizeKb: number) => string;
38
+ /**
39
+ * @returns the error message, or undefined when the file passes
40
+ */
41
+ export declare const validateFile: (file: Pick<File, "name" | "type" | "size">, rules: IFileRules, messages: UploadMessages) => string | undefined;
42
+ /**
43
+ * @returns the error message, or undefined when the image passes
44
+ */
45
+ export declare const validateDimensions: (image: {
46
+ width: number;
47
+ height: number;
48
+ }, rules: IDimensionRules | undefined, messages: UploadMessages) => string | undefined;
49
+ /**
50
+ * Map the upload API response to the value stored in the form, falling back to the local file's name and size
51
+ */
52
+ export declare const toFileValue: (response: unknown, keys: IFileResponseKeys, file?: Pick<File, "name" | "size">) => IFileValue;
53
+ export declare const toUploadFormData: (bodyKey: string, file: File) => FormData;
54
+ export {};
@@ -0,0 +1,84 @@
1
+ import { formatMessage } from "../locale/index.js";
2
+ import { _get } from "../utils/lodash.js";
3
+ export var UploadState = /* @__PURE__ */ ((UploadState2) => {
4
+ UploadState2["EMPTY"] = "empty";
5
+ UploadState2["UPLOADING"] = "uploading";
6
+ UploadState2["SUCCESS"] = "success";
7
+ UploadState2["ERROR"] = "error";
8
+ return UploadState2;
9
+ })(UploadState || {});
10
+ export const parseAccept = (accept) => (Array.isArray(accept) ? accept : (accept || "").split(",")).map((type) => type.trim()).filter(Boolean);
11
+ export const isAcceptedFileType = (file, acceptedTypes) => {
12
+ if (!acceptedTypes.length) return true;
13
+ const fileExtension = file.name.toLowerCase().split(".").pop();
14
+ return acceptedTypes.some((acceptedType) => {
15
+ if (acceptedType.startsWith(".")) {
16
+ return fileExtension === acceptedType.slice(1).toLowerCase();
17
+ }
18
+ if (!acceptedType.includes("/") && !acceptedType.includes("*")) {
19
+ return fileExtension === acceptedType.toLowerCase();
20
+ }
21
+ if (acceptedType.endsWith("/*")) {
22
+ return file.type.startsWith(acceptedType.slice(0, -1));
23
+ }
24
+ return file.type === acceptedType;
25
+ });
26
+ };
27
+ export const formatMaxSize = (maxSizeKb) => maxSizeKb > 1024 ? `${(maxSizeKb / 1024).toFixed(2)} MB` : `${maxSizeKb} KB`;
28
+ export const validateFile = (file, rules, messages) => {
29
+ const acceptedTypes = parseAccept(rules.accept);
30
+ if (!isAcceptedFileType(file, acceptedTypes)) {
31
+ return formatMessage(messages.invalidType, {
32
+ types: acceptedTypes.join(", ")
33
+ });
34
+ }
35
+ if (rules.maxSize && file.size > rules.maxSize * 1024) {
36
+ return formatMessage(messages.maxSize, {
37
+ size: formatMaxSize(rules.maxSize)
38
+ });
39
+ }
40
+ };
41
+ export const validateDimensions = (image, rules, messages) => {
42
+ if (!rules) return;
43
+ const {
44
+ width,
45
+ height
46
+ } = image;
47
+ const checks = [
48
+ [rules.width !== void 0 && width !== rules.width, messages.imageWidth, rules.width, width],
49
+ [rules.height !== void 0 && height !== rules.height, messages.imageHeight, rules.height, height],
50
+ [rules.minWidth !== void 0 && width < rules.minWidth, messages.imageMinWidth, rules.minWidth, width],
51
+ [rules.minHeight !== void 0 && height < rules.minHeight, messages.imageMinHeight, rules.minHeight, height],
52
+ [rules.maxWidth !== void 0 && width > rules.maxWidth, messages.imageMaxWidth, rules.maxWidth, width],
53
+ [rules.maxHeight !== void 0 && height > rules.maxHeight, messages.imageMaxHeight, rules.maxHeight, height]
54
+ ];
55
+ for (const [failed, template, expected, actual] of checks) {
56
+ if (failed) {
57
+ return formatMessage(template, {
58
+ expected,
59
+ actual
60
+ });
61
+ }
62
+ }
63
+ if (rules.aspectRatio !== void 0) {
64
+ const actualRatio = width / height;
65
+ if (Math.abs(actualRatio - rules.aspectRatio) > (rules.aspectRatioTolerance ?? 0.01)) {
66
+ return formatMessage(messages.imageAspectRatio, {
67
+ expected: rules.aspectRatio.toFixed(2),
68
+ actual: actualRatio.toFixed(2)
69
+ });
70
+ }
71
+ }
72
+ };
73
+ export const toFileValue = (response, keys, file) => ({
74
+ url: _get(response, keys.responseURL),
75
+ path: _get(response, keys.responsePath),
76
+ name: _get(response, keys.responseName) || file?.name,
77
+ size: Number(_get(response, keys.responseSize) || file?.size),
78
+ id: _get(response, keys.responseID)
79
+ });
80
+ export const toUploadFormData = (bodyKey, file) => {
81
+ const formData = new FormData();
82
+ formData.append(bodyKey, file);
83
+ return formData;
84
+ };
@@ -1,69 +1,6 @@
1
- export declare const valibotLanguageTH: {
2
- base64: () => string;
3
- bic: () => string;
4
- bytes: (issue: any) => string;
5
- check: () => string;
6
- credit_card: () => string;
7
- cuid: () => string;
8
- cuid2: () => string;
9
- decimal: () => string;
10
- digits: () => string;
11
- email: () => string;
12
- emoji: () => string;
13
- empty: () => string;
14
- ends_with: (issue: any) => string;
15
- every_item: () => string;
16
- excludes: (issue: any) => string;
17
- finite: () => string;
18
- graphemes: (issue: any) => string;
19
- hash: () => string;
20
- hex_color: () => string;
21
- hexadecimal: () => string;
22
- imei: () => string;
23
- includes: (issue: any) => string;
24
- integer: () => string;
25
- ip: () => string;
26
- ipv4: () => string;
27
- ipv6: () => string;
28
- iso_date: () => string;
29
- iso_date_time: () => string;
30
- length: (issue: any) => string;
31
- mac: () => string;
32
- mac_48: () => string;
33
- mac_64: () => string;
34
- max_bytes: (issue: any) => string;
35
- max_graphemes: (issue: any) => string;
36
- max_length: (issue: any) => string;
37
- max_size: (issue: any) => string;
38
- max_value: (issue: any) => string;
39
- max_words: (issue: any) => string;
40
- mime_type: (issue: any) => string;
41
- min_bytes: (issue: any) => string;
42
- min_graphemes: (issue: any) => string;
43
- min_length: (issue: any) => string;
44
- min_size: (issue: any) => string;
45
- min_value: (issue: any) => string;
46
- min_words: (issue: any) => string;
47
- multiple_of: (issue: any) => string;
48
- nanoid: () => string;
49
- non_empty: () => string;
50
- not_bytes: (issue: any) => string;
51
- not_graphemes: (issue: any) => string;
52
- not_length: (issue: any) => string;
53
- not_size: (issue: any) => string;
54
- not_value: (issue: any) => string;
55
- not_words: (issue: any) => string;
56
- octal: () => string;
57
- partial_check: () => string;
58
- regex: () => string;
59
- safe_integer: () => string;
60
- size: (issue: any) => string;
61
- some_item: () => string;
62
- starts_with: (issue: any) => string;
63
- ulid: () => string;
64
- url: () => string;
65
- uuid: () => string;
66
- value: () => string;
67
- words: (issue: any) => string;
68
- default: () => string;
1
+ import type { BaseIssue } from 'valibot';
2
+ type IssueMessage = (issue: BaseIssue<unknown>) => string;
3
+ export declare const valibotLanguageTH: Record<string, IssueMessage> & {
4
+ default: IssueMessage;
69
5
  };
6
+ export {};
@@ -1,7 +1,11 @@
1
+ const requirementOf = (issue) => {
2
+ const requirement = issue.requirement;
3
+ return requirement instanceof Date ? requirement.toISOString() : String(requirement);
4
+ };
1
5
  export const valibotLanguageTH = {
2
6
  base64: () => "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25 base64 \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
3
7
  bic: () => "\u0E23\u0E2B\u0E31\u0E2A bic \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
4
- bytes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E02\u0E19\u0E32\u0E14 ${issue.expected} \u0E44\u0E1A\u0E15\u0E4C \u0E41\u0E15\u0E48\u0E44\u0E14\u0E49\u0E23\u0E31\u0E1A ${issue.received}`,
8
+ bytes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E02\u0E19\u0E32\u0E14 ${requirementOf(issue)} \u0E44\u0E1A\u0E15\u0E4C \u0E41\u0E15\u0E48\u0E44\u0E14\u0E49\u0E23\u0E31\u0E1A ${issue.received}`,
5
9
  check: () => "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E17\u0E35\u0E48\u0E01\u0E23\u0E2D\u0E01\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
6
10
  credit_card: () => "\u0E2B\u0E21\u0E32\u0E22\u0E40\u0E25\u0E02\u0E1A\u0E31\u0E15\u0E23\u0E40\u0E04\u0E23\u0E14\u0E34\u0E15\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
7
11
  cuid: () => "cuid \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
@@ -11,62 +15,62 @@ export const valibotLanguageTH = {
11
15
  email: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E2D\u0E35\u0E40\u0E21\u0E25\u0E17\u0E35\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
12
16
  emoji: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E2D\u0E35\u0E42\u0E21\u0E08\u0E34\u0E17\u0E35\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
13
17
  empty: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E2D\u0E22\u0E48\u0E32\u0E1B\u0E25\u0E48\u0E2D\u0E22\u0E27\u0E48\u0E32\u0E07",
14
- ends_with: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E25\u0E07\u0E17\u0E49\u0E32\u0E22\u0E14\u0E49\u0E27\u0E22 "${issue.expected}"`,
18
+ ends_with: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E25\u0E07\u0E17\u0E49\u0E32\u0E22\u0E14\u0E49\u0E27\u0E22 "${requirementOf(issue)}"`,
15
19
  every_item: () => "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E1A\u0E32\u0E07\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
16
- excludes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E1B\u0E23\u0E30\u0E01\u0E2D\u0E1A\u0E14\u0E49\u0E27\u0E22 "${issue.expected}"`,
20
+ excludes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E1B\u0E23\u0E30\u0E01\u0E2D\u0E1A\u0E14\u0E49\u0E27\u0E22 "${requirementOf(issue)}"`,
17
21
  finite: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E04\u0E48\u0E32\u0E17\u0E35\u0E48\u0E08\u0E33\u0E01\u0E31\u0E14",
18
- graphemes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35 ${issue.expected} \u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23`,
22
+ graphemes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35 ${requirementOf(issue)} \u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23`,
19
23
  hash: () => "\u0E04\u0E48\u0E32 hash \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
20
24
  hex_color: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E2A\u0E35\u0E43\u0E19\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A hex",
21
25
  hexadecimal: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E40\u0E25\u0E02\u0E10\u0E32\u0E19\u0E2A\u0E34\u0E1A\u0E2B\u0E01",
22
26
  imei: () => "imei \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
23
- includes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E1B\u0E23\u0E30\u0E01\u0E2D\u0E1A\u0E14\u0E49\u0E27\u0E22 "${issue.expected}"`,
27
+ includes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E1B\u0E23\u0E30\u0E01\u0E2D\u0E1A\u0E14\u0E49\u0E27\u0E22 "${requirementOf(issue)}"`,
24
28
  integer: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E15\u0E31\u0E27\u0E40\u0E25\u0E02\u0E08\u0E33\u0E19\u0E27\u0E19\u0E40\u0E15\u0E47\u0E21",
25
29
  ip: () => "\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48 ip \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
26
30
  ipv4: () => "\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48 ipv4 \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
27
31
  ipv6: () => "\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48 ipv6 \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
28
32
  iso_date: () => "\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E43\u0E19\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A iso \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
29
33
  iso_date_time: () => "\u0E27\u0E31\u0E19\u0E17\u0E35\u0E48\u0E41\u0E25\u0E30\u0E40\u0E27\u0E25\u0E32\u0E43\u0E19\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A iso \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
30
- length: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E04\u0E27\u0E32\u0E21\u0E22\u0E32\u0E27 ${issue.expected} \u0E15\u0E31\u0E27`,
34
+ length: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E04\u0E27\u0E32\u0E21\u0E22\u0E32\u0E27 ${requirementOf(issue)} \u0E15\u0E31\u0E27`,
31
35
  mac: () => "\u0E17\u0E35\u0E48\u0E2D\u0E22\u0E39\u0E48 mac \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
32
36
  mac_48: () => "mac 48-bit \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
33
37
  mac_64: () => "mac 64-bit \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
34
- max_bytes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${issue.expected} \u0E44\u0E1A\u0E15\u0E4C`,
35
- max_graphemes: (issue) => `\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${issue.expected} \u0E15\u0E31\u0E27`,
36
- max_length: (issue) => `\u0E04\u0E27\u0E32\u0E21\u0E22\u0E32\u0E27\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${issue.expected} \u0E15\u0E31\u0E27`,
37
- max_size: (issue) => `\u0E02\u0E19\u0E32\u0E14\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${issue.expected}`,
38
- max_value: (issue) => `\u0E04\u0E48\u0E32\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${issue.expected}`,
39
- max_words: (issue) => `\u0E08\u0E33\u0E19\u0E27\u0E19\u0E04\u0E33\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${issue.expected} \u0E04\u0E33`,
40
- mime_type: (issue) => "mime type \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
41
- min_bytes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${issue.expected} \u0E44\u0E1A\u0E15\u0E4C`,
42
- min_graphemes: (issue) => `\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${issue.expected} \u0E15\u0E31\u0E27`,
43
- min_length: (issue) => `\u0E04\u0E27\u0E32\u0E21\u0E22\u0E32\u0E27\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${issue.expected} \u0E15\u0E31\u0E27`,
44
- min_size: (issue) => `\u0E02\u0E19\u0E32\u0E14\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32 ${issue.expected}`,
38
+ max_bytes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${requirementOf(issue)} \u0E44\u0E1A\u0E15\u0E4C`,
39
+ max_graphemes: (issue) => `\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${requirementOf(issue)} \u0E15\u0E31\u0E27`,
40
+ max_length: (issue) => `\u0E04\u0E27\u0E32\u0E21\u0E22\u0E32\u0E27\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${requirementOf(issue)} \u0E15\u0E31\u0E27`,
41
+ max_size: (issue) => `\u0E02\u0E19\u0E32\u0E14\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${requirementOf(issue)}`,
42
+ max_value: (issue) => `\u0E04\u0E48\u0E32\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${requirementOf(issue)}`,
43
+ max_words: (issue) => `\u0E08\u0E33\u0E19\u0E27\u0E19\u0E04\u0E33\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 ${requirementOf(issue)} \u0E04\u0E33`,
44
+ mime_type: () => "mime type \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
45
+ min_bytes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${requirementOf(issue)} \u0E44\u0E1A\u0E15\u0E4C`,
46
+ min_graphemes: (issue) => `\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${requirementOf(issue)} \u0E15\u0E31\u0E27`,
47
+ min_length: (issue) => `\u0E04\u0E27\u0E32\u0E21\u0E22\u0E32\u0E27\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${requirementOf(issue)} \u0E15\u0E31\u0E27`,
48
+ min_size: (issue) => `\u0E02\u0E19\u0E32\u0E14\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32 ${requirementOf(issue)}`,
45
49
  min_value: (issue) => {
46
- return `\u0E04\u0E48\u0E32\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${issue.requirement}`;
50
+ return `\u0E04\u0E48\u0E32\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${requirementOf(issue)}`;
47
51
  },
48
- min_words: (issue) => `\u0E08\u0E33\u0E19\u0E27\u0E19\u0E04\u0E33\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${issue.expected} \u0E04\u0E33`,
49
- multiple_of: (issue) => `\u0E04\u0E48\u0E32\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E1B\u0E47\u0E19\u0E08\u0E33\u0E19\u0E27\u0E19\u0E40\u0E17\u0E48\u0E32\u0E02\u0E2D\u0E07 ${issue.expected}`,
52
+ min_words: (issue) => `\u0E08\u0E33\u0E19\u0E27\u0E19\u0E04\u0E33\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E19\u0E49\u0E2D\u0E22 ${requirementOf(issue)} \u0E04\u0E33`,
53
+ multiple_of: (issue) => `\u0E04\u0E48\u0E32\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E1B\u0E47\u0E19\u0E08\u0E33\u0E19\u0E27\u0E19\u0E40\u0E17\u0E48\u0E32\u0E02\u0E2D\u0E07 ${requirementOf(issue)}`,
50
54
  nanoid: () => "nano id \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
51
55
  non_empty: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25",
52
- not_bytes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E43\u0E0A\u0E48 ${issue.expected} \u0E44\u0E1A\u0E15\u0E4C`,
53
- not_graphemes: (issue) => `\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${issue.expected}`,
54
- not_length: (issue) => `\u0E04\u0E27\u0E32\u0E21\u0E22\u0E32\u0E27\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${issue.expected}`,
55
- not_size: (issue) => `\u0E02\u0E19\u0E32\u0E14\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${issue.expected}`,
56
- not_value: (issue) => `\u0E04\u0E48\u0E32\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${issue.expected}`,
57
- not_words: (issue) => `\u0E08\u0E33\u0E19\u0E27\u0E19\u0E04\u0E33\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${issue.expected} \u0E04\u0E33`,
56
+ not_bytes: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E43\u0E0A\u0E48 ${requirementOf(issue)} \u0E44\u0E1A\u0E15\u0E4C`,
57
+ not_graphemes: (issue) => `\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${requirementOf(issue)}`,
58
+ not_length: (issue) => `\u0E04\u0E27\u0E32\u0E21\u0E22\u0E32\u0E27\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${requirementOf(issue)}`,
59
+ not_size: (issue) => `\u0E02\u0E19\u0E32\u0E14\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${requirementOf(issue)}`,
60
+ not_value: (issue) => `\u0E04\u0E48\u0E32\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${requirementOf(issue)}`,
61
+ not_words: (issue) => `\u0E08\u0E33\u0E19\u0E27\u0E19\u0E04\u0E33\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E17\u0E48\u0E32\u0E01\u0E31\u0E1A ${requirementOf(issue)} \u0E04\u0E33`,
58
62
  octal: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E40\u0E25\u0E02\u0E10\u0E32\u0E19\u0E41\u0E1B\u0E14",
59
63
  partial_check: () => "\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E1A\u0E32\u0E07\u0E2A\u0E48\u0E27\u0E19\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
60
64
  regex: () => "\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
61
65
  safe_integer: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E15\u0E31\u0E27\u0E40\u0E25\u0E02\u0E08\u0E33\u0E19\u0E27\u0E19\u0E40\u0E15\u0E47\u0E21\u0E17\u0E35\u0E48\u0E1B\u0E25\u0E2D\u0E14\u0E20\u0E31\u0E22",
62
- size: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E02\u0E19\u0E32\u0E14 ${issue.expected}`,
66
+ size: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E02\u0E19\u0E32\u0E14 ${requirementOf(issue)}`,
63
67
  some_item: () => "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E1A\u0E32\u0E07\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
64
- starts_with: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E23\u0E34\u0E48\u0E21\u0E15\u0E49\u0E19\u0E14\u0E49\u0E27\u0E22 "${issue.expected}"`,
68
+ starts_with: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E23\u0E34\u0E48\u0E21\u0E15\u0E49\u0E19\u0E14\u0E49\u0E27\u0E22 "${requirementOf(issue)}"`,
65
69
  ulid: () => "ulid \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
66
70
  url: () => "url \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
67
71
  uuid: () => "uuid \u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
68
72
  value: () => "\u0E04\u0E48\u0E32\u0E17\u0E35\u0E48\u0E01\u0E23\u0E2D\u0E01\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07",
69
- words: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E04\u0E33 ${issue.expected} \u0E04\u0E33`,
73
+ words: (issue) => `\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E15\u0E49\u0E2D\u0E07\u0E21\u0E35\u0E04\u0E33 ${requirementOf(issue)} \u0E04\u0E33`,
70
74
  default: () => "\u0E01\u0E23\u0E38\u0E13\u0E32\u0E01\u0E23\u0E2D\u0E01\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25"
71
75
  // Fallback message
72
76
  };
@@ -0,0 +1,2 @@
1
+ import type { ICoreMessages } from './th.js';
2
+ export declare const en: ICoreMessages;
@@ -0,0 +1,42 @@
1
+ export const en = {
2
+ common: {
3
+ confirm: "OK",
4
+ cancel: "Cancel",
5
+ select: "Select",
6
+ loading: "Loading...",
7
+ search: "Search...",
8
+ clearSearch: "Clear search",
9
+ empty: "No data found!",
10
+ somethingWentWrong: "Something went wrong"
11
+ },
12
+ pagination: {
13
+ items: "items",
14
+ ofTotal: "of total",
15
+ total: "Total",
16
+ itemsOfTotal: "items of total"
17
+ },
18
+ upload: {
19
+ selectFile: "Click to select a file",
20
+ selectImage: "Click to select an image",
21
+ dropHere: "or drag and drop here",
22
+ uploading: "Uploading...",
23
+ uploadFailed: "Upload failed, please try again",
24
+ retry: "Try again",
25
+ preview: "Preview",
26
+ download: "Download file",
27
+ remove: "Remove file",
28
+ removeConfirm: "Do you want to remove {name}?",
29
+ invalidType: "Invalid file type (only {types} are allowed)",
30
+ maxSize: "File size must not exceed {size}",
31
+ maxFiles: "You can upload up to {max} files",
32
+ error: "An error occurred: {message}",
33
+ imageLoadFailed: "Failed to load image",
34
+ imageWidth: "Image width must be {expected}px (current: {actual}px)",
35
+ imageHeight: "Image height must be {expected}px (current: {actual}px)",
36
+ imageMinWidth: "Image width must be at least {expected}px (current: {actual}px)",
37
+ imageMinHeight: "Image height must be at least {expected}px (current: {actual}px)",
38
+ imageMaxWidth: "Image width must not exceed {expected}px (current: {actual}px)",
39
+ imageMaxHeight: "Image height must not exceed {expected}px (current: {actual}px)",
40
+ imageAspectRatio: "Image aspect ratio is incorrect (expected: {expected}, current: {actual})"
41
+ }
42
+ };
@@ -0,0 +1,7 @@
1
+ import { type ICoreMessages } from './th.js';
2
+ export type { ICoreMessages };
3
+ export type ICoreMessagesOverride = {
4
+ [Group in keyof ICoreMessages]?: Partial<ICoreMessages[Group]>;
5
+ };
6
+ export declare const formatMessage: (template: string, params?: Record<string, string | number>) => string;
7
+ export declare const resolveMessages: (locale: string | undefined, overrides?: ICoreMessagesOverride) => ICoreMessages;
@@ -0,0 +1,8 @@
1
+ import defu from "defu";
2
+ import { th } from "./th.js";
3
+ import { en } from "./en.js";
4
+ export const formatMessage = (template, params = {}) => template.replace(
5
+ /\{(\w+)\}/g,
6
+ (placeholder, key) => key in params ? String(params[key]) : placeholder
7
+ );
8
+ export const resolveMessages = (locale, overrides = {}) => defu(overrides, locale === "th" ? th : en);
@@ -0,0 +1,43 @@
1
+ export declare const th: {
2
+ common: {
3
+ confirm: string;
4
+ cancel: string;
5
+ select: string;
6
+ loading: string;
7
+ search: string;
8
+ clearSearch: string;
9
+ empty: string;
10
+ somethingWentWrong: string;
11
+ };
12
+ pagination: {
13
+ items: string;
14
+ ofTotal: string;
15
+ total: string;
16
+ itemsOfTotal: string;
17
+ };
18
+ upload: {
19
+ selectFile: string;
20
+ selectImage: string;
21
+ dropHere: string;
22
+ uploading: string;
23
+ uploadFailed: string;
24
+ retry: string;
25
+ preview: string;
26
+ download: string;
27
+ remove: string;
28
+ removeConfirm: string;
29
+ invalidType: string;
30
+ maxSize: string;
31
+ maxFiles: string;
32
+ error: string;
33
+ imageLoadFailed: string;
34
+ imageWidth: string;
35
+ imageHeight: string;
36
+ imageMinWidth: string;
37
+ imageMinHeight: string;
38
+ imageMaxWidth: string;
39
+ imageMaxHeight: string;
40
+ imageAspectRatio: string;
41
+ };
42
+ };
43
+ export type ICoreMessages = typeof th;
@@ -0,0 +1,42 @@
1
+ export const th = {
2
+ common: {
3
+ confirm: "\u0E15\u0E01\u0E25\u0E07",
4
+ cancel: "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01",
5
+ select: "\u0E15\u0E01\u0E25\u0E07",
6
+ loading: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E42\u0E2B\u0E25\u0E14...",
7
+ search: "\u0E04\u0E49\u0E19\u0E2B\u0E32...",
8
+ clearSearch: "\u0E25\u0E49\u0E32\u0E07\u0E01\u0E32\u0E23\u0E04\u0E49\u0E19\u0E2B\u0E32",
9
+ empty: "\u0E44\u0E21\u0E48\u0E1E\u0E1A\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25!",
10
+ somethingWentWrong: "\u0E21\u0E35\u0E1A\u0E32\u0E07\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14"
11
+ },
12
+ pagination: {
13
+ items: "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23",
14
+ ofTotal: "\u0E08\u0E32\u0E01\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
15
+ total: "\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14",
16
+ itemsOfTotal: "\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23 \u0E08\u0E32\u0E01\u0E17\u0E31\u0E49\u0E07\u0E2B\u0E21\u0E14"
17
+ },
18
+ upload: {
19
+ selectFile: "\u0E04\u0E25\u0E34\u0E01\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E44\u0E1F\u0E25\u0E4C",
20
+ selectImage: "\u0E04\u0E25\u0E34\u0E01\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E",
21
+ dropHere: "\u0E2B\u0E23\u0E37\u0E2D \u0E25\u0E32\u0E01\u0E41\u0E25\u0E30\u0E27\u0E32\u0E07\u0E17\u0E35\u0E48\u0E19\u0E35\u0E48",
22
+ uploading: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2D\u0E31\u0E1E\u0E42\u0E2B\u0E25\u0E14...",
23
+ uploadFailed: "\u0E2D\u0E31\u0E1E\u0E42\u0E2B\u0E25\u0E14\u0E25\u0E49\u0E21\u0E40\u0E2B\u0E25\u0E27, \u0E01\u0E23\u0E38\u0E13\u0E32\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07",
24
+ retry: "\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07",
25
+ preview: "\u0E14\u0E39\u0E15\u0E31\u0E27\u0E2D\u0E22\u0E48\u0E32\u0E07",
26
+ download: "\u0E14\u0E32\u0E27\u0E19\u0E4C\u0E42\u0E2B\u0E25\u0E14\u0E44\u0E1F\u0E25\u0E4C",
27
+ remove: "\u0E25\u0E1A\u0E44\u0E1F\u0E25\u0E4C",
28
+ removeConfirm: "\u0E04\u0E38\u0E13\u0E15\u0E49\u0E2D\u0E07\u0E01\u0E32\u0E23\u0E25\u0E1A\u0E44\u0E1F\u0E25\u0E4C {name} \u0E43\u0E0A\u0E48\u0E2B\u0E23\u0E37\u0E2D\u0E44\u0E21\u0E48",
29
+ invalidType: "\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17\u0E44\u0E1F\u0E25\u0E4C\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07 (\u0E23\u0E2D\u0E07\u0E23\u0E31\u0E1A\u0E40\u0E09\u0E1E\u0E32\u0E30 {types})",
30
+ maxSize: "\u0E02\u0E19\u0E32\u0E14\u0E44\u0E1F\u0E25\u0E4C\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 {size}",
31
+ maxFiles: "\u0E2A\u0E32\u0E21\u0E32\u0E23\u0E16\u0E2D\u0E31\u0E1E\u0E42\u0E2B\u0E25\u0E14\u0E44\u0E14\u0E49\u0E2A\u0E39\u0E07\u0E2A\u0E38\u0E14 {max} \u0E44\u0E1F\u0E25\u0E4C",
32
+ error: "\u0E1E\u0E1A\u0E02\u0E49\u0E2D\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14: {message}",
33
+ imageLoadFailed: "\u0E44\u0E21\u0E48\u0E2A\u0E32\u0E21\u0E32\u0E23\u0E16\u0E42\u0E2B\u0E25\u0E14\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E44\u0E14\u0E49",
34
+ imageWidth: "\u0E04\u0E27\u0E32\u0E21\u0E01\u0E27\u0E49\u0E32\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E1B\u0E47\u0E19 {expected}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: {actual}px)",
35
+ imageHeight: "\u0E04\u0E27\u0E32\u0E21\u0E2A\u0E39\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E40\u0E1B\u0E47\u0E19 {expected}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: {actual}px)",
36
+ imageMinWidth: "\u0E04\u0E27\u0E32\u0E21\u0E01\u0E27\u0E49\u0E32\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32 {expected}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: {actual}px)",
37
+ imageMinHeight: "\u0E04\u0E27\u0E32\u0E21\u0E2A\u0E39\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E19\u0E49\u0E2D\u0E22\u0E01\u0E27\u0E48\u0E32 {expected}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: {actual}px)",
38
+ imageMaxWidth: "\u0E04\u0E27\u0E32\u0E21\u0E01\u0E27\u0E49\u0E32\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 {expected}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: {actual}px)",
39
+ imageMaxHeight: "\u0E04\u0E27\u0E32\u0E21\u0E2A\u0E39\u0E07\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E15\u0E49\u0E2D\u0E07\u0E44\u0E21\u0E48\u0E40\u0E01\u0E34\u0E19 {expected}px (\u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: {actual}px)",
40
+ imageAspectRatio: "\u0E2D\u0E31\u0E15\u0E23\u0E32\u0E2A\u0E48\u0E27\u0E19\u0E02\u0E2D\u0E07\u0E23\u0E39\u0E1B\u0E20\u0E32\u0E1E\u0E44\u0E21\u0E48\u0E16\u0E39\u0E01\u0E15\u0E49\u0E2D\u0E07 (\u0E15\u0E49\u0E2D\u0E07\u0E01\u0E32\u0E23: {expected}, \u0E1B\u0E31\u0E08\u0E08\u0E38\u0E1A\u0E31\u0E19: {actual})"
41
+ }
42
+ };
@@ -1,3 +1,3 @@
1
- {
2
- "extends": "../../../.nuxt/tsconfig.server.json",
3
- }
1
+ {
2
+ "extends": "../../../.nuxt/tsconfig.server.json",
3
+ }
@@ -16,7 +16,7 @@ export const dialogTheme = {
16
16
  // Desktop styles (centered modal)
17
17
  "md:!top-[50%] md:!left-[50%] md:!bottom-auto md:!right-auto",
18
18
  "md:w-[90vw] md:max-w-[500px]",
19
- "md:translate-x-[-50%] md:translate-y-[-50%]",
19
+ "md:!translate-x-[-50%] md:!translate-y-[-50%]",
20
20
  "md:!rounded-lg md:space-x-4"
21
21
  ],
22
22
  overlay: "fixed inset-0 bg-[#0C111D]/60 backdrop-blur",
@@ -28,7 +28,7 @@ export class ParamHelper {
28
28
  return bool === null ? false : !!bool;
29
29
  };
30
30
  static isNotFoundError = (error) => {
31
- return _get(error, "code", true) === "NOT_FOUND";
31
+ return _get(error, "code", "") === "NOT_FOUND";
32
32
  };
33
33
  static isChangeWithFalse = (value, oldValue) => {
34
34
  return oldValue !== value && !value;
@@ -24,10 +24,7 @@ export class StringHelper {
24
24
  };
25
25
  static getError = (errorData, defaultErrorMessage = "\u0E21\u0E35\u0E1A\u0E32\u0E07\u0E2D\u0E22\u0E48\u0E32\u0E07\u0E1C\u0E34\u0E14\u0E1E\u0E25\u0E32\u0E14") => {
26
26
  let msg = errorData?.message || defaultErrorMessage;
27
- if (!errorData.code || !msg) {
28
- return msg;
29
- }
30
- if (errorData.code !== "INVALID_PARAMS" && !errorData.fields) {
27
+ if (!errorData?.code || !msg || !errorData.fields) {
31
28
  return msg;
32
29
  }
33
30
  for (const [, value] of Object.entries(errorData.fields)) {
@@ -1,5 +1,5 @@
1
1
  import { addYears, format, formatISO, isDate, isValid } from "date-fns";
2
- import * as locales from "date-fns/locale";
2
+ import { th } from "date-fns/locale/th";
3
3
  import { formatInTimeZone } from "date-fns-tz";
4
4
  import { useCoreConfig } from "#core/composables/useConfig";
5
5
  const getTime = (time) => {
@@ -27,7 +27,7 @@ export class TimeHelper {
27
27
  newDateStr = addYears(dateStr, 543);
28
28
  }
29
29
  if (this.getConfig().isThaiMonth || forceThai) {
30
- options.locale = locales.th;
30
+ options.locale = th;
31
31
  }
32
32
  return formatInTimeZone(newDateStr, this.getConfig().timeZone, formatStr, options);
33
33
  };
@@ -16,11 +16,11 @@ export const _get = (object, path, defaultValue) => {
16
16
  }
17
17
  const pathArray = Array.isArray(path) ? path : stringToPath(path);
18
18
  let current = object;
19
- for (let i = 0; i < pathArray.length; i++) {
19
+ for (const key of pathArray) {
20
20
  if (current == null) {
21
21
  return defaultValue;
22
22
  }
23
- current = current[pathArray[i]];
23
+ current = current[key];
24
24
  }
25
25
  return current === void 0 ? defaultValue : current;
26
26
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finema/core",
3
- "version": "3.21.0",
3
+ "version": "3.23.2",
4
4
  "repository": "https://gitlab.finema.co/finema/ui-kit",
5
5
  "license": "MIT",
6
6
  "author": "Finema Dev Core Team",
@@ -35,17 +35,21 @@
35
35
  "lint": "eslint .",
36
36
  "lint:fix": "eslint --fix .",
37
37
  "test": "vitest run",
38
+ "test:unit": "vitest run --project unit",
39
+ "test:nuxt": "vitest run --project nuxt",
38
40
  "test:watch": "vitest watch",
39
- "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit",
41
+ "test:coverage": "vitest run --coverage",
42
+ "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit -p .nuxt/tsconfig.app.json",
43
+ "bundle:report": "node scripts/bundle-report.mjs",
40
44
  "prepare": "husky"
41
45
  },
42
46
  "dependencies": {
43
47
  "@iconify-json/heroicons": "^1.2.2",
44
48
  "@iconify-json/ph": "^1.2.2",
45
49
  "@iconify-json/svg-spinners": "^1.2.2",
46
- "@nuxt/kit": "^4.5.0",
47
- "@nuxt/ui": "^4.10.0",
48
- "@pinia/nuxt": "^0.11.0",
50
+ "@nuxt/kit": "^4.5.2",
51
+ "@nuxt/ui": "^4.11.1",
52
+ "@pinia/nuxt": "^1.0.2",
49
53
  "@tailwindcss/typography": "^0.5.0-alpha.3",
50
54
  "@tiptap/extension-text-align": "^3.18.0",
51
55
  "@vee-validate/nuxt": "^4.15.1",
@@ -65,19 +69,23 @@
65
69
  "devDependencies": {
66
70
  "@eslint/js": "^10.0.1",
67
71
  "@finema/eslint-config": "^2.0.4",
68
- "@nuxt/devtools": "^3.2.4",
69
- "@nuxt/eslint-config": "^1.4.1",
70
- "@nuxt/module-builder": "^1.0.2",
71
- "@nuxt/schema": "^4.4.8",
72
- "@nuxt/test-utils": "^4.0.3",
72
+ "@nuxt/devtools": "^3.4.2",
73
+ "@nuxt/eslint-config": "^1.17.0",
74
+ "@nuxt/module-builder": "^1.0.3",
75
+ "@nuxt/schema": "^4.5.2",
76
+ "@nuxt/test-utils": "^4.3.2",
77
+ "@types/lodash-es": "^4.17.12",
73
78
  "@types/node": "latest",
79
+ "@vitest/coverage-v8": "^5.0.1",
80
+ "@vue/test-utils": "^2.5.1",
74
81
  "changelogen": "^0.6.1",
82
+ "happy-dom": "^20.14.5",
75
83
  "husky": "^9.1.7",
76
84
  "lint-staged": "^17.0.7",
77
- "nuxt": "^4.4.8",
85
+ "nuxt": "^4.5.2",
78
86
  "typescript": "~5.9.3",
79
87
  "typescript-eslint": "^8.18.0",
80
- "vitest": "^4.0.2",
88
+ "vitest": "^5.0.1",
81
89
  "vue-tsc": "^3.0.4"
82
90
  },
83
91
  "lint-staged": {