UNPKG

3.04 kBPlain TextView Raw
1import { BaseDBEntity, SavedDBEntity } from '@naturalcycles/js-lib'
2import { Joi } from './joi.extensions'
3import {
4 AlternativesSchemaTyped,
5 AnySchemaTyped,
6 ArraySchemaTyped,
7 BooleanSchemaTyped,
8 ObjectSchemaTyped,
9 StringSchemaTyped,
10} from './joi.model'
11
12export const booleanSchema = Joi.boolean() as BooleanSchemaTyped
13export const booleanDefaultToFalseSchema = Joi.boolean().default(false) as BooleanSchemaTyped
14export const stringSchema = Joi.string()
15export const numberSchema = Joi.number()
16export const integerSchema = Joi.number().integer()
17export const percentageSchema = Joi.number().integer().min(0).max(100)
18export const dateStringSchema = stringSchema.dateString()
19export const binarySchema = Joi.binary()
20
21export const urlSchema = (scheme: string | string[] = 'https'): StringSchemaTyped =>
22 Joi.string().uri({ scheme })
23
24export function arraySchema<T>(items?: AnySchemaTyped<T, T>): ArraySchemaTyped<T> {
25 return items ? Joi.array().items(items) : Joi.array()
26}
27
28export function objectSchema<IN, OUT = IN>(schema?: {
29 [key in keyof Partial<IN>]: AnySchemaTyped<IN[key]>
30}): ObjectSchemaTyped<IN, OUT> {
31 return Joi.object(schema)
32}
33
34export function oneOfSchema<T = any>(
35 ...schemas: AnySchemaTyped<any>[]
36): AlternativesSchemaTyped<T> {
37 return Joi.alternatives(schemas)
38}
39
40export const anySchema = Joi.any()
41export const anyObjectSchema = Joi.object().options({ stripUnknown: false })
42
43// 1g498efj5sder3324zer
44/**
45 * [a-zA-Z0-9_]*
46 * 6-64 length
47 */
48export const idSchema = stringSchema.regex(/^[a-zA-Z0-9_]{6,64}$/)
49
50/**
51 * `_` should NOT be allowed to be able to use slug-ids as part of natural ids with `_` separator.
52 */
53export const SLUG_PATTERN = /^[a-z0-9-]*$/
54
55/**
56 * "Slug" - a valid URL, filename, etc.
57 */
58export const slugSchema = stringSchema.regex(/^[a-z0-9-]{1,255}$/)
59
60// 16725225600 is 2500-01-01
61export const unixTimestampSchema = numberSchema.integer().min(0).max(16725225600)
62
63// 2
64export const verSchema = numberSchema.optional().integer().min(1).max(100)
65
66/**
67 * Be careful, by default emailSchema does TLD validation. To disable it - use `stringSchema.email({tld: false}).lowercase()`
68 */
69export const emailSchema = stringSchema.email().lowercase()
70
71/**
72 * Pattern is simplified for our use, it's not a canonical SemVer.
73 */
74export const SEM_VER_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+$/
75export const semVerSchema = stringSchema.regex(SEM_VER_PATTERN)
76// todo: .error(() => 'should be SemVer')
77
78export const userAgentSchema = stringSchema
79 .min(5) // I've seen UA of `Android` (7 characters)
80 .max(400)
81
82export const utcOffsetSchema = numberSchema
83 .min(-14 * 60)
84 .max(14 * 60)
85 .dividable(15)
86
87export const ipAddressSchema = stringSchema.ip()
88
89export const baseDBEntitySchema = objectSchema<BaseDBEntity>({
90 id: stringSchema.optional(),
91 created: unixTimestampSchema.optional(),
92 updated: unixTimestampSchema.optional(),
93})
94
95export const savedDBEntitySchema = objectSchema<SavedDBEntity>({
96 id: stringSchema,
97 created: unixTimestampSchema,
98 updated: unixTimestampSchema,
99})