yayson 2.1.0 → 3.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/.eslintrc.json +28 -0
- package/.github/workflows/node.js.yml +1 -1
- package/.mocharc.js +4 -4
- package/.nvmrc +1 -0
- package/README.md +77 -78
- package/babel.config.json +4 -0
- package/legacy.js +2 -0
- package/package.json +26 -29
- package/prettier.config.js +5 -0
- package/src/legacy.js +14 -0
- package/src/yayson/adapter.js +18 -0
- package/src/yayson/adapters/index.js +1 -0
- package/src/yayson/adapters/sequelize.js +11 -0
- package/src/yayson/legacy-presenter.js +121 -0
- package/src/yayson/legacy-store.js +156 -0
- package/src/yayson/presenter.js +198 -0
- package/src/yayson/store.js +194 -0
- package/src/yayson.js +23 -0
- package/webpack.browser.js +27 -0
- package/webpack.common.js +39 -0
- package/webpack.dist.js +21 -0
- package/.circleci/config.yml +0 -35
- package/bower.json +0 -31
- package/coffeelint.json +0 -120
- package/gulpfile.coffee +0 -43
- package/lib/yayson/adapter.js +0 -22
- package/lib/yayson/adapters/index.js +0 -3
- package/lib/yayson/adapters/sequelize.js +0 -14
- package/lib/yayson/presenter.js +0 -209
- package/lib/yayson/store.js +0 -169
- package/lib/yayson/utils.js +0 -47
- package/lib/yayson.js +0 -53
package/.eslintrc.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"commonjs": true,
|
|
4
|
+
"es6": true,
|
|
5
|
+
"mocha": true,
|
|
6
|
+
"node": true
|
|
7
|
+
},
|
|
8
|
+
"parser": "@babel/eslint-parser",
|
|
9
|
+
"parserOptions": {
|
|
10
|
+
"ecmaVersion": 2020
|
|
11
|
+
},
|
|
12
|
+
"ignorePatterns": ["node_modules", "dist"],
|
|
13
|
+
"rules": {
|
|
14
|
+
"eqeqeq": ["error", "smart"],
|
|
15
|
+
"semi": ["error", "never", { "beforeStatementContinuationChars": "always" }],
|
|
16
|
+
"no-extra-semi": "off"
|
|
17
|
+
},
|
|
18
|
+
"plugins": ["mocha"],
|
|
19
|
+
"extends": ["eslint:recommended", "plugin:mocha/recommended"],
|
|
20
|
+
"overrides": [
|
|
21
|
+
{
|
|
22
|
+
"files": ["test/**/*.js"],
|
|
23
|
+
"rules": {
|
|
24
|
+
"no-unused-vars": "off"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
package/.mocharc.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
module.exports = {
|
|
4
4
|
recursive: true,
|
|
5
|
-
require: ['
|
|
5
|
+
require: ['test/node.js'],
|
|
6
6
|
diff: true,
|
|
7
|
-
extension: ['js'
|
|
7
|
+
extension: ['js'],
|
|
8
8
|
package: './package.json',
|
|
9
9
|
reporter: 'spec',
|
|
10
10
|
slow: 75,
|
|
11
11
|
timeout: 10000,
|
|
12
12
|
ui: 'bdd',
|
|
13
|
-
spec: ['test/yayson/**/*.
|
|
14
|
-
'watch-files': ['src/**/*.
|
|
13
|
+
spec: ['test/yayson/**/*.js'],
|
|
14
|
+
'watch-files': ['src/**/*.js', 'test/**/*.js'],
|
|
15
15
|
}
|
package/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
v18.13.0
|
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# YAYSON
|
|
2
2
|
|
|
3
|
-
A library for serializing and reading [JSON API](http://jsonapi.org) data in JavaScript.
|
|
3
|
+
A library for serializing and reading [JSON API](http://jsonapi.org) data in JavaScript.
|
|
4
|
+
|
|
5
|
+
From version 3 we now support native JavaScript classes. YAYSON has zero dependencies and works in the browser and in node 14 and up.
|
|
4
6
|
|
|
5
7
|
[](https://nodei.co/npm/yayson/)
|
|
6
8
|
|
|
@@ -10,55 +12,45 @@ A library for serializing and reading [JSON API](http://jsonapi.org) data in Jav
|
|
|
10
12
|
Install yayson by running:
|
|
11
13
|
|
|
12
14
|
```
|
|
13
|
-
$ npm install yayson --save
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
## Presenting data
|
|
17
|
-
|
|
18
|
-
A basic `Presenter` can look like this in Coffeescript:
|
|
19
|
-
|
|
20
|
-
```coffee
|
|
21
|
-
{Presenter} = require('yayson')(adapter: 'default')
|
|
22
|
-
|
|
23
|
-
class ItemsPresenter extends Presenter
|
|
24
|
-
type: 'items'
|
|
25
15
|
|
|
26
|
-
item =
|
|
27
|
-
id: 5
|
|
28
|
-
name: 'First'
|
|
29
16
|
|
|
30
|
-
|
|
17
|
+
$ npm i yayson
|
|
31
18
|
```
|
|
32
19
|
|
|
33
|
-
|
|
20
|
+
## Presenting data
|
|
21
|
+
|
|
22
|
+
A basic `Presenter` can look like this:
|
|
34
23
|
|
|
35
24
|
```javascript
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}).Presenter;
|
|
25
|
+
const yayson = require('yayson')
|
|
26
|
+
const { Presenter } = yayson()
|
|
39
27
|
|
|
40
|
-
|
|
41
|
-
|
|
28
|
+
class BikePresenter extends Presenter {
|
|
29
|
+
static type = 'bikes'
|
|
30
|
+
}
|
|
42
31
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
32
|
+
const bike = {
|
|
33
|
+
id: 5,
|
|
34
|
+
name: 'Monark'
|
|
35
|
+
};
|
|
47
36
|
|
|
48
|
-
|
|
37
|
+
BikePresenter.render(bike);
|
|
49
38
|
```
|
|
50
39
|
|
|
51
40
|
|
|
52
41
|
This would produce:
|
|
53
42
|
|
|
54
43
|
```javascript
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
55
47
|
{
|
|
56
48
|
data: {
|
|
57
49
|
id: 5,
|
|
58
|
-
type: '
|
|
50
|
+
type: 'bikes',
|
|
59
51
|
attributes: {
|
|
60
52
|
id: 5,
|
|
61
|
-
name: '
|
|
53
|
+
name: 'Monark'
|
|
62
54
|
}
|
|
63
55
|
}
|
|
64
56
|
}
|
|
@@ -69,46 +61,28 @@ be an array.
|
|
|
69
61
|
|
|
70
62
|
A bit more advanced example:
|
|
71
63
|
|
|
72
|
-
```coffee
|
|
73
|
-
{Presenter} = require('yayson')(adapter: 'default')
|
|
74
|
-
|
|
75
|
-
class ItemsPresenter extends Presenter
|
|
76
|
-
type: 'items'
|
|
77
|
-
|
|
78
|
-
attributes: ->
|
|
79
|
-
attrs = super
|
|
80
|
-
attrs.start = moment.utc(attrs.start).toDate()
|
|
81
|
-
attrs
|
|
82
|
-
|
|
83
|
-
relationships: ->
|
|
84
|
-
event: EventsPresenter
|
|
85
|
-
|
|
86
|
-
ItemsPresenter.render(item)
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
In JavaScript this would be done as:
|
|
90
64
|
|
|
91
65
|
```javascript
|
|
92
66
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
class ItemsPresenter extends Presenter {};
|
|
96
|
-
ItemsPresenter.prototype.type = 'items'
|
|
67
|
+
const yayson = require('yayson')
|
|
68
|
+
const { Presenter } = yayson()
|
|
97
69
|
|
|
98
|
-
|
|
99
|
-
|
|
70
|
+
class WheelPresenter extends Presenter {
|
|
71
|
+
static type = 'wheels'
|
|
100
72
|
|
|
101
|
-
|
|
102
|
-
|
|
73
|
+
relationships() {
|
|
74
|
+
return { bike: BikePresenter }
|
|
75
|
+
}
|
|
103
76
|
}
|
|
104
77
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
78
|
+
class BikePresenter extends Presenter {
|
|
79
|
+
static type = 'bikes'
|
|
80
|
+
relationships() {
|
|
81
|
+
return { wheels: WheelPresenter }
|
|
108
82
|
}
|
|
109
83
|
}
|
|
110
84
|
|
|
111
|
-
|
|
85
|
+
|
|
112
86
|
```
|
|
113
87
|
|
|
114
88
|
### Sequelize support
|
|
@@ -117,28 +91,25 @@ By default it is set up to handle standard JS objects. You can also make
|
|
|
117
91
|
it handle Sequelize.js models like this:
|
|
118
92
|
|
|
119
93
|
```javascript
|
|
120
|
-
|
|
94
|
+
|
|
95
|
+
const yayson = require('yayson')
|
|
96
|
+
{Presenter} = yayson({adapter: 'sequelize'})
|
|
121
97
|
|
|
122
98
|
```
|
|
123
99
|
|
|
124
100
|
You can also define your own adapter globally:
|
|
125
101
|
|
|
126
102
|
```javascript
|
|
127
|
-
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
const yayson = require('yayson')
|
|
106
|
+
{Presenter} = yayson(adapter: {
|
|
128
107
|
id: function(model){ return 'omg' + model.id},
|
|
129
108
|
get: function(model, key){ return model[key] }
|
|
130
109
|
})
|
|
131
110
|
|
|
132
111
|
```
|
|
133
112
|
|
|
134
|
-
Or at Presenter level:
|
|
135
|
-
|
|
136
|
-
```javascript
|
|
137
|
-
ItemPresenter.adapter = {
|
|
138
|
-
id: function(model){ return 'omg' + model.id},
|
|
139
|
-
get: function(model, key){ return model[key] }
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
113
|
|
|
143
114
|
Take a look at the SequelizeAdapter if you want to extend YAYSON to your ORM. Pull requests are welcome. :)
|
|
144
115
|
|
|
@@ -146,13 +117,17 @@ Take a look at the SequelizeAdapter if you want to extend YAYSON to your ORM. Pu
|
|
|
146
117
|
|
|
147
118
|
You can add metadata to the top level object.
|
|
148
119
|
|
|
149
|
-
```
|
|
150
|
-
|
|
120
|
+
``` javascript
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
ItemsPresenter.render(items, {meta: count: 10})
|
|
151
124
|
```
|
|
152
125
|
|
|
153
126
|
This would produce:
|
|
154
127
|
|
|
155
128
|
```javascript
|
|
129
|
+
|
|
130
|
+
|
|
156
131
|
{
|
|
157
132
|
meta: {
|
|
158
133
|
count: 10
|
|
@@ -172,16 +147,25 @@ This would produce:
|
|
|
172
147
|
|
|
173
148
|
You can use a `Store` can like this:
|
|
174
149
|
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
|
|
150
|
+
```javascript
|
|
151
|
+
const {Store} = require('yayson')();
|
|
152
|
+
const store = new Store();
|
|
178
153
|
|
|
179
|
-
|
|
180
|
-
|
|
154
|
+
const data = await adapter.get({path: '/events/' + id});
|
|
155
|
+
const event = store.sync(data);
|
|
181
156
|
```
|
|
182
157
|
|
|
183
158
|
This will give you the parsed event with all its relationships.
|
|
184
159
|
|
|
160
|
+
Its also possible to find in the synched data:
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
```javascript
|
|
164
|
+
const event = this.store.find('events', id)
|
|
165
|
+
|
|
166
|
+
const images = this.store.findAll('images')
|
|
167
|
+
```
|
|
168
|
+
|
|
185
169
|
|
|
186
170
|
## Use in the browser
|
|
187
171
|
|
|
@@ -189,6 +173,7 @@ Recommended way is to use it via [webpack](https://github.com/webpack/webpack) o
|
|
|
189
173
|
|
|
190
174
|
If you just want to try it out, copy the file `dist/yayson.js` to your project. Then simply include it:
|
|
191
175
|
```html
|
|
176
|
+
|
|
192
177
|
<script src="./lib/yayson.js"></script>
|
|
193
178
|
```
|
|
194
179
|
Then you can `var yayson = window.yayson()` use the `yayson.Presenter` and `yayson.Store` as usual.
|
|
@@ -202,5 +187,19 @@ Then you can `var yayson = window.yayson()` use the `yayson.Presenter` and `yays
|
|
|
202
187
|
- Safari iOS
|
|
203
188
|
|
|
204
189
|
#### Untested, but should work
|
|
205
|
-
- IE
|
|
190
|
+
- IE 11
|
|
206
191
|
- Android
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
## Legacy support
|
|
195
|
+
|
|
196
|
+
Earlier versions of JSON API worked a bit different from 1.0. Therefore YAYSON provides legacy presenters and stores in order to have interoperability between the versions. Its used similar to the standard presenters:
|
|
197
|
+
|
|
198
|
+
```javascript
|
|
199
|
+
|
|
200
|
+
const yayson = require('yayson/legacy')
|
|
201
|
+
const { Presenter } = yayson()
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
|
package/legacy.js
ADDED
package/package.json
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yayson",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "A library for serializing and reading JSON API standardized data in JavaScript.",
|
|
5
|
-
"main": "
|
|
5
|
+
"main": "src/yayson.js",
|
|
6
6
|
"engines": {
|
|
7
|
-
"node": ">=
|
|
7
|
+
"node": ">=14",
|
|
8
8
|
"npm": ">=6"
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"test": "mocha",
|
|
12
|
-
"build": "
|
|
12
|
+
"build": "webpack --config webpack.dist.js",
|
|
13
|
+
"test-browser": "webpack-dev-server --config webpack.browser.js",
|
|
13
14
|
"preversion": "npm test && npm run build && git add dist/yayson.js",
|
|
14
15
|
"postversion": "git push --follow-tags origin master",
|
|
15
16
|
"release": "npm version minor"
|
|
@@ -36,30 +37,26 @@
|
|
|
36
37
|
"url": "https://github.com/confetti/yayson/issues"
|
|
37
38
|
},
|
|
38
39
|
"homepage": "https://github.com/confetti/yayson",
|
|
40
|
+
"browserslist": [
|
|
41
|
+
"defaults",
|
|
42
|
+
"not IE 11"
|
|
43
|
+
],
|
|
39
44
|
"devDependencies": {
|
|
40
|
-
"
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"
|
|
50
|
-
"sinon": "^
|
|
51
|
-
"sinon-chai": "^3.
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
"
|
|
56
|
-
|
|
57
|
-
"underscore": "^1.13.1"
|
|
58
|
-
},
|
|
59
|
-
"browser": {
|
|
60
|
-
"lodash": false,
|
|
61
|
-
"q": false,
|
|
62
|
-
"underscore": false
|
|
63
|
-
},
|
|
64
|
-
"dependencies": {}
|
|
45
|
+
"@babel/core": "^7.20.12",
|
|
46
|
+
"@babel/eslint-parser": "^7.19.1",
|
|
47
|
+
"@babel/preset-env": "^7.20.2",
|
|
48
|
+
"babel-loader": "^9.1.2",
|
|
49
|
+
"chai": "^4.3.7",
|
|
50
|
+
"core-js": "^3.27.2",
|
|
51
|
+
"eslint": "^8.33.0",
|
|
52
|
+
"eslint-plugin-mocha": "^10.1.0",
|
|
53
|
+
"mocha": "^10.2.0",
|
|
54
|
+
"prettier": "^2.8.3",
|
|
55
|
+
"sinon": "^15.0.1",
|
|
56
|
+
"sinon-chai": "^3.7.0",
|
|
57
|
+
"webpack": "^5.75.0",
|
|
58
|
+
"webpack-cli": "^5.0.1",
|
|
59
|
+
"webpack-dev-server": "^4.11.1",
|
|
60
|
+
"webpack-merge": "^5.8.0"
|
|
61
|
+
}
|
|
65
62
|
}
|
package/src/legacy.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const yayson = require('./yayson')
|
|
2
|
+
const legacyPresenter = require('./yayson/legacy-presenter')
|
|
3
|
+
const legacyStore = require('./yayson/legacy-store')
|
|
4
|
+
|
|
5
|
+
module.exports = function (options = {}) {
|
|
6
|
+
const { Store, Presenter, Adapter } = yayson(options)
|
|
7
|
+
return {
|
|
8
|
+
Store: legacyStore(Store),
|
|
9
|
+
Presenter: legacyPresenter(Presenter),
|
|
10
|
+
Adapter,
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class Adapter {
|
|
2
|
+
static get(model, key) {
|
|
3
|
+
if (key) {
|
|
4
|
+
return model[key]
|
|
5
|
+
}
|
|
6
|
+
return model
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
static id(model) {
|
|
10
|
+
const id = this.get(model, 'id')
|
|
11
|
+
if (id === undefined) {
|
|
12
|
+
return id
|
|
13
|
+
}
|
|
14
|
+
return `${id}`
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = Adapter
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = { sequelize: require('./sequelize') }
|
|
@@ -0,0 +1,121 @@
|
|
|
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
|
+
}
|