Skip to content

Commit 9891a15

Browse files
committed
fix: allow extending only array, not items
fixes #404
1 parent 9100ca2 commit 9891a15

File tree

2 files changed

+39
-6
lines changed

2 files changed

+39
-6
lines changed

package/lib/SimpleSchema.js

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,11 @@ class SimpleSchema {
488488
schemaObj = expandShorthand(schema);
489489
}
490490

491+
const schemaKeys = Object.keys(schemaObj);
492+
const combinedKeys = new Set([...Object.keys(this._schema), ...schemaKeys]);
493+
491494
// Update all of the information cached on the instance
492-
Object.keys(schemaObj).forEach((fieldName) => {
495+
schemaKeys.forEach((fieldName) => {
493496
const definition = standardizeDefinition(schemaObj[fieldName]);
494497

495498
// Merge/extend with any existing definition
@@ -511,7 +514,7 @@ class SimpleSchema {
511514
this._schema[fieldName] = definition;
512515
}
513516

514-
checkAndScrubDefinition(fieldName, this._schema[fieldName], this._constructorOptions, schemaObj);
517+
checkAndScrubDefinition(fieldName, this._schema[fieldName], this._constructorOptions, combinedKeys);
515518
});
516519

517520
checkSchemaOverlap(this._schema);
@@ -1005,8 +1008,16 @@ function standardizeDefinition(def) {
10051008
return standardizedDef;
10061009
}
10071010

1008-
// Checks and mutates definition. Clone it first.
1009-
function checkAndScrubDefinition(fieldName, definition, options, fullSchemaObj) {
1011+
/**
1012+
* @summary Checks and mutates definition. Clone it first.
1013+
* Throws errors if any problems are found.
1014+
* @param {String} fieldName Name of field / key
1015+
* @param {Object} definition Field definition
1016+
* @param {Object} options Options
1017+
* @param {Set} allKeys Set of all field names / keys in entire schema
1018+
* @return {undefined} Void
1019+
*/
1020+
function checkAndScrubDefinition(fieldName, definition, options, allKeys) {
10101021
if (!definition.type) throw new Error(`${fieldName} key is missing "type"`);
10111022

10121023
// Validate the field definition
@@ -1034,7 +1045,7 @@ function checkAndScrubDefinition(fieldName, definition, options, fullSchemaObj)
10341045
if (SimpleSchema.isSimpleSchema(type)) {
10351046
Object.keys(type._schema).forEach((subKey) => {
10361047
const newKey = `${fieldName}.${subKey}`;
1037-
if (Object.prototype.hasOwnProperty.call(fullSchemaObj, newKey)) {
1048+
if (allKeys.has(newKey)) {
10381049
throw new Error(`The type for "${fieldName}" is set to a SimpleSchema instance that defines "${newKey}", but the parent SimpleSchema instance also tries to define "${newKey}"`);
10391050
}
10401051
});
@@ -1043,7 +1054,7 @@ function checkAndScrubDefinition(fieldName, definition, options, fullSchemaObj)
10431054

10441055
// If at least one of the possible types is Array, then make sure we have a
10451056
// definition for the array items, too.
1046-
if (couldBeArray && !Object.prototype.hasOwnProperty.call(fullSchemaObj, `${fieldName}.$`)) {
1057+
if (couldBeArray && !allKeys.has(`${fieldName}.$`)) {
10471058
throw new Error(`"${fieldName}" is Array type but the schema does not include a "${fieldName}.$" definition for the array items"`);
10481059
}
10491060

package/lib/SimpleSchema.tests.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,28 @@ describe('SimpleSchema', function () {
626626

627627
expect(mainSchema._schema['items.$'].type.definitions[0].type._schemaKeys).toEqual(['_id']);
628628
});
629+
630+
it('can extend array definition only, without array item definition', function () {
631+
const schema = new SimpleSchema({
632+
myArray: {
633+
type: Array,
634+
},
635+
'myArray.$': {
636+
type: String,
637+
allowedValues: ['foo', 'bar'],
638+
},
639+
});
640+
641+
expect(schema._schema.myArray.type.definitions[0].minCount).toBe(undefined);
642+
643+
schema.extend({
644+
myArray: {
645+
minCount: 1,
646+
},
647+
});
648+
649+
expect(schema._schema.myArray.type.definitions[0].minCount).toBe(1);
650+
});
629651
});
630652

631653
it('empty required array is valid', function () {

0 commit comments

Comments
 (0)