Repository: json-schema-faker/json-schema-faker
Pull request #819 (2024-10-09 17:33:39)

keep required properties in nested arrays
Currently there is a problem with nested array not respecting required properties. This is due to the fact that the schema is passed as-is in the clean function and nested requires are ignored. 

This PR attempts to fix it passing the items property in the recursive call to `clean`.

For example (added to tests) if we generate `[[{ b: {} }]]` from 
```json
{
  "items": {
    "items": {
      "properties": {
        "price": {}
      },
      "required": [
        "b"
      ]
    }
  }
```
should be kept as-is but instead returns `[]`




Patch:
diff --git a/docs/USAGE.md b/docs/USAGE.md
index aeb404e..73c5d04 100644
--- a/docs/USAGE.md
+++ b/docs/USAGE.md
@@ -192,7 +192,7 @@ JSONSchemaFaker.resolve(schema, refs).then((sample) => {
 
 ## Faking values
 
-`JSONSchemaFaker` has built-in generators for core-formats, [Faker.js](https://github.com/faker-js/faker/) and [Chance.js](http://chancejs.com/) (and others) are also supported but they require setup:
+`JSONSchemaFaker` has built-in generators for core-formats, [Faker.js](https://github.com/marak/Faker.js/) and [Chance.js](http://chancejs.com/) (and others) are also supported but they require setup:
 
 ```js
 JSONSchemaFaker.extend("faker", () => require("@faker-js/faker"));
@@ -207,7 +207,7 @@ JSONSchemaFaker.extend("faker", () => require("@faker-js/faker"));
 
 ([demo »](http://json-schema-faker.js.org/#gist/89659ebf28be89d3f860c3f80cbffe4b))
 
-The above schema will invoke [`faker.internet.email()`](https://github.com/faker-js/faker/blob/1f47f09e25ad43db41ea4187c3cd3f7e113d4cb4/lib/internet.js#L32).
+The above schema will invoke [`faker.internet.email()`](https://github.com/Marak/faker.js/blob/1f47f09e25ad43db41ea4187c3cd3f7e113d4cb4/lib/internet.js#L32).
 
 Note that both generators has higher precedence than **format**.
 
@@ -253,7 +253,7 @@ E.g. using `chance` to faking values while passing arguments to the generator:
 This example works for single-parameter generator function.
 
 However, if you pass multiple arguments to the generator function, just pass them wrapped in an array.
-In the example below we use the [`faker.finance.amount(min, max, dec, symbol)`](https://github.com/faker-js/faker/blob/1f47f09e25ad43db41ea4187c3cd3f7e113d4cb4/lib/finance.js#L85)
+In the example below we use the [`faker.finance.amount(min, max, dec, symbol)`](https://github.com/Marak/faker.js/blob/1f47f09e25ad43db41ea4187c3cd3f7e113d4cb4/lib/finance.js#L85)
 generator which has 4 parameters. We just wrap them with an array and it's equivalent to `faker.finance.amount(100, 10000, 2, "$")`:
 
 ```json
@@ -346,7 +346,7 @@ JSONSchemaFaker.option("alwaysFakeOptionals", true);
 
 ## Extending dependencies
 
-You may extend [Faker.js](https://github.com/faker-js/faker):
+You may extend [Faker.js](https://github.com/Marak/faker.js):
 
 ```javascript
 import { JSONSchemaFaker } from 'json-schema-faker';
@@ -373,7 +373,7 @@ const schema = {
 JSONSchemaFaker.resolve(schema).then(...);
 ```
 
-...or if you want to use [faker's _individual localization packages_](https://github.com/faker-js/faker#individual-localization-packages), simply do the following:
+...or if you want to use [faker's _individual localization packages_](https://github.com/Marak/faker.js#individual-localization-packages), simply do the following:
 
 ```js
 JSONSchemaFaker.extend("faker", () => {
diff --git a/index.d.ts b/index.d.ts
index 494c458..fc29bcc 100644
--- a/index.d.ts
+++ b/index.d.ts
@@ -49,7 +49,7 @@ export interface JSONSchemaFakerFormat {
 }
 
 declare function JSONSchemaFakerOption(opts: JSONSchemaFakerOptions): void;
-declare function JSONSchemaFakerOption<K extends keyof JSONSchemaFakerOptions>(name: K, value: JSONSchemaFakerOptions[K]): void;
+declare function JSONSchemaFakerOption(name: keyof JSONSchemaFakerOptions, value: any): void;
 declare namespace JSONSchemaFakerOption {
   var getDefaults: () => JSONSchemaFakerOptions;
 }
diff --git a/public/v1/index.html b/public/v1/index.html
index 236cee0..9852ff0 100644
--- a/public/v1/index.html
+++ b/public/v1/index.html
@@ -9,7 +9,6 @@
         <link href="http://netdna.bootstrapcdn.com/font-awesome/3.0.2/css/font-awesome.css" rel="stylesheet">
         <script src="https://cdnjs.cloudflare.com/ajax/libs/json-schema-faker/0.3.6/json-schema-faker.js" type="text/javascript" charset="utf-8"></script>
         <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.3/ace.js" type="text/javascript" charset="utf-8"></script>
-        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-fork-ribbon-css/0.2.3/gh-fork-ribbon.min.css" integrity="sha512-TktJbycEG5Van9KvrSHFUcYOKBroD7QCYkEe73HAutODCw9QTFcvF6fuxioYM1h6THNudK1GjVidazj6EslK4A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
         <script src="vendor.js"></script>
         <script src="bundle.js"></script>
         <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
@@ -76,7 +75,7 @@
                         </li>
                     </ul>
                     <ul class="nav navbar-nav navbar-right">
-                        <li><a href="https://github.com/faker-js/faker/">faker.js</a></li>
+                        <li><a href="https://github.com/marak/Faker.js/">faker.js</a></li>
                         <li><a href="http://chancejs.com/">chance.js</a></li>
                         <li><a href="http://fent.github.io/randexp.js/">randexp.js</a></li>
                     </ul>
@@ -128,7 +127,9 @@
             </div>
         </div>
 
-        <a class="github-fork-ribbon" href="https://github.com/json-schema-faker/json-schema-faker" data-ribbon="Fork me on GitHub" title="Fork me on GitHub">Fork me on GitHub</a>
+        <a class="github-ribbon" href="https://github.com/json-schema-faker/json-schema-faker">
+            <img src="https://camo.githubusercontent.com/a6677b08c955af8400f44c6298f40e7d19cc5b2d/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f677261795f3664366436642e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png">
+        </a>
 
         <script>
           (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
diff --git a/src/lib/core/utils.mjs b/src/lib/core/utils.mjs
index b21cf70..b491639 100644
--- a/src/lib/core/utils.mjs
+++ b/src/lib/core/utils.mjs
@@ -499,7 +499,7 @@ function clean(obj, schema, isArray = false) {
 
   if (Array.isArray(obj)) {
     return obj
-      .map(value => clean(value, schema, true))
+      .map(value => clean(value, schema?.items, true))
       .filter(value => typeof value !== 'undefined');
   }
 
diff --git a/src/lib/types/array.mjs b/src/lib/types/array.mjs
index c274292..c783c50 100644
--- a/src/lib/types/array.mjs
+++ b/src/lib/types/array.mjs
@@ -92,7 +92,7 @@ function arrayType(value, path, resolve, traverseCallback) {
   const optionalsProbability = optionAPI('alwaysFakeOptionals') === true ? 1.0 : optionAPI('optionalsProbability');
   const fixedProbabilities = optionAPI('alwaysFakeOptionals') || optionAPI('fixedProbabilities') || false;
 
-  let length = random.number(minItems, maxItems, 0, 5);
+  let length = random.number(minItems, maxItems, 1, 5);
 
   if (optionalsProbability !== null) {
     length = Math.max(fixedProbabilities


Test patch:
diff --git a/docs/TESTING.md b/docs/TESTING.md
index 70c10cf..e092eae 100644
--- a/docs/TESTING.md
+++ b/docs/TESTING.md
@@ -6,7 +6,7 @@
 ### Unit tests
 
 - They just validate the building blocks from the entire library
-- We're using `mocha` and `chai` so the workflow would be very familiar
+- We're using `mocha` and `chai` so the worflow would be very familiar
 
 > Much stuff from the internals are not covered by unit-tests yet, PRs for increasing that are very welcome!
 
diff --git a/tests/schema/core/issues/issue-494.json b/tests/schema/core/issues/issue-494.json
index c28525d..489bf02 100644
--- a/tests/schema/core/issues/issue-494.json
+++ b/tests/schema/core/issues/issue-494.json
@@ -19,8 +19,7 @@
                 "type": "array",
                 "items": {
                   "$ref": "#/definitions/current-account"
-                },
-                "minItems": 1
+                }
               }
             },
             "required": [
diff --git a/tests/schema/core/issues/issue-747.json b/tests/schema/core/issues/issue-747.json
index 5a713d4..476282d 100644
--- a/tests/schema/core/issues/issue-747.json
+++ b/tests/schema/core/issues/issue-747.json
@@ -32,7 +32,6 @@
                 ],
                 "type": "object"
               },
-              "minItems": 1,
               "type": "array"
             }
           },
diff --git a/tests/unit/core/utils.spec.mjs b/tests/unit/core/utils.spec.mjs
index 22af3eb..d71dc17 100644
--- a/tests/unit/core/utils.spec.mjs
+++ b/tests/unit/core/utils.spec.mjs
@@ -523,5 +523,11 @@ describe('Utils', () => {
       const cleaned = utils.clean(a, { required: ['b'] });
       expect(cleaned).to.eql({ b: {}, c: { d: 'string value' } });
     });
+
+    it('should respect nested required keys', () => {
+      const a = [[{ b: {} }]];
+      const cleaned = utils.clean(a, { items: { items: { properties: { price: {} }, required: ['b'] } } });
+      expect(cleaned).to.eql([[{ b: {} }]]);
+    });
   });
 });