kuzzle 2.19.12 → 2.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/api/controllers/authController.d.ts +164 -0
- package/lib/api/controllers/authController.js +469 -654
- package/lib/api/controllers/baseController.d.ts +74 -0
- package/lib/api/controllers/baseController.js +169 -221
- package/lib/api/controllers/documentController.js +6 -8
- package/lib/api/funnel.js +4 -1
- package/lib/api/httpRoutes.js +6 -0
- package/lib/api/openapi/openApiGenerator.js +2 -2
- package/lib/api/request/kuzzleRequest.d.ts +3 -1
- package/lib/api/request/kuzzleRequest.js +32 -0
- package/lib/core/backend/backendController.js +2 -2
- package/lib/core/backend/backendPlugin.js +2 -2
- package/lib/core/network/protocols/httpwsProtocol.js +0 -12
- package/lib/core/plugin/pluginRepository.js +1 -1
- package/lib/core/plugin/pluginsManager.js +1 -1
- package/lib/core/security/index.js +1 -1
- package/lib/core/security/profileRepository.d.ts +14 -4
- package/lib/core/security/profileRepository.js +2 -2
- package/lib/core/security/roleRepository.js +1 -1
- package/lib/core/security/tokenRepository.d.ts +73 -0
- package/lib/core/security/tokenRepository.js +359 -460
- package/lib/core/security/userRepository.js +1 -1
- package/lib/core/shared/repository.d.ts +178 -0
- package/lib/core/shared/repository.js +365 -450
- package/lib/kerror/codes/7-security.json +6 -0
- package/lib/model/security/token.d.ts +2 -0
- package/lib/model/security/token.js +1 -0
- package/lib/service/storage/elasticsearch.js +4 -0
- package/lib/util/{inflector.d.ts → Inflector.d.ts} +5 -0
- package/lib/util/{inflector.js → Inflector.js} +12 -1
- package/package.json +11 -4
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/*
|
|
2
3
|
* Kuzzle, a backend software, self-hostable and ready to use
|
|
3
4
|
* to power modern apps
|
|
@@ -18,469 +19,383 @@
|
|
|
18
19
|
* See the License for the specific language governing permissions and
|
|
19
20
|
* limitations under the License.
|
|
20
21
|
*/
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
const cacheDbEnum = require("../cache/cacheDbEnum");
|
|
27
|
-
const kerror = require("../../kerror");
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* @class Repository
|
|
31
|
-
* @property {Kuzzle} kuzzle
|
|
32
|
-
* @property {string} index
|
|
33
|
-
* @property {number} ttl
|
|
34
|
-
* @property {?string} collection
|
|
35
|
-
* @property {function} ObjectConstructor
|
|
36
|
-
* @property {cacheDbEnum} cacheDb
|
|
37
|
-
* @property {Store} store
|
|
38
|
-
*/
|
|
39
|
-
class Repository {
|
|
40
|
-
/**
|
|
41
|
-
* @param {{cache: cacheDbEnum, store: Store}} [options]
|
|
42
|
-
* @constructor
|
|
43
|
-
*/
|
|
44
|
-
constructor({ cache = cacheDbEnum.INTERNAL, store = null } = {}) {
|
|
45
|
-
this.ttl = global.kuzzle.config.repositories.common.cacheTTL;
|
|
46
|
-
this.collection = null;
|
|
47
|
-
this.ObjectConstructor = null;
|
|
48
|
-
this.store = store;
|
|
49
|
-
this.index = store ? store.index : global.kuzzle.internalIndex.index;
|
|
50
|
-
this.cacheDb = cache;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/**
|
|
54
|
-
* @param {string} id
|
|
55
|
-
* @returns {Promise} resolves on a new ObjectConstructor()
|
|
56
|
-
*/
|
|
57
|
-
async loadOneFromDatabase(id) {
|
|
58
|
-
let response;
|
|
59
|
-
|
|
60
|
-
try {
|
|
61
|
-
response = await this.store.get(this.collection, id);
|
|
62
|
-
} catch (error) {
|
|
63
|
-
if (error.status === 404) {
|
|
64
|
-
throw kerror.get("services", "storage", "not_found", id);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
throw error;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
if (response._id) {
|
|
71
|
-
const dto = {};
|
|
72
|
-
|
|
73
|
-
if (response._source) {
|
|
74
|
-
Object.assign(dto, response._source, { _id: response._id });
|
|
75
|
-
} else {
|
|
76
|
-
Object.assign(dto, response);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return this.fromDTO(dto);
|
|
22
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
25
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
26
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
80
27
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
28
|
+
Object.defineProperty(o, k2, desc);
|
|
29
|
+
}) : (function(o, m, k, k2) {
|
|
30
|
+
if (k2 === undefined) k2 = k;
|
|
31
|
+
o[k2] = m[k];
|
|
32
|
+
}));
|
|
33
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
34
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
35
|
+
}) : function(o, v) {
|
|
36
|
+
o["default"] = v;
|
|
37
|
+
});
|
|
38
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
39
|
+
if (mod && mod.__esModule) return mod;
|
|
40
|
+
var result = {};
|
|
41
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
42
|
+
__setModuleDefault(result, mod);
|
|
43
|
+
return result;
|
|
44
|
+
};
|
|
45
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
46
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
|
+
};
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.Repository = void 0;
|
|
50
|
+
const cacheDbEnum_1 = __importDefault(require("../cache/cacheDbEnum"));
|
|
51
|
+
const kerror = __importStar(require("../../kerror"));
|
|
52
|
+
class Repository {
|
|
53
|
+
constructor({ cache = cacheDbEnum_1.default.INTERNAL, store = null } = {}) {
|
|
54
|
+
this.ttl = global.kuzzle.config.repositories.common.cacheTTL;
|
|
55
|
+
this.collection = null;
|
|
56
|
+
this.ObjectConstructor = null;
|
|
57
|
+
this.store = store;
|
|
58
|
+
this.index = store ? store.index : global.kuzzle.internalIndex.index;
|
|
59
|
+
this.cacheDb = cache;
|
|
95
60
|
}
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Scroll over a paginated search request
|
|
121
|
-
* @param {string} scrollId
|
|
122
|
-
* @param {string} [ttl]
|
|
123
|
-
*/
|
|
124
|
-
async scroll(scrollId, ttl) {
|
|
125
|
-
const response = await this.store.scroll(scrollId, ttl);
|
|
126
|
-
|
|
127
|
-
return this._formatSearchResults(response);
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
/**
|
|
131
|
-
* Loads an object from Cache. Returns a promise that resolves either to the
|
|
132
|
-
* retrieved object of null in case it is not found.
|
|
133
|
-
*
|
|
134
|
-
* The opts object currently accepts one optional parameter: key, which forces
|
|
135
|
-
* the cache key to fetch.
|
|
136
|
-
* In case the key is not provided, it defaults to repos/<index>/<collection>/<id>, i.e.: repos/%kuzzle/users/12
|
|
137
|
-
*
|
|
138
|
-
* @param {string} id - The id of the object to get
|
|
139
|
-
* @param {object} [options] - Optional options.
|
|
140
|
-
* @returns {Promise}
|
|
141
|
-
*/
|
|
142
|
-
async loadFromCache(id, options = {}) {
|
|
143
|
-
const key = options.key || this.getCacheKey(id);
|
|
144
|
-
let response;
|
|
145
|
-
|
|
146
|
-
try {
|
|
147
|
-
response = await global.kuzzle.ask(`core:cache:${this.cacheDb}:get`, key);
|
|
148
|
-
|
|
149
|
-
if (response === null) {
|
|
61
|
+
async loadOneFromDatabase(id) {
|
|
62
|
+
let response;
|
|
63
|
+
try {
|
|
64
|
+
response = await this.store.get(this.collection, id);
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (error.status === 404) {
|
|
68
|
+
throw kerror.get("services", "storage", "not_found", id);
|
|
69
|
+
}
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
72
|
+
if (response._id) {
|
|
73
|
+
const dto = {};
|
|
74
|
+
if (response._source) {
|
|
75
|
+
Object.assign(dto, response._source, { _id: response._id });
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
Object.assign(dto, response);
|
|
79
|
+
}
|
|
80
|
+
return this.fromDTO(dto);
|
|
81
|
+
}
|
|
150
82
|
return null;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return await this.fromDTO(Object.assign({}, JSON.parse(response)));
|
|
154
|
-
} catch (err) {
|
|
155
|
-
throw kerror.get("services", "cache", "read_failed", err.message);
|
|
156
83
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
*
|
|
172
|
-
* @param {string} id - The id of the object to get
|
|
173
|
-
* @param {object} [options] - Optional options.
|
|
174
|
-
* @returns {Promise}
|
|
175
|
-
*/
|
|
176
|
-
async load(id, options = {}) {
|
|
177
|
-
if (this.cacheDb === cacheDbEnum.NONE) {
|
|
178
|
-
return this.loadOneFromDatabase(id);
|
|
84
|
+
async loadMultiFromDatabase(ids) {
|
|
85
|
+
const { items } = await this.store.mGet(this.collection, ids);
|
|
86
|
+
if (items.length === 0) {
|
|
87
|
+
return [];
|
|
88
|
+
}
|
|
89
|
+
const promises = [];
|
|
90
|
+
for (const item of items) {
|
|
91
|
+
promises.push(this.fromDTO({
|
|
92
|
+
...item._source,
|
|
93
|
+
_id: item._id,
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
const objects = await Promise.all(promises);
|
|
97
|
+
return objects;
|
|
179
98
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (objectFromDatabase !== null) {
|
|
191
|
-
await this.persistToCache(objectFromDatabase);
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
return objectFromDatabase;
|
|
99
|
+
/**
|
|
100
|
+
* Search in database corresponding repository according to a query
|
|
101
|
+
*
|
|
102
|
+
* @param {object} searchBody
|
|
103
|
+
* @param {object} [options] - optional search arguments (from, size, scroll)
|
|
104
|
+
* @returns {Promise}
|
|
105
|
+
*/
|
|
106
|
+
async search(searchBody, options = {}) {
|
|
107
|
+
const response = await this.store.search(this.collection, searchBody, options);
|
|
108
|
+
return this.formatSearchResults(response);
|
|
195
109
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Persists the given object in the collection that is attached to the repository.
|
|
204
|
-
*
|
|
205
|
-
* @param {Profile|Role|User} object - The object to persist
|
|
206
|
-
* @param {object} [options] - The persistence options
|
|
207
|
-
* @returns {Promise}
|
|
208
|
-
*/
|
|
209
|
-
persistToDatabase(object, options = {}) {
|
|
210
|
-
const method = options.method || "createOrReplace";
|
|
211
|
-
|
|
212
|
-
if (method === "create") {
|
|
213
|
-
return this.store.create(
|
|
214
|
-
this.collection,
|
|
215
|
-
this.serializeToDatabase(object),
|
|
216
|
-
{ ...options, id: object._id }
|
|
217
|
-
);
|
|
110
|
+
/**
|
|
111
|
+
* Scroll over a paginated search request
|
|
112
|
+
*/
|
|
113
|
+
async scroll(scrollId, ttl) {
|
|
114
|
+
const response = await this.store.scroll(scrollId, ttl);
|
|
115
|
+
return this.formatSearchResults(response);
|
|
218
116
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Loads an object from Cache. Returns a promise that resolves either to the
|
|
119
|
+
* retrieved object of null in case it is not found.
|
|
120
|
+
*
|
|
121
|
+
* The opts object currently accepts one optional parameter: key, which forces
|
|
122
|
+
* the cache key to fetch.
|
|
123
|
+
* In case the key is not provided, it defaults to repos/<index>/<collection>/<id>, i.e.: repos/%kuzzle/users/12
|
|
124
|
+
*
|
|
125
|
+
* @param id - The id of the object to get
|
|
126
|
+
* @param options.key - Cache key.
|
|
127
|
+
*/
|
|
128
|
+
async loadFromCache(id, options = {}) {
|
|
129
|
+
const key = options.key || this.getCacheKey(id);
|
|
130
|
+
let response;
|
|
131
|
+
try {
|
|
132
|
+
response = await global.kuzzle.ask(`core:cache:${this.cacheDb}:get`, key);
|
|
133
|
+
if (response === null) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
return await this.fromDTO(Object.assign({}, JSON.parse(response)));
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
throw kerror.get("services", "cache", "read_failed", err.message);
|
|
140
|
+
}
|
|
242
141
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
142
|
+
/**
|
|
143
|
+
* Loads an object from Cache or from the Database if not available in Cache.
|
|
144
|
+
* Returns a promise that resolves either to the
|
|
145
|
+
* retrieved object of null in case it is not found.
|
|
146
|
+
*
|
|
147
|
+
* If the object is not found in Cache and found in the Database,
|
|
148
|
+
* it will be written to cache also.
|
|
149
|
+
*
|
|
150
|
+
* The opts object currently accepts one optional parameter: key, which forces
|
|
151
|
+
* the cache key to fetch.
|
|
152
|
+
* In case the key is not provided, it defaults to <collection>/id
|
|
153
|
+
* (e.g. users/12)
|
|
154
|
+
*
|
|
155
|
+
* @param id - The id of the object to get
|
|
156
|
+
* @param options.key - Optional cache key
|
|
157
|
+
*/
|
|
158
|
+
async load(id, options = {}) {
|
|
159
|
+
if (this.cacheDb === cacheDbEnum_1.default.NONE) {
|
|
160
|
+
return this.loadOneFromDatabase(id);
|
|
161
|
+
}
|
|
162
|
+
const object = await this.loadFromCache(id, options);
|
|
163
|
+
if (object === null) {
|
|
164
|
+
if (this.store === null) {
|
|
165
|
+
return null;
|
|
166
|
+
}
|
|
167
|
+
const objectFromDatabase = await this.loadOneFromDatabase(id);
|
|
168
|
+
if (objectFromDatabase !== null) {
|
|
169
|
+
await this.persistToCache(objectFromDatabase);
|
|
170
|
+
}
|
|
171
|
+
return objectFromDatabase;
|
|
172
|
+
}
|
|
173
|
+
await this.refreshCacheTTL(object);
|
|
174
|
+
return object;
|
|
246
175
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* Persists the given ObjectConstructor object in cache.
|
|
263
|
-
* The opts optional parameters currently accept 2 options:
|
|
264
|
-
* key: if provided, stores the object to the given key instead of the
|
|
265
|
-
* default one (<collection>/<id>)
|
|
266
|
-
* ttl: if provided, overrides the default ttl set on the repository for
|
|
267
|
-
* the current operation.
|
|
268
|
-
*
|
|
269
|
-
* @param {object} object - The object to persist
|
|
270
|
-
* @param {object} [options] - Optional options for the current operation
|
|
271
|
-
* @returns {Promise}
|
|
272
|
-
*/
|
|
273
|
-
async persistToCache(object, options = {}) {
|
|
274
|
-
const key = options.key || this.getCacheKey(object._id);
|
|
275
|
-
const value = JSON.stringify(this.serializeToCache(object));
|
|
276
|
-
const ttl = options.ttl !== undefined ? options.ttl : this.ttl;
|
|
277
|
-
|
|
278
|
-
await global.kuzzle.ask(`core:cache:${this.cacheDb}:store`, key, value, {
|
|
279
|
-
ttl,
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
return object;
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
/**
|
|
286
|
-
* Removes the object from the Cache Engine
|
|
287
|
-
* The opts optional parameters currently accepts only 1 option:
|
|
288
|
-
* key: if provided, removes the given key instead of the default one (<collection>/<id>)
|
|
289
|
-
*
|
|
290
|
-
* @param {string} id
|
|
291
|
-
* @param {object} [options] - optional options for the current operation
|
|
292
|
-
* @returns {Promise}
|
|
293
|
-
*/
|
|
294
|
-
deleteFromCache(id, options = {}) {
|
|
295
|
-
const key = options.key || this.getCacheKey(id);
|
|
296
|
-
|
|
297
|
-
return global.kuzzle.ask(`core:cache:${this.cacheDb}:del`, key);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* @param {object} object
|
|
302
|
-
* @param {object} [options] - optional options for the current operation
|
|
303
|
-
* @returns {Promise}
|
|
304
|
-
*/
|
|
305
|
-
refreshCacheTTL(object, options = {}) {
|
|
306
|
-
const key = options.key || this.getCacheKey(object._id);
|
|
307
|
-
let ttl;
|
|
308
|
-
|
|
309
|
-
if (options.ttl !== undefined) {
|
|
310
|
-
ttl = options.ttl;
|
|
311
|
-
} else if (object.ttl !== undefined) {
|
|
312
|
-
// if a TTL has been defined at the entry creation, we should
|
|
313
|
-
// use it
|
|
314
|
-
ttl = object.ttl;
|
|
315
|
-
} else {
|
|
316
|
-
ttl = this.ttl;
|
|
176
|
+
/**
|
|
177
|
+
* Persists the given object in the collection that is attached to the repository.
|
|
178
|
+
*
|
|
179
|
+
* @param object - The object to persist
|
|
180
|
+
* @param options.method -
|
|
181
|
+
* @returns {Promise}
|
|
182
|
+
*/
|
|
183
|
+
persistToDatabase(object, options = {}) {
|
|
184
|
+
const method = options.method || "createOrReplace";
|
|
185
|
+
if (method === "create") {
|
|
186
|
+
return this.store.create(this.collection, this.serializeToDatabase(object), { ...options, id: object._id });
|
|
187
|
+
}
|
|
188
|
+
return this.store[method](this.collection, object._id, this.serializeToDatabase(object), options);
|
|
317
189
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
190
|
+
/**
|
|
191
|
+
* Given an object with an id, delete it from the configured storage engines
|
|
192
|
+
*
|
|
193
|
+
* @param object - The object to delete
|
|
194
|
+
* @param options.key - if provided, removes the given key instead of the default one (<collection>/<id>)
|
|
195
|
+
*/
|
|
196
|
+
async delete(object, options = {}) {
|
|
197
|
+
const promises = [];
|
|
198
|
+
if (this.cacheDb !== cacheDbEnum_1.default.NONE) {
|
|
199
|
+
promises.push(this.deleteFromCache(object._id, options));
|
|
200
|
+
}
|
|
201
|
+
if (this.store) {
|
|
202
|
+
promises.push(this.deleteFromDatabase(object._id, options));
|
|
203
|
+
}
|
|
204
|
+
await Promise.all(promises);
|
|
321
205
|
}
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
*/
|
|
342
|
-
serializeToCache(object) {
|
|
343
|
-
return this.toDTO(object);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
/**
|
|
347
|
-
* Serializes the object before being persisted to the database.
|
|
348
|
-
*
|
|
349
|
-
* @param {object} object - The object to serialize
|
|
350
|
-
* @returns {object}
|
|
351
|
-
*/
|
|
352
|
-
serializeToDatabase(object) {
|
|
353
|
-
const dto = this.toDTO(object);
|
|
354
|
-
delete dto._id;
|
|
355
|
-
return dto;
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/**
|
|
359
|
-
* @param {string} id
|
|
360
|
-
*/
|
|
361
|
-
getCacheKey(id) {
|
|
362
|
-
return `repos/${this.index}/${this.collection}/${id}`;
|
|
363
|
-
}
|
|
364
|
-
|
|
365
|
-
/**
|
|
366
|
-
* @param {object} dto
|
|
367
|
-
* @returns {Promise<ObjectConstructor>}
|
|
368
|
-
*/
|
|
369
|
-
async fromDTO(dto) {
|
|
370
|
-
const o = new this.ObjectConstructor();
|
|
371
|
-
Object.assign(o, dto);
|
|
372
|
-
|
|
373
|
-
return o;
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* @param {ObjectConstructor} o
|
|
378
|
-
* @returns {object}
|
|
379
|
-
*/
|
|
380
|
-
toDTO(o) {
|
|
381
|
-
return Object.assign({}, o);
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Recursively delete all objects in repository with a scroll
|
|
386
|
-
*
|
|
387
|
-
* @param {object} options - ES options (refresh)
|
|
388
|
-
* @param {object} part
|
|
389
|
-
* @returns {Promise<integer>} total deleted objects
|
|
390
|
-
*/
|
|
391
|
-
async truncate(options) {
|
|
392
|
-
// Allows safe overrides, as _truncate is called recursively
|
|
393
|
-
return this._truncate(options);
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
/**
|
|
397
|
-
* Do not override this: this function calls itself.
|
|
398
|
-
* @private
|
|
399
|
-
*/
|
|
400
|
-
async _truncate(options, part = null) {
|
|
401
|
-
if (part === null) {
|
|
402
|
-
const objects = await this.search(
|
|
403
|
-
{},
|
|
404
|
-
{ refresh: options.refresh, scroll: "5s", size: 100 }
|
|
405
|
-
);
|
|
406
|
-
const deleted = await this._truncatePart(objects, options);
|
|
407
|
-
|
|
408
|
-
if (objects.hits.length < objects.total) {
|
|
409
|
-
const total = await this._truncate(options, {
|
|
410
|
-
fetched: objects.hits.length,
|
|
411
|
-
scrollId: objects.scrollId,
|
|
412
|
-
total: objects.total,
|
|
206
|
+
/**
|
|
207
|
+
* Delete repository from database according to its id
|
|
208
|
+
*/
|
|
209
|
+
deleteFromDatabase(id, options = {}) {
|
|
210
|
+
return this.store.delete(this.collection, id, options);
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Persists the given ObjectConstructor object in cache.
|
|
214
|
+
*
|
|
215
|
+
* @param object - The object to persist
|
|
216
|
+
* @param options.key - if provided, stores the object to the given key instead of the default one (<collection>/<id>)
|
|
217
|
+
* @param options.ttl - if provided, overrides the default ttl set on the repository for the current operation
|
|
218
|
+
*/
|
|
219
|
+
async persistToCache(object, options = {}) {
|
|
220
|
+
const key = options.key || this.getCacheKey(object._id);
|
|
221
|
+
const value = JSON.stringify(this.serializeToCache(object));
|
|
222
|
+
const ttl = options.ttl !== undefined ? options.ttl : this.ttl;
|
|
223
|
+
await global.kuzzle.ask(`core:cache:${this.cacheDb}:store`, key, value, {
|
|
224
|
+
ttl,
|
|
413
225
|
});
|
|
414
|
-
|
|
415
|
-
return deleted + total;
|
|
416
|
-
}
|
|
417
|
-
|
|
418
|
-
return deleted;
|
|
226
|
+
return object;
|
|
419
227
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
const total = await this._truncate(options, part);
|
|
430
|
-
return deleted + total;
|
|
228
|
+
/**
|
|
229
|
+
* Removes the object from the Cache Engine
|
|
230
|
+
*
|
|
231
|
+
* @param id
|
|
232
|
+
* @param options.key - if provided, stores the object to the given key instead of the default one (<collection>/<id>)
|
|
233
|
+
*/
|
|
234
|
+
async deleteFromCache(id, options = {}) {
|
|
235
|
+
const key = options.key || this.getCacheKey(id);
|
|
236
|
+
await global.kuzzle.ask(`core:cache:${this.cacheDb}:del`, key);
|
|
431
237
|
}
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
238
|
+
/**
|
|
239
|
+
* @param object
|
|
240
|
+
* @param options.key - if provided, stores the object to the given key instead of the default one (<collection>/<id>)
|
|
241
|
+
* @param options.ttl - if provided, overrides the default ttl set on the repository for the current operation
|
|
242
|
+
*/
|
|
243
|
+
refreshCacheTTL(object, options = {}) {
|
|
244
|
+
const key = options.key || this.getCacheKey(object._id);
|
|
245
|
+
let ttl;
|
|
246
|
+
if (options.ttl !== undefined) {
|
|
247
|
+
ttl = options.ttl;
|
|
248
|
+
}
|
|
249
|
+
else if (object.ttl !== undefined) {
|
|
250
|
+
// if a TTL has been defined at the entry creation, we should
|
|
251
|
+
// use it
|
|
252
|
+
ttl = object.ttl;
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
ttl = this.ttl;
|
|
256
|
+
}
|
|
257
|
+
if (ttl > 0) {
|
|
258
|
+
return global.kuzzle.ask(`core:cache:${this.cacheDb}:expire`, key, ttl);
|
|
259
|
+
}
|
|
260
|
+
return global.kuzzle.ask(`core:cache:${this.cacheDb}:persist`, key);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* @param object
|
|
264
|
+
* @param options.key - if provided, stores the object to the given key instead of the default one (<collection>/<id>)
|
|
265
|
+
*/
|
|
266
|
+
async expireFromCache(object, options = {}) {
|
|
267
|
+
const key = options.key || this.getCacheKey(object._id);
|
|
268
|
+
await global.kuzzle.ask(`core:cache:${this.cacheDb}:expire`, key, -1);
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Serializes the object before being persisted to cache.
|
|
272
|
+
*
|
|
273
|
+
* @param object - The object to serialize
|
|
274
|
+
*/
|
|
275
|
+
serializeToCache(object) {
|
|
276
|
+
return this.toDTO(object);
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Serializes the object before being persisted to the database.
|
|
280
|
+
*
|
|
281
|
+
* @param object - The object to serialize
|
|
282
|
+
*/
|
|
283
|
+
serializeToDatabase(object) {
|
|
284
|
+
const dto = this.toDTO(object);
|
|
285
|
+
delete dto._id;
|
|
286
|
+
return dto;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* @param {string} id
|
|
290
|
+
*/
|
|
291
|
+
getCacheKey(id) {
|
|
292
|
+
return `repos/${this.index}/${this.collection}/${id}`;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* @param {object} dto
|
|
296
|
+
* @returns {Promise<ObjectConstructor>}
|
|
297
|
+
*/
|
|
298
|
+
async fromDTO(dto) {
|
|
299
|
+
const o = new this.ObjectConstructor();
|
|
300
|
+
Object.assign(o, dto);
|
|
301
|
+
return o;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* @param {ObjectConstructor} o
|
|
305
|
+
* @returns {object}
|
|
306
|
+
*/
|
|
307
|
+
toDTO(o) {
|
|
308
|
+
return Object.assign({}, o);
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Recursively delete all objects in repository with a scroll
|
|
312
|
+
*
|
|
313
|
+
* @param {object} options - ES options (refresh)
|
|
314
|
+
* @param {object} part
|
|
315
|
+
* @returns {Promise<integer>} total deleted objects
|
|
316
|
+
*/
|
|
317
|
+
async truncate(options) {
|
|
318
|
+
// Allows safe overrides, as _truncate is called recursively
|
|
319
|
+
return this._truncate(options);
|
|
320
|
+
}
|
|
321
|
+
/**
|
|
322
|
+
* Do not override this: this function calls itself.
|
|
323
|
+
*/
|
|
324
|
+
async _truncate(options, part = null) {
|
|
325
|
+
if (part === null) {
|
|
326
|
+
const objects = await this.search({}, { refresh: options.refresh, scroll: "5s", size: 100 });
|
|
327
|
+
const deleted = await this.truncatePart(objects, options);
|
|
328
|
+
if (objects.hits.length < objects.total) {
|
|
329
|
+
const total = await this._truncate(options, {
|
|
330
|
+
fetched: objects.hits.length,
|
|
331
|
+
scrollId: objects.scrollId,
|
|
332
|
+
total: objects.total,
|
|
333
|
+
});
|
|
334
|
+
return deleted + total;
|
|
335
|
+
}
|
|
336
|
+
return deleted;
|
|
337
|
+
}
|
|
338
|
+
const objects = await this.scroll(part.scrollId, "5s");
|
|
339
|
+
const deleted = await this.truncatePart(objects, options);
|
|
340
|
+
part.fetched += objects.hits.length;
|
|
341
|
+
if (part.fetched < part.total) {
|
|
342
|
+
part.scrollId = objects.scrollId;
|
|
343
|
+
const total = await this._truncate(options, part);
|
|
344
|
+
return deleted + total;
|
|
345
|
+
}
|
|
346
|
+
return deleted;
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* @param {Array} objects
|
|
350
|
+
* @param {object} options
|
|
351
|
+
* @returns {Promise<integer>} count of deleted objects
|
|
352
|
+
*/
|
|
353
|
+
async truncatePart(objects, options) {
|
|
354
|
+
const promises = [];
|
|
355
|
+
const processObject = async (object) => {
|
|
356
|
+
// profile and role repositories have protected objects, we can't delete
|
|
357
|
+
// them
|
|
358
|
+
const protectedObjects = ["profiles", "roles"].indexOf(this.collection) !== -1
|
|
359
|
+
? ["admin", "default", "anonymous"]
|
|
360
|
+
: [];
|
|
361
|
+
if (protectedObjects.indexOf(object._id) !== -1) {
|
|
362
|
+
return 0;
|
|
363
|
+
}
|
|
364
|
+
const loaded = await this.load(object._id);
|
|
365
|
+
await this.delete(loaded, options);
|
|
366
|
+
return 1;
|
|
367
|
+
};
|
|
368
|
+
for (const hit of objects.hits) {
|
|
369
|
+
promises.push(processObject(hit));
|
|
370
|
+
}
|
|
371
|
+
const results = await Promise.all(promises);
|
|
372
|
+
return results.reduce((total, deleted) => total + deleted, 0);
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Given a raw search response from ES, returns a {total: int, hits: []} object
|
|
376
|
+
* @param {object} raw
|
|
377
|
+
* @returns {Promise<object>}
|
|
378
|
+
* @private
|
|
379
|
+
*/
|
|
380
|
+
async formatSearchResults(raw) {
|
|
381
|
+
const result = {
|
|
382
|
+
aggregations: raw.aggregations,
|
|
383
|
+
hits: [],
|
|
384
|
+
scrollId: raw.scrollId,
|
|
385
|
+
total: raw.total,
|
|
386
|
+
};
|
|
387
|
+
if (raw.hits && raw.hits.length > 0) {
|
|
388
|
+
const promises = [];
|
|
389
|
+
for (const hit of raw.hits) {
|
|
390
|
+
promises.push(this.fromDTO({
|
|
391
|
+
...hit._source,
|
|
392
|
+
_id: hit._id,
|
|
393
|
+
}));
|
|
394
|
+
}
|
|
395
|
+
result.hits = await Promise.all(promises);
|
|
396
|
+
}
|
|
397
|
+
return result;
|
|
480
398
|
}
|
|
481
|
-
|
|
482
|
-
return result;
|
|
483
|
-
}
|
|
484
399
|
}
|
|
485
|
-
|
|
486
|
-
|
|
400
|
+
exports.Repository = Repository;
|
|
401
|
+
//# sourceMappingURL=repository.js.map
|