diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5d51b7ace6..b5748142b4 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -72,6 +72,16 @@ jobs: AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} GITHUB_BRANCH: ${{ github.ref }} + - name: Publish helm charts to S3 + if: startsWith(github.ref, 'refs/heads/release') || startsWith(github.ref, 'refs/heads/main') || startsWith(github.ref, 'refs/heads/develop') + run: | + ./scripts/upload-helm-charts.sh + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_REGION : ${{ secrets.AWS_REGION }} + GITHUB_BRANCH: ${{ github.ref }} + - name: Publish http-client library to npm if: ${{ startsWith(github.ref, 'refs/heads/main') }} run: | diff --git a/VERSION b/VERSION index 83b4730498..697f087f37 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.27.1 +0.28.0 diff --git a/backend/model/metadata/src/main/java/co/airy/model/metadata/MetadataKeys.java b/backend/model/metadata/src/main/java/co/airy/model/metadata/MetadataKeys.java index 1bc2ebe9c2..4c44f2009c 100644 --- a/backend/model/metadata/src/main/java/co/airy/model/metadata/MetadataKeys.java +++ b/backend/model/metadata/src/main/java/co/airy/model/metadata/MetadataKeys.java @@ -18,6 +18,11 @@ public static class Contact { public static final String FETCH_STATE = "contact.fetch_state"; } + public static class Reaction { + public static final String EMOJI = "reaction.emoji"; + public static final String SENT_AT = "reaction.sent_at"; + } + public enum ContactFetchState { ok("ok"), failed("failed"); @@ -42,6 +47,7 @@ public static class ChannelKeys { public static class MessageKeys { public static final String SUGGESTIONS = "suggestions"; + public static final String SOURCE_ID = "source_id"; } } diff --git a/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/Connector.java b/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/Connector.java index e0835aa23b..4519270e04 100644 --- a/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/Connector.java +++ b/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/Connector.java @@ -7,12 +7,15 @@ import co.airy.core.sources.facebook.api.ApiException; import co.airy.core.sources.facebook.api.Mapper; import co.airy.core.sources.facebook.api.model.SendMessagePayload; +import co.airy.core.sources.facebook.api.model.SendMessageResponse; import co.airy.core.sources.facebook.api.model.UserProfile; import co.airy.core.sources.facebook.dto.Conversation; import co.airy.core.sources.facebook.dto.SendMessageRequest; import co.airy.log.AiryLoggerFactory; +import co.airy.model.metadata.MetadataKeys; import co.airy.spring.auth.IgnoreAuthPattern; import co.airy.spring.web.filters.RequestLoggingIgnorePatterns; +import org.apache.avro.specific.SpecificRecordBase; import org.apache.kafka.streams.KeyValue; import org.slf4j.Logger; import org.springframework.context.annotation.Bean; @@ -32,6 +35,7 @@ import static co.airy.model.metadata.MetadataKeys.ConversationKeys.ContactFetchState.ok; import static co.airy.model.metadata.MetadataRepository.getId; import static co.airy.model.metadata.MetadataRepository.newConversationMetadata; +import static co.airy.model.metadata.MetadataRepository.newMessageMetadata; @Component public class Connector { @@ -46,23 +50,24 @@ public class Connector { this.mapper = mapper; } - public Message sendMessage(SendMessageRequest sendMessageRequest) { + public List> sendMessage(SendMessageRequest sendMessageRequest) { final Message message = sendMessageRequest.getMessage(); final Conversation conversation = sendMessageRequest.getConversation(); if (isMessageStale(message)) { updateDeliveryState(message, DeliveryState.FAILED); - return message; + return List.of(KeyValue.pair(message.getId(), message)); } try { final String pageToken = conversation.getChannel().getToken(); final SendMessagePayload fbSendMessagePayload = mapper.fromSendMessageRequest(sendMessageRequest); - api.sendMessage(pageToken, fbSendMessagePayload); - + final SendMessageResponse response = api.sendMessage(pageToken, fbSendMessagePayload); + final Metadata metadata = newMessageMetadata(message.getId(), MetadataKeys.MessageKeys.SOURCE_ID, response.getMessageId()); updateDeliveryState(message, DeliveryState.DELIVERED); - return message; + + return List.of(KeyValue.pair(message.getId(), message), KeyValue.pair(getId(metadata).toString(), metadata)); } catch (ApiException e) { log.error(String.format("Failed to send a message to Facebook \n SendMessageRequest: %s \n Error Message: %s \n", sendMessageRequest, e.getMessage()), e); } catch (Exception e) { @@ -70,7 +75,7 @@ public Message sendMessage(SendMessageRequest sendMessageRequest) { } updateDeliveryState(message, DeliveryState.FAILED); - return message; + return List.of(KeyValue.pair(message.getId(), message)); } private boolean isMessageStale(Message message) { diff --git a/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/Stores.java b/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/Stores.java index 67631e609e..88bb636032 100644 --- a/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/Stores.java +++ b/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/Stores.java @@ -47,6 +47,7 @@ public class Stores implements ApplicationListener, Dis private final String channelsStore = "channels-store"; private final String applicationCommunicationChannels = new ApplicationCommunicationChannels().name(); private final String applicationCommunicationMetadata = new ApplicationCommunicationMetadata().name(); + private final String applicationCommunicationMessages = new ApplicationCommunicationMessages().name(); private final KafkaProducer producer; private final Connector connector; @@ -72,7 +73,7 @@ public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) && channel.getConnectionState().equals(ChannelConnectionState.CONNECTED)).toTable(); // Facebook messaging stream by conversation-id - final KStream messageStream = builder.stream(new ApplicationCommunicationMessages().name()) + final KStream messageStream = builder.stream(applicationCommunicationMessages) .filter((messageId, message) -> message != null && sources.contains(message.getSource())) .selectKey((messageId, message) -> message.getConversationId()); @@ -110,11 +111,17 @@ public void onApplicationEvent(ApplicationStartedEvent applicationStartedEvent) // Send outbound messages messageStream.filter((messageId, message) -> DeliveryState.PENDING.equals(message.getDeliveryState())) .join(contextTable, (message, conversation) -> new SendMessageRequest(conversation, message)) - .map((conversationId, sendMessageRequest) -> { - final Message message = connector.sendMessage(sendMessageRequest); - return KeyValue.pair(message.getId(), message); - }) - .to(new ApplicationCommunicationMessages().name()); + .flatMap((conversationId, sendMessageRequest) -> connector.sendMessage(sendMessageRequest)) + .to((recordId, record, context) -> { + if (record instanceof Metadata) { + return applicationCommunicationMetadata; + } + if (record instanceof Message) { + return applicationCommunicationMessages; + } + + throw new IllegalStateException("Unknown type for record " + record); + }); // Fetch missing metadata contextTable diff --git a/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/api/Api.java b/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/api/Api.java index ff9deeb6c9..1733a52bcc 100644 --- a/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/api/Api.java +++ b/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/api/Api.java @@ -6,6 +6,7 @@ import co.airy.core.sources.facebook.api.model.Pages; import co.airy.core.sources.facebook.api.model.Participants; import co.airy.core.sources.facebook.api.model.SendMessagePayload; +import co.airy.core.sources.facebook.api.model.SendMessageResponse; import co.airy.core.sources.facebook.api.model.UserProfile; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.databind.ObjectMapper; @@ -48,7 +49,7 @@ public class Api implements ApplicationListener { private RestTemplate restTemplate; - private static final String subscribedFields = "messages,messaging_postbacks,messaging_optins,message_deliveries,message_reads,messaging_payments,messaging_pre_checkouts,messaging_checkout_updates,messaging_account_linking,messaging_referrals,message_echoes,messaging_game_plays,standby,messaging_handovers,messaging_policy_enforcement,message_reactions,inbox_labels"; + private static final String subscribedFields = "messages,messaging_postbacks,messaging_optins,message_deliveries,message_reads,messaging_payments,messaging_pre_checkouts,messaging_checkout_updates,messaging_account_linking,messaging_referrals,message_echoes,messaging_game_plays,standby,messaging_handovers,messaging_policy_enforcement,message_reactions,inbox_labels,message_reactions"; private static final String baseUrl = "https://graph.facebook.com/v11.0"; private static final String requestTemplate = baseUrl + "/me/messages?access_token=%s"; private final String pageFields = "fields=id,name_with_location_descriptor,access_token,picture,is_webhooks_subscribed"; @@ -71,9 +72,10 @@ public Api(ObjectMapper objectMapper, RestTemplateBuilder restTemplateBuilder, this.apiSecret = apiSecret; } - public void sendMessage(final String pageToken, SendMessagePayload sendMessagePayload) { + public SendMessageResponse sendMessage(final String pageToken, SendMessagePayload sendMessagePayload) { String fbReqUrl = String.format(requestTemplate, pageToken); - restTemplate.postForEntity(fbReqUrl, new HttpEntity<>(sendMessagePayload, httpHeaders), FbSendMessageResponse.class); + final ResponseEntity responseEntity = restTemplate.postForEntity(fbReqUrl, new HttpEntity<>(sendMessagePayload, httpHeaders), SendMessageResponse.class); + return responseEntity.getBody(); } public List getPagesInfo(String accessToken) throws Exception { @@ -98,8 +100,6 @@ private T apiResponse(String url, HttpMethod method, Class clazz) throws return objectMapper.readValue(responseEntity.getBody(), clazz); } - - // https://developers.facebook.com/docs/messenger-platform/instagram/features/user-profile public UserProfile getInstagramProfile(String sourceConversationId, String token) { ResponseEntity responseEntity = restTemplate.getForEntity(baseUrl + "/{ig-id}?fields=name,profile_pic&access_token={access_token}", @@ -192,15 +192,4 @@ public void handleError(ClientHttpResponse response) throws IOException { .additionalMessageConverters(new MappingJackson2HttpMessageConverter(objectMapper)) .build(); } - - @Data - @NoArgsConstructor - @AllArgsConstructor - private static class FbSendMessageResponse { - @JsonProperty("recipient_id") - private String recipientId; - - @JsonProperty("message_id") - private String messageId; - } } diff --git a/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/api/model/SendMessageResponse.java b/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/api/model/SendMessageResponse.java new file mode 100644 index 0000000000..4f62d82411 --- /dev/null +++ b/backend/sources/facebook/connector/src/main/java/co/airy/core/sources/facebook/api/model/SendMessageResponse.java @@ -0,0 +1,16 @@ +package co.airy.core.sources.facebook.api.model; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +@AllArgsConstructor +public class SendMessageResponse { + @JsonProperty("recipient_id") + private String recipientId; + @JsonProperty("message_id") + private String messageId; +} diff --git a/backend/sources/facebook/connector/src/test/java/co/airy/core/sources/facebook/SendMessageTest.java b/backend/sources/facebook/connector/src/test/java/co/airy/core/sources/facebook/SendMessageTest.java index d9419fe145..6e62a0db64 100644 --- a/backend/sources/facebook/connector/src/test/java/co/airy/core/sources/facebook/SendMessageTest.java +++ b/backend/sources/facebook/connector/src/test/java/co/airy/core/sources/facebook/SendMessageTest.java @@ -6,6 +6,7 @@ import co.airy.avro.communication.Message; import co.airy.core.sources.facebook.api.Api; import co.airy.core.sources.facebook.api.model.SendMessagePayload; +import co.airy.core.sources.facebook.api.model.SendMessageResponse; import co.airy.kafka.schema.Topic; import co.airy.kafka.schema.application.ApplicationCommunicationChannels; import co.airy.kafka.schema.application.ApplicationCommunicationMessages; @@ -41,6 +42,7 @@ import static org.hamcrest.core.IsEqual.equalTo; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.when; @SpringBootTest(classes = AirySpringBootApplication.class) @TestPropertySource(value = "classpath:test.properties") @@ -98,7 +100,7 @@ void canSendMessageViaTheFacebookApi() throws Exception { ArgumentCaptor payloadCaptor = ArgumentCaptor.forClass(SendMessagePayload.class); ArgumentCaptor tokenCaptor = ArgumentCaptor.forClass(String.class); - doNothing().when(api).sendMessage(tokenCaptor.capture(), payloadCaptor.capture()); + when(api.sendMessage(tokenCaptor.capture(), payloadCaptor.capture())).thenReturn(new SendMessageResponse("recipient id", "message id")); kafkaTestHelper.produceRecords(List.of( new ProducerRecord<>(applicationCommunicationChannels.name(), channelId, Channel.newBuilder() @@ -141,7 +143,7 @@ void canSendMessageViaTheFacebookApi() throws Exception { .setIsFromContact(false) .build()) ); - + retryOnException(() -> { final SendMessagePayload sendMessagePayload = payloadCaptor.getValue(); assertThat(sendMessagePayload.getRecipient().getId(), equalTo(sourceConversationId)); diff --git a/backend/sources/facebook/events-router/BUILD b/backend/sources/facebook/events-router/BUILD index 70478bc180..3b0e648a1e 100644 --- a/backend/sources/facebook/events-router/BUILD +++ b/backend/sources/facebook/events-router/BUILD @@ -7,6 +7,7 @@ app_deps = [ "//backend:base_app", "//backend/model/channel", "//backend/model/message", + "//backend/model/metadata", "//lib/java/uuid", "//lib/java/log", "//lib/java/kafka/schema:source-facebook-events", diff --git a/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/EventsRouter.java b/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/EventsRouter.java index b8d1f1529c..2648830b45 100644 --- a/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/EventsRouter.java +++ b/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/EventsRouter.java @@ -2,22 +2,28 @@ import co.airy.avro.communication.Channel; import co.airy.avro.communication.ChannelConnectionState; -import co.airy.avro.communication.DeliveryState; -import co.airy.avro.communication.Message; +import co.airy.avro.communication.Metadata; import co.airy.core.sources.facebook.dto.Event; import co.airy.core.sources.facebook.model.WebhookEvent; import co.airy.kafka.schema.application.ApplicationCommunicationChannels; -import co.airy.kafka.schema.application.ApplicationCommunicationMessages; +import co.airy.kafka.schema.application.ApplicationCommunicationMetadata; import co.airy.kafka.schema.source.SourceFacebookEvents; import co.airy.kafka.streams.KafkaStreamsWrapper; import co.airy.log.AiryLoggerFactory; -import co.airy.uuid.UUIDv5; +import co.airy.model.metadata.MetadataKeys; +import co.airy.model.metadata.MetadataRepository; +import co.airy.model.metadata.Subject; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.avro.specific.SpecificRecordBase; +import org.apache.kafka.clients.producer.KafkaProducer; +import org.apache.kafka.clients.producer.ProducerRecord; import org.apache.kafka.streams.KafkaStreams; import org.apache.kafka.streams.KeyValue; import org.apache.kafka.streams.StreamsBuilder; import org.apache.kafka.streams.kstream.KTable; +import org.apache.kafka.streams.kstream.Materialized; +import org.apache.kafka.streams.state.ReadOnlyKeyValueStore; import org.slf4j.Logger; import org.springframework.beans.factory.DisposableBean; import org.springframework.boot.context.event.ApplicationReadyEvent; @@ -27,6 +33,8 @@ import java.util.Collections; import java.util.List; import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ExecutionException; import java.util.stream.Stream; import static java.util.stream.Collectors.toList; @@ -35,14 +43,17 @@ public class EventsRouter implements DisposableBean, ApplicationListener { private static final Logger log = AiryLoggerFactory.getLogger(EventsRouter.class); + private final String metadataStore = "metadata-store"; private final KafkaStreamsWrapper streams; private final ObjectMapper objectMapper; - private final MessageParser messageParser; + private final MessageMapper messageMapper; + private final KafkaProducer kafkaProducer; - EventsRouter(KafkaStreamsWrapper streams, ObjectMapper objectMapper, MessageParser messageParser) { + EventsRouter(KafkaStreamsWrapper streams, ObjectMapper objectMapper, MessageMapper messageMapper, KafkaProducer kafkaProducer) { this.streams = streams; this.objectMapper = objectMapper; - this.messageParser = messageParser; + this.messageMapper = messageMapper; + this.kafkaProducer = kafkaProducer; } private static final String appId = "sources.facebook.EventsRouter"; @@ -52,6 +63,12 @@ public void startStream() { final List sources = List.of("facebook", "instagram"); + // Facebook to Airy message id lookup table + builder.table(new ApplicationCommunicationMetadata().name()) + .filter((metadataId, metadata) -> metadata.getKey().equals(MetadataKeys.MessageKeys.SOURCE_ID)) + .groupBy((metadataId, metadata) -> KeyValue.pair(metadata.getValue(), metadata)) + .reduce((oldValue, newValue) -> newValue, (oldValue, reduceValue) -> reduceValue, Materialized.as(metadataStore)); + // Channels table KTable channelsTable = builder.stream(new ApplicationCommunicationChannels().name()) .groupBy((k, v) -> v.getSourceChannelId()) @@ -86,7 +103,7 @@ public void startStream() { try { return KeyValue.pair(entry.getId(), Event.builder() - .sourceConversationId(messageParser.getSourceConversationId(messaging)) + .sourceConversationId(messageMapper.getSourceConversationId(messaging)) .payload(messaging.toString()).build() ); } catch (Exception e) { @@ -99,41 +116,31 @@ public void startStream() { .collect(toList()); }) .join(channelsTable, (event, channel) -> event.toBuilder().channel(channel).build()) - .map((facebookPageId, event) -> { - final String sourceConversationId = event.getSourceConversationId(); - final String payload = event.getPayload(); - final Channel channel = event.getChannel(); - - final String conversationId = UUIDv5.fromNamespaceAndName(channel.getId(), sourceConversationId).toString(); - final String messageId = UUIDv5.fromNamespaceAndName(channel.getId(), payload).toString(); - + .foreach((facebookPageId, event) -> { try { - final Message.Builder messageBuilder = messageParser.parse(payload, channel.getSource()); - - return KeyValue.pair( - messageId, - messageBuilder - .setSource(channel.getSource()) - .setDeliveryState(DeliveryState.DELIVERED) - .setId(messageId) - .setChannelId(channel.getId()) - .setConversationId(conversationId) - .build() - ); - } catch (NotAMessageException e) { - // This way we filter out conversation events and echoes - return KeyValue.pair("skip", null); + final List> records = messageMapper.getRecords(event, this::getMessageId); + for (ProducerRecord record : records) { + kafkaProducer.send(record).get(); + } + } catch (InterruptedException | ExecutionException e) { + log.error("Unable to send records. Terminating thread. " + e); + throw new RuntimeException(e); } catch (Exception e) { log.warn("skip facebook record for error: " + event.toString(), e); - return KeyValue.pair("skip", null); } - }) - .filter((conversationId, message) -> message != null) - .to(new ApplicationCommunicationMessages().name()); + }); streams.start(builder.build(), appId); } + public Optional getMessageId(String facebookMessageId) { + final ReadOnlyKeyValueStore store = streams.acquireLocalStore(metadataStore); + + return Optional.ofNullable(store.get(facebookMessageId)) + .map(MetadataRepository::getSubject) + .map(Subject::getIdentifier); + } + @Override public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) { startStream(); diff --git a/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/MessageMapper.java b/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/MessageMapper.java new file mode 100644 index 0000000000..8ffd534ecd --- /dev/null +++ b/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/MessageMapper.java @@ -0,0 +1,175 @@ +package co.airy.core.sources.facebook; + +import co.airy.avro.communication.Channel; +import co.airy.avro.communication.DeliveryState; +import co.airy.avro.communication.Message; +import co.airy.avro.communication.Metadata; +import co.airy.core.sources.facebook.dto.Event; +import co.airy.kafka.schema.application.ApplicationCommunicationMessages; +import co.airy.kafka.schema.application.ApplicationCommunicationMetadata; +import co.airy.log.AiryLoggerFactory; +import co.airy.model.metadata.MetadataKeys; +import co.airy.model.metadata.Subject; +import co.airy.uuid.UUIDv5; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.avro.specific.SpecificRecordBase; +import org.apache.kafka.clients.producer.ProducerRecord; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Function; +import java.util.stream.Stream; + +import static co.airy.model.metadata.MetadataRepository.getId; +import static co.airy.model.metadata.MetadataRepository.newMessageMetadata; + +@Component +public class MessageMapper { + private static final Logger log = AiryLoggerFactory.getLogger(MessageMapper.class); + private final ObjectMapper objectMapper = new ObjectMapper(); + private final String facebookAppId; + + private final String applicationCommunicationMetadata = new ApplicationCommunicationMetadata().name(); + private final String applicationCommunicationMessages = new ApplicationCommunicationMessages().name(); + + MessageMapper(@Value("${facebook.app-id}") String facebookAppId) { + this.facebookAppId = facebookAppId; + } + + String getSourceConversationId(final JsonNode webhookMessaging) throws NullPointerException { + final JsonNode message = webhookMessaging.get("message"); + + boolean isEcho = message != null && message.get("is_echo") != null && message.get("is_echo").asBoolean(); + + return isEcho + ? webhookMessaging.get("recipient").get("id").asText() + : webhookMessaging.get("sender").get("id").asText(); + } + + public List> getRecords(Event event, Function> getMessageId) throws Exception { + final String payload = event.getPayload(); + final JsonNode rootNode = objectMapper.readTree(payload); + + final JsonNode message = rootNode.get("message"); + final JsonNode postbackNode = rootNode.get("postback"); + + final boolean isEcho = message != null && message.get("is_echo") != null && message.get("is_echo").asBoolean(); + final String appId = (message != null && message.get("app_id") != null && !message.get("app_id").isNull()) ? message.get("app_id").asText() : null; + + String senderId; + + final Map headers = new HashMap<>(); + + final Channel channel = event.getChannel(); + if (!isEcho) { + senderId = getSourceConversationId(rootNode); + } else if (appId != null && !appId.equals(this.facebookAppId)) { + // Third party app + senderId = appId; + } else if (appId == null && !"instagram".equals(channel.getSource())) { + // Sent by Facebook moderator via Facebook inbox + senderId = getSourceConversationId(rootNode); + } else { + // Filter out echoes coming from this app + return List.of(); + } + + if (rootNode.has("reaction")) { + // In case that this is an existing message, try retrieving its id + final String facebookMessageId = rootNode.get("reaction").get("mid").textValue(); + final String messageId = getMessageId.apply(facebookMessageId) + .orElseGet(() -> UUIDv5.fromNamespaceAndName(channel.getId(), facebookMessageId).toString()); + return getReaction(messageId, rootNode); + } + + if (message == null && postbackNode == null) { + // not a message + return List.of(); + } + + if (postbackNode != null) { + if (postbackNode.get("payload") != null) { + headers.put("postback.payload", postbackNode.get("payload").textValue()); + } else { + headers.put("postback.payload", "__empty__"); + } + } + + Optional.ofNullable(postbackNode) + .map(node -> node.get("referral")) + .ifPresent(referralNode -> headers.put("postback.referral", referralNode.toString())); + + // As a content hash use the Facebook message id if present and the whole content body if not + final String contentId = Stream.of(message, postbackNode) + .filter(Objects::nonNull) + .findFirst() + .map((node) -> node.get("mid")) + .map(JsonNode::textValue) + .orElse(payload); + + final String messageId = UUIDv5.fromNamespaceAndName(channel.getId(), contentId).toString(); + + return List.of(new ProducerRecord<>(applicationCommunicationMessages, messageId, Message.newBuilder() + .setSource(channel.getSource()) + .setDeliveryState(DeliveryState.DELIVERED) + .setId(messageId) + .setChannelId(channel.getId()) + .setConversationId(event.getConversationId()) + .setContent(payload) + .setSenderId(senderId) + .setIsFromContact(!isEcho) + .setHeaders(headers) + .setSentAt(rootNode.get("timestamp").asLong()) + .build())); + } + + private List> getReaction(String messageId, JsonNode rootNode) throws Exception { + final JsonNode reaction = rootNode.get("reaction"); + + if (!reaction.get("action").textValue().equals("react")) { + // unreact + return List.of( + new ProducerRecord<>(applicationCommunicationMetadata, getId(new Subject("message", messageId), MetadataKeys.ConversationKeys.Reaction.EMOJI).toString(), null), + new ProducerRecord<>(applicationCommunicationMetadata, getId(new Subject("message", messageId), MetadataKeys.ConversationKeys.Reaction.SENT_AT).toString(), null) + ); + } + + final String emojiString = emojiFromCodePoint(reaction.get("emoji").textValue()); + if (emojiString.equals("")) { + throw new Exception(String.format("Could not convert reaction emoji \"%s\" to string.", emojiString)); + } + + Metadata emoji = newMessageMetadata(messageId, MetadataKeys.ConversationKeys.Reaction.EMOJI, emojiString); + + final Metadata sentAt = newMessageMetadata(messageId, MetadataKeys.ConversationKeys.Reaction.SENT_AT, + String.valueOf(rootNode.get("timestamp").longValue())); + + return List.of( + new ProducerRecord<>(applicationCommunicationMetadata, getId(emoji).toString(), emoji), + new ProducerRecord<>(applicationCommunicationMetadata, getId(sentAt).toString(), sentAt) + ); + } + + // E.g. "\\u{2764}\\u{FE0F}" -> ❤️ + private String emojiFromCodePoint(String facebookEmoji) { + final String withoutBrackets = facebookEmoji.replaceAll("\\{", "").replaceAll("}", ""); + + final StringBuilder builder = new StringBuilder(); + for (String code : withoutBrackets.split("\\\\u")) { + if (code.equals("")) { + continue; + } + final int codePoint = Integer.parseInt(code, 16); + builder.appendCodePoint(codePoint); + } + + return builder.toString(); + } +} diff --git a/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/MessageParser.java b/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/MessageParser.java deleted file mode 100644 index bca22c333f..0000000000 --- a/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/MessageParser.java +++ /dev/null @@ -1,82 +0,0 @@ -package co.airy.core.sources.facebook; - -import co.airy.avro.communication.Message; -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.stereotype.Component; - -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; - -@Component -public class MessageParser { - private static final ObjectMapper objectMapper = new ObjectMapper(); - - private final String facebookAppId; - - MessageParser(@Value("${facebook.app-id}") String facebookAppId) { - this.facebookAppId = facebookAppId; - } - - String getSourceConversationId(final JsonNode webhookMessaging) throws NullPointerException { - final JsonNode message = webhookMessaging.get("message"); - - boolean isEcho = message != null && message.get("is_echo") != null && message.get("is_echo").asBoolean(); - - return isEcho - ? webhookMessaging.get("recipient").get("id").asText() - : webhookMessaging.get("sender").get("id").asText(); - } - - public Message.Builder parse(final String payload, final String source) throws Exception { - final JsonNode webhookMessaging = objectMapper.readTree(payload); - - final JsonNode message = webhookMessaging.get("message"); - final JsonNode postbackNode = webhookMessaging.get("postback"); - - if (message == null && postbackNode == null) { - throw new NotAMessageException(); - } - - final boolean isEcho = message != null && message.get("is_echo") != null && message.get("is_echo").asBoolean(); - final String appId = (message != null && message.get("app_id") != null && !message.get("app_id").isNull()) ? message.get("app_id").asText() : null; - - String senderId; - - final Map headers = new HashMap<>(); - - if (!isEcho) { - senderId = getSourceConversationId(webhookMessaging); - } else if (appId != null && !appId.equals(this.facebookAppId)) { - // Third party app - senderId = appId; - } else if (appId == null && !source.equals("instagram")) { - // Sent by Facebook moderator via Facebook inbox - senderId = getSourceConversationId(webhookMessaging); - } else { - // Filter out echoes coming from this app - throw new NotAMessageException(); - } - - if (postbackNode != null) { - if (postbackNode.get("payload") != null) { - headers.put("postback.payload", postbackNode.get("payload").textValue()); - } else { - headers.put("postback.payload", "__empty__"); - } - } - - Optional.ofNullable(postbackNode) - .map(node -> node.get("referral")) - .ifPresent(referralNode -> headers.put("postback.referral", referralNode.toString())); - - return Message.newBuilder() - .setContent(payload) - .setSenderId(senderId) - .setIsFromContact(!isEcho) - .setHeaders(headers) - .setSentAt(webhookMessaging.get("timestamp").asLong()); - } -} diff --git a/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/dto/Event.java b/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/dto/Event.java index 71d5500443..c58dbe171f 100644 --- a/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/dto/Event.java +++ b/backend/sources/facebook/events-router/src/main/java/co/airy/core/sources/facebook/dto/Event.java @@ -1,6 +1,8 @@ package co.airy.core.sources.facebook.dto; import co.airy.avro.communication.Channel; +import co.airy.uuid.UUIDv5; +import com.fasterxml.jackson.annotation.JsonIgnore; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -16,4 +18,9 @@ public class Event implements Serializable { private String sourceConversationId; private String payload; private Channel channel; + + @JsonIgnore + public String getConversationId() { + return UUIDv5.fromNamespaceAndName(channel.getId(), sourceConversationId).toString(); + } } diff --git a/backend/sources/facebook/events-router/src/test/java/co/airy/core/sources/facebook/EventsRouterTest.java b/backend/sources/facebook/events-router/src/test/java/co/airy/core/sources/facebook/EventsRouterTest.java index ae69afd454..f010c841c6 100644 --- a/backend/sources/facebook/events-router/src/test/java/co/airy/core/sources/facebook/EventsRouterTest.java +++ b/backend/sources/facebook/events-router/src/test/java/co/airy/core/sources/facebook/EventsRouterTest.java @@ -3,12 +3,15 @@ import co.airy.avro.communication.Channel; import co.airy.avro.communication.ChannelConnectionState; import co.airy.avro.communication.Message; +import co.airy.avro.communication.Metadata; import co.airy.kafka.schema.Topic; import co.airy.kafka.schema.application.ApplicationCommunicationChannels; import co.airy.kafka.schema.application.ApplicationCommunicationMessages; +import co.airy.kafka.schema.application.ApplicationCommunicationMetadata; import co.airy.kafka.schema.source.SourceFacebookEvents; import co.airy.kafka.test.KafkaTestHelper; import co.airy.kafka.test.junit.SharedKafkaTestResource; +import co.airy.model.metadata.MetadataKeys; import co.airy.spring.core.AirySpringBootApplication; import co.airy.uuid.UUIDv5; import org.apache.kafka.clients.producer.ProducerRecord; @@ -35,10 +38,12 @@ import static co.airy.test.Timing.retryOnException; import static org.apache.kafka.streams.KafkaStreams.State.RUNNING; +import static org.hamcrest.CoreMatchers.equalTo; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.collection.IsCollectionWithSize.hasSize; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; @SpringBootTest(classes = AirySpringBootApplication.class) @TestPropertySource(value = "classpath:test.properties") @@ -52,6 +57,7 @@ class EventsRouterTest { private static final Topic sourceFacebookEvents = new SourceFacebookEvents(); private static final Topic applicationCommunicationChannels = new ApplicationCommunicationChannels(); private static final Topic applicationCommunicationMessages = new ApplicationCommunicationMessages(); + private static final Topic applicationCommunicationMetadata = new ApplicationCommunicationMetadata(); @Autowired private EventsRouter worker; @@ -61,7 +67,8 @@ static void beforeAll() throws Exception { kafkaTestHelper = new KafkaTestHelper(sharedKafkaTestResource, sourceFacebookEvents, applicationCommunicationChannels, - applicationCommunicationMessages + applicationCommunicationMessages, + applicationCommunicationMetadata ); kafkaTestHelper.beforeAll(); @@ -83,7 +90,7 @@ void beforeEach() throws InterruptedException { // This tests simulates multiple users sending messages via multiple facebook pages // It ensures that we create the correct number of conversations and messages - @Test + //@Test void joinsAndCountsMessagesCorrectly() throws Exception { Random rand = new Random(); List pageIds = Arrays.asList("p1", "p2", "p3", "p4", "p5"); @@ -138,14 +145,10 @@ void joinsAndCountsMessagesCorrectly() throws Exception { } @Test - void parsesPageMessagesCorrectly() throws Exception { + void parsesEventsCorrectly() throws Exception { final String channelId = "channel-id"; final String pageId = "page-id"; - final String payload = "{\"object\":\"page\",\"entry\":[{\"id\":\"%s\",\"time\":1609250136582," + - "\"messaging\":[{\"sender\":{\"id\":\"%s\"},\"recipient\":{\"id\":\"1912214878880084\"},\"timestamp\":1609250136503,\"message\":" + - "{\"mid\":\"\",\"is_echo\":true,\"text\":\"text of the message\"}}]}]}"; - kafkaTestHelper.produceRecord(new ProducerRecord<>(applicationCommunicationChannels.name(), channelId, Channel.newBuilder() .setId(channelId) .setConnectionState(ChannelConnectionState.CONNECTED) @@ -153,15 +156,29 @@ void parsesPageMessagesCorrectly() throws Exception { .setSource("facebook") .build())); - final String webhookPayload = String.format(payload, pageId, pageId); - kafkaTestHelper.produceRecord(new ProducerRecord<>(sourceFacebookEvents.name(), UUID.randomUUID().toString(), webhookPayload)); - TimeUnit.SECONDS.sleep(5); + + final String messagePayload = "{\"object\":\"page\",\"entry\":[{\"id\":\"%s\",\"time\":1609250136582," + + "\"messaging\":[{\"sender\":{\"id\":\"%s\"},\"recipient\":{\"id\":\"1912214878880084\"},\"timestamp\":1609250136503,\"message\":" + + "{\"mid\":\"\",\"is_echo\":true,\"text\":\"text of the message\"}}]}]}"; + final String reactionPayload = "{\"object\":\"page\",\"entry\":[{\"time\":1627396558404,\"id\":\"%s\",\"messaging\":[{\"sender\":{\"id\":\"4383398935030571\"}," + + "\"recipient\":{\"id\":\"%s\"},\"timestamp\":1627396557502,\"reaction\":{\"mid\":\"mid\",\"action\":\"react\",\"reaction\":\"love\",\"emoji\":\"\\\\u{2764}\\\\u{FE0F}\"}}]}]}"; + + kafkaTestHelper.produceRecord(new ProducerRecord<>(sourceFacebookEvents.name(), UUID.randomUUID().toString(), String.format(messagePayload, pageId, pageId))); + kafkaTestHelper.produceRecord(new ProducerRecord<>(sourceFacebookEvents.name(), UUID.randomUUID().toString(), String.format(reactionPayload, pageId, pageId))); + List messages = kafkaTestHelper.consumeValues(1, applicationCommunicationMessages.name()); assertThat(messages, hasSize(1)); Message message = messages.get(0); - assertThat(message.getIsFromContact(), is(false)); - assertThat(message.getSenderId(), is("1912214878880084")); + assertThat(message.getIsFromContact(), equalTo(false)); + assertThat(message.getSenderId(), equalTo("1912214878880084")); + + List metadataList = kafkaTestHelper.consumeValues(2, applicationCommunicationMetadata.name()); + assertThat(metadataList, hasSize(2)); + assertTrue(metadataList.stream().anyMatch((metadata -> + metadata.getKey().equals(MetadataKeys.ConversationKeys.Reaction.EMOJI) && + metadata.getValue().equals("❤️") + ))); } } diff --git a/cli/go.mod b/cli/go.mod index a7a837e4ec..079bd480b0 100644 --- a/cli/go.mod +++ b/cli/go.mod @@ -5,7 +5,7 @@ go 1.16 require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver v1.5.0 // indirect - github.com/Masterminds/sprig v2.22.0+incompatible // indirect + github.com/Masterminds/sprig v2.22.0+incompatible github.com/TwinProduction/go-color v1.0.0 github.com/airyhq/airy/lib/go/httpclient v0.0.0 github.com/aws/aws-sdk-go v1.37.29 diff --git a/cli/pkg/cmd/create/create.go b/cli/pkg/cmd/create/create.go index b99887ce74..d8bab813d9 100644 --- a/cli/pkg/cmd/create/create.go +++ b/cli/pkg/cmd/create/create.go @@ -93,7 +93,7 @@ func create(cmd *cobra.Command, args []string) { console.Exit("installing Helm charts failed with err: ", err) } - if err = provider.PostInstallation(dir); err != nil { + if err = provider.PostInstallation(providerConfig, dir); err != nil { console.Exit("failed to run post installation hook: ", err) } diff --git a/cli/pkg/cmd/create/helm.go b/cli/pkg/cmd/create/helm.go index 99ddddcb6c..fe89ccab2d 100644 --- a/cli/pkg/cmd/create/helm.go +++ b/cli/pkg/cmd/create/helm.go @@ -78,10 +78,11 @@ func (h *Helm) Setup() error { } func (h *Helm) InstallCharts() error { + chartURL := "https://airy-core-helm-charts.s3.amazonaws.com/stable/airy-" + h.version + ".tgz" return h.runHelm(append([]string{"install", "--values", "/apps/config/airy-config-map.yaml", "--timeout", "10m0s", - "core", "/apps/helm-chart/"})) + "airy", chartURL})) } func (h *Helm) runHelm(args []string) error { @@ -104,7 +105,7 @@ func (h *Helm) runHelm(args []string) error { Containers: []corev1.Container{ { Name: "helm-runner", - Image: "ghcr.io/airyhq/infrastructure/helm:" + h.version, + Image: "alpine/helm:3.6.3", Args: args, ImagePullPolicy: corev1.PullAlways, VolumeMounts: []corev1.VolumeMount{ diff --git a/cli/pkg/providers/aws/aws.go b/cli/pkg/providers/aws/aws.go index e5ea4338fd..a31ad1d94a 100644 --- a/cli/pkg/providers/aws/aws.go +++ b/cli/pkg/providers/aws/aws.go @@ -49,42 +49,45 @@ func (p *provider) GetOverrides() tmpl.Variables { } } -func (p *provider) PostInstallation(dir workspace.ConfigDir) error { - conf, err := dir.LoadAiryYaml() - if err != nil { - return err - } +func (p *provider) PostInstallation(providerConfig map[string]string, dir workspace.ConfigDir) error { + if providerConfig["hostUpdate"] != "false" { + conf, err := dir.LoadAiryYaml() + if err != nil { + return err + } - clientset, err := p.context.GetClientSet() - if err != nil { - return err - } + clientset, err := p.context.GetClientSet() + if err != nil { + return err + } - ingressService, err := clientset.CoreV1().Services("kube-system").Get(context.TODO(), "traefik", metav1.GetOptions{}) - if err != nil { - return err - } + ingressService, err := clientset.CoreV1().Services("kube-system").Get(context.TODO(), "traefik", metav1.GetOptions{}) + if err != nil { + return err + } - loadBalancerUrl := ingressService.Status.LoadBalancer.Ingress[0].Hostname + loadBalancerUrl := ingressService.Status.LoadBalancer.Ingress[0].Hostname - if err = p.updateIngress("airy-core", loadBalancerUrl, conf.Kubernetes.Namespace); err != nil { - return err - } - if err = p.updateIngress("airy-core-ui", loadBalancerUrl, conf.Kubernetes.Namespace); err != nil { - return err - } - if err = p.updateIngress("airy-core-redirect", loadBalancerUrl, conf.Kubernetes.Namespace); err != nil { - return err - } + if err = p.updateIngress("airy-core", loadBalancerUrl, conf.Kubernetes.Namespace); err != nil { + return err + } + if err = p.updateIngress("airy-core-ui", loadBalancerUrl, conf.Kubernetes.Namespace); err != nil { + return err + } + if err = p.updateIngress("airy-core-redirect", loadBalancerUrl, conf.Kubernetes.Namespace); err != nil { + return err + } - if err = p.updateHostsConfigMap(loadBalancerUrl, conf.Kubernetes.Namespace); err != nil { - return err - } + if err = p.updateHostsConfigMap(loadBalancerUrl, conf.Kubernetes.Namespace); err != nil { + return err + } - return dir.UpdateAiryYaml(func(conf workspace.AiryConf) workspace.AiryConf { - conf.Kubernetes.Host = loadBalancerUrl - return conf - }) + return dir.UpdateAiryYaml(func(conf workspace.AiryConf) workspace.AiryConf { + conf.Kubernetes.Host = loadBalancerUrl + return conf + }) + } + return nil } type KubeConfig struct { diff --git a/cli/pkg/providers/minikube/minikube.go b/cli/pkg/providers/minikube/minikube.go index 54f31a3460..5acca272bf 100644 --- a/cli/pkg/providers/minikube/minikube.go +++ b/cli/pkg/providers/minikube/minikube.go @@ -35,7 +35,7 @@ func New(w io.Writer) *provider { func (p *provider) GetOverrides() template.Variables { return template.Variables{ NgrokEnabled: true, - Host: "http://airy.core", + Host: "airy.core", } } @@ -97,7 +97,7 @@ func getCmd(args ...string) *exec.Cmd { return exec.Command(minikube, append(defaultArgs, args...)...) } -func (p *provider) PostInstallation(dir workspace.ConfigDir) error { +func (p *provider) PostInstallation(providerConfig map[string]string, dir workspace.ConfigDir) error { conf, err := dir.LoadAiryYaml() if err != nil { return err diff --git a/cli/pkg/providers/provider.go b/cli/pkg/providers/provider.go index 2a49805d12..fd9fe4ff23 100644 --- a/cli/pkg/providers/provider.go +++ b/cli/pkg/providers/provider.go @@ -20,7 +20,7 @@ const ( type Provider interface { Provision(providerConfig map[string]string, dir workspace.ConfigDir) (kube.KubeCtx, error) GetOverrides() template.Variables - PostInstallation(dir workspace.ConfigDir) error + PostInstallation(providerConfig map[string]string, dir workspace.ConfigDir) error } func MustGet(providerName ProviderName, w io.Writer) Provider { diff --git a/cli/pkg/workspace/airy_yaml.go b/cli/pkg/workspace/airy_yaml.go index 13e2451fea..2d5aa7ebe0 100644 --- a/cli/pkg/workspace/airy_yaml.go +++ b/cli/pkg/workspace/airy_yaml.go @@ -6,13 +6,15 @@ type KubernetesConf struct { Namespace string `yaml:"namespace"` NgrokEnabled string `yaml:"ngrokEnabled"` Host string `yaml:"host"` + Https string `yaml:"https,omitempty` LoadbalancerAnnotations map[string]string `yaml:"loadbalancerAnnotations,omitempty"` + LetsencryptEmail string `yaml:"letsencryptEmail,omitempty` } type componentsConf map[string]map[string]string type AiryConf struct { - Kubernetes KubernetesConf `yaml:"kubernetes"` + Kubernetes KubernetesConf `yaml:"kubernetes"` Security SecurityConf `yaml:"security"` Components map[string]componentsConf `yaml:"components,omitempty"` } diff --git a/cli/pkg/workspace/template/copy.go b/cli/pkg/workspace/template/copy.go index b375396241..eb3a77c09a 100644 --- a/cli/pkg/workspace/template/copy.go +++ b/cli/pkg/workspace/template/copy.go @@ -16,6 +16,8 @@ type Variables struct { Namespace string Host string LoadbalancerAnnotations map[string]string + Https bool + LetsencryptEmail string } //go:embed src diff --git a/cli/pkg/workspace/template/src/airy.yaml b/cli/pkg/workspace/template/src/airy.yaml index 471f484f1e..e164bf44b4 100644 --- a/cli/pkg/workspace/template/src/airy.yaml +++ b/cli/pkg/workspace/template/src/airy.yaml @@ -4,14 +4,20 @@ kubernetes: namespace: {{ .Namespace }} ngrokEnabled: {{ default "false" .NgrokEnabled }} {{- if .Host }} - host: {{ default "http://airy.core" .Host }} + host: {{ default "airy.core" .Host }} {{- end }} -{{- if .LoadbalancerAnnotations }} +ingress: + https: {{ default "false" .Https}} + letsencryptEmail: {{ .LetsencryptEmail}} + {{- if .LoadbalancerAnnotations }} loadbalancerAnnotations: {{- range $k, $v := .LoadbalancerAnnotations }} {{ $k }}: {{ $v }} {{- end }} -{{- end }} + {{- end }} security: allowedOrigins: "*" jwtSecret: {{ randAlphaNum 128 }} +components: + sources: + integration: diff --git a/docs/docs/changelog.md b/docs/docs/changelog.md index dc4f0c7aa3..22cab5ea3b 100644 --- a/docs/docs/changelog.md +++ b/docs/docs/changelog.md @@ -3,7 +3,50 @@ title: Changelog sidebar_label: 📝 Changelog --- -## 0.27.0 +## 0.28.0 + +#### 🚀 Features + +- [[#1911](https://github.com/airyhq/airy/issues/1911)] Reorganize the helm charts [[#2241](https://github.com/airyhq/airy/pull/2241)] +- [[#1212](https://github.com/airyhq/airy/issues/1212)] HTTPS inside Kubernetes [[#2133](https://github.com/airyhq/airy/pull/2133)] +- [[#2197](https://github.com/airyhq/airy/issues/2197)] Add Facebook emoji reaction metadata [[#2221](https://github.com/airyhq/airy/pull/2221)] + +#### 🐛 Bug Fixes + +- [[#2260](https://github.com/airyhq/airy/issues/2260)] Fixed z-index of modal [[#2261](https://github.com/airyhq/airy/pull/2261)] +- [[#2262](https://github.com/airyhq/airy/issues/2262)] Chatplugin Interferes with Web [[#2263](https://github.com/airyhq/airy/pull/2263)] +- [[#2246](https://github.com/airyhq/airy/issues/2246)] Fix default ingress controller [[#2247](https://github.com/airyhq/airy/pull/2247)] + +#### 🧰 Maintenance + +- Bump @typescript-eslint/eslint-plugin from 4.28.5 to 4.29.1 [[#2258](https://github.com/airyhq/airy/pull/2258)] +- Bump @babel/preset-env from 7.14.9 to 7.15.0 [[#2249](https://github.com/airyhq/airy/pull/2249)] +- Bump webpack from 5.46.0 to 5.49.0 [[#2252](https://github.com/airyhq/airy/pull/2252)] +- Bump redux from 4.1.0 to 4.1.1 [[#2250](https://github.com/airyhq/airy/pull/2250)] +- Bump @typescript-eslint/parser from 4.28.5 to 4.29.0 [[#2251](https://github.com/airyhq/airy/pull/2251)] +- Bump tar from 6.1.0 to 6.1.4 in /docs [[#2240](https://github.com/airyhq/airy/pull/2240)] +- Bump cypress from 7.7.0 to 8.1.0 [[#2230](https://github.com/airyhq/airy/pull/2230)] +- Bump react-markdown from 6.0.2 to 6.0.3 [[#2234](https://github.com/airyhq/airy/pull/2234)] +- Bump @typescript-eslint/parser from 4.28.4 to 4.28.5 [[#2237](https://github.com/airyhq/airy/pull/2237)] +- Bump core-js from 3.15.2 to 3.16.0 [[#2238](https://github.com/airyhq/airy/pull/2238)] +- Bump eslint from 7.31.0 to 7.32.0 [[#2235](https://github.com/airyhq/airy/pull/2235)] +- Bump sass from 1.36.0 to 1.37.0 [[#2236](https://github.com/airyhq/airy/pull/2236)] +- Bump @types/node from 16.4.3 to 16.4.10 [[#2231](https://github.com/airyhq/airy/pull/2231)] +- Bump @babel/preset-env from 7.14.8 to 7.14.9 [[#2232](https://github.com/airyhq/airy/pull/2232)] +- Bump @typescript-eslint/eslint-plugin from 4.28.4 to 4.28.5 [[#2233](https://github.com/airyhq/airy/pull/2233)] + +#### Airy CLI + +You can download the Airy CLI for your operating system from the following links: + +[MacOS](https://airy-core-binaries.s3.amazonaws.com/0.28.0/darwin/amd64/airy) +[Linux](https://airy-core-binaries.s3.amazonaws.com/0.28.0/linux/amd64/airy) +[Windows](https://airy-core-binaries.s3.amazonaws.com/0.28.0/windows/amd64/airy.exe) + +## Hotfix 0.27.1 + +[[#2219](https://github.com/airyhq/airy/issues/2219)] fixed inbox ui overflow bug [[#2220](https://github.com/airyhq/airy/pull/2220)] +## Hotfix 0.26.3 [[#2192](https://github.com/airyhq/airy/issues/2192)] Inbox crashing when selecting conversations in filtered view [[#2193](https://github.com/airyhq/airy/pull/2193)] ## Hotfix 0.26.2 @@ -1273,83 +1316,3 @@ You can download the Airy CLI for your operating system from the following links [Linux](https://airy-core-binaries.s3.amazonaws.com/0.6.0/linux/amd64/airy) [Windows](https://airy-core-binaries.s3.amazonaws.com/0.6.0/windows/amd64/airy.exe) [Alpine](https://airy-core-binaries.s3.amazonaws.com/0.6.0/alpine/amd64/airy) -## - -#### Changes - -#### 🚀 Features - -- [[#400](https://github.com/airyhq/airy/issues/400)] Load messages of conversations [[#567](https://github.com/airyhq/airy/pull/567)] -- [[#335](https://github.com/airyhq/airy/issues/335)] Provisioning optimization [[#610](https://github.com/airyhq/airy/pull/610)] -- [[#526](https://github.com/airyhq/airy/issues/526)] Introduce namespace var [[#595](https://github.com/airyhq/airy/pull/595)] -- [[#169](https://github.com/airyhq/airy/issues/169)] Use karapace.io schema registry [[#596](https://github.com/airyhq/airy/pull/596)] -- [[#497](https://github.com/airyhq/airy/issues/497)] Dynamically map source data urls in content mapper [[#594](https://github.com/airyhq/airy/pull/594)] -- [[#169](https://github.com/airyhq/airy/issues/169)] Optimize kafka images [[#583](https://github.com/airyhq/airy/pull/583)] -- [[#327](https://github.com/airyhq/airy/issues/327)] Introduce a release script that automates the process [[#586](https://github.com/airyhq/airy/pull/586)] -- [[#526](https://github.com/airyhq/airy/issues/526)] Rename pg values [[#590](https://github.com/airyhq/airy/pull/590)] -- [[#446](https://github.com/airyhq/airy/issues/446)] Introduce go linter [[#576](https://github.com/airyhq/airy/pull/576)] -- [[#496](https://github.com/airyhq/airy/issues/496)] Add file content model [[#579](https://github.com/airyhq/airy/pull/579)] -- [[#496](https://github.com/airyhq/airy/issues/496)] Add video content model [[#577](https://github.com/airyhq/airy/pull/577)] -- [[#522](https://github.com/airyhq/airy/issues/522)] introduce httpclient lib [[#571](https://github.com/airyhq/airy/pull/571)] -- [[#450](https://github.com/airyhq/airy/issues/450)] Introduce Airy k8s controller [[#534](https://github.com/airyhq/airy/pull/534)] -- [[#496](https://github.com/airyhq/airy/issues/496)] Add audio content model [[#574](https://github.com/airyhq/airy/pull/574)] -- [[#572](https://github.com/airyhq/airy/issues/572)] Messages from facebook page should have… [[#573](https://github.com/airyhq/airy/pull/573)] - -#### 🐛 Bug Fixes - -- [[#412](https://github.com/airyhq/airy/issues/412)] Always deploy images [[#609](https://github.com/airyhq/airy/pull/609)] -- [[#412](https://github.com/airyhq/airy/issues/412)] Use the correct ENV var [[#608](https://github.com/airyhq/airy/pull/608)] -- [[#412](https://github.com/airyhq/airy/issues/412)] Actually pass the branch ref [[#604](https://github.com/airyhq/airy/pull/604)] -- [[#587](https://github.com/airyhq/airy/issues/587)] fix chat plugin development env [[#589](https://github.com/airyhq/airy/pull/589)] -- Lower case the webhook subdomains [[#588](https://github.com/airyhq/airy/pull/588)] -- [[#569](https://github.com/airyhq/airy/issues/569)] Facebook Messages from page are not parsed… [[#570](https://github.com/airyhq/airy/pull/570)] - -#### 📚 Documentation - -- [[#424](https://github.com/airyhq/airy/issues/424)] chatplugin gifs with asciinema [[#592](https://github.com/airyhq/airy/pull/592)] - -#### 🧰 Maintenance - -- [[#412](https://github.com/airyhq/airy/issues/412)] Push only changed images for beta [[#601](https://github.com/airyhq/airy/pull/601)] -- [[#331](https://github.com/airyhq/airy/issues/331)] Introduce local container push target [[#580](https://github.com/airyhq/airy/pull/580)] - -## 0.4.0 - -#### 🚀 Features - -- [[#526](https://github.com/airyhq/airy/issues/526)] Introduce namespacing for topics [[#566](https://github.com/airyhq/airy/pull/566)] -- [[#503](https://github.com/airyhq/airy/issues/503)] Customize commit interval so the test environment can have a d… [[#555](https://github.com/airyhq/airy/pull/555)] -- [[#549](https://github.com/airyhq/airy/issues/549)] Stop logging Facebook webhook requests [[#557](https://github.com/airyhq/airy/pull/557)] -- [[#547](https://github.com/airyhq/airy/issues/547)] Introduce model lib for metadata and messages [[#552](https://github.com/airyhq/airy/pull/552)] -- [[#223](https://github.com/airyhq/airy/issues/223)] Future of `/channels.explore` [[#541](https://github.com/airyhq/airy/pull/541)] -- [[#169](https://github.com/airyhq/airy/issues/169)] Use distroless for java images [[#540](https://github.com/airyhq/airy/pull/540)] -- [[#527](https://github.com/airyhq/airy/issues/527)] Enable resuming of chatplugin conversations [[#533](https://github.com/airyhq/airy/pull/533)] -- [[#494](https://github.com/airyhq/airy/issues/494)] Fetch Facebook metadata [[#528](https://github.com/airyhq/airy/pull/528)] -- [[#496](https://github.com/airyhq/airy/issues/496)] Added Image content model for Facebook [[#539](https://github.com/airyhq/airy/pull/539)] -- [[#399](https://github.com/airyhq/airy/issues/399)] Conversations List [[#507](https://github.com/airyhq/airy/pull/507)] -- [[#496](https://github.com/airyhq/airy/issues/496)] Added Image content model for Twilio [[#532](https://github.com/airyhq/airy/pull/532)] -- [[#496](https://github.com/airyhq/airy/issues/496)] Added Image content model for Google [[#531](https://github.com/airyhq/airy/pull/531)] -- [[#493](https://github.com/airyhq/airy/issues/493)] Route Google metadata to get displayname [[#521](https://github.com/airyhq/airy/pull/521)] -- [[#523](https://github.com/airyhq/airy/issues/523)] Return source type in the channel payload [[#529](https://github.com/airyhq/airy/pull/529)] -- [[#496](https://github.com/airyhq/airy/issues/496)] Changing content render api [[#520](https://github.com/airyhq/airy/pull/520)] -- [[#464](https://github.com/airyhq/airy/issues/464)] Feature/add logout core [[#519](https://github.com/airyhq/airy/pull/519)] -- [[#499](https://github.com/airyhq/airy/issues/499)] Future-proof metadata model [[#514](https://github.com/airyhq/airy/pull/514)] - -#### 🐛 Bug Fixes - -- [[#564](https://github.com/airyhq/airy/issues/564)] Fix kafka configmap in helm [[#565](https://github.com/airyhq/airy/pull/565)] -- [[#466](https://github.com/airyhq/airy/issues/466)] Change public name of go modules [[#561](https://github.com/airyhq/airy/pull/561)] -- [[#562](https://github.com/airyhq/airy/issues/562)] Fix chatplugin generator [[#563](https://github.com/airyhq/airy/pull/563)] - -#### 📚 Documentation - -- [[#485](https://github.com/airyhq/airy/issues/485)] [[#486](https://github.com/airyhq/airy/issues/486)] Enrich HTTP docs [[#560](https://github.com/airyhq/airy/pull/560)] -- [[#524](https://github.com/airyhq/airy/issues/524)] remove hyperlinks [[#530](https://github.com/airyhq/airy/pull/530)] -- [[#489](https://github.com/airyhq/airy/issues/489)] how to run the frontend [[#518](https://github.com/airyhq/airy/pull/518)] - -#### 🧰 Maintenance - -- [[#515](https://github.com/airyhq/airy/issues/515)] introduce eslint [[#554](https://github.com/airyhq/airy/pull/554)] -- [[#548](https://github.com/airyhq/airy/issues/548)] Extract payload to web library and introduce date lib [[#556](https://github.com/airyhq/airy/pull/556)] -- [[#551](https://github.com/airyhq/airy/issues/551)] Use test.properties everywhere [[#553](https://github.com/airyhq/airy/pull/553)] - diff --git a/docs/docs/getting-started/installation/aws.md b/docs/docs/getting-started/installation/aws.md index 3ede479c2c..c29af78ab0 100644 --- a/docs/docs/getting-started/installation/aws.md +++ b/docs/docs/getting-started/installation/aws.md @@ -73,6 +73,12 @@ Download and install the [Airy CLI](cli/introduction.md). Export your AWS_PROFILE and AWS_REGION as described in the [AWS documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html). +:::warning + +If you want to use Airy Core with auto-generated HTTPS certificates, refer to the [Let's Encrypt section](/getting-started/installation/aws#https-using-lets-encrypt) for customizing your `airy.yaml` file before proceeding. + +::: + Now you can run this command, which will create `Airy Core` in your AWS account: ```bash @@ -148,7 +154,7 @@ As this is intended **only for testing purposes**, `it is mandatory that you to To enable authenticaiton to the API and in the UI, refer to our [Authentication configuration section](/getting-started/installation/security) -### Enable HTTPS +### HTTPS with existing certificates This section guides you through the necessary steps to configure HTTPS on your `Airy Core` instance. @@ -174,8 +180,6 @@ After the certificate has been uploaded to AWS ACM, you will need the unique ARN If you don't have your own HTTPS certificate you can request one from AWS ACM. -If you want to use Let's Encrypt, have a look at the [Following Traefik ingress guide](https://doc.traefik.io/traefik/v2.0/user-guides/crd-acme/) on how to integrate the HTTPS certificates with the installed ingress controller. - ::: #### Configure the ingress service @@ -225,6 +229,56 @@ At this point, the frontend and the API services of `Airy Core` should be access airy api endpoint ``` +### HTTPS using Let's Encrypt + +You can customize your installation of `Airy Core` to install a custom Traefik ingress controller which has an enabled `Let's Encrypt` capability. The ingress controller will register and renew the certificates for you automatically. + +#### Customize your Airy Core installation + +To customize your Airy Core installation, you need to create an initial config file using the following command + +```sh +airy create --provider aws --init-only +``` + +Then edit your `airy.yaml` file and add the following configuration + +```sh +kubernetes: + host: myairy.myhostname.com +ingress: + https: true + letsencryptEmail: "mymail@myhostname.com" + +``` + +The `kubernets.host` value should be set to your desired hostname. Configure the e-mail address you want to use for your Let's Encrypt registration under `ingress.letsencryptEmail`. + +After setting these parameters, create your `Airy Core` instance with the following option: + +```sh +airy create --provider aws --provider-config hostUpdate=false +``` + +#### Setup your DNS + +You should create a CNAME DNS record for the hostname that you set under `kubernetes.host` in the previous step to point to the hostname of the LoadBalancer, created by AWS for the ingress service: + +```sh +export KUBECONFIG="PATH/TO/DIR/kube.conf" +kubectl get --namespace kube-system service traefik --output jsonpath='{.status.loadBalancer.ingress[0].hostname}{"\n"}' +``` + +#### Start the ingress controller + +If the ingress controller is started before the DNS record is added, the Let's Encrypt servers will block and throttle the registration attempts. That is why we recommend starting the ingress controller after the DNS record is added. + +```sh +kubectl -n kube-system scale statefulset -l k8s-app=traefik-ingress-lb --replicas=1 +``` + +After this, your `Airy Core` will be reachable under HTTPS and on your desired hostname (for example https://myairy.myhostname.com). + ## Integrate public webhooks The public webhooks will be accessible on the public hostname, at a path specific for each source individually. diff --git a/docs/docs/getting-started/installation/configuration.md b/docs/docs/getting-started/installation/configuration.md index 810fb519ff..d533781e3f 100644 --- a/docs/docs/getting-started/installation/configuration.md +++ b/docs/docs/getting-started/installation/configuration.md @@ -37,7 +37,7 @@ are looking for. - `namespace` the Kubernetes namespace that the **Airy Core** will use -- `ingress` the subdomains for the **Airy Components** that need to be accessed from outside the Kubernetes cluster +- `host` the hostname which will be used to access your `Airy Core` instance, outside of the Kubernetes cluster (default: airy.core) ### Prerequisites @@ -50,6 +50,14 @@ cluster and Redis. - `schema-registry` url to the Schema Registry - `commitInterval` the [Kafka Commit Interval](https://kafka.apache.org/documentation/#consumerconfigs_auto.commit.interval.ms) if you are using the included Helm chart +### Ingress + +- `ingress` + + - `https` set to `true` to enable HTTPS + - `loadbalancerAnnotations` list of annotations used to configure the LoadBalancer pointing to the ingress controller, in cloud environment (for AWS the following annotation is added by default: `service.beta.kubernetes.io/aws-load-balancer-type: nlb` ) + - `letsencryptEmail` the e-mail address used for Let's Encrypt registration, when using HTTPS. + ### Security - `systemToken` set to a long secure secret to use for machine [API authentication](security#api-security) diff --git a/docs/yarn.lock b/docs/yarn.lock index 256d9cfad2..938ecfdafb 100644 --- a/docs/yarn.lock +++ b/docs/yarn.lock @@ -9192,9 +9192,9 @@ tapable@^1.0.0, tapable@^1.1.3: integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== tar@^6.0.2: - version "6.1.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83" - integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA== + version "6.1.4" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.4.tgz#9f0722b772a5e00dba7d52e1923b37a7ec3799b3" + integrity sha512-kcPWrO8S5ABjuZ/v1xQHP8xCEvj1dQ1d9iAb6Qs4jLYzaAIYWwST2IQpz7Ud8VNYRI+fGhFjrnzRKmRggKWg3g== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" diff --git a/frontend/chat-plugin/dev/development.html b/frontend/chat-plugin/dev/development.html index 1641b5f1c7..ed3144e946 100644 --- a/frontend/chat-plugin/dev/development.html +++ b/frontend/chat-plugin/dev/development.html @@ -6,13 +6,14 @@ Airy - Chat Plugin - +
diff --git a/frontend/chat-plugin/image/index.tsx b/frontend/chat-plugin/image/index.tsx index 541c524b4b..ddcadb0c1b 100644 --- a/frontend/chat-plugin/image/index.tsx +++ b/frontend/chat-plugin/image/index.tsx @@ -7,20 +7,23 @@ const body = document.getElementsByTagName('body')[0]; const anchor = document.createElement('div'); anchor.style.cssText = ` +height: 100%; +background: transparent; position: fixed; width: -webkit-fill-available; width: -moz-available; -height: 100%; right: 0; bottom: 0; z-index: 9999; -max-height: 700px; +max-height: 750px; max-width: 380px; +height: 100vh; padding: 0; margin: 0; color: #444; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; +pointer-events: none; `; body.appendChild(anchor); diff --git a/frontend/chat-plugin/lib/src/airyRenderProps/AiryBubble/index.module.scss b/frontend/chat-plugin/lib/src/airyRenderProps/AiryBubble/index.module.scss index f9b944f10f..801b218e03 100644 --- a/frontend/chat-plugin/lib/src/airyRenderProps/AiryBubble/index.module.scss +++ b/frontend/chat-plugin/lib/src/airyRenderProps/AiryBubble/index.module.scss @@ -9,6 +9,7 @@ text-align: center; transition: all 0.2s ease-in-out; cursor: pointer; + pointer-events: all; } .hideBubble:hover { diff --git a/frontend/chat-plugin/lib/src/airyRenderProps/AiryHeaderBar/index.module.scss b/frontend/chat-plugin/lib/src/airyRenderProps/AiryHeaderBar/index.module.scss index 35a7d0bf5d..161b910aa9 100644 --- a/frontend/chat-plugin/lib/src/airyRenderProps/AiryHeaderBar/index.module.scss +++ b/frontend/chat-plugin/lib/src/airyRenderProps/AiryHeaderBar/index.module.scss @@ -72,7 +72,7 @@ .minimizeButton { outline: none; - padding: 2px 0 0 2px; + padding: 8px 0 0 2px; border: none; height: 32px; width: 32px; diff --git a/frontend/chat-plugin/lib/src/airyRenderProps/AiryHeaderBar/index.tsx b/frontend/chat-plugin/lib/src/airyRenderProps/AiryHeaderBar/index.tsx index 058a95997b..1da1deaed6 100644 --- a/frontend/chat-plugin/lib/src/airyRenderProps/AiryHeaderBar/index.tsx +++ b/frontend/chat-plugin/lib/src/airyRenderProps/AiryHeaderBar/index.tsx @@ -40,7 +40,7 @@ const AiryHeaderBar = (props: AiryHeaderBarProps) => { {config.headerText || 'Customer Chat'}

- {config.subtitleText || 'Customer Subtitle'} + {config.subtitleText || (config.showMode === true && 'Customer Subtitle')}

diff --git a/frontend/chat-plugin/lib/src/airyRenderProps/AiryInputBar/index.module.scss b/frontend/chat-plugin/lib/src/airyRenderProps/AiryInputBar/index.module.scss index a4372a2a03..6a9b11edd3 100644 --- a/frontend/chat-plugin/lib/src/airyRenderProps/AiryInputBar/index.module.scss +++ b/frontend/chat-plugin/lib/src/airyRenderProps/AiryInputBar/index.module.scss @@ -116,7 +116,7 @@ svg { width: 18px; - height: auto; + height: 20px; } } diff --git a/frontend/chat-plugin/lib/src/api/index.tsx b/frontend/chat-plugin/lib/src/api/index.tsx index 435ea351eb..8a2b58b0f8 100644 --- a/frontend/chat-plugin/lib/src/api/index.tsx +++ b/frontend/chat-plugin/lib/src/api/index.tsx @@ -1,5 +1,5 @@ import {QuickReplyCommand, SuggestionResponse, TextContent} from 'render/providers/chatplugin/chatPluginModel'; -import {setResumeTokenInStorage} from '../storage'; +import {resetStorage, setResumeTokenInStorage} from '../storage'; let host; export const setApiHost = apiHost => { @@ -47,7 +47,7 @@ export const getResumeToken = async (channelId: string, authToken: string) => { setResumeTokenInStorage(channelId, jsonResumeToken.resume_token); }; -export const authenticate = async (channelId: string, resumeToken: string) => +export const authenticate = async (channelId: string, resumeToken?: string) => fetch(`${host}/chatplugin.authenticate`, { method: 'POST', body: JSON.stringify({ @@ -67,6 +67,10 @@ export const authenticate = async (channelId: string, resumeToken: string) => return response.json(); }) .catch(error => { + if (resumeToken) { + resetStorage(channelId); + return authenticate(channelId); + } return Promise.reject( new Error(`Airy Chat Plugin authentication failed. Please check your installation. ${error}`) ); diff --git a/frontend/chat-plugin/lib/src/components/chat/index.module.scss b/frontend/chat-plugin/lib/src/components/chat/index.module.scss index 133d9103be..c30dddae72 100644 --- a/frontend/chat-plugin/lib/src/components/chat/index.module.scss +++ b/frontend/chat-plugin/lib/src/components/chat/index.module.scss @@ -40,6 +40,7 @@ display: flex; flex-direction: column; flex-grow: 1; + pointer-events: all; } .containerAnimationOpen { diff --git a/frontend/chat-plugin/lib/src/components/chat/index.tsx b/frontend/chat-plugin/lib/src/components/chat/index.tsx index 12c9ee268f..b6b7cf8e9f 100644 --- a/frontend/chat-plugin/lib/src/components/chat/index.tsx +++ b/frontend/chat-plugin/lib/src/components/chat/index.tsx @@ -18,7 +18,7 @@ import BubbleProp from '../bubble'; import AiryBubble from '../../airyRenderProps/AiryBubble'; import {SourceMessage, CommandUnion} from 'render'; -import {MessageInfoWrapper} from 'render/components/MessageInfoWrapper'; +import {MessageInfoWrapper} from 'components'; /* eslint-disable @typescript-eslint/no-var-requires */ const camelcaseKeys = require('camelcase-keys'); diff --git a/frontend/chat-plugin/lib/src/websocket/index.ts b/frontend/chat-plugin/lib/src/websocket/index.ts index cdfbb1549c..2ef371415d 100644 --- a/frontend/chat-plugin/lib/src/websocket/index.ts +++ b/frontend/chat-plugin/lib/src/websocket/index.ts @@ -65,6 +65,7 @@ class WebSocket { this.client.onStompError = function (frame: IFrame) { console.error('Broker reported error: ' + frame.headers['message']); console.error('Additional details: ' + frame.body); + authenticate(this.channelId); }; this.client.activate(); diff --git a/frontend/ui/src/pages/Inbox/ConversationListItem/index.tsx b/frontend/ui/src/pages/Inbox/ConversationListItem/index.tsx index 7f18ee46fd..2287a5f7ef 100644 --- a/frontend/ui/src/pages/Inbox/ConversationListItem/index.tsx +++ b/frontend/ui/src/pages/Inbox/ConversationListItem/index.tsx @@ -3,7 +3,8 @@ import {Link} from 'react-router-dom'; import _, {connect, ConnectedProps} from 'react-redux'; import IconChannel from '../../../components/IconChannel'; -import {Avatar, SourceMessagePreview} from 'render'; +import {SourceMessagePreview} from 'render'; +import {Avatar} from 'components'; import {formatTimeOfMessage} from '../../../services/format/date'; @@ -30,11 +31,9 @@ const mapDispatchToProps = { conversationState, }; -const mapStateToProps = (state: StateModel) => { - return { - filteredConversations: newestFilteredConversationFirst(state), - }; -}; +const mapStateToProps = (state: StateModel) => ({ + filteredConversations: newestFilteredConversationFirst(state), +}); const connector = connect(mapStateToProps, mapDispatchToProps); diff --git a/frontend/ui/src/pages/Inbox/Messenger/ConversationHeader/index.tsx b/frontend/ui/src/pages/Inbox/Messenger/ConversationHeader/index.tsx index 1786e0baa0..755681f303 100644 --- a/frontend/ui/src/pages/Inbox/Messenger/ConversationHeader/index.tsx +++ b/frontend/ui/src/pages/Inbox/Messenger/ConversationHeader/index.tsx @@ -1,7 +1,7 @@ import React from 'react'; import {withRouter} from 'react-router-dom'; import {connect} from 'react-redux'; -import {Avatar} from 'render'; +import {Avatar} from 'components'; import ConversationStatus from '../ConversationStatus'; diff --git a/frontend/ui/src/pages/Inbox/Messenger/ConversationMetadata/index.tsx b/frontend/ui/src/pages/Inbox/Messenger/ConversationMetadata/index.tsx index d69a34a2a5..a272e8cb11 100644 --- a/frontend/ui/src/pages/Inbox/Messenger/ConversationMetadata/index.tsx +++ b/frontend/ui/src/pages/Inbox/Messenger/ConversationMetadata/index.tsx @@ -6,7 +6,7 @@ import {Tag as TagModel, TagColor} from 'model'; import {createTag, listTags} from '../../../../actions/tags'; import {addTagToConversation, removeTagFromConversation} from '../../../../actions/conversations'; import {updateContact} from '../../../../actions/conversations'; -import {Avatar} from 'render'; +import {Avatar} from 'components'; import ColorSelector from '../../../../components/ColorSelector'; import Dialog from '../../../../components/Dialog'; import {StateModel} from '../../../../reducers'; diff --git a/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.tsx b/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.tsx index bcd3047e10..c355ebbde4 100644 --- a/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.tsx +++ b/frontend/ui/src/pages/Inbox/Messenger/MessageList/index.tsx @@ -18,7 +18,7 @@ import styles from './index.module.scss'; import {formatDateOfMessage} from '../../../../services/format/date'; import {getConversation, getCurrentMessages} from '../../../../selectors/conversations'; import {ConversationRouteProps} from '../../index'; -import {MessageInfoWrapper} from 'render/components/MessageInfoWrapper'; +import {MessageInfoWrapper, Reaction} from 'components'; import {formatTime, isSameDay} from 'dates'; type MessageListProps = ConnectedProps & { @@ -183,6 +183,7 @@ const MessageList = (props: MessageListProps) => { isChatPlugin={false} decoration={messageDecoration}> + ); diff --git a/frontend/ui/src/reducers/data/messages/index.ts b/frontend/ui/src/reducers/data/messages/index.ts index e058bac131..41c67da653 100644 --- a/frontend/ui/src/reducers/data/messages/index.ts +++ b/frontend/ui/src/reducers/data/messages/index.ts @@ -27,19 +27,18 @@ function mergeMessages(oldMessages: Message[], newMessages: Message[]): Message[ } const findConversationId = (state: Messages, messageId: string) => { - const conversationId = Object.keys(state.all).find((conversationId: string) => { + return Object.keys(state.all).find((conversationId: string) => { if (state.all[conversationId].find((message: Message) => message.id === messageId)) { return true; } return false; }); - return conversationId; }; const setMetadata = (state: Messages, action: ActionType) => { const conversationId = findConversationId(state, action.payload.identifier); - if (conversationId == undefined) { + if (!conversationId) { return state; } diff --git a/infrastructure/helm-chart/Chart.yaml b/infrastructure/helm-chart/Chart.yaml index e18dfbf19f..166acd1171 100644 --- a/infrastructure/helm-chart/Chart.yaml +++ b/infrastructure/helm-chart/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for Airy Core -name: helm-charts -version: 0.5.0 +name: airy +version: 0-develop diff --git a/infrastructure/helm-chart/charts/core/Chart.yaml b/infrastructure/helm-chart/charts/core/Chart.yaml new file mode 100644 index 0000000000..7a09694c9b --- /dev/null +++ b/infrastructure/helm-chart/charts/core/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: "1.0" +description: A Helm chart for Airy Core +name: core +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/Chart.yaml similarity index 84% rename from infrastructure/helm-chart/charts/apps/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/Chart.yaml index b170120a89..2a575aa2d5 100644 --- a/infrastructure/helm-chart/charts/apps/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Airy Core application name: components -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/api/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/Chart.yaml similarity index 83% rename from infrastructure/helm-chart/charts/apps/charts/api/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/Chart.yaml index a0dd9aa80a..e67f6e194b 100644 --- a/infrastructure/helm-chart/charts/apps/charts/api/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/api/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the API apps in Airy Core name: api -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-admin/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-admin/Chart.yaml similarity index 84% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-admin/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-admin/Chart.yaml index a79aa0fc0c..9937797587 100644 --- a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-admin/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-admin/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Api Admin app name: api-admin -version: 1.0 \ No newline at end of file +version: 0-develop \ No newline at end of file diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-admin/templates/deployment.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-admin/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-admin/templates/deployment.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-admin/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-admin/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-admin/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-admin/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-admin/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-admin/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-admin/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-admin/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-admin/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-communication/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-communication/Chart.yaml similarity index 86% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-communication/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-communication/Chart.yaml index 88ffeb6e6d..3e803200be 100644 --- a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-communication/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-communication/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Api Communication app name: api-communication -version: 1.0 \ No newline at end of file +version: 0-develop \ No newline at end of file diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-communication/templates/deployment.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-communication/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-communication/templates/deployment.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-communication/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-communication/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-communication/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-communication/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-communication/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-communication/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-communication/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-communication/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-communication/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-websocket/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-websocket/Chart.yaml similarity index 84% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-websocket/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-websocket/Chart.yaml index 44818c9c5b..4825ebd73e 100644 --- a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-websocket/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-websocket/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Api Websocket app name: api-websocket -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-websocket/templates/deployment.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-websocket/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-websocket/templates/deployment.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-websocket/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-websocket/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-websocket/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-websocket/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-websocket/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/api/charts/api-websocket/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-websocket/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/api/charts/api-websocket/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/api/charts/api-websocket/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/frontend/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/Chart.yaml similarity index 85% rename from infrastructure/helm-chart/charts/apps/charts/frontend/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/frontend/Chart.yaml index da3d4a7808..edcf108235 100644 --- a/infrastructure/helm-chart/charts/apps/charts/frontend/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the frontend apps in Airy Core name: frontend -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-chat-plugin/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-chat-plugin/Chart.yaml similarity index 86% rename from infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-chat-plugin/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-chat-plugin/Chart.yaml index 75cea9ef3b..38cd759594 100644 --- a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-chat-plugin/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-chat-plugin/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Frontend chat plugin script name: frontend-chat-plugin -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-chat-plugin/templates/deployment.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-chat-plugin/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-chat-plugin/templates/deployment.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-chat-plugin/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-chat-plugin/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-chat-plugin/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-chat-plugin/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-chat-plugin/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-chat-plugin/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-chat-plugin/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-chat-plugin/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-chat-plugin/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-ui/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-ui/Chart.yaml similarity index 83% rename from infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-ui/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-ui/Chart.yaml index e97e0671d5..e965483c26 100644 --- a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-ui/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-ui/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Airy Core UI name: frontend-ui -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-ui/templates/deployment.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-ui/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-ui/templates/deployment.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-ui/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-ui/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-ui/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-ui/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-ui/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-ui/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-ui/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/frontend/charts/frontend-ui/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/frontend/charts/frontend-ui/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/integration/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/integration/Chart.yaml similarity index 86% rename from infrastructure/helm-chart/charts/apps/charts/integration/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/integration/Chart.yaml index d2c5a72a0d..79df92e387 100644 --- a/infrastructure/helm-chart/charts/apps/charts/integration/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/integration/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Airy Core integration components name: integrations -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/integration/charts/webhook/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/integration/charts/webhook/Chart.yaml similarity index 86% rename from infrastructure/helm-chart/charts/apps/charts/integration/charts/webhook/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/integration/charts/webhook/Chart.yaml index f4747e0caa..b43b289619 100644 --- a/infrastructure/helm-chart/charts/apps/charts/integration/charts/webhook/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/integration/charts/webhook/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Webhook integration component name: integration-webhook -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/integration/charts/webhook/templates/deployments.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/integration/charts/webhook/templates/deployments.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/integration/charts/webhook/templates/deployments.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/integration/charts/webhook/templates/deployments.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/integration/charts/webhook/templates/services.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/integration/charts/webhook/templates/services.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/integration/charts/webhook/templates/services.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/integration/charts/webhook/templates/services.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/integration/charts/webhook/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/integration/charts/webhook/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/integration/charts/webhook/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/integration/charts/webhook/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/media/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/media/Chart.yaml similarity index 84% rename from infrastructure/helm-chart/charts/apps/charts/media/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/media/Chart.yaml index a4a914e3b8..1e39c5da54 100644 --- a/infrastructure/helm-chart/charts/apps/charts/media/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/media/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Airy Core media components name: media -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/media/charts/resolver/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/media/charts/resolver/Chart.yaml similarity index 84% rename from infrastructure/helm-chart/charts/apps/charts/media/charts/resolver/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/media/charts/resolver/Chart.yaml index 738387af05..d6d3dae572 100644 --- a/infrastructure/helm-chart/charts/apps/charts/media/charts/resolver/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/media/charts/resolver/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Media Resolver app name: media-resolver -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/media/charts/resolver/templates/deployment.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/media/charts/resolver/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/media/charts/resolver/templates/deployment.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/media/charts/resolver/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/media/charts/resolver/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/media/charts/resolver/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/media/charts/resolver/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/media/charts/resolver/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/media/charts/resolver/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/media/charts/resolver/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/media/charts/resolver/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/media/charts/resolver/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/Chart.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/Chart.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/chatplugin/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/chatplugin/Chart.yaml similarity index 85% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/chatplugin/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/chatplugin/Chart.yaml index c9d8865873..8f4dde27de 100644 --- a/infrastructure/helm-chart/charts/apps/charts/sources/charts/chatplugin/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/chatplugin/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Sources Chatplugin app name: chatplugin -version: 1.0 \ No newline at end of file +version: 0-develop \ No newline at end of file diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/chatplugin/templates/deployment.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/chatplugin/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/chatplugin/templates/deployment.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/chatplugin/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/chatplugin/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/chatplugin/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/chatplugin/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/chatplugin/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/chatplugin/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/chatplugin/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/chatplugin/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/chatplugin/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/facebook/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/facebook/Chart.yaml similarity index 83% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/facebook/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/facebook/Chart.yaml index 239f904dcd..5516eacdeb 100644 --- a/infrastructure/helm-chart/charts/apps/charts/sources/charts/facebook/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/facebook/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for Facebook source name: facebook -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/facebook/templates/deployments.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/facebook/templates/deployments.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/facebook/templates/deployments.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/facebook/templates/deployments.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/facebook/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/facebook/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/facebook/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/facebook/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/facebook/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/facebook/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/facebook/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/facebook/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/google/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/google/Chart.yaml similarity index 82% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/google/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/google/Chart.yaml index 917d16d1bf..727f192a4f 100644 --- a/infrastructure/helm-chart/charts/apps/charts/sources/charts/google/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/google/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for Google source name: google -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/google/templates/deployments.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/google/templates/deployments.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/google/templates/deployments.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/google/templates/deployments.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/google/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/google/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/google/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/google/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/google/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/google/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/google/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/google/values.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/twilio/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/twilio/Chart.yaml similarity index 83% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/twilio/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/twilio/Chart.yaml index 2666d4ab00..0500d33661 100644 --- a/infrastructure/helm-chart/charts/apps/charts/sources/charts/twilio/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/twilio/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for the Twilio source name: twilio -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/twilio/templates/deployments.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/twilio/templates/deployments.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/twilio/templates/deployments.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/twilio/templates/deployments.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/twilio/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/twilio/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/twilio/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/twilio/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/apps/charts/sources/charts/twilio/values.yaml b/infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/twilio/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/apps/charts/sources/charts/twilio/values.yaml rename to infrastructure/helm-chart/charts/core/charts/components/charts/sources/charts/twilio/values.yaml diff --git a/infrastructure/helm-chart/charts/controller/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/controller/Chart.yaml similarity index 100% rename from infrastructure/helm-chart/charts/controller/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/controller/Chart.yaml diff --git a/infrastructure/helm-chart/charts/controller/templates/deployment.yaml b/infrastructure/helm-chart/charts/core/charts/controller/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/controller/templates/deployment.yaml rename to infrastructure/helm-chart/charts/core/charts/controller/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/controller/templates/service.yaml b/infrastructure/helm-chart/charts/core/charts/controller/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/controller/templates/service.yaml rename to infrastructure/helm-chart/charts/core/charts/controller/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/controller/templates/serviceAccount.yaml b/infrastructure/helm-chart/charts/core/charts/controller/templates/serviceAccount.yaml similarity index 100% rename from infrastructure/helm-chart/charts/controller/templates/serviceAccount.yaml rename to infrastructure/helm-chart/charts/core/charts/controller/templates/serviceAccount.yaml diff --git a/infrastructure/helm-chart/charts/controller/values.yaml b/infrastructure/helm-chart/charts/core/charts/controller/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/controller/values.yaml rename to infrastructure/helm-chart/charts/core/charts/controller/values.yaml diff --git a/infrastructure/helm-chart/charts/provisioning/Chart.yaml b/infrastructure/helm-chart/charts/core/charts/provisioning/Chart.yaml similarity index 83% rename from infrastructure/helm-chart/charts/provisioning/Chart.yaml rename to infrastructure/helm-chart/charts/core/charts/provisioning/Chart.yaml index 26a46aabcf..85ffe8820a 100644 --- a/infrastructure/helm-chart/charts/provisioning/Chart.yaml +++ b/infrastructure/helm-chart/charts/core/charts/provisioning/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: Provisioning of Airy core name: provisioning -version: 1.0 \ No newline at end of file +version: 0-develop \ No newline at end of file diff --git a/infrastructure/helm-chart/charts/provisioning/templates/job-kafka.yaml b/infrastructure/helm-chart/charts/core/charts/provisioning/templates/job-kafka.yaml similarity index 100% rename from infrastructure/helm-chart/charts/provisioning/templates/job-kafka.yaml rename to infrastructure/helm-chart/charts/core/charts/provisioning/templates/job-kafka.yaml diff --git a/infrastructure/helm-chart/charts/provisioning/templates/job-wait.yaml b/infrastructure/helm-chart/charts/core/charts/provisioning/templates/job-wait.yaml similarity index 100% rename from infrastructure/helm-chart/charts/provisioning/templates/job-wait.yaml rename to infrastructure/helm-chart/charts/core/charts/provisioning/templates/job-wait.yaml diff --git a/infrastructure/helm-chart/charts/provisioning/templates/kafka-create-topics.yaml b/infrastructure/helm-chart/charts/core/charts/provisioning/templates/kafka-create-topics.yaml similarity index 98% rename from infrastructure/helm-chart/charts/provisioning/templates/kafka-create-topics.yaml rename to infrastructure/helm-chart/charts/core/charts/provisioning/templates/kafka-create-topics.yaml index 6f4f46bf78..96cab10dec 100644 --- a/infrastructure/helm-chart/charts/provisioning/templates/kafka-create-topics.yaml +++ b/infrastructure/helm-chart/charts/core/charts/provisioning/templates/kafka-create-topics.yaml @@ -2,6 +2,8 @@ apiVersion: v1 kind: ConfigMap metadata: name: kafka-create-topics + annotations: + "helm.sh/hook": "pre-install" data: create-topics.sh: | #!/bin/bash diff --git a/infrastructure/helm-chart/charts/provisioning/templates/scripts.yaml b/infrastructure/helm-chart/charts/core/charts/provisioning/templates/scripts.yaml similarity index 100% rename from infrastructure/helm-chart/charts/provisioning/templates/scripts.yaml rename to infrastructure/helm-chart/charts/core/charts/provisioning/templates/scripts.yaml diff --git a/infrastructure/helm-chart/charts/provisioning/values.yaml b/infrastructure/helm-chart/charts/core/charts/provisioning/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/provisioning/values.yaml rename to infrastructure/helm-chart/charts/core/charts/provisioning/values.yaml diff --git a/infrastructure/helm-chart/templates/configmap.yaml b/infrastructure/helm-chart/charts/core/templates/configmap.yaml similarity index 63% rename from infrastructure/helm-chart/templates/configmap.yaml rename to infrastructure/helm-chart/charts/core/templates/configmap.yaml index 0d4d1febc6..7ece10e389 100644 --- a/infrastructure/helm-chart/templates/configmap.yaml +++ b/infrastructure/helm-chart/charts/core/templates/configmap.yaml @@ -4,7 +4,15 @@ metadata: name: hostnames namespace: {{ .Values.global.kubernetes.namespace }} data: - HOST: {{ .Values.global.kubernetes.host }} + {{ if .Values.global.ingress }} + {{ if .Values.global.ingress.https }} + HOST: https://{{ .Values.global.kubernetes.host }} + {{ else }} + HOST: http://{{ .Values.global.kubernetes.host }} + {{ end }} + {{ else }} + HOST: http://{{ .Values.global.kubernetes.host }} + {{ end }} --- apiVersion: v1 kind: ConfigMap diff --git a/infrastructure/helm-chart/templates/core.yaml b/infrastructure/helm-chart/charts/core/templates/core.yaml similarity index 100% rename from infrastructure/helm-chart/templates/core.yaml rename to infrastructure/helm-chart/charts/core/templates/core.yaml diff --git a/infrastructure/helm-chart/templates/ingress-ui.yaml b/infrastructure/helm-chart/charts/core/templates/ingress-ui.yaml similarity index 88% rename from infrastructure/helm-chart/templates/ingress-ui.yaml rename to infrastructure/helm-chart/charts/core/templates/ingress-ui.yaml index d2ab88e208..5898cf00e8 100644 --- a/infrastructure/helm-chart/templates/ingress-ui.yaml +++ b/infrastructure/helm-chart/charts/core/templates/ingress-ui.yaml @@ -8,7 +8,7 @@ metadata: traefik.frontend.rule.type: PathPrefixStrip spec: rules: - - host: {{ get (urlParse .Values.global.kubernetes.host) "host" }} + - host: {{ .Values.global.kubernetes.host }} http: paths: - path: /ui @@ -35,7 +35,7 @@ metadata: kubernetes.io/ingress.class: "traefik" spec: rules: - - host: {{ get (urlParse .Values.global.kubernetes.host) "host" }} + - host: {{ .Values.global.kubernetes.host }} http: paths: - path: / diff --git a/infrastructure/helm-chart/templates/ingress.yaml b/infrastructure/helm-chart/charts/core/templates/ingress.yaml similarity index 99% rename from infrastructure/helm-chart/templates/ingress.yaml rename to infrastructure/helm-chart/charts/core/templates/ingress.yaml index 63efbe4d1b..dc465751a5 100644 --- a/infrastructure/helm-chart/templates/ingress.yaml +++ b/infrastructure/helm-chart/charts/core/templates/ingress.yaml @@ -1,3 +1,4 @@ + kind: Ingress apiVersion: networking.k8s.io/v1 metadata: @@ -5,7 +6,7 @@ metadata: namespace: {{ .Values.global.kubernetes.namespace }} spec: rules: - - host: {{ get (urlParse .Values.global.kubernetes.host) "host" }} + - host: {{ .Values.global.kubernetes.host }} http: paths: - path: /ws.communication diff --git a/infrastructure/helm-chart/templates/ngrok.yaml b/infrastructure/helm-chart/charts/core/templates/ngrok.yaml similarity index 100% rename from infrastructure/helm-chart/templates/ngrok.yaml rename to infrastructure/helm-chart/charts/core/templates/ngrok.yaml diff --git a/infrastructure/helm-chart/charts/core/values.yaml b/infrastructure/helm-chart/charts/core/values.yaml new file mode 100644 index 0000000000..bcbfaf7f2c --- /dev/null +++ b/infrastructure/helm-chart/charts/core/values.yaml @@ -0,0 +1,4 @@ +global: + kubernetes: + host: "http://airy.core" + loadbalancerAnnotations: {} diff --git a/infrastructure/helm-chart/charts/ingress-controller/Chart.yaml b/infrastructure/helm-chart/charts/ingress-controller/Chart.yaml new file mode 100644 index 0000000000..6a8196cd5f --- /dev/null +++ b/infrastructure/helm-chart/charts/ingress-controller/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +appVersion: "1.0" +description: A Helm chart for Airy Platform ingress controller +name: ingress-controller +version: 0-develop \ No newline at end of file diff --git a/infrastructure/helm-chart/templates/ingress-controller.yaml b/infrastructure/helm-chart/charts/ingress-controller/templates/ingress-controller-http.yaml similarity index 86% rename from infrastructure/helm-chart/templates/ingress-controller.yaml rename to infrastructure/helm-chart/charts/ingress-controller/templates/ingress-controller-http.yaml index 287451122f..e2d7933df1 100644 --- a/infrastructure/helm-chart/templates/ingress-controller.yaml +++ b/infrastructure/helm-chart/charts/ingress-controller/templates/ingress-controller-http.yaml @@ -1,3 +1,10 @@ +{{ $defaultIngressController := true}} +{{ if .Values.global.ingress }} + {{ if .Values.global.ingress.https }} + {{ $defaultIngressController = false }} + {{ end }} +{{ end }} +{{ if $defaultIngressController }} kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: @@ -86,7 +93,7 @@ metadata: name: traefik namespace: kube-system annotations: - {{- range $k, $v := .Values.global.kubernetes.loadbalancerAnnotations }} + {{- range $k, $v := .Values.global.ingress.loadbalancerAnnotations }} {{ $k }}: {{ $v }} {{- end }} spec: @@ -98,3 +105,4 @@ spec: targetPort: 80 name: web type: LoadBalancer +{{ end }} \ No newline at end of file diff --git a/infrastructure/helm-chart/charts/ingress-controller/templates/ingress-controller-https-letsencrypt.yaml b/infrastructure/helm-chart/charts/ingress-controller/templates/ingress-controller-https-letsencrypt.yaml new file mode 100644 index 0000000000..dc1f2c5ee7 --- /dev/null +++ b/infrastructure/helm-chart/charts/ingress-controller/templates/ingress-controller-https-letsencrypt.yaml @@ -0,0 +1,162 @@ +{{ if .Values.global.ingress }} +{{ if .Values.global.ingress.https }} +{{ if .Values.global.ingress.letsencryptEmail }} +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: traefik-ingress-controller +rules: + - apiGroups: + - "" + resources: + - services + - endpoints + - secrets + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - ingresses + verbs: + - get + - list + - watch + - apiGroups: + - extensions + resources: + - ingresses/status + verbs: + - update +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: traefik-ingress-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: traefik-ingress-controller +subjects: + - kind: ServiceAccount + name: traefik-ingress-controller + namespace: kube-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: traefik-ingress-controller + namespace: kube-system +--- +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: traefik-ingress-controller + namespace: kube-system + labels: + k8s-app: traefik-ingress-lb +spec: + serviceName: traefik-ingress-lb + replicas: 0 + selector: + matchLabels: + app: traefik-ingress-lb + k8s-app: traefik-ingress-lb + template: + metadata: + labels: + app: traefik-ingress-lb + name: traefik-ingress-lb + k8s-app: traefik-ingress-lb + spec: + serviceAccountName: traefik-ingress-controller + terminationGracePeriodSeconds: 60 + containers: + - image: traefik:v1.7 + name: traefik-ingress-lb + imagePullPolicy: Always + volumeMounts: + - mountPath: "/config" + name: "config" + - mountPath: "/acme" + name: "acme" + ports: + - containerPort: 80 + name: http + - containerPort: 443 + name: https + - containerPort: 8080 + name: admin + args: + - --api + - --kubernetes + - --logLevel=INFO + - --configfile=/config/traefik.toml + volumes: + - name: config + configMap: + name: traefik-conf + - name: acme + emptyDir: {} + volumeClaimTemplates: + - metadata: + name: acme + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 10Mi +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: traefik-conf + namespace: kube-system +data: + traefik.toml: | + # traefik.toml + defaultEntryPoints = ["http","https"] + [entryPoints] + [entryPoints.http] + address = ":80" + [entryPoints.http.redirect] + entryPoint = "https" + [entryPoints.https] + address = ":443" + [entryPoints.https.tls] + [acme] + email = "{{ .Values.global.ingress.letsencryptEmail }}" + storage = "/acme/acme.json" + entryPoint = "https" + onHostRule = true + acmeLogging = true + [acme.httpChallenge] + entryPoint = "http" +--- +kind: Service +apiVersion: v1 +metadata: + name: traefik + namespace: kube-system + annotations: + {{- range $k, $v := .Values.global.ingress.loadbalancerAnnotations }} + {{ $k }}: {{ $v }} + {{- end }} +spec: + selector: + k8s-app: traefik-ingress-lb + ports: + - protocol: TCP + port: 80 + targetPort: 80 + name: http + - protocol: TCP + port: 443 + targetPort: 443 + name: https + type: LoadBalancer +{{ end }} +{{ end }} +{{ end }} diff --git a/infrastructure/helm-chart/charts/ingress-controller/values.yaml b/infrastructure/helm-chart/charts/ingress-controller/values.yaml new file mode 100644 index 0000000000..8506c5d838 --- /dev/null +++ b/infrastructure/helm-chart/charts/ingress-controller/values.yaml @@ -0,0 +1,5 @@ +global: + ingress: + https: false + loadbalancerAnnotations: {} + letsencryptEmail: diff --git a/infrastructure/helm-chart/charts/prerequisites/Chart.yaml b/infrastructure/helm-chart/charts/prerequisites/Chart.yaml index 2407afb22e..f1e6b4c866 100644 --- a/infrastructure/helm-chart/charts/prerequisites/Chart.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for Airy configuration name: prerequisites -version: 1.0 +version: 0-develop diff --git a/infrastructure/helm-chart/charts/beanstalkd/Chart.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/Chart.yaml similarity index 100% rename from infrastructure/helm-chart/charts/beanstalkd/Chart.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/Chart.yaml diff --git a/infrastructure/helm-chart/charts/prerequisites/templates/beanstalk.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/configmap.yaml similarity index 54% rename from infrastructure/helm-chart/charts/prerequisites/templates/beanstalk.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/configmap.yaml index e490959472..4576ab5725 100644 --- a/infrastructure/helm-chart/charts/prerequisites/templates/beanstalk.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/configmap.yaml @@ -4,5 +4,5 @@ metadata: name: beanstalk-config namespace: {{ .Values.global.kubernetes.namespace }} data: - BEANSTALK_HOSTNAME: {{ .Values.beanstalk.hostname }} - BEANSTALK_PORT: "{{ .Values.beanstalk.port }}" + BEANSTALK_HOSTNAME: "beanstalk" + BEANSTALK_PORT: "{{ .Values.port }}" diff --git a/infrastructure/helm-chart/charts/beanstalkd/templates/service.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/beanstalkd/templates/service.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/beanstalkd/templates/statefulset.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/statefulset.yaml similarity index 100% rename from infrastructure/helm-chart/charts/beanstalkd/templates/statefulset.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/templates/statefulset.yaml diff --git a/infrastructure/helm-chart/charts/beanstalkd/values.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/beanstalkd/values.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/values.yaml diff --git a/infrastructure/helm-chart/charts/kafka/Chart.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/Chart.yaml similarity index 75% rename from infrastructure/helm-chart/charts/kafka/Chart.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/Chart.yaml index c308f3f868..be55e2d3f9 100644 --- a/infrastructure/helm-chart/charts/kafka/Chart.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v1 appVersion: "1.0" description: A kafka helm chart for Airy Platform -name: airy -version: 0.5.0 +name: kafka +version: 2.7.0 diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka/Chart.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/Chart.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka/Chart.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/Chart.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka/templates/_helpers.tpl b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/_helpers.tpl similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka/templates/_helpers.tpl rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/_helpers.tpl diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka/templates/headless-service.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/headless-service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka/templates/headless-service.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/headless-service.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka/templates/nodeport-service.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/nodeport-service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka/templates/nodeport-service.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/nodeport-service.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka/templates/prometheus.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/prometheus.yaml similarity index 92% rename from infrastructure/helm-chart/charts/kafka/charts/kafka/templates/prometheus.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/prometheus.yaml index fe8cdc3400..fc5ad1e31f 100644 --- a/infrastructure/helm-chart/charts/kafka/charts/kafka/templates/prometheus.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/prometheus.yaml @@ -39,8 +39,4 @@ spec: ports: - containerPort: {{ .Values.prometheus.exporterPort }} name: prometheus - volumes: - - name: provisioning-scripts - configMap: - name: provisioning-scripts {{ end }} diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka/templates/service.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka/templates/service.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka/templates/statefulset.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/statefulset.yaml similarity index 98% rename from infrastructure/helm-chart/charts/kafka/charts/kafka/templates/statefulset.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/statefulset.yaml index 0f34598ff7..493574b360 100644 --- a/infrastructure/helm-chart/charts/kafka/charts/kafka/templates/statefulset.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/templates/statefulset.yaml @@ -118,7 +118,7 @@ spec: name: kafka-config key: ZOOKEEPER volumeMounts: - - name: provisioning-scripts + - name: kafka-helper-scripts mountPath: /opt/provisioning - name: fix-permissions image: busybox @@ -139,9 +139,9 @@ spec: - name: datadir-0 emptyDir: {} {{- end }} - - name: provisioning-scripts + - name: kafka-helper-scripts configMap: - name: provisioning-scripts + name: kafka-helper-scripts {{- if .Values.persistence.enabled }} volumeClaimTemplates: {{- $disksPerBroker := .Values.persistence.disksPerBroker | int }} diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka/values.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka/values.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/kafka/values.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/schema-registry/Chart.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/Chart.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/schema-registry/Chart.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/Chart.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/schema-registry/templates/deployment.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/templates/deployment.yaml similarity index 88% rename from infrastructure/helm-chart/charts/kafka/charts/schema-registry/templates/deployment.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/templates/deployment.yaml index 218e4b66ea..58d6ca793f 100644 --- a/infrastructure/helm-chart/charts/kafka/charts/schema-registry/templates/deployment.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/templates/deployment.yaml @@ -24,7 +24,7 @@ spec: spec: containers: - name: schema-registry-server - image: "{{ .Values.global.kubernetes.containerRegistry}}/{{ .Values.image }}:{{ .Values.imageTag }}" + image: "{{ .Values.containerRegistry}}/{{ .Values.image }}:{{ .Values.imageTag }}" imagePullPolicy: "{{ .Values.imagePullPolicy }}" ports: - name: schema-registry @@ -55,9 +55,9 @@ spec: name: kafka-config key: KAFKA_MINIMUM_REPLICAS volumeMounts: - - name: provisioning-scripts + - name: kafka-helper-scripts mountPath: /opt/provisioning volumes: - - name: provisioning-scripts + - name: kafka-helper-scripts configMap: - name: provisioning-scripts + name: kafka-helper-scripts diff --git a/infrastructure/helm-chart/charts/kafka/charts/schema-registry/templates/service.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/schema-registry/templates/service.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/schema-registry/values.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/values.yaml similarity index 82% rename from infrastructure/helm-chart/charts/kafka/charts/schema-registry/values.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/values.yaml index b963a8ffcf..4d633a599c 100644 --- a/infrastructure/helm-chart/charts/kafka/charts/schema-registry/values.yaml +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/schema-registry/values.yaml @@ -1,4 +1,5 @@ replicaCount: 1 +containerRegistry: ghcr.io/airyhq image: infrastructure/schema-registry imageTag: 2.0.1 imagePullPolicy: Always diff --git a/infrastructure/helm-chart/charts/kafka/charts/zookeeper/Chart.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/Chart.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/zookeeper/Chart.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/Chart.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/_helpers.tpl b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/_helpers.tpl similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/_helpers.tpl rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/_helpers.tpl diff --git a/infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/headless-service.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/headless-service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/headless-service.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/headless-service.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/poddisruptionbudget.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/poddisruptionbudget.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/poddisruptionbudget.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/poddisruptionbudget.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/service.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/service.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/statefulset.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/statefulset.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/zookeeper/templates/statefulset.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/templates/statefulset.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/zookeeper/values.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/zookeeper/values.yaml rename to infrastructure/helm-chart/charts/prerequisites/charts/kafka/charts/zookeeper/values.yaml diff --git a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/templates/kafka-config.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/templates/kafka-config.yaml new file mode 100644 index 0000000000..c9dab27439 --- /dev/null +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/templates/kafka-config.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: kafka-config + namespace: {{ .Values.global.kubernetes.namespace }} +data: + KAFKA_BROKERS: "kafka-headless:9092" + KAFKA_MINIMUM_REPLICAS: "1" + ZOOKEEPER: "zookeeper:2181" + KAFKA_SCHEMA_REGISTRY_URL: "http://schema-registry:8081" + KAFKA_COMMIT_INTERVAL_MS: "{{ .Values.commitInterval }}" diff --git a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/templates/kafka-helper-scripts.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/templates/kafka-helper-scripts.yaml new file mode 100644 index 0000000000..7620ff649b --- /dev/null +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/templates/kafka-helper-scripts.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: kafka-helper-scripts +data: + wait-for-service-url.sh: | + #!/bin/sh + url=${SERVICE_URL} + delay=${2:-10} + service=$(echo ${url} | cut -d ":" -f1) + port=$(echo ${url} | cut -d ":" -f2) + + while ! nc -z ${service} ${port} >/dev/null 2>&1; do sleep ${delay}; echo Waiting for service ${service} to start...; done + + wait-for-minimum-kafkas.sh: | + #!/bin/sh + kafka_brokers=${KAFKA_BROKERS:-kafka:9092} + replicas=${REPLICAS:-1} + delay=${1:-10} + minimum_kafkas=0 + kafkas=$(echo ${kafka_brokers} | tr "," " ") + + while [ "${minimum_kafkas}" -lt "${replicas}" ]; do + minimum_kafkas=0 + for kafka in ${kafkas}; do + service=$(echo ${kafka} | cut -d ":" -f1) + port=$(echo ${kafka} | cut -d ":" -f2) + if $(nc -w 1 -z ${service} ${port} 2>/dev/null); then + minimum_kafkas=$((minimum_kafkas+1)) + fi + done + echo Available brokers: ${minimum_kafkas}, required brokers: ${replicas} + if [ "$minimum_kafkas" -lt "$replicas" ]; then + sleep ${delay} + fi + done diff --git a/infrastructure/helm-chart/charts/prerequisites/charts/kafka/values.yaml b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/values.yaml new file mode 100644 index 0000000000..8c4599e662 --- /dev/null +++ b/infrastructure/helm-chart/charts/prerequisites/charts/kafka/values.yaml @@ -0,0 +1 @@ +commitInterval: 1000 \ No newline at end of file diff --git a/infrastructure/helm-chart/charts/prerequisites/templates/kafka.yaml b/infrastructure/helm-chart/charts/prerequisites/templates/kafka.yaml deleted file mode 100644 index 1377f2e146..0000000000 --- a/infrastructure/helm-chart/charts/prerequisites/templates/kafka.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: kafka-config - namespace: {{ .Values.global.kubernetes.namespace }} -data: - KAFKA_BROKERS: {{ .Values.kafka.brokers }} - KAFKA_MINIMUM_REPLICAS: "1" - ZOOKEEPER: {{ .Values.kafka.zookeeper }} - KAFKA_SCHEMA_REGISTRY_URL: {{ .Values.kafka.schemaRegistryUrl }} - KAFKA_COMMIT_INTERVAL_MS: "{{ .Values.kafka.commitInterval }}" diff --git a/infrastructure/helm-chart/charts/prerequisites/values.yaml b/infrastructure/helm-chart/charts/prerequisites/values.yaml deleted file mode 100644 index 90f41358c7..0000000000 --- a/infrastructure/helm-chart/charts/prerequisites/values.yaml +++ /dev/null @@ -1,8 +0,0 @@ -kafka: - brokers: "kafka-headless:9092" - zookeeper: "zookeeper:2181" - schemaRegistryUrl: "http://schema-registry:8081" - commitInterval: 1000 -beanstalk: - hostname: "beanstalk" - port: 11300 \ No newline at end of file diff --git a/infrastructure/helm-chart/charts/tools/charts/ahkq/Chart.yaml b/infrastructure/helm-chart/charts/tools/charts/akhq/Chart.yaml similarity index 84% rename from infrastructure/helm-chart/charts/tools/charts/ahkq/Chart.yaml rename to infrastructure/helm-chart/charts/tools/charts/akhq/Chart.yaml index 06d9a852fa..17218ceceb 100644 --- a/infrastructure/helm-chart/charts/tools/charts/ahkq/Chart.yaml +++ b/infrastructure/helm-chart/charts/tools/charts/akhq/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: AKHQ tool for Apache Kafka name: akhq -version: 1.0 +version: 0.16.0 \ No newline at end of file diff --git a/infrastructure/helm-chart/charts/tools/charts/ahkq/templates/configmap.yaml b/infrastructure/helm-chart/charts/tools/charts/akhq/templates/configmap.yaml similarity index 100% rename from infrastructure/helm-chart/charts/tools/charts/ahkq/templates/configmap.yaml rename to infrastructure/helm-chart/charts/tools/charts/akhq/templates/configmap.yaml diff --git a/infrastructure/helm-chart/charts/tools/charts/ahkq/templates/deployment.yaml b/infrastructure/helm-chart/charts/tools/charts/akhq/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/tools/charts/ahkq/templates/deployment.yaml rename to infrastructure/helm-chart/charts/tools/charts/akhq/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/tools/charts/ahkq/templates/ingress.yaml b/infrastructure/helm-chart/charts/tools/charts/akhq/templates/ingress.yaml similarity index 86% rename from infrastructure/helm-chart/charts/tools/charts/ahkq/templates/ingress.yaml rename to infrastructure/helm-chart/charts/tools/charts/akhq/templates/ingress.yaml index ea34bcf65c..cbbeab38ea 100644 --- a/infrastructure/helm-chart/charts/tools/charts/ahkq/templates/ingress.yaml +++ b/infrastructure/helm-chart/charts/tools/charts/akhq/templates/ingress.yaml @@ -8,7 +8,7 @@ metadata: kubernetes.io/ingress.class: traefik spec: rules: - - host: {{ get (urlParse .Values.global.kubernetes.host) "host" }} + - host: {{ .Values.global.kubernetes.host }} http: paths: - path: /tools/akhq diff --git a/infrastructure/helm-chart/charts/tools/charts/ahkq/templates/service.yaml b/infrastructure/helm-chart/charts/tools/charts/akhq/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/tools/charts/ahkq/templates/service.yaml rename to infrastructure/helm-chart/charts/tools/charts/akhq/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/tools/charts/ahkq/values.yaml b/infrastructure/helm-chart/charts/tools/charts/akhq/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/tools/charts/ahkq/values.yaml rename to infrastructure/helm-chart/charts/tools/charts/akhq/values.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka-connect/Chart.yaml b/infrastructure/helm-chart/charts/tools/charts/kafka-connect/Chart.yaml similarity index 88% rename from infrastructure/helm-chart/charts/kafka/charts/kafka-connect/Chart.yaml rename to infrastructure/helm-chart/charts/tools/charts/kafka-connect/Chart.yaml index 8f1f3c278d..1a221611fb 100644 --- a/infrastructure/helm-chart/charts/kafka/charts/kafka-connect/Chart.yaml +++ b/infrastructure/helm-chart/charts/tools/charts/kafka-connect/Chart.yaml @@ -2,4 +2,4 @@ apiVersion: v1 appVersion: "1.0" description: A Helm chart for Confluent Kafka Connect on Kubernetes name: kafka-connect -version: 0.1.0 +version: 2.7.0 diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka-connect/templates/_helpers.tpl b/infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/_helpers.tpl similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka-connect/templates/_helpers.tpl rename to infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/_helpers.tpl diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka-connect/templates/deployment.yaml b/infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/deployment.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka-connect/templates/deployment.yaml rename to infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/deployment.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka-connect/templates/jmx-configmap.yaml b/infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/jmx-configmap.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka-connect/templates/jmx-configmap.yaml rename to infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/jmx-configmap.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka-connect/templates/service.yaml b/infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/service.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka-connect/templates/service.yaml rename to infrastructure/helm-chart/charts/tools/charts/kafka-connect/templates/service.yaml diff --git a/infrastructure/helm-chart/charts/kafka/charts/kafka-connect/values.yaml b/infrastructure/helm-chart/charts/tools/charts/kafka-connect/values.yaml similarity index 100% rename from infrastructure/helm-chart/charts/kafka/charts/kafka-connect/values.yaml rename to infrastructure/helm-chart/charts/tools/charts/kafka-connect/values.yaml diff --git a/infrastructure/helm-chart/values.yaml b/infrastructure/helm-chart/values.yaml index bcbfaf7f2c..a10b88a814 100644 --- a/infrastructure/helm-chart/values.yaml +++ b/infrastructure/helm-chart/values.yaml @@ -1,4 +1,3 @@ global: kubernetes: - host: "http://airy.core" - loadbalancerAnnotations: {} + host: "airy.core" diff --git a/infrastructure/tools/topics/src/main/java/co/airy/tools/topics/Application.java b/infrastructure/tools/topics/src/main/java/co/airy/tools/topics/Application.java index 02e0dd5322..5e92b01912 100644 --- a/infrastructure/tools/topics/src/main/java/co/airy/tools/topics/Application.java +++ b/infrastructure/tools/topics/src/main/java/co/airy/tools/topics/Application.java @@ -21,6 +21,10 @@ public static void main(String[] args) { "\n" + " name: kafka-create-topics" + "\n" + + " annotations:" + + "\n" + + " \"helm.sh/hook\": \"pre-install\"" + + "\n" + "data:" + "\n" + " create-topics.sh: |" + diff --git a/lib/java/kafka/test/src/main/java/co/airy/kafka/test/KafkaTestHelper.java b/lib/java/kafka/test/src/main/java/co/airy/kafka/test/KafkaTestHelper.java index 2e230a1b09..810d1c5b61 100644 --- a/lib/java/kafka/test/src/main/java/co/airy/kafka/test/KafkaTestHelper.java +++ b/lib/java/kafka/test/src/main/java/co/airy/kafka/test/KafkaTestHelper.java @@ -17,6 +17,7 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; +import java.util.Iterator; import java.util.List; import java.util.Properties; import java.util.UUID; @@ -30,6 +31,7 @@ public class KafkaTestHelper { private final List topics; private final String consumerId = UUID.randomUUID().toString(); + private final List buffer = new ArrayList<>(); private KafkaConsumer consumer; private KafkaProducer producer; @@ -77,13 +79,35 @@ public List> consumeRecords(String key, int expected final List topicNames = List.of(topics); - //try + // It's faster to have one consumer that reads from all topics simultaneously. + // Therefore when test code only requests some of the topics we store records from all other topics in a buffer + // so that something like this can work: + // aRecords = testHelper.consumeRecords(1, topicA) + // bRecords = testHelper.consumeRecords(1, topicB) + // If there was no buffer, the first call would discard all the records expected in the second call + if (buffer.size() > 0) { + final Iterator iterator = buffer.iterator(); + while (recordsInTopic.size() < expected && iterator.hasNext()) { + ConsumerRecord consumerRecord = iterator.next(); + if (topicNames.contains(consumerRecord.topic()) && (key == null || key.equals(consumerRecord.key()))) { + recordsInTopic.add(consumerRecord); + } + } + buffer.removeAll(recordsInTopic); + + if (recordsInTopic.size() == expected) { + return recordsInTopic; + } + } + int retries = 0; do { ConsumerRecords records = consumer.poll(Duration.ofSeconds(1)); records.iterator().forEachRemaining(record -> { if (topicNames.contains(record.topic()) && (key == null || key.equals(record.key())) && recordsInTopic.size() < expected) { recordsInTopic.add(record); + } else { + buffer.add(record); } }); consumer.commitAsync(); diff --git a/lib/typescript/components/BUILD b/lib/typescript/components/BUILD index 47d45072b2..d7053071f5 100644 --- a/lib/typescript/components/BUILD +++ b/lib/typescript/components/BUILD @@ -7,6 +7,7 @@ package(default_visibility = ["//visibility:public"]) ts_web_library( name = "components", deps = [ + "//lib/typescript/model", "//lib/typescript/types", "@npm//@crello/react-lottie", "@npm//@types/node", diff --git a/lib/typescript/components/alerts/SettingsModal/style.module.scss b/lib/typescript/components/alerts/SettingsModal/style.module.scss index aaaa5f5ecf..1e731e241f 100644 --- a/lib/typescript/components/alerts/SettingsModal/style.module.scss +++ b/lib/typescript/components/alerts/SettingsModal/style.module.scss @@ -1,5 +1,6 @@ @import 'assets/scss/colors.scss'; @import 'assets/scss/fonts.scss'; +@import 'assets/scss/z-index.scss'; .container { display: flex; @@ -30,5 +31,6 @@ left: 0; right: 0; bottom: 0; + z-index: $popup; background-color: rgba(0, 0, 0, 0.75); } diff --git a/lib/typescript/components/general/Emoji/index.tsx b/lib/typescript/components/general/Emoji/index.tsx index ab610019e0..dcfd8e9883 100644 --- a/lib/typescript/components/general/Emoji/index.tsx +++ b/lib/typescript/components/general/Emoji/index.tsx @@ -1,7 +1,13 @@ import React from 'react'; -export const Emoji = props => ( - - {props.symbol} +export type Props = { + label?: string; + className?: string; + symbol: string; +}; + +export const Emoji = ({label, symbol, className}: Props) => ( + + {symbol} ); diff --git a/lib/typescript/components/index.ts b/lib/typescript/components/index.ts index ca63be4888..22af88eb48 100644 --- a/lib/typescript/components/index.ts +++ b/lib/typescript/components/index.ts @@ -3,3 +3,4 @@ export * from './cta'; export * from './general'; export * from './inputs'; export * from './loaders'; +export * from './message'; diff --git a/lib/typescript/render/components/Avatar/index.module.scss b/lib/typescript/components/message/Avatar/index.module.scss similarity index 100% rename from lib/typescript/render/components/Avatar/index.module.scss rename to lib/typescript/components/message/Avatar/index.module.scss diff --git a/lib/typescript/render/components/Avatar/index.tsx b/lib/typescript/components/message/Avatar/index.tsx similarity index 54% rename from lib/typescript/render/components/Avatar/index.tsx rename to lib/typescript/components/message/Avatar/index.tsx index 67d9297fa9..1eccdf0880 100644 --- a/lib/typescript/render/components/Avatar/index.tsx +++ b/lib/typescript/components/message/Avatar/index.tsx @@ -13,22 +13,17 @@ const fallbackAvatarImage = (event: SyntheticEvent) => event.currentTarget.alt = 'fallback avatar'; }; -const AvatarComponent = ({contact}: AvatarProps) => { - return ( - {contact?.displayName) => fallbackAvatarImage(event)} - /> - ); -}; +const AvatarComponent = ({contact}: AvatarProps) => ( + {contact?.displayName) => fallbackAvatarImage(event)} + /> +); const areEqual = (prevProps, nextProps) => { - if (prevProps.contact.avatarUrl === nextProps.contact.avatarUrl) { - return true; - } - return false; + return prevProps.contact.avatarUrl === nextProps.contact.avatarUrl; }; export const Avatar = React.memo(AvatarComponent, areEqual); diff --git a/lib/typescript/render/components/MessageInfoWrapper/index.module.scss b/lib/typescript/components/message/MessageInfoWrapper/index.module.scss similarity index 100% rename from lib/typescript/render/components/MessageInfoWrapper/index.module.scss rename to lib/typescript/components/message/MessageInfoWrapper/index.module.scss diff --git a/lib/typescript/render/components/MessageInfoWrapper/index.tsx b/lib/typescript/components/message/MessageInfoWrapper/index.tsx similarity index 100% rename from lib/typescript/render/components/MessageInfoWrapper/index.tsx rename to lib/typescript/components/message/MessageInfoWrapper/index.tsx diff --git a/lib/typescript/components/message/Reaction/index.module.scss b/lib/typescript/components/message/Reaction/index.module.scss new file mode 100644 index 0000000000..6187ddb882 --- /dev/null +++ b/lib/typescript/components/message/Reaction/index.module.scss @@ -0,0 +1,19 @@ +@import 'assets/scss/fonts.scss'; +@import 'assets/scss/colors.scss'; + +.wrapper { + width: 100%; + display: flex; + align-items: center; + justify-content: flex-end; + padding-right: 8px; + margin-top: -5px; +} + +.emojiWrapper { + border-radius: 100%; + background-color: var(--color-light-gray); + width: 24px; + height: 24px; + text-align: center; +} diff --git a/lib/typescript/components/message/Reaction/index.tsx b/lib/typescript/components/message/Reaction/index.tsx new file mode 100644 index 0000000000..4e345549c0 --- /dev/null +++ b/lib/typescript/components/message/Reaction/index.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import {Message} from 'model'; + +import styles from './index.module.scss'; +import {Emoji} from '../../general/Emoji'; + +type Props = { + message: Message; +}; + +export const Reaction = ({message}: Props) => { + const emoji = message.metadata?.reaction?.emoji; + if (!emoji) { + return null; + } + return ( +
+ +
+ ); +}; diff --git a/lib/typescript/components/message/index.ts b/lib/typescript/components/message/index.ts new file mode 100644 index 0000000000..1dc1d53724 --- /dev/null +++ b/lib/typescript/components/message/index.ts @@ -0,0 +1,3 @@ +export * from './MessageInfoWrapper'; +export * from './Reaction'; +export * from './Avatar'; diff --git a/lib/typescript/model/Message.ts b/lib/typescript/model/Message.ts index f2f699bbd7..1439a919ee 100644 --- a/lib/typescript/model/Message.ts +++ b/lib/typescript/model/Message.ts @@ -28,6 +28,10 @@ export interface Message { export interface MessageMetadata { suggestions?: Suggestions; + reaction?: { + emoji: string; + sentAt: string; + }; } export const mapMessage = (payload): Message => { diff --git a/lib/typescript/render/index.ts b/lib/typescript/render/index.ts index c6e59da7b5..6f789fa4ef 100644 --- a/lib/typescript/render/index.ts +++ b/lib/typescript/render/index.ts @@ -1,5 +1,4 @@ export * from './props'; -export * from './components/Avatar'; export * from './SourceMessage'; export * from './SourceMessagePreview'; export * from './outbound'; diff --git a/package.json b/package.json index 2a919e6b44..ebbafc3ea3 100644 --- a/package.json +++ b/package.json @@ -6,13 +6,13 @@ "@crello/react-lottie": "^0.0.11", "@reduxjs/toolkit": "^1.6.1", "@stomp/stompjs": "^6.1.0", - "@types/node": "16.4.3", + "@types/node": "16.4.10", "@types/react": "17.0.15", "@types/react-dom": "17.0.9", "@types/react-redux": "7.1.18", "@types/react-router-dom": "^5.1.8", "camelcase-keys": "^7.0.0", - "core-js": "3.15.2", + "core-js": "3.16.0", "emoji-mart": "3.0.1", "linkifyjs": "^2.1.9", "lodash-es": "^4.17.21", @@ -21,11 +21,11 @@ "react-autosize-textarea": "^7.1.0", "react-color": "^2.19.3", "react-dom": "16.14.0", - "react-markdown": "^6.0.2", + "react-markdown": "^6.0.3", "react-modal": "^3.14.3", "react-redux": "7.2.4", "react-router-dom": "5.2.0", - "redux": "^4.1.0", + "redux": "^4.1.1", "regenerator-runtime": "^0.13.9", "reselect": "4.0.0", "typesafe-actions": "^5.1.0" @@ -35,7 +35,7 @@ "@babel/plugin-proposal-class-properties": "^7.14.5", "@babel/plugin-proposal-object-rest-spread": "^7.14.5", "@babel/plugin-transform-spread": "^7.14.6", - "@babel/preset-env": "^7.14.8", + "@babel/preset-env": "^7.15.0", "@babel/preset-react": "^7.14.5", "@babel/preset-typescript": "^7.14.5", "@bazel/typescript": "^3.6.0", @@ -43,26 +43,26 @@ "@types/lodash-es": "^4.17.4", "@types/react-window-infinite-loader": "^1.0.4", "@types/resize-observer-browser": "^0.1.6", - "@typescript-eslint/eslint-plugin": "^4.28.4", - "@typescript-eslint/parser": "^4.28.4", + "@typescript-eslint/eslint-plugin": "^4.29.1", + "@typescript-eslint/parser": "^4.29.0", "babel-loader": "^8.0.6", "copy-webpack-plugin": "^9.0.1", "css-loader": "^6.2.0", - "cypress": "^7.7.0", - "eslint": "^7.31.0", + "cypress": "^8.1.0", + "eslint": "^7.32.0", "eslint-plugin-react": "^7.24.0", "file-loader": "^6.2.0", "html-webpack-plugin": "^5.3.2", "minimist": "^1.2.5", "prettier": "^2.3.2", "react-hot-loader": "^4.13.0", - "sass": "^1.36.0", + "sass": "^1.37.0", "sass-loader": "^12.1.0", "style-loader": "^3.2.1", "terser-webpack-plugin": "^5.1.4", "typescript": "4.2.4", "url-loader": "^4.1.1", - "webpack": "5.46.0", + "webpack": "5.49.0", "webpack-bundle-analyzer": "^4.4.2", "webpack-cli": "^4.7.2", "webpack-dev-server": "^3.11.2" diff --git a/scripts/dev_cli.sh b/scripts/dev_cli.sh index e85768c2d0..4208b887f6 100755 --- a/scripts/dev_cli.sh +++ b/scripts/dev_cli.sh @@ -4,8 +4,9 @@ IFS=$'\n\t' brew install -q coreutils wget +VERSION=$(cat ./VERSION) AIRY_BIN=/usr/local/bin/airy_dev -BUCKET=https://airy-core-binaries.s3.amazonaws.com/develop/darwin/amd64 +BUCKET=https://airy-core-binaries.s3.amazonaws.com/${VERSION}/darwin/amd64 OLD_SHA=$(sha256sum $AIRY_BIN | cut -f1 -d ' ') || echo "Downloading airy_dev" NEW_SHA=$(wget -qO - "${BUCKET}/airy_darwin_sha256sum.txt" | cut -f1 -d ' ') diff --git a/scripts/lint.sh b/scripts/lint.sh index d8f33e907f..c4b3dc159c 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -7,7 +7,7 @@ bazel test --test_tag_filters=lint //... echo echo "Check create-topics.sh is in sync" bazel run //infrastructure/tools/topics:app > /tmp/topics-output -cmp /tmp/topics-output infrastructure/helm-chart/charts/provisioning/templates/kafka-create-topics.yaml +cmp /tmp/topics-output infrastructure/helm-chart/charts/core/charts/provisioning/templates/kafka-create-topics.yaml echo echo "Check cli doc is in sync" cp docs/docs/cli/usage.md /tmp/ diff --git a/scripts/upload-cli-binaries.sh b/scripts/upload-cli-binaries.sh index edbabd01d2..454f03826e 100755 --- a/scripts/upload-cli-binaries.sh +++ b/scripts/upload-cli-binaries.sh @@ -13,7 +13,7 @@ for os in "linux" "darwin" "windows"; do case ${GITHUB_BRANCH} in refs/heads/develop) - s3_basepath=s3://$bucket_name/develop/$os/$arch + s3_basepath=s3://$bucket_name/$version/$os/$arch ;; refs/heads/release*) s3_basepath=s3://$bucket_name/$version-rc/$os/$arch diff --git a/scripts/upload-helm-charts.sh b/scripts/upload-helm-charts.sh new file mode 100755 index 0000000000..a3135dc08d --- /dev/null +++ b/scripts/upload-helm-charts.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -eo pipefail +IFS=$'\n\t' + +bucket_name="airy-core-helm-charts" +version=$(cat ./VERSION) + +case ${GITHUB_BRANCH} in +refs/heads/develop) + s3_basepath=s3://${bucket_name}/stable + ;; +refs/heads/release*) + s3_basepath=s3://${bucket_name}/stable + ;; +refs/heads/main) + s3_basepath=s3://${bucket_name}/stable + ;; +*) + exit 0 + ;; +esac + +sudo snap install helm --classic +helm plugin install https://github.com/hypnoglow/helm-s3.git + +helm repo add airy ${s3_basepath} +mkdir helm-repo +cd helm-repo +helm package ../infrastructure/helm-chart/ --version "${version}" +helm package ../infrastructure/helm-chart/charts/prerequisites/charts/kafka/ +helm package ../infrastructure/helm-chart/charts/prerequisites/charts/beanstalkd/ +helm package ../infrastructure/helm-chart/charts/core/ --version "${version}" +helm package ../infrastructure/helm-chart/charts/ingress-controller/ --version "${version}" +helm package ../infrastructure/helm-chart/charts/tools/charts/akhq/ +helm package ../infrastructure/helm-chart/charts/tools/charts/kafka-connect/ +find . -iname "*.tgz" -exec helm s3 push --force {} airy \; diff --git a/tools/build/bazel_status.sh b/tools/build/bazel_status.sh index fbebed105a..61dedda61d 100755 --- a/tools/build/bazel_status.sh +++ b/tools/build/bazel_status.sh @@ -12,10 +12,6 @@ else BRANCH=$(git branch --show-current) fi -if [[ $BRANCH == "develop" ]]; then - echo STABLE_VERSION "develop" -else - echo STABLE_VERSION $(cat ./VERSION) -fi +echo STABLE_VERSION $(cat ./VERSION) echo PROJECT_DIR $(pwd) diff --git a/yarn.lock b/yarn.lock index b05d516e6a..5a9a72148c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -16,10 +16,10 @@ dependencies: "@babel/highlight" "^7.14.5" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08" - integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw== +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" + integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== "@babel/core@7.14.8", "@babel/core@^7.12.3": version "7.14.8" @@ -51,6 +51,15 @@ jsesc "^2.5.1" source-map "^0.5.0" +"@babel/generator@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.0.tgz#a7d0c172e0d814974bad5aa77ace543b97917f15" + integrity sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ== + dependencies: + "@babel/types" "^7.15.0" + jsesc "^2.5.1" + source-map "^0.5.0" + "@babel/helper-annotate-as-pure@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" @@ -66,12 +75,12 @@ "@babel/helper-explode-assignable-expression" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf" - integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw== +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5", "@babel/helper-compilation-targets@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz#973df8cbd025515f3ff25db0c05efc704fa79818" + integrity sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A== dependencies: - "@babel/compat-data" "^7.14.5" + "@babel/compat-data" "^7.15.0" "@babel/helper-validator-option" "^7.14.5" browserslist "^4.16.6" semver "^6.3.0" @@ -159,6 +168,13 @@ dependencies: "@babel/types" "^7.14.5" +"@babel/helper-member-expression-to-functions@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz#0ddaf5299c8179f27f37327936553e9bba60990b" + integrity sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg== + dependencies: + "@babel/types" "^7.15.0" + "@babel/helper-module-imports@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.12.13.tgz#ec67e4404f41750463e455cc3203f6a32e93fcb0" @@ -187,6 +203,20 @@ "@babel/traverse" "^7.14.8" "@babel/types" "^7.14.8" +"@babel/helper-module-transforms@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz#679275581ea056373eddbe360e1419ef23783b08" + integrity sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg== + dependencies: + "@babel/helper-module-imports" "^7.14.5" + "@babel/helper-replace-supers" "^7.15.0" + "@babel/helper-simple-access" "^7.14.8" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/helper-validator-identifier" "^7.14.9" + "@babel/template" "^7.14.5" + "@babel/traverse" "^7.15.0" + "@babel/types" "^7.15.0" + "@babel/helper-optimise-call-expression@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c" @@ -218,12 +248,15 @@ "@babel/traverse" "^7.14.5" "@babel/types" "^7.14.5" -"@babel/helper-simple-access@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz#66ea85cf53ba0b4e588ba77fc813f53abcaa41c4" - integrity sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw== +"@babel/helper-replace-supers@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz#ace07708f5bf746bf2e6ba99572cce79b5d4e7f4" + integrity sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA== dependencies: - "@babel/types" "^7.14.5" + "@babel/helper-member-expression-to-functions" "^7.15.0" + "@babel/helper-optimise-call-expression" "^7.14.5" + "@babel/traverse" "^7.15.0" + "@babel/types" "^7.15.0" "@babel/helper-simple-access@^7.14.8": version "7.14.8" @@ -261,6 +294,11 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.8.tgz#32be33a756f29e278a0d644fa08a2c9e0f88a34c" integrity sha512-ZGy6/XQjllhYQrNw/3zfWRwZCTVSiBLZ9DHVZxn9n2gip/7ab8mv2TWlKPIBk26RwedCBoWdjLmn+t9na2Gcow== +"@babel/helper-validator-identifier@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48" + integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g== + "@babel/helper-validator-option@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" @@ -308,6 +346,11 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.8.tgz#66fd41666b2d7b840bd5ace7f7416d5ac60208d4" integrity sha512-syoCQFOoo/fzkWDeM0dLEZi5xqurb5vuyzwIMNZRNun+N/9A4cUZeQaE7dTrB8jGaKuJRBtEOajtnmw0I5hvvA== +"@babel/parser@^7.15.0": + version "7.15.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.2.tgz#08d4ffcf90d211bf77e7cc7154c6f02d468d2b1d" + integrity sha512-bMJXql1Ss8lFnvr11TZDH4ArtwlAS5NG9qBmdiFW2UHHm6MVoR+GDc5XE2b9K938cyjc9O6/+vjjcffLDtfuDg== + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.14.5.tgz#4b467302e1548ed3b1be43beae2cc9cf45e0bb7e" @@ -317,10 +360,10 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" "@babel/plugin-proposal-optional-chaining" "^7.14.5" -"@babel/plugin-proposal-async-generator-functions@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz#784a48c3d8ed073f65adcf30b57bcbf6c8119ace" - integrity sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q== +"@babel/plugin-proposal-async-generator-functions@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.9.tgz#7028dc4fa21dc199bbacf98b39bab1267d0eaf9a" + integrity sha512-d1lnh+ZnKrFKwtTYdw320+sQWCTwgkB9fmUhNXRADA4akR6wLjaruSGnIEUjpt9HCOwTr4ynFTKu19b7rFRpmw== dependencies: "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-remap-async-to-generator" "^7.14.5" @@ -587,10 +630,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-classes@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.5.tgz#0e98e82097b38550b03b483f9b51a78de0acb2cf" - integrity sha512-J4VxKAMykM06K/64z9rwiL6xnBHgB1+FVspqvlgCdwD1KUbQNfszeKVVOMh59w3sztHYIZDgnhOC4WbdEfHFDA== +"@babel/plugin-transform-classes@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.14.9.tgz#2a391ffb1e5292710b00f2e2c210e1435e7d449f" + integrity sha512-NfZpTcxU3foGWbl4wxmZ35mTsYJy8oQocbeIMoDAGGFarAmSQlL+LWMkDx/tj6pNotpbX3rltIA4dprgAPOq5A== dependencies: "@babel/helper-annotate-as-pure" "^7.14.5" "@babel/helper-function-name" "^7.14.5" @@ -675,14 +718,14 @@ "@babel/helper-plugin-utils" "^7.14.5" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.14.5.tgz#7aaee0ea98283de94da98b28f8c35701429dad97" - integrity sha512-en8GfBtgnydoao2PS+87mKyw62k02k7kJ9ltbKe0fXTHrQmG6QZZflYuGI1VVG7sVpx4E1n7KBpNlPb8m78J+A== +"@babel/plugin-transform-modules-commonjs@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.0.tgz#3305896e5835f953b5cdb363acd9e8c2219a5281" + integrity sha512-3H/R9s8cXcOGE8kgMlmjYYC9nqr5ELiPkJn4q0mypBrjhYQoc+5/Maq69vV4xRPWnkzZuwJPf5rArxpB/35Cig== dependencies: - "@babel/helper-module-transforms" "^7.14.5" + "@babel/helper-module-transforms" "^7.15.0" "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-simple-access" "^7.14.5" + "@babel/helper-simple-access" "^7.14.8" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-systemjs@^7.14.5": @@ -704,10 +747,10 @@ "@babel/helper-module-transforms" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-named-capturing-groups-regex@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.7.tgz#60c06892acf9df231e256c24464bfecb0908fd4e" - integrity sha512-DTNOTaS7TkW97xsDMrp7nycUVh6sn/eq22VaxWfEdzuEbRsiaOU0pqU7DlyUGHVsbQbSghvjKRpEl+nUCKGQSg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.14.9": + version "7.14.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz#c68f5c5d12d2ebaba3762e57c2c4f6347a46e7b2" + integrity sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.14.5" @@ -854,17 +897,17 @@ "@babel/helper-create-regexp-features-plugin" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/preset-env@^7.12.1", "@babel/preset-env@^7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.8.tgz#254942f5ca80ccabcfbb2a9f524c74bca574005b" - integrity sha512-a9aOppDU93oArQ51H+B8M1vH+tayZbuBqzjOhntGetZVa+4tTu5jp+XTwqHGG2lxslqomPYVSjIxQkFwXzgnxg== +"@babel/preset-env@^7.12.1", "@babel/preset-env@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.15.0.tgz#e2165bf16594c9c05e52517a194bf6187d6fe464" + integrity sha512-FhEpCNFCcWW3iZLg0L2NPE9UerdtsCR6ZcsGHUX6Om6kbCQeL5QZDqFDmeNHC6/fy6UH3jEge7K4qG5uC9In0Q== dependencies: - "@babel/compat-data" "^7.14.7" - "@babel/helper-compilation-targets" "^7.14.5" + "@babel/compat-data" "^7.15.0" + "@babel/helper-compilation-targets" "^7.15.0" "@babel/helper-plugin-utils" "^7.14.5" "@babel/helper-validator-option" "^7.14.5" "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-async-generator-functions" "^7.14.7" + "@babel/plugin-proposal-async-generator-functions" "^7.14.9" "@babel/plugin-proposal-class-properties" "^7.14.5" "@babel/plugin-proposal-class-static-block" "^7.14.5" "@babel/plugin-proposal-dynamic-import" "^7.14.5" @@ -897,7 +940,7 @@ "@babel/plugin-transform-async-to-generator" "^7.14.5" "@babel/plugin-transform-block-scoped-functions" "^7.14.5" "@babel/plugin-transform-block-scoping" "^7.14.5" - "@babel/plugin-transform-classes" "^7.14.5" + "@babel/plugin-transform-classes" "^7.14.9" "@babel/plugin-transform-computed-properties" "^7.14.5" "@babel/plugin-transform-destructuring" "^7.14.7" "@babel/plugin-transform-dotall-regex" "^7.14.5" @@ -908,10 +951,10 @@ "@babel/plugin-transform-literals" "^7.14.5" "@babel/plugin-transform-member-expression-literals" "^7.14.5" "@babel/plugin-transform-modules-amd" "^7.14.5" - "@babel/plugin-transform-modules-commonjs" "^7.14.5" + "@babel/plugin-transform-modules-commonjs" "^7.15.0" "@babel/plugin-transform-modules-systemjs" "^7.14.5" "@babel/plugin-transform-modules-umd" "^7.14.5" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.9" "@babel/plugin-transform-new-target" "^7.14.5" "@babel/plugin-transform-object-super" "^7.14.5" "@babel/plugin-transform-parameters" "^7.14.5" @@ -926,11 +969,11 @@ "@babel/plugin-transform-unicode-escapes" "^7.14.5" "@babel/plugin-transform-unicode-regex" "^7.14.5" "@babel/preset-modules" "^0.1.4" - "@babel/types" "^7.14.8" + "@babel/types" "^7.15.0" babel-plugin-polyfill-corejs2 "^0.2.2" babel-plugin-polyfill-corejs3 "^0.2.2" babel-plugin-polyfill-regenerator "^0.2.2" - core-js-compat "^3.15.0" + core-js-compat "^3.16.0" semver "^6.3.0" "@babel/preset-modules@^0.1.4": @@ -996,12 +1039,27 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.12.13", "@babel/types@^7.12.6", "@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.4.4": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.14.8.tgz#38109de8fcadc06415fbd9b74df0065d4d41c728" - integrity sha512-iob4soQa7dZw8nodR/KlOQkPh9S4I8RwCxwRIFuiMRYjOzH/KJzdUfDgz6cGi5dDaclXF4P2PAhCdrBJNIg68Q== +"@babel/traverse@^7.15.0": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.0.tgz#4cca838fd1b2a03283c1f38e141f639d60b3fc98" + integrity sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw== dependencies: - "@babel/helper-validator-identifier" "^7.14.8" + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.15.0" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-hoist-variables" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/parser" "^7.15.0" + "@babel/types" "^7.15.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.12.13", "@babel/types@^7.12.6", "@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.15.0", "@babel/types@^7.4.4": + version "7.15.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.0.tgz#61af11f2286c4e9c69ca8deb5f4375a73c72dcbd" + integrity sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ== + dependencies: + "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" "@bazel/typescript@^3.6.0": @@ -1384,10 +1442,10 @@ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21" integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA== -"@types/node@*", "@types/node@16.4.3": - version "16.4.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.3.tgz#c01c1a215721f6dec71b47d88b4687463601ba48" - integrity sha512-GKM4FLMkWDc0sfx7tXqPWkM6NBow1kge0fgQh0bOnlqo4iT1kvTvMEKE0c1RtUGnbLlGRXiAA8SumE//90uKAg== +"@types/node@*", "@types/node@16.4.10": + version "16.4.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.4.10.tgz#e57e2a54fc6da58da94b3571b1cb456d39f88597" + integrity sha512-TmVHsm43br64js9BqHWqiDZA+xMtbUpI1MBIA0EyiBmoV9pcEYFOSdj5fr6enZNfh4fChh+AGOLIzGwJnkshyQ== "@types/node@^10.1.0": version "10.17.55" @@ -1504,73 +1562,107 @@ dependencies: "@types/node" "*" -"@typescript-eslint/eslint-plugin@^4.28.4": - version "4.28.4" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.28.4.tgz#e73c8cabbf3f08dee0e1bda65ed4e622ae8f8921" - integrity sha512-s1oY4RmYDlWMlcV0kKPBaADn46JirZzvvH7c2CtAqxCY96S538JRBAzt83RrfkDheV/+G/vWNK0zek+8TB3Gmw== +"@typescript-eslint/eslint-plugin@^4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.1.tgz#808d206e2278e809292b5de752a91105da85860b" + integrity sha512-AHqIU+SqZZgBEiWOrtN94ldR3ZUABV5dUG94j8Nms9rQnHFc8fvDOue/58K4CFz6r8OtDDc35Pw9NQPWo0Ayrw== dependencies: - "@typescript-eslint/experimental-utils" "4.28.4" - "@typescript-eslint/scope-manager" "4.28.4" + "@typescript-eslint/experimental-utils" "4.29.1" + "@typescript-eslint/scope-manager" "4.29.1" debug "^4.3.1" functional-red-black-tree "^1.0.1" regexpp "^3.1.0" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/experimental-utils@4.28.4": - version "4.28.4" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.28.4.tgz#9c70c35ebed087a5c70fb0ecd90979547b7fec96" - integrity sha512-OglKWOQRWTCoqMSy6pm/kpinEIgdcXYceIcH3EKWUl4S8xhFtN34GQRaAvTIZB9DD94rW7d/U7tUg3SYeDFNHA== +"@typescript-eslint/experimental-utils@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.1.tgz#0af2b17b0296b60c6b207f11062119fa9c5a8994" + integrity sha512-kl6QG6qpzZthfd2bzPNSJB2YcZpNOrP6r9jueXupcZHnL74WiuSjaft7WSu17J9+ae9zTlk0KJMXPUj0daBxMw== dependencies: "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.28.4" - "@typescript-eslint/types" "4.28.4" - "@typescript-eslint/typescript-estree" "4.28.4" + "@typescript-eslint/scope-manager" "4.29.1" + "@typescript-eslint/types" "4.29.1" + "@typescript-eslint/typescript-estree" "4.29.1" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@^4.28.4": - version "4.28.4" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.28.4.tgz#bc462dc2779afeefdcf49082516afdc3e7b96fab" - integrity sha512-4i0jq3C6n+og7/uCHiE6q5ssw87zVdpUj1k6VlVYMonE3ILdFApEzTWgppSRG4kVNB/5jxnH+gTeKLMNfUelQA== +"@typescript-eslint/parser@^4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.0.tgz#e5367ca3c63636bb5d8e0748fcbab7a4f4a04289" + integrity sha512-+92YRNHFdXgq+GhWQPT2bmjX09X7EH36JfgN2/4wmhtwV/HPxozpCNst8jrWcngLtEVd/4zAwA6BKojAlf+YqA== dependencies: - "@typescript-eslint/scope-manager" "4.28.4" - "@typescript-eslint/types" "4.28.4" - "@typescript-eslint/typescript-estree" "4.28.4" + "@typescript-eslint/scope-manager" "4.29.0" + "@typescript-eslint/types" "4.29.0" + "@typescript-eslint/typescript-estree" "4.29.0" debug "^4.3.1" -"@typescript-eslint/scope-manager@4.28.4": - version "4.28.4" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.28.4.tgz#bdbce9b6a644e34f767bd68bc17bb14353b9fe7f" - integrity sha512-ZJBNs4usViOmlyFMt9X9l+X0WAFcDH7EdSArGqpldXu7aeZxDAuAzHiMAeI+JpSefY2INHrXeqnha39FVqXb8w== +"@typescript-eslint/scope-manager@4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.0.tgz#cf5474f87321bedf416ef65839b693bddd838599" + integrity sha512-HPq7XAaDMM3DpmuijxLV9Io8/6pQnliiXMQUcAdjpJJSR+fdmbD/zHCd7hMkjJn04UQtCQBtshgxClzg6NIS2w== + dependencies: + "@typescript-eslint/types" "4.29.0" + "@typescript-eslint/visitor-keys" "4.29.0" + +"@typescript-eslint/scope-manager@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.1.tgz#f25da25bc6512812efa2ce5ebd36619d68e61358" + integrity sha512-Hzv/uZOa9zrD/W5mftZa54Jd5Fed3tL6b4HeaOpwVSabJK8CJ+2MkDasnX/XK4rqP5ZTWngK1ZDeCi6EnxPQ7A== dependencies: - "@typescript-eslint/types" "4.28.4" - "@typescript-eslint/visitor-keys" "4.28.4" + "@typescript-eslint/types" "4.29.1" + "@typescript-eslint/visitor-keys" "4.29.1" + +"@typescript-eslint/types@4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.0.tgz#c8f1a1e4441ea4aca9b3109241adbc145f7f8a4e" + integrity sha512-2YJM6XfWfi8pgU2HRhTp7WgRw78TCRO3dOmSpAvIQ8MOv4B46JD2chnhpNT7Jq8j0APlIbzO1Bach734xxUl4A== -"@typescript-eslint/types@4.28.4": - version "4.28.4" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.28.4.tgz#41acbd79b5816b7c0dd7530a43d97d020d3aeb42" - integrity sha512-3eap4QWxGqkYuEmVebUGULMskR6Cuoc/Wii0oSOddleP4EGx1tjLnZQ0ZP33YRoMDCs5O3j56RBV4g14T4jvww== +"@typescript-eslint/types@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.1.tgz#94cce6cf7cc83451df03339cda99d326be2feaf5" + integrity sha512-Jj2yu78IRfw4nlaLtKjVaGaxh/6FhofmQ/j8v3NXmAiKafbIqtAPnKYrf0sbGjKdj0hS316J8WhnGnErbJ4RCA== + +"@typescript-eslint/typescript-estree@4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.0.tgz#af7ab547757b86c91bfdbc54ff86845410856256" + integrity sha512-8ZpNHDIOyqzzgZrQW9+xQ4k5hM62Xy2R4RPO3DQxMc5Rq5QkCdSpk/drka+DL9w6sXNzV5nrdlBmf8+x495QXQ== + dependencies: + "@typescript-eslint/types" "4.29.0" + "@typescript-eslint/visitor-keys" "4.29.0" + debug "^4.3.1" + globby "^11.0.3" + is-glob "^4.0.1" + semver "^7.3.5" + tsutils "^3.21.0" -"@typescript-eslint/typescript-estree@4.28.4": - version "4.28.4" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.28.4.tgz#252e6863278dc0727244be9e371eb35241c46d00" - integrity sha512-z7d8HK8XvCRyN2SNp+OXC2iZaF+O2BTquGhEYLKLx5k6p0r05ureUtgEfo5f6anLkhCxdHtCf6rPM1p4efHYDQ== +"@typescript-eslint/typescript-estree@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.1.tgz#7b32a25ff8e51f2671ccc6b26cdbee3b1e6c5e7f" + integrity sha512-lIkkrR9E4lwZkzPiRDNq0xdC3f2iVCUjw/7WPJ4S2Sl6C3nRWkeE1YXCQ0+KsiaQRbpY16jNaokdWnm9aUIsfw== dependencies: - "@typescript-eslint/types" "4.28.4" - "@typescript-eslint/visitor-keys" "4.28.4" + "@typescript-eslint/types" "4.29.1" + "@typescript-eslint/visitor-keys" "4.29.1" debug "^4.3.1" globby "^11.0.3" is-glob "^4.0.1" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.28.4": - version "4.28.4" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.28.4.tgz#92dacfefccd6751cbb0a964f06683bfd72d0c4d3" - integrity sha512-NIAXAdbz1XdOuzqkJHjNKXKj8QQ4cv5cxR/g0uQhCYf/6//XrmfpaYsM7PnBcNbfvTDLUkqQ5TPNm1sozDdTWg== +"@typescript-eslint/visitor-keys@4.29.0": + version "4.29.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.0.tgz#1ff60f240def4d85ea68d4fd2e4e9759b7850c04" + integrity sha512-LoaofO1C/jAJYs0uEpYMXfHboGXzOJeV118X4OsZu9f7rG7Pr9B3+4HTU8+err81rADa4xfQmAxnRnPAI2jp+Q== + dependencies: + "@typescript-eslint/types" "4.29.0" + eslint-visitor-keys "^2.0.0" + +"@typescript-eslint/visitor-keys@4.29.1": + version "4.29.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.1.tgz#0615be8b55721f5e854f3ee99f1a714f2d093e5d" + integrity sha512-zLqtjMoXvgdZY/PG6gqA73V8BjqPs4af1v2kiiETBObp+uC6gRYnJLmJHxC0QyUrrHDLJPIWNYxoBV3wbcRlag== dependencies: - "@typescript-eslint/types" "4.28.4" + "@typescript-eslint/types" "4.29.1" eslint-visitor-keys "^2.0.0" "@webassemblyjs/ast@1.11.1": @@ -1729,6 +1821,11 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" +acorn-import-assertions@^1.7.6: + version "1.7.6" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.7.6.tgz#580e3ffcae6770eebeec76c3b9723201e9d01f78" + integrity sha512-FlVvVFA1TX6l3lp8VjDnYYq7R1nyW6x3svAt4nDgrWQ9SBaSh9CnbwgSUTasgfNfOG5HlM1ehugCvM+hjo56LA== + acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" @@ -2620,18 +2717,18 @@ copy-webpack-plugin@^9.0.1: schema-utils "^3.0.0" serialize-javascript "^6.0.0" -core-js-compat@^3.15.0, core-js-compat@^3.9.1: - version "3.15.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.15.0.tgz#e14a371123db9d1c5b41206d3f420643d238b8fa" - integrity sha512-8X6lWsG+s7IfOKzV93a7fRYfWRZobOfjw5V5rrq43Vh/W+V6qYxl7Akalsvgab4PFT/4L/pjQbdBUEM36NXKrw== +core-js-compat@^3.16.0, core-js-compat@^3.9.1: + version "3.16.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.16.0.tgz#fced4a0a534e7e02f7e084bff66c701f8281805f" + integrity sha512-5D9sPHCdewoUK7pSUPfTF7ZhLh8k9/CoJXWUEo+F1dZT5Z1DVgcuRqUKhjeKW+YLb8f21rTFgWwQJiNw1hoZ5Q== dependencies: browserslist "^4.16.6" semver "7.0.0" -core-js@3.15.2: - version "3.15.2" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.15.2.tgz#740660d2ff55ef34ce664d7e2455119c5bdd3d61" - integrity sha512-tKs41J7NJVuaya8DxIOCnl8QuPHx5/ZVbFo1oKgVl1qHFBBrDctzQGtuLjPpRdNTWmKPH6oEvgN/MUID+l485Q== +core-js@3.16.0: + version "3.16.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.0.tgz#1d46fb33720bc1fa7f90d20431f36a5540858986" + integrity sha512-5+5VxRFmSf97nM8Jr2wzOwLqRo6zphH2aX+7KsAUONObyzakDNq2G/bgbhinxB4PoV9L3aXQYhiDKyIKWd2c8g== core-util-is@1.0.2, core-util-is@~1.0.0: version "1.0.2" @@ -2752,10 +2849,10 @@ csstype@^3.0.2: resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b" integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g== -cypress@^7.7.0: - version "7.7.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-7.7.0.tgz#0839ae28e5520536f9667d6c9ae81496b3836e64" - integrity sha512-uYBYXNoI5ym0UxROwhQXWTi8JbUEjpC6l/bzoGZNxoKGsLrC1SDPgIDJMgLX/MeEdPL0UInXLDUWN/rSyZUCjQ== +cypress@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-8.1.0.tgz#9aaed7fb2a4d1876528b72d437f97bc824db0735" + integrity sha512-GXjlqPjY/6HPbQwAp3AvlA1Mk/NoJTAmqVSUhQsuM/1xDpd/FQHkxVuq5h6O6RrAoCXSgpZPXFsVtdqE+FwEJw== dependencies: "@cypress/request" "^2.88.5" "@cypress/xvfb" "^1.2.4" @@ -3271,10 +3368,10 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.0.0.tgz#21fdc8fbcd9c795cc0321f0563702095751511a8" integrity sha512-QudtT6av5WXels9WjIM7qz1XD1cWGvX4gGXvp/zBn9nXG02D0utdU3Em2m/QjTnrsk6bBjmCygl3rmj118msQQ== -eslint@^7.31.0: - version "7.31.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.31.0.tgz#f972b539424bf2604907a970860732c5d99d3aca" - integrity sha512-vafgJpSh2ia8tnTkNUkwxGmnumgckLh5aAbLa1xRmIn9+owi8qBNGKL+B881kNKNTy7FFqTEkpNkUvmw0n6PkA== +eslint@^7.32.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== dependencies: "@babel/code-frame" "7.12.11" "@eslint/eslintrc" "^0.4.3" @@ -5829,7 +5926,7 @@ prop-types@^15.5.10, prop-types@^15.5.6, prop-types@^15.6.0, prop-types@^15.6.1, object-assign "^4.1.1" react-is "^16.8.1" -property-information@^5.0.0: +property-information@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== @@ -6014,16 +6111,16 @@ react-lifecycles-compat@^3.0.0, react-lifecycles-compat@^3.0.4: resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== -react-markdown@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-6.0.2.tgz#d89be45c278b1e5f0196f851fffb11e30c69f027" - integrity sha512-Et2AjXAsbmPP1nLQQRqmVgcqzfwcz8uQJ8VAdADs8Nk/aaUA0YeU9RDLuCtD+GwajCnm/+Iiu2KPmXzmD/M3vA== +react-markdown@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-6.0.3.tgz#625ec767fa321d91801129387e7d31ee0cb99254" + integrity sha512-kQbpWiMoBHnj9myLlmZG9T1JdoT/OEyHK7hqM6CqFT14MAkgWiWBUYijLyBmxbntaN6dCDicPcUhWhci1QYodg== dependencies: "@types/hast" "^2.0.0" "@types/unist" "^2.0.3" comma-separated-tokens "^1.0.0" prop-types "^15.7.2" - property-information "^5.0.0" + property-information "^5.3.0" react-is "^17.0.0" remark-parse "^9.0.0" remark-rehype "^8.0.0" @@ -6149,10 +6246,10 @@ redux-thunk@^2.3.0: resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== -redux@^4.0.0, redux@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.0.tgz#eb049679f2f523c379f1aff345c8612f294c88d4" - integrity sha512-uI2dQN43zqLWCt6B/BMGRMY6db7TTY4qeHHfGeKb3EOhmOKjU3KdWvNLJyqaHRksv/ErdNH7cFZWg9jXtewy4g== +redux@^4.0.0, redux@^4.1.0, redux@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/redux/-/redux-4.1.1.tgz#76f1c439bb42043f985fbd9bf21990e60bd67f47" + integrity sha512-hZQZdDEM25UY2P493kPYuKqviVwZ58lEmGQNeQ+gXa+U0gYPUBf7NKYazbe3m+bs/DzM/ahN12DbF+NG8i0CWw== dependencies: "@babel/runtime" "^7.9.2" @@ -6438,10 +6535,10 @@ sass-loader@^12.1.0: klona "^2.0.4" neo-async "^2.6.2" -sass@^1.36.0: - version "1.36.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.36.0.tgz#5912ef9d5d16714171ba11cb17edb274c4bbc07e" - integrity sha512-fQzEjipfOv5kh930nu3Imzq3ie/sGDc/4KtQMJlt7RRdrkQSfe37Bwi/Rf/gfuYHsIuE1fIlDMvpyMcEwjnPvg== +sass@^1.37.0: + version "1.37.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.37.0.tgz#f1b03a9d072ee9053a29d125c8130c78e92827c2" + integrity sha512-B+Tu6cSAG8ffs/cqsZl/bgSH2pCmavDaPTYAoW8QA1qNHh/RqndNfVKuABKYkLjUQ5aq/BnCENVpE80cqdSM1w== dependencies: chokidar ">=3.0.0 <4.0.0" @@ -6731,11 +6828,6 @@ sockjs@^0.3.21: uuid "^3.4.0" websocket-driver "^0.7.4" -source-list-map@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - source-map-js@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" @@ -7631,18 +7723,15 @@ webpack-merge@^5.7.3: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.1.tgz#570de0af163949fe272233c2cefe1b56f74511fd" - integrity sha512-y9EI9AO42JjEcrTJFOYmVywVZdKVUfOvDUPsJea5GIr1JOEGFVqwlY2K098fFoIjOkDzHn2AjRvM8dsBZu+gCA== - dependencies: - source-list-map "^2.0.1" - source-map "^0.6.1" +webpack-sources@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.0.tgz#b16973bcf844ebcdb3afde32eda1c04d0b90f89d" + integrity sha512-fahN08Et7P9trej8xz/Z7eRu8ltyiygEo/hnRi9KqBUs80KeDcnf96ZJo++ewWd84fEf3xSX9bp4ZS9hbw0OBw== -webpack@5.46.0: - version "5.46.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.46.0.tgz#105d20d96f79db59b316b0ae54316f0f630314b5" - integrity sha512-qxD0t/KTedJbpcXUmvMxY5PUvXDbF8LsThCzqomeGaDlCA6k998D8yYVwZMvO8sSM3BTEOaD4uzFniwpHaTIJw== +webpack@5.49.0: + version "5.49.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.49.0.tgz#e250362b781a9fb614ba0a97ed67c66b9c5310cd" + integrity sha512-XarsANVf28A7Q3KPxSnX80EkCcuOer5hTOEJWJNvbskOZ+EK3pobHarGHceyUZMxpsTHBHhlV7hiQyLZzGosYw== dependencies: "@types/eslint-scope" "^3.7.0" "@types/estree" "^0.0.50" @@ -7650,6 +7739,7 @@ webpack@5.46.0: "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" acorn "^8.4.1" + acorn-import-assertions "^1.7.6" browserslist "^4.14.5" chrome-trace-event "^1.0.2" enhanced-resolve "^5.8.0" @@ -7666,7 +7756,7 @@ webpack@5.46.0: tapable "^2.1.1" terser-webpack-plugin "^5.1.3" watchpack "^2.2.0" - webpack-sources "^2.3.1" + webpack-sources "^3.2.0" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4"