@naturalcycles/nodejs-lib 15.30.0 → 15.32.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.
@@ -1,6 +1,6 @@
1
1
  import { type ValidationFunction, type ValidationFunctionResult } from '@naturalcycles/js-lib';
2
2
  import type { JsonSchema, JsonSchemaBuilder } from '@naturalcycles/js-lib/json-schema';
3
- import { type ZodType } from '@naturalcycles/js-lib/zod';
3
+ import { ZodType } from '@naturalcycles/js-lib/zod';
4
4
  import type { Ajv } from 'ajv';
5
5
  import { AjvValidationError } from './ajvValidationError.js';
6
6
  export interface AjvValidationOptions {
@@ -63,7 +63,7 @@ export declare class AjvSchema<T = unknown> {
63
63
  * Implementation note: JsonSchemaBuilder goes first in the union type, otherwise TypeScript fails to infer <T> type
64
64
  * correctly for some reason.
65
65
  */
66
- static create<T>(schema: JsonSchemaBuilder<T> | JsonSchema<T> | AjvSchema<T>, cfg?: Partial<AjvSchemaCfg>): AjvSchema<T>;
66
+ static create<T>(schema: JsonSchemaBuilder<T> | JsonSchema<T> | AjvSchema<T> | ZodType<T>, cfg?: Partial<AjvSchemaCfg>): AjvSchema<T>;
67
67
  /**
68
68
  * @experimental
69
69
  */
@@ -81,5 +81,12 @@ export declare class AjvSchema<T = unknown> {
81
81
  isValid(input: T, opt?: AjvValidationOptions): boolean;
82
82
  getValidationResult(input: T, opt?: AjvValidationOptions): ValidationFunctionResult<T, AjvValidationError>;
83
83
  getValidationFunction(): ValidationFunction<T, AjvValidationError>;
84
+ static isZodSchemaWithAjvSchema<T>(schema: ZodType<T>): schema is ZodTypeWithAjvSchema<T>;
85
+ static cacheAjvSchemaInZodSchema<T>(zodSchema: ZodType<T>, ajvSchema: AjvSchema<T>): ZodTypeWithAjvSchema<T>;
86
+ static requireCachedAjvSchemaFromZodSchema<T>(zodSchema: ZodTypeWithAjvSchema<T>): AjvSchema<T>;
84
87
  private getAJVValidateFunction;
85
88
  }
89
+ export declare const HIDDEN_AJV_SCHEMA: unique symbol;
90
+ export interface ZodTypeWithAjvSchema<T> extends ZodType<T> {
91
+ [HIDDEN_AJV_SCHEMA]: AjvSchema<T>;
92
+ }
@@ -2,7 +2,7 @@ import { _isObject, _lazyValue, } from '@naturalcycles/js-lib';
2
2
  import { JsonSchemaAnyBuilder } from '@naturalcycles/js-lib/json-schema';
3
3
  import { _deepCopy, _filterNullishValues } from '@naturalcycles/js-lib/object';
4
4
  import { _substringBefore } from '@naturalcycles/js-lib/string';
5
- import { z } from '@naturalcycles/js-lib/zod';
5
+ import { z, ZodType } from '@naturalcycles/js-lib/zod';
6
6
  import { _inspect } from '../../string/inspect.js';
7
7
  import { AjvValidationError } from './ajvValidationError.js';
8
8
  import { getAjv } from './getAjv.js';
@@ -49,14 +49,21 @@ export class AjvSchema {
49
49
  if (schema instanceof JsonSchemaAnyBuilder) {
50
50
  return new AjvSchema(schema.build(), cfg);
51
51
  }
52
+ if (schema instanceof ZodType)
53
+ return AjvSchema.createFromZod(schema);
52
54
  return new AjvSchema(schema, cfg);
53
55
  }
54
56
  /**
55
57
  * @experimental
56
58
  */
57
59
  static createFromZod(zodSchema, cfg) {
60
+ if (AjvSchema.isZodSchemaWithAjvSchema(zodSchema)) {
61
+ return AjvSchema.requireCachedAjvSchemaFromZodSchema(zodSchema);
62
+ }
58
63
  const jsonSchema = z.toJSONSchema(zodSchema, { target: 'draft-7' });
59
- return new AjvSchema(jsonSchema, cfg);
64
+ const ajvSchema = new AjvSchema(jsonSchema, cfg);
65
+ AjvSchema.cacheAjvSchemaInZodSchema(zodSchema, ajvSchema);
66
+ return ajvSchema;
60
67
  }
61
68
  cfg;
62
69
  /**
@@ -114,6 +121,16 @@ export class AjvSchema {
114
121
  });
115
122
  };
116
123
  }
124
+ static isZodSchemaWithAjvSchema(schema) {
125
+ return !!schema[HIDDEN_AJV_SCHEMA];
126
+ }
127
+ static cacheAjvSchemaInZodSchema(zodSchema, ajvSchema) {
128
+ return Object.assign(zodSchema, { [HIDDEN_AJV_SCHEMA]: ajvSchema });
129
+ }
130
+ static requireCachedAjvSchemaFromZodSchema(zodSchema) {
131
+ return zodSchema[HIDDEN_AJV_SCHEMA];
132
+ }
117
133
  getAJVValidateFunction = _lazyValue(() => this.cfg.ajv.compile(this.schema));
118
134
  }
119
135
  const separator = '\n';
136
+ export const HIDDEN_AJV_SCHEMA = Symbol('HIDDEN_AJV_SCHEMA');
@@ -1,4 +1,4 @@
1
- import type { BaseDBEntity, IANATimezone, IsoDate, IsoDateTime, NumberEnum, StringEnum, UnixTimestamp, UnixTimestampMillis } from '@naturalcycles/js-lib/types';
1
+ import type { AnyObject, BaseDBEntity, IANATimezone, IsoDate, IsoDateTime, NumberEnum, StringEnum, UnixTimestamp, UnixTimestampMillis } from '@naturalcycles/js-lib/types';
2
2
  import type { AlternativesSchema, AnySchema, ArraySchema, ObjectSchema } from 'joi';
3
3
  import type { NumberSchema } from './number.extensions.js';
4
4
  import type { StringSchema } from './string.extensions.js';
@@ -33,8 +33,8 @@ export declare const numberEnumValueSchema: <ENUM extends NumberEnum>(en: ENUM)
33
33
  */
34
34
  export declare const numberEnumKeySchema: <ENUM extends NumberEnum>(en: ENUM) => StringSchema;
35
35
  export declare const urlSchema: (scheme?: string | string[]) => StringSchema;
36
- export declare function arraySchema<T>(items?: AnySchema<T>): ArraySchema<T[]>;
37
- export declare function objectSchema<T>(schema?: {
36
+ export declare function arraySchema<T>(items: AnySchema<T>): ArraySchema<T[]>;
37
+ export declare function objectSchema<T extends AnyObject>(schema: {
38
38
  [key in keyof Partial<T>]: AnySchema<T[key]>;
39
39
  }): ObjectSchema<T>;
40
40
  export declare function oneOfSchema<T = any>(...schemas: AnySchema[]): AlternativesSchema<T>;
@@ -37,7 +37,7 @@ export const numberEnumValueSchema = (en) => Joi.number().valid(..._numberEnumVa
37
37
  export const numberEnumKeySchema = (en) => Joi.string().valid(..._numberEnumKeys(en));
38
38
  export const urlSchema = (scheme = 'https') => Joi.string().uri({ scheme });
39
39
  export function arraySchema(items) {
40
- return items ? Joi.array().items(items) : Joi.array();
40
+ return Joi.array().items(items);
41
41
  }
42
42
  export function objectSchema(schema) {
43
43
  return Joi.object(schema);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@naturalcycles/nodejs-lib",
3
3
  "type": "module",
4
- "version": "15.30.0",
4
+ "version": "15.32.0",
5
5
  "dependencies": {
6
6
  "@naturalcycles/js-lib": "^15",
7
7
  "@types/js-yaml": "^4",
@@ -8,7 +8,7 @@ import type { JsonSchema, JsonSchemaBuilder } from '@naturalcycles/js-lib/json-s
8
8
  import { JsonSchemaAnyBuilder } from '@naturalcycles/js-lib/json-schema'
9
9
  import { _deepCopy, _filterNullishValues } from '@naturalcycles/js-lib/object'
10
10
  import { _substringBefore } from '@naturalcycles/js-lib/string'
11
- import { z, type ZodType } from '@naturalcycles/js-lib/zod'
11
+ import { z, ZodType } from '@naturalcycles/js-lib/zod'
12
12
  import type { Ajv } from 'ajv'
13
13
  import { _inspect } from '../../string/inspect.js'
14
14
  import { AjvValidationError } from './ajvValidationError.js'
@@ -105,13 +105,14 @@ export class AjvSchema<T = unknown> {
105
105
  * correctly for some reason.
106
106
  */
107
107
  static create<T>(
108
- schema: JsonSchemaBuilder<T> | JsonSchema<T> | AjvSchema<T>,
108
+ schema: JsonSchemaBuilder<T> | JsonSchema<T> | AjvSchema<T> | ZodType<T>,
109
109
  cfg?: Partial<AjvSchemaCfg>,
110
110
  ): AjvSchema<T> {
111
111
  if (schema instanceof AjvSchema) return schema
112
112
  if (schema instanceof JsonSchemaAnyBuilder) {
113
113
  return new AjvSchema<T>(schema.build(), cfg)
114
114
  }
115
+ if (schema instanceof ZodType) return AjvSchema.createFromZod(schema)
115
116
  return new AjvSchema<T>(schema as JsonSchema<T>, cfg)
116
117
  }
117
118
 
@@ -119,8 +120,16 @@ export class AjvSchema<T = unknown> {
119
120
  * @experimental
120
121
  */
121
122
  static createFromZod<T>(zodSchema: ZodType<T>, cfg?: Partial<AjvSchemaCfg>): AjvSchema<T> {
123
+ if (AjvSchema.isZodSchemaWithAjvSchema(zodSchema)) {
124
+ return AjvSchema.requireCachedAjvSchemaFromZodSchema(zodSchema)
125
+ }
126
+
122
127
  const jsonSchema = z.toJSONSchema(zodSchema, { target: 'draft-7' })
123
- return new AjvSchema<T>(jsonSchema as JsonSchema<T>, cfg)
128
+ const ajvSchema = new AjvSchema<T>(jsonSchema as JsonSchema<T>, cfg)
129
+
130
+ AjvSchema.cacheAjvSchemaInZodSchema(zodSchema, ajvSchema)
131
+
132
+ return ajvSchema
124
133
  }
125
134
 
126
135
  readonly cfg: AjvSchemaCfg
@@ -199,7 +208,28 @@ export class AjvSchema<T = unknown> {
199
208
  }
200
209
  }
201
210
 
211
+ static isZodSchemaWithAjvSchema<T>(schema: ZodType<T>): schema is ZodTypeWithAjvSchema<T> {
212
+ return !!(schema as any)[HIDDEN_AJV_SCHEMA]
213
+ }
214
+
215
+ static cacheAjvSchemaInZodSchema<T>(
216
+ zodSchema: ZodType<T>,
217
+ ajvSchema: AjvSchema<T>,
218
+ ): ZodTypeWithAjvSchema<T> {
219
+ return Object.assign(zodSchema, { [HIDDEN_AJV_SCHEMA]: ajvSchema })
220
+ }
221
+
222
+ static requireCachedAjvSchemaFromZodSchema<T>(zodSchema: ZodTypeWithAjvSchema<T>): AjvSchema<T> {
223
+ return zodSchema[HIDDEN_AJV_SCHEMA]
224
+ }
225
+
202
226
  private getAJVValidateFunction = _lazyValue(() => this.cfg.ajv.compile<T>(this.schema))
203
227
  }
204
228
 
205
229
  const separator = '\n'
230
+
231
+ export const HIDDEN_AJV_SCHEMA = Symbol('HIDDEN_AJV_SCHEMA')
232
+
233
+ export interface ZodTypeWithAjvSchema<T> extends ZodType<T> {
234
+ [HIDDEN_AJV_SCHEMA]: AjvSchema<T>
235
+ }
@@ -5,6 +5,7 @@ import {
5
5
  _stringEnumValues,
6
6
  } from '@naturalcycles/js-lib'
7
7
  import type {
8
+ AnyObject,
8
9
  BaseDBEntity,
9
10
  IANATimezone,
10
11
  IsoDate,
@@ -72,11 +73,11 @@ export const numberEnumKeySchema = <ENUM extends NumberEnum>(en: ENUM): StringSc
72
73
  export const urlSchema = (scheme: string | string[] = 'https'): StringSchema =>
73
74
  Joi.string().uri({ scheme })
74
75
 
75
- export function arraySchema<T>(items?: AnySchema<T>): ArraySchema<T[]> {
76
- return items ? Joi.array().items(items) : Joi.array()
76
+ export function arraySchema<T>(items: AnySchema<T>): ArraySchema<T[]> {
77
+ return Joi.array().items(items)
77
78
  }
78
79
 
79
- export function objectSchema<T>(schema?: {
80
+ export function objectSchema<T extends AnyObject>(schema: {
80
81
  [key in keyof Partial<T>]: AnySchema<T[key]>
81
82
  }): ObjectSchema<T> {
82
83
  return Joi.object(schema)