kuzzle 2.23.0 → 2.25.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/README.md CHANGED
@@ -111,12 +111,8 @@ Learn how to [Write an Application](https://docs.kuzzle.io/core/2/guides/getting
111
111
 
112
112
  Train yourself and your teams to use Kuzzle to maximize its potential and accelerate the development of your projects.
113
113
  Our teams will be able to meet your needs in terms of expertise and multi-technology support for IoT, mobile/web, backend/frontend, devops.
114
- :point_right: [Get a quote](https://hubs.ly/H0jkfJ_0)
114
+ :point_right: [Get a quote](https://kuzzle.io/pricing/)
115
115
 
116
- ## Public Roadmap
117
-
118
- You can consult the public roadmap on Trello. Come and vote for the features you need!
119
- :point_right: [Kuzzle Public Roadmap](https://trello.com/b/za9vOgRh/kuzzle-public-roadmap)
120
116
 
121
117
  ## Contributing to Kuzzle
122
118
 
@@ -132,7 +128,6 @@ Check our [contributing documentation](./CONTRIBUTING.md) to know about our codi
132
128
  * Visit our [blog](https://blog.kuzzle.io/) to be informed about what we are doing
133
129
  * Come chat with us on [Discord](http://join.discord.kuzzle.io)
134
130
  * Ask technical questions on [stack overflow](https://stackoverflow.com/search?q=kuzzle)
135
- * Check out our [public roadmap](https://trello.com/b/za9vOgRh/kuzzle-public-roadmap) and vote for the upcoming features
136
131
 
137
132
  ## License
138
133
 
@@ -131,6 +131,14 @@ class DocumentController extends NativeController {
131
131
  { from, scroll: scrollTTL, size }
132
132
  );
133
133
  } else {
134
+ if (!index) {
135
+ throw kerror.get("api", "assert", "missing_argument", "index");
136
+ }
137
+
138
+ if (!collection) {
139
+ throw kerror.get("api", "assert", "missing_argument", "collection");
140
+ }
141
+
134
142
  result = await this.ask(
135
143
  "core:storage:public:document:search",
136
144
  index,
@@ -146,7 +146,12 @@ class ClusterIdCardHandler {
146
146
  const childProcess = (0, child_process_1.fork)(path);
147
147
  const exitHandler = () => {
148
148
  if (!childProcess.killed || childProcess.connected) {
149
- childProcess.kill();
149
+ try {
150
+ childProcess.disconnect();
151
+ }
152
+ catch (e) {
153
+ // It could happens that the worker has been killed before the dispose causing disconnect to fail
154
+ }
150
155
  }
151
156
  process.exit();
152
157
  };
@@ -136,7 +136,8 @@ process.on("message", async (message) => {
136
136
  });
137
137
 
138
138
  // When the IPC is closed on the main process side
139
- process.on("disconnect", () => {
139
+ process.on("disconnect", async () => {
140
+ await idCardRenewer.dispose();
140
141
  process.exit();
141
142
  });
142
143
 
@@ -210,6 +210,7 @@ const defaultConfig = {
210
210
  port: 7512,
211
211
  protocols: {
212
212
  http: {
213
+ additionalContentTypes: [],
213
214
  allowCompression: true,
214
215
  enabled: true,
215
216
  maxEncodingLayers: 3,
@@ -236,10 +236,16 @@ function checkHttpOptions(config) {
236
236
  `[http] "maxFormFileSize" parameter: cannot parse "${cfg.maxFormFileSize}"`
237
237
  );
238
238
  cfg.maxFormFileSize = maxFormFileSize;
239
+
239
240
  assert(
240
241
  typeof config.http.cookieAuthentication === "boolean",
241
242
  `[http] "cookieAuthentication" parameter: invalid value "${config.http.cookieAuthentication}" (boolean expected)`
242
243
  );
244
+ assert(
245
+ Array.isArray(cfg.additionalContentTypes) &&
246
+ cfg.additionalContentTypes.every((ct) => typeof ct === "string"),
247
+ `[http] "additionalContentTypes" parameter: invalid value "${cfg.additionalContentTypes}" (array of strings expected)`
248
+ );
243
249
  }
244
250
 
245
251
  function checkClusterOptions(config) {
@@ -502,7 +502,7 @@ class HttpWsProtocol extends Protocol {
502
502
 
503
503
  if (
504
504
  contentType &&
505
- !HTTP_ALLOWED_CONTENT_TYPES.some((allowed) =>
505
+ !this.httpConfig.opts.allowedContentTypes.some((allowed) =>
506
506
  contentType.includes(allowed)
507
507
  )
508
508
  ) {
@@ -1194,6 +1194,10 @@ class HttpWsProtocol extends Protocol {
1194
1194
  headers,
1195
1195
  opts: {
1196
1196
  allowCompression: cfg.allowCompression,
1197
+ allowedContentTypes: [
1198
+ ...HTTP_ALLOWED_CONTENT_TYPES,
1199
+ ...cfg.additionalContentTypes,
1200
+ ],
1197
1201
  maxEncodingLayers: cfg.maxEncodingLayers,
1198
1202
  maxFormFileSize: cfg.maxFormFileSize,
1199
1203
  },
@@ -136,6 +136,18 @@ class Router {
136
136
  this._executeFromHttp("post", apiRequest, cb);
137
137
  });
138
138
 
139
+ this.http.get("_healthcheck", (request, cb) => {
140
+ request.response.configure({
141
+ status: 200,
142
+ });
143
+
144
+ /**
145
+ * By avoiding using the funnel, we avoid the request to be logged
146
+ * This is useful for ochestrators healthchecks
147
+ */
148
+ cb(request);
149
+ });
150
+
139
151
  for (const route of routes) {
140
152
  const verb = route.verb.toLowerCase();
141
153
 
@@ -335,6 +335,17 @@
335
335
  "class": "InternalError"
336
336
  }
337
337
  }
338
+ },
339
+ "koncorde": {
340
+ "code": 5,
341
+ "errors": {
342
+ "elastic_translation_error": {
343
+ "description": "An error occured while translating a Koncorde filter to an Elasticsearch query",
344
+ "code": 1,
345
+ "message": "An error occured while translating a Koncorde filter to an Elasticsearch query: %s",
346
+ "class": "BadRequestError"
347
+ }
348
+ }
338
349
  }
339
350
  }
340
351
  }
@@ -21,6 +21,8 @@
21
21
 
22
22
  "use strict";
23
23
 
24
+ const kerror = require("../../kerror");
25
+
24
26
  class KeywordError extends Error {
25
27
  constructor(type, name) {
26
28
  super(
@@ -33,17 +35,78 @@ class KeywordError extends Error {
33
35
 
34
36
  const KONCORDE_OPERATORS = ["and", "or", "not", "bool"];
35
37
 
38
+ /**
39
+ * Parse the Koncorde path to extract the path and the value
40
+ * path have the form "path.to.field[json_value]"
41
+ *
42
+ * @param {string} path
43
+ * @returns
44
+ */
45
+ function parseKoncordePath(path) {
46
+ const firstBracket = path.indexOf("[");
47
+
48
+ if (firstBracket < 0) {
49
+ return {
50
+ path,
51
+ };
52
+ }
53
+
54
+ const lastBracket = path.lastIndexOf("]");
55
+
56
+ if (lastBracket < 0) {
57
+ throw kerror.get(
58
+ "services",
59
+ "koncorde",
60
+ "elastic_translation_error",
61
+ `Invalid exists path "${path}": missing closing bracket`
62
+ );
63
+ }
64
+
65
+ return {
66
+ path: path.slice(0, firstBracket),
67
+ value: JSON.parse(path.slice(firstBracket + 1, lastBracket)),
68
+ };
69
+ }
70
+
36
71
  const KONCORDE_CLAUSES_TO_ES = {
37
72
  equals: (content) => ({
38
73
  term: {
39
74
  ...content,
40
75
  },
41
76
  }),
42
- exists: (field) => ({
43
- exists: {
44
- field,
45
- },
46
- }),
77
+ exists: (field) => {
78
+ // Support old syntax { exists: { field: "path" } } and { exists: "path" }
79
+ const parsedInfo = parseKoncordePath(field.field || field);
80
+
81
+ // If we have a value, we need to use a range query to be sure that the value is the same
82
+ if (parsedInfo.value) {
83
+ return {
84
+ bool: {
85
+ filter: [
86
+ {
87
+ exists: {
88
+ field: parsedInfo.path,
89
+ },
90
+ },
91
+ {
92
+ range: {
93
+ [parsedInfo.path]: {
94
+ gte: parsedInfo.value,
95
+ lte: parsedInfo.value,
96
+ },
97
+ },
98
+ },
99
+ ],
100
+ },
101
+ };
102
+ }
103
+
104
+ return {
105
+ exists: {
106
+ field: parsedInfo.path,
107
+ },
108
+ };
109
+ },
47
110
  geoBoundingBox: (content) => ({
48
111
  geo_bounding_box: {
49
112
  ...content,
@@ -68,6 +68,18 @@ export type ServerConfiguration = {
68
68
  */
69
69
  protocols: {
70
70
  http: {
71
+ /**
72
+ * Enables Kuzzle to accept additional Content-Types.
73
+ * Note: This relies on the implementation of a
74
+ * "protocol:http:beforeParsingPayload" pipe that implements
75
+ * the formatting of the additional content types to JSON.
76
+ * The default content types are:
77
+ * * application/json
78
+ * * application/x-www-form-urlencoded
79
+ * * multipart/form-data
80
+ * @default []
81
+ */
82
+ additionalContentTypes: string[];
71
83
  /**
72
84
  * Enable support for compressed requests, using the Content-Encoding header
73
85
  * Currently supported compression algorithms: gzip, deflate, identity
package/package.json CHANGED
@@ -1,44 +1,44 @@
1
1
  {
2
2
  "name": "kuzzle",
3
3
  "author": "The Kuzzle Team <support@kuzzle.io>",
4
- "version": "2.23.0",
4
+ "version": "2.25.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": {
8
+ "build-ts": "tsc",
9
+ "build": "npm run build-ts",
10
+ "clean": "touch index.ts && npm run build | grep TSFILE | cut -d' ' -f 2 | xargs rm",
11
+ "codecov": "codecov",
12
+ "cucumber": "cucumber.js --fail-fast",
13
+ "dev:test": "npm run dev -- docker/scripts/start-kuzzle-test.ts --enable-plugins functional-test-plugin",
14
+ "dev": "npx ergol docker/scripts/start-kuzzle-dev.ts -c ./config/ergol.config.json",
15
+ "doc-error-codes": "node -r ts-node/register doc/build-error-codes",
16
+ "docker:install": "docker-compose run kuzzle_node_1 npm install",
17
+ "docker:npm": "docker-compose run kuzzle_node_1 npm run --",
18
+ "docker:test:unit": "docker-compose run kuzzle_node_1 npm run test:unit",
8
19
  "docker": "docker-compose run kuzzle_node_1 ",
9
20
  "file": "npx ergol docker/scripts/start-kuzzle-dev.ts -c ./config/ergol.config.json",
10
- "start:dev": "npx ergol docker/scripts/start-kuzzle-dev.ts -c ./config/ergol.config.json --script-args=--enable-plugins functional-test-plugin",
11
21
  "prepublishOnly": "npm run build",
12
- "build": "npm run build-ts",
13
- "clean": "touch index.ts && npm run build | grep TSFILE | cut -d' ' -f 2 | xargs rm",
14
- "build-ts": "tsc",
22
+ "prettier": "npx prettier ./lib ./test ./bin ./features ./plugins/available/functional-test-plugin --write",
15
23
  "services": "npx kourou app:start-services",
16
- "dev": "npx ergol docker/scripts/start-kuzzle-dev.ts -c ./config/ergol.config.json",
17
- "dev:test": "npm run dev -- docker/scripts/start-kuzzle-dev.ts --enable-plugins functional-test-plugin",
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",
20
- "test:unit": "DEBUG= npx --node-arg=--trace-warnings mocha --exit",
21
- "test:unit:coverage": "DEBUG= nyc --reporter=text-summary --reporter=lcov mocha --exit",
22
- "test:functional": "npm run test:functional:http && npm run test:functional:websocket && npm run test:jest",
24
+ "start:dev": "npx ergol docker/scripts/start-kuzzle-dev.ts -c ./config/ergol.config.json --script-args=--enable-plugins functional-test-plugin",
23
25
  "test:functional:http": "KUZZLE_PROTOCOL=http npx cucumber-js --profile http",
24
- "test:functional:websocket": "KUZZLE_PROTOCOL=websocket npx cucumber-js --profile websocket",
25
- "test:functional:legacy": "npm run test:functional:legacy:http && npm run test:functional:legacy:websocket && npm run test:functional:legacy:mqtt",
26
+ "test:functional:jest": "npm run test:jest",
26
27
  "test:functional:legacy:http": "npx cucumber-js --format progress-bar --profile http ./features-legacy",
27
- "test:functional:legacy:websocket": "npx cucumber-js --format progress-bar --profile websocket ./features-legacy",
28
28
  "test:functional:legacy:mqtt": "npx cucumber-js --format progress-bar --profile mqtt ./features-legacy",
29
- "test:functional:jest": "npm run test:jest",
30
- "cucumber": "cucumber.js --fail-fast",
31
- "codecov": "codecov",
32
- "prettier": "npx prettier ./lib ./test ./bin ./features ./plugins/available/functional-test-plugin --write",
33
- "test:lint": "npm run test:lint:js && npm run test:lint:ts",
34
- "test:lint:ts": "eslint --max-warnings=0 ./lib --ext .ts --config .eslintc-ts.json",
35
- "test:lint:ts:fix": "eslint --max-warnings=0 --fix ./lib --ext .ts --config .eslintc-ts.json",
36
- "test:lint:js": "eslint --max-warnings=0 ./lib ./test ./bin ./features ./plugins/available/functional-test-plugin",
29
+ "test:functional:legacy:websocket": "npx cucumber-js --format progress-bar --profile websocket ./features-legacy",
30
+ "test:functional:legacy": "npm run test:functional:legacy:http && npm run test:functional:legacy:websocket && npm run test:functional:legacy:mqtt",
31
+ "test:functional:websocket": "KUZZLE_PROTOCOL=websocket npx cucumber-js --profile websocket",
32
+ "test:functional": "npm run test:functional:http && npm run test:functional:websocket && npm run test:jest",
33
+ "test:jest": "jest",
37
34
  "test:lint:js:fix": "eslint --max-warnings=0 --fix ./lib ./test ./bin ./features",
38
- "doc-error-codes": "node -r ts-node/register doc/build-error-codes",
39
- "docker:install": "docker-compose run kuzzle_node_1 npm install",
40
- "docker:test:unit": "docker-compose run kuzzle_node_1 npm run test:unit",
41
- "docker:npm": "docker-compose run kuzzle_node_1 npm run --"
35
+ "test:lint:js": "eslint --max-warnings=0 ./lib ./test ./bin ./features ./plugins/available/functional-test-plugin",
36
+ "test:lint:ts:fix": "eslint --max-warnings=0 --fix ./lib --ext .ts --config .eslintc-ts.json",
37
+ "test:lint:ts": "eslint --max-warnings=0 ./lib --ext .ts --config .eslintc-ts.json",
38
+ "test:lint": "npm run test:lint:js && npm run test:lint:ts",
39
+ "test:unit:coverage": "DEBUG= nyc --reporter=text-summary --reporter=lcov mocha --exit",
40
+ "test:unit": "DEBUG= npx --node-arg=--trace-warnings mocha --exit",
41
+ "test": "npm run clean && npm run --silent test:lint && npm run build && npm run test:unit:coverage && npm run test:functional"
42
42
  },
43
43
  "directories": {
44
44
  "lib": "lib"
@@ -79,7 +79,7 @@
79
79
  "semver": "^7.3.8",
80
80
  "sorted-array": "^2.0.4",
81
81
  "uuid": "^9.0.0",
82
- "uWebSockets.js": "https://github.com/uNetworking/uWebSockets.js/archive/refs/tags/v20.0.0.tar.gz",
82
+ "uWebSockets.js": "https://github.com/uNetworking/uWebSockets.js/archive/refs/tags/v20.7.0.tar.gz",
83
83
  "validator": "^13.9.0",
84
84
  "winston": "^3.8.2",
85
85
  "winston-elasticsearch": "0.17.1",