@weapnl/js-junction 0.0.1
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/CHANGELOG.md +128 -0
- package/README.md +348 -0
- package/babel.config.json +5 -0
- package/dist/index.js +4369 -0
- package/docker-compose.yml +14 -0
- package/index.d.ts +150 -0
- package/package.json +34 -0
- package/src/api.js +226 -0
- package/src/batch.js +39 -0
- package/src/builder/caster.js +67 -0
- package/src/builder/model.js +259 -0
- package/src/builder/properties/accessors.js +116 -0
- package/src/builder/properties/attributes.js +118 -0
- package/src/builder/properties/counts.js +79 -0
- package/src/builder/properties/property.js +37 -0
- package/src/builder/properties/relations.js +124 -0
- package/src/connection.js +83 -0
- package/src/filters/count.js +27 -0
- package/src/filters/filter.js +9 -0
- package/src/filters/filters.js +33 -0
- package/src/filters/limit.js +27 -0
- package/src/filters/order.js +30 -0
- package/src/filters/pluck.js +28 -0
- package/src/filters/relations.js +27 -0
- package/src/filters/scopes.js +30 -0
- package/src/filters/search.js +34 -0
- package/src/filters/whereIn.js +31 -0
- package/src/filters/wheres.js +32 -0
- package/src/index.js +12 -0
- package/src/mixins/actionMixin.js +20 -0
- package/src/mixins/filterMixin.js +104 -0
- package/src/mixins/modifierMixin.js +22 -0
- package/src/mixins/paginationMixin.js +20 -0
- package/src/modifiers/appends.js +28 -0
- package/src/modifiers/hiddenFields.js +27 -0
- package/src/modifiers/modifier.js +9 -0
- package/src/modifiers/modifiers.js +19 -0
- package/src/request/action.js +29 -0
- package/src/request/pagination.js +35 -0
- package/src/request.js +317 -0
- package/src/response.js +33 -0
- package/src/utilities/format.js +11 -0
- package/webpack.config.js +28 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mixin paginationMixin
|
|
3
|
+
*/
|
|
4
|
+
const paginationMixin = {
|
|
5
|
+
/**
|
|
6
|
+
* @param {int} page
|
|
7
|
+
* @param {int} [perPage]
|
|
8
|
+
* @param {null|int} [findPageForId] Find the page the given id is on.
|
|
9
|
+
* @returns {this}
|
|
10
|
+
*/
|
|
11
|
+
pagination (page, perPage = 25, findPageForId = null) {
|
|
12
|
+
this._pagination.page(page);
|
|
13
|
+
this._pagination.perPage(perPage);
|
|
14
|
+
this._pagination.findPageForId(findPageForId);
|
|
15
|
+
|
|
16
|
+
return this;
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export default paginationMixin;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Modifier from './modifier';
|
|
2
|
+
import Format from '../utilities/format';
|
|
3
|
+
|
|
4
|
+
export default class Appends extends Modifier {
|
|
5
|
+
constructor () {
|
|
6
|
+
super();
|
|
7
|
+
|
|
8
|
+
this._appends = [];
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
filled () {
|
|
12
|
+
return this._appends.length > 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
add (appends) {
|
|
16
|
+
this._appends.push(..._.map(appends, Format.snakeCase));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
toObject () {
|
|
20
|
+
const data = {};
|
|
21
|
+
|
|
22
|
+
if (this.filled()) {
|
|
23
|
+
data.appends = this._appends;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import Modifier from './modifier';
|
|
2
|
+
|
|
3
|
+
export default class HiddenFields extends Modifier {
|
|
4
|
+
constructor () {
|
|
5
|
+
super();
|
|
6
|
+
|
|
7
|
+
this._fields = [];
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
filled () {
|
|
11
|
+
return this._fields.length > 0;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
add (fields) {
|
|
15
|
+
this._fields.push(...fields);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
toObject () {
|
|
19
|
+
const data = {};
|
|
20
|
+
|
|
21
|
+
if (this.filled()) {
|
|
22
|
+
data.hidden_fields = this._fields;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return data;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Appends from './appends';
|
|
2
|
+
import HiddenFields from './hiddenFields';
|
|
3
|
+
|
|
4
|
+
export default class Modifiers {
|
|
5
|
+
constructor () {
|
|
6
|
+
this.appends = new Appends();
|
|
7
|
+
this.hiddenFields = new HiddenFields();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
toObject () {
|
|
11
|
+
const items = [];
|
|
12
|
+
|
|
13
|
+
for (let i = 0, modifiers = ['appends', 'hiddenFields']; i < modifiers.length; i++) {
|
|
14
|
+
if (this[modifiers[i]].filled()) items.push(this[modifiers[i]].toObject());
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return _.merge(...items);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export default class Action {
|
|
2
|
+
constructor () {
|
|
3
|
+
this._name = null;
|
|
4
|
+
this._id = null;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
filled () {
|
|
8
|
+
return !! this._name;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
name (name) {
|
|
12
|
+
this._name = name;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
id (id) {
|
|
16
|
+
this._id = id;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
toObject () {
|
|
20
|
+
if (! this.filled()) return null;
|
|
21
|
+
|
|
22
|
+
const data = {};
|
|
23
|
+
|
|
24
|
+
data.action = this._name;
|
|
25
|
+
if (this._id) data.id = this._id;
|
|
26
|
+
|
|
27
|
+
return data;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export default class Pagination {
|
|
2
|
+
constructor () {
|
|
3
|
+
this._page = null;
|
|
4
|
+
this._perPage = null;
|
|
5
|
+
this._findPageForId = null;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
filled () {
|
|
9
|
+
return this._perPage && (this._page || this._findPageForId);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
page (page) {
|
|
13
|
+
this._page = page;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
perPage (perPage) {
|
|
17
|
+
this._perPage = perPage;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
findPageForId (id) {
|
|
21
|
+
this._findPageForId = id;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
toObject () {
|
|
25
|
+
const data = {};
|
|
26
|
+
|
|
27
|
+
if (this.filled()) {
|
|
28
|
+
data.page = this._page;
|
|
29
|
+
data.paginate = this._perPage;
|
|
30
|
+
data.page_for_id = this._findPageForId;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
}
|
package/src/request.js
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import Action from './request/action';
|
|
2
|
+
import Connection from './connection';
|
|
3
|
+
import Filters from './filters/filters';
|
|
4
|
+
import Modifiers from './modifiers/modifiers';
|
|
5
|
+
import Pagination from './request/pagination';
|
|
6
|
+
|
|
7
|
+
import actionMixin from './mixins/actionMixin';
|
|
8
|
+
import filterMixin from './mixins/filterMixin';
|
|
9
|
+
import modifierMixin from './mixins/modifierMixin';
|
|
10
|
+
import paginationMixin from './mixins/paginationMixin';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @mixes actionMixin
|
|
14
|
+
* @mixes filterMixin
|
|
15
|
+
* @mixes modifierMixin
|
|
16
|
+
* @mixes paginationMixin
|
|
17
|
+
*/
|
|
18
|
+
export default class Request {
|
|
19
|
+
constructor () {
|
|
20
|
+
this.url = null;
|
|
21
|
+
|
|
22
|
+
this._action = new Action();
|
|
23
|
+
this._filters = new Filters();
|
|
24
|
+
this._modifiers = new Modifiers();
|
|
25
|
+
this._pagination = new Pagination();
|
|
26
|
+
this._customParameters = [];
|
|
27
|
+
|
|
28
|
+
this._onSuccess = () => {};
|
|
29
|
+
this._onError = () => {};
|
|
30
|
+
this._onValidationError = () => {};
|
|
31
|
+
this._onUnauthorized = () => {};
|
|
32
|
+
this._onForbidden = () => {};
|
|
33
|
+
|
|
34
|
+
this._connection = new Connection();
|
|
35
|
+
|
|
36
|
+
this._response = null;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
get response () {
|
|
40
|
+
return this._response;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @param {string} url
|
|
45
|
+
*
|
|
46
|
+
* @returns {this} The current instance.
|
|
47
|
+
*/
|
|
48
|
+
setUrl (url) {
|
|
49
|
+
this.url = url;
|
|
50
|
+
|
|
51
|
+
return this;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @returns {this} The current instance.
|
|
56
|
+
*/
|
|
57
|
+
cancel () {
|
|
58
|
+
this._connection.cancel();
|
|
59
|
+
|
|
60
|
+
return this;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* @returns {this} The current instance.
|
|
65
|
+
*/
|
|
66
|
+
async get () {
|
|
67
|
+
const url = this.url ?? this.constructor.endpoint;
|
|
68
|
+
|
|
69
|
+
this._response = await this._connection.get(
|
|
70
|
+
`${url}`,
|
|
71
|
+
this.bodyParameters,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
await this.triggerResponseEvents(this._response);
|
|
75
|
+
|
|
76
|
+
return this;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @param {Object} data
|
|
81
|
+
*
|
|
82
|
+
* @returns {this} The current instance.
|
|
83
|
+
*/
|
|
84
|
+
async post (data = {}) {
|
|
85
|
+
const url = this.url ?? this.constructor.endpoint;
|
|
86
|
+
|
|
87
|
+
this._response = await this._connection.post(
|
|
88
|
+
`${url}`,
|
|
89
|
+
data,
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
await this.triggerResponseEvents(this._response);
|
|
93
|
+
|
|
94
|
+
return this;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* @param {Object} data
|
|
99
|
+
*
|
|
100
|
+
* @returns {this} The current instance.
|
|
101
|
+
*/
|
|
102
|
+
async put (data = {}) {
|
|
103
|
+
const url = this.url ?? this.constructor.endpoint;
|
|
104
|
+
|
|
105
|
+
this._response = await this._connection.put(
|
|
106
|
+
`${url}`,
|
|
107
|
+
{ ...data, ...this.bodyParameters },
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
await this.triggerResponseEvents(this._response);
|
|
111
|
+
|
|
112
|
+
return this;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @returns {this} The current instance.
|
|
117
|
+
*/
|
|
118
|
+
async delete () {
|
|
119
|
+
const url = this.url ?? this.constructor.endpoint;
|
|
120
|
+
|
|
121
|
+
this._response = await this._connection.delete(
|
|
122
|
+
`${url}`,
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
await this.triggerResponseEvents(this._response);
|
|
126
|
+
|
|
127
|
+
return this;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {Object} files
|
|
132
|
+
* @param {Object} data
|
|
133
|
+
*
|
|
134
|
+
* @returns {this} The current instance.
|
|
135
|
+
*/
|
|
136
|
+
async storeFiles (files = {}, data = {}) {
|
|
137
|
+
const url = this.url ?? this.constructor.endpoint;
|
|
138
|
+
|
|
139
|
+
this._connection.setConfig({
|
|
140
|
+
headers: {
|
|
141
|
+
'Content-Type': 'multipart/form-data',
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const formData = this._createFormData(_.merge({}, files, data));
|
|
146
|
+
|
|
147
|
+
this._response = await this._connection.post(
|
|
148
|
+
`${url}?${this.bodyParameters}`,
|
|
149
|
+
formData,
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
await this.triggerResponseEvents(this._response);
|
|
153
|
+
|
|
154
|
+
return this;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @returns {Object} Filter and modifier query parameters.
|
|
159
|
+
*/
|
|
160
|
+
get bodyParameters () {
|
|
161
|
+
return _.merge(..._.compact([
|
|
162
|
+
this._filters.toObject(),
|
|
163
|
+
this._modifiers.toObject(),
|
|
164
|
+
this._pagination.toObject(),
|
|
165
|
+
this._action.toObject(),
|
|
166
|
+
...this._customParameters,
|
|
167
|
+
]));
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* @param {function(Response.data)} callback
|
|
172
|
+
*
|
|
173
|
+
* @returns {this} The current instance.
|
|
174
|
+
*/
|
|
175
|
+
onSuccess (callback = () => {}) {
|
|
176
|
+
this._onSuccess = callback;
|
|
177
|
+
|
|
178
|
+
return this;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* @param {function(Response)} callback
|
|
183
|
+
*
|
|
184
|
+
* @returns {this} The current instance.
|
|
185
|
+
*/
|
|
186
|
+
onError (callback = () => {}) {
|
|
187
|
+
this._onError = callback;
|
|
188
|
+
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* @param {function(Response.validation)} callback
|
|
194
|
+
*
|
|
195
|
+
* @returns {this} The current instance.
|
|
196
|
+
*/
|
|
197
|
+
onValidationError (callback = () => {}) {
|
|
198
|
+
this._onValidationError = callback;
|
|
199
|
+
|
|
200
|
+
return this;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* @param {function(Response)} callback
|
|
205
|
+
*
|
|
206
|
+
* @returns {this} The current instance.
|
|
207
|
+
*/
|
|
208
|
+
onUnauthorized (callback = () => {}) {
|
|
209
|
+
this._onUnauthorized = callback;
|
|
210
|
+
|
|
211
|
+
return this;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @param {function(Response)} callback
|
|
216
|
+
*
|
|
217
|
+
* @returns {this} The current instance.
|
|
218
|
+
*/
|
|
219
|
+
onForbidden (callback = () => {}) {
|
|
220
|
+
this._onForbidden = callback;
|
|
221
|
+
|
|
222
|
+
return this;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @param {Response} response
|
|
227
|
+
* @param {*} successResponse
|
|
228
|
+
*/
|
|
229
|
+
async triggerResponseEvents (response, successResponse = null) {
|
|
230
|
+
if (response.statusCode >= 200 && response.statusCode < 300) {
|
|
231
|
+
if (! this._onSuccess) return;
|
|
232
|
+
|
|
233
|
+
return await this._onSuccess(...[successResponse, response.data].filter((value) => !! value));
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
switch (response.statusCode) {
|
|
237
|
+
case 401:
|
|
238
|
+
if (this._onUnauthorized) await this._onUnauthorized(response);
|
|
239
|
+
break;
|
|
240
|
+
case 403:
|
|
241
|
+
if (this._onForbidden) await this._onForbidden(response);
|
|
242
|
+
break;
|
|
243
|
+
case 422:
|
|
244
|
+
const validation = {
|
|
245
|
+
message: response.validation.message,
|
|
246
|
+
errors: {},
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
_.each(response.validation.errors, (value, key) => {
|
|
250
|
+
return _.set(validation.errors, key, value);
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
if (this._onValidationError) await this._onValidationError(validation);
|
|
254
|
+
break;
|
|
255
|
+
default:
|
|
256
|
+
if (this._onError) await this._onError(response);
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Add custom parameters to the request.
|
|
263
|
+
*
|
|
264
|
+
* @param {Array} parameters
|
|
265
|
+
*
|
|
266
|
+
* @returns {this} The current instance.
|
|
267
|
+
*/
|
|
268
|
+
customParameters (parameters = []) {
|
|
269
|
+
this._customParameters.push(...parameters);
|
|
270
|
+
|
|
271
|
+
return this;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Convert data to FormData.
|
|
276
|
+
*
|
|
277
|
+
* @param {Object} data
|
|
278
|
+
*
|
|
279
|
+
* @returns {FormData}
|
|
280
|
+
*/
|
|
281
|
+
_createFormData (data = {}) {
|
|
282
|
+
const formData = new FormData();
|
|
283
|
+
|
|
284
|
+
function appendFormData (data, name) {
|
|
285
|
+
name = name || '';
|
|
286
|
+
|
|
287
|
+
if (data instanceof File) {
|
|
288
|
+
formData.append(name, data);
|
|
289
|
+
} else if (data === true || data === false) {
|
|
290
|
+
formData.append(name, data ? '1' : '0');
|
|
291
|
+
} else if (_.isArray(data) || _.isObject(data)) {
|
|
292
|
+
if (_.size(data) <= 0) {
|
|
293
|
+
formData.append(name, '');
|
|
294
|
+
} else {
|
|
295
|
+
_.forOwn(data, (dataItem, key) => {
|
|
296
|
+
const newName = name === ''
|
|
297
|
+
? key
|
|
298
|
+
: name + '[' + key + ']';
|
|
299
|
+
|
|
300
|
+
appendFormData(dataItem, newName);
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
} else {
|
|
304
|
+
formData.append(name, data);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
appendFormData(data);
|
|
309
|
+
|
|
310
|
+
return formData;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
Object.assign(Request.prototype, actionMixin);
|
|
315
|
+
Object.assign(Request.prototype, filterMixin);
|
|
316
|
+
Object.assign(Request.prototype, modifierMixin);
|
|
317
|
+
Object.assign(Request.prototype, paginationMixin);
|
package/src/response.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export default class Response {
|
|
2
|
+
constructor () {
|
|
3
|
+
this._axiosResponse = null;
|
|
4
|
+
|
|
5
|
+
this.statusCode = null;
|
|
6
|
+
|
|
7
|
+
this.data = null;
|
|
8
|
+
|
|
9
|
+
this.validation = null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get failed () {
|
|
13
|
+
return this.statusCode >= 400;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
set (statusCode, axiosResponse) {
|
|
17
|
+
this._axiosResponse = axiosResponse;
|
|
18
|
+
|
|
19
|
+
this.statusCode = statusCode;
|
|
20
|
+
|
|
21
|
+
switch (this.statusCode) {
|
|
22
|
+
case 200:
|
|
23
|
+
this.data = this._axiosResponse.data;
|
|
24
|
+
break;
|
|
25
|
+
case 400:
|
|
26
|
+
this.data = this._axiosResponse.response.data;
|
|
27
|
+
break;
|
|
28
|
+
case 422:
|
|
29
|
+
this.validation = this._axiosResponse.response.data;
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const webpack = require('webpack');
|
|
3
|
+
|
|
4
|
+
module.exports = {
|
|
5
|
+
entry: ['babel-polyfill', path.resolve(__dirname, 'src/index.js')],
|
|
6
|
+
output: {
|
|
7
|
+
path: path.resolve(__dirname, 'dist'),
|
|
8
|
+
filename: 'index.js',
|
|
9
|
+
library: 'Api',
|
|
10
|
+
libraryTarget: 'umd',
|
|
11
|
+
},
|
|
12
|
+
plugins: [
|
|
13
|
+
new webpack.ProvidePlugin({
|
|
14
|
+
_: 'lodash',
|
|
15
|
+
axios: 'axios',
|
|
16
|
+
}),
|
|
17
|
+
],
|
|
18
|
+
module: {
|
|
19
|
+
rules: [
|
|
20
|
+
{
|
|
21
|
+
test: /\.(js)$/,
|
|
22
|
+
exclude: /node_modules/,
|
|
23
|
+
use: 'babel-loader',
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
mode: 'development',
|
|
28
|
+
};
|