yayson 3.0.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +440 -68
- package/build/legacy.cjs +278 -0
- package/build/legacy.d.cts +105 -0
- package/build/legacy.d.cts.map +1 -0
- package/build/legacy.d.mts +105 -0
- package/build/legacy.d.mts.map +1 -0
- package/build/legacy.mjs +279 -0
- package/build/legacy.mjs.map +1 -0
- package/build/symbols-DSjKJ8vh.mjs +26 -0
- package/build/symbols-DSjKJ8vh.mjs.map +1 -0
- package/build/symbols-nFs99aEX.cjs +61 -0
- package/build/types-BsfPiPEw.d.mts +122 -0
- package/build/types-BsfPiPEw.d.mts.map +1 -0
- package/build/types-DbMIe8E2.d.cts +122 -0
- package/build/types-DbMIe8E2.d.cts.map +1 -0
- package/build/utils.cjs +31 -0
- package/build/utils.d.cts +11 -0
- package/build/utils.d.cts.map +1 -0
- package/build/utils.d.mts +11 -0
- package/build/utils.d.mts.map +1 -0
- package/build/utils.mjs +22 -0
- package/build/utils.mjs.map +1 -0
- package/build/yayson-BJv2Z0Z6.mjs +391 -0
- package/build/yayson-BJv2Z0Z6.mjs.map +1 -0
- package/build/yayson-BKEyEcGk.d.cts +69 -0
- package/build/yayson-BKEyEcGk.d.cts.map +1 -0
- package/build/yayson-CRbukIqr.d.mts +69 -0
- package/build/yayson-CRbukIqr.d.mts.map +1 -0
- package/build/yayson-CUfrxK9d.cjs +407 -0
- package/build/yayson.cjs +3 -0
- package/build/yayson.d.cts +3 -0
- package/build/yayson.d.mts +3 -0
- package/build/yayson.mjs +3 -0
- package/package.json +72 -28
- package/skill/yayson/SKILL.md +233 -0
- package/skill/yayson/references/api.md +266 -0
- package/.eslintrc.json +0 -28
- package/.github/workflows/node.js.yml +0 -30
- package/.mocharc.js +0 -15
- package/.nvmrc +0 -1
- package/RELEASE.md +0 -3
- package/babel.config.json +0 -4
- package/legacy.js +0 -2
- package/prettier.config.js +0 -5
- package/src/legacy.js +0 -14
- package/src/yayson/adapter.js +0 -18
- package/src/yayson/adapters/index.js +0 -1
- package/src/yayson/adapters/sequelize.js +0 -11
- package/src/yayson/legacy-presenter.js +0 -121
- package/src/yayson/legacy-store.js +0 -156
- package/src/yayson/presenter.js +0 -198
- package/src/yayson/store.js +0 -194
- package/src/yayson.js +0 -23
- package/tags +0 -59
- package/webpack.browser.js +0 -27
- package/webpack.common.js +0 -39
- package/webpack.dist.js +0 -21
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
module.exports = function (Presenter) {
|
|
2
|
-
return class LegacyPresenter extends Presenter {
|
|
3
|
-
static type = 'object'
|
|
4
|
-
|
|
5
|
-
pluralType() {
|
|
6
|
-
return this.constructor.plural || this.constructor.type + 's'
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
attributes(instance) {
|
|
10
|
-
if (!instance) {
|
|
11
|
-
return null
|
|
12
|
-
}
|
|
13
|
-
const attributes = { ...this.constructor.adapter.get(instance) }
|
|
14
|
-
const relationships = this.relationships()
|
|
15
|
-
for (let key in relationships) {
|
|
16
|
-
var id
|
|
17
|
-
const data = attributes[key]
|
|
18
|
-
if (data == null) {
|
|
19
|
-
id = attributes[key + 'Id']
|
|
20
|
-
if (id != null) {
|
|
21
|
-
attributes[key] = id
|
|
22
|
-
}
|
|
23
|
-
} else if (data instanceof Array) {
|
|
24
|
-
attributes[key] = data.map((obj) => obj.id)
|
|
25
|
-
} else {
|
|
26
|
-
attributes[key] = data.id
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return attributes
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
includeRelationships(scope, instance) {
|
|
33
|
-
if (!scope.links) {
|
|
34
|
-
scope.links = {}
|
|
35
|
-
}
|
|
36
|
-
const relationships = this.relationships()
|
|
37
|
-
const result = []
|
|
38
|
-
for (var key in relationships) {
|
|
39
|
-
const factory = relationships[key]
|
|
40
|
-
if (!factory) throw new Error(`Presenter for ${key} in ${this.constructor.type} is not defined`)
|
|
41
|
-
|
|
42
|
-
const presenter = new factory(scope)
|
|
43
|
-
|
|
44
|
-
const data = this.constructor.adapter.get(instance, key)
|
|
45
|
-
if (data != null) {
|
|
46
|
-
presenter.toJSON(data, { defaultPlural: true })
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const type = scope[this.pluralType()] != null ? this.pluralType() : this.constructor.type
|
|
50
|
-
const keyName = scope[presenter.pluralType()] != null ? presenter.pluralType() : presenter.constructor.type
|
|
51
|
-
const link = { type: keyName }
|
|
52
|
-
scope.links[`${type}.${key}`] = link
|
|
53
|
-
result.push(link)
|
|
54
|
-
}
|
|
55
|
-
return result
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
toJSON(instanceOrCollection, options) {
|
|
59
|
-
let type
|
|
60
|
-
if (options == null) {
|
|
61
|
-
options = {}
|
|
62
|
-
}
|
|
63
|
-
if (instanceOrCollection instanceof Array) {
|
|
64
|
-
const collection = instanceOrCollection
|
|
65
|
-
if (!this.scope[(type = this.pluralType())]) {
|
|
66
|
-
this.scope[type] = []
|
|
67
|
-
}
|
|
68
|
-
collection.forEach((instance) => {
|
|
69
|
-
return this.toJSON(instance)
|
|
70
|
-
})
|
|
71
|
-
} else {
|
|
72
|
-
let links
|
|
73
|
-
const instance = instanceOrCollection
|
|
74
|
-
let added = true
|
|
75
|
-
const attrs = this.attributes(instance)
|
|
76
|
-
if ((links = this.links())) {
|
|
77
|
-
attrs.links = links
|
|
78
|
-
}
|
|
79
|
-
// If eg x.image already exists
|
|
80
|
-
if (this.scope[this.constructor.type] && !this.scope[this.pluralType()]) {
|
|
81
|
-
if (this.scope[this.constructor.type].id !== attrs.id) {
|
|
82
|
-
this.scope[this.pluralType()] = [this.scope[this.constructor.type]]
|
|
83
|
-
delete this.scope[this.constructor.type]
|
|
84
|
-
this.scope[this.pluralType()].push(attrs)
|
|
85
|
-
} else {
|
|
86
|
-
added = false
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// If eg x.images already exists
|
|
90
|
-
} else if (this.scope[this.pluralType()]) {
|
|
91
|
-
if (!this.scope[this.pluralType()].some((i) => i.id === attrs.id)) {
|
|
92
|
-
this.scope[this.pluralType()].push(attrs)
|
|
93
|
-
} else {
|
|
94
|
-
added = false
|
|
95
|
-
}
|
|
96
|
-
} else if (options.defaultPlural) {
|
|
97
|
-
this.scope[this.pluralType()] = [attrs]
|
|
98
|
-
} else {
|
|
99
|
-
this.scope[this.constructor.type] = attrs
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
if (added) {
|
|
103
|
-
this.includeRelationships(this.scope, instance)
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return this.scope
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
render(instanceOrCollection) {
|
|
110
|
-
return this.toJSON(instanceOrCollection)
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
static toJSON() {
|
|
114
|
-
return new this().toJSON(...arguments)
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
static render() {
|
|
118
|
-
return new this().render(...arguments)
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
}
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
// TODO: This file was created by bulk-decaffeinate.
|
|
2
|
-
// Sanity-check the conversion and remove this comment.
|
|
3
|
-
/*
|
|
4
|
-
* decaffeinate suggestions:
|
|
5
|
-
* DS101: Remove unnecessary use of Array.from
|
|
6
|
-
* DS102: Remove unnecessary code created because of implicit returns
|
|
7
|
-
* DS205: Consider reworking code to avoid use of IIFEs
|
|
8
|
-
* DS207: Consider shorter variations of null checks
|
|
9
|
-
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
module.exports = function () {
|
|
13
|
-
class Record {
|
|
14
|
-
constructor(options) {
|
|
15
|
-
this.type = options.type
|
|
16
|
-
this.data = options.data
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
return class Store {
|
|
21
|
-
constructor(options) {
|
|
22
|
-
this.types = options.types || {}
|
|
23
|
-
this.reset()
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
reset() {
|
|
27
|
-
this.records = []
|
|
28
|
-
return (this.relations = {})
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
toModel(rec, type, models) {
|
|
32
|
-
const model = {...rec.data}
|
|
33
|
-
if (!models[type][model.id]) {
|
|
34
|
-
models[type][model.id] = model
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const relations = this.relations[type]
|
|
38
|
-
for (let attribute in relations) {
|
|
39
|
-
var relationType = relations[attribute]
|
|
40
|
-
model[attribute] =
|
|
41
|
-
model[attribute] instanceof Array
|
|
42
|
-
? model[attribute].map((id) => this.find(relationType, id, models))
|
|
43
|
-
: this.find(relationType, model[attribute], models)
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
return model
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
setupRelations(links) {
|
|
50
|
-
return (() => {
|
|
51
|
-
const result = []
|
|
52
|
-
for (let key in links) {
|
|
53
|
-
const value = links[key]
|
|
54
|
-
let [type, attribute] = Array.from(key.split('.'))
|
|
55
|
-
type = this.types[type] || type
|
|
56
|
-
if (!this.relations[type]) {
|
|
57
|
-
this.relations[type] = {}
|
|
58
|
-
}
|
|
59
|
-
result.push((this.relations[type][attribute] = this.types[value.type] || value.type))
|
|
60
|
-
}
|
|
61
|
-
return result
|
|
62
|
-
})()
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
findRecord(type, id) {
|
|
66
|
-
return this.records.find((r) => r.type === type && r.data.id === id)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
findRecords(type) {
|
|
70
|
-
return this.records.filter((r) => r.type === type)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
retrive(type, data) {
|
|
74
|
-
this.sync(data)
|
|
75
|
-
const { id } = data[type]
|
|
76
|
-
return this.find(type, id)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
find(type, id, models) {
|
|
80
|
-
if (models == null) {
|
|
81
|
-
models = {}
|
|
82
|
-
}
|
|
83
|
-
const rec = this.findRecord(type, id)
|
|
84
|
-
if (rec == null) {
|
|
85
|
-
return null
|
|
86
|
-
}
|
|
87
|
-
if (!models[type]) {
|
|
88
|
-
models[type] = {}
|
|
89
|
-
}
|
|
90
|
-
return models[type][id] || this.toModel(rec, type, models)
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
findAll(type, models) {
|
|
94
|
-
if (models == null) {
|
|
95
|
-
models = {}
|
|
96
|
-
}
|
|
97
|
-
const recs = this.findRecords(type)
|
|
98
|
-
if (recs == null) {
|
|
99
|
-
return []
|
|
100
|
-
}
|
|
101
|
-
recs.forEach((rec) => {
|
|
102
|
-
if (!models[type]) {
|
|
103
|
-
models[type] = {}
|
|
104
|
-
}
|
|
105
|
-
return this.toModel(rec, type, models)
|
|
106
|
-
})
|
|
107
|
-
return Object.values(models[type] || {})
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
remove(type, id) {
|
|
111
|
-
type = this.types[type] || type
|
|
112
|
-
|
|
113
|
-
const remove = (record) => {
|
|
114
|
-
const index = this.records.indexOf(record)
|
|
115
|
-
if (!(index < 0)) {
|
|
116
|
-
return this.records.splice(index, 1)
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (id != null) {
|
|
121
|
-
return remove(this.findRecord(type, id))
|
|
122
|
-
} else {
|
|
123
|
-
const records = this.findRecords(type)
|
|
124
|
-
return records.forEach(remove)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
sync(data) {
|
|
129
|
-
this.setupRelations(data.links)
|
|
130
|
-
|
|
131
|
-
return (() => {
|
|
132
|
-
const result = []
|
|
133
|
-
for (var name in data) {
|
|
134
|
-
if (name === 'meta' || name === 'links') {
|
|
135
|
-
continue
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
const value = data[name]
|
|
139
|
-
|
|
140
|
-
const add = (d) => {
|
|
141
|
-
const type = this.types[name] || name
|
|
142
|
-
this.remove(type, d.id)
|
|
143
|
-
return this.records.push(new Record({ type, data: d }))
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (value instanceof Array) {
|
|
147
|
-
result.push(value.forEach(add))
|
|
148
|
-
} else {
|
|
149
|
-
result.push(add(value))
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return result
|
|
153
|
-
})()
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
package/src/yayson/presenter.js
DELETED
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
module.exports = function (adapter) {
|
|
2
|
-
const buildLinks = function (link) {
|
|
3
|
-
if (link == null) {
|
|
4
|
-
return
|
|
5
|
-
}
|
|
6
|
-
if (link.self != null || link.related != null) {
|
|
7
|
-
return link
|
|
8
|
-
} else {
|
|
9
|
-
return { self: link }
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return class Presenter {
|
|
14
|
-
static adapter = adapter
|
|
15
|
-
static type = 'objects'
|
|
16
|
-
|
|
17
|
-
constructor(scope) {
|
|
18
|
-
if (scope == null) {
|
|
19
|
-
scope = {}
|
|
20
|
-
}
|
|
21
|
-
this.scope = scope
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
id(instance) {
|
|
25
|
-
return this.constructor.adapter.id(instance)
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
//eslint-disable-next-line no-unused-vars
|
|
29
|
-
selfLinks(instance) {}
|
|
30
|
-
|
|
31
|
-
links() {}
|
|
32
|
-
|
|
33
|
-
relationships() {}
|
|
34
|
-
|
|
35
|
-
attributes(instance) {
|
|
36
|
-
if (instance == null) {
|
|
37
|
-
return null
|
|
38
|
-
}
|
|
39
|
-
const attributes = { ...this.constructor.adapter.get(instance) }
|
|
40
|
-
delete attributes['id']
|
|
41
|
-
|
|
42
|
-
const relationships = this.relationships()
|
|
43
|
-
for (let key in relationships) {
|
|
44
|
-
delete attributes[key]
|
|
45
|
-
}
|
|
46
|
-
return attributes
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
includeRelationships(scope, instance) {
|
|
50
|
-
const relationships = this.relationships()
|
|
51
|
-
const result = []
|
|
52
|
-
for (var key in relationships) {
|
|
53
|
-
const factory = relationships[key]
|
|
54
|
-
if (!factory) throw new Error(`Presenter for ${key} in ${this.constructor.type} is not defined`)
|
|
55
|
-
|
|
56
|
-
const presenter = new factory(scope)
|
|
57
|
-
|
|
58
|
-
const data = this.constructor.adapter.get(instance, key)
|
|
59
|
-
result.push(presenter.toJSON(data, { include: true }))
|
|
60
|
-
}
|
|
61
|
-
return result
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
buildRelationships(instance) {
|
|
65
|
-
if (instance == null) {
|
|
66
|
-
return null
|
|
67
|
-
}
|
|
68
|
-
const rels = this.relationships()
|
|
69
|
-
const links = this.links(instance) || {}
|
|
70
|
-
let relationships = null
|
|
71
|
-
for (var key in rels) {
|
|
72
|
-
let data = this.constructor.adapter.get(instance, key)
|
|
73
|
-
var presenter = rels[key]
|
|
74
|
-
var buildData = (d) => {
|
|
75
|
-
return (data = {
|
|
76
|
-
id: this.constructor.adapter.id(d),
|
|
77
|
-
type: presenter.type,
|
|
78
|
-
})
|
|
79
|
-
}
|
|
80
|
-
const build = (d) => {
|
|
81
|
-
const rel = {}
|
|
82
|
-
if (d != null) {
|
|
83
|
-
rel.data = buildData(d)
|
|
84
|
-
}
|
|
85
|
-
if (links[key] != null) {
|
|
86
|
-
rel.links = buildLinks(links[key])
|
|
87
|
-
} else if (d == null) {
|
|
88
|
-
rel.data = null
|
|
89
|
-
}
|
|
90
|
-
return rel
|
|
91
|
-
}
|
|
92
|
-
if (!relationships) {
|
|
93
|
-
relationships = {}
|
|
94
|
-
}
|
|
95
|
-
if (!relationships[key]) {
|
|
96
|
-
relationships[key] = {}
|
|
97
|
-
}
|
|
98
|
-
if (data instanceof Array) {
|
|
99
|
-
relationships[key].data = data.map(buildData)
|
|
100
|
-
if (links[key] != null) {
|
|
101
|
-
relationships[key].links = buildLinks(links[key])
|
|
102
|
-
}
|
|
103
|
-
} else {
|
|
104
|
-
relationships[key] = build(data)
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return relationships
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
buildSelfLink(instance) {
|
|
111
|
-
return buildLinks(this.selfLinks(instance))
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
toJSON(instanceOrCollection, options) {
|
|
115
|
-
if (options == null) {
|
|
116
|
-
options = {}
|
|
117
|
-
}
|
|
118
|
-
if (options.meta != null) {
|
|
119
|
-
this.scope.meta = options.meta
|
|
120
|
-
}
|
|
121
|
-
if (options.links != null) {
|
|
122
|
-
this.scope.links = options.links
|
|
123
|
-
}
|
|
124
|
-
if (!this.scope.data) {
|
|
125
|
-
this.scope.data = null
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (instanceOrCollection == null) {
|
|
129
|
-
return this.scope
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (instanceOrCollection instanceof Array) {
|
|
133
|
-
const collection = instanceOrCollection
|
|
134
|
-
if (!this.scope.data) {
|
|
135
|
-
this.scope.data = []
|
|
136
|
-
}
|
|
137
|
-
collection.forEach((instance) => {
|
|
138
|
-
return this.toJSON(instance, options)
|
|
139
|
-
})
|
|
140
|
-
} else {
|
|
141
|
-
const instance = instanceOrCollection
|
|
142
|
-
let added = true
|
|
143
|
-
const model = {
|
|
144
|
-
id: this.id(instance),
|
|
145
|
-
type: this.constructor.type,
|
|
146
|
-
attributes: this.attributes(instance),
|
|
147
|
-
}
|
|
148
|
-
if (model.id === undefined) {
|
|
149
|
-
delete model.id
|
|
150
|
-
}
|
|
151
|
-
const relationships = this.buildRelationships(instance)
|
|
152
|
-
if (relationships != null) {
|
|
153
|
-
model.relationships = relationships
|
|
154
|
-
}
|
|
155
|
-
const links = this.buildSelfLink(instance)
|
|
156
|
-
if (links != null) {
|
|
157
|
-
model.links = links
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (options.include) {
|
|
161
|
-
if (!this.scope.included) {
|
|
162
|
-
this.scope.included = []
|
|
163
|
-
}
|
|
164
|
-
if (!this.scope.included.concat(this.scope.data).some((i) => i.id === model.id && i.type === model.type)) {
|
|
165
|
-
this.scope.included.push(model)
|
|
166
|
-
} else {
|
|
167
|
-
added = false
|
|
168
|
-
}
|
|
169
|
-
} else if (this.scope.data != null) {
|
|
170
|
-
if (!(this.scope.data instanceof Array) || !this.scope.data.some((i) => i.id === model.id)) {
|
|
171
|
-
this.scope.data.push(model)
|
|
172
|
-
} else {
|
|
173
|
-
added = false
|
|
174
|
-
}
|
|
175
|
-
} else {
|
|
176
|
-
this.scope.data = model
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
if (added) {
|
|
180
|
-
this.includeRelationships(this.scope, instance)
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return this.scope
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
render(instanceOrCollection, options) {
|
|
187
|
-
return this.toJSON(instanceOrCollection, options)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
static toJSON() {
|
|
191
|
-
return new this().toJSON(...arguments)
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
static render() {
|
|
195
|
-
return new this().render(...arguments)
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
}
|
package/src/yayson/store.js
DELETED
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
module.exports = function () {
|
|
2
|
-
class Record {
|
|
3
|
-
constructor(options) {
|
|
4
|
-
;({
|
|
5
|
-
id: this.id,
|
|
6
|
-
type: this.type,
|
|
7
|
-
attributes: this.attributes,
|
|
8
|
-
relationships: this.relationships,
|
|
9
|
-
links: this.links,
|
|
10
|
-
meta: this.meta,
|
|
11
|
-
} = options)
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
class Store {
|
|
16
|
-
//eslint-disable-next-line no-unused-vars
|
|
17
|
-
constructor(options) {
|
|
18
|
-
this.reset()
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
reset() {
|
|
22
|
-
this.records = []
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
toModel(rec, type, models) {
|
|
26
|
-
let typeAttribute
|
|
27
|
-
const model = { ...(rec.attributes || {}) }
|
|
28
|
-
if (model.type) {
|
|
29
|
-
typeAttribute = model.type
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
model.id = rec.id
|
|
33
|
-
model.type = rec.type
|
|
34
|
-
if (!models[type]) {
|
|
35
|
-
models[type] = {}
|
|
36
|
-
}
|
|
37
|
-
if (!models[type][rec.id]) {
|
|
38
|
-
models[type][rec.id] = model
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (Object.prototype.hasOwnProperty.call(model, 'meta')) {
|
|
42
|
-
model.attributes = { meta: model.meta }
|
|
43
|
-
delete model.meta
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
if (rec.meta != null) {
|
|
47
|
-
model.meta = rec.meta
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (rec.links != null) {
|
|
51
|
-
model.links = rec.links
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
if (rec.relationships != null) {
|
|
55
|
-
for (let key in rec.relationships) {
|
|
56
|
-
const rel = rec.relationships[key]
|
|
57
|
-
const { data } = rel
|
|
58
|
-
const { links } = rel
|
|
59
|
-
const { meta } = rel
|
|
60
|
-
|
|
61
|
-
model[key] = null
|
|
62
|
-
if (data == null && links == null) {
|
|
63
|
-
continue
|
|
64
|
-
}
|
|
65
|
-
const resolve = ({ type, id }) => {
|
|
66
|
-
return this.find(type, id, models)
|
|
67
|
-
}
|
|
68
|
-
model[key] = data instanceof Array ? data.map(resolve) : data != null ? resolve(data) : {}
|
|
69
|
-
|
|
70
|
-
// Model of the relation
|
|
71
|
-
const currentModel = model[key]
|
|
72
|
-
|
|
73
|
-
if (currentModel != null) {
|
|
74
|
-
// retain the links and meta from the relationship entry
|
|
75
|
-
// use as underscore property name because the currentModel may also have a link and meta reference
|
|
76
|
-
currentModel._links = links || {}
|
|
77
|
-
currentModel._meta = meta || {}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (typeAttribute) {
|
|
83
|
-
model.type = typeAttribute
|
|
84
|
-
}
|
|
85
|
-
return model
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
findRecord(type, id) {
|
|
89
|
-
return this.records.find((r) => r.type === type && r.id === id)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
findRecords(type) {
|
|
93
|
-
return this.records.filter((r) => r.type === type)
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
find(type, id, models) {
|
|
97
|
-
if (models == null) {
|
|
98
|
-
models = {}
|
|
99
|
-
}
|
|
100
|
-
const rec = this.findRecord(type, id)
|
|
101
|
-
if (rec == null) {
|
|
102
|
-
return null
|
|
103
|
-
}
|
|
104
|
-
if (!models[type]) {
|
|
105
|
-
models[type] = {}
|
|
106
|
-
}
|
|
107
|
-
return models[type][id] || this.toModel(rec, type, models)
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
findAll(type, models) {
|
|
111
|
-
if (models == null) {
|
|
112
|
-
models = {}
|
|
113
|
-
}
|
|
114
|
-
const recs = this.findRecords(type)
|
|
115
|
-
if (recs == null) {
|
|
116
|
-
return []
|
|
117
|
-
}
|
|
118
|
-
recs.forEach((rec) => {
|
|
119
|
-
if (!models[type]) {
|
|
120
|
-
models[type] = {}
|
|
121
|
-
}
|
|
122
|
-
return this.toModel(rec, type, models)
|
|
123
|
-
})
|
|
124
|
-
return Object.values(models[type] || {})
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
remove(type, id) {
|
|
128
|
-
const remove = (record) => {
|
|
129
|
-
const index = this.records.indexOf(record)
|
|
130
|
-
if (!(index < 0)) {
|
|
131
|
-
return this.records.splice(index, 1)
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
if (id != null) {
|
|
136
|
-
return remove(this.findRecord(type, id))
|
|
137
|
-
} else {
|
|
138
|
-
const records = this.findRecords(type)
|
|
139
|
-
return records.map(remove)
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
sync(body) {
|
|
144
|
-
const sync = (data) => {
|
|
145
|
-
if (data == null) {
|
|
146
|
-
return null
|
|
147
|
-
}
|
|
148
|
-
const add = (obj) => {
|
|
149
|
-
const { type, id } = obj
|
|
150
|
-
this.remove(type, id)
|
|
151
|
-
const rec = new Record(obj)
|
|
152
|
-
this.records.push(rec)
|
|
153
|
-
return rec
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
if (data instanceof Array) {
|
|
157
|
-
return data.map(add)
|
|
158
|
-
} else {
|
|
159
|
-
return add(data)
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
sync(body.included)
|
|
164
|
-
const recs = sync(body.data)
|
|
165
|
-
|
|
166
|
-
if (recs == null) {
|
|
167
|
-
return null
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const models = {}
|
|
171
|
-
let result = null
|
|
172
|
-
|
|
173
|
-
if (recs instanceof Array) {
|
|
174
|
-
result = recs.map((rec) => {
|
|
175
|
-
return this.toModel(rec, rec.type, models)
|
|
176
|
-
})
|
|
177
|
-
} else {
|
|
178
|
-
result = this.toModel(recs, recs.type, models)
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
if (Object.prototype.hasOwnProperty.call(body, 'links')) {
|
|
182
|
-
result.links = body.links
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
if (Object.prototype.hasOwnProperty.call(body, 'meta')) {
|
|
186
|
-
result.meta = body.meta
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
return result
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return Store
|
|
194
|
-
}
|
package/src/yayson.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
const Adapter = require('./yayson/adapter')
|
|
2
|
-
const adapters = require('./yayson/adapters')
|
|
3
|
-
const presenter = require('./yayson/presenter')
|
|
4
|
-
const store = require('./yayson/store')
|
|
5
|
-
|
|
6
|
-
const lookupAdapter = function (nameOrAdapter) {
|
|
7
|
-
if (nameOrAdapter === 'default') {
|
|
8
|
-
return Adapter
|
|
9
|
-
}
|
|
10
|
-
return adapters[nameOrAdapter] || nameOrAdapter || Adapter
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
module.exports = function ({ adapter: nameOrAdapter } = {}) {
|
|
14
|
-
const adapter = lookupAdapter(nameOrAdapter)
|
|
15
|
-
const Presenter = presenter(lookupAdapter(adapter))
|
|
16
|
-
const Store = store()
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
Store,
|
|
20
|
-
Presenter,
|
|
21
|
-
Adapter,
|
|
22
|
-
}
|
|
23
|
-
}
|