@globalbrain/sefirot 3.23.0 → 3.24.0

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 (52) hide show
  1. package/lib/components/SInputAddon.vue +3 -3
  2. package/lib/components/STableCellNumber.vue +1 -1
  3. package/lib/http/Http.ts +14 -16
  4. package/lib/support/Day.ts +43 -0
  5. package/lib/validation/Rule.ts +1 -1
  6. package/lib/validation/rules/checked.ts +11 -5
  7. package/lib/validation/rules/decimal.ts +11 -6
  8. package/lib/validation/rules/decimalOrHyphen.ts +11 -5
  9. package/lib/validation/rules/email.ts +11 -5
  10. package/lib/validation/rules/fileExtension.ts +11 -7
  11. package/lib/validation/rules/hms.ts +11 -8
  12. package/lib/validation/rules/maxFileSize.ts +11 -12
  13. package/lib/validation/rules/maxLength.ts +12 -7
  14. package/lib/validation/rules/maxTotalFileSize.ts +11 -12
  15. package/lib/validation/rules/maxValue.ts +12 -8
  16. package/lib/validation/rules/minLength.ts +12 -7
  17. package/lib/validation/rules/minValue.ts +12 -8
  18. package/lib/validation/rules/month.ts +12 -8
  19. package/lib/validation/rules/negativeInteger.ts +10 -5
  20. package/lib/validation/rules/positiveInteger.ts +10 -5
  21. package/lib/validation/rules/required.ts +1 -1
  22. package/lib/validation/rules/requiredHms.ts +10 -8
  23. package/lib/validation/rules/requiredIf.ts +12 -6
  24. package/lib/validation/rules/requiredYmd.ts +11 -8
  25. package/lib/validation/rules/rule.ts +12 -6
  26. package/lib/validation/rules/url.ts +11 -5
  27. package/lib/validation/rules/ymd.ts +11 -8
  28. package/lib/validation/rules/zeroOrNegativeInteger.ts +11 -6
  29. package/lib/validation/rules/zeroOrPositiveInteger.ts +11 -6
  30. package/lib/validation/validators/checked.ts +1 -1
  31. package/lib/validation/validators/decimal.ts +11 -0
  32. package/lib/validation/validators/email.ts +12 -0
  33. package/lib/validation/validators/fileExtension.ts +7 -2
  34. package/lib/validation/validators/hms.ts +8 -12
  35. package/lib/validation/validators/hyphen.ts +1 -1
  36. package/lib/validation/validators/index.ts +8 -0
  37. package/lib/validation/validators/maxFileSize.ts +9 -2
  38. package/lib/validation/validators/maxLength.ts +9 -0
  39. package/lib/validation/validators/maxTotalFileSize.ts +12 -2
  40. package/lib/validation/validators/maxValue.ts +7 -0
  41. package/lib/validation/validators/minLength.ts +9 -0
  42. package/lib/validation/validators/minValue.ts +7 -0
  43. package/lib/validation/validators/month.ts +7 -1
  44. package/lib/validation/validators/negativeInteger.ts +7 -1
  45. package/lib/validation/validators/positiveInteger.ts +7 -1
  46. package/lib/validation/validators/requiredHms.ts +6 -10
  47. package/lib/validation/validators/requiredIf.ts +19 -0
  48. package/lib/validation/validators/requiredYmd.ts +6 -10
  49. package/lib/validation/validators/url.ts +11 -0
  50. package/lib/validation/validators/ymd.ts +11 -15
  51. package/lib/validation/validators/zero.ts +1 -1
  52. package/package.json +1 -1
@@ -1,12 +1,12 @@
1
1
  <script setup lang="ts">
2
2
  import IconCaretDown from '@iconify-icons/ph/caret-down-bold'
3
+ import { computed, ref } from 'vue'
3
4
  import {
4
5
  type DropdownSection,
5
6
  getSelectedOption,
6
7
  useManualDropdownPosition
7
- } from 'sefirot/composables/Dropdown'
8
- import { useFlyout } from 'sefirot/composables/Flyout'
9
- import { computed, ref } from 'vue'
8
+ } from '../composables/Dropdown'
9
+ import { useFlyout } from '../composables/Flyout'
10
10
  import { isString } from '../support/Utils'
11
11
  import SDropdown from './SDropdown.vue'
12
12
  import SIcon from './SIcon.vue'
@@ -1,7 +1,7 @@
1
1
  <script setup lang="ts">
2
- import { format } from 'sefirot/support/Num'
3
2
  import { computed } from 'vue'
4
3
  import { type TableCellValueColor } from '../composables/Table'
4
+ import { format } from '../support/Num'
5
5
  import SIcon from './SIcon.vue'
6
6
  import SLink from './SLink.vue'
7
7
 
