UNPKG

5.72 kBJavaScriptView Raw
1var dotty = require('dotty');
2var clone = require('clone');
3var xtend = require('xtend');
4
5function BaseModel(data, lance, parent, parentPath) {
6 if(!(this instanceof BaseModel)) {
7 return new BaseModel(data);
8 }
9 var self = this;
10 if(typeof data !== 'object') {
11 throw 'nope';
12 }
13 if(!lance) {
14 throw 'nope';
15 }
16 self._lance = lance;
17 self._data = data;
18 self._isDirty = false;
19 self._parent = parent;
20 self._parentPath = parentPath;
21 self._collection = [];
22
23 self._populateCollection();
24}
25
26var proto = BaseModel.prototype;
27
28proto._populateCollection = function() {
29 var self = this;
30 var collectionNode = self.meta('collectionNode');
31 if(!collectionNode) {
32 return;
33 }
34 self._collection = self._data[collectionNode]
35 .map(function(item) {
36 return self._lance.wrap(item, self);
37 });
38}
39
40proto.get = function(field) {
41 var self = this;
42 var out = dotty.get(self._data, field);
43 if(typeof out === 'object' && !Array.isArray(out)) {
44 return self._lance.wrap(out, self);
45 }
46 return out;
47}
48
49proto.set = function(field, value) {
50 var self = this;
51 self._isDirty = true;
52 if(self._parent) {
53 self._parent.set(self._parentPath + '.' + field, value);
54 }
55 return dotty.put(self._data, field, value);
56}
57
58proto.meta = function(field) {
59 var self = this;
60 return self.get('_meta.' + field);
61}
62
63proto.fetch = function(linkName, opts) {
64 var self = this;
65 opts = xtend({}, opts);
66 var uri = dotty.get(self._data, ['_links', linkName, 'href']);
67 if(!uri) {
68 return new Promise(function() {
69 throw new Error('invalid linkName');
70 });
71 }
72 return self._lance.fetchPath(uri, opts);
73}
74
75proto.save = function(opts) {
76 var self = this;
77 opts = xtend({
78 headers: {
79 'Content-Type': 'application/lance+json'
80 }
81 }, opts);
82 if(!self._isDirty) {
83 return new Promise(function() {
84 return self;
85 });
86 }
87 var link = dotty.get(self._data, '_links.self.href');
88 if(!link) {
89 return new Promise(function() {
90 throw 'not updateable';
91 });
92 }
93 var uri = self._lance._baseUrl + link;
94 return fetch(uri, {
95 method: 'put',
96 headers: opts.headers,
97 body: JSON.stringify(self._data)
98 })
99 .then(function(data) {
100 return data.json();
101 })
102 .then(function(json) {
103 self._isDirty = false;
104 self.setData(json);
105 return self;
106 });
107}
108
109proto.setData = function(data) {
110 var self = this;
111 self._data = data;
112 self._populateCollection();
113}
114
115proto.fetchMore = function(params, opts) {
116 var self = this;
117 return self.fetch('self', params, opts);
118}
119
120proto.delete = function(opts) {
121 var self = this;
122 opts = xtend({
123 headers: {}
124 }, opts);
125 var link = dotty.get(self._data, '_links.self.href');
126 if(!link) {
127 return new Promise(function() {
128 throw new Error('not deletable');
129 })
130 }
131 var uri = self._lance._baseUrl + link;
132 return fetch(uri, {
133 method: 'delete',
134 headers: opts.headers
135 })
136 .then(function(data) {
137 return data.json();
138 })
139 .then(function(json) {
140 return json;
141 });
142}
143
144proto.collection = function() {
145 var self = this;
146 return self._collection;
147}
148
149proto.totalCount = function() {
150 var self = this;
151 var totalCount = dotty.get(self._data, '_meta.totalCount');
152 if(totalCount || totalCount === 0 || totalCount === '0') {
153 return totalCount;
154 } else if(self.isCollection()) {
155 return self.collection().length;
156 } else if(Array.isArray(self._data)) {
157 return self._data.length
158 } else {
159 return 0;
160 }
161}
162
163proto.currentPage = function() {
164 var self = this;
165 if (self.isCollection()) {
166 return dotty.get(self._data, '_meta.currentPage') || 1;
167 } else {
168 return undefined;
169 }
170}
171
172proto.pageCount = function() {
173 var self = this;
174 if (self.isCollection()) {
175 return dotty.get(self._data, '_meta.pageCount') || 1;
176 } else {
177 return undefined;
178 }
179}
180
181proto.nextPage = function() {
182 var self = this;
183 var link = dotty.get(self._data, '_links.next.href');
184 if(!link) {
185 return new Promise(function() {
186 return false;
187 });
188 }
189 var uri = self._lance._baseUrl + link;
190 return fetch(uri)
191 .then(function(data) {
192 return data.json();
193 })
194 .then(function(json) {
195 return self._lance.wrap(json);
196 });
197}
198
199proto.prevPage = function() {
200 var self = this;
201 var link = dotty.get(self._data, '_links.pev.href');
202 if(!link) {
203 return new Promise(function() {
204 return false;
205 });
206 }
207 var uri = self._lance._baseUrl + link;
208 return fetch(uri)
209 .then(function(data) {
210 return data.json();
211 })
212 .then(function(json) {
213 return self._lance.wrap(json);
214 });
215}
216
217proto.isDirty = function() {
218 var self = this;
219 return self._isDirty;
220}
221
222proto.isCollection = function() {
223 var self = this;
224 return (self.meta('collectionNode')) ? true : false;
225}
226
227proto.hasClass = function() {
228 var self = this;
229 return (self.meta('class')) ? true : false;
230}
231
232proto.hasSelf = function() {
233 var self = this;
234 var link = dotty.get(self._data, '_links.self.href');
235 return (link) ? true : false;
236}
237
238proto.forEachLink = function(cb) {
239 var self = this;
240 for (var key in self._data._links) {
241 cb(key, self._data._links[key]);
242 }
243}
244
245proto.forEachMeta = function(cb) {
246 var self = this;
247 for (var key in self._data._meta) {
248 cb(key, self._data._meta[key]);
249 }
250}
251
252proto.forEachGetter = function(cb) {
253 var self = this;
254 for (var key in self._data) {
255 cb(key, self.get(key));
256 }
257}
258
259proto.toJson = function() {
260 var self = this;
261 var _data = clone(self._data);
262 delete _data._meta;
263 delete _data._links;
264 return _data;
265}
266
267proto.toLanceJson = function() {
268 var self = this;
269 var _data = clone(self._data);
270 return _data;
271}
272
273module.exports = BaseModel;