@globalbrain/sefirot 3.35.3 → 3.37.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.
- package/lib/composables/Policy.ts +26 -0
- package/lib/composables/V.ts +37 -13
- package/lib/validation/rules/index.ts +1 -0
- package/lib/validation/rules/slackChannelName.ts +15 -0
- package/lib/validation/validators/index.ts +1 -0
- package/lib/validation/validators/slackChannelName.ts +16 -0
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ComputedRef, computed } from 'vue'
|
|
2
|
+
|
|
3
|
+
export type Policy<Code extends string | undefined = undefined> = ComputedRef<PolicyResponse<Code>>
|
|
4
|
+
|
|
5
|
+
export interface PolicyResponse<Code extends string | undefined = undefined> {
|
|
6
|
+
ok: boolean | null
|
|
7
|
+
code?: Code
|
|
8
|
+
message?: string
|
|
9
|
+
is(code: Code): boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface PolicyHelpers<Code extends string | undefined = undefined> {
|
|
13
|
+
allow: (code?: Code, message?: string) => PolicyResponse<Code>
|
|
14
|
+
deny: (code?: Code, message?: string) => PolicyResponse<Code>
|
|
15
|
+
pending: (code?: Code, message?: string) => PolicyResponse<Code>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function usePolicy<Code extends string | undefined = undefined>(
|
|
19
|
+
fn: (helpers: PolicyHelpers<Code>) => PolicyResponse<Code>
|
|
20
|
+
): Policy<Code> {
|
|
21
|
+
return computed(() => fn({
|
|
22
|
+
allow: (code, message) => ({ ok: true, code, message, is: (c) => c === code }),
|
|
23
|
+
deny: (code, message) => ({ ok: false, code, message, is: (c) => c === code }),
|
|
24
|
+
pending: (code, message) => ({ ok: null, code, message, is: (c) => c === code })
|
|
25
|
+
}))
|
|
26
|
+
}
|
package/lib/composables/V.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
type Validation,
|
|
3
|
+
type ValidationArgs,
|
|
4
|
+
type GlobalConfig as VuelidateConfig,
|
|
5
|
+
useVuelidate
|
|
6
|
+
} from '@vuelidate/core'
|
|
2
7
|
import { type MaybeRefOrGetter, type Ref, computed, toValue } from 'vue'
|
|
3
8
|
import { type Snackbar, useSnackbars } from '../stores/Snackbars'
|
|
4
9
|
import { useTrans } from './Lang'
|
|
@@ -10,6 +15,7 @@ export interface V<
|
|
|
10
15
|
validation: Ref<Validation<Rules, Data>>
|
|
11
16
|
validate(): Promise<boolean>
|
|
12
17
|
validateAndNotify(message?: Snackbar): Promise<boolean>
|
|
18
|
+
notify(message?: Snackbar): void
|
|
13
19
|
reset(): void
|
|
14
20
|
}
|
|
15
21
|
|
|
@@ -24,24 +30,24 @@ export interface ValidatableError {
|
|
|
24
30
|
readonly $message: string | Ref<string>
|
|
25
31
|
}
|
|
26
32
|
|
|
33
|
+
export interface VNotification {
|
|
34
|
+
notify(message?: Snackbar): void
|
|
35
|
+
}
|
|
36
|
+
|
|
27
37
|
export function useV<
|
|
28
38
|
Data extends { [key in keyof Rules]: any },
|
|
29
39
|
Rules extends ValidationArgs = ValidationArgs
|
|
30
40
|
>(
|
|
31
41
|
data?: MaybeRefOrGetter<Data>,
|
|
32
|
-
rules?: MaybeRefOrGetter<Rules
|
|
42
|
+
rules?: MaybeRefOrGetter<Rules>,
|
|
43
|
+
config?: VuelidateConfig
|
|
33
44
|
): V<Data, Rules> {
|
|
34
|
-
const {
|
|
35
|
-
en: { notify: 'Form contains errors. Please correct them and try again.' },
|
|
36
|
-
ja: { notify: 'フォームにエラーがあります。内容を確認し、再度お試しください。' }
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
const snackbars = useSnackbars()
|
|
45
|
+
const { notify } = useVNotification()
|
|
40
46
|
|
|
41
47
|
const d = computed(() => toValue(data) ?? {})
|
|
42
48
|
const r = computed(() => toValue(rules) ?? {})
|
|
43
49
|
|
|
44
|
-
const validation = useVuelidate(r, d) as any
|
|
50
|
+
const validation = useVuelidate(r, d, config) as any
|
|
45
51
|
|
|
46
52
|
function reset(): void {
|
|
47
53
|
validation.value.$reset()
|
|
@@ -55,10 +61,7 @@ export function useV<
|
|
|
55
61
|
const valid = await validate()
|
|
56
62
|
|
|
57
63
|
if (!valid) {
|
|
58
|
-
|
|
59
|
-
mode: 'danger',
|
|
60
|
-
text: t.notify
|
|
61
|
-
})
|
|
64
|
+
notify(message)
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
return valid
|
|
@@ -68,6 +71,27 @@ export function useV<
|
|
|
68
71
|
validation,
|
|
69
72
|
validate,
|
|
70
73
|
validateAndNotify,
|
|
74
|
+
notify,
|
|
71
75
|
reset
|
|
72
76
|
}
|
|
73
77
|
}
|
|
78
|
+
|
|
79
|
+
export function useVNotification(): VNotification {
|
|
80
|
+
const { t } = useTrans({
|
|
81
|
+
en: { notify: 'Form contains errors. Please correct them and try again.' },
|
|
82
|
+
ja: { notify: 'フォームにエラーがあります。内容を確認し、再度お試しください。' }
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
const snackbars = useSnackbars()
|
|
86
|
+
|
|
87
|
+
function notify(message?: Snackbar): void {
|
|
88
|
+
snackbars.push(message ?? {
|
|
89
|
+
mode: 'danger',
|
|
90
|
+
text: t.notify
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
notify
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -19,6 +19,7 @@ export { requiredHms } from './requiredHms'
|
|
|
19
19
|
export { requiredIf } from './requiredIf'
|
|
20
20
|
export { requiredYmd } from './requiredYmd'
|
|
21
21
|
export { rule } from './rule'
|
|
22
|
+
export { slackChannelName } from './slackChannelName'
|
|
22
23
|
export { url } from './url'
|
|
23
24
|
export { ymd } from './ymd'
|
|
24
25
|
export { zeroOrNegativeInteger } from './zeroOrNegativeInteger'
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createRule } from '../Rule'
|
|
2
|
+
import { type SlackChannelNameOptions, slackChannelName as baseSlackChannelName } from '../validators'
|
|
3
|
+
|
|
4
|
+
export const message = {
|
|
5
|
+
en: 'The slack channel name is invalid.',
|
|
6
|
+
ja: 'Slackチャンネル名の形式が正しくありません。'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function slackChannelName(options?: SlackChannelNameOptions, msg?: string) {
|
|
10
|
+
return createRule({
|
|
11
|
+
message: ({ lang }) => msg ?? message[lang],
|
|
12
|
+
optional: true,
|
|
13
|
+
validation: (value) => baseSlackChannelName(value, options)
|
|
14
|
+
})
|
|
15
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { isString } from '../../support/Utils'
|
|
2
|
+
|
|
3
|
+
export interface SlackChannelNameOptions {
|
|
4
|
+
offset?: number
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function slackChannelName(value: unknown, options: SlackChannelNameOptions = {}): boolean {
|
|
8
|
+
if (!isString(value)) {
|
|
9
|
+
return false
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { offset = 0 } = options
|
|
13
|
+
const maxLength = /* Slack channel name max length */ 80 - offset
|
|
14
|
+
|
|
15
|
+
return new RegExp(`^[\\p{Ll}\\p{Lm}\\p{Lo}\\p{M}\\p{N}_-]{1,${maxLength}}$`, 'u').test(value)
|
|
16
|
+
}
|