package/lib/http/Http.ts CHANGED
@@ -140,25 +140,23 @@ export class Http {
140
140
  const fd = form || new FormData()
141
141
  let formKey: string
142
142
 
143
- for (const property in obj) {
144
- if (Reflect.has(obj, property)) {
145
- if (namespace) {
146
- formKey = `${namespace}[${property}]`
147
- } else {
148
- formKey = property
149
- }
143
+ Object.keys(obj).forEach((property) => {
144
+ if (namespace) {
145
+ formKey = `${namespace}[${property}]`
146
+ } else {
147
+ formKey = property
148
+ }
150
149
 
151
- if (obj[property] === undefined) {
152
- continue
153
- }
150
+ if (obj[property] === undefined) {
151
+ return
152
+ }
154
153
 
155
- if (typeof obj[property] === 'object' && !(obj[property] instanceof Blob)) {
156
- this.objectToFormData(obj[property], fd, property)
157
- } else {
158
- fd.append(formKey, obj[property])
159
- }
154
+ if (typeof obj[property] === 'object' && !(obj[property] instanceof Blob)) {
155
+ this.objectToFormData(obj[property], fd, property)
156
+ } else {
157
+ fd.append(formKey, obj[property])
160
158
  }
161
- }
159
+ })
162
160
 
163
161
  return fd
164
162
  }
@@ -2,6 +2,7 @@ import dayjs, { type ConfigType, type Dayjs } from 'dayjs'
2
2
  import PluginRelativeTime from 'dayjs/plugin/relativeTime'
3
3
  import PluginTimezone from 'dayjs/plugin/timezone'
4
4
  import PluginUtc from 'dayjs/plugin/utc'
5
+ import { isNumber, isObject, isString } from './Utils'
5
6
 
6
7
  dayjs.extend(PluginUtc)
7
8
  dayjs.extend(PluginTimezone)
@@ -19,6 +20,14 @@ export interface Ymd {
19
20
  date: number | null
20
21
  }
21
22
 
23
+ export type YmdType = 'y' | 'm' | 'd'
24
+
25
+ export const YmdMap = {
26
+ y: 'year',
27
+ m: 'month',
28
+ d: 'date'
29
+ } as const
30
+
22
31
  /**
23
32
  * The hour, minute, and second object interface.
24
33
  */
@@ -28,6 +37,14 @@ export interface Hms {
28
37
  second: string | null
29
38
  }
30
39
 
40
+ export type HmsType = 'h' | 'm' | 's'
41
+
42
+ export const HmsMap = {
43
+ h: 'hour',
44
+ m: 'minute',
45
+ s: 'second'
46
+ } as const
47
+
31
48
  export function day(input?: Input): Day {
32
49
  return dayjs(input)
33
50
  }
@@ -69,3 +86,29 @@ export function createHms(
69
86
  second
70
87
  }
71
88
  }
89
+
90
+ export function isYmd(value: unknown, required: YmdType[] = ['y', 'm', 'd']): value is Ymd {
91
+ if (!isObject(value)) {
92
+ return false
93
+ }
94
+
95
+ return required
96
+ .reduce<string[]>((keys, type) => {
97
+ keys.push(YmdMap[type])
98
+ return keys
99
+ }, [])
100
+ .every((key) => value[key] === null || isNumber(value[key]))
101
+ }
102
+
103
+ export function isHms(value: unknown, required: HmsType[] = ['h', 'm', 's']): value is Hms {
104
+ if (!isObject(value)) {
105
+ return false
106
+ }
107
+
108
+ return required
109
+ .reduce<string[]>((keys, type) => {
110
+ keys.push(HmsMap[type])
111
+ return keys
112
+ }, [])
113
+ .every((key) => value[key] === null || isString(value[key]))
114
+ }
@@ -5,7 +5,7 @@ import { type Lang, useLang } from '../composables/Lang'
5
5
  export interface RuleOptions {
6
6
  optional?: boolean
7
7
  message(params: MessageProps): string
8
- validation(value: unknown): boolean
8
+ validation(value: unknown): boolean | Promise<boolean>
9
9
  }
10
10
 
11
11
  export interface MessageProps extends VMessageProps {
@@ -1,9 +1,15 @@
1
- import { helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
2
  import { checked as baseChecked } from '../validators/checked'
3
3
 
4
+ export const message = {
5
+ en: 'You must check the field.',
6
+ ja: 'この項目は選択が必須です。'
7
+ }
8
+
4
9
  export function checked(msg?: string) {
5
- return helpers.withMessage(
6
- () => msg ?? 'You must check the field.',
7
- (value: boolean) => !helpers.req(value) || baseChecked(value)
8
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ optional: true,
13
+ validation: baseChecked
14
+ })
9
15
  }
@@ -1,9 +1,14 @@
1
- import { and, decimal as baseDecimal, helpers, not } from '@vuelidate/validators'
2
- import { hyphen } from '../validators'
1
+ import { createRule } from '../Rule'
2
+ import { decimal as baseDecimal, hyphen } from '../validators'
3
+
4
+ export const message = {
5
+ en: 'The value must be valid decimal numbers.',
6
+ ja: 'この値は小数または10進数である必要があります。'
7
+ }
3
8
 
4
9
  export function decimal(msg?: string) {
5
- return helpers.withMessage(
6
- () => msg ?? 'The value must be valid decimal numbers.',
7
- and(not(hyphen), baseDecimal)
8
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ validation: (value) => !hyphen(value) && baseDecimal(value)
13
+ })
9
14
  }
