Skip to content

Commit da946e1

Browse files
committed
enforceLinks option
1 parent d85cb63 commit da946e1

File tree

9 files changed

+29
-11
lines changed

9 files changed

+29
-11
lines changed

doc/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Changelog
22

33

4+
##### 1.2.4 (2015-08-29)
5+
- Feature: add `enforceLinks` option, when set as `false` it will ignore referential integrity errors. Useful for client-side use.
6+
7+
48
##### 1.2.3 (2015-08-28)
59
- Polish: do not expose missing related records error, should be internal error.
610
- Polish: use UTF-8 charset for ad hoc serializer.

lib/browser.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ export default class Fortune extends FortuneCore {
2727
if (hasIndexedDB) options.adapter = { type: indexedDB }
2828
else if (hasWebStorage) options.adapter = { type: webStorage }
2929

30+
if (!('enforceLinks' in options))
31+
options.enforceLinks = false
32+
3033
super(options)
3134
}
3235

lib/core.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ export default class Fortune extends events.EventEmitter {
6464
*
6565
* // An options object that is specific to the serializer. Optional.
6666
* options: { ... }
67-
* }]
67+
* }],
68+
*
69+
* // Whether or not to enforce referential integrity. Default: `true` for
70+
* // server, `false` for browser.
71+
* enforceLinks: true
6872
* }
6973
* ```
7074
*

lib/dispatch/check_links.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import * as keys from '../common/keys'
2-
import { includes } from '../common/array_proxy'
32

43

54
/**
@@ -9,11 +8,12 @@ import { includes } from '../common/array_proxy'
98
* @param {Object} fields
109
* @param {Array} links - An array of strings indicating which fields are
1110
* links. Need to pass this so that it doesn't get computed each time.
12-
* @param {Object} adapter
1311
* @param {Object} [meta]
1412
* @return {Promise}
1513
*/
16-
export default function checkLinks (record, fields, links, adapter, meta) {
14+
export default function checkLinks (record, fields, links, meta) {
15+
const { adapter, options: { enforceLinks } } = this
16+
1717
return Promise.all(links.map(field => new Promise((resolve, reject) => {
1818
const ids = Array.isArray(record[field]) ? record[field] :
1919
!(field in record) || record[field] === null ? [] : [ record[field] ]
@@ -25,10 +25,13 @@ export default function checkLinks (record, fields, links, adapter, meta) {
2525
}, meta)
2626

2727
.then(records => {
28-
for (let record of records)
29-
if (!includes(ids, record[keys.primary]))
28+
if (enforceLinks) {
29+
const recordIds = new Set(records.map(record => record[keys.primary]))
30+
31+
for (let id of ids) if (!recordIds.has(id))
3032
return reject(new Error(
3133
`A related record for the field "${field}" was not found.`))
34+
}
3235

3336
return resolve(records)
3437
})

lib/dispatch/create.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export default function (context) {
4444
enforce(type, record, fields)
4545

4646
// Ensure referential integrity.
47-
return checkLinks(record, fields, links, adapter, meta)
47+
return checkLinks.call(this, record, fields, links, meta)
4848
}))
4949
.then(() => adapter.beginTransaction())
5050
.then(t => {

lib/dispatch/update.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export default function (context) {
2727
// Keyed by update, valued by hash of linked records.
2828
const linkedMap = new WeakMap()
2929

30-
const { type, meta } = context.request
30+
const { request: { type, meta } } = context
3131
const fields = recordTypes[type]
3232
const transform = transforms[type]
3333
const links = Object.keys(fields)
@@ -82,7 +82,7 @@ export default function (context) {
8282
enforce(type, record, fields)
8383

8484
// Ensure referential integrity.
85-
return checkLinks(record, fields, links, adapter, meta)
85+
return checkLinks.call(this, record, fields, links, meta)
8686
.then(linked => {
8787
linkedMap.set(update, linked)
8888
return record

lib/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ export default class Fortune extends FortuneCore {
2626
options.serializers = Object.keys(serializers).map(name =>
2727
({ type: serializers[name] }))
2828

29+
if (!('enforceLinks' in options))
30+
options.enforceLinks = true
31+
2932
super(options)
3033
}
3134

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "fortune",
33
"description": "High-level I/O for web applications.",
4-
"version": "1.2.3",
4+
"version": "1.2.4",
55
"license": "MIT",
66
"author": {
77
"email": "[email protected]",

test/integration/serializers/ad_hoc.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ run(() => {
107107
headers: { 'Content-Type': mediaType },
108108
body: [ {
109109
name: 'Ayy lmao',
110-
nicknames: [ 'ayy', 'lmao' ]
110+
nicknames: [ 'ayy', 'lmao' ],
111+
owner: 1
111112
} ]
112113
}, response => {
113114
equal(response.status, 201, 'status is correct')

0 commit comments

Comments
 (0)