@naturalcycles/nodejs-lib 15.89.1 → 15.90.1

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 (28) hide show
  1. package/dist/validation/ajv/ajvSchema.d.ts +0 -5
  2. package/dist/validation/ajv/ajvSchema.js +0 -10
  3. package/package.json +1 -3
  4. package/src/validation/ajv/ajvSchema.ts +0 -15
  5. package/dist/validation/joi/index.d.ts +0 -9
  6. package/dist/validation/joi/index.js +0 -5
  7. package/dist/validation/joi/joi.extensions.d.ts +0 -11
  8. package/dist/validation/joi/joi.extensions.js +0 -25
  9. package/dist/validation/joi/joi.model.d.ts +0 -7
  10. package/dist/validation/joi/joi.model.js +0 -5
  11. package/dist/validation/joi/joi.shared.schemas.d.ts +0 -91
  12. package/dist/validation/joi/joi.shared.schemas.js +0 -135
  13. package/dist/validation/joi/joi.validation.error.d.ts +0 -29
  14. package/dist/validation/joi/joi.validation.error.js +0 -8
  15. package/dist/validation/joi/joi.validation.util.d.ts +0 -33
  16. package/dist/validation/joi/joi.validation.util.js +0 -139
  17. package/dist/validation/joi/number.extensions.d.ts +0 -6
  18. package/dist/validation/joi/number.extensions.js +0 -38
  19. package/dist/validation/joi/string.extensions.d.ts +0 -11
  20. package/dist/validation/joi/string.extensions.js +0 -104
  21. package/src/validation/joi/index.ts +0 -32
  22. package/src/validation/joi/joi.extensions.ts +0 -38
  23. package/src/validation/joi/joi.model.ts +0 -12
  24. package/src/validation/joi/joi.shared.schemas.ts +0 -207
  25. package/src/validation/joi/joi.validation.error.ts +0 -35
  26. package/src/validation/joi/joi.validation.util.ts +0 -183
  27. package/src/validation/joi/number.extensions.ts +0 -46
  28. package/src/validation/joi/string.extensions.ts +0 -129
@@ -1,6 +1,5 @@
1
1
  import { type ValidationFunction, type ValidationFunctionResult } from '@naturalcycles/js-lib';
2
2
  import { type AnyObject } from '@naturalcycles/js-lib/types';
3
- import type { ZodType } from '@naturalcycles/js-lib/zod';
4
3
  import type { Ajv } from 'ajv';
5
4
  import { AjvValidationError } from './ajvValidationError.js';
6
5
  import { type JsonSchema, JsonSchemaTerminal } from './jsonSchemaBuilder.js';
