@qikdev/sdk 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/.gitlab-ci.yml ADDED
@@ -0,0 +1,13 @@
1
+ # You can override the included template(s) by including variable overrides
2
+ # SAST customization: https://docs.gitlab.com/ee/user/application_security/sast/#customizing-the-sast-settings
3
+ # Secret Detection customization: https://docs.gitlab.com/ee/user/application_security/secret_detection/#customizing-settings
4
+ # Dependency Scanning customization: https://docs.gitlab.com/ee/user/application_security/dependency_scanning/#customizing-the-dependency-scanning-settings
5
+ # Container Scanning customization: https://docs.gitlab.com/ee/user/application_security/container_scanning/#customizing-the-container-scanning-settings
6
+ # Note that environment variables can be set in several places
7
+ # See https://docs.gitlab.com/ee/ci/variables/#cicd-variable-precedence
8
+ stages:
9
+ - test
10
+ sast:
11
+ stage: test
12
+ include:
13
+ - template: Security/SAST.gitlab-ci.yml
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+
2
+
3
+
4
+ # Qik Javascript SDK
5
+
6
+ [Site](https://qik.dev) |
7
+
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ npm install qikdev --save
13
+ ```
14
+
15
+ ## Getting Started
16
+
17
+ ```js
18
+ //Import the Qik module
19
+ import Qik from 'qikdev';
20
+
21
+
22
+
23
+
24
+
25
+ ```
package/jsdoc.conf ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "source": {
3
+ "exclude": [
4
+ "node_modules"
5
+ ]
6
+ },
7
+ "opts": {
8
+ "template": "node_modules/docdash"
9
+ }
10
+ }
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@qikdev/sdk",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Promise based Javascript SDK",
6
+ "scripts": {
7
+ "build": "webpack --mode=production && npm run test",
8
+ "dev": "webpack --mode=development --progress --colors --watch",
9
+ "test": "mocha --colors ./test/*.spec.js",
10
+ "test:watch": "mocha --colors -w ./test/*.spec.js",
11
+ "document": "jsdoc -r . -d docs -c jsdoc.conf README.md"
12
+ },
13
+ "main": "dist/index.js",
14
+ "homepage": "https://qik.dev",
15
+ "bugs": {
16
+ "url":"https://support.qik.dev"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://gitlab.com/qikdevelopers/sdk.git"
21
+ },
22
+ "keywords": [
23
+ "qik",
24
+ "api",
25
+ "javascript"
26
+ ],
27
+ "author": "qik.dev",
28
+ "license": "ISC",
29
+ "devDependencies": {
30
+ "babel-preset-env": "^1.7.0",
31
+ "babel-register": "^6.26.0",
32
+ "chai": "^4.2.0",
33
+ "docdash": "^1.1.1",
34
+ "jsdoc": "^3.6.3",
35
+ "jsdom": "^14.1.0",
36
+ "mocha": "^9.2.0",
37
+ "webpack": "^4.41.5",
38
+ "webpack-cli": "^3.3.11"
39
+ },
40
+ "dependencies": {
41
+ "axios": "^0.19.2",
42
+ "axios-extensions": "^3.1.2",
43
+ "browser-or-node": "^1.2.1",
44
+ "lodash": "^4.17.15"
45
+ }
46
+ }
@@ -0,0 +1,92 @@
1
+ import _ from 'lodash';
2
+ import { EventDispatcher } from './qik.utils.js';
3
+
4
+
5
+ ///////////////////////////////////////////////////////////////////////////////
6
+
7
+ /**
8
+ * Creates a new QikAccess service
9
+ * This module provides helpful functions and tools for managing and understanding a user's permissions and access control
10
+ *
11
+ * @alias access
12
+ * @constructor
13
+ * @hideconstructor
14
+ * @param {QikCore} qik A reference to the parent instance of the QikCore module. This module is usually created by a QikCore instance that passes itself in as the first argument.
15
+ */
16
+ var QikAccess = function(QikCore) {
17
+
18
+
19
+ if (!QikCore.auth) {
20
+ throw new Error(`Can't Instantiate QikAccess before QikAccess has been initialized`);
21
+ }
22
+
23
+ //////////////////////////////////
24
+
25
+ var store = {};
26
+ var service = {};
27
+
28
+ //Create a new dispatcher
29
+ var dispatcher = new EventDispatcher();
30
+ dispatcher.bootstrap(service);
31
+
32
+
33
+ ///////////////////////////////////////////////////////////////////////////////
34
+
35
+ /**
36
+ * Check whether a user has a specific permission, useful for checking custom permissions
37
+ * or simply whether or not a user has a permission in any realm
38
+ * @param {String} permission The permission to check
39
+ * @return {Boolean}
40
+ * @alias access.has
41
+ * @example
42
+ *
43
+ * //Returns true or false if the user has the permission
44
+ * var hasPermission = qik.access.has('create photo');
45
+ */
46
+ service.has = function(permission, webMode) {
47
+
48
+ //Get the current acting user session
49
+ var user = service.retrieveCurrentSession(webMode);
50
+
51
+ if (!user) {
52
+ return false;
53
+ }
54
+
55
+ if (service.isQikAdmin() && !webMode) {
56
+ return true;
57
+ }
58
+
59
+ ///////////////////////////////////////////////////////////////////////////////
60
+
61
+ var permissionSets = user.permissionSets;
62
+
63
+ //Get all of the possible permissions
64
+ var permissions = _.chain(permissionSets)
65
+ .reduce(function(results, set, key) {
66
+
67
+ results.push(set.permissions);
68
+
69
+ return results;
70
+ }, [])
71
+ // .map(retrieveSubRealms)
72
+ .flattenDeep()
73
+ .compact()
74
+ .uniq()
75
+ .value();
76
+
77
+ //Check if any of the users permissions include the one
78
+ //we are looking for
79
+ return _.includes(permissions, permission);
80
+ }
81
+
82
+ //////////////////////////////////
83
+
84
+ return service;
85
+
86
+ }
87
+
88
+ ///////////////////////////////////////////////////////////////////////////////
89
+
90
+
91
+
92
+ export default QikAccess;
@@ -0,0 +1,406 @@
1
+ import axios from 'axios';
2
+ import _ from 'lodash';
3
+ import qs from 'qs';
4
+
5
+
6
+
7
+ import {
8
+ cacheAdapterEnhancer,
9
+ throttleAdapterEnhancer,
10
+ Cache,
11
+ } from 'axios-extensions';
12
+
13
+
14
+ const CancelToken = axios.CancelToken;
15
+
16
+ ///////////////////////////////////////
17
+
18
+
19
+ /**
20
+ * Creates a new QikAPI instance.
21
+ * This module is a wrapper around the <a href="https://www.npmjs.com/package/axios">axios</a> package. It aims to make it easier for you to connect with and consume endpoints from the Qik REST API for more information about the available endpoints see <a href="https://developer.qik.io">Qik REST API Documentation</a>
22
+ * @alias api
23
+ * @constructor
24
+ * @param {QikCore} qik A reference to the parent instance of the QikCore module. The QikAPI module is usually created by a QikCore instance that passes itself in as the first argument.
25
+ */
26
+
27
+
28
+ var QikAPI = function(qik) {
29
+
30
+ ///////////////////////////////////////
31
+
32
+ // //Cache Defaults
33
+ // var FIVE_MINUTES = 1000 * 60 * 5;
34
+ // var CAPACITY = 100;
35
+ // { maxAge: FIVE_MINUTES, max: 100 }
36
+
37
+
38
+ /**
39
+ * The default cache to use when requests are made from this instance
40
+ * @type {LRUCache}
41
+ * @access private
42
+ */
43
+ var defaultCache;
44
+
45
+ if (process.browser) {
46
+ defaultCache = qik.cache.get('api');
47
+ }
48
+
49
+ ///////////////////////////////////////
50
+
51
+ //Get the default adapter
52
+ const defaultAdapter = axios.defaults.adapter
53
+ // console.log('DEFAULT ADAPTER', defaultAdapter)
54
+
55
+
56
+ ///////////////////////////////////////
57
+
58
+ //Add our own adapter to the service
59
+ let cacheAdapter = function(config) {
60
+
61
+ return new Promise(function(resolve, reject) {
62
+
63
+
64
+ var useCache;
65
+ var cachedResponse;
66
+
67
+ ///////////////////////////////////////
68
+
69
+ //Don't cache action methods
70
+ switch (String(config.method).toLowerCase()) {
71
+ case 'post':
72
+ case 'patch':
73
+ case 'put':
74
+ case 'delete':
75
+ //Unless we've specified we want a cache
76
+ if (!config.cache) {
77
+ //Don't use the cache
78
+ config.cache = false;
79
+ }
80
+ break;
81
+ }
82
+
83
+ ///////////////////////////////////////
84
+ ///////////////////////////////////////
85
+
86
+ if (config.cache === false) {
87
+ //No cache so make new request
88
+ } else {
89
+
90
+ //Use the cache specified or the default cache
91
+ useCache = config.cache || defaultCache;
92
+
93
+ //If there is a cache
94
+ if (useCache) {
95
+
96
+ //Generate the cache key from the request
97
+ var cacheKey = getCacheKeyFromConfig(config);
98
+
99
+ //If we have the cachedResponse version
100
+ cachedResponse = useCache.get(cacheKey);
101
+ }
102
+ }
103
+
104
+ ///////////////////////////////////////
105
+ ///////////////////////////////////////
106
+
107
+ if (cachedResponse) {
108
+ // console.log('FROM CACHE', config.url, cachedResponse);
109
+ return resolve(cachedResponse);
110
+ }
111
+
112
+
113
+
114
+ // const axiosWithoutAdapter = createNewAxios();
115
+
116
+
117
+ var copy = Object.assign(config, { adapter: defaultAdapter });
118
+
119
+
120
+ // console.log('NEW ADAPTER THING', copy)
121
+ // const axiosWithoutAdapter = axios(copy);
122
+
123
+
124
+ return axios.request(config)
125
+ .then(function(res) {
126
+
127
+ // console.log('RESPONSE', res)
128
+ resolve(res);
129
+ }, function(err) {
130
+
131
+ // console.log('ERROR', err)
132
+ reject(err);
133
+ });
134
+
135
+ })
136
+ }
137
+
138
+
139
+
140
+
141
+ //////////////////////////////////////////////////////////////////////////////
142
+
143
+ const service = createNewAxios(cacheAdapter);
144
+
145
+ //////////////////////////////////////////////////////////////////////////////
146
+
147
+ function createNewAxios(adapter) {
148
+
149
+ var instance = axios.create({
150
+ paramsSerializer: params => qs.stringify(params, { arrayFormat: 'repeat' }),
151
+ adapter,
152
+ // adapter: throttleAdapterEnhancer(cacheAdapterEnhancer(axios.defaults.adapter, { defaultCache: defaultCache }))
153
+ // adapter: throttleAdapterEnhancer(cacheAdapterEnhancer(axios.defaults.adapter, { defaultCache: defaultCache }))
154
+ });
155
+
156
+ ///////////////////////////////////////
157
+
158
+ instance.defaults.baseURL = qik.apiURL;
159
+ instance.defaults.headers.common.Accept = 'application/json';
160
+
161
+ /////////////////////////////////////////////////////
162
+
163
+ // Add relative date and timezone to every request
164
+ instance.interceptors.request.use(function(config) {
165
+
166
+ config.headers['qik-request-date'] = new Date().getTime();
167
+ if (qik.date.defaultTimezone) {
168
+ config.headers['qik-request-timezone'] = Intl.DateTimeFormat().resolvedOptions().timeZone;
169
+ }
170
+
171
+ config.headers['qik-api-version'] = qik.version;
172
+
173
+ return config;
174
+
175
+ });
176
+
177
+ /////////////////////////////////////////////////////
178
+
179
+ instance.interceptors.response.use(function(response) {
180
+ var config = response.config
181
+ return response;
182
+ }, function(err) {
183
+
184
+ if (axios.isCancel(err)) {
185
+ console.log('Request cancelled');
186
+ return Promise.reject(err);
187
+ }
188
+
189
+ //Get the response status
190
+ var status = _.get(err, 'response.status') || err.status;
191
+
192
+ //Check the status
193
+ switch (status) {
194
+ case 401:
195
+ //Ignore let QikAuth handle it
196
+ break;
197
+ case 502:
198
+ case 504:
199
+ //Retry until it works
200
+ console.log(`qik.api > ${status} connection error retrying`)
201
+ return instance.request(err.config);
202
+ break;
203
+ case 404:
204
+ //Not found
205
+ break;
206
+ default:
207
+ //Some other error, likely a problem connecting to the server
208
+ console.log('qik.api > connection error', status, err);
209
+ break;
210
+ }
211
+
212
+ /////////////////////////////////////////////////////
213
+
214
+ return Promise.reject(err);
215
+ })
216
+
217
+ return instance;
218
+ }
219
+
220
+ ///////////////////////////////////////
221
+
222
+
223
+ /**
224
+ * @name api.get
225
+ * @description Makes a get http request to the Qik REST API
226
+ * @function
227
+ * @param {String} path The Qik API endpoint to request
228
+ * @param {Object} config Optional parameters for the request
229
+ * @example
230
+ * //Make a request to get the current user session
231
+ * qik.api.get('/content/article', {
232
+ * params:{
233
+ * select:'title created',
234
+ * limit:10,
235
+ * simple:true,
236
+ * }
237
+ * })
238
+ * .then(function (response) {
239
+ * console.log(response);
240
+ * })
241
+ * .catch(function (error) {
242
+ * console.log(error);
243
+ * });
244
+ */
245
+
246
+
247
+ /**
248
+ * @name api.post
249
+ * @description Makes a post http request to the Qik REST API
250
+ * @function
251
+ * @param {String} path The Qik API endpoint to request
252
+ * @param {Object} config Optional parameters for the request
253
+ * @example
254
+ *
255
+ * qik.api.post('/content/article', {title:'my new article', ...}, {
256
+ * //headers and other things
257
+ * })
258
+ * .then(function (response) {
259
+ * console.log(response);
260
+ * })
261
+ * .catch(function (error) {
262
+ * console.log(error);
263
+ * });
264
+ */
265
+
266
+ /**
267
+ * @name api.put
268
+ * @description Makes a put http request to the Qik REST API
269
+ * @function
270
+ * @param {String} path The Qik API endpoint to request
271
+ * @param {Object} config Optional parameters for the request
272
+ * @example
273
+ *
274
+ * qik.api.put('/content/article/5ca3d64dd2bb085eb9d450db', {title:'my new article', ...}, {
275
+ * //headers and other things
276
+ * })
277
+ * .then(function (response) {
278
+ * console.log(response);
279
+ * })
280
+ * .catch(function (error) {
281
+ * console.log(error);
282
+ * });
283
+ */
284
+
285
+ /**
286
+ * @name api.delete
287
+ * @description Makes a delete http request to the Qik REST API
288
+ * @function
289
+ * @param {String} path The Qik API endpoint to request
290
+ * @param {Object} config Optional parameters for the request
291
+ * @example
292
+ *
293
+ * qik.api.delete('/content/article/5ca3d64dd2bb085eb9d450db')
294
+ * .then(function (response) {
295
+ * console.log(response);
296
+ * })
297
+ * .catch(function (error) {
298
+ * console.log(error);
299
+ * });
300
+ */
301
+
302
+
303
+
304
+ ///////////////////////////////////////////////////
305
+
306
+ /**
307
+ * A helper function for generating an authenticated url for the current user
308
+ * @param {string} endpoint The id of the asset, or the asset object you want to download
309
+ * @alias api.generateEndpointURL
310
+ * @param {object} params
311
+ * @return {string} A full URL with relevant parameters included
312
+ * @example
313
+ * // returns 'https://api.qik.io/something?access_token=2352345...'
314
+ * qik.api.generateEndpointURL('/something');
315
+ */
316
+
317
+ service.generateEndpointURL = function(path, params) {
318
+
319
+ if (!path || !String(path).length) {
320
+ return;
321
+ }
322
+
323
+ if (!params) {
324
+ params = {};
325
+ }
326
+
327
+ var url = `${qik.apiURL}${path}`;
328
+
329
+ ////////////////////////////////////////
330
+
331
+ url = parameterDefaults(url, params);
332
+
333
+ ////////////////////////////////////////
334
+
335
+ //Map the parameters to a query string
336
+ var queryParameters = qik.utils.mapParameters(params);
337
+
338
+ if (queryParameters.length) {
339
+ url += '?' + queryParameters;
340
+ }
341
+
342
+ return url;
343
+
344
+ }
345
+
346
+ ///////////////////////////////////////////////////////
347
+
348
+ function parameterDefaults(url, params) {
349
+
350
+ //If we haven't requested without token
351
+ if (!params.withoutToken) {
352
+ //Get the current token from QikAuth
353
+ var CurrentQikToken = qik.auth.getCurrentToken();
354
+
355
+ //Check to see if we have a token and none has been explicity set
356
+ if (!params['access_token'] && CurrentQikToken) {
357
+ //Use the current token by default
358
+ params['access_token'] = CurrentQikToken;
359
+ }
360
+ }
361
+
362
+ return url;
363
+ }
364
+
365
+
366
+ /////////////////////////////////////////////////////
367
+
368
+ //Get all mongo ids from a string
369
+ function retrieveIDs(data) {
370
+
371
+ var dataString;
372
+
373
+ if (_.isString(data)) {
374
+ dataString = data;
375
+ } else {
376
+ dataString = JSON.stringify(data);
377
+ }
378
+
379
+ //Find all mongo ids included in the object
380
+ var myregexp = /[0-9a-fA-F]{24}/g;
381
+ var matches = dataString.match(myregexp);
382
+
383
+ //Make sure the matches are unique
384
+ return _.uniq(matches);
385
+ }
386
+
387
+ ///////////////////////////////////////
388
+
389
+
390
+ service.CancelToken = CancelToken;
391
+ service.axios = axios;
392
+
393
+ ///////////////////////////////////////
394
+
395
+ return service;
396
+ }
397
+
398
+
399
+
400
+
401
+ ///////////////////////////////////////
402
+ ///////////////////////////////////////
403
+ ///////////////////////////////////////
404
+
405
+ export { CancelToken as CancelToken };
406
+ export default QikAPI;