Skip to content

Commit

Permalink
enforceLinks option
Browse files Browse the repository at this point in the history
  • Loading branch information
gr0uch committed Aug 28, 2015
1 parent d85cb63 commit da946e1
Show file tree
Hide file tree
Showing 9 changed files with 29 additions and 11 deletions.
4 changes: 4 additions & 0 deletions doc/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Changelog


##### 1.2.4 (2015-08-29)
- Feature: add `enforceLinks` option, when set as `false` it will ignore referential integrity errors. Useful for client-side use.


##### 1.2.3 (2015-08-28)
- Polish: do not expose missing related records error, should be internal error.
- Polish: use UTF-8 charset for ad hoc serializer.
Expand Down
3 changes: 3 additions & 0 deletions lib/browser.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ export default class Fortune extends FortuneCore {
if (hasIndexedDB) options.adapter = { type: indexedDB }
else if (hasWebStorage) options.adapter = { type: webStorage }

if (!('enforceLinks' in options))
options.enforceLinks = false

super(options)
}

Expand Down
6 changes: 5 additions & 1 deletion lib/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ export default class Fortune extends events.EventEmitter {
*
* // An options object that is specific to the serializer. Optional.
* options: { ... }
* }]
* }],
*
* // Whether or not to enforce referential integrity. Default: `true` for
* // server, `false` for browser.
* enforceLinks: true
* }
* ```
*
Expand Down
13 changes: 8 additions & 5 deletions lib/dispatch/check_links.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import * as keys from '../common/keys'
import { includes } from '../common/array_proxy'


/**
Expand All @@ -9,11 +8,12 @@ import { includes } from '../common/array_proxy'
* @param {Object} fields
* @param {Array} links - An array of strings indicating which fields are
* links. Need to pass this so that it doesn't get computed each time.
* @param {Object} adapter
* @param {Object} [meta]
* @return {Promise}
*/
export default function checkLinks (record, fields, links, adapter, meta) {
export default function checkLinks (record, fields, links, meta) {
const { adapter, options: { enforceLinks } } = this

return Promise.all(links.map(field => new Promise((resolve, reject) => {
const ids = Array.isArray(record[field]) ? record[field] :
!(field in record) || record[field] === null ? [] : [ record[field] ]
Expand All @@ -25,10 +25,13 @@ export default function checkLinks (record, fields, links, adapter, meta) {
}, meta)

.then(records => {
for (let record of records)
if (!includes(ids, record[keys.primary]))
if (enforceLinks) {
const recordIds = new Set(records.map(record => record[keys.primary]))

for (let id of ids) if (!recordIds.has(id))
return reject(new Error(
`A related record for the field "${field}" was not found.`))
}

return resolve(records)
})
Expand Down
2 changes: 1 addition & 1 deletion lib/dispatch/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default function (context) {
enforce(type, record, fields)

// Ensure referential integrity.
return checkLinks(record, fields, links, adapter, meta)
return checkLinks.call(this, record, fields, links, meta)
}))
.then(() => adapter.beginTransaction())
.then(t => {
Expand Down
4 changes: 2 additions & 2 deletions lib/dispatch/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default function (context) {
// Keyed by update, valued by hash of linked records.
const linkedMap = new WeakMap()

const { type, meta } = context.request
const { request: { type, meta } } = context
const fields = recordTypes[type]
const transform = transforms[type]
const links = Object.keys(fields)
Expand Down Expand Up @@ -82,7 +82,7 @@ export default function (context) {
enforce(type, record, fields)

// Ensure referential integrity.
return checkLinks(record, fields, links, adapter, meta)
return checkLinks.call(this, record, fields, links, meta)
.then(linked => {
linkedMap.set(update, linked)
return record
Expand Down
3 changes: 3 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ export default class Fortune extends FortuneCore {
options.serializers = Object.keys(serializers).map(name =>
({ type: serializers[name] }))

if (!('enforceLinks' in options))
options.enforceLinks = true

super(options)
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "fortune",
"description": "High-level I/O for web applications.",
"version": "1.2.3",
"version": "1.2.4",
"license": "MIT",
"author": {
"email": "[email protected]",
Expand Down
3 changes: 2 additions & 1 deletion test/integration/serializers/ad_hoc.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ run(() => {
headers: { 'Content-Type': mediaType },
body: [ {
name: 'Ayy lmao',
nicknames: [ 'ayy', 'lmao' ]
nicknames: [ 'ayy', 'lmao' ],
owner: 1
} ]
}, response => {
equal(response.status, 201, 'status is correct')
Expand Down

0 comments on commit da946e1

Please sign in to comment.