@@ -1,8 +1,14 @@
1
- import { decimal as baseDecimal, helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
+ import { decimal as baseDecimal, hyphen } from '../validators'
3
+
4
+ export const message = {
5
+ en: 'The value must be valid decimal numbers or just a hyphen.',
6
+ ja: 'この値は小数、10進数、またはハイフンである必要があります。'
7
+ }
2
8
 
3
9
  export function decimalOrHyphen(msg?: string) {
4
- return helpers.withMessage(
5
- () => msg ?? 'The value must be valid decimal numbers or just a hyphen.',
6
- baseDecimal
7
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ validation: (value) => hyphen(value) || baseDecimal(value)
13
+ })
8
14
  }
@@ -1,8 +1,14 @@
1
- import { email as baseEmail, helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
+ import { email as baseEmail } from '../validators'
3
+
4
+ export const message = {
5
+ en: 'The Email is invalid.',
6
+ ja: 'Emailの形式が正しくありません。'
7
+ }
2
8
 
3
9
  export function email(msg?: string) {
4
- return helpers.withMessage(
5
- () => msg ?? 'The Email is invalid.',
6
- baseEmail
7
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ validation: baseEmail
13
+ })
8
14
  }
@@ -1,11 +1,15 @@
1
- import { helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
2
  import { fileExtension as baseFileExtension } from '../validators/fileExtension'
3
3
 
4
+ export const message = {
5
+ en: 'The file extension is invalid.',
6
+ ja: 'ファイル拡張子が正しくありません。'
7
+ }
8
+
4
9
  export function fileExtension(extensions: string[], msg?: string) {
5
- return helpers.withMessage(
6
- () => msg ?? 'The file extension is invalid.',
7
- (value: File) => {
8
- return !helpers.req(value) || baseFileExtension(value, extensions)
9
- }
10
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ optional: true,
13
+ validation: (value) => baseFileExtension(value, extensions)
14
+ })
11
15
  }
@@ -1,14 +1,17 @@
1
- import { helpers } from '@vuelidate/validators'
2
- import { type Hms } from '../../support/Day'
1
+ import { createRule } from '../Rule'
3
2
  import { hms as baseHms } from '../validators/hms'
4
3
 
5
4
  type HmsType = 'h' | 'm' | 's'
6
5
 
6
+ export const message = {
7
+ en: 'The time is invalid.',
8
+ ja: '時間表記が正しくありません。'
9
+ }
10
+
7
11
  export function hms(required?: HmsType[], msg?: string) {
8
- return helpers.withMessage(
9
- () => msg ?? 'The time is invalid.',
10
- (value: Hms) => {
11
- return !helpers.req(value) || baseHms(value, required)
12
- }
13
- )
12
+ return createRule({
13
+ message: ({ lang }) => msg ?? message[lang],
14
+ optional: true,
15
+ validation: (value) => baseHms(value, required)
16
+ })
14
17
  }
@@ -1,16 +1,15 @@
1
- import { helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
2
  import { maxFileSize as baseMaxFileSize } from '../validators/maxFileSize'
3
3
 
4
+ export const message = {
5
+ en: (size: string) => `The file must be smaller than or equal to ${size}.`,
6
+ ja: (size: string) => `ファイルは${size}よりも小さい必要があります。`
7
+ }
8
+
4
9
  export function maxFileSize(size: string, msg?: string) {
5
- return helpers.withParams(
6
- { size },
7
- helpers.withMessage(
8
- ({ $params }) => {
9
- return msg ?? `The file must be smaller than ${$params.size}.`
10
- },
11
- (value: File) => {
12
- return !helpers.req(value) || baseMaxFileSize(value, size)
13
- }
14
- )
15
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang](size),
12
+ optional: true,
13
+ validation: (value) => baseMaxFileSize(value, size)
14
+ })
16
15
  }
@@ -1,10 +1,15 @@
1
- import { maxLength as baseMaxLength, helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
+ import { maxLength as baseMaxLength } from '../validators'
3
+
4
+ export const message = {
5
+ en: (length: number) => `The value must be less than or equal to ${length} characters.`,
6
+ ja: (length: number) => `この値は、最大${length}文字までです。`
7
+ }
2
8
 
3
9
  export function maxLength(length: number, msg?: string) {
4
- return helpers.withMessage(
5
- ({ $params }) => {
6
- return msg ?? `The value must be less or equal to ${($params as any).max} characters.`
7
- },
8
- baseMaxLength(length)
9
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang](length),
12
+ optional: true,
13
+ validation: (value) => baseMaxLength(value, length)
14
+ })
10
15
  }
