UNPKG

2.79 kBJavaScriptView Raw
1var dotty = require('dotty');
2var template = require('string-template');
3var xtend = require('xtend');
4var BaseModel = require('./base-model');
5
6function Lance(opts) {
7 if(!(this instanceof Lance)) {
8 return new Lance(opts);
9 }
10 var self = this;
11 if(!opts || !opts.baseUrl) {
12 throw new Error('baseUrl Missing.');
13 }
14 self._baseUrl = opts.baseUrl;
15 self._rootPath = opts.rootPath || '';
16 self._modelMap = opts.modelMap || {};
17 self._metaModel;
18}
19
20var proto = Lance.prototype;
21
22proto.initialize = function() {
23 var self = this;
24 var uri = this._baseUrl + this._rootPath;
25 return fetch(uri)
26 .then(function(response) {
27 return response.json();
28 })
29 .then(function(json) {
30 var metaModel = self.wrap(json);
31 self._metaModel = metaModel;
32 return self._metaModel;
33 });
34}
35
36proto.metaModel = function() {
37 var self = this;
38 if(!self._metaModel) {
39 throw new Error('initialize first');
40 }
41 return self._metaModel;
42}
43
44proto.fetch = function(linkName, opts) {
45 var self = this;
46 opts = xtend({
47 headers: {}
48 }, opts);
49 var uri = self._metaModel.get(['_links', linkName, 'href']);
50 if(!uri) {
51 return new Promise(function() {
52 throw new Error('invalid linkName');
53 });
54 }
55 return self.fetchPath(uri, opts);
56}
57
58proto.fetchPath = function(link, opts) {
59 var self = this;
60 opts = opts || {};
61 if(opts.params) {
62 link = template(link, opts.params);
63 }
64 uri = self._baseUrl + link;
65 console.log('GET ', uri);
66 return fetch(uri, {
67 headers: opts.headers
68 })
69 .then(function(data) {
70 return data.json();
71 })
72 .then(function(json) {
73 return self.wrap(json);
74 });
75}
76
77/**
78 * Wrap data in model
79 * Wrap collection children in models too
80 */
81proto.wrap = function(data, parent) {
82 var self = this;
83 var modelName = dotty.get(data, '_meta.class');
84 var model;
85 if(modelName && typeof this._modelMap[modelName] === 'function') {
86 model = new this._modelMap[modelName](data, this, parent);
87 } else {
88 model = new BaseModel(data, this, parent);
89 }
90 return model;
91}
92
93proto.create = function(linkName, opts) {
94 var self = this;
95 opts = xtend({
96 headers: {
97 'Content-Type': 'application/lance+json'
98 },
99 data: {}
100 }, opts);
101 var link = self._metaModel.get(['_links', linkName, 'href']);
102 if(!link) {
103 return new Promise(function() {
104 throw new Error('Invalid linkName');
105 });
106 }
107 if(typeof opts.data.toJson === 'function') {
108 opts.data = opts.data.toJson();
109 }
110 var uri = self._baseUrl + link;
111 return fetch(uri, {
112 method: 'post',
113 body: JSON.stringify(opts.data),
114 headers: opts.headers
115 })
116 .then(function(data) {
117 return data.json();
118 })
119 .then(function(json) {
120 return self.wrap(json);
121 });
122}
123
124module.exports = Lance;