8000 Merge branch 'master' into release · js-data/js-data@55937b9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 55937b9

Browse files
committed
Merge branch 'master' into release
2 parents 592dca4 + 10f738a commit 55937b9

File tree

17 files changed

+443
-109
lines changed

17 files changed

+443
-109
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
##### 3.0.0-rc.8 - 21 February 2017
2+
3+
###### Breaking changes
4+
- #445
5+
- The `strict` option has been removed from the `toJSON` methods. The methods now rely wholly on `Schema#pick` for strictness, and assumes the original `strict: false` behavior if no schema is defined.
6+
- `Schema#pick` now copies properties not defined in the "properties" keyword if the "additionalProperties" keyword is present and truthy.
7+
- Mappers are no longer given an empty schema if no schema is provided
8+
9+
###### Bug fixes
10+
- #446 - fix(Collection): Add noValidate option to Collection#add, by @ivanvoznyakovsky
11+
112
##### 3.0.0-rc.7 - 29 January 2017
213

314
###### Bug fixes

CONTRIBUTORS

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,28 @@
33
# Names are formatted as:
44
# Name [email address]
55
#
6+
Alex <alexander.maznev@gmail.com>
67
antoinebrault <antoinebrault@gmail.com>
8+
Cory Robinson <crobinson42@users.noreply.github.com>
79
David Madner <david.madner@gmx.net>
10+
Frans Krojegård <frans@krojegard.com>
811
InternalFX <bryan@internalfx.com>
12+
Ivan Voznyakovsky <ivan.voznyakovsky@gmail.com>
913
Jason Dobry <jason.dobry@gmail.com>
1014
Ken Børge Viktil <ken.borge.viktil@evry.com>
1115
Kent C. Dodds <kent@doddsfamily.us>
1216
Matt Lewis <matthew.lewis@socialsignin.co.uk>
1317
Matt Winkler <matt@mattwinkler.com>
18+
Matthew Overall <matthew.overall@gmail.com>
1419
Mitranim <me@mitranim.com>
20+
Nick Escallon <nickescallon@gmail.com>
21+
Nick Vahalik <nick@nickvahalik.com>
1522
Pencroff <pencroff@gmail.com>
1623
Robert Porter <rob@Roberts-MacBook-Pro.local>
24+
Scotty Waggoner <ozzieorca@gmail.com>
25+
Sergii Stotskyi <sergiy.stotskiy@gmail.com>
1726
Simon Williams <simon@systemparadox.co.uk>
27+
Tomás Fox <tomas.c.fox@gmail.com>
1828
Trey Nelson <treyenelson@gmail.com>
1929
Viktor Zozulyak <zozulyakviktor@gmail.com>
2030
Warren Taylor <warren@warrentaylor.ca>

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<img src="https://raw.githubusercontent.com/js-data/js-data/master/js-data.png" alt="js-data logo" title="js-data" align="right" width="96" height="96" />
22

3-
# [js-data v3](http://www.js-data.io/) [![Slack][1]][2] [![NPM][3]][4] [![Downloads][5]][6] [![Coverage][7]][8]
3+
# [js-data v3](http://www.js-data.io/) [![Slack][1]][2] [![NPM][3]][4] [![npm version](https://img.shields.io/badge/npm-v3.0.0--rc.8-yellow.svg?style=flat)](https://www.npmjs.org/package/js-data) [![Downloads][5]][6] [![Coverage][7]][8]
44

