valgen 3.2.1 → 4.0.0-alpha.3

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 (143) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +12 -7
  3. package/cjs/core/constants.js +5 -0
  4. package/cjs/core/context.js +65 -0
  5. package/cjs/core/index.js +21 -0
  6. package/cjs/core/types.js +2 -0
  7. package/cjs/core/validation-error.js +11 -0
  8. package/cjs/core/validator.js +61 -0
  9. package/cjs/helpers/object.utils.js +19 -0
  10. package/cjs/helpers/string.utils.js +9 -0
  11. package/cjs/index.js +18 -0
  12. package/cjs/package.json +3 -0
  13. package/cjs/rules/index.js +39 -0
  14. package/cjs/rules/is-any.js +12 -0
  15. package/cjs/rules/is-array.js +38 -0
  16. package/cjs/rules/is-bigint.js +21 -0
  17. package/cjs/rules/is-boolean.js +30 -0
  18. package/cjs/rules/is-date.js +63 -0
  19. package/cjs/rules/is-empty.js +68 -0
  20. package/cjs/rules/is-enum.js +30 -0
  21. package/cjs/rules/is-integer.js +26 -0
  22. package/cjs/rules/is-matches.js +24 -0
  23. package/cjs/rules/is-null.js +40 -0
  24. package/cjs/rules/is-number.js +26 -0
  25. package/cjs/rules/is-object-id.js +28 -0
  26. package/cjs/rules/is-object.js +103 -0
  27. package/cjs/rules/is-record.js +41 -0
  28. package/cjs/rules/is-string.js +79 -0
  29. package/cjs/rules/is-tuple.js +32 -0
  30. package/cjs/rules/length.js +41 -0
  31. package/cjs/rules/optional.js +44 -0
  32. package/cjs/rules/pipe.js +43 -0
  33. package/cjs/rules/range.js +89 -0
  34. package/cjs/rules/string-formats.js +296 -0
  35. package/cjs/rules/union.js +31 -0
  36. package/cjs/rules/utilities.js +31 -0
  37. package/esm/core/constants.js +2 -0
  38. package/esm/core/context.js +61 -0
  39. package/esm/core/index.js +5 -0
  40. package/esm/core/types.js +1 -0
  41. package/esm/core/validation-error.js +7 -0
  42. package/esm/core/validator.js +56 -0
  43. package/esm/helpers/object.utils.js +14 -0
  44. package/esm/helpers/string.utils.js +5 -0
  45. package/esm/index.js +2 -0
  46. package/esm/rules/index.js +23 -0
  47. package/esm/rules/is-any.js +8 -0
  48. package/esm/rules/is-array.js +34 -0
  49. package/esm/rules/is-bigint.js +17 -0
  50. package/esm/rules/is-boolean.js +26 -0
  51. package/esm/rules/is-date.js +55 -0
  52. package/esm/rules/is-empty.js +63 -0
  53. package/esm/rules/is-enum.js +26 -0
  54. package/esm/rules/is-integer.js +22 -0
  55. package/esm/rules/is-matches.js +20 -0
  56. package/esm/rules/is-null.js +34 -0
  57. package/esm/rules/is-number.js +22 -0
  58. package/esm/rules/is-object-id.js +21 -0
  59. package/esm/rules/is-object.js +99 -0
  60. package/esm/rules/is-record.js +37 -0
  61. package/esm/rules/is-string.js +70 -0
  62. package/esm/rules/is-tuple.js +28 -0
  63. package/esm/rules/length.js +35 -0
  64. package/esm/rules/optional.js +38 -0
  65. package/esm/rules/pipe.js +38 -0
  66. package/esm/rules/range.js +81 -0
  67. package/esm/rules/string-formats.js +266 -0
  68. package/esm/rules/union.js +27 -0
  69. package/esm/rules/utilities.js +26 -0
  70. package/package.json +33 -37
  71. package/typings/core/constants.d.ts +2 -0
  72. package/typings/core/context.d.ts +26 -0
  73. package/typings/core/index.d.ts +6 -0
  74. package/typings/core/types.d.ts +18 -0
  75. package/typings/core/validation-error.d.ts +5 -0
  76. package/typings/core/validator.d.ts +18 -0
  77. package/typings/helpers/object.utils.d.ts +2 -0
  78. package/typings/helpers/string.utils.d.ts +1 -0
  79. package/typings/index.d.ts +2 -0
  80. package/typings/rules/index.d.ts +23 -0
  81. package/typings/rules/is-any.d.ts +5 -0
  82. package/typings/rules/is-array.d.ts +7 -0
  83. package/typings/rules/is-bigint.d.ts +7 -0
  84. package/typings/rules/is-boolean.d.ts +7 -0
  85. package/typings/rules/is-date.d.ts +19 -0
  86. package/typings/rules/is-empty.d.ts +13 -0
  87. package/typings/rules/is-enum.d.ts +9 -0
  88. package/typings/rules/is-integer.d.ts +7 -0
  89. package/typings/rules/is-matches.d.ts +9 -0
  90. package/typings/rules/is-null.d.ts +16 -0
  91. package/typings/rules/is-number.d.ts +7 -0
  92. package/typings/rules/is-object-id.d.ts +10 -0
  93. package/typings/rules/is-object.d.ts +22 -0
  94. package/typings/rules/is-record.d.ts +7 -0
  95. package/typings/rules/is-string.d.ts +42 -0
  96. package/typings/rules/is-tuple.d.ts +27 -0
  97. package/typings/rules/length.d.ts +21 -0
  98. package/typings/rules/optional.d.ts +17 -0
  99. package/typings/rules/pipe.d.ts +11 -0
  100. package/typings/rules/range.d.ts +48 -0
  101. package/typings/rules/string-formats.d.ts +140 -0
  102. package/typings/rules/union.d.ts +5 -0
  103. package/typings/rules/utilities.d.ts +11 -0
  104. package/lib/ArrayType.d.ts +0 -5
  105. package/lib/ArrayType.js +0 -43
  106. package/lib/DataType.d.ts +0 -25
  107. package/lib/DataType.js +0 -214
  108. package/lib/ObjectType.d.ts +0 -5
  109. package/lib/ObjectType.js +0 -78
  110. package/lib/SchemaError.d.ts +0 -3
  111. package/lib/SchemaError.js +0 -17
  112. package/lib/UnionType.d.ts +0 -5
  113. package/lib/UnionType.js +0 -54
  114. package/lib/Valgen.d.ts +0 -88
  115. package/lib/Valgen.js +0 -289
  116. package/lib/ValidationError.d.ts +0 -2
  117. package/lib/ValidationError.js +0 -4
  118. package/lib/factories/AnyFactory.d.ts +0 -28
  119. package/lib/factories/AnyFactory.js +0 -73
  120. package/lib/factories/ArrayFactory.d.ts +0 -16
  121. package/lib/factories/ArrayFactory.js +0 -148
  122. package/lib/factories/Base64Factory.d.ts +0 -12
  123. package/lib/factories/Base64Factory.js +0 -31
  124. package/lib/factories/BooleanFactory.d.ts +0 -12
  125. package/lib/factories/BooleanFactory.js +0 -49
  126. package/lib/factories/DateFactory.d.ts +0 -40
  127. package/lib/factories/DateFactory.js +0 -239
  128. package/lib/factories/FunctionFactory.d.ts +0 -12
  129. package/lib/factories/FunctionFactory.js +0 -28
  130. package/lib/factories/IntegerFactory.d.ts +0 -14
  131. package/lib/factories/IntegerFactory.js +0 -33
  132. package/lib/factories/NilFactory.d.ts +0 -4
  133. package/lib/factories/NilFactory.js +0 -20
  134. package/lib/factories/NumberFactory.d.ts +0 -36
  135. package/lib/factories/NumberFactory.js +0 -178
  136. package/lib/factories/ObjectFactory.d.ts +0 -38
  137. package/lib/factories/ObjectFactory.js +0 -326
  138. package/lib/factories/StringFactory.d.ts +0 -16
  139. package/lib/factories/StringFactory.js +0 -94
  140. package/lib/factories/UnionFactory.d.ts +0 -13
  141. package/lib/factories/UnionFactory.js +0 -62
  142. package/lib/index.d.ts +0 -19
  143. package/lib/index.js +0 -37
