@qikdev/sdk 1.0.2 → 1.0.5
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/README.md +1 -1
- package/dist/{docs/access.html → access.html} +353 -20
- package/dist/api.html +444 -0
- package/dist/{docs/auth.html → auth.html} +14 -14
- package/dist/cache.html +351 -0
- package/dist/{docs/content.html → content.html} +46 -21
- package/dist/{docs/files.html → files.html} +147 -6
- package/dist/{docs/filter.html → filter.html} +9 -9
- package/dist/geo.html +1029 -0
- package/dist/global.html +240 -0
- package/dist/index.html +96 -0
- package/dist/main.js +2 -3
- package/dist/module-QikStorage-CookieStorageAdapter.html +407 -0
- package/dist/module-QikStorage-LocalStorageAdapter.html +193 -0
- package/dist/module-QikStorage-StorageAdapter.html +977 -0
- package/dist/module-QikStorage.html +433 -0
- package/dist/qik.access.js.html +904 -0
- package/dist/qik.api.js.html +409 -0
- package/dist/{docs/qik.auth.js.html → qik.auth.js.html} +142 -104
- package/dist/qik.cache.js.html +125 -0
- package/dist/qik.content.js.html +967 -0
- package/dist/qik.core.js.html +322 -0
- package/dist/qik.files.js.html +249 -0
- package/dist/{docs/qik.filter.js.html → qik.filter.js.html} +3 -3
- package/dist/qik.geo.js.html +963 -0
- package/dist/{docs/qik.socket.js.html → qik.socket.js.html} +53 -12
- package/dist/qik.storage.js.html +375 -0
- package/dist/qik.system.js.html +117 -0
- package/dist/qik.utils.js.html +1548 -0
- package/dist/{docs/socket.html → socket.html} +7 -7
- package/dist/{docs/styles → styles}/jsdoc.css +2 -2
- package/dist/system.html +197 -0
- package/dist/utils.html +4422 -0
- package/package.json +2 -2
- package/src/api/qik.filter.js +1 -1
- package/src/api/qik.geo.js +1 -1
- package/src/api/qik.socket.js +18 -12
- package/src/api/qik.utils.js +6 -0
- package/src/version.js +1 -1
- package/dist/docs/api.html +0 -1356
- package/dist/docs/cache.html +0 -351
- package/dist/docs/index.html +0 -96
- package/dist/docs/qik.access.js.html +0 -790
- package/dist/docs/qik.api.js.html +0 -511
- package/dist/docs/qik.cache.js.html +0 -131
- package/dist/docs/qik.content.js.html +0 -918
- package/dist/docs/qik.core.js.html +0 -301
- package/dist/docs/qik.files.js.html +0 -219
- package/dist/docs/qik.system.js.html +0 -117
- package/dist/docs/qik.utils.js.html +0 -1467
- package/dist/docs/system.html +0 -197
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Bold.eot +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Bold.ttf +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Bold.woff +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Bold.woff2 +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Regular.eot +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Regular.ttf +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Regular.woff +0 -0
- /package/dist/{docs/fonts → fonts}/Montserrat/Montserrat-Regular.woff2 +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.svg +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
- /package/dist/{docs/fonts → fonts}/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
- /package/dist/{docs/scripts → scripts}/collapse.js +0 -0
- /package/dist/{docs/scripts → scripts}/linenumber.js +0 -0
- /package/dist/{docs/scripts → scripts}/nav.js +0 -0
- /package/dist/{docs/scripts → scripts}/polyfill.js +0 -0
- /package/dist/{docs/scripts → scripts}/prettify/Apache-License-2.0.txt +0 -0
- /package/dist/{docs/scripts → scripts}/prettify/lang-css.js +0 -0
- /package/dist/{docs/scripts → scripts}/prettify/prettify.js +0 -0
- /package/dist/{docs/scripts → scripts}/search.js +0 -0
- /package/dist/{docs/styles → styles}/prettify.css +0 -0
|
@@ -0,0 +1,967 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<title>qik.content.js - Documentation</title>
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
<script src="scripts/prettify/prettify.js"></script>
|
|
10
|
+
<script src="scripts/prettify/lang-css.js"></script>
|
|
11
|
+
<!--[if lt IE 9]>
|
|
12
|
+
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
|
13
|
+
<![endif]-->
|
|
14
|
+
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
|
|
15
|
+
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
|
|
16
|
+
<script src="scripts/nav.js" defer></script>
|
|
17
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
|
|
21
|
+
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
|
|
22
|
+
<label for="nav-trigger" class="navicon-button x">
|
|
23
|
+
<div class="navicon"></div>
|
|
24
|
+
</label>
|
|
25
|
+
|
|
26
|
+
<label for="nav-trigger" class="overlay"></label>
|
|
27
|
+
|
|
28
|
+
<nav >
|
|
29
|
+
|
|
30
|
+
<h2><a href="index.html">Home</a></h2><h3>Classes</h3><ul><li><a href="access.html">access</a><ul class='methods'><li data-type='method'><a href="access.html#.actionableScopes">actionableScopes</a></li><li data-type='method'><a href="access.html#.allPermissions">allPermissions</a></li><li data-type='method'><a href="access.html#.allPermissionTypes">allPermissionTypes</a></li><li data-type='method'><a href="access.html#.allUserScopes">allUserScopes</a></li><li data-type='method'><a href="access.html#.canCreate">canCreate</a></li><li data-type='method'><a href="access.html#.canDeleteItem">canDeleteItem</a></li><li data-type='method'><a href="access.html#.canEditItem">canEditItem</a></li><li data-type='method'><a href="access.html#.canEraseItem">canEraseItem</a></li><li data-type='method'><a href="access.html#.canKnowOf">canKnowOf</a></li><li data-type='method'><a href="access.html#.canListItem">canListItem</a></li><li data-type='method'><a href="access.html#.canRestoreItem">canRestoreItem</a></li><li data-type='method'><a href="access.html#.canViewItem">canViewItem</a></li><li data-type='method'><a href="access.html#.checkActionAccess">checkActionAccess</a></li><li data-type='method'><a href="access.html#.getAllDescendants">getAllDescendants</a></li><li data-type='method'><a href="access.html#.has">has</a></li><li data-type='method'><a href="access.html#.hasFeature">hasFeature</a></li><li data-type='method'><a href="access.html#.hashPermissions">hashPermissions</a></li><li data-type='method'><a href="access.html#.isAdministrator">isAdministrator</a></li><li data-type='method'><a href="access.html#.isAssignee">isAssignee</a></li><li data-type='method'><a href="access.html#.isOwner">isOwner</a></li></ul></li><li><a href="api.html">api</a><ul class='methods'><li data-type='method'><a href="api.html#.generateEndpointURL">generateEndpointURL</a></li></ul></li><li><a href="auth.html">auth</a><ul class='methods'><li data-type='method'><a href="auth.html#.changeOrganisation">changeOrganisation</a></li><li data-type='method'><a href="auth.html#.ensureValidToken">ensureValidToken</a></li><li data-type='method'><a href="auth.html#.getCurrentToken">getCurrentToken</a></li><li data-type='method'><a href="auth.html#.getCurrentUser">getCurrentUser</a></li><li data-type='method'><a href="auth.html#.impersonate">impersonate</a></li><li data-type='method'><a href="auth.html#.login">login</a></li><li data-type='method'><a href="auth.html#.logout">logout</a></li><li data-type='method'><a href="auth.html#.retrieveUserFromResetToken">retrieveUserFromResetToken</a></li><li data-type='method'><a href="auth.html#.sendResetPasswordRequest">sendResetPasswordRequest</a></li><li data-type='method'><a href="auth.html#.set">set</a></li><li data-type='method'><a href="auth.html#.sync">sync</a></li><li data-type='method'><a href="auth.html#.updateUserWithToken">updateUserWithToken</a></li></ul></li><li><a href="cache.html">cache</a><ul class='methods'><li data-type='method'><a href="cache.html#.get">get</a></li><li data-type='method'><a href="cache.html#.reset">reset</a></li></ul></li><li><a href="content.html">content</a><ul class='methods'><li data-type='method'><a href="content.html#.create">create</a></li><li data-type='method'><a href="content.html#.delete">delete</a></li><li data-type='method'><a href="content.html#.get">get</a></li><li data-type='method'><a href="content.html#.getFromSlug">getFromSlug</a></li><li data-type='method'><a href="content.html#.glossary">glossary</a></li><li data-type='method'><a href="content.html#.list">list</a></li><li data-type='method'><a href="content.html#.patch">patch</a></li><li data-type='method'><a href="content.html#.restore">restore</a></li><li data-type='method'><a href="content.html#.scopeGlossary">scopeGlossary</a></li><li data-type='method'><a href="content.html#.update">update</a></li><li data-type='method'><a href="content.html#.validateField">validateField</a></li><li data-type='method'><a href="content.html#.variables">variables</a></li></ul></li><li><a href="files.html">files</a><ul class='methods'><li data-type='method'><a href="files.html#.downloadUrl">downloadUrl</a></li><li data-type='method'><a href="files.html#.duration">duration</a></li><li data-type='method'><a href="files.html#.filesize">filesize</a></li><li data-type='method'><a href="files.html#.getBinaryTypeFromMime">getBinaryTypeFromMime</a></li><li data-type='method'><a href="files.html#.mediaUrl">mediaUrl</a></li></ul></li><li><a href="filter.html">filter</a><ul class='methods'><li data-type='method'><a href="filter.html#.activeFilterComparators">activeFilterComparators</a></li><li data-type='method'><a href="filter.html#.activeFilterKeys">activeFilterKeys</a></li><li data-type='method'><a href="filter.html#.activeFilterOperators">activeFilterOperators</a></li><li data-type='method'><a href="filter.html#.activeFilters">activeFilters</a></li><li data-type='method'><a href="filter.html#.activeFilterValues">activeFilterValues</a></li><li data-type='method'><a href="filter.html#.filterChangeString">filterChangeString</a></li><li data-type='method'><a href="filter.html#.isValidFilter">isValidFilter</a></li></ul></li><li><a href="geo.html">geo</a><ul class='methods'><li data-type='method'><a href="geo.html#.distance">distance</a></li><li data-type='method'><a href="geo.html#.getDefaultCountry">getDefaultCountry</a></li><li data-type='method'><a href="geo.html#.getDefaultTimezone">getDefaultTimezone</a></li><li data-type='method'><a href="geo.html#.getPosition">getPosition</a></li><li data-type='method'><a href="geo.html#.stopWatchPosition">stopWatchPosition</a></li><li data-type='method'><a href="geo.html#.watchPosition">watchPosition</a></li></ul></li><li><a href="module-QikStorage-CookieStorageAdapter.html">CookieStorageAdapter</a><ul class='methods'><li data-type='method'><a href="module-QikStorage-CookieStorageAdapter.html#getCookieOptions">getCookieOptions</a></li><li data-type='method'><a href="module-QikStorage-CookieStorageAdapter.html#isCookieMode">isCookieMode</a></li></ul></li><li><a href="module-QikStorage-LocalStorageAdapter.html">LocalStorageAdapter</a></li><li><a href="module-QikStorage-StorageAdapter.html">StorageAdapter</a><ul class='methods'><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#clearUser">clearUser</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getAccessToken">getAccessToken</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getRefreshToken">getRefreshToken</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getTokenExpiry">getTokenExpiry</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#getUser">getUser</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#isAvailable">isAvailable</a></li><li data-type='method'><a href="module-QikStorage-StorageAdapter.html#setUser">setUser</a></li></ul></li><li><a href="socket.html">socket</a><ul class='methods'><li data-type='method'><a href="socket.html#.channel">channel</a></li><li data-type='method'><a href="socket.html#.close">close</a></li><li data-type='method'><a href="socket.html#.connect">connect</a></li><li data-type='method'><a href="socket.html#.reconnect">reconnect</a></li><li data-type='method'><a href="socket.html#.subscribe">subscribe</a></li><li data-type='method'><a href="socket.html#.unsubscribe">unsubscribe</a></li></ul></li><li><a href="system.html">system</a><ul class='methods'><li data-type='method'><a href="system.html#.countries">countries</a></li></ul></li><li><a href="utils.html">utils</a><ul class='methods'><li data-type='method'><a href="utils.html#.cleanValue">cleanValue</a></li><li data-type='method'><a href="utils.html#.comma">comma</a></li><li data-type='method'><a href="utils.html#.errorMessage">errorMessage</a></li><li data-type='method'><a href="utils.html#.exists">exists</a></li><li data-type='method'><a href="utils.html#.extractFromArray">extractFromArray</a></li><li data-type='method'><a href="utils.html#.formatCurrency">formatCurrency</a></li><li data-type='method'><a href="utils.html#.getTypeFromID">getTypeFromID</a></li><li data-type='method'><a href="utils.html#.guid">guid</a></li><li data-type='method'><a href="utils.html#.hash">hash</a></li><li data-type='method'><a href="utils.html#.id">id</a></li><li data-type='method'><a href="utils.html#.ids">ids</a></li><li data-type='method'><a href="utils.html#.isValidEmailAddress">isValidEmailAddress</a></li><li data-type='method'><a href="utils.html#.loadExternalScript">loadExternalScript</a></li><li data-type='method'><a href="utils.html#.loadExternalStyle">loadExternalStyle</a></li><li data-type='method'><a href="utils.html#.machineName">machineName</a></li><li data-type='method'><a href="utils.html#.mapParameters">mapParameters</a></li><li data-type='method'><a href="utils.html#.matchInArray">matchInArray</a></li><li data-type='method'><a href="utils.html#.parseBoolean">parseBoolean</a></li><li data-type='method'><a href="utils.html#.parseDate">parseDate</a></li><li data-type='method'><a href="utils.html#.parseEmail">parseEmail</a></li><li data-type='method'><a href="utils.html#.parseInt">parseInt</a></li><li data-type='method'><a href="utils.html#.parseNumber">parseNumber</a></li><li data-type='method'><a href="utils.html#.parseURL">parseURL</a></li></ul></li></ul><h3>Modules</h3><ul><li><a href="module-QikStorage.html">QikStorage</a><ul class='methods'><li data-type='method'><a href="module-QikStorage.html#.createStorageAdapter">createStorageAdapter</a></li></ul></li></ul><h3>Global</h3><ul><li><a href="global.html#EventDispatcher">EventDispatcher</a></li></ul>
|
|
31
|
+
</nav>
|
|
32
|
+
|
|
33
|
+
<div id="main">
|
|
34
|
+
|
|
35
|
+
<h1 class="page-title">qik.content.js</h1>
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
<section>
|
|
44
|
+
<article>
|
|
45
|
+
<pre class="prettyprint source linenums"><code>///////////////////////////////////////////////////
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new QikContent instance.
|
|
49
|
+
* This module provides a number of helper functions for creating and modifying content via the REST API
|
|
50
|
+
* @alias content
|
|
51
|
+
* @constructor
|
|
52
|
+
* @hideconstructor
|
|
53
|
+
* @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.
|
|
54
|
+
*/
|
|
55
|
+
export default function (qik) {
|
|
56
|
+
if (!qik.api) {
|
|
57
|
+
throw new Error(`Can't Instantiate QikContent before QikAPI exists`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
///////////////////////////////////////////////////
|
|
61
|
+
|
|
62
|
+
var service = {
|
|
63
|
+
debug: false,
|
|
64
|
+
loadingGlossary: false,
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
///////////////////////////////////////////////////////////////////////////////
|
|
68
|
+
|
|
69
|
+
const variables = {};
|
|
70
|
+
let inflightVariablesRequest;
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
*
|
|
74
|
+
* Retrieves all global variables for the current user. This is often used when running custom code in an action.
|
|
75
|
+
* @alias content.variables
|
|
76
|
+
* @param {Array} keys Provide specific keys of variables you want to retrieve
|
|
77
|
+
* @param {Object} options Additional options when making the request
|
|
78
|
+
* @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.
|
|
79
|
+
* @example
|
|
80
|
+
*
|
|
81
|
+
* const { OAUTH_CLIENT_ID, OAUTH_KEY } = await sdk.content.variables();
|
|
82
|
+
*/
|
|
83
|
+
|
|
84
|
+
service.variables = async function (keys, options) {
|
|
85
|
+
options = options || {};
|
|
86
|
+
keys = keys || [];
|
|
87
|
+
|
|
88
|
+
var reload = options.refresh || options.reload || !variables.data;
|
|
89
|
+
if (reload) {
|
|
90
|
+
if (!inflightVariablesRequest) {
|
|
91
|
+
inflightVariablesRequest = qik.api.post(`/variables`, { keys });
|
|
92
|
+
inflightVariablesRequest.then(resolveRequest, resolveRequest);
|
|
93
|
+
function resolveRequest() {
|
|
94
|
+
inflightVariablesRequest = null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const { data } = await inflightVariablesRequest;
|
|
99
|
+
variables.data = data;
|
|
100
|
+
qik.dispatch("variables", data);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return variables.data;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
///////////////////////////////////////////////////
|
|
107
|
+
|
|
108
|
+
const glossaryCache = qik.cache.get("user:glossary");
|
|
109
|
+
|
|
110
|
+
let inflightGlossaryRequest;
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Yield to the event loop to keep the UI responsive
|
|
114
|
+
* @private
|
|
115
|
+
*/
|
|
116
|
+
function yieldToMain() {
|
|
117
|
+
return new Promise((resolve) => {
|
|
118
|
+
if (typeof requestIdleCallback === "function") {
|
|
119
|
+
requestIdleCallback(resolve, { timeout: 50 });
|
|
120
|
+
} else {
|
|
121
|
+
setTimeout(resolve, 0);
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Inflate compressed glossary data from the /glossary/compressed endpoint
|
|
128
|
+
* Processes in chunks to avoid blocking the main thread
|
|
129
|
+
* @private
|
|
130
|
+
*/
|
|
131
|
+
async function inflateGlossary({ _s: strings, _k: keyMap, types }) {
|
|
132
|
+
function inflate(val) {
|
|
133
|
+
if (typeof val === "string" && val[0] === "~") {
|
|
134
|
+
return strings[parseInt(val.slice(1))];
|
|
135
|
+
}
|
|
136
|
+
if (Array.isArray(val)) return val.map(inflate);
|
|
137
|
+
if (val && typeof val === "object") {
|
|
138
|
+
const result = {};
|
|
139
|
+
for (const [k, v] of Object.entries(val)) {
|
|
140
|
+
result[keyMap[k] || k] = inflate(v);
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
return val;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const CHUNK_SIZE = 50;
|
|
148
|
+
const results = [];
|
|
149
|
+
|
|
150
|
+
for (let i = 0; i < types.length; i += CHUNK_SIZE) {
|
|
151
|
+
const chunk = types.slice(i, i + CHUNK_SIZE);
|
|
152
|
+
results.push(...chunk.map(inflate));
|
|
153
|
+
|
|
154
|
+
// Yield to main thread between chunks
|
|
155
|
+
if (i + CHUNK_SIZE < types.length) {
|
|
156
|
+
await yieldToMain();
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
return results;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
*
|
|
165
|
+
* Retrieves the glossary of all content types visible to the requesting user.
|
|
166
|
+
By default this will include all fields, validation, expressions and other configuration
|
|
167
|
+
* @alias content.glossary
|
|
168
|
+
* @param {Object} options Additional options
|
|
169
|
+
* @param {Boolean} options.hash Whether to return the data as a keyed object
|
|
170
|
+
allowing for fast selection of specific content types, by default will return as an array
|
|
171
|
+
* @param {Boolean} options.reload Force glossary to reload and not be cached.
|
|
172
|
+
If false will retrieve content type data from the in memory cache
|
|
173
|
+
* @param {Boolean} options.uncompressed Use the uncompressed endpoint
|
|
174
|
+
* @example
|
|
175
|
+
*
|
|
176
|
+
* const { article, profile } = await sdk.content.glossary({hash:true});
|
|
177
|
+
* // Use compressed endpoint for faster loading
|
|
178
|
+
* const glossary = await sdk.content.glossary({compressed:true});
|
|
179
|
+
*/
|
|
180
|
+
service.glossary = async function (options) {
|
|
181
|
+
options = options || {};
|
|
182
|
+
|
|
183
|
+
// Check if we already have the glossary cached
|
|
184
|
+
let cached = glossaryCache.get("glossary");
|
|
185
|
+
const uncompressed = !!options.uncompressed;
|
|
186
|
+
let compressed = !uncompressed;
|
|
187
|
+
var reload = options.refresh || options.reload || !cached;
|
|
188
|
+
|
|
189
|
+
// If we are forcing a reload
|
|
190
|
+
if (reload) {
|
|
191
|
+
if (!inflightGlossaryRequest) {
|
|
192
|
+
service.loadingGlossary = true;
|
|
193
|
+
|
|
194
|
+
// Use compressed endpoint if requested
|
|
195
|
+
const endpoint = compressed ? `/glossary/compressed` : `/glossary`;
|
|
196
|
+
inflightGlossaryRequest = qik.api.get(endpoint, { cache: false });
|
|
197
|
+
inflightGlossaryRequest.then(resolveRequest, resolveRequest);
|
|
198
|
+
function resolveRequest() {
|
|
199
|
+
inflightGlossaryRequest = null;
|
|
200
|
+
service.loadingGlossary = false;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Now we have the glossary
|
|
205
|
+
const { data } = await inflightGlossaryRequest;
|
|
206
|
+
|
|
207
|
+
// Inflate if compressed format (async to avoid blocking UI)
|
|
208
|
+
const glossaryData =
|
|
209
|
+
data._s && data._k && data.types ? await inflateGlossary(data) : data;
|
|
210
|
+
|
|
211
|
+
// Cache it for later
|
|
212
|
+
glossaryCache.set("glossary", glossaryData);
|
|
213
|
+
cached = glossaryData;
|
|
214
|
+
qik.dispatch("glossary", glossaryData);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (options.hash) {
|
|
218
|
+
var result = qik.utils.hash(cached, "key");
|
|
219
|
+
return result;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (options.hex) {
|
|
223
|
+
var result = qik.utils.hash(cached, "hex");
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
return cached;
|
|
228
|
+
};
|
|
229
|
+
|
|
230
|
+
///////////////////////////////////////////////////
|
|
231
|
+
|
|
232
|
+
const scopeGlossary = {};
|
|
233
|
+
|
|
234
|
+
let inflightScopeGlossaryRequest;
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
*
|
|
238
|
+
* Retrieves the scope glossary of all scopes the user can know about. This helps to convert a scope id into a human readable title.
|
|
239
|
+
* @alias content.scopeGlossary
|
|
240
|
+
* @param {Object} options Additional options
|
|
241
|
+
* @param {Boolean} options.hash Whether to return the data as a keyed object with each scopes _id as the key
|
|
242
|
+
allowing for fast selection of specific scopes, by default will return a structured tree
|
|
243
|
+
* @param {Boolean} options.reload Force the glossary to reload and not be cached.
|
|
244
|
+
If false will retrieve content type data from the in memory cache
|
|
245
|
+
* @example
|
|
246
|
+
*
|
|
247
|
+
* const scopes = await sdk.content.scopeGlossary();
|
|
248
|
+
*/
|
|
249
|
+
|
|
250
|
+
service.scopeGlossary = async function (options) {
|
|
251
|
+
options = options || {};
|
|
252
|
+
|
|
253
|
+
var reload = options.refresh || options.reload || !scopeGlossary.data;
|
|
254
|
+
|
|
255
|
+
if (reload) {
|
|
256
|
+
if (!inflightScopeGlossaryRequest) {
|
|
257
|
+
inflightScopeGlossaryRequest = qik.api.get(`/scope/glossary`, {
|
|
258
|
+
cache: false,
|
|
259
|
+
});
|
|
260
|
+
inflightScopeGlossaryRequest.then(resolveRequest, resolveRequest);
|
|
261
|
+
function resolveRequest() {
|
|
262
|
+
inflightScopeGlossaryRequest = null;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const { data } = await inflightScopeGlossaryRequest;
|
|
267
|
+
scopeGlossary.data = data;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
if (options.hash) {
|
|
271
|
+
var result = qik.utils.hash(scopeGlossary.data, "_id");
|
|
272
|
+
return result;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return scopeGlossary.data;
|
|
276
|
+
};
|
|
277
|
+
|
|
278
|
+
///////////////////////////////////////////////////
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
*
|
|
282
|
+
* Retrieves all available filter comparators for each data type
|
|
283
|
+
* @alias content.comparators
|
|
284
|
+
* @param {Object} options Additional options
|
|
285
|
+
* @param {Boolean} options.reload Ignore any locally cached data
|
|
286
|
+
* @example
|
|
287
|
+
* const {hash, available, types} = await sdk.content.comparators();
|
|
288
|
+
* console.log(available) // {boolean:[{title:'Is equal to', operator:'equal'...}]}
|
|
289
|
+
* console.log(hash) // {equal:[{title:'Is equal to', operator:'equal'...}]}
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
const comparators = {};
|
|
293
|
+
|
|
294
|
+
service.comparators = async function (options) {
|
|
295
|
+
options = options || {};
|
|
296
|
+
|
|
297
|
+
var reload = options.reload || options.refresh || !comparators.data;
|
|
298
|
+
|
|
299
|
+
if (reload) {
|
|
300
|
+
const { data } = await qik.api.get(`/system/comparators`);
|
|
301
|
+
|
|
302
|
+
/////////////////////////////
|
|
303
|
+
|
|
304
|
+
data.available = {};
|
|
305
|
+
|
|
306
|
+
Object.entries(data.types).forEach(([key, value]) => {
|
|
307
|
+
data.available[key] = value.map(function (comparatorKey) {
|
|
308
|
+
return data.hash[comparatorKey];
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
/////////////////////////////
|
|
313
|
+
|
|
314
|
+
comparators.data = data;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// if (options.hash) {
|
|
318
|
+
// var result = qik.utils.hash(comparators.data, 'key');
|
|
319
|
+
// return result;
|
|
320
|
+
// }
|
|
321
|
+
|
|
322
|
+
return comparators.data;
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
///////////////////////////////////////////////////
|
|
326
|
+
|
|
327
|
+
function getLimits(fieldDefinition) {
|
|
328
|
+
var { minimum, maximum } = fieldDefinition;
|
|
329
|
+
minimum = qik.utils.parseInt(minimum);
|
|
330
|
+
minimum = Math.max(minimum, 0);
|
|
331
|
+
|
|
332
|
+
maximum = qik.utils.parseInt(maximum);
|
|
333
|
+
maximum = Math.max(maximum, 0); // cant be less than 0
|
|
334
|
+
if (maximum == 0) {
|
|
335
|
+
//Unlimited maximum
|
|
336
|
+
} else {
|
|
337
|
+
maximum = Math.max(maximum, minimum); // cant be less than the minimum
|
|
338
|
+
}
|
|
339
|
+
return { minimum, maximum };
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
service.meetsValidationRequirements = function (
|
|
343
|
+
input,
|
|
344
|
+
fieldType,
|
|
345
|
+
validationCriteria,
|
|
346
|
+
) {
|
|
347
|
+
if (validationCriteria.minLength) {
|
|
348
|
+
var stringLength = String(input).length;
|
|
349
|
+
if (stringLength < validationCriteria.minLength) {
|
|
350
|
+
return `Must be at least ${validationCriteria.minLength} characters`;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
if (validationCriteria.maxLength) {
|
|
355
|
+
var stringLength = String(input).length;
|
|
356
|
+
if (stringLength > validationCriteria.maxLength) {
|
|
357
|
+
return `Can be no more than ${validationCriteria.maxLength} characters`;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (validationCriteria.minValue) {
|
|
362
|
+
if (input !== undefined) {
|
|
363
|
+
var number = Number(input);
|
|
364
|
+
if (number < validationCriteria.minValue) {
|
|
365
|
+
return `Must be at least ${validationCriteria.minValue}`;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
if (validationCriteria.maxValue) {
|
|
371
|
+
if (input !== undefined) {
|
|
372
|
+
var number = Number(input);
|
|
373
|
+
if (number > validationCriteria.maxValue) {
|
|
374
|
+
return `Can be no greater than ${validationCriteria.maxValue}`;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Checks if a certain input validates against a field definition
|
|
382
|
+
* @alias content.validateField
|
|
383
|
+
* @param {Any} input The input to validate
|
|
384
|
+
* @param {Object} fieldDefinition The field to validate against
|
|
385
|
+
* @param {Object} options Additional options when calling the function
|
|
386
|
+
* @example
|
|
387
|
+
* const validationResult = await sdk.content.validateField('Johnny Bobbins', {title:'Name', key:'firstName', type:'string', minimum:1, maximum:1, ...});
|
|
388
|
+
* console.log(validationResult)
|
|
389
|
+
* // Results in { valid:true }
|
|
390
|
+
*
|
|
391
|
+
* const validationResult = await sdk.content.validateField('Johnny Bobbins', {title:'Number', key:'number', type:'integer', minimum:1, maximum:1, ...});
|
|
392
|
+
* console.log(validationResult)
|
|
393
|
+
* // Results in { valid:false, status:400, message:'Invalid number input for field' }
|
|
394
|
+
*/
|
|
395
|
+
|
|
396
|
+
service.validateField = function (input, fieldDefinition, options) {
|
|
397
|
+
options = options || {};
|
|
398
|
+
|
|
399
|
+
var fieldType = fieldDefinition.type || "string";
|
|
400
|
+
var { minimum, maximum } = getLimits(fieldDefinition);
|
|
401
|
+
|
|
402
|
+
var isObject = fieldDefinition.type == "group" && fieldDefinition.asObject;
|
|
403
|
+
var singleValue = isObject
|
|
404
|
+
? minimum === maximum && maximum === 1
|
|
405
|
+
: maximum === 1;
|
|
406
|
+
var multiValue = !singleValue;
|
|
407
|
+
|
|
408
|
+
//////////////////
|
|
409
|
+
|
|
410
|
+
var isNumeric;
|
|
411
|
+
switch (fieldType) {
|
|
412
|
+
case "integer":
|
|
413
|
+
case "decimal":
|
|
414
|
+
case "number":
|
|
415
|
+
case "float":
|
|
416
|
+
isNumeric = true;
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
//////////////////
|
|
421
|
+
|
|
422
|
+
var inputWasProvided = qik.utils.exists(input);
|
|
423
|
+
|
|
424
|
+
// A required boolean field means "must be true" — false counts as missing.
|
|
425
|
+
if (fieldDefinition.type === "boolean" && input !== true) {
|
|
426
|
+
inputWasProvided = false;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
//If an answer is required
|
|
430
|
+
if (minimum) {
|
|
431
|
+
//but none was provided
|
|
432
|
+
if (!inputWasProvided) {
|
|
433
|
+
//Throw an error
|
|
434
|
+
return {
|
|
435
|
+
valid: false,
|
|
436
|
+
message: `${fieldDefinition.title} is a required field`,
|
|
437
|
+
status: 400,
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
} else {
|
|
441
|
+
//No answer is needed and none was provided
|
|
442
|
+
if (!inputWasProvided) {
|
|
443
|
+
return {
|
|
444
|
+
valid: true,
|
|
445
|
+
};
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
//////////////////
|
|
450
|
+
|
|
451
|
+
//If we are requiring multiple values
|
|
452
|
+
if (multiValue) {
|
|
453
|
+
//But the input is not an array
|
|
454
|
+
if (!Array.isArray(input)) {
|
|
455
|
+
if (minimum) {
|
|
456
|
+
return {
|
|
457
|
+
valid: false,
|
|
458
|
+
message: `${fieldDefinition.title} requires at least ${minimum} values`,
|
|
459
|
+
status: 400,
|
|
460
|
+
};
|
|
461
|
+
} else {
|
|
462
|
+
console.log("NOT PROVIDED AS ARRAY", fieldDefinition.title, input);
|
|
463
|
+
return {
|
|
464
|
+
valid: false,
|
|
465
|
+
message: `${fieldDefinition.title} must be provided as an array`,
|
|
466
|
+
status: 400,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
////////////////////////////
|
|
472
|
+
|
|
473
|
+
var compacted = input;
|
|
474
|
+
|
|
475
|
+
compacted = compacted.filter(function (v) {
|
|
476
|
+
//Check if we care about this value
|
|
477
|
+
var empty = v === undefined || v === null || v === "";
|
|
478
|
+
return !empty;
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
// console.log('COMPACTED', input.length, compacted.length);
|
|
482
|
+
|
|
483
|
+
////////////////////////////
|
|
484
|
+
|
|
485
|
+
//We need an exact number of answers
|
|
486
|
+
if (minimum == maximum) {
|
|
487
|
+
//But we don't have the number of answers needed
|
|
488
|
+
if (minimum && compacted.length != minimum) {
|
|
489
|
+
return {
|
|
490
|
+
valid: false,
|
|
491
|
+
message: `${fieldDefinition.title} requires exactly ${maximum} values`,
|
|
492
|
+
status: 400,
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
//We have too many answers
|
|
498
|
+
if (maximum && compacted.length > maximum) {
|
|
499
|
+
return {
|
|
500
|
+
valid: false,
|
|
501
|
+
message: `${fieldDefinition.title} requires less than ${maximum + 1} values`,
|
|
502
|
+
status: 400,
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
//We don't have enough answers
|
|
507
|
+
if (compacted.length < minimum) {
|
|
508
|
+
// console.log(fieldDefinition.title, 'INPUT', input.length, minimum, input, compacted)
|
|
509
|
+
|
|
510
|
+
return {
|
|
511
|
+
valid: false,
|
|
512
|
+
message: `${fieldDefinition.title} requires at least ${minimum} values`,
|
|
513
|
+
status: 400,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
////////////////////////////
|
|
518
|
+
|
|
519
|
+
var foundBadEntry;
|
|
520
|
+
|
|
521
|
+
//Find any bad values
|
|
522
|
+
var badEntry = compacted.find(function (val) {
|
|
523
|
+
var valueFieldType = fieldType;
|
|
524
|
+
|
|
525
|
+
if (fieldDefinition.type === "group") {
|
|
526
|
+
valueFieldType = "object";
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
if (
|
|
530
|
+
fieldDefinition.type === "reference" &&
|
|
531
|
+
fieldDefinition.widget === "form"
|
|
532
|
+
) {
|
|
533
|
+
valueFieldType = "object";
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
var isValid = qik.utils.isValidValue(
|
|
537
|
+
val,
|
|
538
|
+
valueFieldType,
|
|
539
|
+
options.strict,
|
|
540
|
+
);
|
|
541
|
+
|
|
542
|
+
////////////////////////////
|
|
543
|
+
|
|
544
|
+
if (!isValid) {
|
|
545
|
+
foundBadEntry = true;
|
|
546
|
+
return true;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
////////////////////////////
|
|
550
|
+
|
|
551
|
+
//Is there additional validation requirements
|
|
552
|
+
if (fieldDefinition.validation) {
|
|
553
|
+
var additionalValidationErrors = service.meetsValidationRequirements(
|
|
554
|
+
val,
|
|
555
|
+
fieldType,
|
|
556
|
+
fieldDefinition.validation,
|
|
557
|
+
);
|
|
558
|
+
if (additionalValidationErrors) {
|
|
559
|
+
foundBadEntry = true;
|
|
560
|
+
return true;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
if (foundBadEntry) {
|
|
566
|
+
let badValueMessage = `Invalid input for ${fieldDefinition.title}`;
|
|
567
|
+
return {
|
|
568
|
+
valid: false,
|
|
569
|
+
message: badValueMessage,
|
|
570
|
+
status: 400,
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
} else {
|
|
574
|
+
var dataType = fieldType;
|
|
575
|
+
var widgetType = fieldDefinition.widget;
|
|
576
|
+
if (dataType === "group") {
|
|
577
|
+
dataType = "object";
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
if (dataType === "reference" && widgetType === "form") {
|
|
581
|
+
dataType = "object";
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
//////////////////
|
|
585
|
+
|
|
586
|
+
var cleanedValue = service.getCleanedValue(input, dataType, options);
|
|
587
|
+
|
|
588
|
+
//////////////////
|
|
589
|
+
|
|
590
|
+
var isValidValue = qik.utils.isValidValue(
|
|
591
|
+
cleanedValue,
|
|
592
|
+
dataType,
|
|
593
|
+
options.strict,
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
//////////////////
|
|
597
|
+
|
|
598
|
+
//Invalid input
|
|
599
|
+
if (!isValidValue) {
|
|
600
|
+
return {
|
|
601
|
+
valid: false,
|
|
602
|
+
message: `Single value '${input}' is not a valid ${dataType} for ${fieldDefinition.title}`,
|
|
603
|
+
criteria: {
|
|
604
|
+
isValidValue,
|
|
605
|
+
cleanedValue,
|
|
606
|
+
fieldType,
|
|
607
|
+
options,
|
|
608
|
+
},
|
|
609
|
+
status: 400,
|
|
610
|
+
};
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
//Is there additional validation requirements
|
|
614
|
+
let hasAdditionalValidation = false;
|
|
615
|
+
|
|
616
|
+
const validation = {};
|
|
617
|
+
if (String(fieldDefinition.minValue)) {
|
|
618
|
+
validation.minValue = parseInt(fieldDefinition.minValue);
|
|
619
|
+
hasAdditionalValidation = true;
|
|
620
|
+
}
|
|
621
|
+
if (String(fieldDefinition.maxValue)) {
|
|
622
|
+
validation.maxValue = parseInt(fieldDefinition.maxValue);
|
|
623
|
+
hasAdditionalValidation = true;
|
|
624
|
+
}
|
|
625
|
+
if (String(fieldDefinition.minLength)) {
|
|
626
|
+
validation.minLength = parseInt(fieldDefinition.minLength);
|
|
627
|
+
hasAdditionalValidation = true;
|
|
628
|
+
}
|
|
629
|
+
if (String(fieldDefinition.maxLength)) {
|
|
630
|
+
validation.maxLength = parseInt(fieldDefinition.maxLength);
|
|
631
|
+
hasAdditionalValidation = true;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
if (hasAdditionalValidation) {
|
|
635
|
+
const validationCriteria = Object.assign(
|
|
636
|
+
{},
|
|
637
|
+
validation,
|
|
638
|
+
fieldDefinition.validation || {},
|
|
639
|
+
);
|
|
640
|
+
var additionalValidationError = service.meetsValidationRequirements(
|
|
641
|
+
input,
|
|
642
|
+
fieldType,
|
|
643
|
+
validationCriteria,
|
|
644
|
+
);
|
|
645
|
+
if (additionalValidationError) {
|
|
646
|
+
return {
|
|
647
|
+
valid: false,
|
|
648
|
+
message: additionalValidationError,
|
|
649
|
+
status: 400,
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
//////////////////
|
|
656
|
+
|
|
657
|
+
return {
|
|
658
|
+
valid: true,
|
|
659
|
+
};
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
service.getCleanedValue = function (input, dataType, options) {
|
|
663
|
+
switch (dataType) {
|
|
664
|
+
case "number":
|
|
665
|
+
case "float":
|
|
666
|
+
case "decimal":
|
|
667
|
+
if (!qik.utils.exists(input)) {
|
|
668
|
+
return undefined;
|
|
669
|
+
} else {
|
|
670
|
+
return Number(input);
|
|
671
|
+
}
|
|
672
|
+
break;
|
|
673
|
+
case "integer":
|
|
674
|
+
if (!qik.utils.exists(input)) {
|
|
675
|
+
return undefined;
|
|
676
|
+
} else {
|
|
677
|
+
return parseInt(input);
|
|
678
|
+
}
|
|
679
|
+
break;
|
|
680
|
+
case "boolean":
|
|
681
|
+
if (!qik.utils.exists(input)) {
|
|
682
|
+
return undefined;
|
|
683
|
+
}
|
|
684
|
+
return qik.utils.parseBoolean(input);
|
|
685
|
+
break;
|
|
686
|
+
case "email":
|
|
687
|
+
return options.strict ? input : String(input).toLowerCase();
|
|
688
|
+
break;
|
|
689
|
+
case "reference":
|
|
690
|
+
return options.strict ? input : qik.utils.id(input);
|
|
691
|
+
break;
|
|
692
|
+
default:
|
|
693
|
+
return options.strict
|
|
694
|
+
? input
|
|
695
|
+
: qik.utils.cleanValue(input, dataType, options);
|
|
696
|
+
break;
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
return input;
|
|
700
|
+
};
|
|
701
|
+
|
|
702
|
+
///////////////////////////////////////////////////
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
*
|
|
706
|
+
* Retrieves a list of records matching the provided criteria
|
|
707
|
+
* @alias content.list
|
|
708
|
+
* @param {String} type The type or definition of records we want to retrieve
|
|
709
|
+
* @param {Object} options The options for our query
|
|
710
|
+
* @param {String} options.search Freeform text keywords
|
|
711
|
+
* @param {Object} options.sort How to sort the results
|
|
712
|
+
* @param {String} options.sort.key Which key to sort on
|
|
713
|
+
* @param {String} options.sort.direction Which direction to sort on
|
|
714
|
+
* @param {Object} options.sort.type What type of data is being sorted
|
|
715
|
+
* @param {Object} options.page Page configuration
|
|
716
|
+
* @param {Number} options.page.size Page size
|
|
717
|
+
* @param {Number} options.page.index Page index
|
|
718
|
+
* @param {Object} options.filter How to filter the results
|
|
719
|
+
* @example
|
|
720
|
+
*
|
|
721
|
+
*
|
|
722
|
+
* sdk.content.list('profile', {
|
|
723
|
+
* search:'Jim',
|
|
724
|
+
* page:{
|
|
725
|
+
* size:50,
|
|
726
|
+
* index:2,
|
|
727
|
+
* },
|
|
728
|
+
* sort:{
|
|
729
|
+
* key:'age',
|
|
730
|
+
* direction:'asc',
|
|
731
|
+
* type:'integer',
|
|
732
|
+
* },
|
|
733
|
+
* filter:{
|
|
734
|
+
* operator:'and',
|
|
735
|
+
* filters:[{
|
|
736
|
+
* key:'age',
|
|
737
|
+
* comparator:'>',
|
|
738
|
+
* value:5,
|
|
739
|
+
* }],
|
|
740
|
+
* },
|
|
741
|
+
* })
|
|
742
|
+
*/
|
|
743
|
+
|
|
744
|
+
service.list = async function (type, options, advanced) {
|
|
745
|
+
if (!advanced) {
|
|
746
|
+
advanced = {};
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
const remoteURL = advanced.remoteURL || `/content/${type}/list`;
|
|
750
|
+
|
|
751
|
+
if (advanced.cancellable) {
|
|
752
|
+
if (!advanced.config) {
|
|
753
|
+
advanced.config = {};
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
//Create a cancel token
|
|
757
|
+
const CancelToken = qik.api.CancelToken;
|
|
758
|
+
const source = CancelToken.source();
|
|
759
|
+
advanced.config.cancelToken = source.token;
|
|
760
|
+
|
|
761
|
+
const promise = qik.api.post(remoteURL, options, advanced.config);
|
|
762
|
+
return {
|
|
763
|
+
promise,
|
|
764
|
+
cancel(message) {
|
|
765
|
+
source.cancel(message || "Operation canceled by the user.");
|
|
766
|
+
},
|
|
767
|
+
};
|
|
768
|
+
} else {
|
|
769
|
+
const { data } = await qik.api.post(remoteURL, options, advanced.config);
|
|
770
|
+
return data;
|
|
771
|
+
}
|
|
772
|
+
};
|
|
773
|
+
|
|
774
|
+
///////////////////////////////////////////////////
|
|
775
|
+
|
|
776
|
+
/**
|
|
777
|
+
*
|
|
778
|
+
* Create an item
|
|
779
|
+
* @alias content.create
|
|
780
|
+
* @param {String} type The type or definition of the record we want to create
|
|
781
|
+
* @param {Object} input The data for our new record
|
|
782
|
+
* @example
|
|
783
|
+
*
|
|
784
|
+
*
|
|
785
|
+
* const result = await sdk.content.create('profile', {
|
|
786
|
+
* firstName:'Mickey',
|
|
787
|
+
* lastName:'Mouse',
|
|
788
|
+
* gender:'male',
|
|
789
|
+
* meta:{
|
|
790
|
+
* scopes:['61eca4746971e75c1fc670cf'],
|
|
791
|
+
* }
|
|
792
|
+
* })
|
|
793
|
+
*/
|
|
794
|
+
|
|
795
|
+
service.create = async function (type, input) {
|
|
796
|
+
const dataModel = { ...input };
|
|
797
|
+
|
|
798
|
+
// Sanitize down to just ids before we send
|
|
799
|
+
if (dataModel.meta?.scopes) {
|
|
800
|
+
dataModel.meta.scopes = qik.utils.ids(dataModel.meta.scopes);
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
const { data } = await qik.api.post(`/content/${type}/create`, dataModel);
|
|
804
|
+
return data;
|
|
805
|
+
};
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
*
|
|
809
|
+
* Update an item, Only fields the user has permission to view will be returned
|
|
810
|
+
* @alias content.update
|
|
811
|
+
* @param {String} id The id of the record we want to update
|
|
812
|
+
* @param {Object} input The data to update
|
|
813
|
+
* @example
|
|
814
|
+
*
|
|
815
|
+
* const result = await sdk.content.update('61eca4746971e75c1fc670cd', {
|
|
816
|
+
* firstName:'Minnie',
|
|
817
|
+
* lastName:'Mouse',
|
|
818
|
+
* gender:'female',
|
|
819
|
+
* meta:{
|
|
820
|
+
* scopes:['61eca4746971e75c1fc670cd'],
|
|
821
|
+
* }
|
|
822
|
+
* })
|
|
823
|
+
*/
|
|
824
|
+
service.update = async function (id, input) {
|
|
825
|
+
id = qik.utils.id(id);
|
|
826
|
+
|
|
827
|
+
const dataModel = { ...input };
|
|
828
|
+
|
|
829
|
+
// Sanitize down to just ids before we send
|
|
830
|
+
if (dataModel.meta?.scopes) {
|
|
831
|
+
dataModel.meta.scopes = qik.utils.ids(dataModel.meta.scopes);
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
const { data } = await qik.api.put(`/content/${id}`, dataModel);
|
|
835
|
+
return data;
|
|
836
|
+
};
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
*
|
|
840
|
+
* Partially update and patch an item, Only fields the user has permission to edit will be updated
|
|
841
|
+
* @alias content.patch
|
|
842
|
+
* @param {String} id The id of the record we want to update
|
|
843
|
+
* @param {Object} input The data to update, this will be merged with existing data
|
|
844
|
+
* @example
|
|
845
|
+
*
|
|
846
|
+
* const result = await sdk.content.patch('61eca4746971e75c1fc670cd', {
|
|
847
|
+
* firstName:'Mickey',
|
|
848
|
+
* gender:'male',
|
|
849
|
+
* })
|
|
850
|
+
*/
|
|
851
|
+
service.patch = async function (id, input) {
|
|
852
|
+
id = qik.utils.id(id);
|
|
853
|
+
|
|
854
|
+
const dataModel = { ...input };
|
|
855
|
+
|
|
856
|
+
// Sanitize down to just ids before we send
|
|
857
|
+
if (dataModel.meta?.scopes) {
|
|
858
|
+
dataModel.meta.scopes = qik.utils.ids(dataModel.meta.scopes);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
const { data } = await qik.api.patch(`/content/${id}`, dataModel);
|
|
862
|
+
return data;
|
|
863
|
+
};
|
|
864
|
+
|
|
865
|
+
/**
|
|
866
|
+
*
|
|
867
|
+
* Get an item from the database, Only fields the user has permission to view will be returned
|
|
868
|
+
* @alias content.get
|
|
869
|
+
* @param {String} id The id of the record we want to update
|
|
870
|
+
* @example
|
|
871
|
+
*
|
|
872
|
+
* const result = await sdk.content.get('61eca4746971e75c1fc670cd')
|
|
873
|
+
*/
|
|
874
|
+
service.get = async function (id, params) {
|
|
875
|
+
id = qik.utils.id(id);
|
|
876
|
+
params = params || {};
|
|
877
|
+
|
|
878
|
+
const { data } = await qik.api.get(`/content/${id}`, params);
|
|
879
|
+
return data;
|
|
880
|
+
};
|
|
881
|
+
|
|
882
|
+
service.getFromID = async function (id) {
|
|
883
|
+
return service.get(id);
|
|
884
|
+
};
|
|
885
|
+
|
|
886
|
+
/**
|
|
887
|
+
*
|
|
888
|
+
* Delete an item from the database
|
|
889
|
+
* @alias content.delete
|
|
890
|
+
* @param {String} id The id of the record we want to delete
|
|
891
|
+
* @example
|
|
892
|
+
* const result = await sdk.content.delete('61eca4746971e75c1fc670cd')
|
|
893
|
+
*/
|
|
894
|
+
service.delete = async function (id, input) {
|
|
895
|
+
id = qik.utils.id(id);
|
|
896
|
+
const { data } = await qik.api.delete(`/content/${id}`, input);
|
|
897
|
+
return data;
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
/**
|
|
901
|
+
*
|
|
902
|
+
* Restore a deleted item from the database
|
|
903
|
+
* @alias content.restore
|
|
904
|
+
* @param {String} id The id of the record we want to restore
|
|
905
|
+
* @example
|
|
906
|
+
* const result = await sdk.content.restore('61eca4746971e75c1fc670cd')
|
|
907
|
+
*/
|
|
908
|
+
service.restore = async function (id, input) {
|
|
909
|
+
id = qik.utils.id(id);
|
|
910
|
+
const { data } = await qik.api.get(`/content/${id}/restore`, input);
|
|
911
|
+
return data;
|
|
912
|
+
};
|
|
913
|
+
|
|
914
|
+
/**
|
|
915
|
+
*
|
|
916
|
+
* Retrieve an item from the database by providing it's 'slug'
|
|
917
|
+
* @alias content.getFromSlug
|
|
918
|
+
* @param {String} slug The slug id of the record we want to retrieve
|
|
919
|
+
* it must be provided as either `(type):(slug)`` or `(definition):(slug)`
|
|
920
|
+
* (if unsure use the `meta.abs` absolute slug property of the item you are wanting to retrieve).
|
|
921
|
+
* @example
|
|
922
|
+
* const result = await sdk.content.getFromSlug('article:how-to-get-started')
|
|
923
|
+
* const result = await sdk.content.getFromSlug('car:toyota-landcruiser')
|
|
924
|
+
* const result = await sdk.content.getFromSlug('article:toyota-landcruiser')
|
|
925
|
+
*/
|
|
926
|
+
service.getFromSlug = async function (slug) {
|
|
927
|
+
const { data } = await qik.api.get(`/content/slug/${slug}`);
|
|
928
|
+
return data;
|
|
929
|
+
};
|
|
930
|
+
|
|
931
|
+
// service.getFromSlug = async function(type, slug) {
|
|
932
|
+
// const { data } = await qik.api.get(`/content/${type}/slug/${slug}`);
|
|
933
|
+
// return data;
|
|
934
|
+
// }
|
|
935
|
+
|
|
936
|
+
// service.getFromExternalID = async function(type, externalID) {
|
|
937
|
+
// const { data } = await qik.api.get(`/content/${type}/external/${externalID}`);
|
|
938
|
+
// return data;
|
|
939
|
+
// }
|
|
940
|
+
|
|
941
|
+
return service;
|
|
942
|
+
}
|
|
943
|
+
</code></pre>
|
|
944
|
+
</article>
|
|
945
|
+
</section>
|
|
946
|
+
|
|
947
|
+
|
|
948
|
+
|
|
949
|
+
|
|
950
|
+
|
|
951
|
+
|
|
952
|
+
</div>
|
|
953
|
+
|
|
954
|
+
<br class="clear">
|
|
955
|
+
|
|
956
|
+
<footer>
|
|
957
|
+
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.11</a> on Mon Jul 13 2026 18:47:22 GMT+1000 (Australian Eastern Standard Time) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
|
|
958
|
+
</footer>
|
|
959
|
+
|
|
960
|
+
<script>prettyPrint();</script>
|
|
961
|
+
<script src="scripts/polyfill.js"></script>
|
|
962
|
+
<script src="scripts/linenumber.js"></script>
|
|
963
|
+
|
|
964
|
+
|
|
965
|
+
|
|
966
|
+
</body>
|
|
967
|
+
</html>
|