UNPKG

@naturalcycles/nodejs-lib

Version:
123 lines (103 loc) 3.57 kB
import { BaseDBEntity, SavedDBEntity } from '@naturalcycles/js-lib' import { Joi } from './joi.extensions' import { AlternativesSchemaTyped, AnySchemaTyped, ArraySchemaTyped, BooleanSchemaTyped, ObjectSchemaTyped, StringSchemaTyped, } from './joi.model' export const booleanSchema = Joi.boolean() as BooleanSchemaTyped export const booleanDefaultToFalseSchema = Joi.boolean().default(false) as BooleanSchemaTyped export const stringSchema = Joi.string() export const numberSchema = Joi.number() export const integerSchema = Joi.number().integer() export const percentageSchema = Joi.number().integer().min(0).max(100) export const dateStringSchema = stringSchema.dateString() export const binarySchema = Joi.binary() export const urlSchema = (scheme: string | string[] = 'https'): StringSchemaTyped => Joi.string().uri({ scheme }) export function arraySchema<T>(items?: AnySchemaTyped<T, T>): ArraySchemaTyped<T> { return items ? Joi.array().items(items) : Joi.array() } export function objectSchema<IN, OUT = IN>(schema?: { [key in keyof Partial<IN>]: AnySchemaTyped<IN[key]> }): ObjectSchemaTyped<IN, OUT> { return Joi.object(schema) } export function oneOfSchema<T = any>( ...schemas: AnySchemaTyped<any>[] ): AlternativesSchemaTyped<T> { return Joi.alternatives(schemas) } export const anySchema = Joi.any() export const anyObjectSchema = Joi.object().options({ stripUnknown: false }) // 1g498efj5sder3324zer /** * [a-zA-Z0-9_]* * 6-64 length */ export const idSchema = stringSchema.regex(/^[a-zA-Z0-9_]{6,64}$/) /** * `_` should NOT be allowed to be able to use slug-ids as part of natural ids with `_` separator. */ export const SLUG_PATTERN = /^[a-z0-9-]*$/ /** * "Slug" - a valid URL, filename, etc. */ export const slugSchema = stringSchema.regex(/^[a-z0-9-]{1,255}$/) const TS_2500 = 16725225600 // 2500-01-01 const TS_2000 = 946684800 // 2000-01-01 /** * Between years 1970 and 2050 */ export const unixTimestampSchema = numberSchema.integer().min(0).max(TS_2500) /** * Between years 2000 and 2050 */ export const unixTimestamp2000Schema = numberSchema.integer().min(0).min(TS_2000).max(TS_2500) /** * Between years 1970 and 2050 */ export const unixTimestampMillisSchema = numberSchema .integer() .min(0) .max(TS_2500 * 1000) /** * Between years 2000 and 2050 */ export const unixTimestampMillis2000Schema = numberSchema .integer() .min(TS_2000 * 1000) .max(TS_2500 * 1000) // 2 export const verSchema = numberSchema.optional().integer().min(1).max(100) /** * Be careful, by default emailSchema does TLD validation. To disable it - use `stringSchema.email({tld: false}).lowercase()` */ export const emailSchema = stringSchema.email().lowercase() /** * Pattern is simplified for our use, it's not a canonical SemVer. */ export const SEM_VER_PATTERN = /^[0-9]+\.[0-9]+\.[0-9]+$/ export const semVerSchema = stringSchema.regex(SEM_VER_PATTERN) // todo: .error(() => 'should be SemVer') export const userAgentSchema = stringSchema .min(5) // I've seen UA of `Android` (7 characters) .max(400) export const utcOffsetSchema = numberSchema .min(-14 * 60) .max(14 * 60) .dividable(15) export const ipAddressSchema = stringSchema.ip() export const baseDBEntitySchema = objectSchema<BaseDBEntity>({ id: stringSchema.optional(), created: unixTimestamp2000Schema.optional(), updated: unixTimestamp2000Schema.optional(), }) export const savedDBEntitySchema = objectSchema<SavedDBEntity>({ id: stringSchema, created: unixTimestamp2000Schema, updated: unixTimestamp2000Schema, })