From a13f22d195568fbb3d70eb38e02a3d224fa4c319 Mon Sep 17 00:00:00 2001 From: RustamGimadiev Date: Mon, 31 May 2021 19:03:26 +0300 Subject: [PATCH 01/10] add ability to use relative pathes --- .../kafka/ui/config/CustomWebFilter.java | 26 ++++++++++++++++--- kafka-ui-react-app/package.json | 1 + 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/CustomWebFilter.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/CustomWebFilter.java index 8ad7f66db53..dfe9c4c13f1 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/CustomWebFilter.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/CustomWebFilter.java @@ -1,5 +1,6 @@ package com.provectus.kafka.ui.config; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; @@ -7,15 +8,32 @@ import reactor.core.publisher.Mono; @Component + public class CustomWebFilter implements WebFilter { + + private final ServerProperties serverProperties; + + public CustomWebFilter(ServerProperties serverProperties) { + this.serverProperties = serverProperties; + } + @Override public Mono filter(ServerWebExchange exchange, WebFilterChain chain) { - if (exchange.getRequest().getURI().getPath().equals("/") - || exchange.getRequest().getURI().getPath().startsWith("/ui")) { + String contextPath = serverProperties.getServlet().getContextPath() != null + ? serverProperties.getServlet().getContextPath() : ""; + + if (exchange.getRequest().getURI().getPath().equals(contextPath + "/") + || exchange.getRequest().getURI().getPath().startsWith(contextPath + "/ui")) { return chain.filter( exchange.mutate().request(exchange.getRequest().mutate().path("/index.html").build()) - .build()); - } + .build() + ); + } else if (exchange.getRequest().getURI().getPath().startsWith(contextPath)) { + return chain.filter( + exchange.mutate().request(exchange.getRequest().mutate().contextPath(contextPath).build()) + .build() + ); + } return chain.filter(exchange); } diff --git a/kafka-ui-react-app/package.json b/kafka-ui-react-app/package.json index 6ca047947ca..e8815efc962 100644 --- a/kafka-ui-react-app/package.json +++ b/kafka-ui-react-app/package.json @@ -1,6 +1,7 @@ { "name": "kafka-ui", "version": "0.1.0", + "homepage": "./", "private": true, "dependencies": { "@fortawesome/fontawesome-free": "^5.15.3", From 1ea92556fb5b700fc07e0507a2be2aefb556bdcd Mon Sep 17 00:00:00 2001 From: Alexander Krivonosov <31561808+GneyHabub@users.noreply.github.com> Date: Tue, 1 Jun 2021 18:16:15 +0300 Subject: [PATCH 02/10] Add basename prop (#513) --- kafka-ui-react-app/src/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kafka-ui-react-app/src/index.tsx b/kafka-ui-react-app/src/index.tsx index 2a82087ef5e..b9ba2433a0d 100644 --- a/kafka-ui-react-app/src/index.tsx +++ b/kafka-ui-react-app/src/index.tsx @@ -11,7 +11,7 @@ const store = configureStore(); ReactDOM.render( - + , From b5a4d206308b64c992dbac5194a46d2758ffa8cf Mon Sep 17 00:00:00 2001 From: RustamGimadiev Date: Wed, 2 Jun 2021 15:05:56 +0300 Subject: [PATCH 03/10] add static controller --- docker/kafka-ui-reverse-proxy.yaml | 22 ++++++++ docker/proxy.conf | 9 +++ .../kafka/ui/controller/StaticController.java | 56 +++++++++++++++++++ kafka-ui-react-app/public/index.html | 3 + kafka-ui-react-app/src/lib/constants.ts | 8 ++- 5 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 docker/kafka-ui-reverse-proxy.yaml create mode 100644 docker/proxy.conf create mode 100644 kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java diff --git a/docker/kafka-ui-reverse-proxy.yaml b/docker/kafka-ui-reverse-proxy.yaml new file mode 100644 index 00000000000..e410b7dbe8a --- /dev/null +++ b/docker/kafka-ui-reverse-proxy.yaml @@ -0,0 +1,22 @@ +--- +version: '2' +services: + nginx: + image: nginx:latest + volumes: + - ./proxy.conf:/etc/nginx/conf.d/default.conf + ports: + - 8080:80 + + kafka-ui: + container_name: kafka-ui-new + image: provectuslabs/kafka-ui:latest + ports: + - 8082:8080 + environment: + KAFKA_CLUSTERS_0_NAME: local + KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9092 + SERVER_SERVLET_CONTEXT_PATH: /kafka-ui + SERVER_SERVLET_CONTEXTPATH: /kafka-ui + SPRING_SERVER_SERVLET_CONTEXT_PATH: /kafka-ui + SPRING_SERVER_SERVLET_CONTEXTPATH: /kafka-ui diff --git a/docker/proxy.conf b/docker/proxy.conf new file mode 100644 index 00000000000..3c72de83301 --- /dev/null +++ b/docker/proxy.conf @@ -0,0 +1,9 @@ +server { + listen 80; + server_name localhost; + + location /kafka-ui { +# rewrite /kafka-ui/(.*) /$1 break; + proxy_pass http://kafka-ui:8080; + } +} diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java new file mode 100644 index 00000000000..eddc886a48d --- /dev/null +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java @@ -0,0 +1,56 @@ +package com.provectus.kafka.ui.controller; + +import com.provectus.kafka.ui.api.BrokersApi; +import com.provectus.kafka.ui.model.Broker; +import com.provectus.kafka.ui.model.BrokerMetrics; +import com.provectus.kafka.ui.service.ClusterService; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import lombok.RequiredArgsConstructor; +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.autoconfigure.web.ServerProperties; +import org.springframework.core.io.Resource; +import org.springframework.http.ResponseEntity; +import org.springframework.util.FileCopyUtils; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Flux; +import reactor.core.publisher.Mono; + +@RestController +@RequiredArgsConstructor +@Log4j2 +public class StaticController { + private final ServerProperties serverProperties; + + @Value("classpath:static/index.html") + private Resource indexFile; + + @RequestMapping(value = "/index.html", + produces = { "text/html" }, + method = RequestMethod.GET) + public Mono> getIndex(ServerWebExchange exchange) throws IOException { + + String contextPath = serverProperties.getServlet().getContextPath() != null + ? serverProperties.getServlet().getContextPath() : ""; + + String data = asString(indexFile) + .replace("./static", contextPath + "/static") + .replace("window.basePath=\"/\"", "window.basePath=\"" + contextPath + "\""); + + return Mono.just(ResponseEntity.ok(data)); + } + + public static String asString(Resource resource) throws IOException { + try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) { + return FileCopyUtils.copyToString(reader); + } + } + +} diff --git a/kafka-ui-react-app/public/index.html b/kafka-ui-react-app/public/index.html index 5faabaa4a7f..8ee64413dda 100644 --- a/kafka-ui-react-app/public/index.html +++ b/kafka-ui-react-app/public/index.html @@ -7,6 +7,9 @@ Kafka UI + diff --git a/kafka-ui-react-app/src/lib/constants.ts b/kafka-ui-react-app/src/lib/constants.ts index f49da1ba0da..c3182a4b62e 100644 --- a/kafka-ui-react-app/src/lib/constants.ts +++ b/kafka-ui-react-app/src/lib/constants.ts @@ -1,7 +1,13 @@ import { ConfigurationParameters } from 'generated-sources'; +declare global { + interface Window { + basePath: string; + } +} + export const BASE_PARAMS: ConfigurationParameters = { - basePath: process.env.REACT_APP_API_URL || '', + basePath: process.env.REACT_APP_API_URL || window.basePath || '', credentials: 'include', headers: { 'Content-Type': 'application/json', From 85bbd06c5a840e26d3a787b29912b0514f38472a Mon Sep 17 00:00:00 2001 From: RustamGimadiev Date: Wed, 2 Jun 2021 15:30:24 +0300 Subject: [PATCH 04/10] add docker-compose --- docker/kafka-ui-reverse-proxy.yaml | 5 +---- kafka-ui-react-app/src/index.tsx | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/docker/kafka-ui-reverse-proxy.yaml b/docker/kafka-ui-reverse-proxy.yaml index e410b7dbe8a..69d94e627a6 100644 --- a/docker/kafka-ui-reverse-proxy.yaml +++ b/docker/kafka-ui-reverse-proxy.yaml @@ -9,7 +9,7 @@ services: - 8080:80 kafka-ui: - container_name: kafka-ui-new + container_name: kafka-ui image: provectuslabs/kafka-ui:latest ports: - 8082:8080 @@ -17,6 +17,3 @@ services: KAFKA_CLUSTERS_0_NAME: local KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:9092 SERVER_SERVLET_CONTEXT_PATH: /kafka-ui - SERVER_SERVLET_CONTEXTPATH: /kafka-ui - SPRING_SERVER_SERVLET_CONTEXT_PATH: /kafka-ui - SPRING_SERVER_SERVLET_CONTEXTPATH: /kafka-ui diff --git a/kafka-ui-react-app/src/index.tsx b/kafka-ui-react-app/src/index.tsx index b9ba2433a0d..0b7931418c2 100644 --- a/kafka-ui-react-app/src/index.tsx +++ b/kafka-ui-react-app/src/index.tsx @@ -6,12 +6,13 @@ import * as serviceWorker from 'serviceWorker'; import configureStore from 'redux/store/configureStore'; import AppContainer from 'components/AppContainer'; import 'theme/index.scss'; +import 'lib/constants'; const store = configureStore(); ReactDOM.render( - + , From 8be6f0771daa45e95b172752e4230087f255446a Mon Sep 17 00:00:00 2001 From: German Osin Date: Wed, 2 Jun 2021 17:58:16 +0300 Subject: [PATCH 05/10] Refactoring --- .../com/provectus/kafka/ui/config/Config.java | 4 +- .../kafka/ui/controller/StaticController.java | 59 ++++++----- .../ProtobufFileRecordDeserializer.java | 8 +- .../deserialization/RecordDeserializer.java | 2 +- .../SchemaRegistryRecordDeserializer.java | 98 ++++++++++++------- .../SimpleRecordDeserializer.java | 6 +- .../provectus/kafka/ui/util/NumberUtil.java | 4 + .../provectus/kafka/ui/util/ResourceUtil.java | 20 ++++ 8 files changed, 127 insertions(+), 74 deletions(-) create mode 100644 kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/ResourceUtil.java diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/Config.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/Config.java index de2f3775421..11b987fa6d9 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/Config.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/config/Config.java @@ -22,7 +22,7 @@ public KeyedObjectPool pool() { } private GenericKeyedObjectPoolConfig poolConfig() { - GenericKeyedObjectPoolConfig poolConfig = new GenericKeyedObjectPoolConfig(); + final var poolConfig = new GenericKeyedObjectPoolConfig(); poolConfig.setMaxIdlePerKey(3); poolConfig.setMaxTotalPerKey(3); return poolConfig; @@ -30,7 +30,7 @@ private GenericKeyedObjectPoolConfig poolConfig() { @Bean public MBeanExporter exporter() { - final MBeanExporter exporter = new MBeanExporter(); + final var exporter = new MBeanExporter(); exporter.setAutodetect(true); exporter.setExcludedBeans("pool"); return exporter; diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java index eddc886a48d..01e2b635f0d 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java @@ -1,26 +1,16 @@ package com.provectus.kafka.ui.controller; -import com.provectus.kafka.ui.api.BrokersApi; -import com.provectus.kafka.ui.model.Broker; -import com.provectus.kafka.ui.model.BrokerMetrics; -import com.provectus.kafka.ui.service.ClusterService; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; +import com.provectus.kafka.ui.util.ResourceUtil; +import java.util.concurrent.atomic.AtomicReference; import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.core.io.Resource; import org.springframework.http.ResponseEntity; -import org.springframework.util.FileCopyUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.server.ServerWebExchange; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @RestController @@ -31,26 +21,35 @@ public class StaticController { @Value("classpath:static/index.html") private Resource indexFile; + private final AtomicReference renderedIndexFile = new AtomicReference<>(); - @RequestMapping(value = "/index.html", - produces = { "text/html" }, - method = RequestMethod.GET) - public Mono> getIndex(ServerWebExchange exchange) throws IOException { - - String contextPath = serverProperties.getServlet().getContextPath() != null - ? serverProperties.getServlet().getContextPath() : ""; - - String data = asString(indexFile) - .replace("./static", contextPath + "/static") - .replace("window.basePath=\"/\"", "window.basePath=\"" + contextPath + "\""); - - return Mono.just(ResponseEntity.ok(data)); + @GetMapping(value = "/index.html", produces = { "text/html" }) + public Mono> getIndex() { + return Mono.just(ResponseEntity.ok(getRenderedIndexFile())); } - public static String asString(Resource resource) throws IOException { - try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) { - return FileCopyUtils.copyToString(reader); + public String getRenderedIndexFile() { + String rendered = renderedIndexFile.get(); + if (rendered == null) { + rendered = buildIndexFile(); + if (renderedIndexFile.compareAndSet(null, rendered)) { + return rendered; + } else { + return renderedIndexFile.get(); + } + } else { + return rendered; } } + @SneakyThrows + private String buildIndexFile() { + final String contextPath = serverProperties.getServlet().getContextPath() != null + ? serverProperties.getServlet().getContextPath() : ""; + final String staticPath = contextPath + "/static"; + return ResourceUtil.readAsString(indexFile) + .replace("href=\"./static", "href=\""+staticPath) + .replace("src=\"./static", "src=\""+staticPath) + .replace("window.basePath=\"/\"", "window.basePath=\"" + contextPath + "\""); + } } diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/ProtobufFileRecordDeserializer.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/ProtobufFileRecordDeserializer.java index a2addd676e9..da1160ef4fb 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/ProtobufFileRecordDeserializer.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/ProtobufFileRecordDeserializer.java @@ -26,16 +26,16 @@ public ProtobufFileRecordDeserializer(Path protobufSchemaPath, String messageNam } @Override - public Object deserialize(ConsumerRecord record) { + public Object deserialize(ConsumerRecord msg) { try { - final DynamicMessage message = DynamicMessage.parseFrom( + final var message = DynamicMessage.parseFrom( protobufSchema.toDescriptor(), - new ByteArrayInputStream(record.value().get()) + new ByteArrayInputStream(msg.value().get()) ); byte[] bytes = ProtobufSchemaUtils.toJson(message); return parseJson(bytes); } catch (Throwable e) { - throw new RuntimeException("Failed to parse record from topic " + record.topic(), e); + throw new RuntimeException("Failed to parse record from topic " + msg.topic(), e); } } diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/RecordDeserializer.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/RecordDeserializer.java index 32fbb3af3fd..d175009c63c 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/RecordDeserializer.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/RecordDeserializer.java @@ -5,5 +5,5 @@ public interface RecordDeserializer { - Object deserialize(ConsumerRecord record); + Object deserialize(ConsumerRecord msg); } diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java index 49c3942baff..c4b75c9f06d 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.google.protobuf.Message; import com.provectus.kafka.ui.model.KafkaCluster; +import io.confluent.kafka.schemaregistry.ParsedSchema; import io.confluent.kafka.schemaregistry.SchemaProvider; import io.confluent.kafka.schemaregistry.avro.AvroSchemaProvider; import io.confluent.kafka.schemaregistry.avro.AvroSchemaUtils; @@ -16,14 +17,17 @@ import io.confluent.kafka.serializers.KafkaAvroDeserializer; import io.confluent.kafka.serializers.protobuf.KafkaProtobufDeserializer; import java.io.IOException; +import java.nio.ByteBuffer; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; +import lombok.SneakyThrows; import lombok.extern.log4j.Log4j2; import org.apache.avro.generic.GenericRecord; import org.apache.kafka.clients.consumer.ConsumerRecord; +import org.apache.kafka.common.errors.SerializationException; import org.apache.kafka.common.serialization.StringDeserializer; import org.apache.kafka.common.utils.Bytes; @@ -99,57 +103,83 @@ private MessageFormat getMessageFormat(ConsumerRecord record) { return topicFormatMap.computeIfAbsent(record.topic(), k -> detectFormat(record)); } - private MessageFormat detectFormat(ConsumerRecord record) { - String schemaName = String.format(cluster.getSchemaNameTemplate(), record.topic()); + private MessageFormat detectFormat(ConsumerRecord msg) { if (schemaRegistryClient != null) { try { - final List versions = schemaRegistryClient.getAllVersions(schemaName); - if (!versions.isEmpty()) { - final Integer version = versions.iterator().next(); - final String subjectName = String.format(cluster.getSchemaNameTemplate(), record.topic()); - final Schema schema = schemaRegistryClient.getByVersion(subjectName, version, false); - if (schema.getSchemaType().equals(MessageFormat.PROTOBUF.name())) { + final Optional type = getSchemaFromMessage(msg).or(() -> getSchemaBySubject(msg)); + if (type.isPresent()) { + if (type.equals(MessageFormat.PROTOBUF.name())) { try { - protobufDeserializer.deserialize(record.topic(), record.value().get()); + protobufDeserializer.deserialize(msg.topic(), msg.value().get()); return MessageFormat.PROTOBUF; } catch (Throwable e) { - log.info("Failed to get Protobuf schema for topic {}", record.topic(), e); + log.info("Failed to get Protobuf schema for topic {}", msg.topic(), e); } - } else if (schema.getSchemaType().equals(MessageFormat.AVRO.name())) { + } else if (type.equals(MessageFormat.AVRO.name())) { try { - avroDeserializer.deserialize(record.topic(), record.value().get()); + avroDeserializer.deserialize(msg.topic(), msg.value().get()); return MessageFormat.AVRO; } catch (Throwable e) { - log.info("Failed to get Avro schema for topic {}", record.topic(), e); + log.info("Failed to get Avro schema for topic {}", msg.topic(), e); } - } else if (schema.getSchemaType().equals(MessageFormat.JSON.name())) { + } else if (type.equals(MessageFormat.JSON.name())) { try { - parseJsonRecord(record); + parseJsonRecord(msg); return MessageFormat.JSON; } catch (IOException e) { - log.info("Failed to parse json from topic {}", record.topic()); + log.info("Failed to parse json from topic {}", msg.topic()); } } } - } catch (RestClientException | IOException e) { - log.warn("Failed to get Schema for topic {}", record.topic(), e); + } catch (Exception e) { + log.warn("Failed to get Schema for topic {}", msg.topic(), e); } } try { - parseJsonRecord(record); + parseJsonRecord(msg); return MessageFormat.JSON; } catch (IOException e) { - log.info("Failed to parse json from topic {}", record.topic()); + log.info("Failed to parse json from topic {}", msg.topic()); } return MessageFormat.STRING; } - private Object parseAvroRecord(ConsumerRecord record) throws IOException { - String topic = record.topic(); - if (record.value() != null && avroDeserializer != null) { - byte[] valueBytes = record.value().get(); + @SneakyThrows + private Optional getSchemaFromMessage(ConsumerRecord msg) { + Optional result = Optional.empty(); + final Bytes value = msg.value(); + if (value != null) { + ByteBuffer buffer = ByteBuffer.wrap(value.get()); + if (buffer.get() == 0) { + int id = buffer.getInt(); + result = Optional.ofNullable( + schemaRegistryClient.getSchemaById(id) + ).map(ParsedSchema::schemaType); + } + } + return result; + } + + @SneakyThrows + private Optional getSchemaBySubject(ConsumerRecord msg) { + String schemaName = String.format(cluster.getSchemaNameTemplate(), msg.topic()); + final List versions = schemaRegistryClient.getAllVersions(schemaName); + if (!versions.isEmpty()) { + final Integer version = versions.iterator().next(); + final String subjectName = String.format(cluster.getSchemaNameTemplate(), msg.topic()); + final Schema schema = schemaRegistryClient.getByVersion(subjectName, version, false); + return Optional.ofNullable(schema).map(Schema::getSchemaType); + } else { + return Optional.empty(); + } + } + + private Object parseAvroRecord(ConsumerRecord msg) throws IOException { + String topic = msg.topic(); + if (msg.value() != null && avroDeserializer != null) { + byte[] valueBytes = msg.value().get(); GenericRecord avroRecord = (GenericRecord) avroDeserializer.deserialize(topic, valueBytes); byte[] bytes = AvroSchemaUtils.toJson(avroRecord); return parseJson(bytes); @@ -158,10 +188,10 @@ private Object parseAvroRecord(ConsumerRecord record) throws IOExc } } - private Object parseProtobufRecord(ConsumerRecord record) throws IOException { - String topic = record.topic(); - if (record.value() != null && protobufDeserializer != null) { - byte[] valueBytes = record.value().get(); + private Object parseProtobufRecord(ConsumerRecord msg) throws IOException { + String topic = msg.topic(); + if (msg.value() != null && protobufDeserializer != null) { + byte[] valueBytes = msg.value().get(); final Message message = protobufDeserializer.deserialize(topic, valueBytes); byte[] bytes = ProtobufSchemaUtils.toJson(message); return parseJson(bytes); @@ -170,8 +200,8 @@ private Object parseProtobufRecord(ConsumerRecord record) throws I } } - private Object parseJsonRecord(ConsumerRecord record) throws IOException { - var value = record.value(); + private Object parseJsonRecord(ConsumerRecord msg) throws IOException { + var value = msg.value(); if (value == null) { return Map.of(); } @@ -184,12 +214,12 @@ private Object parseJson(byte[] bytes) throws IOException { }); } - private Object parseStringRecord(ConsumerRecord record) { - String topic = record.topic(); - if (record.value() == null) { + private Object parseStringRecord(ConsumerRecord msg) { + String topic = msg.topic(); + if (msg.value() == null) { return Map.of(); } - byte[] valueBytes = record.value().get(); + byte[] valueBytes = msg.value().get(); return stringDeserializer.deserialize(topic, valueBytes); } diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SimpleRecordDeserializer.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SimpleRecordDeserializer.java index 4dabd18ac5d..dc22ef4ff54 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SimpleRecordDeserializer.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SimpleRecordDeserializer.java @@ -9,9 +9,9 @@ public class SimpleRecordDeserializer implements RecordDeserializer { private final StringDeserializer stringDeserializer = new StringDeserializer(); @Override - public Object deserialize(ConsumerRecord record) { - if (record.value() != null) { - return stringDeserializer.deserialize(record.topic(), record.value().get()); + public Object deserialize(ConsumerRecord msg) { + if (msg.value() != null) { + return stringDeserializer.deserialize(msg.topic(), msg.value().get()); } else { return "empty"; } diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/NumberUtil.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/NumberUtil.java index 3f557f8e368..a729f16c472 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/NumberUtil.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/NumberUtil.java @@ -3,6 +3,10 @@ import org.apache.commons.lang3.math.NumberUtils; public class NumberUtil { + + private NumberUtil() { + } + public static boolean isNumeric(Object value) { return value != null && NumberUtils.isCreatable(value.toString()); } diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/ResourceUtil.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/ResourceUtil.java new file mode 100644 index 00000000000..1b499169264 --- /dev/null +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/util/ResourceUtil.java @@ -0,0 +1,20 @@ +package com.provectus.kafka.ui.util; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.StandardCharsets; +import org.springframework.core.io.Resource; +import org.springframework.util.FileCopyUtils; + +public class ResourceUtil { + + private ResourceUtil() { + } + + public static String readAsString(Resource resource) throws IOException { + try (Reader reader = new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8)) { + return FileCopyUtils.copyToString(reader); + } + } +} From b85f934ff30a7935370100082534fadb96360b35 Mon Sep 17 00:00:00 2001 From: German Osin Date: Wed, 2 Jun 2021 18:09:43 +0300 Subject: [PATCH 06/10] Refactoring --- .../com/provectus/kafka/ui/controller/StaticController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java index 01e2b635f0d..dd87b349a4b 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/controller/StaticController.java @@ -48,8 +48,8 @@ private String buildIndexFile() { ? serverProperties.getServlet().getContextPath() : ""; final String staticPath = contextPath + "/static"; return ResourceUtil.readAsString(indexFile) - .replace("href=\"./static", "href=\""+staticPath) - .replace("src=\"./static", "src=\""+staticPath) + .replace("href=\"./static", "href=\"" + staticPath) + .replace("src=\"./static", "src=\"" + staticPath) .replace("window.basePath=\"/\"", "window.basePath=\"" + contextPath + "\""); } } From 75ec74ef43e5c6a2c9715501159f430949927e3c Mon Sep 17 00:00:00 2001 From: German Osin Date: Wed, 2 Jun 2021 18:30:07 +0300 Subject: [PATCH 07/10] fixed comparison bugs --- .../deserialization/SchemaRegistryRecordDeserializer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java index c4b75c9f06d..32f43573042 100644 --- a/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java +++ b/kafka-ui-api/src/main/java/com/provectus/kafka/ui/deserialization/SchemaRegistryRecordDeserializer.java @@ -108,21 +108,21 @@ private MessageFormat detectFormat(ConsumerRecord msg) { try { final Optional type = getSchemaFromMessage(msg).or(() -> getSchemaBySubject(msg)); if (type.isPresent()) { - if (type.equals(MessageFormat.PROTOBUF.name())) { + if (type.get().equals(MessageFormat.PROTOBUF.name())) { try { protobufDeserializer.deserialize(msg.topic(), msg.value().get()); return MessageFormat.PROTOBUF; } catch (Throwable e) { log.info("Failed to get Protobuf schema for topic {}", msg.topic(), e); } - } else if (type.equals(MessageFormat.AVRO.name())) { + } else if (type.get().equals(MessageFormat.AVRO.name())) { try { avroDeserializer.deserialize(msg.topic(), msg.value().get()); return MessageFormat.AVRO; } catch (Throwable e) { log.info("Failed to get Avro schema for topic {}", msg.topic(), e); } - } else if (type.equals(MessageFormat.JSON.name())) { + } else if (type.get().equals(MessageFormat.JSON.name())) { try { parseJsonRecord(msg); return MessageFormat.JSON; From 8ee10ffb2626d06cd102cb47fae37d5670552b6e Mon Sep 17 00:00:00 2001 From: RustamGimadiev Date: Wed, 2 Jun 2021 19:46:50 +0300 Subject: [PATCH 08/10] dirty --- kafka-ui-react-app/src/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kafka-ui-react-app/src/index.tsx b/kafka-ui-react-app/src/index.tsx index 0b7931418c2..28fab237bf4 100644 --- a/kafka-ui-react-app/src/index.tsx +++ b/kafka-ui-react-app/src/index.tsx @@ -12,7 +12,7 @@ const store = configureStore(); ReactDOM.render( - + , From 91b5d7a5ea012b6f6891b29b59c943e1bd23d010 Mon Sep 17 00:00:00 2001 From: RustamGimadiev Date: Thu, 3 Jun 2021 13:29:42 +0300 Subject: [PATCH 09/10] clenaup --- README.md | 6 +----- kafka-ui-react-app/.env | 3 +-- kafka-ui-react-app/src/lib/constants.ts | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c443569afa3..1ecd42229bb 100644 --- a/README.md +++ b/README.md @@ -153,6 +153,7 @@ For example, if you want to use an environment variable to set the `name` parame |Name |Description |-----------------------|------------------------------- +|`SERVER_SERVLET_CONTEXT_PATH` | URI basePath |`KAFKA_CLUSTERS_0_NAME` | Cluster name |`KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS` |Address where to connect |`KAFKA_CLUSTERS_0_ZOOKEEPER` | Zookeper service address @@ -163,8 +164,3 @@ For example, if you want to use an environment variable to set the `name` parame |`KAFKA_CLUSTERS_0_READONLY` |Enable read only mode. Default: false |`LOGGING_LEVEL_ROOT` | Setting log level (all, debug, info, warn, error, fatal, off). Default: debug |`LOGGING_LEVEL_COM_PROVECTUS` |Setting log level (all, debug, info, warn, error, fatal, off). Default: debug - - - - - diff --git a/kafka-ui-react-app/.env b/kafka-ui-react-app/.env index c72dff4ca9b..4e768b56d84 100644 --- a/kafka-ui-react-app/.env +++ b/kafka-ui-react-app/.env @@ -1,2 +1 @@ -# Kafka REST API -REACT_APP_API_URL= +# \ No newline at end of file diff --git a/kafka-ui-react-app/src/lib/constants.ts b/kafka-ui-react-app/src/lib/constants.ts index c3182a4b62e..6a559b13a4e 100644 --- a/kafka-ui-react-app/src/lib/constants.ts +++ b/kafka-ui-react-app/src/lib/constants.ts @@ -7,7 +7,7 @@ declare global { } export const BASE_PARAMS: ConfigurationParameters = { - basePath: process.env.REACT_APP_API_URL || window.basePath || '', + basePath: window.basePath, credentials: 'include', headers: { 'Content-Type': 'application/json', From b20c7726f42c9cf7b01c5aef0b04cff5e547811a Mon Sep 17 00:00:00 2001 From: Oleg Shuralev Date: Thu, 3 Jun 2021 15:13:14 +0300 Subject: [PATCH 10/10] Update React app --- kafka-ui-react-app/package-lock.json | 426 ++++++++++-------------- kafka-ui-react-app/package.json | 3 +- kafka-ui-react-app/src/index.tsx | 2 +- kafka-ui-react-app/src/lib/constants.ts | 2 +- 4 files changed, 181 insertions(+), 252 deletions(-) diff --git a/kafka-ui-react-app/package-lock.json b/kafka-ui-react-app/package-lock.json index 753b50a5f49..ea72d54cdcd 100644 --- a/kafka-ui-react-app/package-lock.json +++ b/kafka-ui-react-app/package-lock.json @@ -88,7 +88,8 @@ "typescript": "^4.2.3" }, "engines": { - "node": ">=14.15.4" + "node": ">=14.15.4", + "npm": ">=7.15.1" } }, "node_modules/@babel/code-frame": { @@ -1893,7 +1894,6 @@ "jest-resolve": "^26.6.2", "jest-util": "^26.6.2", "jest-worker": "^26.6.2", - "node-notifier": "^8.0.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^4.0.1", @@ -2977,47 +2977,6 @@ "debug": "^4.1.1" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.24.0.tgz", - "integrity": "sha512-9+WYJGDnuC9VtYLqBhcSuM7du75fyCS/ypC8c5g7Sdw7pGL4NDTbeH38eJPfzIydCHZDoOgjloxSAA3+4l/zsA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/visitor-keys": "4.24.0" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.24.0.tgz", - "integrity": "sha512-tkZUBgDQKdvfs8L47LaqxojKDE+mIUmOzdz7r+u+U54l3GDkTpEbQ1Jp3cNqqAU9vMUCBA1fitsIhm7yN0vx9Q==", - "dev": true - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.24.0.tgz", - "integrity": "sha512-kBDitL/by/HK7g8CYLT7aKpAwlR8doshfWz8d71j97n5kUa5caHWvY0RvEUEanL/EqBJoANev8Xc/mQ6LLwXGA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/visitor-keys": "4.24.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.24.0.tgz", - "integrity": "sha512-4ox1sjmGHIxjEDBnMCtWFFhErXtKA1Ec0sBpuz0fqf3P+g3JFGyTxxbF06byw0FRsPnnbq44cKivH7Ks1/0s6g==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.24.0", - "eslint-visitor-keys": "^2.0.0" - } - }, "node_modules/@typescript-eslint/parser/node_modules/debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -3033,15 +2992,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "node_modules/@typescript-eslint/parser/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - } - }, "node_modules/@typescript-eslint/scope-manager": { "version": "4.24.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.24.0.tgz", @@ -4716,16 +4666,26 @@ } }, "node_modules/browserslist": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", - "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001181", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.649", + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", - "node-releases": "^1.1.70" + "node-releases": "^1.1.71" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" } }, "node_modules/bs-logger": { @@ -4947,10 +4907,14 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001207", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001207.tgz", - "integrity": "sha512-UPQZdmAsyp2qfCTiMU/zqGSWOYaY9F9LL61V8f+8MrubsaDGpaHD9HRV/EWZGULZn0Hxu48SKzI5DgFwTvHuYw==", - "dev": true + "version": "1.0.30001233", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001233.tgz", + "integrity": "sha512-BmkbxLfStqiPA7IEzQpIk0UFZFf3A4E6fzjPJ6OR+bFC2L8ES9J8zGA/asoi47p8XDVkev+WJo2I2Nc8c/34Yg==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + } }, "node_modules/capture-exit": { "version": "2.0.0", @@ -5920,21 +5884,24 @@ "dev": true }, "node_modules/cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", "dev": true, "dependencies": { "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", + "cssnano-preset-default": "^4.0.8", "is-resolvable": "^1.0.0", "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", "dev": true, "dependencies": { "css-declaration-sorter": "^4.0.1", @@ -5965,8 +5932,11 @@ "postcss-ordered-values": "^4.1.2", "postcss-reduce-initial": "^4.0.3", "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", + "postcss-svgo": "^4.0.3", "postcss-unique-selectors": "^4.0.1" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/cssnano-util-get-arguments": { @@ -6457,9 +6427,9 @@ "dev": true }, "node_modules/dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", "dev": true, "dependencies": { "ip": "^1.1.0", @@ -6617,9 +6587,6 @@ "resolved": "https://registry.npmjs.org/easy-table/-/easy-table-1.1.0.tgz", "integrity": "sha1-hvmrTBAvA3G3KXuSplHVgkvIy3M=", "dev": true, - "dependencies": { - "wcwidth": ">=1.0.1" - }, "optionalDependencies": { "wcwidth": ">=1.0.1" } @@ -6647,9 +6614,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.3.707", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.707.tgz", - "integrity": "sha512-BqddgxNPrcWnbDdJw7SzXVzPmp+oiyjVrc7tkQVaznPGSS9SKZatw6qxoP857M+HbOyyqJQwYQtsuFIMSTNSZA==", + "version": "1.3.745", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.745.tgz", + "integrity": "sha512-ZZCx4CS3kYT3BREYiIXocDqlNPT56KfdTS1Ogo4yvxRriBqiEXCDTLIQZT/zNVtby91xTWMMxW2NBiXh8bpLHw==", "dev": true }, "node_modules/elliptic": { @@ -9025,9 +8992,9 @@ "dev": true }, "node_modules/hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "node_modules/hpack.js": { @@ -9054,12 +9021,6 @@ "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", "dev": true }, - "node_modules/html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", - "dev": true - }, "node_modules/html-element-map": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.0.tgz", @@ -9936,15 +9897,6 @@ "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", "dev": true }, - "node_modules/is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", - "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", - "dev": true, - "dependencies": { - "html-comment-regex": "^1.1.0" - } - }, "node_modules/is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -10434,7 +10386,6 @@ "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", - "fsevents": "^2.1.2", "graceful-fs": "^4.2.4", "jest-regex-util": "^26.0.0", "jest-serializer": "^26.6.2", @@ -12691,10 +12642,16 @@ "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, "node_modules/nanoid": { - "version": "3.1.22", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz", - "integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==", - "dev": true + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } }, "node_modules/nanomatch": { "version": "1.2.13", @@ -14037,12 +13994,11 @@ } }, "node_modules/postcss-initial": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.2.tgz", - "integrity": "sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz", + "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==", "dev": true, "dependencies": { - "lodash.template": "^4.5.0", "postcss": "^7.0.2" } }, @@ -14649,14 +14605,21 @@ } }, "node_modules/postcss-safe-parser/node_modules/postcss": { - "version": "8.2.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.9.tgz", - "integrity": "sha512-b+TmuIL4jGtCHtoLi+G/PisuIl9avxs8IZMSmlABRwNz5RLUUACrC+ws81dcomz1nRezm5YPdXiMEzBEKgYn+Q==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", "dev": true, "dependencies": { "colorette": "^1.2.2", - "nanoid": "^3.1.22", - "source-map": "^0.6.1" + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" } }, "node_modules/postcss-selector-matches": { @@ -14692,15 +14655,17 @@ } }, "node_modules/postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", - "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", "dev": true, "dependencies": { - "is-svg": "^3.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0", "svgo": "^1.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/postcss-svgo/node_modules/postcss-value-parser": { @@ -15481,7 +15446,6 @@ "eslint-webpack-plugin": "^2.5.2", "file-loader": "6.1.1", "fs-extra": "^9.0.1", - "fsevents": "^2.1.3", "html-webpack-plugin": "4.5.0", "identity-obj-proxy": "3.0.0", "jest": "26.6.0", @@ -16186,9 +16150,9 @@ "dev": true }, "node_modules/resolve-url-loader": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz", - "integrity": "sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.3.tgz", + "integrity": "sha512-WbDSNFiKPPLem1ln+EVTE+bFUBdTTytfQZWbmghroaFNFaAVmGq0Saqw6F/306CwgPXsGwXVxbODE+3xAo/YbA==", "dev": true, "dependencies": { "adjust-sourcemap-loader": "3.0.0", @@ -16201,6 +16165,9 @@ "rework": "1.0.1", "rework-visit": "1.0.0", "source-map": "0.6.1" + }, + "engines": { + "node": ">=6.0.0" } }, "node_modules/resolve-url-loader/node_modules/ansi-styles": { @@ -17185,6 +17152,15 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, + "node_modules/source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map-resolve": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", @@ -18874,10 +18850,8 @@ "integrity": "sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==", "dev": true, "dependencies": { - "chokidar": "^3.4.1", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0", - "watchpack-chokidar2": "^2.0.1" + "neo-async": "^2.5.0" }, "optionalDependencies": { "chokidar": "^3.4.1", @@ -19261,7 +19235,6 @@ "anymatch": "^2.0.0", "async-each": "^1.0.1", "braces": "^2.3.2", - "fsevents": "^1.2.7", "glob-parent": "^3.1.0", "inherits": "^2.0.3", "is-binary-path": "^1.0.0", @@ -19523,9 +19496,9 @@ } }, "node_modules/webpack-dev-server/node_modules/ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "dev": true, "dependencies": { "async-limiter": "~1.0.0" @@ -20218,10 +20191,25 @@ } }, "node_modules/ws": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", - "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==", - "dev": true + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } }, "node_modules/xml": { "version": "1.0.1", @@ -23254,47 +23242,6 @@ "debug": "^4.1.1" }, "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.24.0.tgz", - "integrity": "sha512-9+WYJGDnuC9VtYLqBhcSuM7du75fyCS/ypC8c5g7Sdw7pGL4NDTbeH38eJPfzIydCHZDoOgjloxSAA3+4l/zsA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/visitor-keys": "4.24.0" - } - }, - "@typescript-eslint/types": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.24.0.tgz", - "integrity": "sha512-tkZUBgDQKdvfs8L47LaqxojKDE+mIUmOzdz7r+u+U54l3GDkTpEbQ1Jp3cNqqAU9vMUCBA1fitsIhm7yN0vx9Q==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.24.0.tgz", - "integrity": "sha512-kBDitL/by/HK7g8CYLT7aKpAwlR8doshfWz8d71j97n5kUa5caHWvY0RvEUEanL/EqBJoANev8Xc/mQ6LLwXGA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.24.0", - "@typescript-eslint/visitor-keys": "4.24.0", - "debug": "^4.1.1", - "globby": "^11.0.1", - "is-glob": "^4.0.1", - "semver": "^7.3.2", - "tsutils": "^3.17.1" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.24.0.tgz", - "integrity": "sha512-4ox1sjmGHIxjEDBnMCtWFFhErXtKA1Ec0sBpuz0fqf3P+g3JFGyTxxbF06byw0FRsPnnbq44cKivH7Ks1/0s6g==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.24.0", - "eslint-visitor-keys": "^2.0.0" - } - }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", @@ -23309,15 +23256,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } } } }, @@ -25031,16 +24969,16 @@ } }, "browserslist": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.3.tgz", - "integrity": "sha512-vIyhWmIkULaq04Gt93txdh+j02yX/JzlyhLYbV3YQCn/zvES3JnY7TifHHvvr1w5hTDluNKMkV05cs4vy8Q7sw==", + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001181", - "colorette": "^1.2.1", - "electron-to-chromium": "^1.3.649", + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", "escalade": "^3.1.1", - "node-releases": "^1.1.70" + "node-releases": "^1.1.71" } }, "bs-logger": { @@ -25272,9 +25210,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001207", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001207.tgz", - "integrity": "sha512-UPQZdmAsyp2qfCTiMU/zqGSWOYaY9F9LL61V8f+8MrubsaDGpaHD9HRV/EWZGULZn0Hxu48SKzI5DgFwTvHuYw==", + "version": "1.0.30001233", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001233.tgz", + "integrity": "sha512-BmkbxLfStqiPA7IEzQpIk0UFZFf3A4E6fzjPJ6OR+bFC2L8ES9J8zGA/asoi47p8XDVkev+WJo2I2Nc8c/34Yg==", "dev": true }, "capture-exit": { @@ -26269,13 +26207,13 @@ "dev": true }, "cssnano": { - "version": "4.1.10", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", - "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.11.tgz", + "integrity": "sha512-6gZm2htn7xIPJOHY824ERgj8cNPgPxyCSnkXc4v7YvNW+TdVfzgngHcEhy/8D11kUWRUMbke+tC+AUcUsnMz2g==", "dev": true, "requires": { "cosmiconfig": "^5.0.0", - "cssnano-preset-default": "^4.0.7", + "cssnano-preset-default": "^4.0.8", "is-resolvable": "^1.0.0", "postcss": "^7.0.0" }, @@ -26311,9 +26249,9 @@ } }, "cssnano-preset-default": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", - "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.8.tgz", + "integrity": "sha512-LdAyHuq+VRyeVREFmuxUZR1TXjQm8QQU/ktoo/x7bz+SdOge1YKc5eMN6pRW7YWBmyq59CqYba1dJ5cUukEjLQ==", "dev": true, "requires": { "css-declaration-sorter": "^4.0.1", @@ -26344,7 +26282,7 @@ "postcss-ordered-values": "^4.1.2", "postcss-reduce-initial": "^4.0.3", "postcss-reduce-transforms": "^4.0.2", - "postcss-svgo": "^4.0.2", + "postcss-svgo": "^4.0.3", "postcss-unique-selectors": "^4.0.1" } }, @@ -26822,9 +26760,9 @@ "dev": true }, "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.4.tgz", + "integrity": "sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA==", "dev": true, "requires": { "ip": "^1.1.0", @@ -27015,9 +26953,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.707", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.707.tgz", - "integrity": "sha512-BqddgxNPrcWnbDdJw7SzXVzPmp+oiyjVrc7tkQVaznPGSS9SKZatw6qxoP857M+HbOyyqJQwYQtsuFIMSTNSZA==", + "version": "1.3.745", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.745.tgz", + "integrity": "sha512-ZZCx4CS3kYT3BREYiIXocDqlNPT56KfdTS1Ogo4yvxRriBqiEXCDTLIQZT/zNVtby91xTWMMxW2NBiXh8bpLHw==", "dev": true }, "elliptic": { @@ -29469,9 +29407,9 @@ "dev": true }, "hosted-git-info": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", "dev": true }, "hpack.js": { @@ -29498,12 +29436,6 @@ "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", "dev": true }, - "html-comment-regex": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", - "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", - "dev": true - }, "html-element-map": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/html-element-map/-/html-element-map-1.3.0.tgz", @@ -30406,15 +30338,6 @@ "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", "dev": true }, - "is-svg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", - "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", - "dev": true, - "requires": { - "html-comment-regex": "^1.1.0" - } - }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -33220,9 +33143,9 @@ "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, "nanoid": { - "version": "3.1.22", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.22.tgz", - "integrity": "sha512-/2ZUaJX2ANuLtTvqTlgqBQNJoQO398KyJgZloL0PZkC0dpysjncRUPsFe3DUPzz/y3h+u7C46np8RMuvF3jsSQ==", + "version": "3.1.23", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", + "integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==", "dev": true }, "nanomatch": { @@ -34648,12 +34571,11 @@ } }, "postcss-initial": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.2.tgz", - "integrity": "sha512-ugA2wKonC0xeNHgirR4D3VWHs2JcU08WAi1KFLVcnb7IN89phID6Qtg2RIctWbnvp1TM2BOmDtX8GGLCKdR8YA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/postcss-initial/-/postcss-initial-3.0.4.tgz", + "integrity": "sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg==", "dev": true, "requires": { - "lodash.template": "^4.5.0", "postcss": "^7.0.2" } }, @@ -35298,14 +35220,14 @@ }, "dependencies": { "postcss": { - "version": "8.2.9", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.2.9.tgz", - "integrity": "sha512-b+TmuIL4jGtCHtoLi+G/PisuIl9avxs8IZMSmlABRwNz5RLUUACrC+ws81dcomz1nRezm5YPdXiMEzBEKgYn+Q==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.0.tgz", + "integrity": "sha512-+ogXpdAjWGa+fdYY5BQ96V/6tAo+TdSSIMP5huJBIygdWwKtVoB5JWZ7yUd4xZ8r+8Kvvx4nyg/PQ071H4UtcQ==", "dev": true, "requires": { "colorette": "^1.2.2", - "nanoid": "^3.1.22", - "source-map": "^0.6.1" + "nanoid": "^3.1.23", + "source-map-js": "^0.6.2" } } } @@ -35343,12 +35265,11 @@ } }, "postcss-svgo": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", - "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.3.tgz", + "integrity": "sha512-NoRbrcMWTtUghzuKSoIm6XV+sJdvZ7GZSc3wdBN0W19FTtp2ko8NqLsgoh/m9CzNhU3KLPvQmjIwtaNFkaFTvw==", "dev": true, "requires": { - "is-svg": "^3.0.0", "postcss": "^7.0.0", "postcss-value-parser": "^3.0.0", "svgo": "^1.0.0" @@ -36820,9 +36741,9 @@ "dev": true }, "resolve-url-loader": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.2.tgz", - "integrity": "sha512-QEb4A76c8Mi7I3xNKXlRKQSlLBwjUV/ULFMP+G7n3/7tJZ8MG5wsZ3ucxP1Jz8Vevn6fnJsxDx9cIls+utGzPQ==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.3.tgz", + "integrity": "sha512-WbDSNFiKPPLem1ln+EVTE+bFUBdTTytfQZWbmghroaFNFaAVmGq0Saqw6F/306CwgPXsGwXVxbODE+3xAo/YbA==", "dev": true, "requires": { "adjust-sourcemap-loader": "3.0.0", @@ -37859,6 +37780,12 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, + "source-map-js": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz", + "integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==", + "dev": true + }, "source-map-resolve": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", @@ -40485,9 +40412,9 @@ } }, "ws": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", - "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.2.tgz", + "integrity": "sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==", "dev": true, "requires": { "async-limiter": "~1.0.0" @@ -40963,10 +40890,11 @@ } }, "ws": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.4.tgz", - "integrity": "sha512-Qm8k8ojNQIMx7S+Zp8u/uHOx7Qazv3Yv4q68MiWWWOJhiwG5W3x7iqmRtJo8xxrciZUY4vRxUTJCKuRnF28ZZw==", - "dev": true + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "requires": {} }, "xml": { "version": "1.0.1", diff --git a/kafka-ui-react-app/package.json b/kafka-ui-react-app/package.json index e8815efc962..3d0c58c8e46 100644 --- a/kafka-ui-react-app/package.json +++ b/kafka-ui-react-app/package.json @@ -118,7 +118,8 @@ "typescript": "^4.2.3" }, "engines": { - "node": ">=14.15.4" + "node": ">=14.15.4", + "npm": ">=7.15.1" }, "proxy": "http://localhost:8080", "jest": { diff --git a/kafka-ui-react-app/src/index.tsx b/kafka-ui-react-app/src/index.tsx index 28fab237bf4..c61eba1831f 100644 --- a/kafka-ui-react-app/src/index.tsx +++ b/kafka-ui-react-app/src/index.tsx @@ -12,7 +12,7 @@ const store = configureStore(); ReactDOM.render( - + , diff --git a/kafka-ui-react-app/src/lib/constants.ts b/kafka-ui-react-app/src/lib/constants.ts index 6a559b13a4e..7ee0e6de035 100644 --- a/kafka-ui-react-app/src/lib/constants.ts +++ b/kafka-ui-react-app/src/lib/constants.ts @@ -7,7 +7,7 @@ declare global { } export const BASE_PARAMS: ConfigurationParameters = { - basePath: window.basePath, + basePath: window.basePath || '', credentials: 'include', headers: { 'Content-Type': 'application/json',