@caruuto/caruuto-js 0.1.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/.editorconfig +9 -0
- package/.eslintignore +1 -0
- package/.eslintrc.js +19 -0
- package/.prettierignore +1 -0
- package/CHANGELOG.md +6 -0
- package/README.md +3 -0
- package/index.js +41 -0
- package/lib/filters.js +321 -0
- package/lib/helpers.js +246 -0
- package/lib/performFetch.js +72 -0
- package/lib/terminators.js +210 -0
- package/package.json +68 -0
- package/scripts/coverage.js +12 -0
- package/x.js +13 -0
package/.editorconfig
ADDED
package/.eslintignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node_modules
|
package/.eslintrc.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
env: {
|
|
3
|
+
es2021: true,
|
|
4
|
+
mocha: true,
|
|
5
|
+
node: true
|
|
6
|
+
},
|
|
7
|
+
extends: ['eslint:recommended', 'plugin:prettier/recommended'],
|
|
8
|
+
overrides: [],
|
|
9
|
+
parserOptions: {
|
|
10
|
+
ecmaVersion: 12,
|
|
11
|
+
sourceType: 'module'
|
|
12
|
+
},
|
|
13
|
+
plugins: [],
|
|
14
|
+
rules: {
|
|
15
|
+
'no-redeclare': 0,
|
|
16
|
+
'prettier/prettier': 0,
|
|
17
|
+
quotes: ['error', 'single']
|
|
18
|
+
}
|
|
19
|
+
}
|
package/.prettierignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
node_modules
|
package/CHANGELOG.md
ADDED
package/README.md
ADDED
package/index.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
const CaruutoClient = function (caruutoUrl, caruutoApiKey) {
|
|
2
|
+
this.options = {}
|
|
3
|
+
this.options.caruutoUrl = caruutoUrl
|
|
4
|
+
this.options.caruutoApiKey = caruutoApiKey
|
|
5
|
+
|
|
6
|
+
this.options.version = '1'
|
|
7
|
+
this.options.callback = this._processRequest.bind(this)
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// -----------------------------------------
|
|
11
|
+
// Attach fetcher
|
|
12
|
+
// -----------------------------------------
|
|
13
|
+
|
|
14
|
+
require('./lib/performFetch')(CaruutoClient)
|
|
15
|
+
|
|
16
|
+
// -----------------------------------------
|
|
17
|
+
// Attach helpers
|
|
18
|
+
// -----------------------------------------
|
|
19
|
+
|
|
20
|
+
require('./lib/helpers')(CaruutoClient)
|
|
21
|
+
|
|
22
|
+
// -----------------------------------------
|
|
23
|
+
// Attach filters
|
|
24
|
+
// -----------------------------------------
|
|
25
|
+
|
|
26
|
+
require('./lib/filters')(CaruutoClient)
|
|
27
|
+
|
|
28
|
+
// -----------------------------------------
|
|
29
|
+
// Attach terminators
|
|
30
|
+
// -----------------------------------------
|
|
31
|
+
|
|
32
|
+
require('./lib/terminators')(CaruutoClient)
|
|
33
|
+
|
|
34
|
+
module.exports = CaruutoClient
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new Caruuto Client.
|
|
38
|
+
*/
|
|
39
|
+
module.exports.createClient = (caruutoUrl, caruutoApiKey) => {
|
|
40
|
+
return new CaruutoClient(caruutoUrl, caruutoApiKey)
|
|
41
|
+
}
|
package/lib/filters.js
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
module.exports = function (CaruutoClient) {
|
|
2
|
+
/**
|
|
3
|
+
* Select a page
|
|
4
|
+
*
|
|
5
|
+
* @param {Number} page
|
|
6
|
+
* @return API
|
|
7
|
+
* @api public
|
|
8
|
+
*/
|
|
9
|
+
CaruutoClient.prototype.goToPage = function (page) {
|
|
10
|
+
this.page = page
|
|
11
|
+
|
|
12
|
+
return this
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Select a collection
|
|
17
|
+
*
|
|
18
|
+
* @param {String} collection
|
|
19
|
+
* @return API
|
|
20
|
+
* @api public
|
|
21
|
+
*/
|
|
22
|
+
CaruutoClient.prototype.in = function (collection) {
|
|
23
|
+
this.collection = collection
|
|
24
|
+
|
|
25
|
+
return this
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Select a bucket
|
|
30
|
+
*
|
|
31
|
+
* @param {String} bucket
|
|
32
|
+
* @return API
|
|
33
|
+
* @api public
|
|
34
|
+
*/
|
|
35
|
+
CaruutoClient.prototype.inMedia = function (bucket) {
|
|
36
|
+
bucket = bucket || true
|
|
37
|
+
|
|
38
|
+
this.mediaBucket = bucket
|
|
39
|
+
|
|
40
|
+
return this
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Select a document limit
|
|
45
|
+
*
|
|
46
|
+
* @param {Number} limit
|
|
47
|
+
* @return API
|
|
48
|
+
* @api public
|
|
49
|
+
*/
|
|
50
|
+
CaruutoClient.prototype.limitTo = function (limit) {
|
|
51
|
+
this.limit = limit
|
|
52
|
+
|
|
53
|
+
return this
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Select a field to sort on and the sort direction
|
|
58
|
+
*
|
|
59
|
+
* @param {String} sortField
|
|
60
|
+
* @param {String} sortOrder
|
|
61
|
+
* @return API
|
|
62
|
+
* @api public
|
|
63
|
+
*/
|
|
64
|
+
CaruutoClient.prototype.sortBy = function (sortField, sortOrder) {
|
|
65
|
+
this.sort = this.sort || {}
|
|
66
|
+
this.sort[sortField] = sortOrder === 'desc' ? -1 : 1
|
|
67
|
+
|
|
68
|
+
return this
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Select the fields to retrieve
|
|
73
|
+
*
|
|
74
|
+
* @param {Array} fields
|
|
75
|
+
* @return API
|
|
76
|
+
* @api public
|
|
77
|
+
*/
|
|
78
|
+
CaruutoClient.prototype.useFields = function (fields) {
|
|
79
|
+
if (fields !== undefined) {
|
|
80
|
+
const fieldsObj = {}
|
|
81
|
+
|
|
82
|
+
fields.forEach(function (field) {
|
|
83
|
+
fieldsObj[field] = 1
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
this.fields = JSON.stringify(fieldsObj)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return this
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Select the version to be used
|
|
94
|
+
*
|
|
95
|
+
* @param {String} version
|
|
96
|
+
* @return API
|
|
97
|
+
* @api public
|
|
98
|
+
*/
|
|
99
|
+
CaruutoClient.prototype.useVersion = function (version) {
|
|
100
|
+
this.customVersion = version
|
|
101
|
+
|
|
102
|
+
return this
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Set the saved query to a Mongo query expression
|
|
107
|
+
*
|
|
108
|
+
* @param {Object} query
|
|
109
|
+
* @return API
|
|
110
|
+
* @api public
|
|
111
|
+
*/
|
|
112
|
+
CaruutoClient.prototype.where = function (query) {
|
|
113
|
+
this.query = query
|
|
114
|
+
|
|
115
|
+
return this
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Add a /^value/i regex expression to the saved query
|
|
120
|
+
*
|
|
121
|
+
* @param {String} field
|
|
122
|
+
* @param {String} value
|
|
123
|
+
* @return API
|
|
124
|
+
* @api public
|
|
125
|
+
*/
|
|
126
|
+
CaruutoClient.prototype.whereFieldBeginsWith = function (field, value) {
|
|
127
|
+
this._addToQuery(field, '$regex', '^' + value)
|
|
128
|
+
|
|
129
|
+
return this
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Add a /value/i regex expression to the saved query
|
|
134
|
+
*
|
|
135
|
+
* @param {String} field
|
|
136
|
+
* @param {String} value
|
|
137
|
+
* @return API
|
|
138
|
+
* @api public
|
|
139
|
+
*/
|
|
140
|
+
CaruutoClient.prototype.whereFieldContains = function (field, value) {
|
|
141
|
+
this._addToQuery(field, '$regex', value)
|
|
142
|
+
|
|
143
|
+
return this
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Add a negated /value/i regex expression to the saved query
|
|
148
|
+
*
|
|
149
|
+
* @param {String} field
|
|
150
|
+
* @param {String} value
|
|
151
|
+
* @return API
|
|
152
|
+
* @api public
|
|
153
|
+
*/
|
|
154
|
+
CaruutoClient.prototype.whereFieldDoesNotContain = function (field, value) {
|
|
155
|
+
this._addToQuery(field, '$not', '/' + value + '/i')
|
|
156
|
+
|
|
157
|
+
return this
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Add a {$exists: false} expression to the saved query
|
|
162
|
+
*
|
|
163
|
+
* @param {String} field
|
|
164
|
+
* @return API
|
|
165
|
+
* @api public
|
|
166
|
+
*/
|
|
167
|
+
CaruutoClient.prototype.whereFieldDoesNotExist = function (field) {
|
|
168
|
+
this._addToQuery(field, '$eq', null)
|
|
169
|
+
|
|
170
|
+
return this
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Add a /value$/i regex expression to the saved query
|
|
175
|
+
*
|
|
176
|
+
* @param {String} field
|
|
177
|
+
* @param {String} value
|
|
178
|
+
* @return API
|
|
179
|
+
* @api public
|
|
180
|
+
*/
|
|
181
|
+
CaruutoClient.prototype.whereFieldEndsWith = function (field, value) {
|
|
182
|
+
this._addToQuery(field, '$regex', value + '$')
|
|
183
|
+
|
|
184
|
+
return this
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Add a {$exists: true} expression to the saved query
|
|
189
|
+
*
|
|
190
|
+
* @param {String} field
|
|
191
|
+
* @return API
|
|
192
|
+
* @api public
|
|
193
|
+
*/
|
|
194
|
+
CaruutoClient.prototype.whereFieldExists = function (field) {
|
|
195
|
+
this._addToQuery(field, '$ne', null)
|
|
196
|
+
|
|
197
|
+
return this
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Add an exact match expression to the saved query
|
|
202
|
+
*
|
|
203
|
+
* @param {String} field
|
|
204
|
+
* @param {String} value
|
|
205
|
+
* @return API
|
|
206
|
+
* @api public
|
|
207
|
+
*/
|
|
208
|
+
CaruutoClient.prototype.whereFieldIsEqualTo = function (field, value) {
|
|
209
|
+
this._addToQuery(field, value)
|
|
210
|
+
|
|
211
|
+
return this
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Add a $gt expression to the saved query
|
|
216
|
+
*
|
|
217
|
+
* @param {String} field
|
|
218
|
+
* @param {Number} value
|
|
219
|
+
* @return API
|
|
220
|
+
* @api public
|
|
221
|
+
*/
|
|
222
|
+
CaruutoClient.prototype.whereFieldIsGreaterThan = function (field, value) {
|
|
223
|
+
this._addToQuery(field, '$gt', value)
|
|
224
|
+
|
|
225
|
+
return this
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Add a $gte expression to the saved query
|
|
230
|
+
*
|
|
231
|
+
* @param {String} field
|
|
232
|
+
* @param {Number} value
|
|
233
|
+
* @return API
|
|
234
|
+
* @api public
|
|
235
|
+
*/
|
|
236
|
+
CaruutoClient.prototype.whereFieldIsGreaterThanOrEqualTo = function (
|
|
237
|
+
field,
|
|
238
|
+
value
|
|
239
|
+
) {
|
|
240
|
+
this._addToQuery(field, '$gte', value)
|
|
241
|
+
|
|
242
|
+
return this
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Add a $lt expression to the saved query
|
|
247
|
+
*
|
|
248
|
+
* @param {String} field
|
|
249
|
+
* @param {Number} value
|
|
250
|
+
* @return API
|
|
251
|
+
* @api public
|
|
252
|
+
*/
|
|
253
|
+
CaruutoClient.prototype.whereFieldIsLessThan = function (field, value) {
|
|
254
|
+
this._addToQuery(field, '$lt', value)
|
|
255
|
+
|
|
256
|
+
return this
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Add a $lte expression to the saved query
|
|
261
|
+
*
|
|
262
|
+
* @param {String} field
|
|
263
|
+
* @param {Number} value
|
|
264
|
+
* @return API
|
|
265
|
+
* @api public
|
|
266
|
+
*/
|
|
267
|
+
CaruutoClient.prototype.whereFieldIsLessThanOrEqualTo = function (
|
|
268
|
+
field,
|
|
269
|
+
value
|
|
270
|
+
) {
|
|
271
|
+
this._addToQuery(field, '$lte', value)
|
|
272
|
+
|
|
273
|
+
return this
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Add a negated exact match expression to the saved query
|
|
278
|
+
*
|
|
279
|
+
* @param {String} field
|
|
280
|
+
* @param {String} value
|
|
281
|
+
* @return API
|
|
282
|
+
* @api public
|
|
283
|
+
*/
|
|
284
|
+
CaruutoClient.prototype.whereFieldIsNotEqualTo = function (field, value) {
|
|
285
|
+
if (isNaN(value)) {
|
|
286
|
+
this._addToQuery(field, '$not', '/^' + value + '$/i')
|
|
287
|
+
} else {
|
|
288
|
+
this._addToQuery(field, '$ne', value)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
return this
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Add a $nin expression to the saved query
|
|
296
|
+
*
|
|
297
|
+
* @param {String} field
|
|
298
|
+
* @param {Array} matches
|
|
299
|
+
* @return API
|
|
300
|
+
* @api public
|
|
301
|
+
*/
|
|
302
|
+
CaruutoClient.prototype.whereFieldIsNotOneOf = function (field, matches) {
|
|
303
|
+
this._addToQuery(field, '$nin', matches)
|
|
304
|
+
|
|
305
|
+
return this
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Add a $in expression to the saved query
|
|
310
|
+
*
|
|
311
|
+
* @param {String} field
|
|
312
|
+
* @param {Array} matches
|
|
313
|
+
* @return API
|
|
314
|
+
* @api public
|
|
315
|
+
*/
|
|
316
|
+
CaruutoClient.prototype.whereFieldIsOneOf = function (field, matches) {
|
|
317
|
+
this._addToQuery(field, '$in', matches)
|
|
318
|
+
|
|
319
|
+
return this
|
|
320
|
+
}
|
|
321
|
+
}
|
package/lib/helpers.js
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
const querystring = require('query-string')
|
|
2
|
+
const parseUrl = require('url-parse')
|
|
3
|
+
|
|
4
|
+
module.exports = function (CaruutoClient) {
|
|
5
|
+
/**
|
|
6
|
+
* Add a Mongo query expression to the save query
|
|
7
|
+
*
|
|
8
|
+
* @param {String} field
|
|
9
|
+
* @param {String} operator
|
|
10
|
+
* @param {String} value
|
|
11
|
+
* @return undefined
|
|
12
|
+
* @api private
|
|
13
|
+
*/
|
|
14
|
+
CaruutoClient.prototype._addToQuery = function (field, operator, value) {
|
|
15
|
+
if (this.query === undefined) {
|
|
16
|
+
this.query = {}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
if (this.query[field] === undefined) {
|
|
20
|
+
this.query[field] = {}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (value === undefined) {
|
|
24
|
+
this.query[field] = operator
|
|
25
|
+
} else {
|
|
26
|
+
this.query[field][operator] = value
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Build an API URL
|
|
32
|
+
*
|
|
33
|
+
* @param {Object} options
|
|
34
|
+
* @return String
|
|
35
|
+
* @api private
|
|
36
|
+
*/
|
|
37
|
+
CaruutoClient.prototype._buildURL = function (options) {
|
|
38
|
+
// console.log('options :>> ', options)
|
|
39
|
+
options = options || {}
|
|
40
|
+
|
|
41
|
+
options.version = `v${this.options.version || 0}`
|
|
42
|
+
|
|
43
|
+
let url = ''
|
|
44
|
+
|
|
45
|
+
url += this.options.caruutoUrl
|
|
46
|
+
// url += ':' + this.options.port
|
|
47
|
+
|
|
48
|
+
if (this.mediaBucket) {
|
|
49
|
+
url +=
|
|
50
|
+
'/media' +
|
|
51
|
+
(typeof this.mediaBucket === 'string' ? '/' + this.mediaBucket : '')
|
|
52
|
+
} else if (this.collection) {
|
|
53
|
+
url += '/' + options.version + '/' + this.collection
|
|
54
|
+
} else {
|
|
55
|
+
url +=
|
|
56
|
+
'/' +
|
|
57
|
+
(this.customVersion !== undefined
|
|
58
|
+
? this.customVersion
|
|
59
|
+
: options.version) +
|
|
60
|
+
'/' +
|
|
61
|
+
this.endpoint
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (options.signUrl) {
|
|
65
|
+
url += '/sign'
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// if (options.config) {
|
|
69
|
+
// url += '/config'
|
|
70
|
+
// }
|
|
71
|
+
|
|
72
|
+
if (options.status) {
|
|
73
|
+
url += '/status'
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (options.collections) {
|
|
77
|
+
url += '/api/contentTypes'
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// if (options.stats) {
|
|
81
|
+
// url += '/stats'
|
|
82
|
+
// }
|
|
83
|
+
|
|
84
|
+
if (this.count) {
|
|
85
|
+
url += '/count'
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (options.id) {
|
|
89
|
+
url += '/' + options.id
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (options.useParams) {
|
|
93
|
+
const params = {}
|
|
94
|
+
|
|
95
|
+
if (this.query) {
|
|
96
|
+
params.filter = JSON.stringify(this._encodeObjectKeys(this.query))
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (this.fields) {
|
|
100
|
+
params.fields = this.fields
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!isNaN(parseInt(this.limit))) {
|
|
104
|
+
params.count = this.limit
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (this.page) {
|
|
108
|
+
params.page = this.page
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (this.compose !== undefined) {
|
|
112
|
+
params.compose = this.compose
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (typeof this.history !== 'undefined') {
|
|
116
|
+
params.includeHistory = this.history
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (this.sort) {
|
|
120
|
+
params.sort = JSON.stringify(this.sort)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const paramsStr = querystring.stringify(params, {
|
|
124
|
+
encode: false
|
|
125
|
+
})
|
|
126
|
+
|
|
127
|
+
if (paramsStr.length > 0) {
|
|
128
|
+
url += '?' + paramsStr
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return url
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Formats a request as an object
|
|
137
|
+
*
|
|
138
|
+
* @param {Object} options - request options
|
|
139
|
+
* @return Object
|
|
140
|
+
* @api private
|
|
141
|
+
*/
|
|
142
|
+
CaruutoClient.prototype._createRequestObject = function (options) {
|
|
143
|
+
const parsedUri = parseUrl(options.uri)
|
|
144
|
+
const requestObject = Object.assign({}, options, {
|
|
145
|
+
uri: {
|
|
146
|
+
href: parsedUri.href,
|
|
147
|
+
hostname: parsedUri.hostname,
|
|
148
|
+
path: parsedUri.path,
|
|
149
|
+
port: parsedUri.port,
|
|
150
|
+
protocol: parsedUri.protocol
|
|
151
|
+
}
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
if (this.headers) {
|
|
155
|
+
requestObject.headers = this.headers
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
if (typeof this.options.callback === 'function') {
|
|
159
|
+
return this.options.callback(requestObject, this)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
return requestObject
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Recursively URI encodes all properties of an object
|
|
167
|
+
* @param {Object} object The object to encode
|
|
168
|
+
* @return {Object} The encoded object
|
|
169
|
+
*/
|
|
170
|
+
CaruutoClient.prototype._encodeObjectKeys = function (object) {
|
|
171
|
+
return Object.keys(object).reduce((result, key) => {
|
|
172
|
+
if (
|
|
173
|
+
object[key] &&
|
|
174
|
+
typeof object[key] === 'object' &&
|
|
175
|
+
!Array.isArray(object[key])
|
|
176
|
+
) {
|
|
177
|
+
result[key] = this._encodeObjectKeys(object[key])
|
|
178
|
+
} else {
|
|
179
|
+
result[key] =
|
|
180
|
+
typeof object[key] === 'string'
|
|
181
|
+
? encodeURIComponent(object[key])
|
|
182
|
+
: object[key]
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return result
|
|
186
|
+
}, {})
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Logs a message
|
|
191
|
+
*
|
|
192
|
+
* @param {String} message
|
|
193
|
+
* @return undefined
|
|
194
|
+
* @api private
|
|
195
|
+
*/
|
|
196
|
+
CaruutoClient.prototype._log = function (message) {
|
|
197
|
+
if (console && console.log) {
|
|
198
|
+
console.log(`[Caruuto JS] ${message}`)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Clear any saved options and parameters
|
|
204
|
+
*
|
|
205
|
+
* @return undefined
|
|
206
|
+
* @api private
|
|
207
|
+
*/
|
|
208
|
+
CaruutoClient.prototype._reset = function () {
|
|
209
|
+
this.params = {}
|
|
210
|
+
this.customVersion = undefined
|
|
211
|
+
this.property = undefined
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Set a header on the response object
|
|
216
|
+
*
|
|
217
|
+
* @param {String} name
|
|
218
|
+
* @param {String} value
|
|
219
|
+
* @return undefined
|
|
220
|
+
* @api private
|
|
221
|
+
*/
|
|
222
|
+
CaruutoClient.prototype._setHeader = function (name, value) {
|
|
223
|
+
this.headers = this.headers || {}
|
|
224
|
+
|
|
225
|
+
this.headers[name] = value
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Strip reserved properties from document object
|
|
230
|
+
*
|
|
231
|
+
* @param {Object} document
|
|
232
|
+
* @return Object
|
|
233
|
+
* @api private
|
|
234
|
+
*/
|
|
235
|
+
CaruutoClient.prototype._stripReservedProperties = function (document) {
|
|
236
|
+
const sanitisedDocument = {}
|
|
237
|
+
|
|
238
|
+
Object.keys(document).forEach(property => {
|
|
239
|
+
if (this.reservedProperties.indexOf(property) === -1) {
|
|
240
|
+
sanitisedDocument[property] = document[property]
|
|
241
|
+
}
|
|
242
|
+
})
|
|
243
|
+
|
|
244
|
+
return sanitisedDocument
|
|
245
|
+
}
|
|
246
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const crossFetch = require('cross-fetch')
|
|
2
|
+
const debug = require('debug')('caruuto-js')
|
|
3
|
+
|
|
4
|
+
const resolveFetch = customFetch => {
|
|
5
|
+
let _fetch
|
|
6
|
+
|
|
7
|
+
if (customFetch) {
|
|
8
|
+
_fetch = customFetch
|
|
9
|
+
} else if (typeof fetch === 'undefined') {
|
|
10
|
+
_fetch = crossFetch
|
|
11
|
+
} else {
|
|
12
|
+
_fetch = fetch
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return (...args) => _fetch(...args)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = function (CaruutoClient) {
|
|
19
|
+
/**
|
|
20
|
+
* Makes a request to API and handles possible failures
|
|
21
|
+
*
|
|
22
|
+
* @param {Object} options - request options
|
|
23
|
+
* @return Results
|
|
24
|
+
* @api private
|
|
25
|
+
*/
|
|
26
|
+
CaruutoClient.prototype._processRequest = async function (requestObject) {
|
|
27
|
+
const fetch = resolveFetch(this.options.fetch)
|
|
28
|
+
const options = {
|
|
29
|
+
headers: Object.assign({}, requestObject.headers),
|
|
30
|
+
method: requestObject.method,
|
|
31
|
+
uri: requestObject.uri.href
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (requestObject.body) {
|
|
35
|
+
options.body = requestObject.body
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (
|
|
39
|
+
requestObject.headers &&
|
|
40
|
+
requestObject.headers['content-type'] &&
|
|
41
|
+
requestObject.headers['content-type'] !== 'application/json'
|
|
42
|
+
) {
|
|
43
|
+
options.json = false
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
debug(`Querying URI: ${decodeURIComponent(options.uri)}`)
|
|
47
|
+
|
|
48
|
+
// console.log('options :>> ', options)
|
|
49
|
+
|
|
50
|
+
const response = await fetch(options.uri, options).catch(err => {
|
|
51
|
+
console.log('err :>> ', err)
|
|
52
|
+
return Promise.reject(err)
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
if (response.status >= 400) {
|
|
56
|
+
const err = new Error()
|
|
57
|
+
err.status = response.status
|
|
58
|
+
err.uri = options.uri
|
|
59
|
+
|
|
60
|
+
try {
|
|
61
|
+
const responseData = await response.json()
|
|
62
|
+
|
|
63
|
+
if (responseData.message) {
|
|
64
|
+
err.message = responseData.message
|
|
65
|
+
}
|
|
66
|
+
} catch (error) {}
|
|
67
|
+
return Promise.reject(err)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return await response.json()
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
module.exports = function (CaruutoClient) {
|
|
2
|
+
/**
|
|
3
|
+
* Create one/multiple documents or hooks
|
|
4
|
+
*
|
|
5
|
+
* @param {Object} data
|
|
6
|
+
* @return Promise
|
|
7
|
+
* @api public
|
|
8
|
+
*/
|
|
9
|
+
CaruutoClient.prototype.create = function (data) {
|
|
10
|
+
this.terminator = 'create'
|
|
11
|
+
|
|
12
|
+
const requestPayload = {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
uri: this._buildURL()
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// if (this._isValidHook()) {
|
|
18
|
+
// requestPayload.body = data
|
|
19
|
+
|
|
20
|
+
// this._setHeader('content-type', 'text/plain')
|
|
21
|
+
// } else {
|
|
22
|
+
requestPayload.body =
|
|
23
|
+
data instanceof Array
|
|
24
|
+
? data.map(this._stripReservedProperties.bind(this))
|
|
25
|
+
: this._stripReservedProperties(data)
|
|
26
|
+
// }
|
|
27
|
+
|
|
28
|
+
return this._createRequestObject(requestPayload)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Delete the documents affected by the saved query
|
|
33
|
+
*
|
|
34
|
+
* @return Promise
|
|
35
|
+
* @api public
|
|
36
|
+
*/
|
|
37
|
+
CaruutoClient.prototype.delete = function () {
|
|
38
|
+
this.terminator = 'delete'
|
|
39
|
+
|
|
40
|
+
const requestPayload = {
|
|
41
|
+
method: 'DELETE',
|
|
42
|
+
uri: this._buildURL()
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// if (!this._isValidHook()) {
|
|
46
|
+
// if (this.isClient) {
|
|
47
|
+
// if (!this.isClient.id && !this.isClient.self) {
|
|
48
|
+
// throw new Error(
|
|
49
|
+
// 'Unable run delete on all clients. Please use the whereClientIs() filter.'
|
|
50
|
+
// )
|
|
51
|
+
// }
|
|
52
|
+
// } else {
|
|
53
|
+
if (this.query === undefined) {
|
|
54
|
+
throw new Error('Unable to find query for delete')
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
requestPayload.body = {
|
|
58
|
+
query: this.query
|
|
59
|
+
}
|
|
60
|
+
// }
|
|
61
|
+
// }
|
|
62
|
+
|
|
63
|
+
return this._createRequestObject(requestPayload)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Get the documents affected by the saved query
|
|
68
|
+
*
|
|
69
|
+
* @return Promise
|
|
70
|
+
* @api public
|
|
71
|
+
*/
|
|
72
|
+
CaruutoClient.prototype.find = function (options) {
|
|
73
|
+
this.terminator = 'find'
|
|
74
|
+
|
|
75
|
+
if (options && options.extractMetadata) {
|
|
76
|
+
this.count = true
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
return this._createRequestObject({
|
|
80
|
+
method: 'GET',
|
|
81
|
+
uri: this._buildURL({
|
|
82
|
+
useParams: true
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Get a list of all collections
|
|
89
|
+
*
|
|
90
|
+
* @return Promise
|
|
91
|
+
* @api public
|
|
92
|
+
*/
|
|
93
|
+
CaruutoClient.prototype.getCollections = function () {
|
|
94
|
+
this.terminator = 'getCollections'
|
|
95
|
+
|
|
96
|
+
return this._createRequestObject({
|
|
97
|
+
method: 'GET',
|
|
98
|
+
uri: this._buildURL({ collections: true })
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Get the config for a collection if one is specified, or for main API if not
|
|
104
|
+
*
|
|
105
|
+
* @return Promise
|
|
106
|
+
* @api public
|
|
107
|
+
*/
|
|
108
|
+
CaruutoClient.prototype.getConfig = function () {
|
|
109
|
+
this.terminator = 'getConfig'
|
|
110
|
+
|
|
111
|
+
return this._createRequestObject({
|
|
112
|
+
method: 'GET',
|
|
113
|
+
uri: this._buildURL({ config: true })
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Get the languages supported by the API
|
|
119
|
+
*
|
|
120
|
+
* @return Promise
|
|
121
|
+
* @api public
|
|
122
|
+
*/
|
|
123
|
+
// CaruutoClient.prototype.getLanguages = function () {
|
|
124
|
+
// this.terminator = 'getLanguages'
|
|
125
|
+
|
|
126
|
+
// return this._createRequestObject({
|
|
127
|
+
// method: 'GET',
|
|
128
|
+
// uri: this._buildURL({ languages: true })
|
|
129
|
+
// })
|
|
130
|
+
// }
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Get a signed URL for media upload
|
|
134
|
+
*
|
|
135
|
+
* @return Promise
|
|
136
|
+
* @api public
|
|
137
|
+
*/
|
|
138
|
+
CaruutoClient.prototype.getSignedUrl = function (parameters) {
|
|
139
|
+
this.terminator = 'getSignedUrl'
|
|
140
|
+
|
|
141
|
+
return this._createRequestObject({
|
|
142
|
+
body: parameters,
|
|
143
|
+
method: 'POST',
|
|
144
|
+
uri: this._buildURL({ signUrl: true })
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get the status of the API
|
|
150
|
+
*
|
|
151
|
+
* @return Promise
|
|
152
|
+
* @api public
|
|
153
|
+
*/
|
|
154
|
+
CaruutoClient.prototype.getStatus = function () {
|
|
155
|
+
this.terminator = 'getStatus'
|
|
156
|
+
|
|
157
|
+
return this._createRequestObject({
|
|
158
|
+
method: 'POST',
|
|
159
|
+
uri: this._buildURL({ status: true })
|
|
160
|
+
})
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Update the documents affect by the saved query
|
|
165
|
+
*
|
|
166
|
+
* @param {Object} update
|
|
167
|
+
* @return Promise
|
|
168
|
+
* @api public
|
|
169
|
+
*/
|
|
170
|
+
CaruutoClient.prototype.update = function (update) {
|
|
171
|
+
this.terminator = 'update'
|
|
172
|
+
|
|
173
|
+
const requestPayload = {
|
|
174
|
+
method: 'PUT',
|
|
175
|
+
uri: this._buildURL()
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// if (this._isValidHook()) {
|
|
179
|
+
// requestPayload.body = update
|
|
180
|
+
|
|
181
|
+
// this._setHeader('content-type', 'text/plain')
|
|
182
|
+
// } else {
|
|
183
|
+
// if (this.isClient) {
|
|
184
|
+
// if (!this.isClient.id && !this.isClient.self) {
|
|
185
|
+
// throw new Error(
|
|
186
|
+
// 'Unable to run update on all clients. Please use whereClientIs() or whereClientIsSelf() filters.'
|
|
187
|
+
// )
|
|
188
|
+
// }
|
|
189
|
+
|
|
190
|
+
// // Remove `clientId` from the payload.
|
|
191
|
+
// if (update.clientId) {
|
|
192
|
+
// delete update.clientId
|
|
193
|
+
// }
|
|
194
|
+
|
|
195
|
+
// requestPayload.body = update
|
|
196
|
+
// } else {
|
|
197
|
+
if (this.query === undefined) {
|
|
198
|
+
throw new Error('Unable to find query for update')
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
requestPayload.body = {
|
|
202
|
+
query: this.query,
|
|
203
|
+
update: this._stripReservedProperties(update)
|
|
204
|
+
}
|
|
205
|
+
// }
|
|
206
|
+
// }
|
|
207
|
+
|
|
208
|
+
return this._createRequestObject(requestPayload)
|
|
209
|
+
}
|
|
210
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@caruuto/caruuto-js",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A high-level library for interacting with Caruuto",
|
|
5
|
+
"exports": "./index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"test": "eslint --ext js,jsx . && prettier --write '**/*.{js,jsx,md,html,css}' && NODE_ENV=test mocha {test,core/test}/**/*.js",
|
|
8
|
+
"posttest": "./scripts/coverage.js"
|
|
9
|
+
},
|
|
10
|
+
"author": "Jim Lambie <jim@27.works>",
|
|
11
|
+
"license": "GPL",
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"cross-fetch": "^3.1.6",
|
|
14
|
+
"debug": "^2.6.1",
|
|
15
|
+
"got": "^11.0.0",
|
|
16
|
+
"mocha": "^10.2.0",
|
|
17
|
+
"query-string": "5.0.1",
|
|
18
|
+
"url-parse": "1.4.3"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/Caruuto/caruuto-js.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/Caruuto/caruuto-js/issues"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=16"
|
|
29
|
+
},
|
|
30
|
+
"husky": {
|
|
31
|
+
"hooks": {
|
|
32
|
+
"pre-commit": "lint-staged"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"lint-staged": {
|
|
36
|
+
"*.{js,jsx,md,html,css}": [
|
|
37
|
+
"prettier --write",
|
|
38
|
+
"git add"
|
|
39
|
+
]
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/Caruuto/caruuto-js",
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"coveralls": "^3.0.2",
|
|
44
|
+
"eslint": "8.5.0",
|
|
45
|
+
"eslint-config-next": "13.0.5",
|
|
46
|
+
"eslint-config-prettier": "^8.6.0",
|
|
47
|
+
"eslint-plugin-prettier": "^4.2.1",
|
|
48
|
+
"eslint-plugin-react": "^7.32.2",
|
|
49
|
+
"form-data": "^4.0.0",
|
|
50
|
+
"husky": "^8.0.0",
|
|
51
|
+
"lint-staged": "^13.2.1",
|
|
52
|
+
"mockery": "^1.7.0",
|
|
53
|
+
"nock": "^12.0.0",
|
|
54
|
+
"nyc": "^15.0.1",
|
|
55
|
+
"prettier": "2.8.4",
|
|
56
|
+
"prettier-standard": "^15.0.1",
|
|
57
|
+
"should": "^9.0.2",
|
|
58
|
+
"sinon": "^4.5.0",
|
|
59
|
+
"standard": "^16.0.3",
|
|
60
|
+
"supertest": "^4.0.0",
|
|
61
|
+
"underscore": "^1.8.3"
|
|
62
|
+
},
|
|
63
|
+
"standard.options": {
|
|
64
|
+
"ignore": [],
|
|
65
|
+
"plugins": [],
|
|
66
|
+
"envs": []
|
|
67
|
+
}
|
|
68
|
+
}
|
package/x.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const { createClient } = require('./index')
|
|
2
|
+
|
|
3
|
+
;(async () => {
|
|
4
|
+
const x = createClient('https://caruuto-next.27.works/api', 'apiKey2')
|
|
5
|
+
|
|
6
|
+
x.in('surveys')
|
|
7
|
+
// x.whereFieldContains('title', 'John')
|
|
8
|
+
x.goToPage(1)
|
|
9
|
+
|
|
10
|
+
const y = await x.find().catch(console.log)
|
|
11
|
+
|
|
12
|
+
console.log(y)
|
|
13
|
+
})()
|