@qikdev/sdk 0.1.170 → 0.1.180
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/dist/main.js +1 -1
- package/package.json +4 -13
- package/src/api/qik.access.js +715 -750
- package/src/api/qik.api.js +3 -3
- package/src/api/qik.auth.js +797 -740
- package/src/api/qik.content.js +731 -712
- package/src/api/qik.core.js +1 -0
- package/src/api/qik.files.js +4 -40
- package/src/api/qik.socket.js +293 -305
- package/src/api/qik.utils.js +1 -3
- package/src/version.js +1 -1
- package/.husky/pre-commit +0 -5
- package/dist/sdk.js +0 -2
- package/dist/sdk.js.LICENSE.txt +0 -8
- package/eslint.config.js +0 -6
- package/yarn-error.log +0 -3598
package/src/api/qik.content.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import axios from
|
|
2
|
-
import _ from
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import _ from 'lodash';
|
|
3
3
|
|
|
4
4
|
///////////////////////////////////////////////////
|
|
5
5
|
|
|
@@ -11,126 +11,137 @@ import _ from "lodash";
|
|
|
11
11
|
* @hideconstructor
|
|
12
12
|
* @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.
|
|
13
13
|
*/
|
|
14
|
-
export default function
|
|
15
|
-
if (!qik.api) {
|
|
16
|
-
throw new Error(`Can't Instantiate QikContent before QikAPI exists`);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
///////////////////////////////////////////////////
|
|
20
|
-
|
|
21
|
-
var service = {
|
|
22
|
-
debug: false,
|
|
23
|
-
loadingGlossary: false,
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
///////////////////////////////////////////////////////////////////////////////
|
|
27
|
-
|
|
28
|
-
const variables = {};
|
|
29
|
-
let inflightVariablesRequest;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
*
|
|
33
|
-
* Retrieves all global variables for the current user. This is often used when running custom code in an action.
|
|
34
|
-
* @alias content.variables
|
|
35
|
-
* @param {Array} keys Provide specific keys of variables you want to retrieve
|
|
36
|
-
* @param {Object} options Additional options when making the request
|
|
37
|
-
* @param {Boolean} options.reload Force variables to reload and not be cached. If false will retrieve any variables that are already known from the in memory cache.
|
|
38
|
-
* @example
|
|
39
|
-
*
|
|
40
|
-
* const { OAUTH_CLIENT_ID, OAUTH_KEY } = await sdk.content.variables();
|
|
41
|
-
*/
|
|
42
|
-
|
|
43
|
-
service.variables = async function (keys, options) {
|
|
44
|
-
options = options || {};
|
|
45
|
-
keys = keys || [];
|
|
46
|
-
|
|
47
|
-
var reload = options.refresh || options.reload || !variables.data;
|
|
48
|
-
if (reload) {
|
|
49
|
-
if (!inflightVariablesRequest) {
|
|
50
|
-
inflightVariablesRequest = qik.api.post(`/variables`, { keys });
|
|
51
|
-
inflightVariablesRequest.then(resolveRequest, resolveRequest);
|
|
52
|
-
function resolveRequest() {
|
|
53
|
-
inflightVariablesRequest = null;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
14
|
+
export default function(qik) {
|
|
56
15
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
qik.dispatch("variables", data);
|
|
16
|
+
if (!qik.api) {
|
|
17
|
+
throw new Error(`Can't Instantiate QikContent before QikAPI exists`);
|
|
60
18
|
}
|
|
61
19
|
|
|
62
|
-
|
|
63
|
-
};
|
|
20
|
+
///////////////////////////////////////////////////
|
|
64
21
|
|
|
65
|
-
|
|
22
|
+
var service = {
|
|
23
|
+
debug: false,
|
|
24
|
+
loadingGlossary:false,
|
|
25
|
+
}
|
|
66
26
|
|
|
67
|
-
const glossaryCache = qik.cache.get("user:glossary");
|
|
68
27
|
|
|
69
|
-
|
|
28
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
70
29
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
30
|
+
const variables = {}
|
|
31
|
+
let inflightVariablesRequest;
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* Retrieves all global variables for the current user. This is often used when running custom code in an action.
|
|
37
|
+
* @alias content.variables
|
|
38
|
+
* @param {Array} keys Provide specific keys of variables you want to retrieve
|
|
39
|
+
* @param {Object} options Additional options when making the request
|
|
40
|
+
* @param {Boolean} options.reload Force variables to reload and not be cached. If false will retrieve any variables that are already known from the in memory cache.
|
|
41
|
+
* @example
|
|
42
|
+
*
|
|
43
|
+
* const { OAUTH_CLIENT_ID, OAUTH_KEY } = await sdk.content.variables();
|
|
44
|
+
*/
|
|
45
|
+
|
|
46
|
+
service.variables = async function(keys, options) {
|
|
47
|
+
options = options || {};
|
|
48
|
+
keys = keys || [];
|
|
49
|
+
|
|
50
|
+
var reload = options.refresh || options.reload || !variables.data;
|
|
51
|
+
if (reload) {
|
|
52
|
+
if(!inflightVariablesRequest) {
|
|
53
|
+
inflightVariablesRequest = qik.api.post(`/variables`, {keys});
|
|
54
|
+
inflightVariablesRequest.then(resolveRequest, resolveRequest);
|
|
55
|
+
function resolveRequest() {
|
|
56
|
+
inflightVariablesRequest = null;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const { data } = await inflightVariablesRequest
|
|
61
|
+
variables.data = data;
|
|
62
|
+
qik.dispatch('variables', data)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
return variables.data;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
///////////////////////////////////////////////////
|
|
69
|
+
|
|
70
|
+
const glossaryCache = qik.cache.get('user:glossary');
|
|
71
|
+
|
|
72
|
+
let inflightGlossaryRequest;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
*
|
|
76
|
+
* Retrieves the glossary of all content types visible to the requesting user.
|
|
74
77
|
By default this will include all fields, validation, expressions and other configuration
|
|
75
78
|
* @alias content.glossary
|
|
76
79
|
* @param {Object} options Additional options
|
|
77
|
-
* @param {Boolean} options.hash Whether to return the data as a keyed object
|
|
80
|
+
* @param {Boolean} options.hash Whether to return the data as a keyed object
|
|
78
81
|
allowing for fast selection of specific content types, by default will return as an array
|
|
79
82
|
* @param {Boolean} options.reload Force glossary to reload and not be cached.
|
|
80
83
|
If false will retrieve content type data from the in memory cache
|
|
81
84
|
* @example
|
|
82
|
-
*
|
|
85
|
+
*
|
|
83
86
|
* const { article, profile } = await sdk.content.glossary({hash:true});
|
|
84
87
|
*/
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
88
|
+
service.glossary = async function(options) {
|
|
89
|
+
options = options || {};
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
// Check if we already have the glossary cached
|
|
93
|
+
let cached = glossaryCache.get('glossary');
|
|
94
|
+
var reload = options.refresh || options.reload || !cached;
|
|
95
|
+
|
|
96
|
+
// If we are forcing a reload
|
|
97
|
+
if (reload) {
|
|
98
|
+
if(!inflightGlossaryRequest) {
|
|
99
|
+
|
|
100
|
+
service.loadingGlossary = true;
|
|
101
|
+
|
|
102
|
+
inflightGlossaryRequest = qik.api.get(`/glossary`, {cache:false});
|
|
103
|
+
inflightGlossaryRequest.then(resolveRequest, resolveRequest);
|
|
104
|
+
function resolveRequest() {
|
|
105
|
+
inflightGlossaryRequest = null;
|
|
106
|
+
service.loadingGlossary = false;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Now we have the glossary
|
|
111
|
+
const { data } = await inflightGlossaryRequest
|
|
112
|
+
|
|
113
|
+
// Cache it for later
|
|
114
|
+
glossaryCache.set('glossary', data);
|
|
115
|
+
cached = data;
|
|
116
|
+
qik.dispatch('glossary', data)
|
|
102
117
|
}
|
|
103
|
-
}
|
|
104
118
|
|
|
105
|
-
// Now we have the glossary
|
|
106
|
-
const { data } = await inflightGlossaryRequest;
|
|
107
119
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
}
|
|
120
|
+
if (options.hash) {
|
|
121
|
+
var result = qik.utils.hash(cached, 'key');
|
|
122
|
+
return result;
|
|
123
|
+
}
|
|
113
124
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
125
|
+
if (options.hex) {
|
|
126
|
+
var result = qik.utils.hash(cached, 'hex');
|
|
127
|
+
return result;
|
|
128
|
+
}
|
|
118
129
|
|
|
119
|
-
|
|
120
|
-
var result = qik.utils.hash(cached, "hex");
|
|
121
|
-
return result;
|
|
130
|
+
return cached;
|
|
122
131
|
}
|
|
123
132
|
|
|
124
|
-
return cached;
|
|
125
|
-
};
|
|
126
133
|
|
|
127
|
-
///////////////////////////////////////////////////
|
|
128
134
|
|
|
129
|
-
|
|
130
|
-
let inflightScopeGlossaryRequest;
|
|
135
|
+
///////////////////////////////////////////////////
|
|
131
136
|
|
|
132
|
-
|
|
133
|
-
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
const scopeGlossary = {}
|
|
140
|
+
|
|
141
|
+
let inflightScopeGlossaryRequest;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
*
|
|
134
145
|
* Retrieves the scope glossary of all scopes the user can know about. This helps to convert a scope id into a human readable title.
|
|
135
146
|
* @alias content.scopeGlossary
|
|
136
147
|
* @param {Object} options Additional options
|
|
@@ -139,701 +150,709 @@ export default function (qik) {
|
|
|
139
150
|
* @param {Boolean} options.reload Force the glossary to reload and not be cached.
|
|
140
151
|
If false will retrieve content type data from the in memory cache
|
|
141
152
|
* @example
|
|
142
|
-
*
|
|
153
|
+
*
|
|
143
154
|
* const scopes = await sdk.content.scopeGlossary();
|
|
144
155
|
*/
|
|
145
156
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
157
|
+
service.scopeGlossary = async function(options) {
|
|
158
|
+
options = options || {};
|
|
159
|
+
|
|
160
|
+
var reload = options.refresh || options.reload || !scopeGlossary.data;
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
if (reload) {
|
|
164
|
+
|
|
165
|
+
if(!inflightScopeGlossaryRequest) {
|
|
166
|
+
inflightScopeGlossaryRequest = qik.api.get(`/scope/glossary`, {cache:false});
|
|
167
|
+
inflightScopeGlossaryRequest.then(resolveRequest, resolveRequest);
|
|
168
|
+
function resolveRequest() {
|
|
169
|
+
inflightScopeGlossaryRequest = null;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const { data } = await inflightScopeGlossaryRequest
|
|
174
|
+
scopeGlossary.data = data;
|
|
161
175
|
}
|
|
162
|
-
}
|
|
163
176
|
|
|
164
|
-
|
|
177
|
+
if (options.hash) {
|
|
178
|
+
var result = qik.utils.hash(scopeGlossary.data, '_id');
|
|
179
|
+
return result;
|
|
180
|
+
}
|
|
165
181
|
|
|
166
|
-
|
|
167
|
-
scopeGlossaryCache.set("scopes", data);
|
|
168
|
-
cached = data;
|
|
169
|
-
qik.dispatch("glossary:scope", data);
|
|
182
|
+
return scopeGlossary.data;
|
|
170
183
|
}
|
|
171
184
|
|
|
172
|
-
if (options.hash) {
|
|
173
|
-
var result = qik.utils.hash(cached, "_id");
|
|
174
|
-
return result;
|
|
175
|
-
}
|
|
176
185
|
|
|
177
|
-
return cached;
|
|
178
|
-
};
|
|
179
186
|
|
|
180
|
-
///////////////////////////////////////////////////
|
|
181
187
|
|
|
182
|
-
|
|
183
|
-
*
|
|
184
|
-
* Retrieves all available filter comparators for each data type
|
|
185
|
-
* @alias content.comparators
|
|
186
|
-
* @param {Object} options Additional options
|
|
187
|
-
* @param {Boolean} options.reload Ignore any locally cached data
|
|
188
|
-
* @example
|
|
189
|
-
* const {hash, available, types} = await sdk.content.comparators();
|
|
190
|
-
* console.log(available) // {boolean:[{title:'Is equal to', operator:'equal'...}]}
|
|
191
|
-
* console.log(hash) // {equal:[{title:'Is equal to', operator:'equal'...}]}
|
|
192
|
-
*/
|
|
188
|
+
///////////////////////////////////////////////////
|
|
193
189
|
|
|
194
|
-
|
|
190
|
+
/**
|
|
191
|
+
*
|
|
192
|
+
* Retrieves all available filter comparators for each data type
|
|
193
|
+
* @alias content.comparators
|
|
194
|
+
* @param {Object} options Additional options
|
|
195
|
+
* @param {Boolean} options.reload Ignore any locally cached data
|
|
196
|
+
* @example
|
|
197
|
+
* const {hash, available, types} = await sdk.content.comparators();
|
|
198
|
+
* console.log(available) // {boolean:[{title:'Is equal to', operator:'equal'...}]}
|
|
199
|
+
* console.log(hash) // {equal:[{title:'Is equal to', operator:'equal'...}]}
|
|
200
|
+
*/
|
|
195
201
|
|
|
196
|
-
service.comparators = async function (options) {
|
|
197
|
-
options = options || {};
|
|
198
202
|
|
|
199
|
-
|
|
203
|
+
const comparators = {}
|
|
200
204
|
|
|
201
|
-
|
|
202
|
-
|
|
205
|
+
service.comparators = async function(options) {
|
|
206
|
+
options = options || {};
|
|
203
207
|
|
|
204
|
-
|
|
208
|
+
var reload = options.reload || options.refresh || !comparators.data;
|
|
205
209
|
|
|
206
|
-
|
|
210
|
+
if (reload) {
|
|
211
|
+
const { data } = await qik.api.get(`/system/comparators`);
|
|
207
212
|
|
|
208
|
-
Object.entries(data.types).forEach(([key, value]) => {
|
|
209
|
-
data.available[key] = value.map(function (comparatorKey) {
|
|
210
|
-
return data.hash[comparatorKey];
|
|
211
|
-
});
|
|
212
|
-
});
|
|
213
213
|
|
|
214
|
-
|
|
214
|
+
/////////////////////////////
|
|
215
215
|
|
|
216
|
-
|
|
217
|
-
}
|
|
216
|
+
data.available = {};
|
|
218
217
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
218
|
+
Object.entries(data.types).forEach(([key, value]) => {
|
|
219
|
+
data.available[key] = value.map(function(comparatorKey) {
|
|
220
|
+
return data.hash[comparatorKey];
|
|
221
|
+
})
|
|
222
|
+
});
|
|
223
223
|
|
|
224
|
-
return comparators.data;
|
|
225
|
-
};
|
|
226
224
|
|
|
227
|
-
|
|
225
|
+
/////////////////////////////
|
|
228
226
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
minimum = qik.utils.parseInt(minimum);
|
|
232
|
-
minimum = Math.max(minimum, 0);
|
|
227
|
+
comparators.data = data;
|
|
228
|
+
}
|
|
233
229
|
|
|
234
|
-
maximum = qik.utils.parseInt(maximum);
|
|
235
|
-
maximum = Math.max(maximum, 0); // cant be less than 0
|
|
236
|
-
if (maximum == 0) {
|
|
237
|
-
//Unlimited maximum
|
|
238
|
-
} else {
|
|
239
|
-
maximum = Math.max(maximum, minimum); // cant be less than the minimum
|
|
240
|
-
}
|
|
241
|
-
return { minimum, maximum };
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
service.meetsValidationRequirements = function (
|
|
245
|
-
input,
|
|
246
|
-
fieldType,
|
|
247
|
-
validationCriteria,
|
|
248
|
-
) {
|
|
249
|
-
if (validationCriteria.minLength) {
|
|
250
|
-
var stringLength = String(input).length;
|
|
251
|
-
if (stringLength < validationCriteria.minLength) {
|
|
252
|
-
return `Must be at least ${validationCriteria.minLength} characters`;
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
230
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return
|
|
260
|
-
|
|
231
|
+
|
|
232
|
+
// if (options.hash) {
|
|
233
|
+
// var result = qik.utils.hash(comparators.data, 'key');
|
|
234
|
+
// return result;
|
|
235
|
+
// }
|
|
236
|
+
|
|
237
|
+
return comparators.data;
|
|
261
238
|
}
|
|
262
239
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
240
|
+
///////////////////////////////////////////////////
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
function getLimits(fieldDefinition) {
|
|
244
|
+
|
|
245
|
+
var { minimum, maximum } = fieldDefinition;
|
|
246
|
+
minimum = qik.utils.parseInt(minimum);
|
|
247
|
+
minimum = Math.max(minimum, 0);
|
|
248
|
+
|
|
249
|
+
maximum = qik.utils.parseInt(maximum);
|
|
250
|
+
maximum = Math.max(maximum, 0); // cant be less than 0
|
|
251
|
+
if (maximum == 0) {
|
|
252
|
+
//Unlimited maximum
|
|
253
|
+
} else {
|
|
254
|
+
maximum = Math.max(maximum, minimum); // cant be less than the minimum
|
|
268
255
|
}
|
|
269
|
-
|
|
256
|
+
return { minimum, maximum };
|
|
270
257
|
}
|
|
271
258
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
service.meetsValidationRequirements = function(input, fieldType, validationCriteria) {
|
|
263
|
+
|
|
264
|
+
if (validationCriteria.minLength) {
|
|
265
|
+
var stringLength = String(input).length;
|
|
266
|
+
if (stringLength < validationCriteria.minLength) {
|
|
267
|
+
return `Must be at least ${validationCriteria.minLength} characters`;
|
|
268
|
+
|
|
269
|
+
}
|
|
277
270
|
}
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
};
|
|
281
|
-
|
|
282
|
-
/**
|
|
283
|
-
* Checks if a certain input validates against a field definition
|
|
284
|
-
* @alias content.validateField
|
|
285
|
-
* @param {Any} input The input to validate
|
|
286
|
-
* @param {Object} fieldDefinition The field to validate against
|
|
287
|
-
* @param {Object} options Additional options when calling the function
|
|
288
|
-
* @example
|
|
289
|
-
* const validationResult = await sdk.content.validateField('Johnny Bobbins', {title:'Name', key:'firstName', type:'string', minimum:1, maximum:1, ...});
|
|
290
|
-
* console.log(validationResult)
|
|
291
|
-
* // Results in { valid:true }
|
|
292
|
-
*
|
|
293
|
-
* const validationResult = await sdk.content.validateField('Johnny Bobbins', {title:'Number', key:'number', type:'integer', minimum:1, maximum:1, ...});
|
|
294
|
-
* console.log(validationResult)
|
|
295
|
-
* // Results in { valid:false, status:400, message:'Invalid number input for field' }
|
|
296
|
-
*/
|
|
297
|
-
|
|
298
|
-
service.validateField = function (input, fieldDefinition, options) {
|
|
299
|
-
options = options || {};
|
|
300
|
-
|
|
301
|
-
var fieldType = fieldDefinition.type || "string";
|
|
302
|
-
var { minimum, maximum } = getLimits(fieldDefinition);
|
|
303
|
-
|
|
304
|
-
var isObject = fieldDefinition.type == "group" && fieldDefinition.asObject;
|
|
305
|
-
var singleValue = isObject
|
|
306
|
-
? minimum === maximum && maximum === 1
|
|
307
|
-
: maximum === 1;
|
|
308
|
-
var multiValue = !singleValue;
|
|
309
|
-
|
|
310
|
-
//////////////////
|
|
311
|
-
|
|
312
|
-
var isNumeric;
|
|
313
|
-
switch (fieldType) {
|
|
314
|
-
case "integer":
|
|
315
|
-
case "decimal":
|
|
316
|
-
case "number":
|
|
317
|
-
case "float":
|
|
318
|
-
isNumeric = true;
|
|
319
|
-
break;
|
|
320
|
-
}
|
|
321
271
|
|
|
322
|
-
|
|
272
|
+
if (validationCriteria.maxLength) {
|
|
273
|
+
var stringLength = String(input).length;
|
|
274
|
+
if (stringLength > validationCriteria.maxLength) {
|
|
275
|
+
return `Can be no more than ${validationCriteria.maxLength} characters`;
|
|
323
276
|
|
|
324
|
-
|
|
277
|
+
}
|
|
278
|
+
}
|
|
325
279
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
280
|
+
if (validationCriteria.minValue) {
|
|
281
|
+
if(input !== undefined) {
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
var number = Number(input);
|
|
285
|
+
if (number < validationCriteria.minValue) {
|
|
286
|
+
return `Must be at least ${validationCriteria.minValue}`;
|
|
287
|
+
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
if (validationCriteria.maxValue) {
|
|
293
|
+
if(input !== undefined) {
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
var number = Number(input);
|
|
297
|
+
if (number > validationCriteria.maxValue) {
|
|
298
|
+
return `Can be no greater than ${validationCriteria.maxValue}`;
|
|
299
|
+
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
344
303
|
}
|
|
345
304
|
|
|
346
|
-
|
|
305
|
+
/**
|
|
306
|
+
* Checks if a certain input validates against a field definition
|
|
307
|
+
* @alias content.validateField
|
|
308
|
+
* @param {Any} input The input to validate
|
|
309
|
+
* @param {Object} fieldDefinition The field to validate against
|
|
310
|
+
* @param {Object} options Additional options when calling the function
|
|
311
|
+
* @example
|
|
312
|
+
* const validationResult = await sdk.content.validateField('Johnny Bobbins', {title:'Name', key:'firstName', type:'string', minimum:1, maximum:1, ...});
|
|
313
|
+
* console.log(validationResult)
|
|
314
|
+
* // Results in { valid:true }
|
|
315
|
+
*
|
|
316
|
+
* const validationResult = await sdk.content.validateField('Johnny Bobbins', {title:'Number', key:'number', type:'integer', minimum:1, maximum:1, ...});
|
|
317
|
+
* console.log(validationResult)
|
|
318
|
+
* // Results in { valid:false, status:400, message:'Invalid number input for field' }
|
|
319
|
+
*/
|
|
320
|
+
|
|
321
|
+
service.validateField = function(input, fieldDefinition, options) {
|
|
322
|
+
options = options || {}
|
|
323
|
+
|
|
324
|
+
var fieldType = fieldDefinition.type || 'string';
|
|
325
|
+
var { minimum, maximum } = getLimits(fieldDefinition);
|
|
326
|
+
|
|
327
|
+
var isObject = (fieldDefinition.type == 'group' && fieldDefinition.asObject);
|
|
328
|
+
var singleValue = isObject ? minimum === maximum && maximum === 1 : maximum === 1;
|
|
329
|
+
var multiValue = !singleValue;
|
|
330
|
+
|
|
331
|
+
//////////////////
|
|
332
|
+
|
|
333
|
+
var isNumeric;
|
|
334
|
+
switch (fieldType) {
|
|
335
|
+
case 'integer':
|
|
336
|
+
case 'decimal':
|
|
337
|
+
case 'number':
|
|
338
|
+
case 'float':
|
|
339
|
+
isNumeric = true;
|
|
340
|
+
break;
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
//////////////////
|
|
344
|
+
|
|
345
|
+
var inputWasProvided = qik.utils.exists(input);
|
|
347
346
|
|
|
348
|
-
|
|
349
|
-
if (multiValue) {
|
|
350
|
-
//But the input is not an array
|
|
351
|
-
if (!Array.isArray(input)) {
|
|
347
|
+
//If an answer is required
|
|
352
348
|
if (minimum) {
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
349
|
+
//but none was provided
|
|
350
|
+
if (!inputWasProvided) {
|
|
351
|
+
//Throw an error
|
|
352
|
+
return {
|
|
353
|
+
valid: false,
|
|
354
|
+
message: `${fieldDefinition.title} is a required field`,
|
|
355
|
+
status: 400,
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
358
|
} else {
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
359
|
+
//No answer is needed and none was provided
|
|
360
|
+
if (!inputWasProvided) {
|
|
361
|
+
return {
|
|
362
|
+
valid: true,
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
365
|
}
|
|
366
|
-
}
|
|
367
366
|
|
|
368
|
-
|
|
367
|
+
//////////////////
|
|
369
368
|
|
|
370
|
-
var compacted = input;
|
|
371
369
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
var empty = v === undefined || v === null || v === "";
|
|
375
|
-
return !empty;
|
|
376
|
-
});
|
|
370
|
+
//If we are requiring multiple values
|
|
371
|
+
if (multiValue) {
|
|
377
372
|
|
|
378
|
-
|
|
373
|
+
//But the input is not an array
|
|
374
|
+
if (!Array.isArray(input)) {
|
|
379
375
|
|
|
380
|
-
|
|
376
|
+
if (minimum) {
|
|
377
|
+
return {
|
|
378
|
+
valid: false,
|
|
379
|
+
message: `${fieldDefinition.title} requires at least ${minimum} values`,
|
|
380
|
+
status: 400,
|
|
381
|
+
}
|
|
382
|
+
} else {
|
|
381
383
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
};
|
|
391
|
-
}
|
|
392
|
-
}
|
|
384
|
+
console.log('NOT PROVIDED AS ARRAY', fieldDefinition.title, input)
|
|
385
|
+
return {
|
|
386
|
+
valid: false,
|
|
387
|
+
message: `${fieldDefinition.title} must be provided as an array`,
|
|
388
|
+
status: 400,
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
393
392
|
|
|
394
|
-
//We have too many answers
|
|
395
|
-
if (maximum && compacted.length > maximum) {
|
|
396
|
-
return {
|
|
397
|
-
valid: false,
|
|
398
|
-
message: `${fieldDefinition.title} requires less than ${maximum + 1} values`,
|
|
399
|
-
status: 400,
|
|
400
|
-
};
|
|
401
|
-
}
|
|
402
393
|
|
|
403
|
-
//We don't have enough answers
|
|
404
|
-
if (compacted.length < minimum) {
|
|
405
|
-
// console.log(fieldDefinition.title, 'INPUT', input.length, minimum, input, compacted)
|
|
406
394
|
|
|
407
|
-
|
|
408
|
-
valid: false,
|
|
409
|
-
message: `${fieldDefinition.title} requires at least ${minimum} values`,
|
|
410
|
-
status: 400,
|
|
411
|
-
};
|
|
412
|
-
}
|
|
395
|
+
////////////////////////////
|
|
413
396
|
|
|
414
|
-
|
|
397
|
+
var compacted = input;
|
|
415
398
|
|
|
416
|
-
|
|
399
|
+
compacted = compacted.filter(function(v) {
|
|
400
|
+
//Check if we care about this value
|
|
401
|
+
var empty = v === undefined || v === null || v === '';
|
|
402
|
+
return !empty;
|
|
403
|
+
})
|
|
417
404
|
|
|
418
|
-
//Find any bad values
|
|
419
|
-
var badEntry = compacted.find(function (val) {
|
|
420
|
-
var valueFieldType = fieldType;
|
|
421
405
|
|
|
422
|
-
|
|
423
|
-
valueFieldType = "object";
|
|
424
|
-
}
|
|
406
|
+
// console.log('COMPACTED', input.length, compacted.length);
|
|
425
407
|
|
|
426
|
-
|
|
427
|
-
fieldDefinition.type === "reference" &&
|
|
428
|
-
fieldDefinition.widget === "form"
|
|
429
|
-
) {
|
|
430
|
-
valueFieldType = "object";
|
|
431
|
-
}
|
|
408
|
+
////////////////////////////
|
|
432
409
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
valueFieldType,
|
|
436
|
-
options.strict,
|
|
437
|
-
);
|
|
410
|
+
//We need an exact number of answers
|
|
411
|
+
if (minimum == maximum) {
|
|
438
412
|
|
|
439
|
-
|
|
413
|
+
//But we don't have the number of answers needed
|
|
414
|
+
if (minimum && (compacted.length != minimum)) {
|
|
415
|
+
return {
|
|
416
|
+
valid: false,
|
|
417
|
+
message: `${fieldDefinition.title} requires exactly ${maximum} values`,
|
|
418
|
+
status: 400,
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
440
422
|
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
423
|
+
//We have too many answers
|
|
424
|
+
if (maximum && (compacted.length > maximum)) {
|
|
425
|
+
|
|
426
|
+
return {
|
|
427
|
+
valid: false,
|
|
428
|
+
message: `${fieldDefinition.title} requires less than ${maximum+1} values`,
|
|
429
|
+
status: 400,
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
//We don't have enough answers
|
|
434
|
+
if (compacted.length < minimum) {
|
|
445
435
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
436
|
+
// console.log(fieldDefinition.title, 'INPUT', input.length, minimum, input, compacted)
|
|
437
|
+
|
|
438
|
+
return {
|
|
439
|
+
valid: false,
|
|
440
|
+
message: `${fieldDefinition.title} requires at least ${minimum} values`,
|
|
441
|
+
status: 400,
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
////////////////////////////
|
|
446
|
+
|
|
447
|
+
var foundBadEntry;
|
|
448
|
+
|
|
449
|
+
//Find any bad values
|
|
450
|
+
var badEntry = compacted.find(function(val) {
|
|
451
|
+
var valueFieldType = fieldType;
|
|
452
|
+
|
|
453
|
+
if (fieldDefinition.type === 'group') {
|
|
454
|
+
valueFieldType = 'object';
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
if (fieldDefinition.type === 'reference' && fieldDefinition.widget === 'form') {
|
|
458
|
+
valueFieldType = 'object';
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
var isValid = qik.utils.isValidValue(val, valueFieldType, options.strict);
|
|
462
|
+
|
|
463
|
+
////////////////////////////
|
|
464
|
+
|
|
465
|
+
if (!isValid) {
|
|
466
|
+
foundBadEntry = true;
|
|
467
|
+
return true;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
////////////////////////////
|
|
471
|
+
|
|
472
|
+
//Is there additional validation requirements
|
|
473
|
+
if (fieldDefinition.validation) {
|
|
474
|
+
var additionalValidationErrors = service.meetsValidationRequirements(val, fieldType, fieldDefinition.validation)
|
|
475
|
+
if (additionalValidationErrors) {
|
|
476
|
+
foundBadEntry = true;
|
|
477
|
+
return true;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
})
|
|
481
|
+
|
|
482
|
+
if (foundBadEntry) {
|
|
483
|
+
let badValueMessage = `Invalid input for ${fieldDefinition.title}`;
|
|
484
|
+
return {
|
|
485
|
+
valid: false,
|
|
486
|
+
message: badValueMessage,
|
|
487
|
+
status: 400,
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
} else {
|
|
492
|
+
|
|
493
|
+
var dataType = fieldType;
|
|
494
|
+
var widgetType = fieldDefinition.widget;
|
|
495
|
+
if (dataType === 'group') {
|
|
496
|
+
dataType = 'object';
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
if (dataType === 'reference' && widgetType === 'form') {
|
|
500
|
+
dataType = 'object';
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
|
|
504
|
+
//////////////////
|
|
505
|
+
|
|
506
|
+
var cleanedValue = service.getCleanedValue(input, dataType, options);
|
|
507
|
+
|
|
508
|
+
|
|
509
|
+
//////////////////
|
|
510
|
+
|
|
511
|
+
var isValidValue = qik.utils.isValidValue(cleanedValue, dataType, options.strict);
|
|
512
|
+
|
|
513
|
+
//////////////////
|
|
514
|
+
|
|
515
|
+
//Invalid input
|
|
516
|
+
if (!isValidValue) {
|
|
517
|
+
return {
|
|
518
|
+
valid: false,
|
|
519
|
+
message: `Single value '${input}' is not a valid ${dataType} for ${fieldDefinition.title}`,
|
|
520
|
+
criteria: {
|
|
521
|
+
isValidValue,
|
|
522
|
+
cleanedValue,
|
|
523
|
+
fieldType,
|
|
524
|
+
options,
|
|
525
|
+
},
|
|
526
|
+
status: 400,
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
//Is there additional validation requirements
|
|
531
|
+
let hasAdditionalValidation = false;
|
|
532
|
+
|
|
533
|
+
const validation = {}
|
|
534
|
+
if(String(fieldDefinition.minValue)) { validation.minValue = parseInt(fieldDefinition.minValue); hasAdditionalValidation = true }
|
|
535
|
+
if(String(fieldDefinition.maxValue)) { validation.maxValue = parseInt(fieldDefinition.maxValue); hasAdditionalValidation = true }
|
|
536
|
+
if(String(fieldDefinition.minLength)) { validation.minLength = parseInt(fieldDefinition.minLength); hasAdditionalValidation = true }
|
|
537
|
+
if(String(fieldDefinition.maxLength)) { validation.maxLength = parseInt(fieldDefinition.maxLength); hasAdditionalValidation = true }
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
if (hasAdditionalValidation) {
|
|
541
|
+
const validationCriteria = Object.assign({}, validation, fieldDefinition.validation || {});
|
|
542
|
+
var additionalValidationError = service.meetsValidationRequirements(input, fieldType, validationCriteria)
|
|
543
|
+
if (additionalValidationError) {
|
|
544
|
+
return {
|
|
545
|
+
valid: false,
|
|
546
|
+
message: additionalValidationError,
|
|
547
|
+
status: 400,
|
|
548
|
+
};
|
|
549
|
+
}
|
|
550
|
+
}
|
|
459
551
|
}
|
|
460
|
-
});
|
|
461
552
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
return {
|
|
465
|
-
valid: false,
|
|
466
|
-
message: badValueMessage,
|
|
467
|
-
status: 400,
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
|
-
} else {
|
|
471
|
-
var dataType = fieldType;
|
|
472
|
-
var widgetType = fieldDefinition.widget;
|
|
473
|
-
if (dataType === "group") {
|
|
474
|
-
dataType = "object";
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
if (dataType === "reference" && widgetType === "form") {
|
|
478
|
-
dataType = "object";
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
//////////////////
|
|
482
|
-
|
|
483
|
-
var cleanedValue = service.getCleanedValue(input, dataType, options);
|
|
484
|
-
|
|
485
|
-
//////////////////
|
|
486
|
-
|
|
487
|
-
var isValidValue = qik.utils.isValidValue(
|
|
488
|
-
cleanedValue,
|
|
489
|
-
dataType,
|
|
490
|
-
options.strict,
|
|
491
|
-
);
|
|
492
|
-
|
|
493
|
-
//////////////////
|
|
494
|
-
|
|
495
|
-
//Invalid input
|
|
496
|
-
if (!isValidValue) {
|
|
553
|
+
//////////////////
|
|
554
|
+
|
|
497
555
|
return {
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
);
|
|
537
|
-
var additionalValidationError = service.meetsValidationRequirements(
|
|
538
|
-
input,
|
|
539
|
-
fieldType,
|
|
540
|
-
validationCriteria,
|
|
541
|
-
);
|
|
542
|
-
if (additionalValidationError) {
|
|
543
|
-
return {
|
|
544
|
-
valid: false,
|
|
545
|
-
message: additionalValidationError,
|
|
546
|
-
status: 400,
|
|
547
|
-
};
|
|
556
|
+
valid: true,
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
service.getCleanedValue = function(input, dataType, options) {
|
|
562
|
+
switch (dataType) {
|
|
563
|
+
case 'number':
|
|
564
|
+
case 'float':
|
|
565
|
+
case 'decimal':
|
|
566
|
+
if (!qik.utils.exists(input)) {
|
|
567
|
+
return undefined;
|
|
568
|
+
} else {
|
|
569
|
+
return Number(input);
|
|
570
|
+
}
|
|
571
|
+
break;
|
|
572
|
+
case 'integer':
|
|
573
|
+
if (!qik.utils.exists(input)) {
|
|
574
|
+
return undefined;
|
|
575
|
+
} else {
|
|
576
|
+
return parseInt(input);
|
|
577
|
+
}
|
|
578
|
+
break;
|
|
579
|
+
case 'boolean':
|
|
580
|
+
if (!qik.utils.exists(input)) {
|
|
581
|
+
return undefined;
|
|
582
|
+
}
|
|
583
|
+
return qik.utils.parseBoolean(input);
|
|
584
|
+
break;
|
|
585
|
+
case 'email':
|
|
586
|
+
return options.strict ? input : String(input).toLowerCase();
|
|
587
|
+
break;
|
|
588
|
+
case 'reference':
|
|
589
|
+
return options.strict ? input : qik.utils.id(input);
|
|
590
|
+
break;
|
|
591
|
+
default:
|
|
592
|
+
return options.strict ? input : qik.utils.cleanValue(input, dataType, options);
|
|
593
|
+
break
|
|
548
594
|
}
|
|
549
|
-
|
|
595
|
+
|
|
596
|
+
return input;
|
|
550
597
|
}
|
|
551
598
|
|
|
552
|
-
|
|
599
|
+
///////////////////////////////////////////////////
|
|
600
|
+
|
|
601
|
+
/**
|
|
602
|
+
*
|
|
603
|
+
* Retrieves a list of records matching the provided criteria
|
|
604
|
+
* @alias content.list
|
|
605
|
+
* @param {String} type The type or definition of records we want to retrieve
|
|
606
|
+
* @param {Object} options The options for our query
|
|
607
|
+
* @param {String} options.search Freeform text keywords
|
|
608
|
+
* @param {Object} options.sort How to sort the results
|
|
609
|
+
* @param {String} options.sort.key Which key to sort on
|
|
610
|
+
* @param {String} options.sort.direction Which direction to sort on
|
|
611
|
+
* @param {Object} options.sort.type What type of data is being sorted
|
|
612
|
+
* @param {Object} options.page Page configuration
|
|
613
|
+
* @param {Number} options.page.size Page size
|
|
614
|
+
* @param {Number} options.page.index Page index
|
|
615
|
+
* @param {Object} options.filter How to filter the results
|
|
616
|
+
* @example
|
|
617
|
+
*
|
|
618
|
+
*
|
|
619
|
+
* sdk.content.list('profile', {
|
|
620
|
+
* search:'Jim',
|
|
621
|
+
* page:{
|
|
622
|
+
* size:50,
|
|
623
|
+
* index:2,
|
|
624
|
+
* },
|
|
625
|
+
* sort:{
|
|
626
|
+
* key:'age',
|
|
627
|
+
* direction:'asc',
|
|
628
|
+
* type:'integer',
|
|
629
|
+
* },
|
|
630
|
+
* filter:{
|
|
631
|
+
* operator:'and',
|
|
632
|
+
* filters:[{
|
|
633
|
+
* key:'age',
|
|
634
|
+
* comparator:'>',
|
|
635
|
+
* value:5,
|
|
636
|
+
* }],
|
|
637
|
+
* },
|
|
638
|
+
* })
|
|
639
|
+
*/
|
|
553
640
|
|
|
554
|
-
|
|
555
|
-
valid: true,
|
|
556
|
-
};
|
|
557
|
-
};
|
|
641
|
+
service.list = async function(type, options, advanced) {
|
|
558
642
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
if (!qik.utils.exists(input)) {
|
|
565
|
-
return undefined;
|
|
566
|
-
} else {
|
|
567
|
-
return Number(input);
|
|
643
|
+
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
if (!advanced) {
|
|
647
|
+
advanced = {};
|
|
568
648
|
}
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
649
|
+
|
|
650
|
+
const remoteURL = advanced.remoteURL || `/content/${type}/list`;
|
|
651
|
+
|
|
652
|
+
if (advanced.cancellable) {
|
|
653
|
+
|
|
654
|
+
if (!advanced.config) {
|
|
655
|
+
advanced.config = {}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
//Create a cancel token
|
|
659
|
+
const CancelToken = qik.api.CancelToken;
|
|
660
|
+
const source = CancelToken.source();
|
|
661
|
+
advanced.config.cancelToken = source.token;
|
|
662
|
+
|
|
663
|
+
|
|
664
|
+
const promise = qik.api.post(remoteURL, options, advanced.config);
|
|
665
|
+
return {
|
|
666
|
+
promise,
|
|
667
|
+
cancel(message) {
|
|
668
|
+
source.cancel(message || 'Operation canceled by the user.');
|
|
669
|
+
},
|
|
670
|
+
}
|
|
671
|
+
|
|
573
672
|
} else {
|
|
574
|
-
|
|
673
|
+
const { data } = await qik.api.post(remoteURL, options, advanced.config);
|
|
674
|
+
return data;
|
|
575
675
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
676
|
+
|
|
677
|
+
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
///////////////////////////////////////////////////
|
|
684
|
+
|
|
685
|
+
/**
|
|
686
|
+
*
|
|
687
|
+
* Create an item
|
|
688
|
+
* @alias content.create
|
|
689
|
+
* @param {String} type The type or definition of the record we want to create
|
|
690
|
+
* @param {Object} input The data for our new record
|
|
691
|
+
* @example
|
|
692
|
+
*
|
|
693
|
+
*
|
|
694
|
+
* const result = await sdk.content.create('profile', {
|
|
695
|
+
* firstName:'Mickey',
|
|
696
|
+
* lastName:'Mouse',
|
|
697
|
+
* gender:'male',
|
|
698
|
+
* meta:{
|
|
699
|
+
* scopes:['61eca4746971e75c1fc670cf'],
|
|
700
|
+
* }
|
|
701
|
+
* })
|
|
702
|
+
*/
|
|
703
|
+
|
|
704
|
+
service.create = async function(type, input) {
|
|
705
|
+
|
|
706
|
+
const dataModel = {...input};
|
|
707
|
+
|
|
708
|
+
// Sanitize down to just ids before we send
|
|
709
|
+
if(dataModel.meta?.scopes) {
|
|
710
|
+
dataModel.meta.scopes = qik.utils.ids(dataModel.meta.scopes);
|
|
580
711
|
}
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
return
|
|
585
|
-
break;
|
|
586
|
-
case "reference":
|
|
587
|
-
return options.strict ? input : qik.utils.id(input);
|
|
588
|
-
break;
|
|
589
|
-
default:
|
|
590
|
-
return options.strict
|
|
591
|
-
? input
|
|
592
|
-
: qik.utils.cleanValue(input, dataType, options);
|
|
593
|
-
break;
|
|
712
|
+
|
|
713
|
+
|
|
714
|
+
const { data } = await qik.api.post(`/content/${type}/create`, dataModel);
|
|
715
|
+
return data;
|
|
594
716
|
}
|
|
595
717
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
* key:'age',
|
|
627
|
-
* direction:'asc',
|
|
628
|
-
* type:'integer',
|
|
629
|
-
* },
|
|
630
|
-
* filter:{
|
|
631
|
-
* operator:'and',
|
|
632
|
-
* filters:[{
|
|
633
|
-
* key:'age',
|
|
634
|
-
* comparator:'>',
|
|
635
|
-
* value:5,
|
|
636
|
-
* }],
|
|
637
|
-
* },
|
|
638
|
-
* })
|
|
639
|
-
*/
|
|
640
|
-
|
|
641
|
-
service.list = async function (type, options, advanced) {
|
|
642
|
-
if (!advanced) {
|
|
643
|
-
advanced = {};
|
|
718
|
+
/**
|
|
719
|
+
*
|
|
720
|
+
* Update an item, Only fields the user has permission to view will be returned
|
|
721
|
+
* @alias content.update
|
|
722
|
+
* @param {String} id The id of the record we want to update
|
|
723
|
+
* @param {Object} input The data to update
|
|
724
|
+
* @example
|
|
725
|
+
*
|
|
726
|
+
* const result = await sdk.content.update('61eca4746971e75c1fc670cd', {
|
|
727
|
+
* firstName:'Minnie',
|
|
728
|
+
* lastName:'Mouse',
|
|
729
|
+
* gender:'female',
|
|
730
|
+
* meta:{
|
|
731
|
+
* scopes:['61eca4746971e75c1fc670cd'],
|
|
732
|
+
* }
|
|
733
|
+
* })
|
|
734
|
+
*/
|
|
735
|
+
service.update = async function(id, input) {
|
|
736
|
+
id = qik.utils.id(id);
|
|
737
|
+
|
|
738
|
+
const dataModel = {...input};
|
|
739
|
+
|
|
740
|
+
// Sanitize down to just ids before we send
|
|
741
|
+
if(dataModel.meta?.scopes) {
|
|
742
|
+
dataModel.meta.scopes = qik.utils.ids(dataModel.meta.scopes);
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
|
|
746
|
+
const { data } = await qik.api.put(`/content/${id}`, dataModel);
|
|
747
|
+
return data;
|
|
644
748
|
}
|
|
645
749
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
750
|
+
/**
|
|
751
|
+
*
|
|
752
|
+
* Partially update and patch an item, Only fields the user has permission to edit will be updated
|
|
753
|
+
* @alias content.patch
|
|
754
|
+
* @param {String} id The id of the record we want to update
|
|
755
|
+
* @param {Object} input The data to update, this will be merged with existing data
|
|
756
|
+
* @example
|
|
757
|
+
*
|
|
758
|
+
* const result = await sdk.content.patch('61eca4746971e75c1fc670cd', {
|
|
759
|
+
* firstName:'Mickey',
|
|
760
|
+
* gender:'male',
|
|
761
|
+
* })
|
|
762
|
+
*/
|
|
763
|
+
service.patch = async function(id, input) {
|
|
764
|
+
id = qik.utils.id(id);
|
|
765
|
+
|
|
766
|
+
const dataModel = {...input};
|
|
767
|
+
|
|
768
|
+
// Sanitize down to just ids before we send
|
|
769
|
+
if(dataModel.meta?.scopes) {
|
|
770
|
+
dataModel.meta.scopes = qik.utils.ids(dataModel.meta.scopes);
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
|
|
774
|
+
const { data } = await qik.api.patch(`/content/${id}`, dataModel);
|
|
775
|
+
return data;
|
|
668
776
|
}
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
* gender:'male',
|
|
686
|
-
* meta:{
|
|
687
|
-
* scopes:['61eca4746971e75c1fc670cf'],
|
|
688
|
-
* }
|
|
689
|
-
* })
|
|
690
|
-
*/
|
|
691
|
-
|
|
692
|
-
service.create = async function (type, input) {
|
|
693
|
-
const dataModel = { ...input };
|
|
694
|
-
|
|
695
|
-
// Sanitize down to just ids before we send
|
|
696
|
-
if (dataModel.meta?.scopes) {
|
|
697
|
-
dataModel.meta.scopes = qik.utils.ids(dataModel.meta.scopes);
|
|
777
|
+
|
|
778
|
+
/**
|
|
779
|
+
*
|
|
780
|
+
* Get an item from the database, Only fields the user has permission to view will be returned
|
|
781
|
+
* @alias content.get
|
|
782
|
+
* @param {String} id The id of the record we want to update
|
|
783
|
+
* @example
|
|
784
|
+
*
|
|
785
|
+
* const result = await sdk.content.get('61eca4746971e75c1fc670cd')
|
|
786
|
+
*/
|
|
787
|
+
service.get = async function(id, params) {
|
|
788
|
+
id = qik.utils.id(id);
|
|
789
|
+
params = params || {}
|
|
790
|
+
|
|
791
|
+
const { data } = await qik.api.get(`/content/${id}`, params);
|
|
792
|
+
return data;
|
|
698
793
|
}
|
|
699
794
|
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
* meta:{
|
|
717
|
-
* scopes:['61eca4746971e75c1fc670cd'],
|
|
718
|
-
* }
|
|
719
|
-
* })
|
|
720
|
-
*/
|
|
721
|
-
service.update = async function (id, input) {
|
|
722
|
-
id = qik.utils.id(id);
|
|
723
|
-
|
|
724
|
-
const dataModel = { ...input };
|
|
725
|
-
|
|
726
|
-
// Sanitize down to just ids before we send
|
|
727
|
-
if (dataModel.meta?.scopes) {
|
|
728
|
-
dataModel.meta.scopes = qik.utils.ids(dataModel.meta.scopes);
|
|
795
|
+
service.getFromID = async function(id) {
|
|
796
|
+
return service.get(id);
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
*
|
|
801
|
+
* Delete an item from the database
|
|
802
|
+
* @alias content.delete
|
|
803
|
+
* @param {String} id The id of the record we want to delete
|
|
804
|
+
* @example
|
|
805
|
+
* const result = await sdk.content.delete('61eca4746971e75c1fc670cd')
|
|
806
|
+
*/
|
|
807
|
+
service.delete = async function(id, input) {
|
|
808
|
+
id = qik.utils.id(id);
|
|
809
|
+
const { data } = await qik.api.delete(`/content/${id}`, input);
|
|
810
|
+
return data;
|
|
729
811
|
}
|
|
730
812
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
* const result = await sdk.content.patch('61eca4746971e75c1fc670cd', {
|
|
744
|
-
* firstName:'Mickey',
|
|
745
|
-
* gender:'male',
|
|
746
|
-
* })
|
|
747
|
-
*/
|
|
748
|
-
service.patch = async function (id, input) {
|
|
749
|
-
id = qik.utils.id(id);
|
|
750
|
-
|
|
751
|
-
const dataModel = { ...input };
|
|
752
|
-
|
|
753
|
-
// Sanitize down to just ids before we send
|
|
754
|
-
if (dataModel.meta?.scopes) {
|
|
755
|
-
dataModel.meta.scopes = qik.utils.ids(dataModel.meta.scopes);
|
|
813
|
+
/**
|
|
814
|
+
*
|
|
815
|
+
* Restore a deleted item from the database
|
|
816
|
+
* @alias content.restore
|
|
817
|
+
* @param {String} id The id of the record we want to restore
|
|
818
|
+
* @example
|
|
819
|
+
* const result = await sdk.content.restore('61eca4746971e75c1fc670cd')
|
|
820
|
+
*/
|
|
821
|
+
service.restore = async function(id, input) {
|
|
822
|
+
id = qik.utils.id(id);
|
|
823
|
+
const { data } = await qik.api.get(`/content/${id}/restore`, input);
|
|
824
|
+
return data;
|
|
756
825
|
}
|
|
757
826
|
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
*/
|
|
791
|
-
service.delete = async function (id, input) {
|
|
792
|
-
id = qik.utils.id(id);
|
|
793
|
-
const { data } = await qik.api.delete(`/content/${id}`, input);
|
|
794
|
-
return data;
|
|
795
|
-
};
|
|
796
|
-
|
|
797
|
-
/**
|
|
798
|
-
*
|
|
799
|
-
* Restore a deleted item from the database
|
|
800
|
-
* @alias content.restore
|
|
801
|
-
* @param {String} id The id of the record we want to restore
|
|
802
|
-
* @example
|
|
803
|
-
* const result = await sdk.content.restore('61eca4746971e75c1fc670cd')
|
|
804
|
-
*/
|
|
805
|
-
service.restore = async function (id, input) {
|
|
806
|
-
id = qik.utils.id(id);
|
|
807
|
-
const { data } = await qik.api.get(`/content/${id}/restore`, input);
|
|
808
|
-
return data;
|
|
809
|
-
};
|
|
810
|
-
|
|
811
|
-
/**
|
|
812
|
-
*
|
|
813
|
-
* Retrieve an item from the database by providing it's 'slug'
|
|
814
|
-
* @alias content.getFromSlug
|
|
815
|
-
* @param {String} slug The slug id of the record we want to retrieve
|
|
816
|
-
* it must be provided as either `(type):(slug)`` or `(definition):(slug)`
|
|
817
|
-
* (if unsure use the `meta.abs` absolute slug property of the item you are wanting to retrieve).
|
|
818
|
-
* @example
|
|
819
|
-
* const result = await sdk.content.getFromSlug('article:how-to-get-started')
|
|
820
|
-
* const result = await sdk.content.getFromSlug('car:toyota-landcruiser')
|
|
821
|
-
* const result = await sdk.content.getFromSlug('article:toyota-landcruiser')
|
|
822
|
-
*/
|
|
823
|
-
service.getFromSlug = async function (slug) {
|
|
824
|
-
const { data } = await qik.api.get(`/content/slug/${slug}`);
|
|
825
|
-
return data;
|
|
826
|
-
};
|
|
827
|
-
|
|
828
|
-
// service.getFromSlug = async function(type, slug) {
|
|
829
|
-
// const { data } = await qik.api.get(`/content/${type}/slug/${slug}`);
|
|
830
|
-
// return data;
|
|
831
|
-
// }
|
|
832
|
-
|
|
833
|
-
// service.getFromExternalID = async function(type, externalID) {
|
|
834
|
-
// const { data } = await qik.api.get(`/content/${type}/external/${externalID}`);
|
|
835
|
-
// return data;
|
|
836
|
-
// }
|
|
837
|
-
|
|
838
|
-
return service;
|
|
839
|
-
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
*
|
|
830
|
+
* Retrieve an item from the database by providing it's 'slug'
|
|
831
|
+
* @alias content.getFromSlug
|
|
832
|
+
* @param {String} slug The slug id of the record we want to retrieve
|
|
833
|
+
* it must be provided as either `(type):(slug)`` or `(definition):(slug)`
|
|
834
|
+
* (if unsure use the `meta.abs` absolute slug property of the item you are wanting to retrieve).
|
|
835
|
+
* @example
|
|
836
|
+
* const result = await sdk.content.getFromSlug('article:how-to-get-started')
|
|
837
|
+
* const result = await sdk.content.getFromSlug('car:toyota-landcruiser')
|
|
838
|
+
* const result = await sdk.content.getFromSlug('article:toyota-landcruiser')
|
|
839
|
+
*/
|
|
840
|
+
service.getFromSlug = async function(slug) {
|
|
841
|
+
const { data } = await qik.api.get(`/content/slug/${slug}`);
|
|
842
|
+
return data;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// service.getFromSlug = async function(type, slug) {
|
|
846
|
+
// const { data } = await qik.api.get(`/content/${type}/slug/${slug}`);
|
|
847
|
+
// return data;
|
|
848
|
+
// }
|
|
849
|
+
|
|
850
|
+
// service.getFromExternalID = async function(type, externalID) {
|
|
851
|
+
// const { data } = await qik.api.get(`/content/${type}/external/${externalID}`);
|
|
852
|
+
// return data;
|
|
853
|
+
// }
|
|
854
|
+
|
|
855
|
+
|
|
856
|
+
return service;
|
|
857
|
+
|
|
858
|
+
}
|