55
| __Browser tests__ | __Node.js tests__ |
66
| ---------------------------------|----|

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "js-data",
33
"description": "Robust, framework-agnostic in-memory data store.",
4-
"version": "3.0.0-rc.7",
4+
"version": "3.0.0-rc.8",
55
"homepage": "http://www.js-data.io",
66
"repository": {
77
"type": "git",
@@ -60,19 +60,19 @@
6060
"release": "npm test && npm run doc && repo-tools updates && repo-tools changelog && repo-tools authors"
6161
},
6262
"devDependencies": {
63-
"babel-core": "6.22.1",
63+
"babel-core": "6.23.1",
6464
"babel-eslint": "7.1.1",
6565
"babel-plugin-external-helpers": "6.22.0",
6666
"babel-plugin-syntax-async-functions": "6.13.0",
67-
"babel-plugin-transform-es2015-modules-umd": "6.22.0",
67+
"babel-plugin-transform-es2015-modules-umd": "6.23.0",
6868
"babel-plugin-transform-regenerator": "6.22.0",
69-
"babel-polyfill": "6.22.0",
69+
"babel-polyfill": "6.23.0",
7070
"babel-preset-es2015": "6.22.0",
7171
"chai": "3.5.0",
7272
"ink-docstrap": "git+https://github.com/js-data/docstrap.git#cfbe45fa313e1628c493076d5e15d2b855dfbf2c",
7373
"js-data-repo-tools": "1.0.0",
7474
"jsdoc": "3.4.3",
75-
"karma": "1.4.1",
75+
"karma": "1.5.0",
7676
"karma-babel-preprocessor": "6.0.1",
7777
"karma-chai": "0.1.0",
7878
"karma-chrome-launcher": "2.0.0",

src/Collection.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import utils from './utils'
22
import Component from './Component'
33
import Query from './Query'
4+
import Record from './Record'
45
import Index from '../lib/mindex/index'
56

7+
const { noValidatePath } = Record
8+
69
const DOMAIN = 'Collection'
710

811
const COLLECTION_DEFAULTS = {
@@ -212,6 +215,7 @@ export default Component.extend({
212215
* @param {(Object|Object[]|Record|Record[])} data The record or records to insert.
213216
* @param {Object} [opts] Configuration options.
214217
* @param {boolean} [opts.commitOnMerge=true] See {@link Collection#commitOnMerge}.
218+
* @param {boolean} [opts.noValidate] See {@link Record#noValidate}.
215219
* @param {string} [opts.onConflict] See {@link Collection#onConflict}.
216220
* @returns {(Object|Object[]|Record|Record[])} The added record or records.
217221
*/
@@ -253,6 +257,14 @@ export default Component.extend({
253257
// Here, the currently visited record corresponds to a record already
254258
// in the collection, so we need to merge them
255259
const onConflict = opts.onConflict || this.onConflict
260+
if (onConflict !== 'merge' && onConflict !== 'replace') {
261+
throw utils.err(`${DOMAIN}#add`, 'opts.onConflict')(400, 'one of (merge, replace)', onConflict, true)
262+
}
263+
const existingNoValidate = existing._get(noValidatePath)
264+
if (opts.noValidate) {
265+
// Disable validation
266+
existing._set(noValidatePath, true)
267+
}
256268
if (onConflict === 'merge') {
257269
utils.deepMixIn(existing, record)
258270
} else if (onConflict === 'replace') {
@@ -262,8 +274,10 @@ export default Component.extend({
262274
}
263275
})
264276
existing.set(record)
265-
} else {
266-
throw utils.err(`${DOMAIN}#add`, 'opts.onConflict')(400, 'one of (merge, replace)', onConflict, true)
277+
}
278+
if (opts.noValidate) {
279+
// Restore previous `noValidate` value
280+
existing._set(noValidatePath, existingNoValidate)
267281
}
268282
record = existing
269283
if (opts.commitOnMerge && utils.isFunction(record.commit)) {

src/Component.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ function Component (opts) {
5454
* {@link Component#on} and {@link Component#off} instead.
5555
*
5656
* @name Component#_listeners
57+
* @private
5758
* @instance
5859
* @since 3.0.0
5960
* @type {Object}

src/Container.js

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ export const proxiedMapperMethods = [
592592
* Wrapper for {@link Mapper#toJSON}.
593593
*
594594
* @example
595-
* import {Container} from 'js-data'
595+
* import { Container } from 'js-data'
596596
* import RethinkDBAdapter from 'js-data-rethinkdb'
597597
* const store = new Container()
598598
* store.registerAdapter('rethinkdb', new RethinkDBAdapter(), { default: true })
@@ -605,8 +605,21 @@ export const proxiedMapperMethods = [
605605
* }
606606
* })
607607
* const person = store.createRecord('person', { id: 1, name: 'John', foo: 'bar' })
608-
* console.log(store.toJSON('person', person)) // {"id":1,"name":"John","foo":"bar"}
609-
* console.log(store.toJSON('person', person), { strict: true }) // {"id":1,"name":"John"}
608+
* // "foo" is stripped by toJSON()
609+
* console.log(store.toJSON('person', person)) // {"id":1,"name":"John"}
610+
*
611+
* store.defineMapper('personRelaxed', {
612+
* schema: {
613+
* properties: {
614+
* name: { type: 'string' },
615+
* id: { type: 'string' }
616+
* },
617+
* additionalProperties: true
618+
* }
619+
* })
620+
* const person2 = store.createRecord('personRelaxed', { id: 1, name: 'John', foo: 'bar' })
621+
* // "foo" is not stripped by toJSON
622+
* console.log(store.toJSON('personRelaxed', person2)) // {"id":1,"name":"John","foo":"bar"}
610623
*
611624
* @method Container#toJSON
612625
* @param {string} name Name of the {@link Mapper} to target.

src/Mapper.js

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -463,9 +463,9 @@ function Mapper (opts) {
463463
// Setup schema, with an empty default schema if necessary
464464
if (this.schema) {
465465
this.schema.type || (this.schema.type = 'object')
466-
}
467-
if (!(this.schema instanceof Schema)) {
468-
this.schema = new Schema(this.schema || { type: 'object' })
466+
if (!(this.schema instanceof Schema)) {
467+
this.schema = new Schema(this.schema || { type: 'object' })
468+
}
469469
}
470470

471471
// Create a subclass of Record that's tied to this Mapper
@@ -1995,7 +1995,7 @@ export default Component.extend({
19951995
* be optionally be included. Non-schema properties can be excluded.
19961996
*
19971997
* @example
1998-
* import {Mapper, Schema} from 'js-data'
1998+
* import { Mapper, Schema } from 'js-data'
19991999
* const PersonMapper = new Mapper({
20002000
* name: 'person',
20012001
* schema: {
@@ -2006,15 +2006,27 @@ export default Component.extend({
20062006
* }
20072007
* })
20082008
* const person = PersonMapper.createRecord({ id: 1, name: 'John', foo: 'bar' })
2009-
* console.log(PersonMapper.toJSON(person)) // {"id":1,"name":"John","foo":"bar"}
2010-
* console.log(PersonMapper.toJSON(person), { strict: true }) // {"id":1,"name":"John"}
2009+
* // "foo" is stripped by toJSON()
2010+
* console.log(PersonMapper.toJSON(person)) // {"id":1,"name":"John"}
2011+
*
2012+
* const PersonRelaxedMapper = new Mapper({
2013+
* name: 'personRelaxed',
2014+
* schema: {
2015+
* properties: {
2016+
* name: { type: 'string' },
2017+
* id: { type: 'string' }
2018+
* },
2019+
* additionalProperties: true
2020+
* }
2021+
* })
2022+
* const person2 = PersonRelaxedMapper.createRecord({ id: 1, name: 'John', foo: 'bar' })
2023+
* // "foo" is not stripped by toJSON
2024+
* console.log(PersonRelaxedMapper.toJSON(person2)) // {"id":1,"name":"John","foo":"bar"}
20112025
*
20122026
* @method Mapper#toJSON
20132027
* @param {Record|Record[]} records Record or records from which to create a
20142028
* POJO representation.
20152029
* @param {Object} [opts] Configuration options.
2016-
* @param {boolean} [opts.strict] Whether to exclude properties that are not
2017-
* defined in {@link Mapper#schema}.
20182030
* @param {string[]} [opts.with] Array of relation names or relation fields
20192031
* to include in the POJO representation.
20202032
* @param {boolean} [opts.withAll] Whether to simply include all relations in
@@ -2032,19 +2044,13 @@ export default Component.extend({
20322044
}
20332045
const relationFields = (this ? this.relationFields : []) || []
20342046
let json = {}
2035-
let properties
20362047

20372048
// Copy properties defined in the schema
20382049
if (this && this.schema) {
20392050
json = this.schema.pick(record)
2040-
properties = this.schema.properties
2041-
}
2042-
properties || (properties = {})
2043-
2044-
// Optionally copy properties not defined in the schema
2045-
if (!opts.strict) {
2051+
} else {
20462052
for (var key in record) {
2047-
if (!properties[key] && relationFields.indexOf(key) === -1) {
2053+
if (relationFields.indexOf(key) === -1) {
20482054
json[key] = utils.plainCopy(record[key])
20492055
}
20502056
}
@@ -2372,6 +2378,9 @@ export default Component.extend({
23722378
validate (record, opts) {
23732379
opts || (opts = {})
23742380
const schema = this.getSchema()
2381+
if (!schema) {
2382+
return
2383+
}
23752384
const _opts = utils.pick(opts, ['existingOnly'])
23762385
if (utils.isArray(record)) {
23772386
const errors = record.map((_record) => schema.validate(_record, utils.pick(_opts, ['existingOnly'])))

src/Record.js

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ const previousPath = 'previous'
120120
* @param {Object} [opts] Configuration options.
121121
* @param {boolean} [opts.noValidate=false] Whether to skip validation on the
122122
* initial properties.
123+
* @param {boolean} [opts.validateOnSet=true] Whether to enable setter
124+
* validation on properties after the Record has been initialized.
123125
* @since 3.0.0
124126
*/
125127
function Record (props, opts) {
@@ -129,9 +131,7 @@ function Record (props, opts) {
129131
opts || (opts = {})
130132
const _set = this._set
131133
_set(creatingPath, true)
132-
if (opts.noValidate) {
133-
_set(noValidatePath, opts.noValidate === undefined ? true : opts.noValidate)
134-
}
134+
_set(noValidatePath, !!opts.noValidate)
135135
_set(keepChangeHistoryPath, opts.keepChangeHistory === undefined ? (mapper ? mapper.keepChangeHistory : true) : opts.keepChangeHistory)
136136

137137
// Set the idAttribute value first, if it exists.
@@ -143,8 +143,13 @@ function Record (props, opts) {
143143

144144
utils.fillIn(this, props)
145145
_set(creatingPath, false)
146-
const validateOnSet = opts.validateOnSet === undefined ? (mapper ? mapper.validateOnSet : true) : opts.validateOnSet
147-
_set(noValidatePath, !validateOnSet)
146+
if (opts.validateOnSet !== undefined) {
147+
_set(noValidatePath, !opts.validateOnSet)
148+
} else if (mapper && mapper.validateOnSet !== undefined) {
149+
_set(noValidatePath, !mapper.validateOnSet)
150+
} else {
151+
_set(noValidatePath, false)
152+
}
148153
_set(previousPath, mapper ? mapper.toJSON(props) : utils.plainCopy(props))
149154
}
150155

@@ -740,9 +745,9 @@ export default Component.extend({
740745
* be called with this record instead.
741746
*
742747
* @example <caption>Record#toJSON</caption>
743-
* // Normally you would do: import {Container} from 'js-data'
744-
* const JSData = require('js-data@3.0.0-rc.4')
745-
* const {Container} = JSData
748+
* // Normally you would do: import { Container } from 'js-data'
749+
* const JSData = require('js-data@3.0.0-rc.8')
750+
* const { Container } = JSData
746751
* console.log('Using JSData v' + JSData.version.full)
747752
* const store = new Container()
748753
* store.defineMapper('user', {
@@ -758,12 +763,9 @@ export default Component.extend({
758763
* $$hashKey: '1234'
759764
* })
760765
* console.log('user: ' + JSON.stringify(user.toJSON()))
761-
* console.log('user: ' + JSON.stringify(user.toJSON({ strict: true })))
762766
*
763767
* @method Record#toJSON
764768
* @param {Object} [opts] Configuration options.
765-
* @param {boolean} [opts.strict] Whether to exclude properties that are not
766-
* defined in {@link Mapper#schema}.
767769
* @param {string[]} [opts.with] Array of relation names or relation fields
768770
* to include in the representation. Only available as an option if the class
769771
* from which this record was created has a Mapper and this record resides in
@@ -777,7 +779,7 @@ export default Component.extend({
777779
return mapper.toJSON(this, opts)
778780
} else {
779781
const json = {}
780-
utils.forOwn(this, function (prop, key) {
782+
utils.forOwn(this, (prop, key) => {
781783
json[key] = utils.plainCopy(prop)
782784
})
783785
return json
@@ -847,6 +849,11 @@ export default Component.extend({
847849
validate (opts) {
848850
return this._mapper().validate(this, opts)
849851
}
852+
}, {
853+
creatingPath,
854+
noValidatePath,
855+
keepChangeHistoryPath,
856+
previousPath
850857
})
851858

852859
/**

0 commit comments

Comments
 (0)
0