1 | var dotty = require('dotty');
|
2 | var template = require('string-template');
|
3 | var xtend = require('xtend');
|
4 | var BaseModel = require('./base-model');
|
5 |
|
6 | function 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 |
|
20 | var proto = Lance.prototype;
|
21 |
|
22 | proto.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 |
|
36 | proto.metaModel = function() {
|
37 | var self = this;
|
38 | if(!self._metaModel) {
|
39 | throw new Error('initialize first');
|
40 | }
|
41 | return self._metaModel;
|
42 | }
|
43 |
|
44 | proto.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 |
|
58 | proto.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 |
|
79 |
|
80 |
|
81 | proto.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 |
|
93 | proto.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 |
|
124 | module.exports = Lance;
|