@nattyjs/forms 0.0.1-beta.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.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # `forms`
2
+
3
+ > TODO: description
4
+
5
+ ## Usage
6
+
7
+ ```
8
+ const forms = require('forms');
9
+
10
+ // TODO: DEMONSTRATE API
11
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,525 @@
1
+ 'use strict';
2
+
3
+ const validationDecorators = require('@nattyjs/validation-decorators');
4
+
5
+ const _ReactiveFormContainer = class {
6
+ static register(config) {
7
+ const params = config.decoratorParams;
8
+ const target = config.decoratorParams.target.constructor.name;
9
+ let entityInfo = _ReactiveFormContainer.entityConfig.get(target);
10
+ let propertyInfo = null;
11
+ if (!entityInfo) {
12
+ _ReactiveFormContainer.entityConfig.set(target, { target: config.decoratorParams.target, properties: {} });
13
+ entityInfo = _ReactiveFormContainer.entityConfig.get(target);
14
+ }
15
+ propertyInfo = entityInfo.properties[params.propertyKey];
16
+ if (!propertyInfo)
17
+ propertyInfo = entityInfo.properties[params.propertyKey] = { validators: {}, sanitizers: {} };
18
+ if (!propertyInfo.propConfig && config.propConfig)
19
+ propertyInfo.propConfig = {};
20
+ if (config.propConfig)
21
+ propertyInfo.propConfig = { ...config.propConfig, ...propertyInfo.propConfig };
22
+ if (config.validatorConfig)
23
+ propertyInfo.validators[config.validatorConfig.name] = config.validatorConfig;
24
+ if (config.sanitizerConfig) {
25
+ propertyInfo.sanitizers[config.sanitizerConfig.name] = config.sanitizerConfig;
26
+ }
27
+ }
28
+ static getPropertyValidators(target, propName) {
29
+ const entityInfo = _ReactiveFormContainer.entityConfig.get(target);
30
+ const propertyInfo = entityInfo.properties[propName];
31
+ return propertyInfo ? propertyInfo.validators : {};
32
+ }
33
+ static getProperties(target) {
34
+ return _ReactiveFormContainer.entityConfig.get(target);
35
+ }
36
+ };
37
+ let ReactiveFormContainer = _ReactiveFormContainer;
38
+ ReactiveFormContainer.entityConfig = /* @__PURE__ */ new Map();
39
+
40
+ const nattyForms = new class {
41
+ constructor() {
42
+ this.formConfig = {
43
+ dateConfig: {
44
+ format: "ymd",
45
+ seperator: "-"
46
+ }
47
+ };
48
+ }
49
+ configure(config) {
50
+ this.formConfig = { ...this.formConfig, ...config };
51
+ validationDecorators.validationForms.configure(this.formConfig);
52
+ }
53
+ }();
54
+
55
+ function callValidator(config, validator) {
56
+ return {
57
+ config,
58
+ validator: (params) => {
59
+ const result = validator(config || {}, params);
60
+ return result;
61
+ }
62
+ };
63
+ }
64
+
65
+ function createInstance(model) {
66
+ let classInstance = Object.create(model.prototype);
67
+ try {
68
+ model.apply(classInstance);
69
+ } catch (ex) {
70
+ classInstance = Reflect.construct(model, []);
71
+ }
72
+ return classInstance;
73
+ }
74
+
75
+ const THIS = "this";
76
+ function expressionColumns(config, isNonValidationExpression = false) {
77
+ var columns = [];
78
+ if (config && config.conditionalExpression)
79
+ columns = expressionParser(config.conditionalExpression, isNonValidationExpression);
80
+ return columns;
81
+ }
82
+ function expressionParser(expression, isNonValidationExpression) {
83
+ let columns = [];
84
+ let expressionString = expression.toString();
85
+ let expressionArguments = extractArguments(expressionString);
86
+ if (expressionArguments.length > 0) {
87
+ let splitTexts = [];
88
+ expressionString.replace(/\s/g, "").replace(new RegExp(/{|}/, "g"), "").split(new RegExp(/return|===|!==|==|!=|>=|>|<=|<|&&/)).forEach((t) => {
89
+ let texts = t.replace(/\(|\)/g, "").split("||");
90
+ for (let text of texts)
91
+ splitTexts.push(text);
92
+ });
93
+ splitTexts.forEach((t) => {
94
+ expressionArguments.forEach((x, i) => {
95
+ t = t.trim();
96
+ if (t.startsWith(x + ".")) {
97
+ var splitText = t.split(".");
98
+ if (splitText.length == 2 || splitText.length >= 2 && isNonValidationExpression)
99
+ if (!isNonValidationExpression)
100
+ columns.push({ propName: splitText[1].trim(), argumentIndex: i == 3 ? 0 : i == 2 ? 1 : i == 1 ? -1 : i });
101
+ else
102
+ columns.push({ propName: getConditionPath(splitText), argumentIndex: i == 3 ? 0 : i == 2 ? 1 : i == 1 ? -1 : i });
103
+ else {
104
+ var arrayProp = splitText[1].split("[");
105
+ let jObject = {
106
+ propName: splitText[splitText.length - 1].trim(),
107
+ objectPropName: arrayProp[0],
108
+ arrayIndex: arrayProp.length > 1 ? arrayProp[1].replace("]", "") : void 0,
109
+ argumentIndex: i === 3 ? 0 : i === 2 ? 1 : i
110
+ };
111
+ columns.push(jObject);
112
+ }
113
+ }
114
+ });
115
+ });
116
+ }
117
+ return columns;
118
+ }
119
+ function extractArguments(splitText) {
120
+ let expressionArguments = [THIS];
121
+ if (splitText[0].trim() !== "(" && !splitText.trim().startsWith("function")) {
122
+ let text = splitText[0].split("=>")[0];
123
+ expressionArguments.push(text.trim().replace("(", "").replace(")", ""));
124
+ } else {
125
+ let splitTexts = splitText.match(/\(([^)]+)\)/g);
126
+ if (splitTexts && splitTexts[0])
127
+ splitTexts[0].split(",").forEach((t) => expressionArguments.push(t.trim().replace("(", "").replace(")", "")));
128
+ }
129
+ return expressionArguments;
130
+ }
131
+ function getConditionPath(texts) {
132
+ let path = "";
133
+ for (var i = 1; i < texts.length; i++)
134
+ path += texts.length - 1 == i ? texts[i].trim() : `${texts[i].trim()}.`;
135
+ return path;
136
+ }
137
+
138
+ function isObject(value) {
139
+ return !!value && typeof value === "object";
140
+ }
141
+
142
+ class FormArray extends Array {
143
+ constructor(childrens, params, typeFormGroup) {
144
+ super();
145
+ this.params = params;
146
+ this.typeFormGroup = typeFormGroup;
147
+ this.childrens = new Array();
148
+ this.init(childrens);
149
+ if (params) {
150
+ this.root = params.root;
151
+ this.parent = params.parent;
152
+ }
153
+ }
154
+ init(childrens) {
155
+ childrens.forEach((t) => {
156
+ const typeFormGroup = this.typeFormGroup;
157
+ const formGroup = new typeFormGroup(t, this.params);
158
+ this.childrens.push(formGroup);
159
+ this.push(formGroup);
160
+ });
161
+ }
162
+ get errors() {
163
+ const errors = [];
164
+ this.childrens.forEach((t, index) => {
165
+ const formGroupErrors = t.errors;
166
+ if (formGroupErrors)
167
+ errors.push({ ...formGroupErrors, index });
168
+ });
169
+ return errors.length == 0 ? null : errors;
170
+ }
171
+ get valid() {
172
+ return this.errors == null;
173
+ }
174
+ setServerErrors(errors) {
175
+ for (const error of errors) {
176
+ if (error.index !== void 0) {
177
+ delete error.index;
178
+ this.childrens[error.index].setServerErrors(error);
179
+ }
180
+ }
181
+ }
182
+ }
183
+
184
+ var RunValidatorStrategy = /* @__PURE__ */ ((RunValidatorStrategy2) => {
185
+ RunValidatorStrategy2[RunValidatorStrategy2["None"] = 0] = "None";
186
+ RunValidatorStrategy2[RunValidatorStrategy2["OnSubmit"] = 1] = "OnSubmit";
187
+ RunValidatorStrategy2[RunValidatorStrategy2["OnDirty"] = 2] = "OnDirty";
188
+ return RunValidatorStrategy2;
189
+ })(RunValidatorStrategy || {});
190
+
191
+ class FormGroup {
192
+ constructor(_value, formGroupParam) {
193
+ this._value = _value;
194
+ this.formGroupParam = formGroupParam;
195
+ this.properties = new Array();
196
+ this.runConditionally = {};
197
+ this.sanitizeProps = {};
198
+ this.childrens = /* @__PURE__ */ new Map();
199
+ this._serverErrors = {};
200
+ this._errors = {};
201
+ this._errorMessage = {};
202
+ if (formGroupParam) {
203
+ this.validators = formGroupParam.validators || {};
204
+ this.parent = formGroupParam.parent;
205
+ this.root = formGroupParam.root;
206
+ if (formGroupParam.type)
207
+ this._value = this.createClassInstance(this._value, formGroupParam.type);
208
+ }
209
+ this.properties = Object.keys(_value);
210
+ this.updatePropertiesOnClassInstance();
211
+ this.defineProperties();
212
+ this.parseValidatorsConfig();
213
+ }
214
+ get submit() {
215
+ return this._submit;
216
+ }
217
+ set submit(value) {
218
+ this._submit = value;
219
+ if (value)
220
+ this.runAllValidators();
221
+ }
222
+ createClassInstance(entity, type) {
223
+ const entityInfo = ReactiveFormContainer.getProperties(type.name);
224
+ if (entityInfo) {
225
+ if (entityInfo.properties) {
226
+ const properties = entityInfo.properties;
227
+ const instance = createInstance(type);
228
+ for (const [key, value] of Object.entries(entity)) {
229
+ if (properties[key] && properties[key].propConfig) {
230
+ const propConfig = properties[key].propConfig;
231
+ if (propConfig.type) {
232
+ if (propConfig.isArrayType) {
233
+ if (Array.isArray(entity[key])) {
234
+ instance[key] = new Array();
235
+ entity[key].forEach((item) => {
236
+ instance[key].push(
237
+ this.createClassInstance(item, propConfig.type)
238
+ );
239
+ });
240
+ }
241
+ } else
242
+ instance[key] = this.createClassInstance(entity[key], propConfig.type);
243
+ } else
244
+ instance[key] = value;
245
+ } else
246
+ instance[key] = value;
247
+ }
248
+ return instance;
249
+ }
250
+ }
251
+ return null;
252
+ }
253
+ getSanitizeValue(propName, propValue) {
254
+ if (this.sanitizeProps[propName]) {
255
+ for (const [key, value] of Object.entries(this.sanitizeProps[propName])) {
256
+ propValue = value.sanitizer(propValue, value.config);
257
+ }
258
+ }
259
+ return propValue;
260
+ }
261
+ getEntityInfo(entityInfo) {
262
+ const validators = {};
263
+ const properties = new Array();
264
+ const sanitizers = {};
265
+ if (entityInfo.properties) {
266
+ for (const [key, value] of Object.entries(entityInfo.properties)) {
267
+ validators[key] = new Array();
268
+ properties.push(key);
269
+ for (const validatorInfo of Object.entries(value.validators).values()) {
270
+ const validatorConfig = validatorInfo[1];
271
+ validators[key].push(callValidator(validatorConfig.config, validatorConfig.validator));
272
+ }
273
+ if (Object.keys(value.sanitizers).length > 0)
274
+ sanitizers[key] = value.sanitizers;
275
+ }
276
+ }
277
+ return { properties, validators, sanitizers };
278
+ }
279
+ updatePropertiesOnClassInstance() {
280
+ if (this._value.constructor) {
281
+ const entityInfo = ReactiveFormContainer.getProperties(this._value.constructor.name);
282
+ if (entityInfo) {
283
+ const { properties, validators, sanitizers } = this.getEntityInfo(entityInfo);
284
+ this.validators = validators, this.properties = properties;
285
+ this.sanitizeProps = sanitizers;
286
+ }
287
+ }
288
+ }
289
+ setServerErrors(errors) {
290
+ for (const [key, value] of Object.entries(errors)) {
291
+ const children = this.childrens.get(key);
292
+ if ((Array.isArray(value) || isObject(value)) && children) {
293
+ children.setServerErrors(value);
294
+ } else {
295
+ this._serverErrors[key] = value;
296
+ this.setErrorMessage(key, { server: { message: value } });
297
+ }
298
+ }
299
+ }
300
+ parseValidatorsConfig() {
301
+ if (this.validators) {
302
+ for (const [key, value] of Object.entries(this.validators)) {
303
+ if (Array.isArray(value))
304
+ value.forEach((v) => this.parseConditinalExpression(key, v));
305
+ else
306
+ this.parseConditinalExpression(key, value);
307
+ this.runValidator(key);
308
+ }
309
+ }
310
+ }
311
+ parseConditinalExpression(key, value) {
312
+ if (value.config) {
313
+ const columns = expressionColumns(value.config);
314
+ columns.forEach((t) => {
315
+ this.addConditionally(t.propName, key);
316
+ });
317
+ if (value.config.fieldName)
318
+ this.addConditionally(value.config.fieldName, key);
319
+ }
320
+ }
321
+ addConditionally(propName, key) {
322
+ if (!this.runConditionally[propName])
323
+ this.runConditionally[propName] = [];
324
+ if (this.runConditionally[propName].indexOf(key) == -1)
325
+ this.runConditionally[propName].push(key);
326
+ }
327
+ get value() {
328
+ return this._value;
329
+ }
330
+ runAllValidators() {
331
+ for (const key of this.properties) {
332
+ this.runValidator(key);
333
+ }
334
+ }
335
+ defineProperties() {
336
+ for (const key of this.properties) {
337
+ const value = this._value[key];
338
+ if (Array.isArray(value)) {
339
+ this.defineGroupProp(key, new FormArray(value, {
340
+ validators: this.validators[key] ? this.validators[key][0] : void 0,
341
+ parent: this,
342
+ root: this.root
343
+ }, FormGroup));
344
+ } else if (isObject(value)) {
345
+ this.defineGroupProp(key, new FormGroup(this._value[key], { parent: this, root: this.root || this, validators: this.validators[key] }));
346
+ } else {
347
+ this.defineProp(key, this._value, this.validators[key]);
348
+ }
349
+ }
350
+ }
351
+ defineGroupProp(propName, value) {
352
+ Object.defineProperty(this, propName, {
353
+ get: () => value
354
+ });
355
+ this.childrens.set(propName, value);
356
+ }
357
+ defineProp(propName, value, validator) {
358
+ let _propValue = this._value[propName];
359
+ this._value[propName] = this.getSanitizeValue(propName, this._value[propName]);
360
+ Object.defineProperty(this, propName, {
361
+ get: () => _propValue,
362
+ set: (value2) => {
363
+ _propValue = value2;
364
+ this.clearErrorMessage(propName);
365
+ delete this._serverErrors[propName];
366
+ this._value[propName] = this.getSanitizeValue(propName, value2);
367
+ this.runConditionalValidation(propName);
368
+ this.runValidator(propName);
369
+ }
370
+ });
371
+ }
372
+ runConditionalValidation(propName) {
373
+ const conditionalProps = this.runConditionally[propName];
374
+ if (conditionalProps)
375
+ conditionalProps.forEach((prop) => this.runValidator(prop));
376
+ }
377
+ runValidator(propName) {
378
+ if (nattyForms.formConfig?.runValidatorStrategy && nattyForms.formConfig?.runValidatorStrategy == RunValidatorStrategy.OnSubmit && this.submit || !nattyForms.formConfig?.runValidatorStrategy) {
379
+ if (this.validators) {
380
+ const validator = this.validators[propName];
381
+ if (validator) {
382
+ const errors = this.runValidation(validator, { name: propName, value: this._value[propName], current: this, root: this.root });
383
+ if (errors)
384
+ this._errors[propName] = errors;
385
+ else if (this._errors[propName])
386
+ delete this._errors[propName];
387
+ }
388
+ }
389
+ }
390
+ }
391
+ runValidation(validator, params) {
392
+ if (validator) {
393
+ if (Array.isArray(validator)) {
394
+ let jErrors = {};
395
+ validator.forEach((validatorFn) => {
396
+ const errors = validatorFn.validator(params);
397
+ if (errors) {
398
+ jErrors = { ...jErrors, ...errors };
399
+ }
400
+ });
401
+ const keys = Object.keys(jErrors);
402
+ if (keys.length > 0)
403
+ this.setErrorMessage(params.name, jErrors);
404
+ else
405
+ this.clearErrorMessage(params.name);
406
+ return keys.length > 0 ? jErrors : null;
407
+ } else {
408
+ const errors = validator.validator(params);
409
+ if (errors)
410
+ this.setErrorMessage(params.name, errors);
411
+ else {
412
+ this.clearErrorMessage(params.name);
413
+ }
414
+ return errors;
415
+ }
416
+ }
417
+ }
418
+ get errors() {
419
+ let errors = this._errors;
420
+ for (const [key, value] of this.childrens.entries()) {
421
+ const childGroupErrors = value.errors;
422
+ if (childGroupErrors)
423
+ errors = { ...errors, ...{ [key]: childGroupErrors } };
424
+ }
425
+ errors = { ...errors, ...this._serverErrors };
426
+ return Object.keys(errors).length == 0 ? null : errors;
427
+ }
428
+ get valid() {
429
+ return this.errors == null;
430
+ }
431
+ get errorMessage() {
432
+ return this._errorMessage;
433
+ }
434
+ setErrorMessage(name, errors) {
435
+ this._errorMessage[name] = errors[Object.keys(errors)[0]].message;
436
+ }
437
+ clearErrorMessage(name) {
438
+ delete this._errorMessage[name];
439
+ }
440
+ }
441
+
442
+ function useForm(entity, config) {
443
+ return new FormGroup(entity, {
444
+ type: config?.type,
445
+ validators: config?.validators
446
+ });
447
+ }
448
+
449
+ const Validators = {
450
+ required: (config) => callValidator(config, validationDecorators.ControlValidators.required)
451
+ };
452
+
453
+ validationDecorators.decoratorRegistrationCaller.register = ReactiveFormContainer.register;
454
+
455
+ exports.allOf = validationDecorators.decoratorAllOfValidation;
456
+ exports.alpha = validationDecorators.decoratorAlphaValidation;
457
+ exports.alphaNumeric = validationDecorators.decoratorAlphaNumericValidation;
458
+ exports.ascii = validationDecorators.decoratorAsciiValidation;
459
+ exports.blacklist = validationDecorators.decoratorBlacklistSanitizer;
460
+ exports.contains = validationDecorators.decoratorContainsValidation;
461
+ exports.creditCard = validationDecorators.decoratorCreditCardValidation;
462
+ exports.cusip = validationDecorators.decoratorCusipValidation;
463
+ exports.dataUri = validationDecorators.decoratorDataUriValidation;
464
+ exports.date = validationDecorators.decoratorDateValidation;
465
+ exports.different = validationDecorators.decoratorDifferentValdiation;
466
+ exports.digit = validationDecorators.decoratorDigitValidation;
467
+ exports.email = validationDecorators.decoratorEmailValidation;
468
+ exports.endsWith = validationDecorators.decoratorEndsWithValidation;
469
+ exports.escape = validationDecorators.decoratorEscapeSanitizer;
470
+ exports.even = validationDecorators.decoratorEvenValidation;
471
+ exports.extension = validationDecorators.decoratorExtensionValidation;
472
+ exports.factor = validationDecorators.decoratorFactorValidation;
473
+ exports.greaterThan = validationDecorators.decoratorGreaterThanValidation;
474
+ exports.greaterThanEqualTo = validationDecorators.decoratorGreaterThanEqualToValidation;
475
+ exports.hexColor = validationDecorators.decoratorHexColorValidation;
476
+ exports.ip = validationDecorators.decoratorIpValidation;
477
+ exports.json = validationDecorators.decoratorJsonValidation;
478
+ exports.latLong = validationDecorators.decoratorLatLongValidation;
479
+ exports.latitude = validationDecorators.decoratorLatitudeValdiation;
480
+ exports.leapYear = validationDecorators.decoratorLeapYearValidation;
481
+ exports.lessThan = validationDecorators.decoratorLessThanValidation;
482
+ exports.lessThanEqualTo = validationDecorators.decoratorLessThanEqualToValidation;
483
+ exports.longitude = validationDecorators.decoratorLongitudeValidation;
484
+ exports.lowerCase = validationDecorators.decoratorLowercaseValidation;
485
+ exports.ltrim = validationDecorators.decoratorLtrimSanitizer;
486
+ exports.mac = validationDecorators.decoratorMacValidation;
487
+ exports.maxDate = validationDecorators.decoratorMaxDateValidation;
488
+ exports.maxLength = validationDecorators.decoratorMaxLengthValidation;
489
+ exports.maxNumber = validationDecorators.decoratorMaxNumberValidation;
490
+ exports.maxTime = validationDecorators.decoratorMaxTimeValidation;
491
+ exports.minDate = validationDecorators.decoratorMinDateValidation;
492
+ exports.minLength = validationDecorators.decoratorMinLengthValidation;
493
+ exports.minNumber = validationDecorators.decoratorMinNumberValidation;
494
+ exports.minTime = validationDecorators.decoratorMinTimeValidation;
495
+ exports.noneOf = validationDecorators.decoratorNoneOfValidation;
496
+ exports.notEmpty = validationDecorators.decoratorNotEmptyValidation;
497
+ exports.numeric = validationDecorators.decoratorNumericValidation;
498
+ exports.odd = validationDecorators.decoratorOddValidation;
499
+ exports.oneOf = validationDecorators.decoratorOneOfValidation;
500
+ exports.password = validationDecorators.decoratorPasswordValdiation;
501
+ exports.pattern = validationDecorators.decoratorPatternValidation;
502
+ exports.port = validationDecorators.decoratorPortValidation;
503
+ exports.prefix = validationDecorators.decoratorPrefixSanitizer;
504
+ exports.primeNumber = validationDecorators.decoratorPrimeNumberValidation;
505
+ exports.prop = validationDecorators.prop;
506
+ exports.range = validationDecorators.decoratorRangeValidation;
507
+ exports.required = validationDecorators.decoratorRequiredValidation;
508
+ exports.requiredTrue = validationDecorators.decoratorRequiredTrueValidation;
509
+ exports.rtrim = validationDecorators.decoratorRtrimSanitizer;
510
+ exports.sanitize = validationDecorators.decoratorSanitizeSanitizer;
511
+ exports.startsWith = validationDecorators.decoratorStartsWithValidation;
512
+ exports.stripLow = validationDecorators.decoratorStripLowSanitizer;
513
+ exports.suffix = validationDecorators.decoratorSuffixSanitizer;
514
+ exports.toBoolean = validationDecorators.decoratorToBooleanSanitizer;
515
+ exports.toDate = validationDecorators.decoratorToDateSanitizer;
516
+ exports.toInt = validationDecorators.decoratorToIntSanitizer;
517
+ exports.toString = validationDecorators.decoratorToStringSanitizer;
518
+ exports.trim = validationDecorators.decoratorTrimSanitizer;
519
+ exports.upperCase = validationDecorators.decoratorUpperCaseValidation;
520
+ exports.url = validationDecorators.decoratorUrlValidation;
521
+ exports.whitelist = validationDecorators.decoratorWhitelistSanitizer;
522
+ exports.RunValidatorStrategy = RunValidatorStrategy;
523
+ exports.Validators = Validators;
524
+ exports.nattyForms = nattyForms;
525
+ exports.useForm = useForm;
@@ -0,0 +1,66 @@
1
+ import { ValidatorFn, FormConfig, RequiredConfig } from '@nattyjs/validation-decorators';
2
+ export { decoratorAllOfValidation as allOf, decoratorAlphaValidation as alpha, decoratorAlphaNumericValidation as alphaNumeric, decoratorAsciiValidation as ascii, decoratorBlacklistSanitizer as blacklist, decoratorContainsValidation as contains, decoratorCreditCardValidation as creditCard, decoratorCusipValidation as cusip, decoratorDataUriValidation as dataUri, decoratorDateValidation as date, decoratorDifferentValdiation as different, decoratorDigitValidation as digit, decoratorEmailValidation as email, decoratorEndsWithValidation as endsWith, decoratorEscapeSanitizer as escape, decoratorEvenValidation as even, decoratorExtensionValidation as extension, decoratorFactorValidation as factor, decoratorGreaterThanValidation as greaterThan, decoratorGreaterThanEqualToValidation as greaterThanEqualTo, decoratorHexColorValidation as hexColor, decoratorIpValidation as ip, decoratorJsonValidation as json, decoratorLatLongValidation as latLong, decoratorLatitudeValdiation as latitude, decoratorLeapYearValidation as leapYear, decoratorLessThanValidation as lessThan, decoratorLessThanEqualToValidation as lessThanEqualTo, decoratorLongitudeValidation as longitude, decoratorLowercaseValidation as lowerCase, decoratorLtrimSanitizer as ltrim, decoratorMacValidation as mac, decoratorMaxDateValidation as maxDate, decoratorMaxLengthValidation as maxLength, decoratorMaxNumberValidation as maxNumber, decoratorMaxTimeValidation as maxTime, decoratorMinDateValidation as minDate, decoratorMinLengthValidation as minLength, decoratorMinNumberValidation as minNumber, decoratorMinTimeValidation as minTime, decoratorNoneOfValidation as noneOf, decoratorNotEmptyValidation as notEmpty, decoratorNumericValidation as numeric, decoratorOddValidation as odd, decoratorOneOfValidation as oneOf, decoratorPasswordValdiation as password, decoratorPatternValidation as pattern, decoratorPortValidation as port, decoratorPrefixSanitizer as prefix, decoratorPrimeNumberValidation as primeNumber, prop, decoratorRangeValidation as range, decoratorRequiredValidation as required, decoratorRequiredTrueValidation as requiredTrue, decoratorRtrimSanitizer as rtrim, decoratorSanitizeSanitizer as sanitize, decoratorStartsWithValidation as startsWith, decoratorStripLowSanitizer as stripLow, decoratorSuffixSanitizer as suffix, decoratorToBooleanSanitizer as toBoolean, decoratorToDateSanitizer as toDate, decoratorToIntSanitizer as toInt, decoratorToStringSanitizer as toString, decoratorTrimSanitizer as trim, decoratorUpperCaseValidation as upperCase, decoratorUrlValidation as url, decoratorWhitelistSanitizer as whitelist } from '@nattyjs/validation-decorators';
3
+
4
+ interface Type<T> extends Function {
5
+ new (...args: any[]): T;
6
+ }
7
+
8
+ interface IFormGroup {
9
+ get valid(): boolean;
10
+ get root(): IFormGroup;
11
+ get parent(): IFormGroup;
12
+ get errors(): ValidatorFn;
13
+ submit: boolean;
14
+ get errorMessage(): {
15
+ [key: string]: string;
16
+ };
17
+ get value(): any;
18
+ setServerErrors(value: {
19
+ [key: string]: any;
20
+ }): void;
21
+ }
22
+
23
+ type PropValidator = {
24
+ config: any;
25
+ validator: (params: any) => ValidatorFn;
26
+ };
27
+ type ValidatorConfig<T> = {
28
+ [key in keyof Partial<T>]: PropertyValidatorType<T[key], T[key]>;
29
+ };
30
+ type PropertyValidatorType<T, Prop> = T extends number ? PropValidator : T extends string ? PropValidator : T extends object ? ValidatorConfig<T> : T extends Array<T> ? ValidatorConfig<T> : T;
31
+
32
+ type ControlConfig<T> = {
33
+ [key in keyof T]: FormGroupDefinition<T[key], T[key]>;
34
+ };
35
+ type FormGroupDefinition<T, Prop> = T extends number ? number : T extends string ? string : T extends object ? ControlConfig<T> & IFormGroup : T extends Array<T> ? ControlConfig<T>[] & IFormGroup : T;
36
+
37
+ declare function useForm<T>(entity: T, config?: {
38
+ type?: Type<T>;
39
+ validators?: {
40
+ [key in keyof Partial<T>]: PropertyValidatorType<T[key], T[key]>;
41
+ };
42
+ }): ControlConfig<T> & IFormGroup;
43
+
44
+ declare enum RunValidatorStrategy {
45
+ None = 0,
46
+ OnSubmit = 1,
47
+ OnDirty = 2
48
+ }
49
+
50
+ interface NattyFormConfig extends FormConfig {
51
+ runValidatorStrategy?: RunValidatorStrategy;
52
+ }
53
+
54
+ declare const nattyForms: {
55
+ formConfig: NattyFormConfig;
56
+ configure(config: NattyFormConfig): any;
57
+ };
58
+
59
+ declare const Validators: {
60
+ required: (config?: RequiredConfig) => {
61
+ config: any;
62
+ validator: (params: any) => any;
63
+ };
64
+ };
65
+
66
+ export { IFormGroup, RunValidatorStrategy, Validators, nattyForms, useForm };
package/dist/index.mjs ADDED
@@ -0,0 +1,454 @@
1
+ import { validationForms, ControlValidators, decoratorRegistrationCaller } from '@nattyjs/validation-decorators';
2
+ export { decoratorAllOfValidation as allOf, decoratorAlphaValidation as alpha, decoratorAlphaNumericValidation as alphaNumeric, decoratorAsciiValidation as ascii, decoratorBlacklistSanitizer as blacklist, decoratorContainsValidation as contains, decoratorCreditCardValidation as creditCard, decoratorCusipValidation as cusip, decoratorDataUriValidation as dataUri, decoratorDateValidation as date, decoratorDifferentValdiation as different, decoratorDigitValidation as digit, decoratorEmailValidation as email, decoratorEndsWithValidation as endsWith, decoratorEscapeSanitizer as escape, decoratorEvenValidation as even, decoratorExtensionValidation as extension, decoratorFactorValidation as factor, decoratorGreaterThanValidation as greaterThan, decoratorGreaterThanEqualToValidation as greaterThanEqualTo, decoratorHexColorValidation as hexColor, decoratorIpValidation as ip, decoratorJsonValidation as json, decoratorLatLongValidation as latLong, decoratorLatitudeValdiation as latitude, decoratorLeapYearValidation as leapYear, decoratorLessThanValidation as lessThan, decoratorLessThanEqualToValidation as lessThanEqualTo, decoratorLongitudeValidation as longitude, decoratorLowercaseValidation as lowerCase, decoratorLtrimSanitizer as ltrim, decoratorMacValidation as mac, decoratorMaxDateValidation as maxDate, decoratorMaxLengthValidation as maxLength, decoratorMaxNumberValidation as maxNumber, decoratorMaxTimeValidation as maxTime, decoratorMinDateValidation as minDate, decoratorMinLengthValidation as minLength, decoratorMinNumberValidation as minNumber, decoratorMinTimeValidation as minTime, decoratorNoneOfValidation as noneOf, decoratorNotEmptyValidation as notEmpty, decoratorNumericValidation as numeric, decoratorOddValidation as odd, decoratorOneOfValidation as oneOf, decoratorPasswordValdiation as password, decoratorPatternValidation as pattern, decoratorPortValidation as port, decoratorPrefixSanitizer as prefix, decoratorPrimeNumberValidation as primeNumber, prop, decoratorRangeValidation as range, decoratorRequiredValidation as required, decoratorRequiredTrueValidation as requiredTrue, decoratorRtrimSanitizer as rtrim, decoratorSanitizeSanitizer as sanitize, decoratorStartsWithValidation as startsWith, decoratorStripLowSanitizer as stripLow, decoratorSuffixSanitizer as suffix, decoratorToBooleanSanitizer as toBoolean, decoratorToDateSanitizer as toDate, decoratorToIntSanitizer as toInt, decoratorToStringSanitizer as toString, decoratorTrimSanitizer as trim, decoratorUpperCaseValidation as upperCase, decoratorUrlValidation as url, decoratorWhitelistSanitizer as whitelist } from '@nattyjs/validation-decorators';
3
+
4
+ const _ReactiveFormContainer = class {
5
+ static register(config) {
6
+ const params = config.decoratorParams;
7
+ const target = config.decoratorParams.target.constructor.name;
8
+ let entityInfo = _ReactiveFormContainer.entityConfig.get(target);
9
+ let propertyInfo = null;
10
+ if (!entityInfo) {
11
+ _ReactiveFormContainer.entityConfig.set(target, { target: config.decoratorParams.target, properties: {} });
12
+ entityInfo = _ReactiveFormContainer.entityConfig.get(target);
13
+ }
14
+ propertyInfo = entityInfo.properties[params.propertyKey];
15
+ if (!propertyInfo)
16
+ propertyInfo = entityInfo.properties[params.propertyKey] = { validators: {}, sanitizers: {} };
17
+ if (!propertyInfo.propConfig && config.propConfig)
18
+ propertyInfo.propConfig = {};
19
+ if (config.propConfig)
20
+ propertyInfo.propConfig = { ...config.propConfig, ...propertyInfo.propConfig };
21
+ if (config.validatorConfig)
22
+ propertyInfo.validators[config.validatorConfig.name] = config.validatorConfig;
23
+ if (config.sanitizerConfig) {
24
+ propertyInfo.sanitizers[config.sanitizerConfig.name] = config.sanitizerConfig;
25
+ }
26
+ }
27
+ static getPropertyValidators(target, propName) {
28
+ const entityInfo = _ReactiveFormContainer.entityConfig.get(target);
29
+ const propertyInfo = entityInfo.properties[propName];
30
+ return propertyInfo ? propertyInfo.validators : {};
31
+ }
32
+ static getProperties(target) {
33
+ return _ReactiveFormContainer.entityConfig.get(target);
34
+ }
35
+ };
36
+ let ReactiveFormContainer = _ReactiveFormContainer;
37
+ ReactiveFormContainer.entityConfig = /* @__PURE__ */ new Map();
38
+
39
+ const nattyForms = new class {
40
+ constructor() {
41
+ this.formConfig = {
42
+ dateConfig: {
43
+ format: "ymd",
44
+ seperator: "-"
45
+ }
46
+ };
47
+ }
48
+ configure(config) {
49
+ this.formConfig = { ...this.formConfig, ...config };
50
+ validationForms.configure(this.formConfig);
51
+ }
52
+ }();
53
+
54
+ function callValidator(config, validator) {
55
+ return {
56
+ config,
57
+ validator: (params) => {
58
+ const result = validator(config || {}, params);
59
+ return result;
60
+ }
61
+ };
62
+ }
63
+
64
+ function createInstance(model) {
65
+ let classInstance = Object.create(model.prototype);
66
+ try {
67
+ model.apply(classInstance);
68
+ } catch (ex) {
69
+ classInstance = Reflect.construct(model, []);
70
+ }
71
+ return classInstance;
72
+ }
73
+
74
+ const THIS = "this";
75
+ function expressionColumns(config, isNonValidationExpression = false) {
76
+ var columns = [];
77
+ if (config && config.conditionalExpression)
78
+ columns = expressionParser(config.conditionalExpression, isNonValidationExpression);
79
+ return columns;
80
+ }
81
+ function expressionParser(expression, isNonValidationExpression) {
82
+ let columns = [];
83
+ let expressionString = expression.toString();
84
+ let expressionArguments = extractArguments(expressionString);
85
+ if (expressionArguments.length > 0) {
86
+ let splitTexts = [];
87
+ expressionString.replace(/\s/g, "").replace(new RegExp(/{|}/, "g"), "").split(new RegExp(/return|===|!==|==|!=|>=|>|<=|<|&&/)).forEach((t) => {
88
+ let texts = t.replace(/\(|\)/g, "").split("||");
89
+ for (let text of texts)
90
+ splitTexts.push(text);
91
+ });
92
+ splitTexts.forEach((t) => {
93
+ expressionArguments.forEach((x, i) => {
94
+ t = t.trim();
95
+ if (t.startsWith(x + ".")) {
96
+ var splitText = t.split(".");
97
+ if (splitText.length == 2 || splitText.length >= 2 && isNonValidationExpression)
98
+ if (!isNonValidationExpression)
99
+ columns.push({ propName: splitText[1].trim(), argumentIndex: i == 3 ? 0 : i == 2 ? 1 : i == 1 ? -1 : i });
100
+ else
101
+ columns.push({ propName: getConditionPath(splitText), argumentIndex: i == 3 ? 0 : i == 2 ? 1 : i == 1 ? -1 : i });
102
+ else {
103
+ var arrayProp = splitText[1].split("[");
104
+ let jObject = {
105
+ propName: splitText[splitText.length - 1].trim(),
106
+ objectPropName: arrayProp[0],
107
+ arrayIndex: arrayProp.length > 1 ? arrayProp[1].replace("]", "") : void 0,
108
+ argumentIndex: i === 3 ? 0 : i === 2 ? 1 : i
109
+ };
110
+ columns.push(jObject);
111
+ }
112
+ }
113
+ });
114
+ });
115
+ }
116
+ return columns;
117
+ }
118
+ function extractArguments(splitText) {
119
+ let expressionArguments = [THIS];
120
+ if (splitText[0].trim() !== "(" && !splitText.trim().startsWith("function")) {
121
+ let text = splitText[0].split("=>")[0];
122
+ expressionArguments.push(text.trim().replace("(", "").replace(")", ""));
123
+ } else {
124
+ let splitTexts = splitText.match(/\(([^)]+)\)/g);
125
+ if (splitTexts && splitTexts[0])
126
+ splitTexts[0].split(",").forEach((t) => expressionArguments.push(t.trim().replace("(", "").replace(")", "")));
127
+ }
128
+ return expressionArguments;
129
+ }
130
+ function getConditionPath(texts) {
131
+ let path = "";
132
+ for (var i = 1; i < texts.length; i++)
133
+ path += texts.length - 1 == i ? texts[i].trim() : `${texts[i].trim()}.`;
134
+ return path;
135
+ }
136
+
137
+ function isObject(value) {
138
+ return !!value && typeof value === "object";
139
+ }
140
+
141
+ class FormArray extends Array {
142
+ constructor(childrens, params, typeFormGroup) {
143
+ super();
144
+ this.params = params;
145
+ this.typeFormGroup = typeFormGroup;
146
+ this.childrens = new Array();
147
+ this.init(childrens);
148
+ if (params) {
149
+ this.root = params.root;
150
+ this.parent = params.parent;
151
+ }
152
+ }
153
+ init(childrens) {
154
+ childrens.forEach((t) => {
155
+ const typeFormGroup = this.typeFormGroup;
156
+ const formGroup = new typeFormGroup(t, this.params);
157
+ this.childrens.push(formGroup);
158
+ this.push(formGroup);
159
+ });
160
+ }
161
+ get errors() {
162
+ const errors = [];
163
+ this.childrens.forEach((t, index) => {
164
+ const formGroupErrors = t.errors;
165
+ if (formGroupErrors)
166
+ errors.push({ ...formGroupErrors, index });
167
+ });
168
+ return errors.length == 0 ? null : errors;
169
+ }
170
+ get valid() {
171
+ return this.errors == null;
172
+ }
173
+ setServerErrors(errors) {
174
+ for (const error of errors) {
175
+ if (error.index !== void 0) {
176
+ delete error.index;
177
+ this.childrens[error.index].setServerErrors(error);
178
+ }
179
+ }
180
+ }
181
+ }
182
+
183
+ var RunValidatorStrategy = /* @__PURE__ */ ((RunValidatorStrategy2) => {
184
+ RunValidatorStrategy2[RunValidatorStrategy2["None"] = 0] = "None";
185
+ RunValidatorStrategy2[RunValidatorStrategy2["OnSubmit"] = 1] = "OnSubmit";
186
+ RunValidatorStrategy2[RunValidatorStrategy2["OnDirty"] = 2] = "OnDirty";
187
+ return RunValidatorStrategy2;
188
+ })(RunValidatorStrategy || {});
189
+
190
+ class FormGroup {
191
+ constructor(_value, formGroupParam) {
192
+ this._value = _value;
193
+ this.formGroupParam = formGroupParam;
194
+ this.properties = new Array();
195
+ this.runConditionally = {};
196
+ this.sanitizeProps = {};
197
+ this.childrens = /* @__PURE__ */ new Map();
198
+ this._serverErrors = {};
199
+ this._errors = {};
200
+ this._errorMessage = {};
201
+ if (formGroupParam) {
202
+ this.validators = formGroupParam.validators || {};
203
+ this.parent = formGroupParam.parent;
204
+ this.root = formGroupParam.root;
205
+ if (formGroupParam.type)
206
+ this._value = this.createClassInstance(this._value, formGroupParam.type);
207
+ }
208
+ this.properties = Object.keys(_value);
209
+ this.updatePropertiesOnClassInstance();
210
+ this.defineProperties();
211
+ this.parseValidatorsConfig();
212
+ }
213
+ get submit() {
214
+ return this._submit;
215
+ }
216
+ set submit(value) {
217
+ this._submit = value;
218
+ if (value)
219
+ this.runAllValidators();
220
+ }
221
+ createClassInstance(entity, type) {
222
+ const entityInfo = ReactiveFormContainer.getProperties(type.name);
223
+ if (entityInfo) {
224
+ if (entityInfo.properties) {
225
+ const properties = entityInfo.properties;
226
+ const instance = createInstance(type);
227
+ for (const [key, value] of Object.entries(entity)) {
228
+ if (properties[key] && properties[key].propConfig) {
229
+ const propConfig = properties[key].propConfig;
230
+ if (propConfig.type) {
231
+ if (propConfig.isArrayType) {
232
+ if (Array.isArray(entity[key])) {
233
+ instance[key] = new Array();
234
+ entity[key].forEach((item) => {
235
+ instance[key].push(
236
+ this.createClassInstance(item, propConfig.type)
237
+ );
238
+ });
239
+ }
240
+ } else
241
+ instance[key] = this.createClassInstance(entity[key], propConfig.type);
242
+ } else
243
+ instance[key] = value;
244
+ } else
245
+ instance[key] = value;
246
+ }
247
+ return instance;
248
+ }
249
+ }
250
+ return null;
251
+ }
252
+ getSanitizeValue(propName, propValue) {
253
+ if (this.sanitizeProps[propName]) {
254
+ for (const [key, value] of Object.entries(this.sanitizeProps[propName])) {
255
+ propValue = value.sanitizer(propValue, value.config);
256
+ }
257
+ }
258
+ return propValue;
259
+ }
260
+ getEntityInfo(entityInfo) {
261
+ const validators = {};
262
+ const properties = new Array();
263
+ const sanitizers = {};
264
+ if (entityInfo.properties) {
265
+ for (const [key, value] of Object.entries(entityInfo.properties)) {
266
+ validators[key] = new Array();
267
+ properties.push(key);
268
+ for (const validatorInfo of Object.entries(value.validators).values()) {
269
+ const validatorConfig = validatorInfo[1];
270
+ validators[key].push(callValidator(validatorConfig.config, validatorConfig.validator));
271
+ }
272
+ if (Object.keys(value.sanitizers).length > 0)
273
+ sanitizers[key] = value.sanitizers;
274
+ }
275
+ }
276
+ return { properties, validators, sanitizers };
277
+ }
278
+ updatePropertiesOnClassInstance() {
279
+ if (this._value.constructor) {
280
+ const entityInfo = ReactiveFormContainer.getProperties(this._value.constructor.name);
281
+ if (entityInfo) {
282
+ const { properties, validators, sanitizers } = this.getEntityInfo(entityInfo);
283
+ this.validators = validators, this.properties = properties;
284
+ this.sanitizeProps = sanitizers;
285
+ }
286
+ }
287
+ }
288
+ setServerErrors(errors) {
289
+ for (const [key, value] of Object.entries(errors)) {
290
+ const children = this.childrens.get(key);
291
+ if ((Array.isArray(value) || isObject(value)) && children) {
292
+ children.setServerErrors(value);
293
+ } else {
294
+ this._serverErrors[key] = value;
295
+ this.setErrorMessage(key, { server: { message: value } });
296
+ }
297
+ }
298
+ }
299
+ parseValidatorsConfig() {
300
+ if (this.validators) {
301
+ for (const [key, value] of Object.entries(this.validators)) {
302
+ if (Array.isArray(value))
303
+ value.forEach((v) => this.parseConditinalExpression(key, v));
304
+ else
305
+ this.parseConditinalExpression(key, value);
306
+ this.runValidator(key);
307
+ }
308
+ }
309
+ }
310
+ parseConditinalExpression(key, value) {
311
+ if (value.config) {
312
+ const columns = expressionColumns(value.config);
313
+ columns.forEach((t) => {
314
+ this.addConditionally(t.propName, key);
315
+ });
316
+ if (value.config.fieldName)
317
+ this.addConditionally(value.config.fieldName, key);
318
+ }
319
+ }
320
+ addConditionally(propName, key) {
321
+ if (!this.runConditionally[propName])
322
+ this.runConditionally[propName] = [];
323
+ if (this.runConditionally[propName].indexOf(key) == -1)
324
+ this.runConditionally[propName].push(key);
325
+ }
326
+ get value() {
327
+ return this._value;
328
+ }
329
+ runAllValidators() {
330
+ for (const key of this.properties) {
331
+ this.runValidator(key);
332
+ }
333
+ }
334
+ defineProperties() {
335
+ for (const key of this.properties) {
336
+ const value = this._value[key];
337
+ if (Array.isArray(value)) {
338
+ this.defineGroupProp(key, new FormArray(value, {
339
+ validators: this.validators[key] ? this.validators[key][0] : void 0,
340
+ parent: this,
341
+ root: this.root
342
+ }, FormGroup));
343
+ } else if (isObject(value)) {
344
+ this.defineGroupProp(key, new FormGroup(this._value[key], { parent: this, root: this.root || this, validators: this.validators[key] }));
345
+ } else {
346
+ this.defineProp(key, this._value, this.validators[key]);
347
+ }
348
+ }
349
+ }
350
+ defineGroupProp(propName, value) {
351
+ Object.defineProperty(this, propName, {
352
+ get: () => value
353
+ });
354
+ this.childrens.set(propName, value);
355
+ }
356
+ defineProp(propName, value, validator) {
357
+ let _propValue = this._value[propName];
358
+ this._value[propName] = this.getSanitizeValue(propName, this._value[propName]);
359
+ Object.defineProperty(this, propName, {
360
+ get: () => _propValue,
361
+ set: (value2) => {
362
+ _propValue = value2;
363
+ this.clearErrorMessage(propName);
364
+ delete this._serverErrors[propName];
365
+ this._value[propName] = this.getSanitizeValue(propName, value2);
366
+ this.runConditionalValidation(propName);
367
+ this.runValidator(propName);
368
+ }
369
+ });
370
+ }
371
+ runConditionalValidation(propName) {
372
+ const conditionalProps = this.runConditionally[propName];
373
+ if (conditionalProps)
374
+ conditionalProps.forEach((prop) => this.runValidator(prop));
375
+ }
376
+ runValidator(propName) {
377
+ if (nattyForms.formConfig?.runValidatorStrategy && nattyForms.formConfig?.runValidatorStrategy == RunValidatorStrategy.OnSubmit && this.submit || !nattyForms.formConfig?.runValidatorStrategy) {
378
+ if (this.validators) {
379
+ const validator = this.validators[propName];
380
+ if (validator) {
381
+ const errors = this.runValidation(validator, { name: propName, value: this._value[propName], current: this, root: this.root });
382
+ if (errors)
383
+ this._errors[propName] = errors;
384
+ else if (this._errors[propName])
385
+ delete this._errors[propName];
386
+ }
387
+ }
388
+ }
389
+ }
390
+ runValidation(validator, params) {
391
+ if (validator) {
392
+ if (Array.isArray(validator)) {
393
+ let jErrors = {};
394
+ validator.forEach((validatorFn) => {
395
+ const errors = validatorFn.validator(params);
396
+ if (errors) {
397
+ jErrors = { ...jErrors, ...errors };
398
+ }
399
+ });
400
+ const keys = Object.keys(jErrors);
401
+ if (keys.length > 0)
402
+ this.setErrorMessage(params.name, jErrors);
403
+ else
404
+ this.clearErrorMessage(params.name);
405
+ return keys.length > 0 ? jErrors : null;
406
+ } else {
407
+ const errors = validator.validator(params);
408
+ if (errors)
409
+ this.setErrorMessage(params.name, errors);
410
+ else {
411
+ this.clearErrorMessage(params.name);
412
+ }
413
+ return errors;
414
+ }
415
+ }
416
+ }
417
+ get errors() {
418
+ let errors = this._errors;
419
+ for (const [key, value] of this.childrens.entries()) {
420
+ const childGroupErrors = value.errors;
421
+ if (childGroupErrors)
422
+ errors = { ...errors, ...{ [key]: childGroupErrors } };
423
+ }
424
+ errors = { ...errors, ...this._serverErrors };
425
+ return Object.keys(errors).length == 0 ? null : errors;
426
+ }
427
+ get valid() {
428
+ return this.errors == null;
429
+ }
430
+ get errorMessage() {
431
+ return this._errorMessage;
432
+ }
433
+ setErrorMessage(name, errors) {
434
+ this._errorMessage[name] = errors[Object.keys(errors)[0]].message;
435
+ }
436
+ clearErrorMessage(name) {
437
+ delete this._errorMessage[name];
438
+ }
439
+ }
440
+
441
+ function useForm(entity, config) {
442
+ return new FormGroup(entity, {
443
+ type: config?.type,
444
+ validators: config?.validators
445
+ });
446
+ }
447
+
448
+ const Validators = {
449
+ required: (config) => callValidator(config, ControlValidators.required)
450
+ };
451
+
452
+ decoratorRegistrationCaller.register = ReactiveFormContainer.register;
453
+
454
+ export { RunValidatorStrategy, Validators, nattyForms, useForm };
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@nattyjs/forms",
3
+ "version": "0.0.1-beta.0",
4
+ "description": "",
5
+ "keywords": [],
6
+ "module": "./dist/index.mjs",
7
+ "main": "./dist/index.cjs",
8
+ "types": "./dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "unbuild"
14
+ },
15
+ "author": "ajayojha",
16
+ "license": "MIT",
17
+ "dependencies": {
18
+ "@nattyjs/validation-decorators": "0.0.1-beta.0"
19
+ },
20
+ "devDependencies": {
21
+ "unbuild": "1.2.1"
22
+ }
23
+ }