@@ -25,10 +24,6 @@ export declare class AjvSchema<IN = unknown, OUT = IN> {
25
24
  * correctly for some reason.
26
25
  */
27
26
  static create<IN, OUT = IN>(schema: SchemaHandledByAjv<IN, OUT>, cfg?: Partial<AjvSchemaCfg>): AjvSchema<IN, OUT>;
28
- /**
29
- * @deprecated Use `j` to build schemas, not `z` or `zod`.
30
- */
31
- static createFromZod<T extends ZodType<any, any, any>>(schema: T): AjvSchema<T['_input'], T['_output']>;
32
27
  static isJsonSchemaBuilder<IN, OUT>(schema: unknown): schema is JsonSchemaTerminal<IN, OUT, any>;
33
28
  readonly cfg: AjvSchemaCfg;
34
29
  /**
@@ -3,7 +3,6 @@ import { _assert } from '@naturalcycles/js-lib/error';
3
3
  import { _deepCopy, _filterNullishValues } from '@naturalcycles/js-lib/object';
4
4
  import { _substringBefore } from '@naturalcycles/js-lib/string';
5
5
  import { _typeCast } from '@naturalcycles/js-lib/types';
6
- import { z } from '@naturalcycles/js-lib/zod';
7
6
  import { _inspect } from '../../string/inspect.js';
8
7
  import { AjvValidationError } from './ajvValidationError.js';
9
8
  import { getAjv } from './getAjv.js';
@@ -70,15 +69,6 @@ export class AjvSchema {
70
69
  AjvSchema.cacheAjvSchema(schema, ajvSchema);
71
70
  return ajvSchema;
72
71
  }
73
- /**
74
- * @deprecated Use `j` to build schemas, not `z` or `zod`.
75
- */
76
- static createFromZod(schema) {
77
- const jsonSchema = z.toJSONSchema(schema, {
78
- target: 'draft-2020-12',
79
- });
80
- return AjvSchema.create(jsonSchema);
81
- }
82
72
  static isJsonSchemaBuilder(schema) {
83
73
  return schema instanceof JsonSchemaTerminal;
84
74
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
3
  "type": "module",
4
- "version": "15.89.1",
4
+ "version": "15.90.1",
5
5
  "dependencies": {
6
6
  "@naturalcycles/js-lib": "^15",
7
7
  "@types/js-yaml": "^4",
@@ -10,7 +10,6 @@
10
10
  "ajv": "^8",
11
11
  "chalk": "^5",
12
12
  "dotenv": "^17",
13
- "joi": "^18",
14
13
  "js-yaml": "^4",
15
14
  "jsonwebtoken": "^9",
16
15
  "lru-cache": "^11",
@@ -39,7 +38,6 @@
39
38
  "./stream/*.js": "./dist/stream/*.js",
40
39
  "./yargs": "./dist/yargs/yargs.util.js",
41
40
  "./ajv": "./dist/validation/ajv/index.js",
42
- "./joi": "./dist/validation/joi/index.js",
43
41
  "./zip": "./dist/zip/zip.util.js"
44
42
  },
45
43
  "bin": {
@@ -8,8 +8,6 @@ import { _assert } from '@naturalcycles/js-lib/error'
8
8
  import { _deepCopy, _filterNullishValues } from '@naturalcycles/js-lib/object'
9
9
  import { _substringBefore } from '@naturalcycles/js-lib/string'
10
10
  import { _typeCast, type AnyObject } from '@naturalcycles/js-lib/types'
11
- import type { ZodType } from '@naturalcycles/js-lib/zod'
12
- import { z } from '@naturalcycles/js-lib/zod'
13
11
  import type { Ajv, ErrorObject } from 'ajv'
14
12
  import { _inspect } from '../../string/inspect.js'
15
13
  import { AjvValidationError } from './ajvValidationError.js'
@@ -93,19 +91,6 @@ export class AjvSchema<IN = unknown, OUT = IN> {
93
91
  return ajvSchema
94
92
  }
95
93
 
96
- /**
97
- * @deprecated Use `j` to build schemas, not `z` or `zod`.
98
- */
99
- static createFromZod<T extends ZodType<any, any, any>>(
100
- schema: T,
101
- ): AjvSchema<T['_input'], T['_output']> {
102
- const jsonSchema = z.toJSONSchema(schema, {
103
- target: 'draft-2020-12',
104
- }) as unknown as JsonSchema<T['_input'], T['_output']>
105
-
106
- return AjvSchema.create(jsonSchema)
107
- }
108
-
109
94
  static isJsonSchemaBuilder<IN, OUT>(schema: unknown): schema is JsonSchemaTerminal<IN, OUT, any> {
110
95
  return schema instanceof JsonSchemaTerminal
111
96
  }
@@ -1,9 +0,0 @@
1
- import type { AlternativesSchema, AnySchema, ArraySchema, BinarySchema, BooleanSchema, DateSchema, FunctionSchema, ObjectSchema, ValidationErrorItem } from 'joi';
2
- export * from './joi.extensions.js';
3
- export * from './joi.model.js';
4
- export * from './joi.shared.schemas.js';
5
- export * from './joi.validation.error.js';
6
- export * from './joi.validation.util.js';
7
- export type { AlternativesSchema, AnySchema, ArraySchema, BinarySchema, BooleanSchema, DateSchema, FunctionSchema, ObjectSchema, ValidationErrorItem, };
8
- export type { NumberSchema } from './number.extensions.js';
9
- export type { StringSchema } from './string.extensions.js';
@@ -1,5 +0,0 @@
1
- export * from './joi.extensions.js';
2
- export * from './joi.model.js';
3
- export * from './joi.shared.schemas.js';
4
- export * from './joi.validation.error.js';
5
- export * from './joi.validation.util.js';
@@ -1,11 +0,0 @@
1
- import JoiLib from 'joi';
2
- import type { NumberSchema } from './number.extensions.js';
3
- import type { StringSchema } from './string.extensions.js';
4
- export interface ExtendedJoi extends JoiLib.Root {
5
- string: <TSchema = string>() => StringSchema<TSchema>;
6
- number: <TSchema = number>() => NumberSchema<TSchema>;
7
- }
8
- /**
9
- * This is the only right place to import Joi from
10
- */
11
- export declare const Joi: ExtendedJoi;
@@ -1,25 +0,0 @@
1
- import JoiLib from 'joi';
2
- import { numberExtensions } from './number.extensions.js';
3
- import { stringExtensions } from './string.extensions.js';
4
- /**
5
- * This is the only right place to import Joi from
6
- */
7
- // eslint-disable-next-line @typescript-eslint/naming-convention
8
- export const Joi = JoiLib.defaults(schema => {
9
- // hack to prevent infinite recursion due to .empty('') where '' is a stringSchema itself
10
- if (schema.type === 'string') {
11
- return (schema
12
- .trim() // trim all strings by default
13
- // 2020-09-21: null values are NOT treated as EMPTY enymore
14
- // .empty([schema.valid('', null)]) // treat '' or null as empty (undefined, will be stripped out)
15
- // treat '' as empty (undefined, will be stripped out)
16
- .empty([schema.valid('')]));
17
- }
18
- // Treat `null` as undefined for all schema types
19
- // undefined values will be stripped by default from object values
20
- // 2020-09-21: breaking change: null values are NOT treated as EMPTY anymore
21
- // return schema.empty(null)
22
- return schema;
23
- })
24
- .extend((joi) => stringExtensions(joi))
25
- .extend((joi) => numberExtensions(joi));
@@ -1,7 +0,0 @@
1
- /**
2
- * This type is useful to allow "joi schema merging".
3
- * Because by default Joi doesn't allow normal merging.
4
- * E.g `joiSchema.concat` doesn't play well when some property exists
5
- * in both left and right side.
6
- */
7
- export type JoiSchemaObject<T> = Partial<Record<keyof T, any>>;
@@ -1,5 +0,0 @@
1
- // export interface ObjectSchema<T = any> extends JoiObjectSchema<T> {
2
- // // Open-ended index signature to allow for easier .concat(baseDBEntitySchema)
3
- // [k: string]: any
4
- // }
5
- export {};
@@ -1,91 +0,0 @@
1
- import { type AnyObject, type BaseDBEntity, type IANATimezone, type IsoDate, type IsoDateTime, type NumberEnum, type StringEnum, type StringMap, type UnixTimestamp, type UnixTimestampMillis } from '@naturalcycles/js-lib/types';
2
- import type { AlternativesSchema, AnySchema, ArraySchema, ObjectSchema } from 'joi';
3
- import type { NumberSchema } from './number.extensions.js';
4
- import type { StringSchema } from './string.extensions.js';
5
- export declare const booleanSchema: import("joi").BooleanSchema<boolean>;
6
- export declare const booleanDefaultToFalseSchema: import("joi").BooleanSchema<boolean>;
7
- export declare const stringSchema: StringSchema<string>;
8
- export declare const stringSchemaTyped: <T>() => StringSchema<T>;
9
- export declare const numberSchema: NumberSchema<number>;
10
- export declare const numberSchemaTyped: <T>() => NumberSchema<T>;
11
- export declare const integerSchema: NumberSchema<number>;
12
- export declare const percentageSchema: NumberSchema<number>;
13
- export declare const dateStringSchema: StringSchema<IsoDate>;
14
- export declare const binarySchema: import("joi").BinarySchema<Buffer<ArrayBufferLike>>;
15
- export declare const dateObjectSchema: ObjectSchema<any>;
16
- export declare const dateIntervalStringSchema: StringSchema<string>;
17
- export declare const DATE_TIME_STRING_REGEX: RegExp;
18
- export declare const dateTimeStringSchema: StringSchema<IsoDateTime>;
19
- /**
20
- * Allows all values of a String Enum.
21
- */
22
- export declare const stringEnumValueSchema: <ENUM extends StringEnum>(en: ENUM) => StringSchema<ENUM[keyof ENUM]>;
23
- /**
24
- * Allows all keys of a String Enum.
25
- */
26
- export declare const stringEnumKeySchema: <ENUM extends StringEnum>(en: ENUM) => StringSchema;
27
- /**
28
- * Allows all values of a String Enum.
29
- */
30
- export declare const numberEnumValueSchema: <ENUM extends NumberEnum>(en: ENUM) => NumberSchema<ENUM[keyof ENUM]>;
31
- /**
32
- * Allows all keys of a Number Enum.
33
- */
34
- export declare const numberEnumKeySchema: <ENUM extends NumberEnum>(en: ENUM) => StringSchema;
35
- export declare const urlSchema: (scheme?: string | string[]) => StringSchema;
36
- export declare function arraySchema<T>(items: AnySchema<T>): ArraySchema<T[]>;
37
- export declare function anyObjectSchema<T extends AnyObject>(): ObjectSchema<T>;
38
- export declare function objectSchema<T extends AnyObject>(schema: {
39
- [key in keyof Partial<T>]: AnySchema<T[key]>;
40
- }): ObjectSchema<T>;
41
- export declare function stringMapSchema<T>(key: AnySchema, value: AnySchema<T>): ObjectSchema<StringMap<T>>;
42
- export declare function oneOfSchema<T = any>(...schemas: AnySchema[]): AlternativesSchema<T>;
43
- export declare const anySchema: AnySchema<any>;
44
- export declare const base62Schema: StringSchema<string>;
45
- export declare const base64Schema: StringSchema<string>;
46
- export declare const base64UrlSchema: StringSchema<string>;
47
- export declare const jwtSchema: StringSchema<string>;
48
- /**
49
- * [a-zA-Z0-9_]*
50
- * 6-64 length
51
- */
52
- export declare const idSchema: StringSchema<string>;
53
- export declare const idBase62Schema: StringSchema<string>;
54
- export declare const idBase64Schema: StringSchema<string>;
55
- export declare const idBase64UrlSchema: StringSchema<string>;
56
- /**
57
- * "Slug" - a valid URL, filename, etc.
58
- */
59
- export declare const slugSchema: StringSchema<string>;
60
- /**
61
- * Between years 1970 and 2050
62
- */
63
- export declare const unixTimestampSchema: NumberSchema<UnixTimestamp>;
64
- /**
65
- * Between years 2000 and 2050
66
- */
67
- export declare const unixTimestamp2000Schema: NumberSchema<UnixTimestamp>;
68
- /**
69
- * Between years 1970 and 2050
70
- */
71
- export declare const unixTimestampMillisSchema: NumberSchema<UnixTimestampMillis>;
72
- /**
73
- * Between years 2000 and 2050
74
- */
75
- export declare const unixTimestampMillis2000Schema: NumberSchema<UnixTimestampMillis>;
76
- export declare const verSchema: NumberSchema<number>;
77
- /**
78
- * Be careful, by default emailSchema does TLD validation. To disable it - use `stringSchema.email({tld: false}).lowercase()`
79
- */
80
- export declare const emailSchema: StringSchema<string>;
81
- /**
82
- * Pattern is simplified for our use, it's not a canonical SemVer.
83
- */
84
- export declare const semVerSchema: StringSchema<string>;
85
- export declare const userAgentSchema: StringSchema<string>;
86
- export declare const utcOffsetSchema: NumberSchema<number>;
87
- export declare const ianaTimezoneSchema: StringSchema<IANATimezone>;
88
- export declare const ipAddressSchema: StringSchema<string>;
89
- export declare const baseDBEntitySchema: ObjectSchema<BaseDBEntity>;
90
- export declare const macAddressSchema: StringSchema<string>;
91
- export declare const uuidSchema: StringSchema<string>;
@@ -1,135 +0,0 @@
1
- import { _numberEnumKeys, _numberEnumValues, _stringEnumKeys, _stringEnumValues, } from '@naturalcycles/js-lib';
2
- import { JWT_REGEX, } from '@naturalcycles/js-lib/types';
3
- import { BASE62_REGEX, BASE64_REGEX, BASE64URL_REGEX, ID_REGEX, MAC_ADDRESS_REGEX, SEMVER_REGEX, SLUG_REGEX, } from '../regexes.js';
4
- import { Joi } from './joi.extensions.js';
5
- export const booleanSchema = Joi.boolean();
6
- export const booleanDefaultToFalseSchema = Joi.boolean().default(false);
7
- export const stringSchema = Joi.string();
8
- export const stringSchemaTyped = () => Joi.string();
9
- export const numberSchema = Joi.number();
10
- export const numberSchemaTyped = () => Joi.number();
11
- export const integerSchema = Joi.number().integer();
12
- export const percentageSchema = Joi.number().integer().min(0).max(100);
13
- export const dateStringSchema = stringSchema.dateString();
14
- export const binarySchema = Joi.binary();
15
- export const dateObjectSchema = Joi.object().instance(Date);
16
- const DATE_INTERVAL_REGEX = /^\d{4}-\d{2}-\d{2}\/\d{4}-\d{2}-\d{2}$/;
17
- export const dateIntervalStringSchema = stringSchema.regex(DATE_INTERVAL_REGEX).messages({
18
- 'string.pattern.base': `must be a DateInterval string`,
19
- });
20
- export const DATE_TIME_STRING_REGEX = /^\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}:\d{2}(?:\.\d{1,3})?(?:Z|[+-]\d{2}:\d{2})?)?$/;
21
- export const dateTimeStringSchema = stringSchema.regex(DATE_TIME_STRING_REGEX).messages({
22
- 'string.pattern.base': `must be a DateTime string`,
23
- });
24
- /**
25
- * Allows all values of a String Enum.
26
- */
27
- export const stringEnumValueSchema = (en) => Joi.string().valid(..._stringEnumValues(en));
28
- /**
29
- * Allows all keys of a String Enum.
30
- */
31
- export const stringEnumKeySchema = (en) => Joi.string().valid(..._stringEnumKeys(en));
32
- /**
33
- * Allows all values of a String Enum.
34
- */
35
- export const numberEnumValueSchema = (en) => Joi.number().valid(..._numberEnumValues(en));
36
- /**
37
- * Allows all keys of a Number Enum.
38
- */
39
- export const numberEnumKeySchema = (en) => Joi.string().valid(..._numberEnumKeys(en));
40
- export const urlSchema = (scheme = 'https') => Joi.string().uri({ scheme });
41
- export function arraySchema(items) {
42
- return Joi.array().items(items);
43
- }
44
- export function anyObjectSchema() {
45
- return Joi.object().options({ stripUnknown: false });
46
- }
47
- export function objectSchema(schema) {
48
- return Joi.object(schema);
49
- }
50
- export function stringMapSchema(key, value) {
51
- return Joi.object().pattern(key, value);
52
- }
53
- export function oneOfSchema(...schemas) {
54
- return Joi.alternatives(schemas);
55
- }
56
- export const anySchema = Joi.any();
57
- export const base62Schema = stringSchema.regex(BASE62_REGEX);
58
- export const base64Schema = stringSchema.regex(BASE64_REGEX);
59
- export const base64UrlSchema = stringSchema.regex(BASE64URL_REGEX);
60
- export const jwtSchema = stringSchema.regex(JWT_REGEX);
61
- // 1g498efj5sder3324zer
62
- /**
63
- * [a-zA-Z0-9_]*
64
- * 6-64 length
65
- */
66
- export const idSchema = stringSchema.regex(ID_REGEX);
67
- export const idBase62Schema = base62Schema.min(8).max(64);
68
- export const idBase64Schema = base64Schema.min(8).max(64);
69
- export const idBase64UrlSchema = base64UrlSchema.min(8).max(64);
70
- /**
71
- * "Slug" - a valid URL, filename, etc.
72
- */
73
- export const slugSchema = stringSchema.regex(SLUG_REGEX).min(1).max(255);
74
- const TS_2500 = 16725225600; // 2500-01-01
75
- const TS_2000 = 946684800; // 2000-01-01
76
- /**
77
- * Between years 1970 and 2050
78
- */
79
- export const unixTimestampSchema = numberSchema
80
- .integer()
81
- .min(0)
82
- .max(TS_2500);
83
- /**
84
- * Between years 2000 and 2050
85
- */
86
- export const unixTimestamp2000Schema = numberSchema
87
- .integer()
88
- .min(TS_2000)
89
- .max(TS_2500);
90
- /**
91
- * Between years 1970 and 2050
92
- */
93
- export const unixTimestampMillisSchema = numberSchema
94
- .integer()
95
- .min(0)
96
- .max(TS_2500 * 1000);
97
- /**
98
- * Between years 2000 and 2050
99
- */
100
- export const unixTimestampMillis2000Schema = numberSchema
101
- .integer()
102
- .min(TS_2000 * 1000)
103
- .max(TS_2500 * 1000);
104
- // 2
105
- export const verSchema = numberSchema.optional().integer().min(1).max(100);
106
- /**
107
- * Be careful, by default emailSchema does TLD validation. To disable it - use `stringSchema.email({tld: false}).lowercase()`
108
- */
109
- export const emailSchema = stringSchema.email().lowercase();
110
- /**
111
- * Pattern is simplified for our use, it's not a canonical SemVer.
112
- */
113
- export const semVerSchema = stringSchema.regex(SEMVER_REGEX);
114
- // todo: .error(() => 'should be SemVer')
115
- export const userAgentSchema = stringSchema
116
- .min(5) // I've seen UA of `Android` (7 characters)
117
- .max(400);
118
- export const utcOffsetSchema = numberSchema
119
- .min(-14 * 60)
120
- .max(14 * 60)
121
- .dividable(15);
122
- export const ianaTimezoneSchema = stringSchema
123
- // UTC is added to assist unit-testing, which uses UTC by default (not technically a valid Iana timezone identifier)
124
- .valid(...Intl.supportedValuesOf('timeZone'), 'UTC')
125
- .messages({
126
- 'any.only': `must be a valid IANA timezone string`,
127
- });
128
- export const ipAddressSchema = stringSchema.ip();
129
- export const baseDBEntitySchema = objectSchema({
130
- id: stringSchema.optional(),
131
- created: unixTimestamp2000Schema.optional(),
132
- updated: unixTimestamp2000Schema.optional(),
133
- });
134
- export const macAddressSchema = stringSchema.regex(MAC_ADDRESS_REGEX);
135
- export const uuidSchema = stringSchema.uuid();
@@ -1,29 +0,0 @@
1
- import type { ErrorData } from '@naturalcycles/js-lib/error';
2
- import { AppError } from '@naturalcycles/js-lib/error/error.util.js';
3
- import type { ValidationErrorItem } from 'joi';
4
- /**
5
- * Example of ValidationErrorItem:
6
- *
7
- * {
8
- * message: '"temperature" must be larger than or equal to 33',
9
- * path: [ 'entries', 10, 'temperature' ],
10
- * type: 'number.min',
11
- * context: { limit: 33, value: 30, key: 'temperature', label: 'temperature' }
12
- * }
13
- */
14
- export interface JoiValidationErrorData extends ErrorData {
15
- joiValidationErrorItems: ValidationErrorItem[];
16
- joiValidationInputName?: string;
17
- joiValidationInputId?: string;
18
- /**
19
- * Error "annotation" is stripped in Error.message.
20
- * This field contains the "full" annotation.
21
- *
22
- * This field is non-enumerable, won't be printed or included in JSON by default,
23
- * but still accessible programmatically (via `err.data.annotation`) when needed!
24
- */
25
- annotation?: string;
26
- }
27
- export declare class JoiValidationError extends AppError<JoiValidationErrorData> {
28
- constructor(message: string, data: JoiValidationErrorData);
29
- }
@@ -1,8 +0,0 @@
1
- import { AppError } from '@naturalcycles/js-lib/error/error.util.js';
2
- export class JoiValidationError extends AppError {
3
- constructor(message, data) {
4
- super(message, data, {
5
- name: 'JoiValidationError',
6
- });
7
- }
8
- }
@@ -1,33 +0,0 @@
1
- import { type ValidationFunction, type ValidationFunctionResult } from '@naturalcycles/js-lib';
2
- import type { AnySchema, ValidationOptions } from 'joi';
3
- import { JoiValidationError } from './joi.validation.error.js';
4
- export declare function getJoiValidationFunction<T>(schema: AnySchema<T>): ValidationFunction<T, T, JoiValidationError>;
5
- /**
6
- * Validates with Joi.
7
- * Throws JoiValidationError if invalid.
8
- * Returns *converted* value.
9
- *
10
- * If `schema` is undefined - returns value as is.
11
- */
12
- export declare function validate<T>(input: any, schema?: AnySchema<T>, inputName?: string, opt?: ValidationOptions): T;
13
- /**
14
- * Validates with Joi.
15
- * Returns JoiValidationResult with converted value and error (if any).
16
- * Does not throw.
17
- *
18
- * Joi does NOT mutate the input.
19
- *
20
- * If `schema` is undefined - returns value as is.
21
- */
22
- export declare function getValidationResult<T>(input: T, schema?: AnySchema<T>, inputName?: string, options?: ValidationOptions): ValidationFunctionResult<T, JoiValidationError>;
23
- /**
24
- * Convenience function that returns true if !error.
25
- */
26
- export declare function isValid<T>(input: T, schema?: AnySchema<T>): boolean;
27
- export declare function undefinedIfInvalid<T>(input: any, schema?: AnySchema<T>): T | undefined;
28
- /**
29
- * Will do joi-conversion, regardless of error/validity of value.
30
- *
31
- * @returns converted value
32
- */
33
- export declare function convert<T>(input: any, schema?: AnySchema<T>): T;
@@ -1,139 +0,0 @@
1
- /*
2
- * Does 2 things:
3
- * 1. Validates the value according to Schema passed.
4
- * 2. Converts the value (also according to Schema).
5
- *
6
- * "Converts" mean e.g trims all strings from leading/trailing spaces.
7
- */
8
- import { _hb, _isObject, } from '@naturalcycles/js-lib';
9
- import { _assert } from '@naturalcycles/js-lib/error/assert.js';
10
- import { _truncateMiddle } from '@naturalcycles/js-lib/string/string.util.js';
11
- import { JoiValidationError } from './joi.validation.error.js';
12
- // Strip colors in production (for e.g Sentry reporting)
13
- // const stripColors = process.env.NODE_ENV === 'production' || !!process.env.GAE_INSTANCE
14
- // Currently colors do more bad than good, so let's strip them always for now
15
- const stripColors = true;
16
- const defaultOptions = {
17
- abortEarly: false,
18
- convert: true,
19
- allowUnknown: true,
20
- stripUnknown: {
21
- objects: true,
22
- // true: it will SILENTLY strip invalid values from arrays. Very dangerous! Can lead to data loss!
23
- // false: it will THROW validation error if any of array items is invalid
24
- // Q: is it invalid if it has unknown properties?
25
- // A: no, unknown properties are just stripped (in both 'false' and 'true' states), array is still valid
26
- // Q: will it strip or keep unknown properties in array items?..
27
- // A: strip
28
- arrays: false, // let's be very careful with that! https://github.com/hapijs/joi/issues/658
29
- },
30
- presence: 'required',
31
- // errors: {
32
- // stack: true,
33
- // }
34
- };
35
- export function getJoiValidationFunction(schema) {
36
- return (input, opt) => {
37
- _assert(!opt?.mutateInput, 'mutateInput=true is not yet supported with Joi');
38
- return getValidationResult(input, schema, opt?.inputName);
39
- };
40
- }
41
- /**
42
- * Validates with Joi.
43
- * Throws JoiValidationError if invalid.
44
- * Returns *converted* value.
45
- *
46
- * If `schema` is undefined - returns value as is.
47
- */
48
- export function validate(input, schema, inputName, opt = {}) {
49
- const [error, returnValue] = getValidationResult(input, schema, inputName, opt);
50
- if (error)
51
- throw error;
52
- return returnValue;
53
- }
54
- /**
55
- * Validates with Joi.
56
- * Returns JoiValidationResult with converted value and error (if any).
57
- * Does not throw.
58
- *
59
- * Joi does NOT mutate the input.
60
- *
61
- * If `schema` is undefined - returns value as is.
62
- */
63
- export function getValidationResult(input, schema, inputName, options = {}) {
64
- if (!schema)
65
- return [null, input];
66
- const { value, error } = schema.validate(input, {
67
- ...defaultOptions,
68
- ...options,
69
- });
70
- const err = error ? createError(input, error, inputName) : null;
71
- return [err, value];
72
- }
73
- /**
74
- * Convenience function that returns true if !error.
75
- */
76
- export function isValid(input, schema) {
77
- if (!schema)
78
- return true;
79
- const { error } = schema.validate(input, defaultOptions);
80
- return !error;
81
- }
82
- export function undefinedIfInvalid(input, schema) {
83
- if (!schema)
84
- return input;
85
- const { value, error } = schema.validate(input, defaultOptions);
86
- return error ? undefined : value;
87
- }
88
- /**
89
- * Will do joi-conversion, regardless of error/validity of value.
90
- *
91
- * @returns converted value
92
- */
93
- export function convert(input, schema) {
94
- if (!schema)
95
- return input;
96
- const { value } = schema.validate(input, defaultOptions);
97
- return value;
98
- }
99
- function createError(value, err, inputName) {
100
- const tokens = [];
101
- const inputId = _isObject(value) ? value['id'] : undefined;
102
- if (inputId || inputName) {
103
- inputName ||= value?.constructor?.name;
104
- tokens.push('Invalid ' + [inputName, inputId].filter(Boolean).join('.'));
105
- }
106
- const annotation = err.annotate(stripColors);
107
- if (annotation.length > 100) {
108
- // For rather large annotations - we include up to 5 errors up front, before printing the whole object.
109
- // Up to 5 `details`
110
- tokens.push(...err.details.slice(0, 5).map(i => {
111
- return i.message;
112
- // Currently not specifying the path, to not "overwhelm" the message
113
- // Can be reverted if needed.
114
- // let msg = i.message
115
- // const paths = i.path.filter(Boolean).join('.')
116
- // if (paths) msg += ` @ .${paths}`
117
- // return msg
118
- }));
119
- if (err.details.length > 5)
120
- tokens.push(`... ${err.details.length} errors in total`);
121
- tokens.push('');
122
- }
123
- tokens.push(_truncateMiddle(annotation, 4000, `\n... ${_hb(annotation.length)} message truncated ...\n`));
124
- const msg = tokens.join('\n');
125
- const data = {
126
- joiValidationErrorItems: err.details,
127
- ...(inputName && { joiValidationInputName: inputName }),
128
- ...(inputId && { joiValidationInputId: inputId }),
129
- };
130
- // Make annotation non-enumerable, to not get it automatically printed,
131
- // but still accessible
132
- Object.defineProperty(data, 'annotation', {
133
- writable: true,
134
- configurable: true,
135
- enumerable: false,
136
- value: annotation,
137
- });
138
- return new JoiValidationError(msg, data);
139
- }
@@ -1,6 +0,0 @@
1
- import type Joi from 'joi';
2
- import type { Extension, NumberSchema as JoiNumberSchema } from 'joi';
3
- export interface NumberSchema<TSchema = number> extends JoiNumberSchema<TSchema> {
4
- dividable: (q: number) => this;
5
- }
6
- export declare function numberExtensions(joi: typeof Joi): Extension;
@@ -1,38 +0,0 @@
1
- export function numberExtensions(joi) {
2
- return {
3
- base: joi.number(),
4
- type: 'number',
5
- messages: {
6
- 'number.dividable': `"{{#label}}" must be dividable by {{#q}}`,
7
- },
8
- // validate (v, helpers) {
9
- // console.log('number validate called', {v})
10
- // },
11
- rules: {
12
- // Based on: https://github.com/hapijs/joi/blob/master/API.md#extensions
13
- dividable: {
14
- multi: true,
15
- method(q) {
16
- return this.$_addRule({
17
- name: 'dividable',
18
- args: { q },
19
- });
20
- },
21
- args: [
22
- {
23
- name: 'q',
24
- ref: true,
25
- assert: v => typeof v === 'number' && !Number.isNaN(v),
26
- message: 'must be a number',
27
- },
28
- ],
29
- validate(v, helpers, args) {
30
- if (v % args['q'] === 0) {
31
- return v;
32
- }
33
- return helpers.error('number.dividable', args);
34
- },
35
- },
36
- },
37
- };
38
- }
@@ -1,11 +0,0 @@
1
- import type { IsoDate } from '@naturalcycles/js-lib/types';
2
- import type Joi from 'joi';
3
- import type { Extension, StringSchema as JoiStringSchema } from 'joi';
4
- export interface StringSchema<TSchema = string> extends JoiStringSchema<TSchema> {
5
- dateString: (min?: IsoDate | 'today', max?: IsoDate | 'today') => StringSchema<IsoDate>;
6
- }
7
- export interface JoiDateStringOptions {
8
- min?: IsoDate | 'today';
9
- max?: IsoDate | 'today';
10
- }
11
- export declare function stringExtensions(joi: typeof Joi): Extension;