kuzzle 2.20.0 → 2.20.2
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/documentController.js +6 -8
- package/lib/api/funnel.js +4 -1
- package/lib/api/request/kuzzleRequest.d.ts +2 -0
- package/lib/api/request/kuzzleRequest.js +32 -0
- package/lib/core/network/protocols/httpwsProtocol.js +0 -12
- package/lib/core/plugin/plugin.js +6 -1
- package/lib/core/plugin/pluginsManager.js +9 -2
- package/lib/kuzzle/kuzzle.js +3 -2
- package/lib/types/Plugin.d.ts +5 -0
- package/package.json +16 -10
|
@@ -232,17 +232,15 @@ class DocumentController extends NativeController {
|
|
|
232
232
|
|
|
233
233
|
async export(request) {
|
|
234
234
|
const { index, collection } = request.getIndexAndCollection();
|
|
235
|
-
const { size, scrollTTL
|
|
236
|
-
const format = request.getString("format", "jsonl");
|
|
237
|
-
const fields = request.getBodyArray("fields", []);
|
|
235
|
+
const { size, scrollTTL } = request.getSearchParams();
|
|
238
236
|
const lang = request.getLangParam();
|
|
237
|
+
const format = request.getString("format", "jsonl");
|
|
239
238
|
const separator = request.getString("separator", ",");
|
|
240
|
-
const
|
|
239
|
+
const query = request.getObjectFromBodyOrArgs("query", {});
|
|
240
|
+
const fields = request.getArrayFromBodyOrArgs("fields", []);
|
|
241
|
+
const fieldsName = request.getObjectFromBodyOrArgs("fieldsName", {});
|
|
241
242
|
|
|
242
|
-
|
|
243
|
-
// since those properties are not allowed in the searchBody
|
|
244
|
-
searchBody.fields = undefined;
|
|
245
|
-
searchBody.fieldsName = undefined;
|
|
243
|
+
const searchBody = { query };
|
|
246
244
|
|
|
247
245
|
if (request.context.connection.protocol !== "http") {
|
|
248
246
|
throw kerror.get(
|
package/lib/api/funnel.js
CHANGED
|
@@ -50,6 +50,7 @@ const kerror = require("../kerror");
|
|
|
50
50
|
const debug = require("../util/debug")("kuzzle:funnel");
|
|
51
51
|
const processError = kerror.wrap("api", "process");
|
|
52
52
|
const { has } = require("../util/safeObject");
|
|
53
|
+
const { HttpStream } = require("../types");
|
|
53
54
|
|
|
54
55
|
// Actions of the auth controller that does not necessite to verify the token
|
|
55
56
|
// when cookie auth is active
|
|
@@ -662,7 +663,9 @@ class Funnel {
|
|
|
662
663
|
) {
|
|
663
664
|
// check if the plugin response can be serialized
|
|
664
665
|
try {
|
|
665
|
-
|
|
666
|
+
if (!(responseData instanceof HttpStream)) {
|
|
667
|
+
JSON.stringify(responseData);
|
|
668
|
+
}
|
|
666
669
|
} catch (e) {
|
|
667
670
|
_request.setResult(null);
|
|
668
671
|
throw kerror.get("plugin", "controller", "unserializable_response");
|
|
@@ -373,6 +373,8 @@ export declare class KuzzleRequest {
|
|
|
373
373
|
* Returns the search body query according to the http method
|
|
374
374
|
*/
|
|
375
375
|
getSearchBody(): JSONObject;
|
|
376
|
+
getObjectFromBodyOrArgs(name: string, def?: JSONObject): JSONObject;
|
|
377
|
+
getArrayFromBodyOrArgs(name: string, def?: any): JSONObject;
|
|
376
378
|
/**
|
|
377
379
|
* Returns the search params.
|
|
378
380
|
*/
|
|
@@ -726,6 +726,38 @@ class KuzzleRequest {
|
|
|
726
726
|
}
|
|
727
727
|
return this.getObject("searchBody", {});
|
|
728
728
|
}
|
|
729
|
+
getObjectFromBodyOrArgs(name, def) {
|
|
730
|
+
if (this.context.connection.protocol !== "http" ||
|
|
731
|
+
this.context.connection.misc.verb !== "GET") {
|
|
732
|
+
return this.getBodyObject(name, def);
|
|
733
|
+
}
|
|
734
|
+
const rawObject = this.getString(name, JSON.stringify(def));
|
|
735
|
+
try {
|
|
736
|
+
return JSON.parse(rawObject);
|
|
737
|
+
}
|
|
738
|
+
catch (error) {
|
|
739
|
+
if (error instanceof SyntaxError) {
|
|
740
|
+
throw assertionError.get("invalid_type", name, "JSON string");
|
|
741
|
+
}
|
|
742
|
+
throw error;
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
getArrayFromBodyOrArgs(name, def) {
|
|
746
|
+
if (this.context.connection.protocol !== "http" ||
|
|
747
|
+
this.context.connection.misc.verb !== "GET") {
|
|
748
|
+
return this.getBodyArray(name, def);
|
|
749
|
+
}
|
|
750
|
+
const rawObject = this.getString(name, JSON.stringify(def));
|
|
751
|
+
try {
|
|
752
|
+
return JSON.parse(rawObject);
|
|
753
|
+
}
|
|
754
|
+
catch (error) {
|
|
755
|
+
if (error instanceof SyntaxError) {
|
|
756
|
+
throw assertionError.get("invalid_type", name, "JSON string");
|
|
757
|
+
}
|
|
758
|
+
throw error;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
729
761
|
/**
|
|
730
762
|
* Returns the search params.
|
|
731
763
|
*/
|
|
@@ -83,14 +83,11 @@ const HTTP_ALLOWED_CONTENT_TYPES = [
|
|
|
83
83
|
];
|
|
84
84
|
const HTTP_SKIPPED_HEADERS = ["content-length", "set-cookie"];
|
|
85
85
|
const HTTP_HEADER_CONNECTION = Buffer.from("Connection");
|
|
86
|
-
const HTTP_HEADER_CONTENT_LENGTH = Buffer.from("Content-Length");
|
|
87
86
|
const HTTP_HEADER_ACCESS_CONTROL_ALLOW_ORIGIN = Buffer.from(
|
|
88
87
|
"Access-Control-Allow-Origin"
|
|
89
88
|
);
|
|
90
89
|
const HTTP_HEADER_SET_COOKIE = Buffer.from("Set-Cookie");
|
|
91
90
|
const HTTP_HEADER_VARY = Buffer.from("Vary");
|
|
92
|
-
const HTTP_HEADER_TRANSFER_ENCODING = Buffer.from("Transfer-Encoding");
|
|
93
|
-
const CHUNKED = Buffer.from("chunked");
|
|
94
91
|
const WILDCARD = Buffer.from("*");
|
|
95
92
|
const ORIGIN = Buffer.from("Origin");
|
|
96
93
|
const X_KUZZLE_REQUEST_ID = Buffer.from("X-Kuzzle-Request-Id");
|
|
@@ -782,15 +779,6 @@ class HttpWsProtocol extends Protocol {
|
|
|
782
779
|
// Send Headers in one go
|
|
783
780
|
response.cork(() => {
|
|
784
781
|
this.httpWriteRequestHeaders(request, response, message);
|
|
785
|
-
|
|
786
|
-
if (streamSizeFixed) {
|
|
787
|
-
response.writeHeader(
|
|
788
|
-
HTTP_HEADER_CONTENT_LENGTH,
|
|
789
|
-
Buffer.from(httpStream.totalBytes.toString())
|
|
790
|
-
);
|
|
791
|
-
} else {
|
|
792
|
-
response.writeHeader(HTTP_HEADER_TRANSFER_ENCODING, CHUNKED);
|
|
793
|
-
}
|
|
794
782
|
});
|
|
795
783
|
|
|
796
784
|
httpStream.stream.on("data", (chunk) => {
|
|
@@ -116,16 +116,21 @@ class Plugin {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
const description = {
|
|
119
|
+
version: this.version,
|
|
119
120
|
controllers: [],
|
|
120
121
|
hooks: [],
|
|
121
122
|
manifest: this.manifest,
|
|
122
123
|
pipes: [],
|
|
123
124
|
routes: [],
|
|
124
125
|
strategies: [],
|
|
125
|
-
|
|
126
|
+
imports: {},
|
|
126
127
|
};
|
|
127
128
|
/* eslint-enable sort-keys */
|
|
128
129
|
|
|
130
|
+
if (has(this.instance, "imports")) {
|
|
131
|
+
description.imports = Object.keys(this.instance.imports);
|
|
132
|
+
}
|
|
133
|
+
|
|
129
134
|
if (has(this.instance, "hooks")) {
|
|
130
135
|
description.hooks = Object.keys(this.instance.hooks);
|
|
131
136
|
}
|
|
@@ -207,7 +207,7 @@ class PluginsManager {
|
|
|
207
207
|
*
|
|
208
208
|
* @throws PluginImplementationError - Throws when an error occurs when registering a plugin
|
|
209
209
|
*/
|
|
210
|
-
init(plugins = {}) {
|
|
210
|
+
async init(plugins = {}) {
|
|
211
211
|
this._plugins = new Map([...this.loadPlugins(plugins), ...this._plugins]);
|
|
212
212
|
|
|
213
213
|
global.kuzzle.on("plugin:hook:loop-error", ({ error, pluginName }) => {
|
|
@@ -224,6 +224,7 @@ class PluginsManager {
|
|
|
224
224
|
|
|
225
225
|
// register regular plugins features
|
|
226
226
|
const loadPlugins = [];
|
|
227
|
+
const defaultImports = {};
|
|
227
228
|
|
|
228
229
|
for (const plugin of this._plugins.values()) {
|
|
229
230
|
if (
|
|
@@ -301,13 +302,19 @@ class PluginsManager {
|
|
|
301
302
|
this.loadedPlugins.push(plugin.name);
|
|
302
303
|
}
|
|
303
304
|
|
|
305
|
+
if (!_.isEmpty(plugin.instance.imports)) {
|
|
306
|
+
_.merge(defaultImports, plugin.instance.imports);
|
|
307
|
+
}
|
|
308
|
+
|
|
304
309
|
return null;
|
|
305
310
|
});
|
|
306
311
|
|
|
307
312
|
loadPlugins.push(promise);
|
|
308
313
|
}
|
|
309
314
|
|
|
310
|
-
|
|
315
|
+
await Promise.all(loadPlugins);
|
|
316
|
+
|
|
317
|
+
return defaultImports;
|
|
311
318
|
}
|
|
312
319
|
|
|
313
320
|
/**
|
package/lib/kuzzle/kuzzle.js
CHANGED
|
@@ -165,11 +165,12 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
|
|
|
165
165
|
// before opening connections to external users
|
|
166
166
|
await this.entryPoint.init();
|
|
167
167
|
this.pluginsManager.application = application;
|
|
168
|
-
await this.pluginsManager.init(options.plugins);
|
|
168
|
+
const pluginImports = await this.pluginsManager.init(options.plugins);
|
|
169
169
|
this.log.info(`[✔] Successfully loaded ${this.pluginsManager.loadedPlugins.length} plugins: ${this.pluginsManager.loadedPlugins.join(", ")}`);
|
|
170
|
+
const imports = lodash_1.default.merge({}, pluginImports, options.import);
|
|
170
171
|
// Authentification plugins must be loaded before users import to avoid
|
|
171
172
|
// credentials related error which would prevent Kuzzle from starting
|
|
172
|
-
await this.loadInitialState(
|
|
173
|
+
await this.loadInitialState(imports, options.support);
|
|
173
174
|
await this.ask("core:security:verify");
|
|
174
175
|
this.router.init();
|
|
175
176
|
this.log.info("[✔] Core components loaded");
|
package/lib/types/Plugin.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { PluginManifest } from "./PluginManifest";
|
|
|
4
4
|
import { StrategyDefinition } from "./StrategyDefinition";
|
|
5
5
|
import { PipeEventHandler, HookEventHandler } from "./EventHandler";
|
|
6
6
|
import { JSONObject } from "../../index";
|
|
7
|
+
import { ImportConfig } from "./Kuzzle";
|
|
7
8
|
/**
|
|
8
9
|
* Allows to define plugins controllers and actions
|
|
9
10
|
*/
|
|
@@ -102,6 +103,10 @@ export declare abstract class Plugin {
|
|
|
102
103
|
* @see https://docs.kuzzle.io/core/2/plugins/guides/strategies/overview
|
|
103
104
|
*/
|
|
104
105
|
strategies?: StrategyDefinition;
|
|
106
|
+
/**
|
|
107
|
+
* Define default imports
|
|
108
|
+
*/
|
|
109
|
+
imports?: ImportConfig;
|
|
105
110
|
/**
|
|
106
111
|
* Plugin initialization method.
|
|
107
112
|
*
|
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.20.
|
|
4
|
+
"version": "2.20.2",
|
|
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": {
|
|
@@ -16,15 +16,17 @@
|
|
|
16
16
|
"dev": "npx ergol docker/scripts/start-kuzzle-dev.ts -c ./config/ergol.config.json",
|
|
17
17
|
"dev:test": "npm run dev -- docker/scripts/start-kuzzle-dev.ts --enable-plugins functional-test-plugin",
|
|
18
18
|
"test": "npm run clean && npm run --silent test:lint && npm run build && npm run test:unit:coverage && npm run test:functional",
|
|
19
|
+
"test:jest": "jest",
|
|
19
20
|
"test:unit": "DEBUG= npx --node-arg=--trace-warnings mocha --exit",
|
|
20
21
|
"test:unit:coverage": "DEBUG= nyc --reporter=text-summary --reporter=lcov mocha --exit",
|
|
21
|
-
"test:functional": "npm run test:functional:http && npm run test:functional:websocket",
|
|
22
|
+
"test:functional": "npm run test:functional:http && npm run test:functional:websocket && npm run test:jest",
|
|
22
23
|
"test:functional:http": "KUZZLE_PROTOCOL=http npx cucumber-js --profile http",
|
|
23
24
|
"test:functional:websocket": "KUZZLE_PROTOCOL=websocket npx cucumber-js --profile websocket",
|
|
24
25
|
"test:functional:legacy": "npm run test:functional:legacy:http && npm run test:functional:legacy:websocket && npm run test:functional:legacy:mqtt",
|
|
25
26
|
"test:functional:legacy:http": "npx cucumber-js --format progress-bar --profile http ./features-legacy",
|
|
26
27
|
"test:functional:legacy:websocket": "npx cucumber-js --format progress-bar --profile websocket ./features-legacy",
|
|
27
28
|
"test:functional:legacy:mqtt": "npx cucumber-js --format progress-bar --profile mqtt ./features-legacy",
|
|
29
|
+
"test:functional:jest": "npm run test:jest",
|
|
28
30
|
"cucumber": "cucumber.js --fail-fast",
|
|
29
31
|
"codecov": "codecov",
|
|
30
32
|
"prettier": "npx prettier ./lib ./test ./bin ./features ./plugins/available/functional-test-plugin --write",
|
|
@@ -54,7 +56,7 @@
|
|
|
54
56
|
"eslint-plugin-kuzzle": "^0.0.6",
|
|
55
57
|
"eventemitter3": "^4.0.7",
|
|
56
58
|
"inquirer": "^9.1.4",
|
|
57
|
-
"ioredis": "^5.
|
|
59
|
+
"ioredis": "^5.3.0",
|
|
58
60
|
"js-yaml": "^4.1.0",
|
|
59
61
|
"json-stable-stringify": "^1.0.2",
|
|
60
62
|
"json2yaml": "^1.1.0",
|
|
@@ -62,7 +64,7 @@
|
|
|
62
64
|
"koncorde": "^4.0.3",
|
|
63
65
|
"kuzzle-plugin-auth-passport-local": "^6.3.6",
|
|
64
66
|
"kuzzle-plugin-logger": "^3.0.3",
|
|
65
|
-
"kuzzle-sdk": "^7.10.
|
|
67
|
+
"kuzzle-sdk": "^7.10.5",
|
|
66
68
|
"kuzzle-vault": "^2.0.4",
|
|
67
69
|
"lodash": "4.17.21",
|
|
68
70
|
"long": "^5.2.1",
|
|
@@ -72,13 +74,13 @@
|
|
|
72
74
|
"ndjson": "^2.0.0",
|
|
73
75
|
"node-segfault-handler": "^1.4.2",
|
|
74
76
|
"passport": "^0.6.0",
|
|
75
|
-
"protobufjs": "~7.1
|
|
77
|
+
"protobufjs": "~7.2.1",
|
|
76
78
|
"rc": "1.2.8",
|
|
77
79
|
"semver": "^7.3.8",
|
|
78
80
|
"sorted-array": "^2.0.4",
|
|
79
81
|
"uuid": "^9.0.0",
|
|
80
82
|
"uWebSockets.js": "https://github.com/uNetworking/uWebSockets.js/archive/refs/tags/v20.0.0.tar.gz",
|
|
81
|
-
"validator": "^13.
|
|
83
|
+
"validator": "^13.9.0",
|
|
82
84
|
"winston": "^3.8.2",
|
|
83
85
|
"winston-elasticsearch": "0.17.1",
|
|
84
86
|
"winston-syslog": "^2.7.0",
|
|
@@ -91,14 +93,17 @@
|
|
|
91
93
|
"url": "git://github.com/kuzzleio/kuzzle.git"
|
|
92
94
|
},
|
|
93
95
|
"devDependencies": {
|
|
96
|
+
"@jest/globals": "^29.4.1",
|
|
97
|
+
"@types/jest": "^29.4.0",
|
|
94
98
|
"@types/js-yaml": "^4.0.5",
|
|
95
|
-
"@types/lodash": "^4.14.
|
|
99
|
+
"@types/lodash": "^4.14.191",
|
|
96
100
|
"async": "^3.2.4",
|
|
97
101
|
"chokidar": "^3.5.3",
|
|
98
102
|
"codecov": "^3.8.3",
|
|
99
103
|
"cucumber": "^6.0.5",
|
|
100
104
|
"ergol": "^1.0.2",
|
|
101
|
-
"
|
|
105
|
+
"jest": "^29.4.1",
|
|
106
|
+
"mocha": "^10.2.0",
|
|
102
107
|
"mock-require": "^3.0.3",
|
|
103
108
|
"mqtt": "^4.3.7",
|
|
104
109
|
"nyc": "^15.1.0",
|
|
@@ -109,9 +114,10 @@
|
|
|
109
114
|
"should-sinon": "0.0.6",
|
|
110
115
|
"sinon": "^14.0.2",
|
|
111
116
|
"strip-json-comments": "https://github.com/sindresorhus/strip-json-comments/archive/refs/tags/v3.1.1.tar.gz",
|
|
117
|
+
"ts-jest": "^29.0.5",
|
|
112
118
|
"ts-node": "^10.9.1",
|
|
113
|
-
"typescript": "^4.9.
|
|
114
|
-
"yaml": "^2.1
|
|
119
|
+
"typescript": "^4.9.5",
|
|
120
|
+
"yaml": "^2.2.1"
|
|
115
121
|
},
|
|
116
122
|
"engines": {
|
|
117
123
|
"node": ">= 12.13.0"
|