@@ -1,16 +1,15 @@
1
- import { helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
2
  import { maxTotalFileSize as baseMaxTotalFileSize } from '../validators/maxTotalFileSize'
3
3
 
4
+ export const message = {
5
+ en: (size: string) => `The total file size must be smaller than or equal to ${size}.`,
6
+ ja: (size: string) => `合計ファイルサイズは最大${size}までです。`
7
+ }
8
+
4
9
  export function maxTotalFileSize(size: string, msg?: string) {
5
- return helpers.withParams(
6
- { size },
7
- helpers.withMessage(
8
- ({ $params }) => {
9
- return msg ?? `The total file size must be smaller than ${$params.size}.`
10
- },
11
- (files: File[]) => {
12
- return !helpers.req(files) || baseMaxTotalFileSize(files, size)
13
- }
14
- )
15
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang](size),
12
+ optional: true,
13
+ validation: (value) => baseMaxTotalFileSize(value, size)
14
+ })
16
15
  }
@@ -1,10 +1,14 @@
1
- import { maxValue as baseMaxValue, helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
+ import { maxValue as baseMaxValue } from '../validators'
2
3
 
3
- export function maxValue(value: number, msg?: string) {
4
- return helpers.withMessage(
5
- ({ $params }) => {
6
- return msg ?? `The value must be less or equal to ${($params as any).max}.`
7
- },
8
- baseMaxValue(value)
9
- )
4
+ export const message = {
5
+ en: (max: number) => `The value must be less than or equal to ${max}.`,
6
+ ja: (max: number) => `この値は最大${max}です。`
7
+ }
8
+
9
+ export function maxValue(max: number, msg?: string) {
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang](max),
12
+ validation: (value) => baseMaxValue(value, max)
13
+ })
10
14
  }
@@ -1,10 +1,15 @@
1
- import { minLength as baseMinLength, helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
+ import { minLength as baseMinLength } from '../validators'
3
+
4
+ export const message = {
5
+ en: (min: number) => `The value must be greater than or equal to ${min} characters.`,
6
+ ja: (min: number) => `この値は最小${min}文字です。`
7
+ }
2
8
 
3
9
  export function minLength(length: number, msg?: string) {
4
- return helpers.withMessage(
5
- ({ $params }) => {
6
- return msg ?? `The value must be greater or equal to ${($params as any).min} characters.`
7
- },
8
- baseMinLength(length)
9
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang](length),
12
+ optional: true,
13
+ validation: (value) => baseMinLength(value, length)
14
+ })
10
15
  }
@@ -1,10 +1,14 @@
1
- import { minValue as baseMinValue, helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
+ import { minValue as baseMinValue } from '../validators'
2
3
 
3
- export function minValue(value: number, msg?: string) {
4
- return helpers.withMessage(
5
- ({ $params }) => {
6
- return msg ?? `The value must be greater or equal to ${($params as any).min}.`
7
- },
8
- baseMinValue(value)
9
- )
4
+ export const message = {
5
+ en: (min: number) => `The value must be greater than or equal to ${min}.`,
6
+ ja: (min: number) => `この値は最大${min}です。`
7
+ }
8
+
9
+ export function minValue(min: number, msg?: string) {
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang](min),
12
+ validation: (value) => baseMinValue(value, min)
13
+ })
10
14
  }
@@ -1,11 +1,15 @@
1
- import { helpers } from '@vuelidate/validators'
2
- import { month as baseMonth } from '../validators/month'
1
+ import { createRule } from '../Rule'
2
+ import { month as baseMonth } from '../validators'
3
+
4
+ export const message = {
5
+ en: 'The month is invalid.',
6
+ ja: '月が正しくありません。'
7
+ }
3
8
 
4
9
  export function month(msg?: string) {
5
- return helpers.withMessage(
6
- () => msg ?? 'The month is invalid.',
7
- (value: number) => {
8
- return !helpers.req(value) || baseMonth(value)
9
- }
10
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ optional: true,
13
+ validation: baseMonth
14
+ })
11
15
  }
@@ -1,9 +1,14 @@
1
- import { helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
2
  import { negativeInteger as baseNegativeInteger } from '../validators'
3
3
 
4
+ export const message = {
5
+ en: 'The value must be valid negative integer.',
6
+ ja: 'この値は負の整数である必要があります。'
7
+ }
8
+
4
9
  export function negativeInteger(msg?: string) {
5
- return helpers.withMessage(
6
- () => msg ?? 'The value must be valid negative integer.',
7
- baseNegativeInteger
8
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ validation: baseNegativeInteger
13
+ })
9
14
  }
@@ -1,9 +1,14 @@
1
- import { helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
2
  import { positiveInteger as basePositiveInteger } from '../validators'
3
3
 
4
+ export const message = {
5
+ en: 'The value must be valid positive integer.',
6
+ ja: 'この値は正の整数である必要があります。'
7
+ }
8
+
4
9
  export function positiveInteger(msg?: string) {
5
- return helpers.withMessage(
6
- () => msg ?? 'The value must be valid positive integer.',
7
- basePositiveInteger
8
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ validation: basePositiveInteger
13
+ })
9
14
  }