package/lib/DataType.js DELETED
@@ -1,214 +0,0 @@
1
- 'use strict';
2
-
3
- const promisify = require('putil-promisify');
4
- const objectHash = require('object-hash');
5
- const {coalesce} = require('putil-varhelpers');
6
- const ValidationError = require('./ValidationError');
7
-
8
- const Failed = Symbol.for('Failed');
9
- const PROPERTY_PATTERN = /^[a-zA-Z]\w+$/;
10
-
11
- /**
12
- *
13
- * @class DataType
14
- */
15
- class DataType {
16
-
17
- constructor(library, typeName, factory) {
18
- if (!typeName)
19
- throw new TypeError(`You must provide type name.`);
20
- if (!factory || typeof factory !== 'object')
21
- throw new TypeError('Factory argument must be an object');
22
- if (typeof factory.generate !== 'function')
23
- throw new TypeError('Factory must contain a "generate" function');
24
- Object.defineProperties(this, {
25
- library: {
26
- writable: false,
27
- configurable: false,
28
- value: library
29
- },
30
- factory: {
31
- writable: false,
32
- configurable: false,
33
- value: factory
34
- },
35
- typeName: {
36
- writable: false,
37
- configurable: false,
38
- value: typeName
39
- }
40
- });
41
- this.options = {};
42
- this._fnCache = {};
43
- }
44
-
45
- create(instance, schema) {
46
- let proto = this;
47
- while (proto.predecessors) {
48
- const p = Object.getPrototypeOf(proto);
49
- if (!p.predecessors)
50
- break;
51
- proto = p;
52
- }
53
- Object.setPrototypeOf(instance, proto);
54
- instance.predecessors = [];
55
- schema = instance.schema = this.normalizeSchema(schema);
56
-
57
- if (schema.type) {
58
- const library = this.library;
59
- const stack = library._stack;
60
- stack.push('type');
61
- const types = Array.isArray(schema.type) ? schema.type : [schema.type];
62
- for (const sch of types) {
63
- if (sch === this.typeName)
64
- continue;
65
- const t = library.getType(sch);
66
- if (!(t.factory === instance.factory)) { // noinspection ExceptionCaughtLocallyJS
67
- throw new Error(`"${instance.typeName}" type can't be mixed with "${t.typeName}" type.`);
68
- }
69
- instance.predecessors.push(t);
70
- }
71
- stack.pop();
72
- }
73
- return instance;
74
- }
75
-
76
- normalizeSchema(schema) {
77
- const normalized = {};
78
- const library = this.library;
79
- if (schema.type) {
80
- let a = Array.isArray(schema.type) ? schema.type : [schema.type];
81
- a = a.map(s => {
82
- if (typeof s === 'string')
83
- s = library._parseTypeName(s);
84
- if (typeof s === 'string')
85
- return s;
86
- return library.normalizeSchema(s);
87
- });
88
- if (a.length <= 1) {
89
- if (typeof a[0] === 'object')
90
- Object.assign(schema, a[0]);
91
- else
92
- normalized.type = a[0];
93
- } else normalized.type = a;
94
- }
95
- if (this.factory.normalizeAttribute) {
96
- const stack = this.library._stack;
97
- for (const key of Object.keys(schema)) {
98
- let v = schema[key];
99
- if (v === undefined || key === 'type')
100
- continue;
101
- /* istanbul ignore else */
102
- stack.push(key);
103
- v = this.factory.normalizeAttribute(key, schema[key], schema);
104
- if (v !== undefined)
105
- normalized[key] = v;
106
- /* istanbul ignore else */
107
- stack.pop();
108
- }
109
- }
110
- return normalized;
111
- }
112
-
113
- generate(options = {}) {
114
- options.throwOnError =
115
- coalesce(options.throwOnError, this.library.throwOnError);
116
-
117
- /* istanbul ignore else */
118
- const preparedOptions = this.factory.normalizeCompileOptions ?
119
- this.factory.normalizeCompileOptions(options) : {...options};
120
- Object.keys(preparedOptions).forEach(k => {
121
- if (preparedOptions[k] === undefined)
122
- delete preparedOptions[k];
123
- });
124
-
125
- // Lookup for cached validator for same options
126
- const cacheId = objectHash({
127
- schema: this.schema,
128
- defaults: this.options,
129
- options: preparedOptions
130
- });
131
- let validate = this._fnCache[cacheId];
132
- if (validate)
133
- return validate;
134
-
135
- this._fnCache[cacheId] = function() {
136
- return validate.apply(this, arguments);
137
- };
138
-
139
- const fn = this.factory.generate(this, options);
140
-
141
- const callValidate = (value, ctx) => {
142
- ctx = ctx || {};
143
- const _path = ctx.path = ctx.path || [];
144
- ctx.errors = ctx.errors || [];
145
- ctx.logError = ctx.logError || (
146
- (e) => {
147
- if (ctx.path.length)
148
- e.path = ctx.path.slice();
149
- const s = ctx.getPath();
150
- if (s)
151
- e.message = 'Error at "' + s + '". ' + e.message;
152
- ctx.errors.push(e);
153
- return Failed;
154
- });
155
- ctx.getPath = ctx.getPath || (() => {
156
- let s = '';
157
- const len = _path.length;
158
- for (let i = 0; i < len; i++) {
159
- const x = _path[i];
160
- if (typeof x === 'number')
161
- s += '[' + x + ']';
162
- else if (x.match(PROPERTY_PATTERN))
163
- /* istanbul ignore next */
164
- s += (s ? '.' : '') + x;
165
- else
166
- s += '[' + x.replace(/'/g, '\\\'') + ']';
167
- }
168
- return s;
169
- });
170
-
171
- const v = fn(value, ctx);
172
- const valid = v !== Failed;
173
- if (options.throwOnError && ctx.errors.length) {
174
- const ee = new ValidationError(ctx.errors[0].message);
175
- // @ts-ignore
176
- ee.errors = ctx.errors;
177
- ee.value = value;
178
- Object.assign(ee, ctx.errors[0]);
179
- throw ee;
180
- }
181
- return ctx.errors.length ?
182
- {valid, errors: ctx.errors} :
183
- {valid, value: v};
184
- };
185
-
186
- validate = options.resolvePromises ?
187
- async (value, ctx) => {
188
- value = await promisify.deepResolve(value);
189
- return callValidate(value, ctx);
190
- } :
191
- (value, ctx) => callValidate(value, ctx);
192
- this._fnCache[cacheId] = validate;
193
- validate.dataType = this;
194
- return validate;
195
- }
196
-
197
- get(attr) {
198
- let v;
199
- v = this.schema[attr];
200
- if (v !== undefined)
201
- return v;
202
- if (this.predecessors) {
203
- let i = this.predecessors.length;
204
- while (i--) {
205
- v = this.predecessors[i].get(attr);
206
- if (v !== undefined)
207
- return v;
208
- }
209
- }
210
- }
211
-
212
- }
213
-
214
- module.exports = {DataType, Failed};
@@ -1,5 +0,0 @@
1
- import {DataType} from './DataType';
2
-
3
- export class ObjectType extends DataType {
4
- properties?: { [key: string]: DataType }
5
- }
package/lib/ObjectType.js DELETED
@@ -1,78 +0,0 @@
1
- 'use strict';
2
-
3
- const {DataType} = require('./DataType');
4
-
5
- const PROPERTY_NAME_PATTERN = /^([^?!]+)([?|!])?$/;
6
- const REQUIRED_PROPERTY_PATTERN = /^([^?!]+)([?|!])?$/;
7
-
8
- /**
9
- *
10
- * @class ObjectType
11
- */
12
- class ObjectType extends DataType {
13
-
14
- create(instance, schema) {
15
- instance = super.create(instance, schema);
16
- if (schema.properties) {
17
- instance.properties = {};
18
- const library = this.library;
19
- const stack = library._stack;
20
- stack.push('properties');
21
- for (const [k, p] of Object.entries(schema.properties)) {
22
- const m = k.match(REQUIRED_PROPERTY_PATTERN);
23
- stack.push(m[1]);
24
- const sch = library.normalizeSchema(p);
25
- const t = library.getType(sch);
26
- t.propertyName = m[1];
27
- if (m[2] === '!')
28
- t.required = true;
29
- else if (m[2] === '?')
30
- t.required = false;
31
- else if (typeof p === 'object' && p.required != null)
32
- t.required = p.required;
33
- if (typeof t.required === 'string')
34
- t.required = t.required.split(/\s*,\s*/);
35
- instance.properties[m[1]] = t;
36
- }
37
- stack.pop();
38
- }
39
- return instance;
40
- }
41
-
42
- get(attr) {
43
- if (attr.startsWith('properties.') && this.properties) {
44
- const p = this.properties[attr.substring(11)];
45
- if (p)
46
- return p;
47
- }
48
- return super.get(attr);
49
- }
50
-
51
- normalizeSchema(schema) {
52
- const normalized = super.normalizeSchema(schema);
53
- const properties = normalized.properties;
54
- if (properties) {
55
- const stack = this.library._stack;
56
- stack.push('properties');
57
- normalized.properties = {};
58
- for (const [k, sch] of Object.entries(properties)) {
59
- const m = k.match(PROPERTY_NAME_PATTERN);
60
- stack.push(k);
61
- const v = this.library.normalizeSchema(sch);
62
- if (v !== undefined) {
63
- normalized.properties[m[1]] = v;
64
- if (m[2] === '!')
65
- v.required = true;
66
- if (m[2] === '?')
67
- v.required = false;
68
- }
69
- stack.pop();
70
- }
71
- stack.pop();
72
- }
73
- return normalized;
74
- }
75
-
76
- }
77
-
78
- module.exports = {ObjectType};
@@ -1,3 +0,0 @@
1
- export class SchemaError extends Error {
2
- constructor(msg: string | Error, schemaStack: string[]);
3
- }
@@ -1,17 +0,0 @@
1
- class SchemaError extends Error {
2
- constructor(msg, schemaStack) {
3
- super(
4
- (schemaStack ? 'Schema error at ' + schemaStack.join('.') + '. ' :
5
- /* istanbul ignore next */ '') +
6
- (msg instanceof Error ? msg.message :
7
- /* istanbul ignore next */ msg));
8
- /* istanbul ignore else */
9
- if (schemaStack)
10
- this.schemaStack = schemaStack;
11
- /* istanbul ignore else */
12
- if (msg instanceof Error)
13
- this.stack = msg.stack;
14
- }
15
- }
16
-
17
- module.exports = {SchemaError};
@@ -1,5 +0,0 @@
1
- import {DataType} from './DataType';
2
-
3
- export class UnionType extends DataType {
4
- anyOf?: DataType[];
5
- }
package/lib/UnionType.js DELETED
@@ -1,54 +0,0 @@
1
- 'use strict';
2
- const merge = require('putil-merge');
3
- const {DataType} = require('./DataType');
4
-
5
- /**
6
- *
7
- * @class UnionType
8
- */
9
- class UnionType extends DataType {
10
-
11
- create(instance, schema) {
12
- instance = super.create(instance, schema);
13
- const library = this.library;
14
- const stack = library._stack;
15
- stack.push('anyOf');
16
-
17
- const additionalAttributes = merge({}, schema, {
18
- filter: (o, n) => !['name', 'type', 'anyOf'].includes(n)
19
- });
20
- const hasAdditionalAttributes = Object.keys(additionalAttributes).length;
21
- instance.anyOf = schema.anyOf.map(x => {
22
- if (hasAdditionalAttributes) {
23
- const sch = typeof x === 'string' ?
24
- {type: x, ...additionalAttributes} : {...x, ...additionalAttributes};
25
- return library.getType(sch);
26
- }
27
- return library.getType(x);
28
- });
29
-
30
- stack.pop();
31
- return instance;
32
- }
33
-
34
- get(attr) {
35
- if (attr === 'anyOf' && this.anyOf)
36
- return this.anyOf;
37
- return super.get(attr);
38
- }
39
-
40
- normalizeSchema(schema) {
41
- const normalized = super.normalizeSchema(schema);
42
- const items = normalized.items;
43
- if (items) {
44
- const stack = this.library._stack;
45
- stack.push('items');
46
- normalized.items = this.library.normalizeSchema(items);
47
- stack.pop();
48
- }
49
- return normalized;
50
- }
51
-
52
- }
53
-
54
- module.exports = {UnionType};
package/lib/Valgen.d.ts DELETED
@@ -1,88 +0,0 @@
1
- import {DataType} from "./DataType";
2
-
3
- export namespace Valgen {
4
- export type TypeSchemaDef = string | ITypeSchema;
5
- export type TypeLookupMethod = (typeName: string) => TypeSchemaDef;
6
-
7
- export interface ITypeSchema {
8
- type: string;
9
-
10
- [key: string]: any;
11
- }
12
-
13
- export interface ITypeFactory {
14
- generate: (base: DataType, options?: IGenerateOptions) => ValidateFunction;
15
- }
16
-
17
- export interface IGenerateOptions {
18
- resolvePromises?: boolean;
19
- strictFormat?: boolean;
20
- coerceTypes?: boolean;
21
- convertDates?: boolean;
22
- throwOnError?: boolean
23
- maxArrayErrors?: number;
24
- maxObjectErrors?: number;
25
- removeAdditional?: boolean | 'all';
26
- removeNull?: boolean;
27
- operation?: string; // 'get' | 'create' | 'update' | 'patch' | 'delete'
28
- }
29
-
30
- export type ValidateFunction = (value: any) => IValidationResult;
31
-
32
- export interface IValidationResult {
33
- valid: boolean;
34
- value?: any;
35
- errors?: IValidationError[];
36
- }
37
-
38
- export interface IValidationError {
39
- message: string;
40
- errorType?: string;
41
- path?: string;
42
-
43
- [index: string]: any;
44
- }
45
-
46
- export interface IOptions {
47
- defaultType?: string;
48
- throwOnError?: boolean;
49
- schemaLookup?: TypeLookupMethod;
50
- }
51
- }
52
-
53
- export class Valgen implements Valgen.IOptions {
54
- protected _instances: { [name: string]: DataType };
55
- protected _lookupSchemas: { [name: string]: Valgen.ITypeSchema };
56
- protected _stacks: string[][];
57
- private _idSeq: number;
58
- defaultType: string;
59
- baseTypes: { [name: string]: DataType };
60
- schemaLookup?: Valgen.TypeLookupMethod;
61
- schemas: { [index: string]: Valgen.TypeSchemaDef };
62
- throwOnError?: boolean;
63
-
64
- constructor(options?: Valgen.IOptions);
65
-
66
- addSchema(name: string, schema: Valgen.TypeSchemaDef);
67
-
68
- clearCache();
69
-
70
- generate(schema: Valgen.TypeSchemaDef, options?: Valgen.IGenerateOptions): Valgen.ValidateFunction;
71
-
72
- define(name: string, factory: Valgen.ITypeFactory): DataType;
73
-
74
- normalizeSchema(schema: Valgen.TypeSchemaDef): Valgen.ITypeSchema;
75
-
76
- getType(name: Valgen.TypeSchemaDef): DataType;
77
-
78
- setOption(key: string, value: any): void;
79
-
80
- protected _lookupForSchema(name: string): Valgen.TypeSchemaDef;
81
-
82
- protected _getBaseTypeName(schema: Valgen.TypeSchemaDef): string;
83
-
84
- protected _parseTypeName(v: string): Valgen.TypeSchemaDef;
85
-
86
- protected get _stack(): string[];
87
-
88
- }