kuzzle 2.20.2 → 2.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/api/controllers/debugController.d.ts +2 -27
- package/lib/api/controllers/debugController.js +8 -182
- package/lib/api/controllers/documentController.js +122 -10
- package/lib/api/request/kuzzleRequest.d.ts +8 -0
- package/lib/api/request/kuzzleRequest.js +12 -0
- package/lib/cluster/idCardHandler.js +19 -6
- package/lib/cluster/node.js +18 -1
- package/lib/cluster/protobuf/sync.proto +5 -0
- package/lib/cluster/publisher.js +10 -0
- package/lib/cluster/subscriber.js +8 -1
- package/lib/cluster/workers/IDCardRenewer.js +23 -26
- package/lib/config/default.config.js +1 -0
- package/lib/core/debug/kuzzleDebugger.d.ts +45 -0
- package/lib/core/debug/kuzzleDebugger.js +205 -0
- package/lib/core/storage/clientAdapter.js +4 -2
- package/lib/kuzzle/dumpGenerator.js +1 -1
- package/lib/kuzzle/kuzzle.js +3 -0
- package/lib/service/storage/elasticsearch.js +46 -36
- package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.d.ts +15 -3
- package/lib/types/events/EventGenericDocument.d.ts +21 -1
- package/package.json +1 -1
- package/lib/types/DebugModule.d.ts +0 -24
- package/lib/types/DebugModule.js +0 -39
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const { isMainThread, parentPort } = require("worker_threads");
|
|
4
3
|
const Redis = require("../../service/cache/redis");
|
|
5
4
|
|
|
6
5
|
class IDCardRenewer {
|
|
7
6
|
constructor() {
|
|
8
|
-
this.parentPort = parentPort;
|
|
9
7
|
this.redis = null;
|
|
10
8
|
this.refreshTimer = null;
|
|
11
9
|
this.nodeIdKey = null;
|
|
@@ -50,7 +48,7 @@ class IDCardRenewer {
|
|
|
50
48
|
}
|
|
51
49
|
|
|
52
50
|
// Notify that the worker is running and updating the ID Card
|
|
53
|
-
|
|
51
|
+
process.send({ initialized: true });
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
async initRedis(config, name) {
|
|
@@ -73,13 +71,13 @@ class IDCardRenewer {
|
|
|
73
71
|
// => this node is too slow, we need to remove it from the cluster
|
|
74
72
|
if (refreshed === 0) {
|
|
75
73
|
await this.dispose();
|
|
76
|
-
|
|
74
|
+
process.send({
|
|
77
75
|
error: "Node too slow: ID card expired",
|
|
78
76
|
});
|
|
79
77
|
}
|
|
80
78
|
} catch (error) {
|
|
81
79
|
await this.dispose();
|
|
82
|
-
|
|
80
|
+
process.send({
|
|
83
81
|
error: `Failed to refresh ID Card: ${error.message}`,
|
|
84
82
|
});
|
|
85
83
|
}
|
|
@@ -112,26 +110,25 @@ class IDCardRenewer {
|
|
|
112
110
|
}
|
|
113
111
|
}
|
|
114
112
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
}
|
|
113
|
+
const idCardRenewer = new IDCardRenewer();
|
|
114
|
+
|
|
115
|
+
process.on("message", async (message) => {
|
|
116
|
+
if (message.action === "start") {
|
|
117
|
+
// Simulate basic global Kuzzle Context
|
|
118
|
+
global.kuzzle = { ...message.kuzzle };
|
|
119
|
+
global.kuzzle.log = {
|
|
120
|
+
debug: console.debug, // eslint-disable-line no-console
|
|
121
|
+
error: console.error, // eslint-disable-line no-console
|
|
122
|
+
info: console.info, // eslint-disable-line no-console
|
|
123
|
+
warn: console.warn, // eslint-disable-line no-console
|
|
124
|
+
};
|
|
125
|
+
// Should never throw
|
|
126
|
+
await idCardRenewer.init(message);
|
|
127
|
+
} else if (message.action === "dispose") {
|
|
128
|
+
// Should never throw
|
|
129
|
+
await idCardRenewer.dispose();
|
|
130
|
+
process.exit(0);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
136
133
|
|
|
137
134
|
module.exports = { IDCardRenewer };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { JSONObject } from "kuzzle-sdk";
|
|
2
|
+
export declare class KuzzleDebugger {
|
|
3
|
+
private inspector;
|
|
4
|
+
private debuggerStatus;
|
|
5
|
+
/**
|
|
6
|
+
* Map<eventName, Set<connectionId>>
|
|
7
|
+
*/
|
|
8
|
+
private events;
|
|
9
|
+
init(): Promise<void>;
|
|
10
|
+
registerAsks(): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Connect the debugger
|
|
13
|
+
*/
|
|
14
|
+
enable(): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Disconnect the debugger and clears all the events listeners
|
|
17
|
+
*/
|
|
18
|
+
disable(): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Trigger action from debugger directly following the Chrome Debug Protocol
|
|
21
|
+
* See: https://chromedevtools.github.io/devtools-protocol/v8/
|
|
22
|
+
*/
|
|
23
|
+
post(method: string, params?: JSONObject): Promise<JSONObject>;
|
|
24
|
+
/**
|
|
25
|
+
* Make the websocket connection listen and receive events from Chrome Debug Protocol
|
|
26
|
+
* See events from: https://chromedevtools.github.io/devtools-protocol/v8/
|
|
27
|
+
*/
|
|
28
|
+
addListener(event: string, connectionId: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Remove the websocket connection from the events" listeners
|
|
31
|
+
*/
|
|
32
|
+
removeListener(event: string, connectionId: string): Promise<void>;
|
|
33
|
+
/**
|
|
34
|
+
* Execute a method using the Chrome Debug Protocol
|
|
35
|
+
* @param method Chrome Debug Protocol method to execute
|
|
36
|
+
* @param params
|
|
37
|
+
* @returns
|
|
38
|
+
*/
|
|
39
|
+
private inspectorPost;
|
|
40
|
+
/**
|
|
41
|
+
* Sends a direct notification to a websocket connection without having to listen to a specific room
|
|
42
|
+
*/
|
|
43
|
+
private notifyConnection;
|
|
44
|
+
private notifyGlobalListeners;
|
|
45
|
+
}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.KuzzleDebugger = void 0;
|
|
30
|
+
const inspector_1 = __importDefault(require("inspector"));
|
|
31
|
+
const kerror = __importStar(require("../../kerror"));
|
|
32
|
+
const get_1 = __importDefault(require("lodash/get"));
|
|
33
|
+
const DEBUGGER_EVENT = "kuzzle-debugger-event";
|
|
34
|
+
class KuzzleDebugger {
|
|
35
|
+
constructor() {
|
|
36
|
+
this.debuggerStatus = false;
|
|
37
|
+
/**
|
|
38
|
+
* Map<eventName, Set<connectionId>>
|
|
39
|
+
*/
|
|
40
|
+
this.events = new Map();
|
|
41
|
+
}
|
|
42
|
+
async init() {
|
|
43
|
+
this.inspector = new inspector_1.default.Session();
|
|
44
|
+
// Remove connection id from the list of listeners for each event
|
|
45
|
+
global.kuzzle.on("connection:remove", (connectionId) => {
|
|
46
|
+
if (!this.debuggerStatus) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
for (const listener of this.events.values()) {
|
|
50
|
+
listener.delete(connectionId);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
this.inspector.on("inspectorNotification", async (payload) => {
|
|
54
|
+
if (!this.debuggerStatus) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
await this.notifyGlobalListeners(payload.method, payload);
|
|
58
|
+
const listeners = this.events.get(payload.method);
|
|
59
|
+
if (!listeners) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
const promises = [];
|
|
63
|
+
for (const connectionId of listeners) {
|
|
64
|
+
promises.push(this.notifyConnection(connectionId, DEBUGGER_EVENT, {
|
|
65
|
+
event: payload.method,
|
|
66
|
+
result: payload,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
// No need to catch, notify is already try-catched
|
|
70
|
+
await Promise.all(promises);
|
|
71
|
+
});
|
|
72
|
+
await this.registerAsks();
|
|
73
|
+
}
|
|
74
|
+
async registerAsks() {
|
|
75
|
+
global.kuzzle.onAsk("core:debugger:enable", () => this.enable());
|
|
76
|
+
global.kuzzle.onAsk("core:debugger:disable", () => this.disable());
|
|
77
|
+
global.kuzzle.onAsk("core:debugger:post", (method, params) => this.post(method, params));
|
|
78
|
+
global.kuzzle.onAsk("core:debugger:isEnabled", () => this.debuggerStatus);
|
|
79
|
+
global.kuzzle.onAsk("core:debugger:removeListener", (event, connectionId) => this.removeListener(event, connectionId));
|
|
80
|
+
global.kuzzle.onAsk("core:debugger:addListener", (event, connectionId) => this.addListener(event, connectionId));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Connect the debugger
|
|
84
|
+
*/
|
|
85
|
+
async enable() {
|
|
86
|
+
if (this.debuggerStatus) {
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
this.inspector.connect();
|
|
90
|
+
this.debuggerStatus = true;
|
|
91
|
+
await global.kuzzle.ask("cluster:node:preventEviction", true);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Disconnect the debugger and clears all the events listeners
|
|
95
|
+
*/
|
|
96
|
+
async disable() {
|
|
97
|
+
if (!this.debuggerStatus) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
this.inspector.disconnect();
|
|
101
|
+
this.debuggerStatus = false;
|
|
102
|
+
await global.kuzzle.ask("cluster:node:preventEviction", false);
|
|
103
|
+
this.events.clear();
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Trigger action from debugger directly following the Chrome Debug Protocol
|
|
107
|
+
* See: https://chromedevtools.github.io/devtools-protocol/v8/
|
|
108
|
+
*/
|
|
109
|
+
async post(method, params = {}) {
|
|
110
|
+
if (!this.debuggerStatus) {
|
|
111
|
+
throw kerror.get("core", "debugger", "not_enabled");
|
|
112
|
+
}
|
|
113
|
+
if (!(0, get_1.default)(global.kuzzle.config, "security.debug.native_debug_protocol")) {
|
|
114
|
+
throw kerror.get("core", "debugger", "native_debug_protocol_usage_denied");
|
|
115
|
+
}
|
|
116
|
+
// Always disable report progress because this params causes a segfault.
|
|
117
|
+
// The reason this happens is because the inspector is running inside the same thread
|
|
118
|
+
// as the Kuzzle Process and reportProgress forces the inspector to send events
|
|
119
|
+
// to the main thread, while it is being inspected by the HeapProfiler, which causes javascript code
|
|
120
|
+
// to be executed as the HeapProfiler is running, which causes a segfault.
|
|
121
|
+
// See: https://github.com/nodejs/node/issues/44634
|
|
122
|
+
params.reportProgress = false;
|
|
123
|
+
return this.inspectorPost(method, params);
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Make the websocket connection listen and receive events from Chrome Debug Protocol
|
|
127
|
+
* See events from: https://chromedevtools.github.io/devtools-protocol/v8/
|
|
128
|
+
*/
|
|
129
|
+
async addListener(event, connectionId) {
|
|
130
|
+
if (!this.debuggerStatus) {
|
|
131
|
+
throw kerror.get("core", "debugger", "not_enabled");
|
|
132
|
+
}
|
|
133
|
+
let listeners = this.events.get(event);
|
|
134
|
+
if (!listeners) {
|
|
135
|
+
listeners = new Set();
|
|
136
|
+
this.events.set(event, listeners);
|
|
137
|
+
}
|
|
138
|
+
listeners.add(connectionId);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Remove the websocket connection from the events" listeners
|
|
142
|
+
*/
|
|
143
|
+
async removeListener(event, connectionId) {
|
|
144
|
+
if (!this.debuggerStatus) {
|
|
145
|
+
throw kerror.get("core", "debugger", "not_enabled");
|
|
146
|
+
}
|
|
147
|
+
const listeners = this.events.get(event);
|
|
148
|
+
if (listeners) {
|
|
149
|
+
listeners.delete(connectionId);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Execute a method using the Chrome Debug Protocol
|
|
154
|
+
* @param method Chrome Debug Protocol method to execute
|
|
155
|
+
* @param params
|
|
156
|
+
* @returns
|
|
157
|
+
*/
|
|
158
|
+
async inspectorPost(method, params) {
|
|
159
|
+
if (!this.debuggerStatus) {
|
|
160
|
+
throw kerror.get("core", "debugger", "not_enabled");
|
|
161
|
+
}
|
|
162
|
+
let resolve;
|
|
163
|
+
const promise = new Promise((res) => {
|
|
164
|
+
resolve = res;
|
|
165
|
+
});
|
|
166
|
+
this.inspector.post(method, params, (err, res) => {
|
|
167
|
+
if (err) {
|
|
168
|
+
resolve({
|
|
169
|
+
error: JSON.stringify(Object.getOwnPropertyDescriptors(err)),
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
resolve(res);
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
return promise;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Sends a direct notification to a websocket connection without having to listen to a specific room
|
|
180
|
+
*/
|
|
181
|
+
async notifyConnection(connectionId, event, payload) {
|
|
182
|
+
global.kuzzle.entryPoint._notify({
|
|
183
|
+
channels: [event],
|
|
184
|
+
connectionId,
|
|
185
|
+
payload,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
async notifyGlobalListeners(event, payload) {
|
|
189
|
+
const listeners = this.events.get("*");
|
|
190
|
+
if (!listeners) {
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const promises = [];
|
|
194
|
+
for (const connectionId of listeners) {
|
|
195
|
+
promises.push(this.notifyConnection(connectionId, DEBUGGER_EVENT, {
|
|
196
|
+
event,
|
|
197
|
+
result: payload,
|
|
198
|
+
}));
|
|
199
|
+
}
|
|
200
|
+
// No need to catch, notify is already try-catched
|
|
201
|
+
await Promise.all(promises);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
exports.KuzzleDebugger = KuzzleDebugger;
|
|
205
|
+
//# sourceMappingURL=kuzzleDebugger.js.map
|
|
@@ -175,10 +175,12 @@ class ClientAdapter {
|
|
|
175
175
|
/**
|
|
176
176
|
* Populates the index cache with existing index/collection.
|
|
177
177
|
* Also checks for duplicated index names.
|
|
178
|
-
*
|
|
179
|
-
* @returns {Promise}
|
|
180
178
|
*/
|
|
181
179
|
async populateCache() {
|
|
180
|
+
if (global.kuzzle.config.services.storageEngine.generateMissingAliases) {
|
|
181
|
+
await this.client.generateMissingAliases();
|
|
182
|
+
}
|
|
183
|
+
|
|
182
184
|
const schema = await this.client.getSchema();
|
|
183
185
|
|
|
184
186
|
for (const [index, collections] of Object.entries(schema)) {
|
|
@@ -228,7 +228,7 @@ class DumpGenerator {
|
|
|
228
228
|
while (dumps.length >= config.history.reports) {
|
|
229
229
|
const dir = dumps.shift().path;
|
|
230
230
|
|
|
231
|
-
fs.
|
|
231
|
+
fs.rmdirSync(dir, { recursive: true });
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
for (let i = 0; i < dumps.length - config.history.coredump; i++) {
|
package/lib/kuzzle/kuzzle.js
CHANGED
|
@@ -80,6 +80,7 @@ const package_json_1 = require("../../package.json");
|
|
|
80
80
|
const name_generator_1 = require("../util/name-generator");
|
|
81
81
|
const openapi_1 = require("../api/openapi");
|
|
82
82
|
const crypto_1 = require("../util/crypto");
|
|
83
|
+
const kuzzleDebugger_1 = require("../core/debug/kuzzleDebugger");
|
|
83
84
|
exports.BACKEND_IMPORT_KEY = "backend:init:import";
|
|
84
85
|
let _kuzzle = null;
|
|
85
86
|
Reflect.defineProperty(global, "kuzzle", {
|
|
@@ -119,6 +120,7 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
|
|
|
119
120
|
this.dumpGenerator = new dumpGenerator_1.default();
|
|
120
121
|
this.vault = null;
|
|
121
122
|
this.asyncStore = new asyncStore_1.default();
|
|
123
|
+
this.debugger = new kuzzleDebugger_1.KuzzleDebugger();
|
|
122
124
|
this.version = package_json_1.version;
|
|
123
125
|
this.importTypes = {
|
|
124
126
|
fixtures: this.importFixtures.bind(this),
|
|
@@ -146,6 +148,7 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
|
|
|
146
148
|
regExpEngine: this.config.realtime.pcreSupport ? "js" : "re2",
|
|
147
149
|
seed: this.config.internal.hash.seed,
|
|
148
150
|
});
|
|
151
|
+
await this.debugger.init();
|
|
149
152
|
await new cacheEngine_1.default().init();
|
|
150
153
|
await new storageEngine_1.default().init();
|
|
151
154
|
await new realtime_1.default().init();
|
|
@@ -681,7 +681,7 @@ class ElasticSearch extends Service {
|
|
|
681
681
|
index,
|
|
682
682
|
collection,
|
|
683
683
|
content,
|
|
684
|
-
{ id, refresh, userId = null } = {}
|
|
684
|
+
{ id, refresh, userId = null, injectKuzzleMeta = true } = {}
|
|
685
685
|
) {
|
|
686
686
|
assertIsObject(content);
|
|
687
687
|
|
|
@@ -697,12 +697,14 @@ class ElasticSearch extends Service {
|
|
|
697
697
|
assertWellFormedRefresh(esRequest);
|
|
698
698
|
|
|
699
699
|
// Add metadata
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
700
|
+
if (injectKuzzleMeta) {
|
|
701
|
+
esRequest.body._kuzzle_info = {
|
|
702
|
+
author: getKuid(userId),
|
|
703
|
+
createdAt: Date.now(),
|
|
704
|
+
updatedAt: null,
|
|
705
|
+
updater: null,
|
|
706
|
+
};
|
|
707
|
+
}
|
|
706
708
|
|
|
707
709
|
debug("Create document: %o", esRequest);
|
|
708
710
|
|
|
@@ -789,7 +791,7 @@ class ElasticSearch extends Service {
|
|
|
789
791
|
collection,
|
|
790
792
|
id,
|
|
791
793
|
content,
|
|
792
|
-
{ refresh, userId = null, retryOnConflict } = {}
|
|
794
|
+
{ refresh, userId = null, retryOnConflict, injectKuzzleMeta = true } = {}
|
|
793
795
|
) {
|
|
794
796
|
const esRequest = {
|
|
795
797
|
_source: true,
|
|
@@ -804,11 +806,13 @@ class ElasticSearch extends Service {
|
|
|
804
806
|
assertNoRouting(esRequest);
|
|
805
807
|
assertWellFormedRefresh(esRequest);
|
|
806
808
|
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
809
|
+
if (injectKuzzleMeta) {
|
|
810
|
+
// Add metadata
|
|
811
|
+
esRequest.body.doc._kuzzle_info = {
|
|
812
|
+
updatedAt: Date.now(),
|
|
813
|
+
updater: getKuid(userId),
|
|
814
|
+
};
|
|
815
|
+
}
|
|
812
816
|
|
|
813
817
|
debug("Update document: %o", esRequest);
|
|
814
818
|
|
|
@@ -841,7 +845,13 @@ class ElasticSearch extends Service {
|
|
|
841
845
|
collection,
|
|
842
846
|
id,
|
|
843
847
|
content,
|
|
844
|
-
{
|
|
848
|
+
{
|
|
849
|
+
defaultValues = {},
|
|
850
|
+
refresh,
|
|
851
|
+
userId = null,
|
|
852
|
+
retryOnConflict,
|
|
853
|
+
injectKuzzleMeta = true,
|
|
854
|
+
} = {}
|
|
845
855
|
) {
|
|
846
856
|
const esRequest = {
|
|
847
857
|
_source: true,
|
|
@@ -863,14 +873,16 @@ class ElasticSearch extends Service {
|
|
|
863
873
|
const user = getKuid(userId);
|
|
864
874
|
const now = Date.now();
|
|
865
875
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
876
|
+
if (injectKuzzleMeta) {
|
|
877
|
+
esRequest.body.doc._kuzzle_info = {
|
|
878
|
+
updatedAt: now,
|
|
879
|
+
updater: user,
|
|
880
|
+
};
|
|
881
|
+
esRequest.body.upsert._kuzzle_info = {
|
|
882
|
+
author: user,
|
|
883
|
+
createdAt: now,
|
|
884
|
+
};
|
|
885
|
+
}
|
|
874
886
|
|
|
875
887
|
debug("Upsert document: %o", esRequest);
|
|
876
888
|
|
|
@@ -904,7 +916,7 @@ class ElasticSearch extends Service {
|
|
|
904
916
|
collection,
|
|
905
917
|
id,
|
|
906
918
|
content,
|
|
907
|
-
{ refresh, userId = null } = {}
|
|
919
|
+
{ refresh, userId = null, injectKuzzleMeta = true } = {}
|
|
908
920
|
) {
|
|
909
921
|
const alias = this._getAlias(index, collection);
|
|
910
922
|
const esRequest = {
|
|
@@ -917,13 +929,15 @@ class ElasticSearch extends Service {
|
|
|
917
929
|
assertNoRouting(esRequest);
|
|
918
930
|
assertWellFormedRefresh(esRequest);
|
|
919
931
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
932
|
+
if (injectKuzzleMeta) {
|
|
933
|
+
// Add metadata
|
|
934
|
+
esRequest.body._kuzzle_info = {
|
|
935
|
+
author: getKuid(userId),
|
|
936
|
+
createdAt: Date.now(),
|
|
937
|
+
updatedAt: Date.now(),
|
|
938
|
+
updater: getKuid(userId),
|
|
939
|
+
};
|
|
940
|
+
}
|
|
927
941
|
|
|
928
942
|
try {
|
|
929
943
|
const { body: exists } = await this._client.exists({ id, index: alias });
|
|
@@ -1894,10 +1908,6 @@ class ElasticSearch extends Service {
|
|
|
1894
1908
|
* @returns {Object.<String, String[]>} Object<index, collections>
|
|
1895
1909
|
*/
|
|
1896
1910
|
async getSchema() {
|
|
1897
|
-
// This check avoids a breaking change for those who were using Kuzzle before
|
|
1898
|
-
// alias attribution for each indice was the standard ('auto-version')
|
|
1899
|
-
await this._ensureAliasConsistency();
|
|
1900
|
-
|
|
1901
1911
|
let body;
|
|
1902
1912
|
try {
|
|
1903
1913
|
({ body } = await this._client.cat.aliases({ format: "json" }));
|
|
@@ -3044,9 +3054,9 @@ class ElasticSearch extends Service {
|
|
|
3044
3054
|
* When the latter is missing, create one based on the indice name.
|
|
3045
3055
|
*
|
|
3046
3056
|
* This check avoids a breaking change for those who were using Kuzzle before
|
|
3047
|
-
* alias attribution for each indice turned into a standard (
|
|
3057
|
+
* alias attribution for each indice turned into a standard (appear in 2.14.0).
|
|
3048
3058
|
*/
|
|
3049
|
-
async
|
|
3059
|
+
async generateMissingAliases() {
|
|
3050
3060
|
try {
|
|
3051
3061
|
const { body } = await this._client.cat.indices({ format: "json" });
|
|
3052
3062
|
const indices = body.map(({ index: indice }) => indice);
|
|
@@ -318,9 +318,21 @@ export type StorageEngineElasticsearch = {
|
|
|
318
318
|
};
|
|
319
319
|
};
|
|
320
320
|
};
|
|
321
|
-
maxScrollDuration:
|
|
321
|
+
maxScrollDuration: string;
|
|
322
322
|
defaults: {
|
|
323
|
-
onUpdateConflictRetries:
|
|
324
|
-
scrollTTL:
|
|
323
|
+
onUpdateConflictRetries: number;
|
|
324
|
+
scrollTTL: string;
|
|
325
325
|
};
|
|
326
|
+
/**
|
|
327
|
+
* If true, Kuzzle will generate aliases for collections that don't have one.
|
|
328
|
+
*
|
|
329
|
+
* Typically, if an indice named `&platform.devices` does not have an alias
|
|
330
|
+
* named `@&platform.devices` and pointing on the indice then it will be generated
|
|
331
|
+
* even if another alias already exists on the indice.
|
|
332
|
+
*
|
|
333
|
+
* This option should be true only for retro-compatibility with Kuzzle < 2.14.0
|
|
334
|
+
*
|
|
335
|
+
* Also see https://github.com/kuzzleio/kuzzle/pull/2117
|
|
336
|
+
*/
|
|
337
|
+
generateMissingAliases: boolean;
|
|
326
338
|
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { KuzzleRequest, KDocument, JSONObject } from "../../../";
|
|
1
|
+
import { KuzzleRequest, KDocument, JSONObject, PipeEventHandler } from "../../../";
|
|
2
2
|
/**
|
|
3
3
|
* Events with documents only having the `_id`
|
|
4
4
|
*/
|
|
@@ -23,4 +23,24 @@ export type EventGenericDocumentAfterWrite<KDocumentContent = JSONObject> = Even
|
|
|
23
23
|
export type EventGenericDocumentBeforeUpdate<KDocumentContent = JSONObject> = EventGenericDocument<"beforeUpdate", KDocumentContent>;
|
|
24
24
|
export type EventGenericDocumentAfterUpdate<KDocumentContent = JSONObject> = EventGenericDocument<"afterUpdate", KDocumentContent>;
|
|
25
25
|
export type EventGenericDocumentAfterGet<KDocumentContent = JSONObject> = EventGenericDocument<"afterGet", KDocumentContent>;
|
|
26
|
+
export type EventGenericDocumentInjectMetadata = {
|
|
27
|
+
name: `generic:document:injectMetadata`;
|
|
28
|
+
args: [
|
|
29
|
+
{
|
|
30
|
+
/**
|
|
31
|
+
* Kuzzle Request that triggered the event
|
|
32
|
+
*/
|
|
33
|
+
request: KuzzleRequest;
|
|
34
|
+
/**
|
|
35
|
+
* Metadata of the document
|
|
36
|
+
*/
|
|
37
|
+
metadata: JSONObject;
|
|
38
|
+
/**
|
|
39
|
+
* Default metadata of the document.
|
|
40
|
+
* Only used when calling document:upsert.
|
|
41
|
+
*/
|
|
42
|
+
defaultMetadata?: JSONObject;
|
|
43
|
+
}
|
|
44
|
+
];
|
|
45
|
+
} & PipeEventHandler;
|
|
26
46
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kuzzle",
|
|
3
3
|
"author": "The Kuzzle Team <support@kuzzle.io>",
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.21.0",
|
|
5
5
|
"description": "Kuzzle is an open-source solution that handles all the data management through a secured API, with a large choice of protocols.",
|
|
6
6
|
"bin": "bin/start-kuzzle-server",
|
|
7
7
|
"scripts": {
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/// <reference types="node" />
|
|
2
|
-
/// <reference types="node" />
|
|
3
|
-
import EventEmitter from "events";
|
|
4
|
-
import Inspector from "inspector";
|
|
5
|
-
export type DebugModuleOptions = {
|
|
6
|
-
methods?: string[];
|
|
7
|
-
events?: string[];
|
|
8
|
-
};
|
|
9
|
-
export declare abstract class DebugModule extends EventEmitter {
|
|
10
|
-
name: string;
|
|
11
|
-
methods: string[];
|
|
12
|
-
events: string[];
|
|
13
|
-
/**
|
|
14
|
-
* Called when the module is loaded, after the debugger has been enabled
|
|
15
|
-
*/
|
|
16
|
-
abstract init(inspector: Inspector.Session): Promise<void>;
|
|
17
|
-
/**
|
|
18
|
-
* Called when the module should be cleaned up.
|
|
19
|
-
* - After the Debug Controller has been disabled
|
|
20
|
-
* - Before the debugger is disconnected
|
|
21
|
-
*/
|
|
22
|
-
abstract cleanup(): Promise<void>;
|
|
23
|
-
constructor(name: string, options?: DebugModuleOptions);
|
|
24
|
-
}
|
package/lib/types/DebugModule.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.DebugModule = void 0;
|
|
7
|
-
const events_1 = __importDefault(require("events"));
|
|
8
|
-
class DebugModule extends events_1.default {
|
|
9
|
-
constructor(name, options = {}) {
|
|
10
|
-
super();
|
|
11
|
-
this.name = name;
|
|
12
|
-
this.methods = options.methods || [];
|
|
13
|
-
this.events = options.events || [];
|
|
14
|
-
if (!this.name || this.name.length === 0) {
|
|
15
|
-
throw new Error("DebugModule should have a name");
|
|
16
|
-
}
|
|
17
|
-
if (this.name.charAt(0) !== this.name.charAt(0).toUpperCase()) {
|
|
18
|
-
throw new Error(`Debug Module name "${name}" should start with an uppercase letter`);
|
|
19
|
-
}
|
|
20
|
-
for (const event of this.events) {
|
|
21
|
-
if (event.length === 0) {
|
|
22
|
-
throw new Error(`Event name should not be empty for "${name}"`);
|
|
23
|
-
}
|
|
24
|
-
if (event.charAt(0) !== event.charAt(0).toLowerCase()) {
|
|
25
|
-
throw new Error(`Event name "${event}" should start with a lowercase letter for module "${name}"`);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
for (const method of this.methods) {
|
|
29
|
-
if (method.length === 0) {
|
|
30
|
-
throw new Error(`Method name should not be empty for Debug Module "${name}"`);
|
|
31
|
-
}
|
|
32
|
-
if (method.charAt(0) !== method.charAt(0).toLowerCase()) {
|
|
33
|
-
throw new Error(`Method name "${method}" should start with a lowercase letter for module "${name}"`);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
exports.DebugModule = DebugModule;
|
|
39
|
-
//# sourceMappingURL=DebugModule.js.map
|