@@ -9,6 +9,6 @@ export const message = {
9
9
  export function required(msg?: string) {
10
10
  return createRule({
11
11
  message: ({ lang }) => msg ?? message[lang],
12
- validation: (value) => baseRequired(value)
12
+ validation: baseRequired
13
13
  })
14
14
  }
@@ -1,14 +1,16 @@
1
- import { helpers } from '@vuelidate/validators'
2
- import { type Hms } from '../../support/Day'
1
+ import { createRule } from '../Rule'
3
2
  import { requiredHms as baseRequiredHms } from '../validators/requiredHms'
4
3
 
5
4
  type HmsType = 'h' | 'm' | 's'
6
5
 
6
+ export const message = {
7
+ en: 'The field is required.',
8
+ ja: 'この項目は必須です。'
9
+ }
10
+
7
11
  export function requiredHms(required?: HmsType[], msg?: string) {
8
- return helpers.withMessage(
9
- () => msg ?? 'The field is required.',
10
- (value: Hms) => {
11
- return !helpers.req(value) || baseRequiredHms(value, required)
12
- }
13
- )
12
+ return createRule({
13
+ message: ({ lang }) => msg ?? message[lang],
14
+ validation: (value) => baseRequiredHms(value, required)
15
+ })
14
16
  }
@@ -1,11 +1,17 @@
1
- import { requiredIf as baseRequiredIf, helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
+ import { type RequiredIfCondition, requiredIf as baseRequiredIf } from '../validators'
3
+
4
+ export const message = {
5
+ en: 'The field is required.',
6
+ ja: 'この項目は必須です。'
7
+ }
2
8
 
3
9
  export function requiredIf(
4
- prop: boolean | string | (() => boolean | Promise<boolean>),
10
+ condition: RequiredIfCondition,
5
11
  msg?: string
6
12
  ) {
7
- return helpers.withMessage(
8
- () => msg ?? 'The field is required.',
9
- baseRequiredIf(prop)
10
- )
13
+ return createRule({
14
+ message: ({ lang }) => msg ?? message[lang],
15
+ validation: (value) => baseRequiredIf(value, condition)
16
+ })
11
17
  }
@@ -1,14 +1,17 @@
1
- import { helpers } from '@vuelidate/validators'
2
- import { type Ymd } from '../../support/Day'
1
+ import { createRule } from '../Rule'
3
2
  import { requiredYmd as baseRequiredYmd } from '../validators/requiredYmd'
4
3
 
5
4
  type YmdType = 'y' | 'm' | 'd'
6
5
 
6
+ export const message = {
7
+ en: 'The field is required.',
8
+ ja: 'この項目は必須です。'
9
+ }
10
+
7
11
  export function requiredYmd(required?: YmdType[], msg?: string) {
8
- return helpers.withMessage(
9
- () => msg ?? 'The field is required.',
10
- (value: Ymd) => {
11
- return !helpers.req(value) || baseRequiredYmd(value, required)
12
- }
13
- )
12
+ return createRule({
13
+ message: ({ lang }) => msg ?? message[lang],
14
+ optional: true,
15
+ validation: (value) => baseRequiredYmd(value, required)
16
+ })
14
17
  }
@@ -1,8 +1,14 @@
1
- import { helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
2
 
3
- export function rule(validation: (value: any) => boolean, msg?: string) {
4
- return helpers.withMessage(
5
- () => msg ?? 'The value is invalid.',
6
- (value: any) => !helpers.req(value) || validation(value)
7
- )
3
+ export const message = {
4
+ en: 'The value is invalid.',
5
+ ja: 'この値は正しくありません。'
6
+ }
7
+
8
+ export function rule(validation: (value: unknown) => boolean, msg?: string) {
9
+ return createRule({
10
+ message: ({ lang }) => msg ?? message[lang],
11
+ optional: true,
12
+ validation: (value) => validation(value)
13
+ })
8
14
  }
@@ -1,8 +1,14 @@
1
- import { url as baseUrl, helpers } from '@vuelidate/validators'
1
+ import { createRule } from '../Rule'
2
+ import { url as baseUrl } from '../validators'
3
+
4
+ export const message = {
5
+ en: 'The URL is invalid.',
6
+ ja: 'URLの形式が正しくありません。'
7
+ }
2
8
 
3
9
  export function url(msg?: string) {
4
- return helpers.withMessage(
5
- () => msg ?? 'The URL is invalid.',
6
- baseUrl
7
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ validation: baseUrl
13
+ })
8
14
  }
@@ -1,14 +1,17 @@
1
- import { helpers } from '@vuelidate/validators'
2
- import { type Ymd } from '../../support/Day'
1
+ import { createRule } from '../Rule'
3
2
  import { ymd as baseYmd } from '../validators/ymd'
4
3
 
5
4
  type YmdType = 'y' | 'm' | 'd'
6
5
 
6
+ export const message = {
7
+ en: 'The field is required.',
8
+ ja: 'この項目は必須です。'
9
+ }
10
+
7
11
  export function ymd(required?: YmdType[], msg?: string) {
8
- return helpers.withMessage(
9
- () => msg ?? 'The date is invalid.',
10
- (value: Ymd) => {
11
- return !helpers.req(value) || baseYmd(value, required)
12
- }
13
- )
12
+ return createRule({
13
+ message: ({ lang }) => msg ?? message[lang],
14
+ optional: true,
15
+ validation: (value) => baseYmd(value, required)
16
+ })
14
17
  }
@@ -1,9 +1,14 @@
1
- import { helpers, or } from '@vuelidate/validators'
2
- import { negativeInteger, zero } from '../validators'
1
+ import { createRule } from '../Rule'
2
+ import { negativeInteger as baseNegativeInteger, zero } from '../validators'
3
+
4
+ export const message = {
5
+ en: 'The value must be zero or valid negative integer.',
6
+ ja: 'この値はゼロまたは負の整数である必要があります。'
7
+ }
3
8
 
4
9
  export function zeroOrNegativeInteger(msg?: string) {
5
- return helpers.withMessage(
6
- () => msg ?? 'The value must be zero or valid negative integer.',
7
- or(zero, negativeInteger)
8
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ validation: (value) => zero(value) || baseNegativeInteger(value)
13
+ })
9
14
  }
@@ -1,9 +1,14 @@
1
- import { helpers, or } from '@vuelidate/validators'
2
- import { positiveInteger, zero } from '../validators'
1
+ import { createRule } from '../Rule'
2
+ import { positiveInteger as basePositiveInteger, zero } from '../validators'
3
+
4
+ export const message = {
5
+ en: 'The value must be zero or valid positive integer.',
6
+ ja: 'この値はゼロまたは正の整数である必要があります。'
7
+ }
3
8
 
4
9
  export function zeroOrPositiveInteger(msg?: string) {
5
- return helpers.withMessage(
6
- () => msg ?? 'The value must be zero or valid positive integer.',
7
- or(zero, positiveInteger)
8
- )
10
+ return createRule({
11
+ message: ({ lang }) => msg ?? message[lang],
12
+ validation: (value) => zero(value) || basePositiveInteger(value)
13
+ })
9
14
  }
@@ -1,3 +1,3 @@
1
- export function checked(value: boolean): boolean {
1
+ export function checked(value: unknown): boolean {
2
2
  return value === true
3
3
  }
@@ -0,0 +1,11 @@
1
+ import { isNumber, isString } from '../../support/Utils'
2
+
3
+ const regExp = /^[-]?\d*(\.\d+)?$/
4
+
5
+ export function decimal(value: unknown): boolean {
6
+ if (!(isString(value) || isNumber(value))) {
7
+ return false
8
+ }
9
+
10
+ return regExp.test(String(value))
11
+ }
@@ -0,0 +1,12 @@
1
+ import { isString } from '../../support/Utils'
2
+
3
+ /* eslint-disable-next-line no-control-regex */
4
+ const regExp = /^(?:[A-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21\x23-\x5B\x5D-\x7F]|[\x01-\x09\x0B\x0C\x0E-\x7F])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]{2,}(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0B\x0C\x0E-\x1F\x21-\x5A\x53-\x7F]|\\[\x01-\x09\x0B\x0C\x0E-\x7F])+)\])$/i
5
+
6
+ export function email(value: string): boolean {
7
+ if (!isString(value)) {
8
+ return false
9
+ }
10
+
11
+ return regExp.test(value)
12
+ }
@@ -1,7 +1,12 @@
1
1
  import { getExtension } from '../../support/File'
