@cleverbrush/schema 0.0.7 → 0.0.8

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/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import SchemaValidator from './schemaValidator';
2
- export declare type DefaultSchemaType = 'object' | 'function' | 'number' | 'string' | 'array';
2
+ export declare type DefaultSchemaType = 'object' | 'function' | 'number' | 'string' | 'array' | 'alias';
3
3
  export declare type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
4
4
  export declare type DefaultPropertyDefinition = {
5
5
  isRequired: boolean;
@@ -24,6 +24,10 @@ export declare type ObjectSchemaDefinition<T> = Omit<SchemaDefintion<T>, 'type'>
24
24
  [S in keyof T]: Schema<PropType<T, S>>;
25
25
  }>;
26
26
  };
27
+ export declare type AliasSchemaDefinition<T> = Omit<SchemaDefintion<T>, 'type'> & {
28
+ type: 'alias';
29
+ schemaName: string;
30
+ };
27
31
  export declare type ObjectSchemaDefinitionParam<T> = Omit<ObjectSchemaDefinition<T>, 'type'>;
28
32
  export declare type ParamsValidators<TFunc extends (...args: any) => any> = {
29
33
  [S in keyof Parameters<TFunc>]: SingleSchema<Parameters<TFunc>[S]>;
@@ -53,7 +57,7 @@ export declare type ArraySchemaDefinition<TObj> = Omit<SchemaDefintion<TObj>, 't
53
57
  minLength?: number;
54
58
  maxLength?: number;
55
59
  };
56
- export declare type CompositeSchema<TObj> = TObj extends (...args: any) => any ? FunctionSchemaDefinition<TObj> : TObj extends number ? NumberSchemaDefinition<TObj> : TObj extends string ? StringSchemaDefinition<TObj> | 'string' : NumberSchemaDefinition<TObj> | StringSchemaDefinition<TObj> | ArraySchemaDefinition<TObj> | ObjectSchemaDefinition<TObj>;
60
+ export declare type CompositeSchema<TObj> = TObj extends (...args: any) => any ? FunctionSchemaDefinition<TObj> : TObj extends number ? NumberSchemaDefinition<TObj> : TObj extends string ? StringSchemaDefinition<TObj> | 'string' : NumberSchemaDefinition<TObj> | StringSchemaDefinition<TObj> | ArraySchemaDefinition<TObj> | ObjectSchemaDefinition<TObj> | AliasSchemaDefinition<TObj>;
57
61
  export declare type SingleSchema<TObj = Record<string, never>> = number | string | DefaultSchemaType | CompositeSchema<TObj>;
58
62
  export declare type Schema<TObj> = SingleSchema<TObj> | Array<SingleSchema<TObj>>;
