nox-validation 1.0.7 → 1.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/lib/helpers.js CHANGED
@@ -157,6 +157,117 @@ const isEmpty = (val) => {
157
157
  return false;
158
158
  };
159
159
 
160
+ // field?.field_type (Possible Values => Single, Object, Array)
161
+ // 1. Single => Root Field Then Its Single
162
+ // 2. Object => Nested Field Like Inside Array Or Object
163
+ // 3. Array => Any Kind Of Array Array Of String, Object etc
164
+
165
+ // field?.type (Possible Values)
166
+ // 1. String
167
+ // 2. Number
168
+ // 3. Date
169
+ // 4. Buffer
170
+ // 5. Boolean
171
+ // 6. Mixed
172
+ // 7. ObjectId
173
+ // 8. Object
174
+ // 9. Array
175
+ // 10. Alias
176
+
177
+ // field?.schema_definition?.type
178
+ // it is used for specially when field?.type is Array, but some times both are Array Then We Have to check
179
+
180
+ // field?.meta?.interface
181
+
182
+ const generateType = (field, api) => {
183
+ let { type, schema_definition, meta } = field;
184
+ let interfaceType = meta?.interface;
185
+ let array_type = schema_definition?.type;
186
+ let fieldType = type;
187
+ let find_relations = false;
188
+
189
+
190
+ // When type and Array Type Are Same
191
+ if (type === schema_definition?.type) {
192
+ // Type And Array Type Both is Array
193
+ if (type === constants.types.ARRAY) {
194
+ array_type = constants.types.OBJECT;
195
+ }
196
+ // Todo: when both is Alias type === constants.types.ALIAS
197
+ }
198
+
199
+ switch (api) {
200
+ case "v1":
201
+ // is Relational Field
202
+ if (interfaceType && interfaceType !== "none") {
203
+ // We Need to find Relation
204
+ if (
205
+ [constants.interfaces.MANY_TO_ANY, constants.interfaces.TRANSLATIONS].includes(
206
+ interfaceType
207
+ )
208
+ ) {
209
+ find_relations = true;
210
+ // update type and array type accordingly interface
211
+ if ([constants.interfaces.MANY_TO_ANY].includes(interfaceType)) {
212
+ fieldType = constants.types.ARRAY;
213
+ array_type = constants.types.OBJECT;
214
+ } else {
215
+ fieldType = constants.types.OBJECT;
216
+ }
217
+ } else {
218
+ // It is Relational Field, so we have to update type and array type accordingly interface
219
+ if ([constants.interfaces.MANY_TO_ONE].includes(interfaceType)) {
220
+ fieldType = constants.types.OBJECT_ID;
221
+ }
222
+
223
+ if (
224
+ [
225
+ constants.interfaces.ONE_TO_MANY,
226
+ constants.interfaces.MANY_TO_MANY,
227
+ constants.interfaces.FILES,
228
+ ].includes(interfaceType)
229
+ ) {
230
+ fieldType = constants.types.ARRAY;
231
+ array_type = constants.types.OBJECT_ID;
232
+ }
233
+ }
234
+ }
235
+
236
+ return {
237
+ type: fieldType,
238
+ array_type,
239
+ find_relations,
240
+ };
241
+
242
+ default:
243
+ // API V2
244
+ if (
245
+ [
246
+ constants.interfaces.ONE_TO_MANY,
247
+ constants.interfaces.MANY_TO_MANY,
248
+ constants.interfaces.MANY_TO_ANY,
249
+ constants.interfaces.MANY_TO_ONE,
250
+ constants.interfaces.TRANSLATIONS,
251
+ ].includes(interfaceType)
252
+ ) {
253
+ fieldType = constants.types.OBJECT;
254
+ array_type = null;
255
+ find_relations = true;
256
+ }
257
+
258
+ if (interfaceType === constants.interfaces.FILES) {
259
+ fieldType = constants.types.ARRAY;
260
+ array_type = constants.types.OBJECT_ID;
261
+ find_relations = false;
262
+ }
263
+ return {
264
+ type: fieldType,
265
+ array_type,
266
+ find_relations,
267
+ };
268
+ }
269
+ };
270
+
160
271
  const convertTypes = (field) => {
161
272
  let { type, schema_definition, meta } = field;
162
273
  let array_type = schema_definition?.type ?? null;
@@ -559,15 +670,18 @@ const default_fields = [
559
670
  "_id",
560
671
  ];
561
672
 
562
- const buildNestedStructure = (
673
+ const buildNestedStructure = ({
563
674
  schemaFields,
564
675
  allFields,
565
676
  relations,
566
- formData,
567
677
  relational_fields,
568
678
  isSeparatedFields,
569
- apiVersion
570
- ) => {
679
+ apiVersion,
680
+ maxLevel,
681
+ currentDepthMap,
682
+ rootPath,
683
+ isRoot,
684
+ }) => {
571
685
  const root = {};
572
686
  const nodeMap = new Map();
573
687
 
@@ -577,17 +691,17 @@ const buildNestedStructure = (
577
691
  const pathParts = item.path.split(".");
578
692
  const key = pathParts.join(".");
579
693
 
694
+ const currentDepth = currentDepthMap.get(isRoot ? item.path : rootPath) || 0;
695
+
696
+ if (currentDepth >= maxLevel) return;
697
+
580
698
  let childFields;
581
699
 
582
- const definedType =
583
- apiVersion === constants.API_VERSION.V1 ? convertTypesV1(item) : convertTypes(item);
700
+ const definedType = generateType(item, apiVersion);
701
+ // apiVersion === constants.API_VERSION.V1 ? convertTypesV1(item) : convertTypes(item);
584
702
  // const isUserKey = default_fields.some((field) => item?.path?.includes(field));
585
703
 
586
- if (
587
- definedType.find_relations &&
588
- (item?.type === constants.types.ALIAS ||
589
- item?.schema_definition?.type === constants.types.ALIAS)
590
- ) {
704
+ if (definedType.find_relations) {
591
705
  const relationDetail = getForeignCollectionDetails({
592
706
  relations: relations,
593
707
  collection: item?.schema_id,
@@ -609,15 +723,20 @@ const buildNestedStructure = (
609
723
  }
610
724
 
611
725
  if (childFields) {
612
- childFields = buildNestedStructure(
613
- childFields,
614
- allFields,
615
- relations,
616
- formData,
617
- relational_fields,
618
- isSeparatedFields
619
- );
620
-
726
+ if (!isRoot) currentDepthMap.set(rootPath, currentDepth + 1);
727
+
728
+ childFields = buildNestedStructure({
729
+ schemaFields: childFields,
730
+ allFields: allFields,
731
+ relations: relations,
732
+ relational_fields: relational_fields,
733
+ isSeparatedFields,
734
+ apiVersion,
735
+ maxLevel,
736
+ currentDepthMap,
737
+ rootPath: isRoot ? item.path : rootPath,
738
+ isRoot: false,
739
+ });
621
740
  }
622
741
  }
623
742
 
@@ -689,12 +808,17 @@ const getAllKeys = (structure) => {
689
808
 
690
809
  const normalizeKey = (key) => key.replace(/\[\d+\]/g, "");
691
810
 
692
- const findDisallowedKeys = (formData, structure) => {
811
+ const findDisallowedKeys = (formData, structure, maxLevel) => {
693
812
  const formKeys = [];
694
813
  generateDynamicKeys(formData, formKeys);
695
814
 
696
815
  const validKeys = getAllKeys(structure);
697
- return formKeys.filter((key) => !validKeys.has(normalizeKey(key)));
816
+ return formKeys.filter((key) => {
817
+ const keyParts = normalizeKey(key).split(".");
818
+ const keyLevel = keyParts.length;
819
+ const levelParent = keyParts.slice(maxLevel - 1).join(".");
820
+ return !validKeys.has(normalizeKey(keyLevel > maxLevel ? levelParent : key));
821
+ });
698
822
  };
699
823
 
700
824
  const generateFieldCompareRules = (rule) => {
package/lib/validate.js CHANGED
@@ -7,6 +7,7 @@ const {
7
7
  getValue,
8
8
  setValue,
9
9
  isEmpty,
10
+ getParentKey,
10
11
  } = require("./helpers");
11
12
 
12
13
  const typeChecks = {
@@ -663,6 +664,7 @@ const schema = {
663
664
  },
664
665
  apiVersion: { type: constants.types.STRING, array_type: null },
665
666
  language: { type: constants.types.STRING, array_type: null },
667
+ maxLevel: { type: constants.types.NUMBER, array_type: null },
666
668
  };
667
669
 
668
670
  const validate = (data) => {
@@ -677,12 +679,12 @@ const validate = (data) => {
677
679
  byPassKeys,
678
680
  apiVersion,
679
681
  language,
682
+ maxLevel,
680
683
  } = data;
681
684
  const defaultLanguage = constants.LANGUAGES.length > 0 ? constants.LANGUAGES[0] : "en"; // Replace "en" with your actual default
682
685
  const error_messages =
683
686
  constants.LOCALE_MESSAGES[language] ?? constants.LOCALE_MESSAGES[defaultLanguage];
684
687
 
685
-
686
688
  let result = { status: true, errors: {}, data: formData };
687
689
 
688
690
  const updateValue = (key, value) => {
@@ -833,18 +835,23 @@ const validate = (data) => {
833
835
  schemaFields = fields.filter((field) => field?.schema_id?.toString() === formId?.toString());
834
836
  }
835
837
 
838
+ let currentDepthMap = new Map();
839
+
836
840
  const fieldOptions =
837
- buildNestedStructure(
838
- schemaFields || [],
839
- allFields,
840
- relations,
841
- formData,
842
- relationalFields,
841
+ buildNestedStructure({
842
+ schemaFields: schemaFields || [],
843
+ allFields: allFields,
844
+ relations: relations,
845
+ relational_fields: relationalFields,
843
846
  isSeparatedFields,
844
- apiVersion
845
- ) || [];
846
-
847
- findDisallowedKeys(formData, fieldOptions).forEach((fieldPath) => {
847
+ apiVersion,
848
+ maxLevel,
849
+ currentDepthMap,
850
+ rootPath: "",
851
+ isRoot: true,
852
+ }) || [];
853
+
854
+ findDisallowedKeys(formData, fieldOptions,maxLevel).forEach((fieldPath) => {
848
855
  if (abortEarly && !result.status) return result;
849
856
  const fieldKey = getLastChildKey(fieldPath);
850
857
  if (fieldKey && !result.errors[fieldPath]) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nox-validation",
3
- "version": "1.0.7",
3
+ "version": "1.0.8",
4
4
  "description": "validate dynamic schema",
5
5
  "main": "index.js",
6
6
  "scripts": {