2
+ import { isFile } from '../../support/Utils'
2
3
 
3
- export function fileExtension(file: File, extensions: string[]): boolean {
4
- const fileExtension = getExtension(file)
4
+ export function fileExtension(value: unknown, extensions: string[]): boolean {
5
+ if (!isFile(value)) {
6
+ return false
7
+ }
8
+
9
+ const fileExtension = getExtension(value)
5
10
 
6
11
  return extensions.some((extension) => {
7
12
  // If the extention option is `jpg`, we'll consider other variants such as
@@ -1,22 +1,18 @@
1
- import { type Hms } from '../../support/Day'
1
+ import { HmsMap, type HmsType, isHms } from '../../support/Day'
2
2
 
3
- type HmsType = 'h' | 'm' | 's'
3
+ export function hms(value: unknown, required: HmsType[] = ['h', 'm', 's']): boolean {
4
+ if (!isHms(value, required)) {
5
+ return false
6
+ }
4
7
 
5
- const HmsMap = {
6
- h: 'hour',
7
- m: 'minute',
8
- s: 'second'
9
- } as const
10
-
11
- export function hms(hms: Hms, required: HmsType[] = ['h', 'm', 's']): boolean {
12
8
  return required.every((r) => {
13
- const value = hms[HmsMap[r]]
9
+ const _value = value[HmsMap[r]]
14
10
 
15
- if (value === null) {
11
+ if (_value === null) {
16
12
  return true
17
13
  }
18
14
 
19
- const valueAsNumber = Number(value)
15
+ const valueAsNumber = Number(_value)
20
16
 
21
17
  return (r === 'h')
22
18
  ? (valueAsNumber >= 0 && valueAsNumber < 24)
@@ -1,3 +1,3 @@
1
- export function hyphen(value: string): boolean {
1
+ export function hyphen(value: unknown): boolean {
2
2
  return value === '-'
3
3
  }
@@ -1,14 +1,22 @@
1
1
  export * from './checked'
2
+ export * from './decimal'
3
+ export * from './email'
2
4
  export * from './fileExtension'
3
5
  export * from './hms'
4
6
  export * from './hyphen'
5
7
  export * from './maxFileSize'
8
+ export * from './maxLength'
6
9
  export * from './maxTotalFileSize'
10
+ export * from './maxValue'
11
+ export * from './minLength'
12
+ export * from './minValue'
7
13
  export * from './month'
8
14
  export * from './negativeInteger'
9
15
  export * from './positiveInteger'
10
16
  export * from './required'
11
17
  export * from './requiredHms'
18
+ export * from './requiredIf'
12
19
  export * from './requiredYmd'
20
+ export * from './url'
13
21
  export * from './ymd'
14
22
  export * from './zero'
@@ -1,4 +1,10 @@
1
- export function maxFileSize(file: File, size: string): boolean {
1
+ import { isFile } from '../../support/Utils'
2
+
3
+ export function maxFileSize(value: unknown, size: string): boolean {
4
+ if (!isFile(value)) {
5
+ return false
6
+ }
7
+
2
8
  const factor = /gb/i.test(size)
3
9
  ? 1e9
4
10
  : /mb/i.test(size)
@@ -6,5 +12,6 @@ export function maxFileSize(file: File, size: string): boolean {
6
12
  : /kb/i.test(size)
7
13
  ? 1e3
8
14
  : 1
9
- return file.size <= factor * +size.replace(/[^\d\.]/g, '')
15
+
16
+ return value.size <= factor * +size.replace(/[^\d\.]/g, '')
10
17
  }
@@ -0,0 +1,9 @@
1
+ import { isArray, isString } from '../../support/Utils'
2
+
3
+ export function maxLength(value: unknown, length: number): boolean {
4
+ if (!(isString(value) || isArray(value))) {
5
+ return false
6
+ }
7
+
8
+ return value.length <= length
9
+ }
@@ -1,8 +1,14 @@
1
+ import { isFile } from '../../support/Utils'
2
+
1
3
  /**
2
4
  * Validates if the total size of the given files is smaller than the
3
5
  * given size.
4
6
  */
5
- export function maxTotalFileSize(files: File[], size: string): boolean {
7
+ export function maxTotalFileSize(value: unknown, size: string): boolean {
8
+ if (!isArrayOfFiles(value)) {
9
+ return false
10
+ }
11
+
6
12
  const factor = /gb/i.test(size)
7
13
  ? 1e9
8
14
  : /mb/i.test(size)
@@ -11,7 +17,11 @@ export function maxTotalFileSize(files: File[], size: string): boolean {
11
17
  ? 1e3
12
18
  : 1
13
19
 
14
- const total = files.reduce((total, file) => total + file.size, 0)
20
+ const total = value.reduce((total, file) => total + file.size, 0)
15
21
 
16
22
  return total <= factor * +size.replace(/[^\d\.]/g, '')
17
23
  }
24
+
25
+ function isArrayOfFiles(value: unknown): value is File[] {
26
+ return Array.isArray(value) && value.every((v) => isFile(v))
27
+ }
@@ -0,0 +1,7 @@
1
+ export function maxValue(value: unknown, max: number) {
2
+ if (typeof value === 'string' || value instanceof Date) {
3
+ return +value <= max
4
+ }
5
+
6
+ return false
7
+ }
@@ -0,0 +1,9 @@
1
+ import { isArray, isString } from '../../support/Utils'
2
+
3
+ export function minLength(value: unknown, length: number): boolean {
4
+ if (!(isString(value) || isArray(value))) {
5
+ return false
6
+ }
7
+
8
+ return value.length >= length
9
+ }
@@ -0,0 +1,7 @@
1
+ export function minValue(value: unknown, min: number) {
2
+ if (typeof value === 'string' || value instanceof Date) {
3
+ return +value >= min
4
+ }
5
+
6
+ return false
7
+ }
@@ -1,3 +1,9 @@
1
- export function month(value: number): boolean {
1
+ import { isNumber } from '../../support/Utils'
2
+
3
+ export function month(value: unknown): boolean {
4
+ if (!isNumber(value)) {
5
+ return false
6
+ }
7
+
2
8
  return value > 0 && value < 13
3
9
  }
@@ -1,3 +1,9 @@
1
- export function negativeInteger(value: number): boolean {
1
+ import { isNumber } from '../../support/Utils'
2
+
3
+ export function negativeInteger(value: unknown): boolean {
4
+ if (!isNumber(value)) {
5
+ return false
6
+ }
7
+
2
8
  return Number.isInteger(value) && value < 0
3
9
  }
@@ -1,3 +1,9 @@
1
- export function positiveInteger(value: number): boolean {
1
+ import { isNumber } from '../../support/Utils'
2
+
3
+ export function positiveInteger(value: unknown): boolean {
4
+ if (!isNumber(value)) {
5
+ return false
6
+ }
7
+
2
8
  return Number.isInteger(value) && value > 0
3
9
  }
@@ -1,13 +1,9 @@
1
- import { type Hms } from '../../support/Day'
1
+ import { HmsMap, type HmsType, isHms } from '../../support/Day'
2
2
 
3
- type HmsType = 'h' | 'm' | 's'
3
+ export function requiredHms(value: unknown, required: HmsType[] = ['h', 'm', 's']): boolean {
4
+ if (!isHms(value, required)) {
5
+ return false
6
+ }
4
7
 
5
- const HmsMap = {
6
- h: 'hour',
7
- m: 'minute',
8
- s: 'second'
9
- } as const
10
-
11
- export function requiredHms(hms: Hms, required: HmsType[] = ['h', 'm', 's']): boolean {
12
- return required.every((r) => hms[HmsMap[r]] != null)
8
+ return required.every((r) => value[HmsMap[r]] != null)
13
9
  }
@@ -0,0 +1,19 @@
1
+ import { required } from './required'
2
+
3
+ export type RequiredIfCondition = boolean | string | (() => boolean) | (() => Promise<boolean>)
4
+
5
+ export async function requiredIf(value: unknown, condition: RequiredIfCondition): Promise<boolean> {
6
+ if (typeof condition === 'boolean' && condition) {
7
+ return required(value)
8
+ }
9
+
10
+ if (typeof condition === 'string' && condition) {
11
+ return required(value)
12
+ }
13
+
14
+ if (typeof condition === 'function' && (await condition())) {
15
+ return required(value)
16
+ }
17
+
18
+ return true
19
+ }
@@ -1,13 +1,9 @@
1
- import { type Ymd } from '../../support/Day'
1
+ import { YmdMap, type YmdType, isYmd } from '../../support/Day'
2
2
 
3
- type YmdType = 'y' | 'm' | 'd'
3
+ export function requiredYmd(value: unknown, required: YmdType[] = ['y', 'm', 'd']): boolean {
4
+ if (!isYmd(value, required)) {
5
+ return false
6
+ }
4
7
 
5
- const YmdMap = {
6
- y: 'year',
7
- m: 'month',
8
- d: 'date'
9
- } as const
10
-
11
- export function requiredYmd(ymd: Ymd, required: YmdType[] = ['y', 'm', 'd']): boolean {
12
- return required.every((r) => ymd[YmdMap[r]] != null)
8
+ return required.every((r) => value[YmdMap[r]] != null)
13
9
  }
@@ -0,0 +1,11 @@
1
+ import { isString } from '../../support/Utils'
2
+
3
+ const regExp = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00A1-\uFFFF][a-z0-9\u00A1-\uFFFF_-]{0,62})?[a-z0-9\u00A1-\uFFFF]\.)+(?:[a-z\u00A1-\uFFFF]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i
4
+
5
+ export function url(value: unknown): boolean {
6
+ if (!isString(value)) {
7
+ return false
8
+ }
9
+
10
+ return regExp.test(value)
11
+ }
@@ -1,33 +1,29 @@
1
1
  import day from 'dayjs'
2
- import { type Ymd } from '../../support/Day'
2
+ import { YmdMap, type YmdType, isYmd } from '../../support/Day'
3
3
 
4
- type YmdType = 'y' | 'm' | 'd'
4
+ export function ymd(value: unknown, required: YmdType[] = ['y', 'm', 'd']): boolean {
5
+ if (!isYmd(value, required)) {
6
+ return false
7
+ }
5
8
 
6
- const YmdMap = {
7
- y: 'year',
8
- m: 'month',
9
- d: 'date'
10
- } as const
11
-
12
- export function ymd(ymd: Ymd, required: YmdType[] = ['y', 'm', 'd']): boolean {
13
9
  return required.every((r) => {
14
- const value = ymd[YmdMap[r]]
10
+ const _value = value[YmdMap[r]]
15
11
 
16
- if (value === null) {
12
+ if (_value === null) {
17
13
  return true
18
14
  }
19
15
 
20
16
  if (r === 'y') {
21
- return value > 0 && value <= 9999
17
+ return _value > 0 && _value <= 9999
22
18
  }
23
19
 
24
20
  if (r === 'm') {
25
- return value > 0 && value <= 12
21
+ return _value > 0 && _value <= 12
26
22
  }
27
23
 
28
- const d = day(new Date(2020, ymd.month ? ymd.month - 1 : 1, value))
24
+ const d = day(new Date(2020, value.month ? value.month - 1 : 1, _value))
29
25
 
30
- if (d.month() + 1 !== (ymd.month ?? 1)) {
26
+ if (d.month() + 1 !== (value.month ?? 1)) {
31
27
  return false
32
28
  }
33
29
 
@@ -1,3 +1,3 @@
1
- export function zero(value: number): boolean {
1
+ export function zero(value: unknown): boolean {
2
2
  return value === 0
3
3
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@globalbrain/sefirot",
3
- "version": "3.23.0",
3
+ "version": "3.24.0",
4
4
  "packageManager": "pnpm@8.14.1",
5
5
  "description": "Vue Components for Global Brain Design System.",
6
6
  "author": "Kia Ishii <ka.ishii@globalbrains.com>",