59
63
  export interface ISchemaActions<K, T extends keyof K> {
@@ -95,6 +95,11 @@ class SchemaValidator {
95
95
  throw new Error('not implemented');
96
96
  }
97
97
  async checkValidators(schema, value) {
98
+ if (!schema.isRequired && typeof value === 'undefined') {
99
+ return {
100
+ valid: true
101
+ };
102
+ }
98
103
  if (Array.isArray(schema.validators)) {
99
104
  const validatorsResults = await Promise.allSettled(schema.validators.map((v) => Promise.resolve(v(value))));
100
105
  const rejections = validatorsResults
@@ -166,6 +171,19 @@ class SchemaValidator {
166
171
  if (isDefaultType(schema.type)) {
167
172
  return await this.validateDefaultType(schema.type, obj, schema);
168
173
  }
174
+ else if (schema.type === 'alias') {
175
+ const alias = this.schemas[schema.schemaName]
176
+ .schema;
177
+ if (Array.isArray(alias))
178
+ throw new Error('it is impossible to use alternative schema alias as "type" field');
179
+ if (typeof alias !== 'object')
180
+ throw new Error('it is only possible to use a full schema schema definition as alias');
181
+ const schemaToMerge = { ...schema };
182
+ delete schemaToMerge.type;
183
+ delete schemaToMerge.schemaName;
184
+ const finalSchema = (0, deep_1.deepExtend)(alias, schemaToMerge);
185
+ return await this.validate(finalSchema, obj);
186
+ }
169
187
  else if (schema.type === 'object') {
170
188
  const preliminaryResult = await (0, validateObject_1.validateObject)(obj, schema, this);
171
189
  if (!preliminaryResult.valid)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cleverbrush/schema",
3
- "version": "0.0.7",
3
+ "version": "0.0.8",
4
4
  "keywords": [
5
5
  "object schema validator",
6
6
  "schema",
@@ -19,7 +19,7 @@
19
19
  "build": "tsc"
20
20
  },
21
21
  "dependencies": {
22
- "@cleverbrush/deep": "0.0.7"
22
+ "@cleverbrush/deep": "0.0.8"
23
23
  },
24
24
  "types": "./dist/index.d.ts"
25
25
  }
package/src/index.ts CHANGED
@@ -5,7 +5,8 @@ export type DefaultSchemaType =
5
5
  | 'function'
6
6
  | 'number'
7
7
  | 'string'
8
- | 'array';
8
+ | 'array'
9
+ | 'alias';
9
10
 
10
11
  export type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
11
12
 
@@ -40,6 +41,11 @@ export type ObjectSchemaDefinition<T> = Omit<SchemaDefintion<T>, 'type'> & {
40
41
  }>;
41
42
  };
42
43
 
44
+ export type AliasSchemaDefinition<T> = Omit<SchemaDefintion<T>, 'type'> & {
45
+ type: 'alias';
46
+ schemaName: string;
47
+ };
48
+
43
49
  export type ObjectSchemaDefinitionParam<T> = Omit<
44
50
  ObjectSchemaDefinition<T>,
45
51
  'type'
@@ -100,7 +106,8 @@ export type CompositeSchema<TObj> = TObj extends (...args: any) => any
100
106
  | NumberSchemaDefinition<TObj>
101
107
  | StringSchemaDefinition<TObj>
102
108
  | ArraySchemaDefinition<TObj>
103
- | ObjectSchemaDefinition<TObj>;
109
+ | ObjectSchemaDefinition<TObj>
110
+ | AliasSchemaDefinition<TObj>;
104
111
 
105
112
  export type SingleSchema<TObj = Record<string, never>> =
106
113
  | number
@@ -913,7 +913,7 @@ test('Validate - one of - 1', async () => {
913
913
  expect(result).toHaveProperty('valid', true);
914
914
  });
915
915
 
916
- test('Validate schema', async () => {
916
+ test('Validate schema - 1', async () => {
917
917
  const authorsReportSpecificationSchema = {
918
918
  properties: {
919
919
  type: {
@@ -1120,3 +1120,35 @@ test('Validate schema', async () => {
1120
1120
 
1121
1121
  expect(result).toHaveProperty('valid', true);
1122
1122
  });
1123
+
1124
+ test('Validate schema - 2', async () => {
1125
+ const validator = new SchemaValidator().addSchemaType('Date', {
1126
+ validators: [
1127
+ (value) =>
1128
+ value instanceof Date && !Number.isNaN(value)
1129
+ ? {
1130
+ valid: true
1131
+ }
1132
+ : {
1133
+ valid: false,
1134
+ errors: ['should be a valid Date object']
1135
+ }
1136
+ ]
1137
+ });
1138
+
1139
+ const result = await validator.validate(
1140
+ {
1141
+ type: 'object',
1142
+ properties: {
1143
+ date: {
1144
+ type: 'alias',
1145
+ schemaName: 'Date',
1146
+ isRequired: false
1147
+ }
1148
+ }
1149
+ },
1150
+ {}
1151
+ );
1152
+
1153
+ expect(result).toHaveProperty('valid', true);
1154
+ });
@@ -156,6 +156,11 @@ export default class SchemaValidator<T = Record<string, never>>
156
156
  schema: CompositeSchema<Record<string, never>>,
157
157
  value: any
158
158
  ): Promise<ValidationResult> {
159
+ if (!schema.isRequired && typeof value === 'undefined') {
160
+ return {
161
+ valid: true
162
+ };
163
+ }
159
164
  if (Array.isArray(schema.validators)) {
160
165
  const validatorsResults = await Promise.allSettled(
161
166
  schema.validators.map((v) => Promise.resolve(v(value)))
@@ -251,6 +256,26 @@ export default class SchemaValidator<T = Record<string, never>>
251
256
  obj,
252
257
  schema
253
258
  );
259
+ } else if (schema.type === 'alias') {
260
+ const alias = this.schemas[schema.schemaName]
261
+ .schema as Schema<any>;
262
+ if (Array.isArray(alias))
263
+ throw new Error(
264
+ 'it is impossible to use alternative schema alias as "type" field'
265
+ );
266
+ if (typeof alias !== 'object')
267
+ throw new Error(
268
+ 'it is only possible to use a full schema schema definition as alias'
269
+ );
270
+
271
+ const schemaToMerge = { ...schema };
272
+ delete schemaToMerge.type;
273
+ delete schemaToMerge.schemaName;
274
+ const finalSchema: Schema<any> = deepExtend(
275
+ alias,
276
+ schemaToMerge
277
+ );
278
+ return await this.validate(finalSchema, obj);
254
279
  } else if (schema.type === 'object') {
255
280
  const preliminaryResult = await validateObject(
256
281
  obj,