Skip to content

Commit 69c0ad4

Browse files
committed
[fixed] array().concat() incorrectly cleared the sub-schema
1 parent b2bcbf7 commit 69c0ad4

File tree

3 files changed

+51
-7
lines changed

3 files changed

+51
-7
lines changed

src/array.js

+26-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import typeOf from 'type-name';
2+
13
import inherits from './util/inherits';
24
import isAbsent from './util/isAbsent';
5+
import isSchema from './util/isSchema';
36
import MixedSchema from './mixed';
47
import { mixed, array as locale } from './locale.js';
58
import runValidations, { propagateErrors } from './util/runValidations';
@@ -15,7 +18,9 @@ function ArraySchema(type) {
1518

1619
MixedSchema.call(this, { type: 'array'})
1720

18-
this._subType = null;
21+
// `undefined` specifically means uninitialized, as opposed to
22+
// "no subtype"
23+
this._subType = undefined;
1924

2025
this.withMutation(() => {
2126
this.transform(function(values) {
@@ -91,9 +96,27 @@ inherits(ArraySchema, MixedSchema, {
9196
})
9297
},
9398

94-
of(schema){
99+
// concat(schema) {
100+
// var next = MixedSchema.prototype.concat.call(this, schema)
101+
//
102+
// next._subType = schema._subType === undefined
103+
// ? this._subType
104+
// : schema._subType;
105+
//
106+
// return next
107+
// },
108+
109+
of(schema) {
95110
var next = this.clone()
96-
next._subType = schema
111+
112+
if (schema !== false && !isSchema(schema))
113+
throw new TypeError(
114+
'`array.of()` sub-schema must be a valid yup schema, or `false` to negate a current sub-schema. ' +
115+
'got: ' + typeOf(schema) + ' instead'
116+
)
117+
118+
next._subType = schema;
119+
97120
return next
98121
},
99122

src/util/reach.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@ module.exports = function (obj, path, value, context) {
1212
forEach(path, (_part, isBracket, isArray) => {
1313
let part = isBracket ? trim(_part) : _part;
1414

15-
if (isArray || has(obj, '_subType')) { // we skipped an array
16-
let idx = isArray ? parseInt(part, 10) : 0
15+
if (isArray || has(obj, '_subType')) { // we skipped an array: foo[].bar
16+
let idx = isArray ? parseInt(part, 10) : 0;
17+
1718
obj = obj.resolve({ context, parent, value })._subType;
1819

1920
if (value) {
20-
2121
if (isArray && idx >= value.length) {
2222
throw new Error(
2323
`Yup.reach cannot resolve an array item at index: ${_part}, in the path: ${path}. ` +
2424
`because there is no value at that index. `
2525
)
2626
}
27+
2728
value = value[idx]
2829
}
2930
}
@@ -45,5 +46,9 @@ module.exports = function (obj, path, value, context) {
4546
}
4647
})
4748

48-
return obj && obj.resolve({ context, parent, value })
49+
if (obj) {
50+
obj = obj.resolve({ context, parent, value });
51+
}
52+
53+
return obj
4954
}

test/array.js

+16
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,22 @@ describe('Array types', function(){
6363
.cast(['1', '3']).should.eql([1, 3])
6464
})
6565

66+
it('should concat subType correctly', function(){
67+
expect(
68+
array()
69+
.of(number())
70+
.concat(array())
71+
._subType
72+
).to.exist
73+
74+
expect(
75+
array()
76+
.of(number())
77+
.concat(array().of(false))
78+
._subType
79+
).to.equal(false)
80+
})
81+
6682
it('should pass options to children', function(){
6783
array(
6884
object({ name: string() })

0 commit comments

Comments
 (0)