From ec10a425b878d155417705ca5e536ae4f951070c Mon Sep 17 00:00:00 2001 From: Rene Moser Date: Tue, 30 Nov 2021 17:01:40 +0100 Subject: [PATCH 01/86] Add option to configure spring's server.forward_headers_strategy --- application/src/main/resources/thingsboard.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 69bfd06bc8..813e75ee57 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -19,6 +19,8 @@ server: address: "${HTTP_BIND_ADDRESS:0.0.0.0}" # Server bind port port: "${HTTP_BIND_PORT:8080}" + # Server forward headers strategy + forward_headers_strategy: "${HTTP_FORWARD_HEADERS_STRATEGY:NONE}" # Server SSL configuration ssl: # Enable/disable SSL support From 3351ced60aceb7a4c3e7e5b6010190b99201ae7a Mon Sep 17 00:00:00 2001 From: desoliture Date: Tue, 4 Jan 2022 17:46:46 +0200 Subject: [PATCH 02/86] add backend support for dynamic values for schedules in alarm rules --- .../device/profile/CustomTimeSchedule.java | 3 ++ .../device/profile/SpecificTimeSchedule.java | 3 ++ .../transport/adaptor/JsonConverter.java | 4 ++ .../rule/engine/profile/AlarmRuleState.java | 41 ++++++++++++++----- .../rule/engine/profile/ProfileState.java | 24 +++++++++++ 5 files changed, 64 insertions(+), 11 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CustomTimeSchedule.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CustomTimeSchedule.java index 89bf54eb25..83e8b3874e 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CustomTimeSchedule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/CustomTimeSchedule.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.data.device.profile; import lombok.Data; +import org.thingsboard.server.common.data.query.DynamicValue; import java.util.List; @@ -25,6 +26,8 @@ public class CustomTimeSchedule implements AlarmSchedule { private String timezone; private List items; + private DynamicValue dynamicValue; + @Override public AlarmScheduleType getType() { return AlarmScheduleType.CUSTOM; diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java index 9ef17f25b0..57e57a1b24 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java @@ -16,6 +16,7 @@ package org.thingsboard.server.common.data.device.profile; import lombok.Data; +import org.thingsboard.server.common.data.query.DynamicValue; import java.util.List; import java.util.Set; @@ -28,6 +29,8 @@ public class SpecificTimeSchedule implements AlarmSchedule { private long startsOn; private long endsOn; + private DynamicValue dynamicValue; + @Override public AlarmScheduleType getType() { return AlarmScheduleType.SPECIFIC_TIME; diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java index be4143e388..af2ac148ce 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/adaptor/JsonConverter.java @@ -573,6 +573,10 @@ public class JsonConverter { return JSON_PARSER.parse(json); } + public static T parse(String json, Class clazz) { + return fromJson(parse(json), clazz); + } + public static String toJson(JsonElement element) { return GSON.toJson(element); } diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java index 8ae6390b31..724b10c269 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java @@ -40,6 +40,7 @@ import org.thingsboard.server.common.data.query.KeyFilterPredicate; import org.thingsboard.server.common.data.query.NumericFilterPredicate; import org.thingsboard.server.common.data.query.StringFilterPredicate; import org.thingsboard.server.common.msg.tools.SchedulerUtils; +import org.thingsboard.server.common.transport.adaptor.JsonConverter; import java.time.Instant; import java.time.ZoneId; @@ -115,7 +116,7 @@ class AlarmRuleState { } public AlarmEvalResult eval(DataSnapshot data) { - boolean active = isActive(data.getTs()); + boolean active = isActive(data, data.getTs()); switch (spec.getType()) { case SIMPLE: return (active && eval(alarmRule.getCondition(), data)) ? AlarmEvalResult.TRUE : AlarmEvalResult.FALSE; @@ -128,7 +129,7 @@ class AlarmRuleState { } } - private boolean isActive(long eventTs) { + private boolean isActive(DataSnapshot data, long eventTs) { if (eventTs == 0L) { eventTs = System.currentTimeMillis(); } @@ -138,10 +139,28 @@ class AlarmRuleState { switch (alarmRule.getSchedule().getType()) { case ANY_TIME: return true; - case SPECIFIC_TIME: - return isActiveSpecific((SpecificTimeSchedule) alarmRule.getSchedule(), eventTs); - case CUSTOM: - return isActiveCustom((CustomTimeSchedule) alarmRule.getSchedule(), eventTs); + case SPECIFIC_TIME: { + SpecificTimeSchedule originalSchedule = (SpecificTimeSchedule) alarmRule.getSchedule(); + EntityKeyValue dynamicValue = getDynamicValue(data, originalSchedule.getDynamicValue()); + + if (dynamicValue != null) { + SpecificTimeSchedule schedule = JsonConverter.parse(dynamicValue.getJsonValue(), SpecificTimeSchedule.class); + originalSchedule = schedule == null ? originalSchedule : schedule; + } + + return isActiveSpecific(originalSchedule, eventTs); + } + case CUSTOM: { + CustomTimeSchedule originalSchedule = (CustomTimeSchedule) alarmRule.getSchedule(); + EntityKeyValue dynamicValue = getDynamicValue(data, originalSchedule.getDynamicValue()); + + if (dynamicValue != null) { + CustomTimeSchedule schedule = JsonConverter.parse(dynamicValue.getJsonValue(), CustomTimeSchedule.class); + originalSchedule = schedule == null ? originalSchedule : schedule; + } + + return isActiveCustom(originalSchedule, eventTs); + } default: throw new RuntimeException("Unsupported schedule type: " + alarmRule.getSchedule().getType()); } @@ -236,7 +255,7 @@ class AlarmRuleState { if (repeating.getPredicate().getDynamicValue() != null && repeating.getPredicate().getDynamicValue().getSourceAttribute() != null) { - EntityKeyValue repeatingKeyValue = getDynamicPredicateValue(data, repeating.getPredicate().getDynamicValue()); + EntityKeyValue repeatingKeyValue = getDynamicValue(data, repeating.getPredicate().getDynamicValue()); if (repeatingKeyValue != null) { repeatingTimes = repeatingKeyValue.getLngValue(); } @@ -257,7 +276,7 @@ class AlarmRuleState { if (duration.getPredicate().getDynamicValue() != null && duration.getPredicate().getDynamicValue().getSourceAttribute() != null) { - EntityKeyValue durationKeyValue = getDynamicPredicateValue(data, duration.getPredicate().getDynamicValue()); + EntityKeyValue durationKeyValue = getDynamicValue(data, duration.getPredicate().getDynamicValue()); if (durationKeyValue != null) { durationTimeInMs = timeUnit.toMillis(durationKeyValue.getLngValue()); } @@ -276,7 +295,7 @@ class AlarmRuleState { long requiredDurationInMs = resolveRequiredDurationInMs(dataSnapshot); if (requiredDurationInMs > 0 && state.getLastEventTs() > 0 && ts > state.getLastEventTs()) { long duration = state.getDuration() + (ts - state.getLastEventTs()); - if (isActive(ts)) { + if (isActive(dataSnapshot, ts)) { return duration > requiredDurationInMs ? AlarmEvalResult.TRUE : AlarmEvalResult.NOT_YET_TRUE; } else { return AlarmEvalResult.FALSE; @@ -443,7 +462,7 @@ class AlarmRuleState { } private T getPredicateValue(DataSnapshot data, FilterPredicateValue value, AlarmConditionFilter filter, Function transformFunction) { - EntityKeyValue ekv = getDynamicPredicateValue(data, value.getDynamicValue()); + EntityKeyValue ekv = getDynamicValue(data, value.getDynamicValue()); if (ekv != null) { T result = transformFunction.apply(ekv); if (result != null) { @@ -457,7 +476,7 @@ class AlarmRuleState { } } - private EntityKeyValue getDynamicPredicateValue(DataSnapshot data, DynamicValue value) { + private EntityKeyValue getDynamicValue(DataSnapshot data, DynamicValue value) { EntityKeyValue ekv = null; if (value != null) { switch (value.getSourceType()) { diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java index 0cd4ed63ee..6d3c48892c 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java @@ -27,6 +27,9 @@ import org.thingsboard.server.common.data.device.profile.AlarmRule; import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; import org.thingsboard.server.common.data.device.profile.DurationAlarmConditionSpec; import org.thingsboard.server.common.data.device.profile.RepeatingAlarmConditionSpec; +import org.thingsboard.server.common.data.device.profile.CustomTimeSchedule; +import org.thingsboard.server.common.data.device.profile.SpecificTimeSchedule; +import org.thingsboard.server.common.data.device.profile.AlarmSchedule; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.query.ComplexFilterPredicate; import org.thingsboard.server.common.data.query.DynamicValue; @@ -77,6 +80,7 @@ class ProfileState { addDynamicValuesRecursively(keyFilter.getPredicate(), entityKeys, ruleKeys); } addEntityKeysFromAlarmConditionSpec(alarmRule); + addScheduleDynamicValues(alarmRule.getSchedule()); })); if (alarm.getClearRule() != null) { var clearAlarmKeys = alarmClearKeys.computeIfAbsent(alarm.getId(), id -> new HashSet<>()); @@ -91,6 +95,26 @@ class ProfileState { } } + private void addScheduleDynamicValues(AlarmSchedule schedule) { + DynamicValue dynamicValue = null; + switch (schedule.getType()) { + case SPECIFIC_TIME: + SpecificTimeSchedule specSchedule = (SpecificTimeSchedule) schedule; + dynamicValue = specSchedule.getDynamicValue(); + break; + case CUSTOM: + CustomTimeSchedule custSchedule = (CustomTimeSchedule) schedule; + dynamicValue = custSchedule.getDynamicValue(); + } + + if (dynamicValue != null) { + entityKeys.add( + new AlarmConditionFilterKey(AlarmConditionKeyType.ATTRIBUTE, + dynamicValue.getSourceAttribute()) + ); + } + } + private void addEntityKeysFromAlarmConditionSpec(AlarmRule alarmRule) { AlarmConditionSpec spec = alarmRule.getCondition().getSpec(); if (spec == null) { From 2b203bfdd59cc7b2455411bc6230c2fdec9c5689 Mon Sep 17 00:00:00 2001 From: desoliture Date: Wed, 5 Jan 2022 13:24:53 +0200 Subject: [PATCH 03/86] fix notNull checking for schedule in ProfileState, rename variables and fix logic for parsing dynamicValues in AlarmRuleState --- .../rule/engine/profile/AlarmRuleState.java | 28 +++++++++++-------- .../rule/engine/profile/ProfileState.java | 14 ++++++---- 2 files changed, 25 insertions(+), 17 deletions(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java index 724b10c269..c5ad4607b2 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java @@ -140,26 +140,30 @@ class AlarmRuleState { case ANY_TIME: return true; case SPECIFIC_TIME: { - SpecificTimeSchedule originalSchedule = (SpecificTimeSchedule) alarmRule.getSchedule(); - EntityKeyValue dynamicValue = getDynamicValue(data, originalSchedule.getDynamicValue()); + SpecificTimeSchedule defaultSchedule = (SpecificTimeSchedule) alarmRule.getSchedule(); + EntityKeyValue dynamicValue = getDynamicValue(data, defaultSchedule.getDynamicValue()); - if (dynamicValue != null) { - SpecificTimeSchedule schedule = JsonConverter.parse(dynamicValue.getJsonValue(), SpecificTimeSchedule.class); - originalSchedule = schedule == null ? originalSchedule : schedule; + SpecificTimeSchedule schedule; + try { + schedule = JsonConverter.parse(dynamicValue.getJsonValue(), SpecificTimeSchedule.class); + } catch (Exception e) { + schedule = defaultSchedule; } - return isActiveSpecific(originalSchedule, eventTs); + return isActiveSpecific(schedule, eventTs); } case CUSTOM: { - CustomTimeSchedule originalSchedule = (CustomTimeSchedule) alarmRule.getSchedule(); - EntityKeyValue dynamicValue = getDynamicValue(data, originalSchedule.getDynamicValue()); + CustomTimeSchedule defaultSchedule = (CustomTimeSchedule) alarmRule.getSchedule(); + EntityKeyValue dynamicValue = getDynamicValue(data, defaultSchedule.getDynamicValue()); - if (dynamicValue != null) { - CustomTimeSchedule schedule = JsonConverter.parse(dynamicValue.getJsonValue(), CustomTimeSchedule.class); - originalSchedule = schedule == null ? originalSchedule : schedule; + CustomTimeSchedule schedule; + try { + schedule = JsonConverter.parse(dynamicValue.getJsonValue(), CustomTimeSchedule.class); + } catch (Exception e) { + schedule = defaultSchedule; } - return isActiveCustom(originalSchedule, eventTs); + return isActiveCustom(schedule, eventTs); } default: throw new RuntimeException("Unsupported schedule type: " + alarmRule.getSchedule().getType()); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java index 6d3c48892c..c8751d65f7 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java @@ -80,7 +80,10 @@ class ProfileState { addDynamicValuesRecursively(keyFilter.getPredicate(), entityKeys, ruleKeys); } addEntityKeysFromAlarmConditionSpec(alarmRule); - addScheduleDynamicValues(alarmRule.getSchedule()); + AlarmSchedule schedule = alarmRule.getSchedule(); + if (schedule != null) { + addScheduleDynamicValues(schedule); + } })); if (alarm.getClearRule() != null) { var clearAlarmKeys = alarmClearKeys.computeIfAbsent(alarm.getId(), id -> new HashSet<>()); @@ -99,12 +102,13 @@ class ProfileState { DynamicValue dynamicValue = null; switch (schedule.getType()) { case SPECIFIC_TIME: - SpecificTimeSchedule specSchedule = (SpecificTimeSchedule) schedule; - dynamicValue = specSchedule.getDynamicValue(); + SpecificTimeSchedule specificTimeSchedule = (SpecificTimeSchedule) schedule; + dynamicValue = specificTimeSchedule.getDynamicValue(); break; case CUSTOM: - CustomTimeSchedule custSchedule = (CustomTimeSchedule) schedule; - dynamicValue = custSchedule.getDynamicValue(); + CustomTimeSchedule customTimeSchedule = (CustomTimeSchedule) schedule; + dynamicValue = customTimeSchedule.getDynamicValue(); + break; } if (dynamicValue != null) { From 46e301b2dbc5bc9aaa6e8850961ee5fad1f08093 Mon Sep 17 00:00:00 2001 From: desoliture Date: Wed, 5 Jan 2022 18:14:37 +0200 Subject: [PATCH 04/86] Refactoring for alarm rule schedule add getDynamicValue method to AlarmSchedule interface, refactor main isActive processing methods for work with schedules and dynamic values --- .../data/device/profile/AlarmSchedule.java | 3 ++ .../data/device/profile/AnyTimeSchedule.java | 7 +++ .../device/profile/SpecificTimeSchedule.java | 1 - .../rule/engine/profile/AlarmRuleState.java | 47 ++++++++----------- .../rule/engine/profile/ProfileState.java | 15 +----- 5 files changed, 31 insertions(+), 42 deletions(-) diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmSchedule.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmSchedule.java index 1d5eceb1aa..1fc39ef147 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmSchedule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AlarmSchedule.java @@ -18,6 +18,7 @@ package org.thingsboard.server.common.data.device.profile; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; +import org.thingsboard.server.common.data.query.DynamicValue; import java.io.Serializable; @@ -34,4 +35,6 @@ public interface AlarmSchedule extends Serializable { AlarmScheduleType getType(); + DynamicValue getDynamicValue(); + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AnyTimeSchedule.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AnyTimeSchedule.java index e02086902f..94eea60950 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AnyTimeSchedule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/AnyTimeSchedule.java @@ -15,6 +15,8 @@ */ package org.thingsboard.server.common.data.device.profile; +import org.thingsboard.server.common.data.query.DynamicValue; + public class AnyTimeSchedule implements AlarmSchedule { @Override @@ -22,4 +24,9 @@ public class AnyTimeSchedule implements AlarmSchedule { return AlarmScheduleType.ANY_TIME; } + @Override + public DynamicValue getDynamicValue() { + return null; + } + } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java index 57e57a1b24..0b8dfde791 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/device/profile/SpecificTimeSchedule.java @@ -18,7 +18,6 @@ package org.thingsboard.server.common.data.device.profile; import lombok.Data; import org.thingsboard.server.common.data.query.DynamicValue; -import java.util.List; import java.util.Set; @Data diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java index c5ad4607b2..abcc414206 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.device.profile.AlarmConditionSpec; import org.thingsboard.server.common.data.device.profile.AlarmConditionSpecType; import org.thingsboard.server.common.data.device.profile.AlarmRule; import org.thingsboard.server.common.data.device.profile.CustomTimeSchedule; +import org.thingsboard.server.common.data.device.profile.AlarmSchedule; import org.thingsboard.server.common.data.device.profile.CustomTimeScheduleItem; import org.thingsboard.server.common.data.device.profile.DurationAlarmConditionSpec; import org.thingsboard.server.common.data.device.profile.RepeatingAlarmConditionSpec; @@ -139,35 +140,27 @@ class AlarmRuleState { switch (alarmRule.getSchedule().getType()) { case ANY_TIME: return true; - case SPECIFIC_TIME: { - SpecificTimeSchedule defaultSchedule = (SpecificTimeSchedule) alarmRule.getSchedule(); - EntityKeyValue dynamicValue = getDynamicValue(data, defaultSchedule.getDynamicValue()); - - SpecificTimeSchedule schedule; - try { - schedule = JsonConverter.parse(dynamicValue.getJsonValue(), SpecificTimeSchedule.class); - } catch (Exception e) { - schedule = defaultSchedule; - } - - return isActiveSpecific(schedule, eventTs); - } - case CUSTOM: { - CustomTimeSchedule defaultSchedule = (CustomTimeSchedule) alarmRule.getSchedule(); - EntityKeyValue dynamicValue = getDynamicValue(data, defaultSchedule.getDynamicValue()); + case SPECIFIC_TIME: + return isActiveSpecific((SpecificTimeSchedule) getSchedule(data, alarmRule), eventTs); + case CUSTOM: + return isActiveCustom((CustomTimeSchedule) getSchedule(data, alarmRule), eventTs); + default: + throw new RuntimeException("Unsupported schedule type: " + alarmRule.getSchedule().getType()); + } + } - CustomTimeSchedule schedule; - try { - schedule = JsonConverter.parse(dynamicValue.getJsonValue(), CustomTimeSchedule.class); - } catch (Exception e) { - schedule = defaultSchedule; - } + private AlarmSchedule getSchedule(DataSnapshot data, AlarmRule alarmRule) { + AlarmSchedule schedule = alarmRule.getSchedule(); + EntityKeyValue dynamicValue = getDynamicValue(data, schedule.getDynamicValue()); - return isActiveCustom(schedule, eventTs); + if (dynamicValue != null) { + try { + return JsonConverter.parse(dynamicValue.getJsonValue(), alarmRule.getSchedule().getClass()); + } catch (Exception e) { + log.trace("Failed to parse AlarmSchedule from dynamicValue: {}", dynamicValue.getJsonValue(), e); } - default: - throw new RuntimeException("Unsupported schedule type: " + alarmRule.getSchedule().getType()); } + return schedule; } private boolean isActiveSpecific(SpecificTimeSchedule schedule, long eventTs) { @@ -252,7 +245,7 @@ class AlarmRuleState { long repeatingTimes = 0; AlarmConditionSpec alarmConditionSpec = getSpec(); AlarmConditionSpecType specType = alarmConditionSpec.getType(); - if(specType.equals(AlarmConditionSpecType.REPEATING)) { + if (specType.equals(AlarmConditionSpecType.REPEATING)) { RepeatingAlarmConditionSpec repeating = (RepeatingAlarmConditionSpec) spec; repeatingTimes = repeating.getPredicate().getDefaultValue(); @@ -272,7 +265,7 @@ class AlarmRuleState { long durationTimeInMs = 0; AlarmConditionSpec alarmConditionSpec = getSpec(); AlarmConditionSpecType specType = alarmConditionSpec.getType(); - if(specType.equals(AlarmConditionSpecType.DURATION)) { + if (specType.equals(AlarmConditionSpecType.DURATION)) { DurationAlarmConditionSpec duration = (DurationAlarmConditionSpec) spec; TimeUnit timeUnit = duration.getUnit(); diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java index c8751d65f7..dcfcea98ba 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/ProfileState.java @@ -27,8 +27,6 @@ import org.thingsboard.server.common.data.device.profile.AlarmRule; import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; import org.thingsboard.server.common.data.device.profile.DurationAlarmConditionSpec; import org.thingsboard.server.common.data.device.profile.RepeatingAlarmConditionSpec; -import org.thingsboard.server.common.data.device.profile.CustomTimeSchedule; -import org.thingsboard.server.common.data.device.profile.SpecificTimeSchedule; import org.thingsboard.server.common.data.device.profile.AlarmSchedule; import org.thingsboard.server.common.data.id.DeviceProfileId; import org.thingsboard.server.common.data.query.ComplexFilterPredicate; @@ -99,18 +97,7 @@ class ProfileState { } private void addScheduleDynamicValues(AlarmSchedule schedule) { - DynamicValue dynamicValue = null; - switch (schedule.getType()) { - case SPECIFIC_TIME: - SpecificTimeSchedule specificTimeSchedule = (SpecificTimeSchedule) schedule; - dynamicValue = specificTimeSchedule.getDynamicValue(); - break; - case CUSTOM: - CustomTimeSchedule customTimeSchedule = (CustomTimeSchedule) schedule; - dynamicValue = customTimeSchedule.getDynamicValue(); - break; - } - + DynamicValue dynamicValue = schedule.getDynamicValue(); if (dynamicValue != null) { entityKeys.add( new AlarmConditionFilterKey(AlarmConditionKeyType.ATTRIBUTE, From 03256deee78c9b30d2b13a646c5c53db9a03bfbc Mon Sep 17 00:00:00 2001 From: desoliture Date: Thu, 6 Jan 2022 14:05:12 +0200 Subject: [PATCH 05/86] add corresponding tests for schedule from dynamic values --- .../profile/TbDeviceProfileNodeTest.java | 179 ++++++++++++++++++ 1 file changed, 179 insertions(+) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java index b2c79102c4..63dc9a81d2 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java @@ -44,6 +44,8 @@ import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.device.profile.DurationAlarmConditionSpec; import org.thingsboard.server.common.data.device.profile.RepeatingAlarmConditionSpec; +import org.thingsboard.server.common.data.device.profile.CustomTimeSchedule; +import org.thingsboard.server.common.data.device.profile.CustomTimeScheduleItem; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -71,6 +73,7 @@ import java.math.RoundingMode; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.ArrayList; import java.util.Optional; import java.util.TreeMap; import java.util.UUID; @@ -1086,6 +1089,182 @@ public class TbDeviceProfileNodeTest { verify(ctx, Mockito.never()).tellFailure(Mockito.any(), Mockito.any()); } + @Test + public void testActiveAlarmScheduleFromDynamicValuesWhenDefaultScheduleIsInactive() throws Exception { + init(); + + DeviceProfile deviceProfile = new DeviceProfile(); + deviceProfile.setId(deviceProfileId); + DeviceProfileData deviceProfileData = new DeviceProfileData(); + + Device device = new Device(); + device.setId(deviceId); + device.setCustomerId(customerId); + + AttributeKvCompositeKey compositeKeyActiveSchedule = new AttributeKvCompositeKey( + EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "dynamicValueActiveSchedule" + ); + + AttributeKvEntity attributeKvEntityActiveSchedule = new AttributeKvEntity(); + attributeKvEntityActiveSchedule.setId(compositeKeyActiveSchedule); + attributeKvEntityActiveSchedule.setJsonValue( + "{\"timezone\":\"Europe/Kiev\",\"items\":[{\"enabled\":true,\"dayOfWeek\":1,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":2,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":3,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":4,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":5,\"startsOn\":0,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":6,\"startsOn\":8.64e+7,\"endsOn\":8.64e+7},{\"enabled\":true,\"dayOfWeek\":7,\"startsOn\":0,\"endsOn\":8.64e+7}],\"dynamicValue\":null}" + ); + attributeKvEntityActiveSchedule.setLastUpdateTs(0L); + + AttributeKvEntry entryActiveSchedule = attributeKvEntityActiveSchedule.toData(); + + ListenableFuture> listListenableFutureActiveSchedule = + Futures.immediateFuture(Collections.singletonList(entryActiveSchedule)); + + AlarmConditionFilter highTempFilter = new AlarmConditionFilter(); + highTempFilter.setKey(new AlarmConditionFilterKey(AlarmConditionKeyType.TIME_SERIES, "temperature")); + highTempFilter.setValueType(EntityKeyValueType.NUMERIC); + NumericFilterPredicate highTemperaturePredicate = new NumericFilterPredicate(); + highTemperaturePredicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER); + highTemperaturePredicate.setValue(new FilterPredicateValue<>( + 0.0, + null, + null + )); + highTempFilter.setPredicate(highTemperaturePredicate); + AlarmCondition alarmCondition = new AlarmCondition(); + alarmCondition.setCondition(Collections.singletonList(highTempFilter)); + + CustomTimeSchedule schedule = new CustomTimeSchedule(); + schedule.setItems(Collections.emptyList()); + schedule.setDynamicValue(new DynamicValue<>(DynamicValueSourceType.CURRENT_DEVICE, "dynamicValueActiveSchedule", false)); + + AlarmRule alarmRule = new AlarmRule(); + alarmRule.setCondition(alarmCondition); + alarmRule.setSchedule(schedule); + DeviceProfileAlarm deviceProfileAlarmActiveSchedule = new DeviceProfileAlarm(); + deviceProfileAlarmActiveSchedule.setId("highTemperatureAlarmID"); + deviceProfileAlarmActiveSchedule.setAlarmType("highTemperatureAlarm"); + deviceProfileAlarmActiveSchedule.setCreateRules(new TreeMap<>(Collections.singletonMap(AlarmSeverity.CRITICAL, alarmRule))); + + deviceProfileData.setAlarms(Collections.singletonList(deviceProfileAlarmActiveSchedule)); + deviceProfile.setProfileData(deviceProfileData); + + Mockito.when(cache.get(tenantId, deviceId)).thenReturn(deviceProfile); + Mockito.when(timeseriesService.findLatest(tenantId, deviceId, Collections.singleton("temperature"))) + .thenReturn(Futures.immediateFuture(Collections.emptyList())); + Mockito.when(alarmService.findLatestByOriginatorAndType(tenantId, deviceId, "highTemperatureAlarm")) + .thenReturn(Futures.immediateFuture(null)); + Mockito.when(alarmService.createOrUpdateAlarm(Mockito.any())).thenAnswer(AdditionalAnswers.returnsFirstArg()); + Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + .thenReturn(listListenableFutureActiveSchedule); + + TbMsg theMsg = TbMsg.newMsg("ALARM", deviceId, new TbMsgMetaData(), ""); + Mockito.when(ctx.newMsg(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyString())) + .thenReturn(theMsg); + + ObjectNode data = mapper.createObjectNode(); + data.put("temperature", 35); + TbMsg msg = TbMsg.newMsg(SessionMsgType.POST_TELEMETRY_REQUEST.name(), deviceId, new TbMsgMetaData(), + TbMsgDataType.JSON, mapper.writeValueAsString(data), null, null); + + node.onMsg(ctx, msg); + verify(ctx).tellSuccess(msg); + verify(ctx).enqueueForTellNext(theMsg, "Alarm Created"); + verify(ctx, Mockito.never()).tellFailure(Mockito.any(), Mockito.any()); + } + + @Test + public void testInactiveAlarmScheduleFromDynamicValuesWhenDefaultScheduleIsActive() throws Exception { + init(); + + DeviceProfile deviceProfile = new DeviceProfile(); + deviceProfile.setId(deviceProfileId); + DeviceProfileData deviceProfileData = new DeviceProfileData(); + + Device device = new Device(); + device.setId(deviceId); + device.setCustomerId(customerId); + + AttributeKvCompositeKey compositeKeyInactiveSchedule = new AttributeKvCompositeKey( + EntityType.TENANT, deviceId.getId(), "SERVER_SCOPE", "dynamicValueInactiveSchedule" + ); + + AttributeKvEntity attributeKvEntityInactiveSchedule = new AttributeKvEntity(); + attributeKvEntityInactiveSchedule.setId(compositeKeyInactiveSchedule); + attributeKvEntityInactiveSchedule.setJsonValue( + "{\"timezone\":\"Europe/Kiev\",\"items\":[{\"enabled\":false,\"dayOfWeek\":1,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":2,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":3,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":4,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":5,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":6,\"startsOn\":0,\"endsOn\":0},{\"enabled\":false,\"dayOfWeek\":7,\"startsOn\":0,\"endsOn\":0}],\"dynamicValue\":null}" + ); + + attributeKvEntityInactiveSchedule.setLastUpdateTs(0L); + + AttributeKvEntry entryInactiveSchedule = attributeKvEntityInactiveSchedule.toData(); + + ListenableFuture> listListenableFutureInactiveSchedule = + Futures.immediateFuture(Collections.singletonList(entryInactiveSchedule)); + + AlarmConditionFilter highTempFilter = new AlarmConditionFilter(); + highTempFilter.setKey(new AlarmConditionFilterKey(AlarmConditionKeyType.TIME_SERIES, "temperature")); + highTempFilter.setValueType(EntityKeyValueType.NUMERIC); + NumericFilterPredicate highTemperaturePredicate = new NumericFilterPredicate(); + highTemperaturePredicate.setOperation(NumericFilterPredicate.NumericOperation.GREATER); + highTemperaturePredicate.setValue(new FilterPredicateValue<>( + 0.0, + null, + null + )); + + highTempFilter.setPredicate(highTemperaturePredicate); + AlarmCondition alarmCondition = new AlarmCondition(); + alarmCondition.setCondition(Collections.singletonList(highTempFilter)); + + CustomTimeSchedule schedule = new CustomTimeSchedule(); + + List items = new ArrayList<>(); + for (int i = 0; i < 7; i++) { + CustomTimeScheduleItem item = new CustomTimeScheduleItem(); + item.setEnabled(true); + item.setDayOfWeek(i + 1); + item.setEndsOn(0); + item.setStartsOn(0); + items.add(item); + } + + schedule.setItems(items); + schedule.setDynamicValue(new DynamicValue<>(DynamicValueSourceType.CURRENT_DEVICE, "dynamicValueInactiveSchedule", false)); + + AlarmRule alarmRule = new AlarmRule(); + alarmRule.setCondition(alarmCondition); + alarmRule.setSchedule(schedule); + DeviceProfileAlarm deviceProfileAlarmNonactiveSchedule = new DeviceProfileAlarm(); + deviceProfileAlarmNonactiveSchedule.setId("highTemperatureAlarmID"); + deviceProfileAlarmNonactiveSchedule.setAlarmType("highTemperatureAlarm"); + deviceProfileAlarmNonactiveSchedule.setCreateRules(new TreeMap<>(Collections.singletonMap(AlarmSeverity.CRITICAL, alarmRule))); + + deviceProfileData.setAlarms(Collections.singletonList(deviceProfileAlarmNonactiveSchedule)); + deviceProfile.setProfileData(deviceProfileData); + + Mockito.when(cache.get(tenantId, deviceId)).thenReturn(deviceProfile); + Mockito.when(timeseriesService.findLatest(tenantId, deviceId, Collections.singleton("temperature"))) + .thenReturn(Futures.immediateFuture(Collections.emptyList())); + Mockito.when(alarmService.findLatestByOriginatorAndType(tenantId, deviceId, "highTemperatureAlarm")) + .thenReturn(Futures.immediateFuture(null)); + Mockito.when(alarmService.createOrUpdateAlarm(Mockito.any())).thenAnswer(AdditionalAnswers.returnsFirstArg()); + Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); + Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) + .thenReturn(listListenableFutureInactiveSchedule); + + TbMsg theMsg = TbMsg.newMsg("ALARM", deviceId, new TbMsgMetaData(), ""); + Mockito.when(ctx.newMsg(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyString())) + .thenReturn(theMsg); + + ObjectNode data = mapper.createObjectNode(); + data.put("temperature", 35); + TbMsg msg = TbMsg.newMsg(SessionMsgType.POST_TELEMETRY_REQUEST.name(), deviceId, new TbMsgMetaData(), + TbMsgDataType.JSON, mapper.writeValueAsString(data), null, null); + + node.onMsg(ctx, msg); + verify(ctx).tellSuccess(msg); + verify(ctx, Mockito.never()).enqueueForTellNext(theMsg, "Alarm Created"); + verify(ctx, Mockito.never()).tellFailure(Mockito.any(), Mockito.any()); + } @Test public void testCurrentCustomersAttributeForDynamicValue() throws Exception { From 8f485010f0b0a4328c29cb23f57c37c1a705e3ee Mon Sep 17 00:00:00 2001 From: desoliture Date: Thu, 6 Jan 2022 16:14:46 +0200 Subject: [PATCH 06/86] refactoring --- .../rule/engine/profile/TbDeviceProfileNodeTest.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java index 63dc9a81d2..30e2943110 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java @@ -1246,14 +1246,11 @@ public class TbDeviceProfileNodeTest { .thenReturn(Futures.immediateFuture(Collections.emptyList())); Mockito.when(alarmService.findLatestByOriginatorAndType(tenantId, deviceId, "highTemperatureAlarm")) .thenReturn(Futures.immediateFuture(null)); - Mockito.when(alarmService.createOrUpdateAlarm(Mockito.any())).thenAnswer(AdditionalAnswers.returnsFirstArg()); Mockito.when(ctx.getAttributesService()).thenReturn(attributesService); Mockito.when(attributesService.find(eq(tenantId), eq(deviceId), Mockito.anyString(), Mockito.anySet())) .thenReturn(listListenableFutureInactiveSchedule); TbMsg theMsg = TbMsg.newMsg("ALARM", deviceId, new TbMsgMetaData(), ""); - Mockito.when(ctx.newMsg(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyString())) - .thenReturn(theMsg); ObjectNode data = mapper.createObjectNode(); data.put("temperature", 35); From 6875df9dab6750d2ba0fe2b55c844e639fbfc343 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Mon, 10 Jan 2022 16:49:15 +0200 Subject: [PATCH 07/86] Added Dynamic value to alarm schedule --- .../alarm/alarm-schedule.component.html | 40 ++++++++++++++++++- .../profile/alarm/alarm-schedule.component.ts | 28 +++++++++++-- ui-ngx/src/app/shared/models/device.models.ts | 4 ++ .../assets/locale/locale.constant-en_US.json | 1 + 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html index bf09b33d76..5d63b48f15 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html @@ -73,8 +73,44 @@
-
device-profile.schedule-days
- + + +
+ +
+ {{'filter.dynamic-value' | translate}} +
+
+ +
+
+ +
+
+
+ + + + + {{'filter.no-dynamic-value' | translate}} + + + {{dynamicValueSourceTypeTranslations.get(sourceType) | translate}} + + + +
+
+ + + + +
+
+
+
+
+
device-profile.schedule-days
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts index d5c9f02876..6fd679f3f7 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts @@ -40,6 +40,12 @@ import { import { isDefined, isDefinedAndNotNull } from '@core/utils'; import { MatCheckboxChange } from '@angular/material/checkbox'; import { getDefaultTimezone } from '@shared/models/time/time.models'; +import { + DynamicValueSourceType, + dynamicValueSourceTypeTranslationMap, + getDynamicSourcesForAllowUser +} from '@shared/models/query/query.models'; +import { emit } from 'cluster'; @Component({ selector: 'tb-alarm-schedule', @@ -64,7 +70,8 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator, alarmScheduleTypes = Object.keys(AlarmScheduleType); alarmScheduleType = AlarmScheduleType; alarmScheduleTypeTranslate = AlarmScheduleTypeTranslationMap; - + dynamicValueSourceTypes: DynamicValueSourceType[] = getDynamicSourcesForAllowUser(false); + dynamicValueSourceTypeTranslations = dynamicValueSourceTypeTranslationMap; dayOfWeekTranslationsArray = dayOfWeekTranslations; allDays = Array(7).fill(0).map((x, i) => i); @@ -91,8 +98,19 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator, daysOfWeek: this.fb.array(new Array(7).fill(false), this.validateDayOfWeeks), startsOn: [0, Validators.required], endsOn: [0, Validators.required], - items: this.fb.array(Array.from({length: 7}, (value, i) => this.defaultItemsScheduler(i)), this.validateItems) + items: this.fb.array(Array.from({length: 7}, (value, i) => this.defaultItemsScheduler(i)), this.validateItems), + dynamicValue: this.fb.group({ + sourceType: [null], + sourceAttribute: [null] + }) }); + + this.alarmScheduleForm.get('dynamicValue.sourceType').valueChanges.subscribe((sourceType) => { + if (!sourceType) { + this.alarmScheduleForm.get('dynamicValue.sourceAttribute').patchValue('', {emitEvent:false}); + } + }) + this.alarmScheduleForm.get('type').valueChanges.subscribe((type) => { const defaultTimezone = getDefaultTimezone(); this.alarmScheduleForm.reset({type, items: this.defaultItems, timezone: defaultTimezone}, {emitEvent: false}); @@ -177,7 +195,11 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator, this.alarmScheduleForm.patchValue({ type: this.modelValue.type, timezone: this.modelValue.timezone, - items: alarmDays + items: alarmDays, + dynamicValue: { + sourceAttribute: this.modelValue.dynamicValue.sourceAttribute, + sourceType: this.modelValue.dynamicValue.sourceType + } }, {emitEvent: false}); } break; diff --git a/ui-ngx/src/app/shared/models/device.models.ts b/ui-ngx/src/app/shared/models/device.models.ts index 7fc3d70f78..ffb944803c 100644 --- a/ui-ngx/src/app/shared/models/device.models.ts +++ b/ui-ngx/src/app/shared/models/device.models.ts @@ -477,6 +477,10 @@ export const AlarmScheduleTypeTranslationMap = new Map Date: Tue, 11 Jan 2022 14:38:07 +0200 Subject: [PATCH 08/86] Updated dynamic value logic --- .../home/components/home-components.module.ts | 4 +- .../alarm/alarm-dynamic-value.component.html | 37 ++++++++++ .../alarm/alarm-dynamic-value.component.ts | 68 +++++++++++++++++++ .../alarm/alarm-schedule.component.html | 41 +---------- .../profile/alarm/alarm-schedule.component.ts | 27 ++------ 5 files changed, 115 insertions(+), 62 deletions(-) create mode 100644 ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html create mode 100644 ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts diff --git a/ui-ngx/src/app/modules/home/components/home-components.module.ts b/ui-ngx/src/app/modules/home/components/home-components.module.ts index 73361eddce..6614edebe8 100644 --- a/ui-ngx/src/app/modules/home/components/home-components.module.ts +++ b/ui-ngx/src/app/modules/home/components/home-components.module.ts @@ -147,6 +147,7 @@ import { HOME_COMPONENTS_MODULE_TOKEN } from '@home/components/tokens'; import { DashboardStateComponent } from '@home/components/dashboard-page/dashboard-state.component'; +import { AlarmDynamicValue } from '@home/components/profile/alarm/alarm-dynamic-value.component'; @NgModule({ declarations: @@ -245,6 +246,7 @@ import { DashboardStateComponent } from '@home/components/dashboard-page/dashboa AlarmScheduleInfoComponent, DeviceProfileProvisionConfigurationComponent, AlarmScheduleComponent, + AlarmDynamicValue, AlarmDurationPredicateValueComponent, DeviceWizardDialogComponent, AlarmScheduleDialogComponent, @@ -356,11 +358,11 @@ import { DashboardStateComponent } from '@home/components/dashboard-page/dashboa DeviceWizardDialogComponent, AlarmScheduleInfoComponent, AlarmScheduleComponent, + AlarmDynamicValue, AlarmScheduleDialogComponent, AlarmDurationPredicateValueComponent, EditAlarmDetailsDialogComponent, DeviceProfileProvisionConfigurationComponent, - AlarmScheduleComponent, SmsProviderConfigurationComponent, AwsSnsProviderConfigurationComponent, TwilioSmsProviderConfigurationComponent, diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html new file mode 100644 index 0000000000..6b2852cd68 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html @@ -0,0 +1,37 @@ + + +
+ +
+ {{'filter.dynamic-value' | translate}} +
+
+ +
+
+ +
+
+
+ + + + + {{'filter.no-dynamic-value' | translate}} + + + {{dynamicValueSourceTypeTranslations.get(sourceType) | translate}} + + + +
+
+ + + + +
+
+
+
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts new file mode 100644 index 0000000000..cb4efc1480 --- /dev/null +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts @@ -0,0 +1,68 @@ +import { Component, forwardRef, OnInit } from '@angular/core'; +import { + ControlValueAccessor, + FormBuilder, + FormGroup, + NG_VALUE_ACCESSOR, +} from '@angular/forms'; +import { + DynamicValueSourceType, + dynamicValueSourceTypeTranslationMap, + getDynamicSourcesForAllowUser +} from '@shared/models/query/query.models'; + +@Component({ + selector: 'tb-alarm-dynamic-value', + templateUrl: './alarm-dynamic-value.component.html', + providers: [{ + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => AlarmDynamicValue), + multi: true + }] +}) + +export class AlarmDynamicValue implements ControlValueAccessor, OnInit{ + public dynamicValue: FormGroup; + public dynamicValueSourceTypes: DynamicValueSourceType[] = getDynamicSourcesForAllowUser(false); + public dynamicValueSourceTypeTranslations = dynamicValueSourceTypeTranslationMap; + private propagateChange = (v: any) => { }; + + constructor(private fb: FormBuilder) { + } + + ngOnInit(): void { + this.dynamicValue = this.fb.group({ + sourceType: [null], + sourceAttribute: [null] + }) + + this.dynamicValue.get('sourceType').valueChanges.subscribe( + (sourceType) => { + if (!sourceType) { + this.dynamicValue.get('sourceAttribute').patchValue(null, {emitEvent: false}); + } + } + ); + + this.dynamicValue.valueChanges.subscribe(() => { + this.updateModel(); + }) + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + writeValue(dynamicValue: {sourceType: string, sourceAttribute: string}): void { + if(dynamicValue) { + this.dynamicValue.patchValue(dynamicValue, {emitEvent: false}); + } + } + + private updateModel() { + this.propagateChange(this.dynamicValue.value); + } +} diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html index 5d63b48f15..67a3ac69c0 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html @@ -34,6 +34,7 @@ formControlName="timezone">
+
device-profile.schedule-days
@@ -73,44 +74,8 @@
- - -
- -
- {{'filter.dynamic-value' | translate}} -
-
- -
-
- -
-
-
- - - - - {{'filter.no-dynamic-value' | translate}} - - - {{dynamicValueSourceTypeTranslations.get(sourceType) | translate}} - - - -
-
- - - - -
-
-
-
-
-
device-profile.schedule-days
+ +
device-profile.schedule-days
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts index 6fd679f3f7..2deef61a6d 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.ts @@ -40,12 +40,6 @@ import { import { isDefined, isDefinedAndNotNull } from '@core/utils'; import { MatCheckboxChange } from '@angular/material/checkbox'; import { getDefaultTimezone } from '@shared/models/time/time.models'; -import { - DynamicValueSourceType, - dynamicValueSourceTypeTranslationMap, - getDynamicSourcesForAllowUser -} from '@shared/models/query/query.models'; -import { emit } from 'cluster'; @Component({ selector: 'tb-alarm-schedule', @@ -70,8 +64,6 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator, alarmScheduleTypes = Object.keys(AlarmScheduleType); alarmScheduleType = AlarmScheduleType; alarmScheduleTypeTranslate = AlarmScheduleTypeTranslationMap; - dynamicValueSourceTypes: DynamicValueSourceType[] = getDynamicSourcesForAllowUser(false); - dynamicValueSourceTypeTranslations = dynamicValueSourceTypeTranslationMap; dayOfWeekTranslationsArray = dayOfWeekTranslations; allDays = Array(7).fill(0).map((x, i) => i); @@ -99,18 +91,9 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator, startsOn: [0, Validators.required], endsOn: [0, Validators.required], items: this.fb.array(Array.from({length: 7}, (value, i) => this.defaultItemsScheduler(i)), this.validateItems), - dynamicValue: this.fb.group({ - sourceType: [null], - sourceAttribute: [null] - }) + dynamicValue: [null] }); - this.alarmScheduleForm.get('dynamicValue.sourceType').valueChanges.subscribe((sourceType) => { - if (!sourceType) { - this.alarmScheduleForm.get('dynamicValue.sourceAttribute').patchValue('', {emitEvent:false}); - } - }) - this.alarmScheduleForm.get('type').valueChanges.subscribe((type) => { const defaultTimezone = getDefaultTimezone(); this.alarmScheduleForm.reset({type, items: this.defaultItems, timezone: defaultTimezone}, {emitEvent: false}); @@ -176,7 +159,8 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator, timezone: this.modelValue.timezone, daysOfWeek, startsOn: utcTimestampToTimeOfDay(this.modelValue.startsOn), - endsOn: utcTimestampToTimeOfDay(this.modelValue.endsOn) + endsOn: utcTimestampToTimeOfDay(this.modelValue.endsOn), + dynamicValue: this.modelValue.dynamicValue }, {emitEvent: false}); break; case AlarmScheduleType.CUSTOM: @@ -196,10 +180,7 @@ export class AlarmScheduleComponent implements ControlValueAccessor, Validator, type: this.modelValue.type, timezone: this.modelValue.timezone, items: alarmDays, - dynamicValue: { - sourceAttribute: this.modelValue.dynamicValue.sourceAttribute, - sourceType: this.modelValue.dynamicValue.sourceType - } + dynamicValue: this.modelValue.dynamicValue }, {emitEvent: false}); } break; From 877257202e9e96925d684e8d448259d0ceada56b Mon Sep 17 00:00:00 2001 From: desoliture Date: Tue, 11 Jan 2022 15:38:20 +0200 Subject: [PATCH 09/86] fix incorrect work if endsOn equals zero when choosing schedule to be all day active (from 00:00 to 00:00) startsOn and endsOn equals zero, in this case make endsOn equals 24hours in millis --- .../thingsboard/rule/engine/profile/AlarmRuleState.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java index abcc414206..f997efdeb3 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java @@ -182,7 +182,12 @@ class AlarmRuleState { for (CustomTimeScheduleItem item : schedule.getItems()) { if (item.getDayOfWeek() == dayOfWeek) { if (item.isEnabled()) { - return isActive(eventTs, zoneId, zdt, item.getStartsOn(), item.getEndsOn()); + long endsOn = item.getEndsOn(); + if (endsOn == 0) { + // 24 hours in milliseconds + endsOn = 86400000; + } + return isActive(eventTs, zoneId, zdt, item.getStartsOn(), endsOn); } else { return false; } From 7328012cb491b16eebb89f1c6c0380861bf94c7f Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Tue, 11 Jan 2022 16:06:08 +0200 Subject: [PATCH 10/86] Added license headers --- .../alarm/alarm-dynamic-value.component.html | 17 +++++++++++++++++ .../alarm/alarm-dynamic-value.component.ts | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html index 6b2852cd68..50b2dee7a7 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html @@ -1,3 +1,20 @@ +
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts index cb4efc1480..ad4b8cc02c 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts @@ -1,3 +1,19 @@ +/// +/// Copyright © 2016-2021 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + import { Component, forwardRef, OnInit } from '@angular/core'; import { ControlValueAccessor, From 6267430dd989afaf3c2a34704456db37199e7c90 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Mon, 24 Jan 2022 11:34:37 +0200 Subject: [PATCH 11/86] Add ui-help --- .../profile/alarm/alarm-dynamic-value.component.html | 1 + .../profile/alarm/alarm-dynamic-value.component.ts | 7 +++++-- .../components/profile/alarm/alarm-schedule.component.html | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html index 50b2dee7a7..99eee091cb 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html @@ -48,6 +48,7 @@
+
diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts index ad4b8cc02c..975331b7b4 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts @@ -14,8 +14,9 @@ /// limitations under the License. /// -import { Component, forwardRef, OnInit } from '@angular/core'; +import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { + AbstractControl, ControlValueAccessor, FormBuilder, FormGroup, @@ -43,12 +44,14 @@ export class AlarmDynamicValue implements ControlValueAccessor, OnInit{ public dynamicValueSourceTypeTranslations = dynamicValueSourceTypeTranslationMap; private propagateChange = (v: any) => { }; + @Input() helpId: string; + constructor(private fb: FormBuilder) { } ngOnInit(): void { this.dynamicValue = this.fb.group({ - sourceType: [null], + sourceType: [null, []], sourceAttribute: [null] }) diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html index 67a3ac69c0..7cb5a3029e 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html @@ -34,7 +34,7 @@ formControlName="timezone">
- +
device-profile.schedule-days
@@ -74,7 +74,7 @@
- +
device-profile.schedule-days
From 5118b21f2662a8c8899ec9ec2d71f433e57805c8 Mon Sep 17 00:00:00 2001 From: Kalutka Zhenya Date: Fri, 28 Jan 2022 17:10:43 +0200 Subject: [PATCH 12/86] Added UI help for dynamic value in alarm schedule --- .../alarm_specific_schedule_format.md | 31 ++++++++ .../alarm_сustom_schedule_format.md | 79 +++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 ui-ngx/src/assets/help/en_US/device-profile/alarm_specific_schedule_format.md create mode 100644 ui-ngx/src/assets/help/en_US/device-profile/alarm_сustom_schedule_format.md diff --git a/ui-ngx/src/assets/help/en_US/device-profile/alarm_specific_schedule_format.md b/ui-ngx/src/assets/help/en_US/device-profile/alarm_specific_schedule_format.md new file mode 100644 index 0000000000..cbf6b3a3ea --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/device-profile/alarm_specific_schedule_format.md @@ -0,0 +1,31 @@ +#### Specific schedule format + +An attribute with a dynamic value for a specific schedule format must have JSON in the following format: + +```javascript +{ + "daysOfWeek": [ + 2, + 4 + ], + "endsOn": 0, + "startsOn": 0, + "timezone": "Europe/Kiev" +} +``` + +
    +
  • +timezone: this value is used to designate the timezone you are using. +
  • +
  • +daysOfWeek: this value is used to designate the days in numerical representation (Monday - 1, Tuesday 2, etc.) on which the schedule will be active. +
  • +
  • +startsOn: this value is used to designate the timestamp in milliseconds, from which the schedule will be active for the designated days. +
  • +
  • +endsOn: this value is used to designate the timestamp in milliseconds until which the schedule will be active for the specified days. +
  • +
+When startsOn and endsOn equals 0 it's means that the schedule will be active the whole day. diff --git a/ui-ngx/src/assets/help/en_US/device-profile/alarm_сustom_schedule_format.md b/ui-ngx/src/assets/help/en_US/device-profile/alarm_сustom_schedule_format.md new file mode 100644 index 0000000000..7090ae68e1 --- /dev/null +++ b/ui-ngx/src/assets/help/en_US/device-profile/alarm_сustom_schedule_format.md @@ -0,0 +1,79 @@ +#### Custom schedule format + +An attribute with a dynamic value for a custom schedule format must have JSON in the following format: + +```javascript +{ + "timezone": "Europe/Kiev", + "items": [ + { + "dayOfWeek": 1, + "enabled": true, + "endsOn": 0, + "startsOn": 0 + }, + { + "dayOfWeek": 2, + "enabled": true, + "endsOn": 0, + "startsOn": 0 + }, + { + "dayOfWeek": 3, + "enabled": true, + "endsOn": 0, + "startsOn": 0 + }, + { + "dayOfWeek": 4, + "enabled": true, + "endsOn": 0, + "startsOn": 0 + }, + { + "dayOfWeek": 5, + "enabled": true, + "endsOn": 0, + "startsOn": 0 + }, + { + "dayOfWeek": 6, + "enabled": true, + "endsOn": 0, + "startsOn": 0 + }, + { + "dayOfWeek": 7, + "enabled": true, + "endsOn": 0, + "startsOn": 0 + } + ] +} +``` + +
    +
  • +timezone: this value is used to designate the timezone you are using. +
  • +
  • +items: the array of values representing the days on which the schedule will be active. +
  • +
+ +One array item contains such fields: +
    +
  • +dayOfWeek: this value is used to designate the specified day in numerical representation (Monday - 1, Tuesday 2, etc.) on which the schedule will be active. +
  • +
  • +enabled: this boolean value, used to designate that the specified day in the schedule will be enabled. +
  • +
  • +startsOn: this value is used to designate the timestamp in milliseconds, from which the schedule will be active for the designated day. +
  • +
  • +endsOn: this value is used to designate the timestamp in milliseconds until which the schedule will be active for the specified day. +
  • +
+When startsOn and endsOn equals 0 it's means that the schedule will be active the whole day. From 6969882a699d3b61e0d91102b8965aed943bcbff Mon Sep 17 00:00:00 2001 From: Alexey Markevich Date: Fri, 28 Jan 2022 23:54:10 +0300 Subject: [PATCH 13/86] switch to PostgreSQL10Dialect --- application/src/main/resources/thingsboard.yml | 2 +- .../main/java/org/thingsboard/server/dao/util/PsqlDao.java | 2 +- .../org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java | 2 +- dao/src/test/resources/nosql-test.properties | 2 +- dao/src/test/resources/sql-test.properties | 4 ++-- docker/tb-node.hybrid.env | 2 +- docker/tb-node.postgres.env | 2 +- msa/tb/docker-cassandra/Dockerfile | 2 +- msa/tb/docker-postgres/Dockerfile | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 51494484db..d9fa8ef323 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -518,7 +518,7 @@ spring: open-in-view: "false" hibernate: ddl-auto: "none" - database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.PostgreSQLDialect}" + database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.PostgreSQL10Dialect}" datasource: driverClassName: "${SPRING_DRIVER_CLASS_NAME:org.postgresql.Driver}" url: "${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/thingsboard}" diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlDao.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlDao.java index 81855d99cf..ba30f8975a 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlDao.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlDao.java @@ -21,6 +21,6 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) -@ConditionalOnProperty(prefix = "spring.jpa", value = "database-platform", havingValue = "org.hibernate.dialect.PostgreSQLDialect") +@ConditionalOnProperty(prefix = "spring.jpa", value = "database-platform", havingValue = "org.hibernate.dialect.PostgreSQL10Dialect") public @interface PsqlDao { } \ No newline at end of file diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java index ea44bd52e1..368f550c14 100644 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java +++ b/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java @@ -22,6 +22,6 @@ import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) @ConditionalOnExpression("('${database.ts_latest.type}'=='sql' || '${database.ts_latest.type}'=='timescale') " + - "&& '${spring.jpa.database-platform}'=='org.hibernate.dialect.PostgreSQLDialect'") + "&& '${spring.jpa.database-platform}'=='org.hibernate.dialect.PostgreSQL10Dialect'") public @interface PsqlTsLatestAnyDao { } diff --git a/dao/src/test/resources/nosql-test.properties b/dao/src/test/resources/nosql-test.properties index b81f5db8ac..24fa1b426f 100644 --- a/dao/src/test/resources/nosql-test.properties +++ b/dao/src/test/resources/nosql-test.properties @@ -11,7 +11,7 @@ spring.jpa.properties.hibernate.jdbc.log.warnings=false spring.jpa.show-sql=false spring.jpa.hibernate.ddl-auto=none -spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect spring.datasource.username=postgres spring.datasource.password=postgres spring.datasource.url=jdbc:tc:postgresql:12.8:///thingsboard?TC_DAEMON=true&TC_TMPFS=/testtmpfs:rw&?TC_INITFUNCTION=org.thingsboard.server.dao.PostgreSqlInitializer::initDb diff --git a/dao/src/test/resources/sql-test.properties b/dao/src/test/resources/sql-test.properties index d2add71eea..b85fb7abc1 100644 --- a/dao/src/test/resources/sql-test.properties +++ b/dao/src/test/resources/sql-test.properties @@ -12,7 +12,7 @@ spring.jpa.properties.hibernate.jdbc.log.warnings=false spring.jpa.show-sql=false spring.jpa.hibernate.ddl-auto=none -spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect spring.datasource.username=postgres spring.datasource.password=postgres spring.datasource.url=jdbc:tc:postgresql:12.8:///thingsboard?TC_DAEMON=true&TC_TMPFS=/testtmpfs:rw&?TC_INITFUNCTION=org.thingsboard.server.dao.PostgreSqlInitializer::initDb @@ -32,7 +32,7 @@ service.type=monolith #spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true #spring.jpa.show-sql=false #spring.jpa.hibernate.ddl-auto=none -#spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect +#spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect # #spring.datasource.username=postgres #spring.datasource.password=postgres diff --git a/docker/tb-node.hybrid.env b/docker/tb-node.hybrid.env index 2f5dcee2e3..5f72c6e1a1 100644 --- a/docker/tb-node.hybrid.env +++ b/docker/tb-node.hybrid.env @@ -2,7 +2,7 @@ DATABASE_TS_TYPE=cassandra CASSANDRA_URL=cassandra:9042 -SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQLDialect +SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQL10Dialect SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/thingsboard SPRING_DATASOURCE_USERNAME=postgres diff --git a/docker/tb-node.postgres.env b/docker/tb-node.postgres.env index 63e8d11889..f4e11cd70a 100644 --- a/docker/tb-node.postgres.env +++ b/docker/tb-node.postgres.env @@ -1,7 +1,7 @@ # ThingsBoard server configuration for PostgreSQL database DATABASE_TS_TYPE=sql -SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQLDialect +SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQL10Dialect SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/thingsboard SPRING_DATASOURCE_USERNAME=postgres diff --git a/msa/tb/docker-cassandra/Dockerfile b/msa/tb/docker-cassandra/Dockerfile index 42dfebee45..144c359cc0 100644 --- a/msa/tb/docker-cassandra/Dockerfile +++ b/msa/tb/docker-cassandra/Dockerfile @@ -54,7 +54,7 @@ ENV DATABASE_TS_TYPE=cassandra ENV PGDATA=/data/db ENV CASSANDRA_DATA=/data/cassandra -ENV SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQLDialect +ENV SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQL10Dialect ENV SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver ENV SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/thingsboard ENV SPRING_DATASOURCE_USERNAME=${pkg.user} diff --git a/msa/tb/docker-postgres/Dockerfile b/msa/tb/docker-postgres/Dockerfile index 47e1a0dec6..6b6dbc0011 100644 --- a/msa/tb/docker-postgres/Dockerfile +++ b/msa/tb/docker-postgres/Dockerfile @@ -50,7 +50,7 @@ ENV DATABASE_TS_TYPE=sql ENV PGDATA=/data/db ENV PATH=$PATH:/usr/lib/postgresql/$PG_MAJOR/bin -ENV SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQLDialect +ENV SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQL10Dialect ENV SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver ENV SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/thingsboard ENV SPRING_DATASOURCE_USERNAME=${pkg.user} From 15f28755549babb68bdfe341884b3680730a4677 Mon Sep 17 00:00:00 2001 From: "pinkevycdima@gmail.com" Date: Mon, 31 Jan 2022 14:57:56 +0200 Subject: [PATCH 14/86] UI: add copyDashboardId button in details-panel --- .../pages/dashboard/dashboard-form.component.html | 10 ++++++++++ .../home/pages/dashboard/dashboard-form.component.ts | 11 +++++++++++ ui-ngx/src/assets/locale/locale.constant-en_US.json | 2 ++ ui-ngx/src/assets/locale/locale.constant-ru_RU.json | 2 ++ ui-ngx/src/assets/locale/locale.constant-uk_UA.json | 2 ++ 5 files changed, 27 insertions(+) diff --git a/ui-ngx/src/app/modules/home/pages/dashboard/dashboard-form.component.html b/ui-ngx/src/app/modules/home/pages/dashboard/dashboard-form.component.html index 0d8971395e..9bd5dd07ab 100644 --- a/ui-ngx/src/app/modules/home/pages/dashboard/dashboard-form.component.html +++ b/ui-ngx/src/app/modules/home/pages/dashboard/dashboard-form.component.html @@ -66,6 +66,16 @@ {{'dashboard.delete' | translate }}
+
+ +
Date: Tue, 1 Feb 2022 18:09:08 +0200 Subject: [PATCH 15/86] Added disable mod --- .../alarm/alarm-dynamic-value.component.ts | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts index 975331b7b4..910aa99962 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.ts @@ -16,7 +16,6 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { - AbstractControl, ControlValueAccessor, FormBuilder, FormGroup, @@ -44,7 +43,11 @@ export class AlarmDynamicValue implements ControlValueAccessor, OnInit{ public dynamicValueSourceTypeTranslations = dynamicValueSourceTypeTranslationMap; private propagateChange = (v: any) => { }; - @Input() helpId: string; + @Input() + helpId: string; + + @Input() + disabled: boolean; constructor(private fb: FormBuilder) { } @@ -81,6 +84,15 @@ export class AlarmDynamicValue implements ControlValueAccessor, OnInit{ } } + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (this.disabled) { + this.dynamicValue.disable({emitEvent: false}); + } else { + this.dynamicValue.enable({emitEvent: false}); + } + } + private updateModel() { this.propagateChange(this.dynamicValue.value); } From ae85dae8bd8a7c89468155979f43056302655dea Mon Sep 17 00:00:00 2001 From: desoliture Date: Tue, 1 Feb 2022 18:23:06 +0200 Subject: [PATCH 16/86] fix processing isActive logic in custom schedules when endsOn equals zero --- .../thingsboard/rule/engine/profile/AlarmRuleState.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java index f997efdeb3..ec7f38576e 100644 --- a/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java +++ b/rule-engine/rule-engine-components/src/main/java/org/thingsboard/rule/engine/profile/AlarmRuleState.java @@ -172,7 +172,13 @@ class AlarmRuleState { return false; } } - return isActive(eventTs, zoneId, zdt, schedule.getStartsOn(), schedule.getEndsOn()); + long endsOn = schedule.getEndsOn(); + if (endsOn == 0) { + // 24 hours in milliseconds + endsOn = 86400000; + } + + return isActive(eventTs, zoneId, zdt, schedule.getStartsOn(), endsOn); } private boolean isActiveCustom(CustomTimeSchedule schedule, long eventTs) { From 09d898c3a70a224b38c7d3e7ab89084426c17113 Mon Sep 17 00:00:00 2001 From: desoliture Date: Tue, 22 Feb 2022 18:00:12 +0200 Subject: [PATCH 17/86] update license headers --- .../components/profile/alarm/alarm-dynamic-value.component.html | 2 +- .../components/profile/alarm/alarm-dynamic-value.component.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html index 99eee091cb..6a64ba4800 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-dynamic-value.component.html @@ -1,6 +1,6 @@ + +
+
+
+ {{ flagIcon }} + + + {{country.flag}} + {{country.name + ' +' + country.dialCode }} + + +
+ + phone-input.phone-input-label + + + {{ 'phone-input.phone-input-required' | translate }} + + + {{ 'phone-input.phone-input-validation' | translate }} + + + {{ 'phone-input.phone-input-pattern' | translate }} + + +
+
diff --git a/ui-ngx/src/app/shared/components/phone-input.component.scss b/ui-ngx/src/app/shared/components/phone-input.component.scss new file mode 100644 index 0000000000..0145a13d62 --- /dev/null +++ b/ui-ngx/src/app/shared/components/phone-input.component.scss @@ -0,0 +1,60 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +:host ::ng-deep { + + .phone-input-container { + display: flex; + align-items: center; + + .phone-input { + width: 100%; + } + } + + .flags-select-container { + display: inline-block; + position: relative; + width: 50px; + height: 100%; + margin-right: 5px; + } + + .flag-container { + position: absolute; + font-size: 20px; + top: 50%; + left: 0; + transform: translate(0, -50%); + } + .country-select { + width: 45px; + height: 30px; + + .country-flag { + font-size: 22px; + padding-right: 10px; + } + + .mat-select-trigger { + height: 100%; + width: 100%; + } + + .mat-select-value { + visibility: hidden; + } + } +} diff --git a/ui-ngx/src/app/shared/components/phone-input.component.ts b/ui-ngx/src/app/shared/components/phone-input.component.ts new file mode 100644 index 0000000000..6618811e19 --- /dev/null +++ b/ui-ngx/src/app/shared/components/phone-input.component.ts @@ -0,0 +1,215 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + +import { Component, forwardRef, Input, OnInit } from '@angular/core'; +import { + ControlValueAccessor, + FormBuilder, + FormControl, + FormGroup, + NG_VALIDATORS, + NG_VALUE_ACCESSOR, + ValidationErrors, + Validator, + ValidatorFn, + Validators +} from '@angular/forms'; +import { TranslateService } from '@ngx-translate/core'; +import { Country, CountryData } from '@shared/models/country.models'; +import examples from 'libphonenumber-js/examples.mobile.json'; +import { CountryCode, getExampleNumber, parsePhoneNumberFromString } from 'libphonenumber-js'; +import { phoneNumberPattern } from '@shared/models/settings.models'; +import { Subscription } from 'rxjs'; + +@Component({ + selector: 'tb-phone-input', + templateUrl: './phone-input.component.html', + styleUrls: ['./phone-input.component.scss'], + providers: [ + CountryData, + { + provide: NG_VALUE_ACCESSOR, + useExisting: forwardRef(() => PhoneInputComponent), + multi: true + }, + { + provide: NG_VALIDATORS, + useExisting: forwardRef(() => PhoneInputComponent), + multi: true + } + ] +}) +export class PhoneInputComponent implements OnInit, ControlValueAccessor, Validator { + + @Input() disabled: boolean; + @Input() defaultCountry: CountryCode = 'US'; + @Input() enableFlagsSelect = true; + @Input() required = true; + + allCountries: Array = []; + phonePlaceholder: string; + countryCallingCode: string; + flagIcon: string; + + phoneNumberPattern = phoneNumberPattern; + + private modelValue: string; + public phoneFormGroup: FormGroup; + private valueChange$: Subscription = null; + private propagateChange = (v: any) => { }; + + constructor(private translate: TranslateService, + private fb: FormBuilder, + private countryCodeData: CountryData) { + } + + ngOnInit(): void { + if (this.enableFlagsSelect) { + this.fetchCountryData(); + } + this.phoneFormGroup = this.fb.group({ + country: [this.defaultCountry, []], + phoneNumber: [ + this.countryCallingCode, + this.required ? [Validators.required, Validators.pattern(phoneNumberPattern), this.validatePhoneNumber()] : [] + ] + }); + + this.valueChange$ = this.phoneFormGroup.get('phoneNumber').valueChanges.subscribe(() => { + this.updateModel(); + }); + + this.phoneFormGroup.get('country').valueChanges.subscribe(value => { + if (value) { + const code = this.countryCallingCode; + this.getFlagAndPhoneNumberData(value); + let phoneNumber = this.phoneFormGroup.get('phoneNumber').value; + if (code !== this.countryCallingCode && phoneNumber) { + phoneNumber = phoneNumber.replace(code, this.countryCallingCode); + } else { + phoneNumber = this.countryCallingCode; + } + this.phoneFormGroup.get('phoneNumber').patchValue(phoneNumber); + } + }); + + this.phoneFormGroup.get('phoneNumber').valueChanges.subscribe(value => { + if (value) { + const parsedPhoneNumber = parsePhoneNumberFromString(value); + const country = this.phoneFormGroup.get('country').value; + if (parsedPhoneNumber?.country && parsedPhoneNumber?.country !== country) { + this.phoneFormGroup.get('country').patchValue(parsedPhoneNumber.country, {emitEvent: true}); + } + } + }); + } + + ngOnDestroy() { + if (this.valueChange$) { + this.valueChange$.unsubscribe(); + } + } + + getFlagAndPhoneNumberData(country) { + if (this.enableFlagsSelect) { + this.flagIcon = this.getFlagIcon(country); + } + this.getPhoneNumberData(country); + } + + getPhoneNumberData(country): void { + const phoneData = getExampleNumber(country, examples); + this.phonePlaceholder = phoneData.number; + this.countryCallingCode = '+' + phoneData.countryCallingCode; + } + + getFlagIcon(countryCode) { + const base = 127462 - 65; + return String.fromCodePoint(...countryCode.split('').map(country => base + country.charCodeAt(0))); + } + + validatePhoneNumber(): ValidatorFn { + return (c: FormControl) => { + const phoneNumber = c.value; + if (phoneNumber) { + const parsedPhoneNumber = parsePhoneNumberFromString(phoneNumber); + if (!parsedPhoneNumber?.isValid() || !parsedPhoneNumber?.isPossible()) { + return { + invalidPhoneNumber: { + valid: false + } + }; + } + } + return null; + }; + } + + validate(): ValidationErrors | null { + return this.phoneFormGroup.get('phoneNumber').valid ? null : { + phoneFormGroup: false + }; + } + + registerOnChange(fn: any): void { + this.propagateChange = fn; + } + + registerOnTouched(fn: any): void { + } + + setDisabledState(isDisabled: boolean): void { + this.disabled = isDisabled; + if (isDisabled) { + this.phoneFormGroup.disable({emitEvent: false}); + } else { + this.phoneFormGroup.enable({emitEvent: false}); + } + } + + protected fetchCountryData(): void { + this.allCountries = []; + this.countryCodeData.allCountries.forEach((c) => { + const cc = c[1]; + const country: Country = { + name: c[0].toString(), + iso2: c[1].toString(), + dialCode: c[2].toString(), + flag: this.getFlagIcon(cc), + }; + + this.allCountries.push(country); + }); + } + + writeValue(phoneNumber): void { + this.modelValue = phoneNumber; + const country = phoneNumber ? parsePhoneNumberFromString(phoneNumber)?.country : this.defaultCountry; + this.getFlagAndPhoneNumberData(country); + this.phoneFormGroup.patchValue({phoneNumber, country}, {emitEvent: !phoneNumber}); + } + + private updateModel() { + const phoneNumber = this.phoneFormGroup.get('phoneNumber'); + if (phoneNumber.valid && this.modelValue !== phoneNumber.value) { + this.modelValue = phoneNumber.value; + this.propagateChange(this.modelValue); + } else { + this.propagateChange(null); + } + } + +} diff --git a/ui-ngx/src/app/shared/models/country.models.ts b/ui-ngx/src/app/shared/models/country.models.ts new file mode 100644 index 0000000000..a4ed4d38d9 --- /dev/null +++ b/ui-ngx/src/app/shared/models/country.models.ts @@ -0,0 +1,1587 @@ +import { Injectable } from '@angular/core'; + +export interface Country { + name: string; + iso2: string; + dialCode: string; + areaCodes?: string[]; + flag: string; +} + +export enum SearchCountryField { + DialCode = 'dialCode', + Iso2 = 'iso2', + Name = 'name', + All = 'all' +} + + +export enum CountryISO{ + Afghanistan = 'AF', + Albania = 'AL', + Algeria = 'DZ', + AmericanSamoa = 'AS', + Andorra = 'AD', + Angola = 'AO', + Anguilla = 'AI', + AntiguaAndBarbuda = 'AG', + Argentina = 'AR', + Armenia = 'AM', + Aruba = 'AW', + Australia = 'AU', + Austria = 'AT', + Azerbaijan = 'AZ', + Bahamas = 'BS', + Bahrain = 'BH', + Bangladesh = 'BD', + Barbados = 'BB', + Belarus = 'BY', + Belgium = 'BE', + Belize = 'BZ', + Benin = 'BJ', + Bermuda = 'BM', + Bhutan = 'BT', + Bolivia = 'BO', + BosniaAndHerzegovina = 'BA', + Botswana = 'BW', + Brazil = 'BR', + BritishIndianOceanTerritory = 'IO', + BritishVirginIslands = 'VG', + Brunei = 'BN', + Bulgaria = 'BG', + BurkinaFaso = 'BF', + Burundi = 'BI', + Cambodia = 'KH', + Cameroon = 'CM', + Canada = 'CA', + CapeVerde = 'CV', + CaribbeanNetherlands = 'BQ', + CaymanIslands = 'KY', + CentralAfricanRepublic = 'CF', + Chad = 'TD', + Chile = 'CL', + China = 'CN', + ChristmasIsland = 'CX', + Cocos = 'CC', + Colombia = 'CC', + Comoros = 'KM', + CongoDRCJamhuriYaKidemokrasiaYaKongo = 'CD', + CongoRepublicCongoBrazzaville = 'CG', + CookIslands = 'CK', + CostaRica = 'CR', + CôteDIvoire = 'CI', + Croatia = 'HR', + Cuba = 'CU', + Curaçao = 'CW', + Cyprus = 'CY', + CzechRepublic = 'CZ', + Denmark = 'DK', + Djibouti = 'DJ', + Dominica = 'DM', + DominicanRepublic = 'DO', + Ecuador = 'EC', + Egypt = 'EG', + ElSalvador = 'SV', + EquatorialGuinea = 'GQ', + Eritrea = 'ER', + Estonia = 'EE', + Ethiopia = 'ET', + FalklandIslands = 'FK', + FaroeIslands = 'FO', + Fiji = 'FJ', + Finland = 'FI', + France = 'FR', + FrenchGuiana = 'GF', + FrenchPolynesia = 'PF', + Gabon = 'GA', + Gambia = 'GM', + Georgia = 'GE', + Germany = 'DE', + Ghana = 'GH', + Gibraltar = 'GI', + Greece = 'GR', + Greenland = 'GL', + Grenada = 'GD', + Guadeloupe = 'GP', + Guam = 'GU', + Guatemala = 'GT', + Guernsey = 'GG', + Guinea = 'GN', + GuineaBissau = 'GW', + Guyana = 'GY', + Haiti = 'HT', + Honduras = 'HN', + HongKong = 'HK', + Hungary = 'HU', + Iceland = 'IS', + India = 'IN', + Indonesia = 'ID', + Iran = 'IR', + Iraq = 'IQ', + Ireland = 'IE', + IsleOfMan = 'IM', + Israel = 'IL', + Italy = 'IT', + Jamaica = 'JM', + Japan = 'JP', + Jersey = 'JE', + Jordan = 'JO', + Kazakhstan = 'KZ', + Kenya = 'KE', + Kiribati = 'KI', + Kosovo = 'XK', + Kuwait = 'KW', + Kyrgyzstan = 'KG', + Laos = 'LA', + Latvia = 'LV', + Lebanon = 'LB', + Lesotho = 'LS', + Liberia = 'LR', + Libya = 'LY', + Liechtenstein = 'LI', + Lithuania = 'LT', + Luxembourg = 'LU', + Macau = 'MO', + Macedonia = 'MK', + Madagascar = 'MG', + Malawi = 'MW', + Malaysia = 'MY', + Maldives = 'MV', + Mali = 'ML', + Malta = 'MT', + MarshallIslands = 'MH', + Martinique = 'MQ', + Mauritania = 'MR', + Mauritius = 'MU', + Mayotte = 'YT', + Mexico = 'MX', + Micronesia = 'FM', + Moldova = 'MD', + Monaco = 'MC', + Mongolia = 'MN', + Montenegro = 'ME', + Montserrat = 'MS', + Morocco = 'MA', + Mozambique = 'MZ', + Myanmar = 'MM', + Namibia = 'NA', + Nauru = 'NR', + Nepal = 'NP', + Netherlands = 'NL', + NewCaledonia = 'NC', + NewZealand = 'NZ', + Nicaragua = 'NI', + Niger = 'NE', + Nigeria = 'NG', + Niue = 'NU', + NorfolkIsland = 'NF', + NorthKorea = 'KP', + NorthernMarianaIslands = 'MP', + Norway = 'NO', + Oman = 'OM', + Pakistan = 'PK', + Palau = 'PW', + Palestine = 'PS', + Panama = 'PA', + PapuaNewGuinea = 'PG', + Paraguay = 'PY', + Peru = 'PE', + Philippines = 'PH', + Poland = 'PL', + Portugal = 'PT', + PuertoRico = 'PR', + Qatar = 'QA', + Réunion = 'RE', + Romania = 'RO', + Russia = 'RU', + Rwanda = 'RW', + SaintBarthélemy = 'BL', + SaintHelena = 'SH', + SaintKittsAndNevis = 'KN', + SaintLucia = 'LC', + SaintMartin = 'MF', + SaintPierreAndMiquelon = 'PM', + SaintVincentAndTheGrenadines = 'VC', + Samoa = 'WS', + SanMarino = 'SM', + SãoToméAndPríncipe = 'ST', + SaudiArabia = 'SA', + Senegal = 'SN', + Serbia = 'RS', + Seychelles = 'SC', + SierraLeone = 'SL', + Singapore = 'SG', + SintMaarten = 'SX', + Slovakia = 'SK', + Slovenia = 'SI', + SolomonIslands = 'SB', + Somalia = 'SO', + SouthAfrica = 'ZA', + SouthKorea = 'KR', + SouthSudan = 'SS', + Spain = 'ES', + SriLanka = 'LK', + Sudan = 'SD', + Suriname = 'SR', + SvalbardAndJanMayen = 'SJ', + Swaziland = 'SZ', + Sweden = 'SE', + Switzerland = 'CH', + Syria = 'SY', + Taiwan = 'TW', + Tajikistan = 'TJ', + Tanzania = 'TZ', + Thailand = 'TH', + TimorLeste = 'TL', + Togo = 'TG', + Tokelau = 'TK', + Tonga = 'TO', + TrinidadAndTobago = 'TT', + Tunisia = 'TN', + Turkey = 'TR', + Turkmenistan = 'TM', + TurksAndCaicosIslands = 'TC', + Tuvalu = 'TV', + USVirginIslands = 'VI', + Uganda = 'UG', + Ukraine = 'UA', + UnitedArabEmirates = 'AE', + UnitedKingdom = 'GB', + UnitedStates = 'US', + Uruguay = 'UY', + Uzbekistan = 'UZ', + Vanuatu = 'VU', + VaticanCity = 'VA', + Venezuela = 'VE', + Vietnam = 'VN', + WallisAndFutuna = 'WF', + WesternSahara = 'EH', + Yemen = 'YE', + Zambia = 'ZM', + Zimbabwe = 'ZW', + ÅlandIslands = 'AX', +} + +@Injectable() +export class CountryData { + public allCountries = [ + [ + 'Afghanistan', + CountryISO.Afghanistan, + '93' + ], + [ + 'Albania', + CountryISO.Albania, + '355' + ], + [ + 'Algeria', + CountryISO.Algeria, + '213' + ], + [ + 'American Samoa', + CountryISO.AmericanSamoa, + '1', + 1, + [ + '684', + ] + ], + [ + 'Andorra', + CountryISO.Andorra, + '376' + ], + [ + 'Angola', + CountryISO.Angola, + '244' + ], + [ + 'Anguilla', + CountryISO.Anguilla, + '1', + 1, + [ + '264', + ] + ], + [ + 'Antigua and Barbuda', + CountryISO.AntiguaAndBarbuda, + '1', + 1, + [ + '268', + ] + ], + [ + 'Argentina', + CountryISO.Argentina, + '54' + ], + [ + 'Armenia', + CountryISO.Armenia, + '374' + ], + [ + 'Aruba', + CountryISO.Aruba, + '297' + ], + [ + 'Australia', + CountryISO.Australia, + '61', + 0 + ], + [ + 'Austria', + CountryISO.Austria, + '43' + ], + [ + 'Azerbaijan', + CountryISO.Azerbaijan, + '994' + ], + [ + 'Bahamas', + CountryISO.Bahamas, + '1', + 1, + [ + '242', + ] + ], + [ + 'Bahrain', + CountryISO.Bahrain, + '973' + ], + [ + 'Bangladesh', + CountryISO.Bangladesh, + '880' + ], + [ + 'Barbados', + CountryISO.Barbados, + '1', + 1, + [ + '246', + ] + ], + [ + 'Belarus', + CountryISO.Belarus, + '375' + ], + [ + 'Belgium', + CountryISO.Belgium, + '32' + ], + [ + 'Belize', + CountryISO.Belize, + '501' + ], + [ + 'Benin', + CountryISO.Benin, + '229' + ], + [ + 'Bermuda', + CountryISO.Bermuda, + '1', + 1, + [ + '441', + ] + ], + [ + 'Bhutan', + CountryISO.Bhutan, + '975' + ], + [ + 'Bolivia', + CountryISO.Bolivia, + '591' + ], + [ + 'Bosnia and Herzegovina', + CountryISO.BosniaAndHerzegovina, + '387' + ], + [ + 'Botswana', + CountryISO.Botswana, + '267' + ], + [ + 'Brazil', + CountryISO.Brazil, + '55' + ], + [ + 'British Indian Ocean Territory', + CountryISO.BritishIndianOceanTerritory, + '246' + ], + [ + 'British Virgin Islands', + CountryISO.BritishVirginIslands, + '1', + 1, + [ + '284', + ] + ], + [ + 'Brunei', + CountryISO.Brunei, + '673' + ], + [ + 'Bulgaria', + CountryISO.Bulgaria, + '359' + ], + [ + 'Burkina Faso', + CountryISO.BurkinaFaso, + '226' + ], + [ + 'Burundi', + CountryISO.Burundi, + '257' + ], + [ + 'Cambodia', + CountryISO.Cambodia, + '855' + ], + [ + 'Cameroon', + CountryISO.Cameroon, + '237' + ], + [ + 'Canada', + CountryISO.Canada, + '1', + 1, + [ + '204', '226', '236', '249', '250', '289', '306', '343', '365', '387', '403', '416', + '418', '431', '437', '438', '450', '506', '514', '519', '548', '579', '581', '587', + '604', '613', '639', '647', '672', '705', '709', '742', '778', '780', '782', '807', + '819', '825', '867', '873', '902', '905' + ] + ], + [ + 'Cape Verde', + CountryISO.CapeVerde, + '238' + ], + [ + 'Caribbean Netherlands', + CountryISO.CaribbeanNetherlands, + '599', + 1 + ], + [ + 'Cayman Islands', + CountryISO.CaymanIslands, + '1', + 1, + [ + '345', + ] + ], + [ + 'Central African Republic', + CountryISO.CentralAfricanRepublic, + '236' + ], + [ + 'Chad', + CountryISO.Chad, + '235' + ], + [ + 'Chile', + CountryISO.Chile, + '56' + ], + [ + 'China', + CountryISO.China, + '86' + ], + [ + 'Christmas Island', + CountryISO.ChristmasIsland, + '61', + 2 + ], + [ + 'Cocos Islands', + CountryISO.Cocos, + '61', + 1 + ], + [ + 'Colombia', + CountryISO.Colombia, + '57' + ], + [ + 'Comoros', + CountryISO.Comoros, + '269' + ], + [ + 'Congo-Kinshasa', + CountryISO.CongoDRCJamhuriYaKidemokrasiaYaKongo, + '243' + ], + [ + 'Congo-Brazzaville', + CountryISO.CongoRepublicCongoBrazzaville, + '242' + ], + [ + 'Cook Islands', + CountryISO.CookIslands, + '682' + ], + [ + 'Costa Rica', + CountryISO.CostaRica, + '506' + ], + [ + 'Côte d’Ivoire', + CountryISO.CôteDIvoire, + '225' + ], + [ + 'Croatia', + CountryISO.Croatia, + '385' + ], + [ + 'Cuba', + CountryISO.Cuba, + '53' + ], + [ + 'Curaçao', + CountryISO.Curaçao, + '599', + 0 + ], + [ + 'Cyprus', + CountryISO.Cyprus, + '357' + ], + [ + 'Czech Republic', + CountryISO.CzechRepublic, + '420' + ], + [ + 'Denmark', + CountryISO.Denmark, + '45' + ], + [ + 'Djibouti', + CountryISO.Djibouti, + '253' + ], + [ + 'Dominica', + CountryISO.Dominica, + '1767' + ], + [ + 'Dominican Republic', + CountryISO.DominicanRepublic, + '1', + 2, + ['809', '829', '849'] + ], + [ + 'Ecuador', + CountryISO.Ecuador, + '593' + ], + [ + 'Egypt', + CountryISO.Egypt, + '20' + ], + [ + 'El Salvador', + CountryISO.ElSalvador, + '503' + ], + [ + 'Equatorial Guinea', + CountryISO.EquatorialGuinea, + '240' + ], + [ + 'Eritrea', + CountryISO.Eritrea, + '291' + ], + [ + 'Estonia', + CountryISO.Estonia, + '372' + ], + [ + 'Ethiopia', + CountryISO.Ethiopia, + '251' + ], + [ + 'Falkland Islands', + CountryISO.FalklandIslands, + '500' + ], + [ + 'Faroe Islands', + CountryISO.FaroeIslands, + '298' + ], + [ + 'Fiji', + CountryISO.Fiji, + '679' + ], + [ + 'Finland', + CountryISO.Finland, + '358', + 0 + ], + [ + 'France', + CountryISO.France, + '33' + ], + [ + 'French Guiana', + CountryISO.FrenchGuiana, + '594' + ], + [ + 'French Polynesia', + CountryISO.FrenchPolynesia, + '689' + ], + [ + 'Gabon', + CountryISO.Gabon, + '241' + ], + [ + 'Gambia', + CountryISO.Gambia, + '220' + ], + [ + 'Georgia', + CountryISO.Georgia, + '995' + ], + [ + 'Germany', + CountryISO.Germany, + '49' + ], + [ + 'Ghana', + CountryISO.Ghana, + '233' + ], + [ + 'Gibraltar', + CountryISO.Gibraltar, + '350' + ], + [ + 'Greece', + CountryISO.Greece, + '30' + ], + [ + 'Greenland', + CountryISO.Greenland, + '299' + ], + [ + 'Grenada', + CountryISO.Grenada, + '1473' + ], + [ + 'Guadeloupe', + CountryISO.Guadeloupe, + '590', + 0 + ], + [ + 'Guam', + CountryISO.Guam, + '1', + 1, + [ + '671', + ] + ], + [ + 'Guatemala', + CountryISO.Guatemala, + '502' + ], + [ + 'Guernsey', + CountryISO.Guernsey, + '44', + 1, + [1481] + ], + [ + 'Guinea', + CountryISO.Guinea, + '224' + ], + [ + 'Guinea-Bissau', + CountryISO.GuineaBissau, + '245' + ], + [ + 'Guyana', + CountryISO.Guyana, + '592' + ], + [ + 'Haiti', + CountryISO.Haiti, + '509' + ], + [ + 'Honduras', + CountryISO.Honduras, + '504' + ], + [ + 'Hong Kong', + CountryISO.HongKong, + '852' + ], + [ + 'Hungary', + CountryISO.Hungary, + '36' + ], + [ + 'Iceland', + CountryISO.Iceland, + '354' + ], + [ + 'India', + CountryISO.India, + '91' + ], + [ + 'Indonesia', + CountryISO.Indonesia, + '62' + ], + [ + 'Iran', + CountryISO.Iran, + '98' + ], + [ + 'Iraq', + CountryISO.Iraq, + '964' + ], + [ + 'Ireland', + CountryISO.Ireland, + '353' + ], + [ + 'Isle of Man', + CountryISO.IsleOfMan, + '44', + 2, + [1624] + ], + [ + 'Israel', + CountryISO.Israel, + '972' + ], + [ + 'Italy', + CountryISO.Italy, + '39', + 0 + ], + [ + 'Jamaica', + CountryISO.Jamaica, + '1', + 1, + [ + '876', + ] + ], + [ + 'Japan', + CountryISO.Japan, + '81' + ], + [ + 'Jersey', + CountryISO.Jersey, + '44', + 3, + [1534] + ], + [ + 'Jordan', + CountryISO.Jordan, + '962' + ], + [ + 'Kazakhstan', + CountryISO.Kazakhstan, + '7', + 1 + ], + [ + 'Kenya', + CountryISO.Kenya, + '254' + ], + [ + 'Kiribati', + CountryISO.Kiribati, + '686' + ], + [ + 'Kosovo', + CountryISO.Kosovo, + '383' + ], + [ + 'Kuwait', + CountryISO.Kuwait, + '965' + ], + [ + 'Kyrgyzstan', + CountryISO.Kyrgyzstan, + '996' + ], + [ + 'Laos', + CountryISO.Laos, + '856' + ], + [ + 'Latvia', + CountryISO.Latvia, + '371' + ], + [ + 'Lebanon', + CountryISO.Lebanon, + '961' + ], + [ + 'Lesotho', + CountryISO.Lesotho, + '266' + ], + [ + 'Liberia', + CountryISO.Liberia, + '231' + ], + [ + 'Libya', + CountryISO.Libya, + '218' + ], + [ + 'Liechtenstein', + CountryISO.Liechtenstein, + '423' + ], + [ + 'Lithuania', + CountryISO.Lithuania, + '370' + ], + [ + 'Luxembourg', + CountryISO.Luxembourg, + '352' + ], + [ + 'Macau', + CountryISO.Macau, + '853' + ], + [ + 'Macedonia', + CountryISO.Macedonia, + '389' + ], + [ + 'Madagascar', + CountryISO.Madagascar, + '261' + ], + [ + 'Malawi', + CountryISO.Malawi, + '265' + ], + [ + 'Malaysia', + CountryISO.Malaysia, + '60' + ], + [ + 'Maldives', + CountryISO.Maldives, + '960' + ], + [ + 'Mali', + CountryISO.Mali, + '223' + ], + [ + 'Malta', + CountryISO.Malta, + '356' + ], + [ + 'Marshall Islands', + CountryISO.MarshallIslands, + '692' + ], + [ + 'Martinique', + CountryISO.Martinique, + '596' + ], + [ + 'Mauritania', + CountryISO.Mauritania, + '222' + ], + [ + 'Mauritius', + CountryISO.Mauritius, + '230' + ], + [ + 'Mayotte', + CountryISO.Mayotte, + '262', + 1 + ], + [ + 'Mexico', + CountryISO.Mexico, + '52' + ], + [ + 'Micronesia', + CountryISO.Micronesia, + '691' + ], + [ + 'Moldova', + CountryISO.Moldova, + '373' + ], + [ + 'Monaco', + CountryISO.Monaco, + '377' + ], + [ + 'Mongolia', + CountryISO.Mongolia, + '976' + ], + [ + 'Montenegro', + CountryISO.Montenegro, + '382' + ], + [ + 'Montserrat', + CountryISO.Montserrat, + '1', + 1, + [ + '664', + ] + ], + [ + 'Morocco', + CountryISO.Morocco, + '212', + 0 + ], + [ + 'Mozambique', + CountryISO.Mozambique, + '258' + ], + [ + 'Myanmar', + CountryISO.Myanmar, + '95' + ], + [ + 'Namibia', + CountryISO.Namibia, + '264' + ], + [ + 'Nauru', + CountryISO.Nauru, + '674' + ], + [ + 'Nepal', + CountryISO.Nepal, + '977' + ], + [ + 'Netherlands', + CountryISO.Netherlands, + '31' + ], + [ + 'New Caledonia', + CountryISO.NewCaledonia, + '687' + ], + [ + 'New Zealand', + CountryISO.NewZealand, + '64' + ], + [ + 'Nicaragua', + CountryISO.Nicaragua, + '505' + ], + [ + 'Niger', + CountryISO.Niger, + '227' + ], + [ + 'Nigeria', + CountryISO.Nigeria, + '234' + ], + [ + 'Niue', + CountryISO.Niue, + '683' + ], + [ + 'Norfolk Island', + CountryISO.NorfolkIsland, + '672' + ], + [ + 'North Korea', + CountryISO.NorthKorea, + '850' + ], + [ + 'Northern Mariana Islands', + CountryISO.NorthernMarianaIslands, + '1670' + ], + [ + 'Norway', + CountryISO.Norway, + '47', + 0 + ], + [ + 'Oman', + CountryISO.Oman, + '968' + ], + [ + 'Pakistan', + CountryISO.Pakistan, + '92' + ], + [ + 'Palau', + CountryISO.Palau, + '680' + ], + [ + 'Palestine', + CountryISO.Palestine, + '970' + ], + [ + 'Panama', + CountryISO.Panama, + '507' + ], + [ + 'Papua New Guinea', + CountryISO.PapuaNewGuinea, + '675' + ], + [ + 'Paraguay', + CountryISO.Paraguay, + '595' + ], + [ + 'Peru', + CountryISO.Peru, + '51' + ], + [ + 'Philippines', + CountryISO.Philippines, + '63' + ], + [ + 'Poland', + CountryISO.Poland, + '48' + ], + [ + 'Portugal', + CountryISO.Portugal, + '351' + ], + [ + 'Puerto Rico', + CountryISO.PuertoRico, + '1', + 3, + ['787', '939'] + ], + [ + 'Qatar', + CountryISO.Qatar, + '974' + ], + [ + 'Réunion', + CountryISO.Réunion, + '262', + 0 + ], + [ + 'Romania', + CountryISO.Romania, + '40' + ], + [ + 'Russia', + CountryISO.Russia, + '7', + 0 + ], + [ + 'Rwanda', + CountryISO.Rwanda, + '250' + ], + [ + 'Saint Barthélemy', + CountryISO.SaintBarthélemy, + '590', + 1 + ], + [ + 'Saint Helena', + CountryISO.SaintHelena, + '290' + ], + [ + 'Saint Kitts and Nevis', + CountryISO.SaintKittsAndNevis, + '1869' + ], + [ + 'Saint Lucia', + CountryISO.SaintLucia, + '1', + 1, + [ + '758', + ] + ], + [ + 'Saint Martin', + CountryISO.SaintMartin, + '590', + 2 + ], + [ + 'Saint Pierre and Miquelon', + CountryISO.SaintPierreAndMiquelon, + '508' + ], + [ + 'Saint Vincent and the Grenadines', + CountryISO.SaintVincentAndTheGrenadines, + '1', + 1, + [ + '784', + ] + ], + [ + 'Samoa', + CountryISO.Samoa, + '685' + ], + [ + 'San Marino', + CountryISO.SanMarino, + '378' + ], + [ + 'São Tomé and Príncipe', + CountryISO.SãoToméAndPríncipe, + '239' + ], + [ + 'Saudi Arabia', + CountryISO.SaudiArabia, + '966' + ], + [ + 'Senegal', + CountryISO.Senegal, + '221' + ], + [ + 'Serbia', + CountryISO.Serbia, + '381' + ], + [ + 'Seychelles', + CountryISO.Seychelles, + '248' + ], + [ + 'Sierra Leone', + CountryISO.SierraLeone, + '232' + ], + [ + 'Singapore', + CountryISO.Singapore, + '65' + ], + [ + 'Sint Maarten', + CountryISO.SintMaarten, + '1', + 1, + [ + '721', + ] + ], + [ + 'Slovakia', + CountryISO.Slovakia, + '421' + ], + [ + 'Slovenia', + CountryISO.Slovenia, + '386' + ], + [ + 'Solomon Islands', + CountryISO.SolomonIslands, + '677' + ], + [ + 'Somalia', + CountryISO.Somalia, + '252' + ], + [ + 'South Africa', + CountryISO.SouthAfrica, + '27' + ], + [ + 'South Korea', + CountryISO.SouthKorea, + '82' + ], + [ + 'South Sudan', + CountryISO.SouthSudan, + '211' + ], + [ + 'Spain', + CountryISO.Spain, + '34' + ], + [ + 'Sri Lanka', + CountryISO.SriLanka, + '94' + ], + [ + 'Sudan', + CountryISO.Sudan, + '249' + ], + [ + 'Suriname', + CountryISO.Suriname, + '597' + ], + [ + 'Svalbard and Jan Mayen', + CountryISO.SvalbardAndJanMayen, + '47', + 1 + ], + [ + 'Swaziland', + CountryISO.Swaziland, + '268' + ], + [ + 'Sweden', + CountryISO.Sweden, + '46' + ], + [ + 'Switzerland', + CountryISO.Switzerland, + '41' + ], + [ + 'Syria', + CountryISO.Syria, + '963' + ], + [ + 'Taiwan', + CountryISO.Taiwan, + '886' + ], + [ + 'Tajikistan', + CountryISO.Tajikistan, + '992' + ], + [ + 'Tanzania', + CountryISO.Tanzania, + '255' + ], + [ + 'Thailand', + CountryISO.Thailand, + '66' + ], + [ + 'Timor-Leste', + CountryISO.TimorLeste, + '670' + ], + [ + 'Togo', + CountryISO.Togo, + '228' + ], + [ + 'Tokelau', + CountryISO.Tokelau, + '690' + ], + [ + 'Tonga', + CountryISO.Tonga, + '676' + ], + [ + 'Trinidad and Tobago', + CountryISO.TrinidadAndTobago, + '1', + 1, + [ + '868', + ] + ], + [ + 'Tunisia', + CountryISO.Tunisia, + '216' + ], + [ + 'Turkey', + CountryISO.Turkey, + '90' + ], + [ + 'Turkmenistan', + CountryISO.Turkmenistan, + '993' + ], + [ + 'Turks and Caicos Islands', + CountryISO.TurksAndCaicosIslands, + '1649' + ], + [ + 'Tuvalu', + CountryISO.Tuvalu, + '688' + ], + [ + 'U.S. Virgin Islands', + CountryISO.USVirginIslands, + '1', + 1, + [ + '340', + ] + ], + [ + 'Uganda', + CountryISO.Uganda, + '256' + ], + [ + 'Ukraine', + CountryISO.Ukraine, + '380' + ], + [ + 'United Arab Emirates', + CountryISO.UnitedArabEmirates, + '971' + ], + [ + 'United Kingdom', + CountryISO.UnitedKingdom, + '44', + 0 + ], + [ + 'United States', + CountryISO.UnitedStates, + '1', + 0 + ], + [ + 'Uruguay', + CountryISO.Uruguay, + '598' + ], + [ + 'Uzbekistan', + CountryISO.Uzbekistan, + '998' + ], + [ + 'Vanuatu', + CountryISO.Vanuatu, + '678' + ], + [ + 'Vatican City', + CountryISO.VaticanCity, + '39', + 1 + ], + [ + 'Venezuela', + CountryISO.Venezuela, + '58' + ], + [ + 'Vietnam', + CountryISO.Vietnam, + '84' + ], + [ + 'Wallis and Futuna', + CountryISO.WallisAndFutuna, + '681' + ], + [ + 'Western Sahara', + CountryISO.WesternSahara, + '212', + 1 + ], + [ + 'Yemen', + CountryISO.Yemen, + '967' + ], + [ + 'Zambia', + CountryISO.Zambia, + '260' + ], + [ + 'Zimbabwe', + CountryISO.Zimbabwe, + '263' + ], + [ + 'Åland Islands', + CountryISO.ÅlandIslands, + '358', + 1 + ] + ]; +} diff --git a/ui-ngx/src/app/shared/shared.module.ts b/ui-ngx/src/app/shared/shared.module.ts index a356fa5921..706ffb16a0 100644 --- a/ui-ngx/src/app/shared/shared.module.ts +++ b/ui-ngx/src/app/shared/shared.module.ts @@ -159,6 +159,7 @@ import { TbMarkdownComponent } from '@shared/components/markdown.component'; import { ProtobufContentComponent } from '@shared/components/protobuf-content.component'; import { CssComponent } from '@shared/components/css.component'; import { SafePipe } from '@shared/pipe/safe.pipe'; +import { PhoneInputComponent } from '@shared/components/phone-input.component'; export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) { return markedOptionsService; @@ -277,7 +278,8 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) WidgetsBundleSearchComponent, CopyButtonComponent, TogglePasswordComponent, - ProtobufContentComponent + ProtobufContentComponent, + PhoneInputComponent ], imports: [ CommonModule, @@ -472,7 +474,8 @@ export function MarkedOptionsFactory(markedOptionsService: MarkedOptionsService) WidgetsBundleSearchComponent, CopyButtonComponent, TogglePasswordComponent, - ProtobufContentComponent + ProtobufContentComponent, + PhoneInputComponent ] }) export class SharedModule { } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index aab433c992..050080d5ba 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3351,6 +3351,12 @@ "material-icons": "Material icons", "show-all": "Show all icons" }, + "phone-input": { + "phone-input-label": "Phone number", + "phone-input-required": "Phone number is required", + "phone-input-validation": "Phone number is invalid or not possible", + "phone-input-pattern": "Invalid phone number. Should be in E.164 format, ex. +19995550123." + }, "custom": { "widget-action": { "action-cell-button": "Action cell button", diff --git a/ui-ngx/yarn.lock b/ui-ngx/yarn.lock index 0aac92b131..45fe658406 100644 --- a/ui-ngx/yarn.lock +++ b/ui-ngx/yarn.lock @@ -6027,6 +6027,11 @@ less@4.1.1: needle "^2.5.2" source-map "~0.6.0" +libphonenumber-js@^1.10.4: + version "1.10.4" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.4.tgz#90397f0ed620262570a32244c9fbc389cc417ce4" + integrity sha512-9QWxEk4GW5RDnFzt8UtyRENfFpAN8u7Sbf9wf32tcXY9tdtnz1dKHIBwW2Wnfx8ypXJb9zUnTpK9aQJ/B8AlnA== + license-webpack-plugin@2.3.20: version "2.3.20" resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-2.3.20.tgz#f51fb674ca31519dbedbe1c7aabc036e5a7f2858" From 19c313dbedfa9cca37f0c42aaba7f2064fa32686 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Mon, 30 May 2022 14:54:41 +0300 Subject: [PATCH 38/86] Refactoring --- .../components/phone-input.component.html | 3 +- .../components/phone-input.component.ts | 34 ++++++++++++++----- .../src/app/shared/models/country.models.ts | 16 +++++++++ .../assets/locale/locale.constant-en_US.json | 2 +- 4 files changed, 44 insertions(+), 11 deletions(-) diff --git a/ui-ngx/src/app/shared/components/phone-input.component.html b/ui-ngx/src/app/shared/components/phone-input.component.html index 9001e04ce8..15ed9bf2df 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.html +++ b/ui-ngx/src/app/shared/components/phone-input.component.html @@ -27,7 +27,7 @@
- + phone-input.phone-input-label diff --git a/ui-ngx/src/app/shared/components/phone-input.component.ts b/ui-ngx/src/app/shared/components/phone-input.component.ts index 6618811e19..536b1cc723 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.ts +++ b/ui-ngx/src/app/shared/components/phone-input.component.ts @@ -59,6 +59,15 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida @Input() enableFlagsSelect = true; @Input() required = true; + private floatLabel = 'always'; + get showLabel(): string { + return this.floatLabel; + } + @Input() + set showLabel(value) { + this.floatLabel = value ? 'always' : 'never'; + } + allCountries: Array = []; phonePlaceholder: string; countryCallingCode: string; @@ -82,11 +91,9 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida } this.phoneFormGroup = this.fb.group({ country: [this.defaultCountry, []], - phoneNumber: [ - this.countryCallingCode, - this.required ? [Validators.required, Validators.pattern(phoneNumberPattern), this.validatePhoneNumber()] : [] - ] + phoneNumber: [null, this.required ? [Validators.required] : []] }); + this.phoneFormGroup.get('phoneNumber').setValidators([Validators.pattern(phoneNumberPattern), this.validatePhoneNumber()]); this.valueChange$ = this.phoneFormGroup.get('phoneNumber').valueChanges.subscribe(() => { this.updateModel(); @@ -97,12 +104,14 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida const code = this.countryCallingCode; this.getFlagAndPhoneNumberData(value); let phoneNumber = this.phoneFormGroup.get('phoneNumber').value; - if (code !== this.countryCallingCode && phoneNumber) { - phoneNumber = phoneNumber.replace(code, this.countryCallingCode); - } else { - phoneNumber = this.countryCallingCode; + if (phoneNumber) { + if (code !== this.countryCallingCode && phoneNumber.includes(code)) { + phoneNumber = phoneNumber.replace(code, this.countryCallingCode); + } else { + phoneNumber = this.countryCallingCode; + } + this.phoneFormGroup.get('phoneNumber').patchValue(phoneNumber); } - this.phoneFormGroup.get('phoneNumber').patchValue(phoneNumber); } }); @@ -123,6 +132,13 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida } } + focus() { + const phoneNumber = this.phoneFormGroup.get('phoneNumber'); + if (!phoneNumber.value) { + phoneNumber.patchValue(this.countryCallingCode); + } + } + getFlagAndPhoneNumberData(country) { if (this.enableFlagsSelect) { this.flagIcon = this.getFlagIcon(country); diff --git a/ui-ngx/src/app/shared/models/country.models.ts b/ui-ngx/src/app/shared/models/country.models.ts index a4ed4d38d9..10612de015 100644 --- a/ui-ngx/src/app/shared/models/country.models.ts +++ b/ui-ngx/src/app/shared/models/country.models.ts @@ -1,3 +1,19 @@ +/// +/// Copyright © 2016-2022 The Thingsboard Authors +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// + import { Injectable } from '@angular/core'; export interface Country { diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 050080d5ba..b720594fe0 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -3355,7 +3355,7 @@ "phone-input-label": "Phone number", "phone-input-required": "Phone number is required", "phone-input-validation": "Phone number is invalid or not possible", - "phone-input-pattern": "Invalid phone number. Should be in E.164 format, ex. +19995550123." + "phone-input-pattern": "Invalid phone number. Should be in E.164 format, ex. {{phoneNumber}}" }, "custom": { "widget-action": { From 4301927b7f1cccd818d576c1a2c0822f5d899fda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20N=C3=BA=C3=B1ez?= Date: Thu, 2 Jun 2022 20:40:01 +0200 Subject: [PATCH 39/86] [WIP] Add spanish feature to 3.4 --- .../assets/locale/locale.constant-es_ES.json | 2094 +++++++++++++++-- 1 file changed, 1934 insertions(+), 160 deletions(-) diff --git a/ui-ngx/src/assets/locale/locale.constant-es_ES.json b/ui-ngx/src/assets/locale/locale.constant-es_ES.json index f8e16aca0e..578153c62f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-es_ES.json +++ b/ui-ngx/src/assets/locale/locale.constant-es_ES.json @@ -58,7 +58,8 @@ "next-with-label": "Siguiente: {{label}}", "read-more": "Leer más", "hide": "Ocultar", - "done": "Hecho" + "done": "Terminado", + "print": "Imprimir" }, "aggregation": { "aggregation": "Agrupación", @@ -75,6 +76,7 @@ "admin": { "general": "General", "general-settings": "Configuración general", + "home-settings": "Ajustes Home", "outgoing-mail": "Servidor de correo", "outgoing-mail-settings": "Configuración del servidor de correo de salida", "system-settings": "Sistema", @@ -104,6 +106,7 @@ "proxy-port-range": "El puerto proxy debe estar en un rango de 1 a 65535.", "proxy-user": "Usuario proxy", "proxy-password": "Contraseña proxy", + "change-password": "Cambiar contraseña", "send-test-mail": "Enviar correo de prueba", "sms-provider": "Proveedor SMS", "sms-provider-settings": "Ajustes proveedor SMS", @@ -111,18 +114,21 @@ "sms-provider-type-required": "Se requiere proveedor SMS.", "sms-provider-type-aws-sns": "Amazon SNS", "sms-provider-type-twilio": "Twilio", + "sms-provider-type-smpp": "SMPP", "aws-access-key-id": "AWS Access Key ID", - "aws-access-key-id-required": "Se requiere AWS Access Key ID", + "aws-access-key-id-required": "AWS Access Key ID requerido", "aws-secret-access-key": "AWS Secret Access Key", - "aws-secret-access-key-required": "Se requere AWS Secret Access Key", + "aws-secret-access-key-required": "AWS Secret Access Key requerido", "aws-region": "Región AWS", "aws-region-required": "Se requere región AWS", "number-from": "Nº de teléfono Origen", "number-from-required": "Se requere Nº de teléfono origen.", "number-to": "Nº de teléfono de destino", "number-to-required": "Se requere Nº de teléfono de destino.", - "phone-number-hint": "Nº de teléfono en formato E.164, ex. +19995550123", - "phone-number-pattern": "Nº Inválido. Debe estar en formato E.164, ex. +19995550123.", + "phone-number-hint": "Nº de teléfono en formato E.164, ej. +19995550123", + "phone-number-hint-twilio": "Nº de teléfono en formato E.164 SID/SID de servicio de mensajería, ej. +19995550123/PNXXX/MGXXX", + "phone-number-pattern": "Nº Inválido. Debe estar en formato E.164, ej. +19995550123.", + "phone-number-pattern-twilio": "Nº Inválido. Debe estar en formato E.164 , ej. +19995550123/PNXXX/MGXXX.", "sms-message": "Mensaje SMS", "sms-message-required": "Se requeriere mensaje SMS.", "sms-message-max-length": "Los SMS no pueden ser más largos de 1600 caracteres", @@ -149,12 +155,14 @@ "password-expiration-period-days-range": "El período de caducidad de la contraseña en días no puede ser negativo", "password-reuse-frequency-days": "Frecuencia de reutilización de contraseña en días", "password-reuse-frequency-days-range": "La frecuencia de reutilización de contraseña en días no puede ser negativa", + "allow-whitespace": "Permitir espacios en blanco", "general-policy": "Política general", "max-failed-login-attempts": "Número máximo de intentos fallidos de inicio de sesión, antes de que la cuenta esté bloqueada", "minimum-max-failed-login-attempts-range": "El número máximo de intentos fallidos de inicio de sesión no puede ser negativo", "user-lockout-notification-email": "En caso de bloqueo de la cuenta del usuario, envíe una notificación por correo electrónico", "domain-name": "Nombre de dominio", "domain-name-unique": "El nombre de dominio y protocolo debe ser único.", + "domain-name-max-length": "El nombre de dominio debe ser menor que 256", "error-verification-url": "Un nombre de dominio no debe contener símbolos '/' y ':'. Ejemplo: thingsboard.io", "oauth2": { "access-token-uri": "URI Access token", @@ -171,21 +179,28 @@ "client-authentication-method": "Método de autenticación", "client-id": "ID Cliente", "client-id-required": "Se requere ID Cliente.", + "client-id-max-length": "El ID Cliente debe ser menor de 256", "client-secret": "Secreto de Cliente", "client-secret-required": "Se requiere Secreto de Cliente.", + "client-secret-max-length": "El secreto de cliente debe ser menor de 2049", "custom-setting": "Ajustes personalizados", "customer-name-pattern": "Patrón nombre de cliente", + "customer-name-pattern-max-length": "El patrón del nombre de cliente debe ser menor de 256", "default-dashboard-name": "Nombre de panel por defecto", + "default-dashboard-name-max-length": "El nombre del panel debe ser menor de 256", "delete-domain-text": "Atención, tras la confirmación el dominio y todos los datos del proveedor no estarán disponibles.", "delete-domain-title": "Eliminar los ajustes del dominio '{{domainName}}'?", "delete-registration-text": "Atención, tras la confirmación los datos del proveedor no estarán disponibles.", "delete-registration-title": "Eliminar el proveedor '{{name}}'?", "email-attribute-key": "Clave de atributos email", "email-attribute-key-required": "Se requiere clave de atributos de email.", + "email-attribute-key-max-length": "La clave de atributos de email debe ser menor de 32", "first-name-attribute-key": "Clave de atributos de nombre", + "first-name-attribute-key-max-length": "La clave de atributos de nombre debe ser menor de 32", "general": "General", "jwk-set-uri": "URI web key JSON", "last-name-attribute-key": "Clave de atributos de apellido", + "last-name-attribute-key-max-length": "La clave de atributos de apellido debe ser menor de 32", "login-button-icon": "Icono de botón login", "login-button-label": "Etiqueta de proveedor", "login-button-label-placeholder": "Login con $(Provider label)", @@ -194,6 +209,7 @@ "mapper": "Mapeador", "new-domain": "Nuevo dominio", "oauth2": "OAuth2", + "password-max-length": "La contraseña debe ser menor de 256", "redirect-uri-template": "Plantilla de redirección URI", "copy-redirect-uri": "Copiar URI de redirección", "registration-id": "ID de registro", @@ -203,21 +219,141 @@ "scope-required": "Se requiere alcance.", "tenant-name-pattern": "Patrón de nombre de propietario", "tenant-name-pattern-required": "Se requiere patrón de nombre de propietario.", + "tenant-name-pattern-max-length": "EL patrón de nombre de propietario debe ser menor de 256", "tenant-name-strategy": "Estrategia de Nombre de Propietario", "type": "Tipo de mapeador", "uri-pattern-error": "Formato de URI inválido.", "url": "URL", "url-pattern": "Formato URL inválido.", "url-required": "Se requiere URL.", + "url-max-length": "URL debe ser menor de 256", "user-info-uri": "URI Información de usuario", "user-info-uri-required": "Se requiere URI de información usuario.", + "username-max-length": "El usuario debe ser menor de 256", "user-name-attribute-name": "Clave de atributos de nombre de usuario", "user-name-attribute-name-required": "Se requiere clave de atributos de nombre de usuario", "protocol": "Protocolo", "domain-schema-http": "HTTP", "domain-schema-https": "HTTPS", "domain-schema-mixed": "HTTP+HTTPS", - "enable": "Activar ajustes OAuth2" + "enable": "Activar ajustes OAuth2", + "domains": "Dominios", + "mobile-apps": "Aplicaciones móviles", + "no-mobile-apps": "No hay aplicaciones configuradas", + "mobile-package": "Paquete de aplicación", + "mobile-package-placeholder": "Ej.: mi.ejemplo.app", + "mobile-package-hint": "Para Android: El ID único de aplicación. Para iOS: Identificador Product bundle.", + "mobile-package-unique": "El paquete de aplicación debe ser único.", + "mobile-app-secret": "Secreto de aplicación", + "invalid-mobile-app-secret": "El secreto de aplicación sólo puede contener carácteres alfanuméricos y debe tener entre 16 y 2048 carácteres de longitud.", + "copy-mobile-app-secret": "Copiar secreto de aplicación", + "add-mobile-app": "Añadir aplicación", + "delete-mobile-app": "Borrar información de aplicación", + "providers": "Proveedores", + "platform-web": "Web", + "platform-android": "Android", + "platform-ios": "iOS", + "all-platforms": "Todas las plataformas", + "allowed-platforms": "Plataformas permitidas" + }, + "smpp-provider": { + "smpp-version": "Versión SMPP", + "smpp-host": "Host SMPP", + "smpp-host-required": "Host SMPP requerido", + "smpp-port": "Puerto SMPP", + "smpp-port-required": "Puerto SMPP requerido", + "system-id": "System ID", + "system-id-required": "System ID requerido", + "password": "Contraseña", + "password-required": "Contraseña requerida", + "type-settings": "Ajustes de tipo", + "source-settings": "Ajustes de origen", + "destination-settings": "Ajustes de destino", + "additional-settings": "Ajustes adicionales", + "system-type": "Tipo de sistema", + "bind-type": "Tipo de enlace", + "service-type": "Tipo de servicio", + "source-address": "Dirección de origen", + "source-ton": "Origen TON", + "source-npi": "Origen NPI", + "destination-ton": "Destino TON (Tipo de número)", + "destination-npi": "Destino NPI (Numbering Plan Identification)", + "address-range": "Rango de dirección", + "coding-scheme": "Esquema de codificación", + "bind-type-tx": "Transmisor", + "bind-type-rx": "Receptor", + "bind-type-trx": "Transceptor", + "ton-unknown": "Desconocido", + "ton-international": "Internacional", + "ton-national": "Nacional", + "ton-network-specific": "Específico de red", + "ton-subscriber-number": "Número de suscriptor", + "ton-alphanumeric": "Alfanumérico", + "ton-abbreviated": "Abreviado", + "npi-unknown": "0 - Desconocido", + "npi-isdn": "1 - RDSI/Teléfono plan numérico (E163/E164)", + "npi-data-numbering-plan": "3 - Datos plan numérico (X.121)", + "npi-telex-numbering-plan": "4 - Telex plan numérico (F.69)", + "npi-land-mobile": "6 - Línea Móvil (E.212)", + "npi-national-numbering-plan": "8 - Nacional", + "npi-private-numbering-plan": "9 - Privado", + "npi-ermes-numbering-plan": "10 - ERMES (ETSI DE/PS 3 01-3)", + "npi-internet": "13 - Internet (IP)", + "npi-wap-client-id": "18 - WAP Client Id (to be defined by WAP Forum)", + "scheme-smsc": "0 - SMSC Default Alphabet (ASCII for short and long code and to GSM for toll-free)", + "scheme-ia5": "1 - IA5 (ASCII for short and long code, Latin 9 for toll-free (ISO-8859-9))", + "scheme-octet-unspecified-2": "2 - Octet Unspecified (8-bit binary)", + "scheme-latin-1": "3 - Latin 1 (ISO-8859-1)", + "scheme-octet-unspecified-4": "4 - Octet Unspecified (8-bit binary)", + "scheme-jis": "5 - JIS (X 0208-1990)", + "scheme-cyrillic": "6 - Cyrillic (ISO-8859-5)", + "scheme-latin-hebrew": "7 - Latin/Hebrew (ISO-8859-8)", + "scheme-ucs-utf": "8 - UCS2/UTF-16 (ISO/IEC-10646)", + "scheme-pictogram-encoding": "9 - Pictogram Encoding", + "scheme-music-codes": "10 - Music Codes (ISO-2022-JP)", + "scheme-extended-kanji-jis": "13 - Extended Kanji JIS (X 0212-1990)", + "scheme-korean-graphic-character-set": "14 - Korean Graphic Character Set (KS C 5601/KS X 1001)" + }, + "queue-select-name": "Select queue name", + "queue-name": "Name", + "queue-name-required": "Queue name is required!", + "queues": "Queues", + "queue-partitions": "Partitions", + "queue-submit-strategy": "Submit strategy", + "queue-processing-strategy": "Processing strategy", + "queue-configuration": "Queue configuration", + "2fa": { + "2fa": "Two-factor authentication", + "available-providers": "Available providers", + "issuer-name": "Issuer name", + "issuer-name-required": "Issuer name is required.", + "max-verification-failures-before-user-lockout": "Max verification failures before user lockout", + "max-verification-failures-before-user-lockout-pattern": "Max verification failures must be a positive integer.", + "number-of-checking-attempts": "Number of checking attempts", + "number-of-checking-attempts-pattern": "Number of checking attempts must be a positive integer.", + "number-of-checking-attempts-required": "Number of checking attempts is required.", + "number-of-codes": "Number of codes", + "number-of-codes-pattern": "Number of codes must be a positive integer.", + "number-of-codes-required": "Number of codes is required.", + "provider": "Provider", + "retry-verification-code-period": "Retry verification code period (sec)", + "retry-verification-code-period-pattern": "Minimal period time is 5 sec", + "retry-verification-code-period-required": "Retry verification code period is required.", + "total-allowed-time-for-verification": "Total allowed time for verification (sec)", + "total-allowed-time-for-verification-pattern": "Minimal total allowed time is 60 sec", + "total-allowed-time-for-verification-required": "Total allowed time is required.", + "use-system-two-factor-auth-settings": "Use system two factor auth settings", + "verification-code-check-rate-limit": "Verification code check rate limit", + "verification-code-lifetime": "Verification code lifetime (sec)", + "verification-code-lifetime-pattern": "Verification code lifetime must be a positive integer.", + "verification-code-lifetime-required": "Verification code lifetime is required.", + "verification-message-template": "Verification message template", + "verification-limitations": "Verification limitations", + "verification-message-template-pattern": "Verification message need to contains pattern: ${code}", + "verification-message-template-required": "Verification message template is required.", + "within-time": "Within time (sec)", + "within-time-pattern": "Time must be a positive integer.", + "within-time-required": "Time is required." } }, "alarm": { @@ -299,6 +435,7 @@ "filter-type-single-entity": "Única entidad", "filter-type-entity-list": "Lista de entidades", "filter-type-entity-name": "Nombre de entidad", + "filter-type-entity-type": "Tipo de entidad", "filter-type-state-entity": "Entidad desde estado de panel", "filter-type-state-entity-description": "Entidad tomada de los parámetros de panel", "filter-type-asset-type": "Tipo de activo", @@ -312,6 +449,7 @@ "filter-type-entity-view-type-and-name-description": "Vistas de entidad del tipo '{{entityView}}' y cuyo nombre comience por '{{prefix}}'", "filter-type-edge-type": "Tipo de borde", "filter-type-edge-type-description": "Bordes del tipo '{{edgeType}}'", + "filter-type-edge-type-and-name-description": "Vistas de entidad del tipo '{{entityViewType}}' y cuyo nombre comience por '{{prefix}}'", "filter-type-relations-query": "Consulta de relaciones", "filter-type-relations-query-description": "{{entities}} que tienen {{relationType}} relación {{direction}} {{rootEntity}}", "filter-type-asset-search-query": "Búsqueda de activos", @@ -323,23 +461,21 @@ "filter-type-apiUsageState": "Uso de API", "filter-type-edge-search-query": "Consultar búsqueda de borde", "filter-type-edge-search-query-description": "Bordes con tipos {{edgeTypes}} que tienen {{relationType}} relación {{direction}} {{rootEntity}}", - "type-assigned-to-edge": "Asignado a borde", - "type-unassigned-from-edge": "Sin asignar desde bordes", - "entity-filter": "Filtro por entidad", - "resolve-multiple": "Tomar como múltiples entidades", - "filter-type": "Filtro por tipo", - "filter-type-required": "Se requiere filtro por tipo.", - "entity-filter-no-entity-matched": "No se han encontrado entidades con el filtro especificado.", - "no-entity-filter-specified": "No hay filtro de entidades especificado", - "root-state-entity": "Usar estado de panel como raíz", - "last-level-relation": "Buscar sólo la relación de último nivel", - "root-entity": "Entidad raiz", - "state-entity-parameter-name": "Nombre de parámetro de entidad de estado", - "default-state-entity": "Entidad de estado predeterminada", + "entity-filter": "Filtro de entidad", + "resolve-multiple": "Resolver como múltiples entidades", + "filter-type": "Tipo de filtro", + "filter-type-required": "Se requiere tipo de filtro.", + "entity-filter-no-entity-matched": "No se encontraron entidades que coincidan con el filtro especificado.", + "no-entity-filter-specified": "No se ha especificado filtro de entidad", + "root-state-entity": "Usar entidad de estado del panel como raíz", + "last-level-relation": "Obtener sólo el último nivel de relación", + "root-entity": "Entidad raíz", + "state-entity-parameter-name": "Parámetro de estado de entidad", + "default-state-entity": "Entidad de estado por defecto", "default-entity-parameter-name": "Por defecto", - "max-relation-level": "Máx nivel de relación", + "max-relation-level": "Máximo nivel de relación", "unlimited-level": "Nivel ilimitado", - "state-entity": "Entidad estado del panel", + "state-entity": "Entidad de estado del panel", "all-entities": "Todas las entidades", "any-relation": "cualquiera" }, @@ -349,6 +485,7 @@ "management": "Gestión de Activos", "view-assets": "Ver Activos", "add": "Añadir Activo", + "assign-to-customer": "Asignar a cliente", "assign-asset-to-customer": "Asignar Activo(s) A Cliente", "assign-asset-to-customer-text": "Selecciona los activos a asignar al cliente", @@ -371,6 +508,8 @@ "asset-types": "Tipos de activo", "name": "Nombre", "name-required": "Nombre requerido.", + "name-max-length": "El nombre debe tener menos de 256", + "label-max-length": "La etiqueta debe tener menos de 256", "description": "Descripción", "type": "Tipo", "type-required": "Tipo requerido.", @@ -380,6 +519,8 @@ "asset-details": "Detalles de activo", "assign-assets": "Asignar activos", "assign-assets-text": "Asignar { count, plural, 1 {1 activo} other {# activos} } a cliente", + "assign-asset-to-edge-title": "Asignar activo(s) al borde", + "assign-asset-to-edge-text": "Por favor, selecciona lo activos a asignar al borde", "delete-assets": "Borrar activos", "unassign-assets": "Cancelar asignación de activo", "unassign-assets-action-title": "Cancelar asignación de { count, plural, 1 {1 activo} other {# activos} } del cliente", @@ -398,25 +539,25 @@ "unassign-asset": "Cancelar asignación de activo", "unassign-assets-title": "Cancelar las asignaciones { count, plural, 1 {1 activo} other {# activos} }?", "unassign-assets-text": "Tras la confirmación todos los activos seleccionados serán desasignados y no serán accesibles por el cliente.", + "unassign-assets-from-edge": "Anular activos de borde", "copyId": "Copiar ID de activo", "idCopiedMessage": "El ID ha sido copiado al portapapeles", "select-asset": "Seleccionar activo", "no-assets-matching": "No se han encontrado activos que coincidan con '{{entity}}' .", "asset-required": "Nombre de activo requerido", "name-starts-with": "El nombre de activo comienza con", + "help-text": "Usar el símbolo '%' de acuerdo a las necesidades: '%nombre_activo_contiene%', '%nombre_activo_acaba_en', 'nombre_activo_comienza_con'.", "import": "Importar activos", "asset-file": "Archivo del activo", - "search": "Buscar activos", - "selected-assets": "{ count, plural, 1 {1 activo} other {# activos} } seleccionados", "label": "Etiqueta", + "search": "Buscar activos", "assign-asset-to-edge": "Asignar activo(s) al borde", - "assign-asset-to-edge-text":"Por favor, seleccione los activos para asignar al borde", "unassign-asset-from-edge": "Anular activo de bodre", "unassign-asset-from-edge-title": "¿Está seguro de que desea desasignar el activo '{{assetName}}'?", "unassign-asset-from-edge-text": "Después de la confirmación, el activo no será asignado y el borde no podrá acceder a él", - "unassign-assets-from-edge-action-title": "Anular asignación {count, plural, 1 {1 activo} other {# activos} } desde el borde", "unassign-assets-from-edge-title": "¿Está seguro de que desea desasignar {count, plural, 1 {1 activo} other {# activos} }?", - "unassign-assets-from-edge-text": "Después de la confirmación, todos los activos seleccionados quedarán sin asignar y el borde no podrá acceder a ellos." + "unassign-assets-from-edge-text": "Después de la confirmación, todos los activos seleccionados quedarán sin asignar y el borde no podrá acceder a ellos.", + "selected-assets": "{ count, plural, 1 {1 activo} other {# activos} } seleccionados" }, "attribute": { "attributes": "Atributos", @@ -428,6 +569,7 @@ "scope-shared": "Atributos Compartidos", "add": "Agregar atributo", "key": "Clave", + "key-max-length": "La clave debe ser menor de 256", "last-update-time": "Hora de última actualización", "key-required": "Clave del atributo requerida.", "value": "Valor", @@ -449,12 +591,16 @@ }, "api-usage": { "api-usage": "Uso de API", + "alarm": "Alarma", + "alarms-created": "Alarmas creadas", + "alarms-created-daily-activity": "Actividad diaria de Alarmas creadas", + "alarms-created-hourly-activity": "Actividad horaria de Alarmas creadas", + "alarms-created-monthly-activity": "Actividad mensual de Alarmas creadas", "data-points": "Puntos de datos", - "data-points-storage-days": "Días de grabación de puntos de datos", + "data-points-storage-days": "Días de guardado de puntos de datos", "email": "Email", "email-messages": "Mensajes de Email", "email-messages-daily-activity": "Actividad diaria de Emails", - "email-messages-hourly-activity": "Actividad horaria de Emails", "email-messages-monthly-activity": "Actividad mensual de Emails", "exceptions": "Excepciones", "executions": "Ejecuciones", @@ -466,6 +612,9 @@ "javascript-functions-monthly-activity": "Actividad mensual de funciones JavaScript", "latest-error": "Último error", "messages": "Mensajes", + "notifications": "Notificaciones", + "notifications-email-sms": "Notificaciones (Email/SMS)", + "notifications-hourly-activity": "Notificaciones actividad horaria", "permanent-failures": "${entityName} Fallos permanentes", "permanent-timeouts": "${entityName} Timeouts permanentes", "processing-failures": "${entityName} Fallos de procesamiento", @@ -483,7 +632,6 @@ "sms": "SMS", "sms-messages": "Mensajes SMS", "sms-messages-daily-activity": "Actividad diaria de mensajes SMS", - "sms-messages-hourly-activity": "Actividad horaria de mensajes SMS", "sms-messages-monthly-activity": "Actividad mensual de mensajes SMS", "successful": "${entityName} Exitoso", "telemetry": "Telemetría", @@ -519,6 +667,8 @@ "type-credentials-updated": "Credenciales actualizados", "type-assigned-to-customer": "Asignado a Cliente", "type-unassigned-from-customer": "Deasignado a Cliente", + "type-assigned-to-edge": "Asignado a Borde", + "type-unassigned-from-edge": "Deasignado de Borde", "type-activated": "Activado", "type-suspended": "Suspendido", "type-credentials-read": "Lectura de credenciales", @@ -561,7 +711,10 @@ "address2": "Dirección 2", "phone": "Teléfono", "email": "Email", - "no-address": "Sin Dirección" + "no-address": "Sin Dirección", + "state-max-length": "Longitud de provincia debe ser menor que 256", + "phone-max-length": "Teléfono debe ser menor que 256", + "city-max-length": "Ciudad debe ser menor que 256" }, "common": { "username": "Usuario", @@ -570,7 +723,9 @@ "enter-password": "Introduce la contraseña", "enter-search": "Introduce búsqueda", "created-time": "Fecha de creación", - "loading": "Cargando..." + "loading": "Cargando...", + "proceed": "Proceder", + "open-details-page": "Abrir detalles" }, "content-type": { "json": "Json", @@ -616,10 +771,10 @@ "manage-dashboards": "Gestionar paneles", "title": "Título", "title-required": "Título requerido.", + "title-max-length": "Título debe ser menor de 256", "description": "Descripción", "details": "Detalles", "events": "Eventos", - "edges": "Bordes del cliente", "copyId": "Copiar ID de cliente", "idCopiedMessage": "El ID de cliente se ha copiado al portapapeles", "select-customer": "Seleccionar Cliente", @@ -629,7 +784,9 @@ "default-customer": "Cliente por defecto", "default-customer-required": "Se requiere cliente por defecto para realizar debu a nivel de propietario", "search": "Buscar clientes", - "selected-customers": "{ count, plural, 1 {1 cliente} other {# clientes} } seleccionados" + "selected-customers": "{ count, plural, 1 {1 cliente} other {# clientes} } seleccionados", + "edges": "Instancias de borde del cliente", + "manage-edges": "Administrar Bordes" }, "datetime": { "date-from": "Fecha desde", @@ -645,6 +802,7 @@ "add": "Agregar Panel", "assign-dashboard-to-customer": "Asignar panel(es) a cliente", "assign-dashboard-to-customer-text": "Por favor, seleccione algún panel para asignar al Cliente.", + "assign-dashboard-to-edge-title": "Asignar panel(es) a Borde", "assign-to-customer-text": "Por favor, seleccione algún cliente para asignar al(los) panel(es).", "assign-to-customer": "Asignar a cliente", "unassign-from-customer": "Desasignar del cliente", @@ -655,19 +813,27 @@ "assign-to-customers": "Asignar Panel / Paneles a Clientes", "assign-to-customers-text": "Selecciona los clientes para asignar los paneles", "unassign-from-customers": "Desasignar Panel / Paneles de clientes", - "unassign-from-customers-text": "Selecciona los clientes para desasignar los paneles", + "unassign-from-customers-text": "Selecciona los clientes para desasignar los paneles", "no-dashboards-text": "Ningún panel encontrado", "no-widgets": "Ningún widget configurado", "add-widget": "Agregar nuevo widget", "title": "Título", + "image": "Imagen de panel", + "mobile-app-settings": "Ajustes de aplicación móvil", + "mobile-order": "Órden de paneles en aplicación móvil", + "mobile-hide": "Ocultar panel en aplicación móvil", + "update-image": "Actualizar imagen de panel", + "take-screenshot": "Captura de pantalla", "select-widget-title": "Seleccionar widget", + "select-widget-value": "{{title}}: seleccionar widget", "select-widget-subtitle": "Lista de tipos de widgets disponibles", "delete": "Eliminar panel", "title-required": "Título requerido.", + "title-max-length": "Título debe ser menor de 256", "description": "Descripción", "details": "Detalles", "dashboard-details": "Detalles del panel", - "add-dashboard-text": "Agregar nuevo panel", + "add-dashboard-text": "Agregar nuevo panel", "assign-dashboards": "Asignar paneles", "assign-new-dashboard": "Asignar nuevo panel", "assign-dashboards-text": "Asignar { count, plural, 1 {1 panel} other {# paneles} } al cliente", @@ -705,8 +871,12 @@ "background-image": "Imagen de fondo", "background-size-mode": "Modo tamaño de fondo", "no-image": "No se ha seleccionado ningúna imagen", + "empty-image": "Sin imagen", "drop-image": "Suelte una imagen o haga clic para seleccionar un archivo para cargar.", + "maximum-upload-file-size": "Tamaño máximo de fichero: {{ size }}", + "cannot-upload-file": "No es posible subir el fichero", "settings": "Ajustes", + "layout-settings": "Ajustes de diseño", "columns-count": "Número de columnas", "columns-count-required": "Número de columnas requerido.", "min-columns-count-message": "Solo se permite un número mínimo de 10 columnas.", @@ -729,14 +899,23 @@ "mobile-row-height-required": "Altura de fila requerida.", "min-mobile-row-height-message": "Sólo se permiten 5 píxeles como altura mínima de fila (móvil).", "max-mobile-row-height-message": "Sólo se permiten 200 píxeles como altura máxima de fila (móvil).", + "title-settings": "Ajustes de título", "display-title": "Mostrar título del panel", - "toolbar-always-open": "Mantener la barra de herramientas abierta", "title-color": "Color del título", + "toolbar-settings": "Ajustes de la barra de herramientas", + "hide-toolbar": "Ocultar barra de herramientas", + "toolbar-always-open": "Mantener la barra de herramientas abierta", "display-dashboards-selection": "Mostrar selección de paneles", "display-entities-selection": "Mostrar selección de entidades", "display-filters": "Mostrar filtros", "display-dashboard-timewindow": "Mostrar ventana de tiempo", "display-dashboard-export": "Mostrar exportar", + "display-update-dashboard-image": "Mostrar actualización de imagen", + "dashboard-logo-settings": "Ajustes del logotipo del panel", + "display-dashboard-logo": "Mostrar logotipo en pantalla completa", + "dashboard-logo-image": "Imagen logotipo", + "advanced-settings": "Ajustes avanzados", + "dashboard-css": "CSS del panel", "import": "Importar panel", "export": "Exportar panel", "export-failed-error": "Imposible exportar panel: {{error}}", @@ -783,11 +962,15 @@ "select-state": "Seleccionar estado destino (target state)", "state-controller": "Controlador de estados", "search": "Buscar paneles", - "selected-dashboards": "{ count, plural, 1 {1 panel} other {# paneles} } seleccionados", + "selected-dashboards": "{count, plural, 1 {1 panel} other {# paneles} } seleccionados", + "home-dashboard": "Panel principal", + "home-dashboard-hide-toolbar": "Ocultar barra de herramientas en panel principal", "unassign-dashboard-from-edge-text": "Después de la confirmación, el tablero no será asignado y el borde no podrá acceder a él", - "unassign-dashboards-from-edge-text": "Después de la confirmación, se anulará la asignación de todos los paneles seleccionados y no serán accesibles por de borde", + "unassign-dashboards-from-edge-title": "Estas seguro de desasignar { count, plural, 1 {1 panel} other {# paneles} }?", + "unassign-dashboards-from-edge-text": "Después de la confirmación, se anulará la asignación de todos los paneles seleccionados y no serán accesibles por de borde", "assign-dashboard-to-edge": "Asignar panel(es) al borde", - "assign-dashboard-to-edge-text": "Por favor selecciona los paneles para asignar al borde" + "assign-dashboard-to-edge-text": "Por favor selecciona los paneles para asignar al borde", + "non-existent-dashboard-state-error": "El panel con id de estado \"{{ stateId }}\" no se ha encontrado" }, "datakey": { "settings": "Ajustes", @@ -809,7 +992,20 @@ "maximum-timeseries-or-attributes": "Máximo { count, plural, 1 {1 timeseries/atributo es permitido.} other {# timeseries/atributos son permitidos} }", "alarm-fields-required": "Campos de alarma requeridos.", "function-types": "Tipos de funciones", + "function-type": "Tipos de función", "function-types-required": "Tipos de funciones requerido.", + "alarm-keys": "Claves de Alarmas", + "alarm-key": "Clave de Slarma", + "alarm-key-functions": "Funciones de claves de Alarmas", + "alarm-key-function": "Función de clave de Alarma", + "latest-keys": "Últimas claves", + "latest-key": "Última clave", + "latest-key-functions": "Funciones de últimas claves", + "latest-key-function": "Función de última clave", + "timeseries-keys": "Claves de series de tiempo", + "timeseries-key": "Clave de series de tiempo", + "timeseries-key-functions": "Funciones de series de tiempo", + "timeseries-key-function": "Función de serie de tiempo", "maximum-function-types": "Máximo { count, plural, 1 {1 tipo de función está permitida.} other {# tipos de funciones están permitidos} }", "time-description": "hora del valor actual", "value-description": "el valor actual", @@ -820,6 +1016,7 @@ "datasource": { "type": "Típo de fuente de datos", "name": "Nombre", + "label": "Etiqueta", "add-datasource-prompt": "Por favor, agrega una fuente de datos" }, "details": { @@ -835,6 +1032,7 @@ "management": "Gestión de Dispositivos", "view-devices": "Ver Dispositivos", "device-alias": "Alias de dispositivo", + "device-type-max-length": "El tipo de dispositivo debe ser menor de 256", "aliases": "Alias de dispositivos", "no-alias-matching": "'{{alias}}' no encontrado.", "no-aliases-found": "Ningún alias encontrado.", @@ -850,6 +1048,7 @@ "remove-alias": "Eliminar alias", "add-alias": "Agregar alias", "name-starts-with": "Nombre empieza con", + "help-text": "Usar '%' de acuerdo a las necesidades: '%nombre_dispositivo_contiene%', '%nombre_dispositivo_termina_en', 'nombre_dispositivo_empieza_con'.", "device-list": "Lista de dispositivos", "use-device-name-filter": "Usar filtro", "device-list-empty": "Ningún dispositivo seleccionado.", @@ -859,6 +1058,8 @@ "assign-to-customer": "Asignar a cliente", "assign-device-to-customer": "Asignar dispositivo(s) a Cliente", "assign-device-to-customer-text": "Por favor, seleccione los dispositivos que serán asignados al cliente", + "assign-device-to-edge-title": "Asignar Dispositivo(s) a Borde", + "assign-device-to-edge-text": "Selecciona los dispositivos a asignar al Borde", "make-public": "Hacer dispositivo público", "make-private": "Hacer dispositivo privado", "no-devices-text": "Ningún dispositivo encontrado", @@ -874,6 +1075,9 @@ "unassign-from-customer": "Desasignar del cliente", "unassign-devices": "Desasignar dispositivos", "unassign-devices-action-title": "Desasignar { count, plural, 1 {1 dispositivo} other {# dispositivos} } del cliente", + "unassign-device-from-edge-title": "¿Está seguro de que desea desasignar el dispositivo '{{deviceName}}'?", + "unassign-device-from-edge-text": "Después de la confirmación, el dispositivo no será asignado y el borde no podrá acceder a él", + "unassign-devices-from-edge": "Desasignar dispositivos del Borde", "assign-new-device": "Asignar nuevo dispositivo", "make-public-device-title": "¿Hacer el dispositivo '{{deviceName}}' público?", "make-public-device-text": "Tras la confirmación, el dispositivo y la información relacionada serán públicos y podrá ser accesible por otros.", @@ -891,18 +1095,51 @@ "unassign-devices-title": "¿Desasignar { count, plural, 1 {1 dispositivo} other {# dispositivos} }?", "unassign-devices-text": "Tras la confirmación, los dispositivos seleccionados serán desasignados y no podrán ser accedidos por el cliente.", "device-credentials": "Credenciales del dispositivo", - "credentials-type": "Tipo de credencial", + "loading-device-credentials": "Cargando credenciales del dispositivo...", + "credentials-type": "Tipo de credenciales", "access-token": "Tóken de acceso", - "access-token-required": "Access token requerido.", - "access-token-invalid": "Access token debe tener entre 1 a 32 caracteres.", + "access-token-required": "Tóken de acceso requerido.", + "access-token-invalid": "Tóken de acceso debe tener entre 1 a 32 caracteres.", + "certificate-pem-format": "Certificado en formato PEM", + "certificate-pem-format-required": "Certificado requerido.", + "lwm2m-security-config": { + "identity": "Identidad Cliente", + "identity-required": "Identidad Cliente requerida.", + "identity-tooltip": "La identidad PSK es un identificador PSK arbitrario hasta 128 bytes, como se describe en el estándar [RFC7925].\nEl identificador PSK DEBE ser convertido a un string y después codificado en octetos usando UTF-8.", + "client-key": "Clave Cliente", + "client-key-required": "Clave Cliente requerida.", + "client-key-tooltip-prk": "La clave RPK o id DEBE estar conforme al estándar [RFC7250] y codificada a un formato Base64!", + "client-key-tooltip-psk": "La clave PSK DEBE estar conforme al estándar [RFC4279] y en formato HexDec de: 32, 64 o 128 caracteres!", + "endpoint": "Nombre Endpoint Cliente", + "endpoint-required": "Nombre Endpoint requerido.", + "client-public-key": "Clave pública Cliente", + "client-public-key-hint": "Si la clave pública está vacía, se usará el certificado de confianza", + "client-public-key-tooltip": "La clave pública X509 debe estar codificada en formato DER X509v3 y soportar exclusivamente el algoritmo EC y codificada en formato Base64!", + "mode": "Modo de Seguridad", + "client-tab": "Configuración de Seguridad del cliente", + "client-certificate": "Certificado de Cliente", + "bootstrap-tab": "Cliente Bootstrap", + "bootstrap-server": "Servidor Bootstrap", + "lwm2m-server": "Servidor LwM2M", + "client-publicKey-or-id": "Id o clave pública de cliente", + "client-publicKey-or-id-required": "Id o clave pública requerida.", + "client-publicKey-or-id-tooltip-psk": "La clave pública PSK es un identificador PSK arbitrario hasta 128 bytes, como se describe en el estándar [RFC7925].\nEl identificador PSK DEBE ser convertido a un string y después codificado en octetos usando UTF-8.", + "client-publicKey-or-id-tooltip-rpk": "La clave pública RPK o id DEBE estar conforme al estándar [RFC7250] y codificada a un formato Base64!", + "client-publicKey-or-id-tooltip-x509": "La clave pública X509 debe estar codificada en formato DER X509v3 y soportar exclusivamente el algoritmo EC y codificada en formato Base64", + "client-secret-key": "Clave secreta de Cliente", + "client-secret-key-required": "Clave secreta requerida.", + "client-secret-key-tooltip-psk": "La clave PSK debe ser en el estándar [RFC4279] y en formato HexDec de: 32, 64 o 128 caracteres!", + "client-secret-key-tooltip-prk": "La clave RPK debe estar en formato PKCS_8 (Codificación DER, estándar [RFC5958]) y luego codificada en formato Base64!", + "client-secret-key-tooltip-x509": "La clave X509 debe estar en formato PKCS_8 (Codificación DER, estándar [RFC5958]) y luego codificada en formato Base64!" + }, "client-id": "ID Cliente", "client-id-pattern": "Contiene carácter inválido.", "user-name": "Nombre Usuario", "user-name-required": "Se requiere nombre de usuario.", "client-id-or-user-name-necessary": "El ID Cliente y/o el Nombre de usuario son necesarios", "password": "Contraseña", - "secret": "Secreta", - "secret-required": "Secreta requerida.", + "secret": "Secreto", + "secret-required": "Secreto requerido.", "device-type": "Tipo de dispositivo", "device-type-required": "Tipo de dispositivo requerido.", "select-device-type": "Seleccionar tipo de dispositivo", @@ -913,6 +1150,8 @@ "device-types": "Tipos de dispositivo", "name": "Nombre", "name-required": "El nombre es requerido.", + "name-max-length": "El nombre debe ser menor de 256", + "label-max-length": "La etiqueta debe ser menor de 256", "description": "Descripción", "label": "Etiqueta", "events": "Eventos", @@ -946,9 +1185,6 @@ "customer-to-assign-device": "Cliente al que asignar el dispositivo", "add-credentials": "Añadir credencial" }, - "assign-device-to-edge-text": "Seleccione los dispositivos para asignar al borde", - "unassign-device-from-edge-title": "¿Está seguro de que desea desasignar el dispositivo '{{deviceName}}'?", - "unassign-device-from-edge-text": "Después de la confirmación, el dispositivo no será asignado y el borde no podrá acceder a él", "unassign-devices-from-edge-title": "¿Está seguro de que desea desasignar {count, plural, 1 {1 dispositivo} other {# dispositivos} }?", "unassign-devices-from-edge-text": "Después de la confirmación, todos los dispositivos seleccionados quedarán sin asignar y el borde no podrá acceder a ellos." }, @@ -968,6 +1204,7 @@ "set-default": "Hacer perfil por defecto", "delete": "Borrar perfil de dispositivo", "copyId": "Copiar ID de perfil", + "name-max-length": "El nombre debe ser menor de 256", "new-device-profile-name": "Nombre de perfil", "new-device-profile-name-required": "Se requiere nombre de perfil.", "name": "Nombre", @@ -975,19 +1212,26 @@ "type": "Tipo de perfil", "type-required": "Se requiere tipo de perfil.", "type-default": "Por defecto", + "image": "Imagen del perfil de dispositivo", "transport-type": "Tipo de transporte", "transport-type-required": "Se requiere tipo de transporte.", "transport-type-default": "Por defecto", "transport-type-default-hint": "Soporta transportes por MQTT básico, HTTP y CoAP", "transport-type-mqtt": "MQTT", "transport-type-mqtt-hint": "Activa ajustes avanzados de transporte MQTT", + "transport-type-coap": "CoAP", + "transport-type-coap-hint": "Activa ajustes avanzados del transporte CoAP", "transport-type-lwm2m": "LWM2M", "transport-type-lwm2m-hint": "Transporte LWM2M", + "transport-type-snmp": "SNMP", + "transport-type-snmp-hint": "Configuración transporte SNMP", "description": "Descripción", "default": "Defecto", "profile-configuration": "Configuración de perfil", "transport-configuration": "Configuración de transporte", "default-rule-chain": "Cadena de reglas por defecto", + "mobile-dashboard": "Panel móvil", + "mobile-dashboard-hint": "Usado por la aplicación móvil como panel de detalle", "select-queue-hint": "Selecciona desde el desplegable o añade un nombre personalizado.", "delete-device-profile-title": "Eliminar el perfil '{{deviceProfileName}}'?", "delete-device-profile-text": "Atención, tras la confirmación el perfil y todos sus datos serán borrados e irrecuperables.", @@ -1002,18 +1246,43 @@ "mqtt-device-payload-type": "Payload de dispositivo MQTT", "mqtt-device-payload-type-json": "JSON", "mqtt-device-payload-type-proto": "Protobuf", + "mqtt-enable-compatibility-with-json-payload-format": "Activar compatibilidad con otros formatos de payload.", + "mqtt-enable-compatibility-with-json-payload-format-hint": "Si se activa, la plataforma usará un formato de payload Protobuf por defecto. Si el parseo falla, la plataforma intentará usar el formato JSON. Útil para retrocompatibilidad durante actualizaciones de firmware. Por ejemplo, si la versión inicial de firmware usa JSON y una versión posterior usa Protobuf. Durante el proceso de actualización de firmware a los dispositivos, se requiere soportar Protobuf y JSON al mismo tiempo. El modo de retrocompatibilidad introduce una pequeña degradación en el rendimiento, es recomendable desactivarlo una vez que todos los dispositivos estén actualizados.", + "mqtt-use-json-format-for-default-downlink-topics": "Usar formato JSON para los downlink", + "mqtt-use-json-format-for-default-downlink-topics-hint": "When enabled, the platform will use Json payload format to push attributes and RPC via the following topics: v1/devices/me/attributes/response/$request_id, v1/devices/me/attributes, v1/devices/me/rpc/request/$request_id, v1/devices/me/rpc/response/$request_id. This setting does not impact attribute and rpc subscriptions sent using new (v2) topics: v2/a/res/$request_id, v2/a, v2/r/req/$request_id, v2/r/res/$request_id. Where $request_id is an integer request identifier.", + "mqtt-send-ack-on-validation-exception": "Enviar PUBACK en error de validación al publicar (PUBLISH)", + "mqtt-send-ack-on-validation-exception-hint": "By default, the platform will close the MQTT session on message validation failure. When enabled, the platform will send publish acknowledgment instead of closing the session.", + "snmp-add-mapping": "Añadir mapeado SNMP", + "snmp-mapping-not-configured": "No hay mapeado OID a series de tiempo/telemetría configurado", + "snmp-timseries-or-attribute-name": "Nombre Series de tiempo/nombre atributo para mapeado", + "snmp-timseries-or-attribute-type": "Tipo Series de tiempo/nombre atributo para mapeado", + "snmp-method-pdu-type-get-request": "GetRequest", + "snmp-method-pdu-type-get-next-request": "GetNextRequest", + "snmp-oid": "OID", + "transport-device-payload-type-json": "JSON", + "transport-device-payload-type-proto": "Protobuf", "mqtt-payload-type-required": "Se requiere tipo de Payload.", + "coap-device-type": "Tipo de dispositivo CoAP", + "coap-device-payload-type": "Payload dispositivo CoAP", + "coap-device-type-required": "Se requiere tipo de dispositivo CoAP.", + "coap-device-type-default": "Por defecto", + "coap-device-type-efento": "Efento NB-IoT", "support-level-wildcards": "Se soportan los wilcards únicos [+] y multi-nivel [#].", "telemetry-topic-filter": "Filtro de topic en telemetría", "telemetry-topic-filter-required": "Se requiere filtro de topic (telemetría).", "attributes-topic-filter": "Filtro de topic en atributos", "attributes-topic-filter-required": "Se requiere filtro de topic (atributos).", - "telemetry-proto-schema": "Proto schema de telemetría", - "telemetry-proto-schema-required": "Se requiere proto schema de telemetría.", - "attributes-proto-schema": "Proto schema de atributos", - "attributes-proto-schema-required": "Se requiere proto schema de atributos.", + "telemetry-proto-schema": "Proto esquema de telemetría", + "telemetry-proto-schema-required": "Se requiere proto esquema de telemetría.", + "attributes-proto-schema": "Proto esquema de atributos", + "attributes-proto-schema-required": "Se requiere proto esquema de atributos.", + "rpc-response-proto-schema": "Proto esquema de respuesta RPC", + "rpc-response-proto-schema-required": "Se requiere proto esquema de respuesta RPC.", "rpc-response-topic-filter": "Filtro de topic de respuesta RPC", - "rpc-response-topic-filter-required": "Se requiere fitro de respuesta RPC.", + "rpc-response-topic-filter-required": "Se requiere filtro de topic respuesta RPC.", + "rpc-request-proto-schema": "Proto esquema de petición RPC", + "rpc-request-proto-schema-required": "Se requiere proto esquema de petición RPC.", + "rpc-request-proto-schema-hint": "Las peticiones RPC deben contener siempre los siguientes campos: string method = 1; int32 requestId = 2; y params = 3 para cualquier tipo de datoas.", "not-valid-pattern-topic-filter": "No es un patrón de filtro válido", "not-valid-single-character": "Uso inválido de wildcard único", "not-valid-multi-character": "Uso inválido de wildcard multi-nivel", @@ -1027,6 +1296,7 @@ "alarm-type": "Tipo de alarma", "alarm-type-required": "Se requiere tipo de alarma.", "alarm-type-unique": "El tipo de alarma, debe ser único dentro de las reglas de alarma del perfil de dispositivo.", + "alarm-type-max-length": "El tipo de alarma debe ser menor de 256", "create-alarm-pattern": "Crear alarma {{alarmType}}", "create-alarm-rules": "Crear reglas de alarma", "no-create-alarm-rules": "No hay condiciones de creación de alarma configuradas", @@ -1046,14 +1316,20 @@ "condition-duration-time-unit-required": "Se requiere una unidad de tiempo.", "advanced-settings": "Ajustes avanzados", "alarm-rule-details": "Detalles", + "alarm-rule-details-hint": "Ayuda: usa ${nombredeClave} para sustituir los valores de atributos o telemetrías usadas en la condición de la regla de alarma.", "add-alarm-rule-details": "Añadir detalles", + "alarm-rule-mobile-dashboard": "Panel Móvil", + "alarm-rule-mobile-dashboard-hint": "Usado por la aplicación móvil como panel de detalle de alarmas", + "alarm-rule-no-mobile-dashboard": "No hay panel seleccionado", "propagate-alarm": "Propagar alarma", "alarm-rule-relation-types-list": "Tipos de relación para propagar", "alarm-rule-relation-types-list-hint": "Si no está seleccionado 'propagar relaciones', las alarmas serán propagadas sin filtrar por relación.", + "propagate-alarm-to-owner": "Propagar alarma al propietario de la entidad (Cliente o Administrador)", + "propagate-alarm-to-tenant": "Propagar alarma a Administrador", "alarm-details": "Detalles de alarma", "alarm-rule-condition": "Condiciones de regla de alarma", "enter-alarm-rule-condition-prompt": "Por favor, añade una condición de alarma", - "edit-alarm-rule-condition": "Editar condición de alarma", + "edit-alarm-rule-condition": "Editar condición de alarma", "device-provisioning": "Aprovisionamiento de dispositivos", "provision-strategy": "Estrategia de aprovisionamiento", "provision-strategy-required": "Se requiere estrategia de aprovisionamiento.", @@ -1073,6 +1349,7 @@ "condition-type-simple": "Simple", "condition-type-duration": "Duración", "condition-during": "Durante {{during}}", + "condition-during-dynamic": "Durante \"{{ attribute }}\" ({{during}})", "condition-type-repeating": "Repetitiva", "condition-type-required": "Se requiere tipo de condición.", "condition-repeating-value": "Nº de eventos", @@ -1080,12 +1357,13 @@ "condition-repeating-value-pattern": "Nº de eventos debe ser un número entero.", "condition-repeating-value-required": "Se requiere Nº de eventos.", "condition-repeat-times": "Repetición { count, plural, 1 {1 vez} other {# veces} }", + "condition-repeat-times-dynamic": "Repetición \"{ atributo }\" ({ count, plural, 1 {1 vez} other {# veces} })", "schedule-type": "Tipo de horario", "schedule-type-required": "Tipo de horario requerido.", "schedule": "Horario", "edit-schedule": "Editar horario de alarma", "schedule-any-time": "Siempre activo", - "schedule-specific-time": "Activo en una hora específica", + "schedule-specific-time": "Activo en una hora específica", "schedule-custom": "Personalizado", "schedule-day": { "monday": "Lunes", @@ -1098,9 +1376,205 @@ }, "schedule-days": "Días", "schedule-time": "Hora", - "schedule-time-from": "De", + "schedule-time-from": "Desde", "schedule-time-to": "Hasta", - "schedule-days-of-week-required": "Debe ser seleccionado por lo menos un día de la semana." + "schedule-days-of-week-required": "Seleccionar por lo menos un día de la semana.", + "create-device-profile": "Crear un nuevo perfil de dispositivo", + "import": "Importar perfil de dispositivo", + "export": "Exportar perfil de dispositivo", + "export-failed-error": "No ha sido posible exportar el perfil de dispositivo: {{error}}", + "device-profile-file": "Archivo de perfil de dispositivo", + "invalid-device-profile-file-error": "No ha sido posible importar perfil de dispositivo: Estructura de datos inválida.", + "power-saving-mode": "Modo de ahorro de energía (PSM)", + "power-saving-mode-type": { + "default": "Usar el del perfil del dispositivo", + "psm": "Power Saving Mode (PSM)", + "drx": "Discontinuous Reception (DRX)", + "edrx": "Extended Discontinuous Reception (eDRX)" + }, + "edrx-cycle": "Ciclo eDRX", + "edrx-cycle-required": "Se requiere ciclo eDRX.", + "edrx-cycle-pattern": "El ciclo eDRX debe ser un número entero positivo.", + "edrx-cycle-min": "El mínimo de ciclo eDRX es de {{ min }} segundos.", + "paging-transmission-window": "Ventana de transmisión (Paging Transmission Window)", + "paging-transmission-window-required": "Se requiere ventana de transmisión (Paging transmission window).", + "paging-transmission-window-pattern": "Ventana de transmision debe ser un número entero positivo.", + "paging-transmission-window-min": "El mínimo de ventana de transmisión es de {{ min }} segundos.", + "psm-activity-timer": "Tiempo Actividad PSM (PSM Activity Timer)", + "psm-activity-timer-required": "Se requiere el tiempo de actividad PSM.", + "psm-activity-timer-pattern": "Tiempo de actividad PSM debe ser un número entero positivo.", + "psm-activity-timer-min": "El tiempo de actividad PSM mínimo es de {{ min }} segundos.", + "lwm2m": { + "object-list": "Lista de objetos", + "object-list-empty": "No hay objetos seleccionados.", + "no-objects-found": "No se encontraron objetos.", + "no-objects-matching": "No hay objetos que coincidan con '{{object}}'.", + "model-tab": "Modelo LWM2M", + "add-new-instances": "Añadir nueva instancia", + "instances-list": "Lista de Instancias", + "instances-list-required": "Se requiere lista de instancias.", + "instance-id-pattern": "El id de instancia debe ser un número entero positivo.", + "instance-id-max": "El id máximo de instancia es {{max}}.", + "instance": "Instancia", + "resource-label": "#ID Nombre Recurso", + "observe-label": "Observar", + "attribute-label": "Atributo", + "telemetry-label": "Telemetría", + "edit-observe-select": "Para editar observar, selecciona telemetría o atributo", + "edit-attributes-select": "Para editar atributo, selecciona telemetría o atributo", + "no-attributes-set": "No hay atributos ajustados", + "key-name": "Nombre de clave", + "key-name-required": "Se requiere nombre de clave", + "attribute-name": "Nombre Atributo", + "attribute-name-required": "Se requiere nombre de atributo.", + "attribute-value": "Valor de atributo", + "attribute-value-required": "Se requiere valor de atributo.", + "attribute-value-pattern": "El valor del atributo debe ser un número entero positivo.", + "edit-attributes": "Edita atributos: {{ name }}", + "view-attributes": "Ver atributos: {{ name }}", + "add-attribute": "Añadir atributo", + "edit-attribute": "Editar atributo", + "view-attribute": "Ver atributos", + "remove-attribute": "Borrar atributos", + "delete-server-text": "Atención, tras la confirmación la configuración del servidor se borrará y será irrecuperable.", + "delete-server-title": "Estas seguro de borrar el servidor?", + "mode": "Configuración de seguridad", + "bootstrap-tab": "Bootstrap", + "bootstrap-server-legend": "Servidor Bootstrap (ShortId...)", + "lwm2m-server-legend": "Servidor LwM2M (ShortId...)", + "server": "Servidor", + "short-id": "Short server ID", + "short-id-tooltip": "Id corto del servidor. Usado como enlace para asociar las instancias de objetos del servidor.\nEste identificador sirve para identificar únicamente cada servidor LwM2M configurado para el cliente LwM2M.\nLos recursos DEBEN ser ajustados cuando el servidor Bootstrap tenga un valor de 'false'.\nLos valores ID:0 and ID:65535 NO DEBEN ser usados para identificar al servidor LwM2M.", + "short-id-required": "Se requiere Short server ID.", + "short-id-range": "Short server ID debe estar en un rango de 1 a 65534.", + "short-id-pattern": "Short server ID debe ser un número entero positivo.", + "lifetime": "Ciclo de vida registro de cliente (Registration Lifetime)", + "lifetime-required": "Se requiere ciclo de vida.", + "lifetime-pattern": "Ciclo de vida debe ser un número entero positivo.", + "default-min-period": "Periodo mínimo entre notificaciones (s)", + "default-min-period-tooltip": "Valor predeterminado que el cliente LwM2M debe usar para el período mínimo de una Observación en ausencia de éste parámetro incluido en una observación.", + "default-min-period-required": "Período mímino requerido.", + "default-min-period-pattern": "El período mínimo debe ser un número entero positivo.", + "notification-storing": "Grabado de notificaciones cuando esté desactivado u offline", + "binding": "Binding", + "binding-type": { + "u": "U: El cliente es alcanzable por UDP en cualquier momento.", + "m": "M: El cliente es alcanzable por MQTT en cualquier momento.", + "h": "H: El cliente es alcanzable por HTTP en cualquier momento.", + "t": "T: El cliente es alcanzable por TCP en cualquier momento.", + "s": "S: El cliente es alcanzable por SMS en cualquier momento.", + "n": "N: El cliente DEBE enviar las respuestas a las peticiones sobre el modo Non-IP (soportado desde la versión LWM2M 1.1).", + "uq": "UQ: Conexión UDP en modo de cola (no soportado desde la versión LWM2M 1.1)", + "uqs": "UQS: Conexiones UDP y SMS activas, UDP en modo cola, SMS en modo estándar (no soportado desde la versión LWM2M 1.1)", + "tq": "TQ: Conexión TCP en modo de cola (no soportado desde la versión LWM2M 1.1)", + "tqs": "TQS: Conexiones TCP y SMS activas, TCP en modo cola, SMS en modo estándar (no soportado desde la versión LWM2M 1.1)", + "sq": "SQ: Conexión SMS en modo de cola (no soportado desde la versión LWM2M 1.1)" + }, + "binding-tooltip": "This is the list in the\"binding\" resource of the LwM2M server object - /1/x/7.\nIndicates the supported binding modes in the LwM2M Client.\nThis value SHOULD be the same as the value in the “Supported Binding and Modes” resource in the Device Object (/3/0/16).\nWhile multiple transports are supported, only one transport binding can be used during the entire Transport Session.\nAs an example, when UDP and SMS are both supported, the LwM2M Client and the LwM2M Server can choose to communicate either over UDP or SMS during the entire Transport Session.", + "bootstrap-server": "Servidor Bootstrap", + "lwm2m-server": "Servidor LwM2M", + "include-bootstrap-server": "Incluir actualizaciónes del servidor Bootstrap", + "bootstrap-update-title": "Ya has configurado un servidor Bootstrap. Estás seguro de que quieres excluir las actualizaciones?", + "bootstrap-update-text": "Atención, tras la confirmación la configuración del servidor Bootstrap será irrecuperable.", + "server-host": "Host", + "server-host-required": "Se requiere Host.", + "server-port": "Puerto", + "server-port-required": "Se requiere Puerto.", + "server-port-pattern": "El puerto debe ser un número entero positivo.", + "server-port-range": "El puerto debe comprender en el rango 1 a 65535.", + "server-public-key": "Clave Pública del Servidor", + "server-public-key-required": "Se requiere la Clave Pública del servidor.", + "client-hold-off-time": "Tiempo de espera (Hold Off Time)", + "client-hold-off-time-required": "Se requiere tiempo de espera.", + "client-hold-off-time-pattern": "El tiempo de espera debe ser un número entero positivo.", + "client-hold-off-time-tooltip": "El tiempo de espera se usa sólamente con un servidor Bootstrap", + "account-after-timeout": "Cuenta tras el tiempo de espera", + "account-after-timeout-required": "Se requiere Cuenta tras el tiempo de espera.", + "account-after-timeout-pattern": "Cuenta tras el tiempo de espera debe ser un número entero positivo.", + "account-after-timeout-tooltip": "Bootstrap-Server Account after the timeout value given by this resource.", + "server-type": "Tipo de servidor", + "add-new-server-title": "Añadir nueva configuración", + "add-server-config": "Añadir configuración de servidor", + "add-lwm2m-server-config": "Añadir Servidor LwM2M", + "no-config-servers": "No hay servidores configurados", + "others-tab": "Otros ajustes", + "client-strategy": "Estrategia del cliente en la conexión", + "client-strategy-label": "Estrategia", + "client-strategy-only-observe": "Realizar un request para observar al cliente tras la conexión inicial", + "client-strategy-read-all": "Leer todos los recursos y realizar un request para observar al cliente tras el registro", + "fw-update": "Actualización de Firmware", + "fw-update-strategy": "Estrategia de actualización de Firmware", + "fw-update-strategy-data": "Enviar actualización de firmware como un fichero binario usando el Objeto 19 y el Recurso 0 (Data)", + "fw-update-strategy-package": "Enviar actualización de firmware como un fichero binario usando el Objeto 5 y el Recurso 0 (Package)", + "fw-update-strategy-package-uri": "Auto-generar una URL CoAP única para la descarga del paquete y enviarla usando el Objeto 5 y el Recurso 1 (Package URI)", + "sw-update": "Actualización de Software", + "sw-update-strategy": "Estrategia de Actualización de Software", + "sw-update-strategy-package": "Enviar como un fichero binario usando el Objeto 9 y el Recurso 2 (Package)", + "sw-update-strategy-package-uri": "Auto-generar una URL CoAP única para la descarga del paquete y enviarla usando el Objeto 9 y el Recurso 3 (Package URI)", + "fw-update-resource": "Recurso CoAP Actualización de Firmware", + "fw-update-resource-required": "Se requiere el Recurso CoAP Actualización de Firmware.", + "sw-update-resource": "Recurso CoAP Actualización de Software", + "sw-update-resource-required": "Se requiere el Recurso CoAP Actualización de Software.", + "config-json-tab": "Configuracion Json Perfil de dispositivo", + "attributes-name": { + "min-period": "Período mínimo", + "max-period": "Período máximo", + "greater-than": "Mayor que", + "less-than": "Menor que", + "step": "Paso", + "min-evaluation-period": "Período mínimo de evaluación", + "max-evaluation-period": "Período máximo de evaluación" + }, + "composite-operations-support": "Soporta operaciones Lectura/Escritura/Observación Compuestas" + }, + "snmp": { + "add-communication-config": "Añadir configuración de comunicaciones", + "add-mapping": "Añadir mapeado", + "authentication-passphrase": "Frase de contraseña", + "authentication-passphrase-required": "Se requiere frase de contraseña.", + "authentication-protocol": "Protocolo de autenticación", + "authentication-protocol-required": "Se requiere Protocolo de autenticación.", + "communication-configs": "Configuracion de comunicaciones", + "community": "Community", + "community-required": "Se requiere Community.", + "context-name": "Nombre de contexto", + "data-key": "Clave de datos", + "data-key-required": "Se requiere clave de datos.", + "data-type": "Tipo de datos", + "data-type-required": "Se requiere tipo de datos.", + "engine-id": "Engine ID", + "host": "Host", + "host-required": "Se requiere Host.", + "oid": "OID", + "oid-pattern": "Formato OID inválido.", + "oid-required": "Se requiere OID.", + "please-add-communication-config": "Por favor, añadir configuración de comunicación", + "please-add-mapping-config": "Por favor, añadir configuración de mapeado", + "port": "Puerto", + "port-format": "Formato de puerto inválido.", + "port-required": "Se requiere puerto.", + "privacy-passphrase": "Frase de clave de privacidad", + "privacy-passphrase-required": "Se requiere Frase de clave de privacidad.", + "privacy-protocol": "Protocolo privacidad", + "privacy-protocol-required": "Se requiere Protocolo privacidad.", + "protocol-version": "Versión protocolo", + "protocol-version-required": "Se requiere versión protocolo.", + "querying-frequency": "Frecuencia de peticiones, ms", + "querying-frequency-invalid-format": "Frecuencia de peticiones debe ser un número entero positivo.", + "querying-frequency-required": "Se requiere frecuencia de peticiones.", + "retries": "Reintentos", + "retries-invalid-format": "Reintentos debe ser un número entero positivo.", + "retries-required": "Se requiere reintentos.", + "scope": "Alcance", + "scope-required": "Se requiere alcance.", + "security-name": "Nombre seguridad", + "security-name-required": "Se requiere Nombre seguridad.", + "timeout-ms": "Timeout, ms", + "timeout-ms-invalid-format": "Timeout debe ser un número entero positivo.", + "timeout-ms-required": "Se requiere timeout.", + "user-name": "Usuario", + "user-name-required": "Se requiere usuario." + } }, "dialog": { "close": "Cerrar diálogo" @@ -1113,6 +1587,9 @@ "edge": "Borde", "edge-instances": "Instancias de Borde", "edge-file": "Archivo de borde", + "name-max-length": "El nombre debe ser menor de 256", + "label-max-length": "La etiqueta debe ser menor de 256", + "type-max-length": "El tipo debe ser menor de 256", "management": "Gestión de bordes", "no-edges-matching": "No se encontraron bordes que coincidan con '{{entity}}'", "add": "Agregar borde", @@ -1125,7 +1602,7 @@ "delete-edges-title": "¿Está seguro de que desea edge {count, plural, 1 {1 borde} other {# bordes} }?", "delete-edges-text": "Tenga cuidado, después de la confirmación se eliminarán todos los bordes seleccionados y todos los datos relacionados se volverán irrecuperables", "name": "Nombre", - "name-starts-with": "Edge name starts with", + "name-starts-with": "Nombre de Borde comienza con", "name-required": "Se requiere nombre", "description": "Descripción", "details": "Detalles", @@ -1133,8 +1610,8 @@ "copy-id": "Copiar ID de borde", "id-copied-message": "El ID de borde se ha copiado al portapapeles", "sync": "Sinc Edge", - "edge-required": "Edge required", - "edge-type": "Type de la bordure", + "edge-required": "Borde Requerido", + "edge-type": "Tipo de Borde", "edge-type-required": "El tipo de borde es requerido.", "event-action": "Información de la entidad", "entity-id": "ID de entidad", @@ -1155,7 +1632,7 @@ "make-public-edge-title": "¿Estás seguro de que quieres hacer público el edge '{{edgeName}}'?", "make-public-edge-text": "Después de la confirmación, el borde y todos sus datos serán públicos y accesibles para otros", "make-private": "Hacer que edge sea privado", - "public": "Public", + "public": "Público", "make-private-edge-title": "¿Está seguro de que desea que el borde '{{edgeName}}' sea privado?", "make-private-edge-text": "Después de la confirmación, el borde y todos sus datos se harán privados y otros no podrán acceder a ellos", "import": "Importar borde", @@ -1198,40 +1675,40 @@ "widget-datasource-error": "Este widget solo admite la fuente de datos de la entidad EDGE" }, "edge-event": { - "type-dashboard": "Dashboard", - "type-asset": "Asset", - "type-device": "Device", - "type-device-profile": "Device Profile", - "type-entity-view": "Entity View", - "type-alarm": "Alarm", - "type-rule-chain": "Rule Chain", - "type-rule-chain-metadata": "Rule Chain Metadata", - "type-edge": "Edge", - "type-user": "User", - "type-customer": "Customer", - "type-relation": "Relation", - "type-widgets-bundle": "Widgets Bundle", - "type-widgets-type": "Widgets Type", - "type-admin-settings": "Admin Settings", - "action-type-added": "Added", - "action-type-deleted": "Deleted", - "action-type-updated": "Updated", - "action-type-post-attributes": "Post Attributes", - "action-type-attributes-updated": "Attributes Updated", - "action-type-attributes-deleted": "Attributes Deleted", - "action-type-timeseries-updated": "Timeseries Updated", - "action-type-credentials-updated": "Credentials Updated", - "action-type-assigned-to-customer": "Assigned to Customer", - "action-type-unassigned-from-customer": "Unassigned from Customer", - "action-type-relation-add-or-update": "Relation Add or Update", - "action-type-relation-deleted": "Relation Deleted", - "action-type-rpc-call": "RPC Call", - "action-type-alarm-ack": "Alarm Ack", - "action-type-alarm-clear": "Alarm Clear", - "action-type-assigned-to-edge": "Assigned to Edge", - "action-type-unassigned-from-edge": "Unassigned from Edge", - "action-type-credentials-request": "Credentials Request", - "action-type-entity-merge-request": "Entity Merge Request" + "type-dashboard": "Panel", + "type-asset": "Activo", + "type-device": "Dispositivo", + "type-device-profile": "Perfil de dispositivo", + "type-entity-view": "Vista de entidad", + "type-alarm": "Alarma", + "type-rule-chain": "Cadena de reglas", + "type-rule-chain-metadata": "Metadatos de Cadena de Reglas", + "type-edge": "Borde", + "type-user": "Usuario", + "type-customer": "Cliente", + "type-relation": "Relación", + "type-widgets-bundle": "Paquete de Widgets", + "type-widgets-type": "Tipos de Widgets", + "type-admin-settings": "Ajustes de Administración", + "action-type-added": "Añadido", + "action-type-deleted": "Borrado", + "action-type-updated": "Actualizado", + "action-type-post-attributes": "Envío de Atributos", + "action-type-attributes-updated": "Atributos Actualizados", + "action-type-attributes-deleted": "Atributos Borrados", + "action-type-timeseries-updated": "Series de tiempo Actualizadas", + "action-type-credentials-updated": "Credenciales Actualizadas", + "action-type-assigned-to-customer": "Asignado a Cliente", + "action-type-unassigned-from-customer": "Desasignado de Cliente", + "action-type-relation-add-or-update": "Añadir o Actualizar relación", + "action-type-relation-deleted": "Relación borrada", + "action-type-rpc-call": "Llamada RPC", + "action-type-alarm-ack": "ACK Alarma", + "action-type-alarm-clear": "Borrado de Alarma", + "action-type-assigned-to-edge": "Asignado a Borde", + "action-type-unassigned-from-edge": "Desasignado de Borde", + "action-type-credentials-request": "Obtención de Credenciales", + "action-type-entity-merge-request": "Unión de entidades" }, "error": { "unable-to-connect": "Imposible conectar con el servidor! Por favor, revise su conexión a internet.", @@ -1241,6 +1718,7 @@ "entity": { "entity": "Entidad", "entities": "Entidades", + "entities-count": "Nº de entidades", "aliases": "Alias de entidad", "entity-alias": "Alias de entidad", "unable-delete-entity-alias-title": "No ha sido posible eliminar el alias de entidad", @@ -1261,6 +1739,7 @@ "no-entities-matching": "No se han encontrado entidades que coincidan con '{{entity}}' .", "no-entity-types-matching": "No se han encontrado tipos de entidad que coincidan con '{{entityType}}' .", "name-starts-with": "Nombre empieza con", + "help-text": "Usar el símbolo '%' de acuerdo a las necesidades: '%entity_name_contains%', '%entity_name_ends', 'entity_starts_with'.", "use-entity-name-filter": "Usar filtro", "entity-list-empty": "No hay entidades seleccionadas.", "entity-type-list-empty": "No hay tipos de entidad seleccionados.", @@ -1350,7 +1829,9 @@ "type-edge": "Borde", "type-edges": "Bordes", "list-of-edges": "{count, plural, 1 {Un borde} other {Lista de # bordes} }", - "edge-name-starts-with": "Bordes cuyos nombres comienzan con '{{prefijo}}'" + "edge-name-starts-with": "Bordes cuyos nombres comienzan con '{{prefijo}}'", + "type-tb-resource": "Recurso", + "type-ota-package": "Paquete OTA" }, "entity-field": { "created-time": "Hora de creación", @@ -1392,6 +1873,7 @@ "remove-alias": "Borrar alias de la vista de entidad", "add-alias": "Añadir alias a la vista de entidad", "name-starts-with": "Nombre de vista de entidad comienza con", + "help-text": "Usar el símbolo '%' de acuerdo a las necesidades: '%entity-view_name_contains%', '%entity-view_name_ends', 'entity-view_starts_with'.", "entity-view-list": "Lista de vistas de entidad", "use-entity-view-name-filter": "Usar el filtro", "entity-view-list-empty": "No hay vistas de entidad seleccionadas.", @@ -1402,6 +1884,7 @@ "assign-to-customer": "Asignar a cliente", "assign-entity-view-to-customer": "Asignar vista de entidad a cliente", "assign-entity-view-to-customer-text": "Por favor, seleccione las vistas de entidad para asignar al cliente", + "assign-entity-view-to-edge-title": "Asignar vista(s) de entidad a Borde", "no-entity-views-text": "No se encontraron vistas de entidad", "assign-to-customer-text": "Por favor, seleccione el cliente para asignar la vista de entidad", "entity-view-details": "Detalles de la vista de entidad", @@ -1435,6 +1918,8 @@ "created-time": "Fecha de creación", "name": "Nombre", "name-required": "Nombre Requerido.", + "name-max-length": "Nombre debe ser menor de 256", + "type-max-length": "Tipo de vista de entidad debe ser menor de 256", "description": "Descripción", "events": "Eventos", "details": "Detalles", @@ -1464,12 +1949,12 @@ "attributes-propagation-hint": "La vista de entidad copiará automáticamente los atributos especificados de la entidad de destino cada vez que guarde o actualice esta vista de entidad. Por razones de rendimiento, los atributos de entidad objetivo no se propagan a la vista de entidad en cada cambio de atributo. Puede habilitar la propagación automática configurando el nodo de la regla \"copiar a la vista\" en su cadena de reglas y vincular los mensajes \"Atributos de la publicación\" y \"Atributos actualizados\" al nuevo nodo de la regla.", "timeseries-data": "Datos de series temporales", "timeseries-data-hint": "Configure las claves de los datos de las series temporales de la entidad de destino que serán accesibles para la vista de la entidad. Los datos de esta serie temporal son de solo lectura.", + "search": "Buscar vistas de entidad", + "selected-entity-views": "{ count, plural, 1 {1 vista de entidad} other {# vistas de entidad} } seleccionadas", "make-public-entity-view-title": "¿Está seguro de que desea que la vista de entidad '{{entityViewName}}' sea pública?", "make-public-entity-view-text": "Tras la confirmación, la vista de la entidad y todos sus datos se harán públicos y accesibles para otros.", "make-private-entity-view-title": "¿Está seguro de que desea que la vista de entidad '{{entityViewName}}' sea privada?", "make-private-entity-view-text": "Tras la confirmación, la vista de la entidad y todos sus datos se harán privados y no serán accesibles para otros.", - "search": "Buscar vistas de entidad", - "selected-entity-views": "{ count, plural, 1 {1 vista de entidad} other {# vistas de entidad} } seleccionadas", "assign-entity-view-to-edge": "Asignar vista (s) de entidad a borde", "assign-entity-view-to-edge-text": "Seleccione las vistas de entidad para asignar al borde", "unassign-entity-view-from-edge-title": "¿Está seguro de que desea anular la asignación de la vista de entidad '{{entityViewName}}'?", @@ -1481,14 +1966,15 @@ }, "event": { "event-type": "Tipo de evento", + "events-filter": "Filtro de Eventos", + "clean-events": "Borrar Eventos", "type-error": "Error", "type-lc-event": "Ciclo de vida del evento", "type-stats": "Estadísticas", "type-debug-rule-node": "Debug", "type-debug-rule-chain": "Debug", "no-events-prompt": "Ningún evento encontrado.", - "error": "Error", - "type-edge-event": "Downlink", + "error": "Error", "alarm": "Alarma", "event-time": "Hora del evento", "server": "Servidor", @@ -1506,9 +1992,17 @@ "success": "Éxito", "failed": "Fallo", "messages-processed": "Mensajes procesados", + "min-messages-processed": "Mínimo de mensajes procesados", "errors-occurred": "Ocurrieron errores", + "min-errors-occurred": "Minimum errors occurred", + "min-value": "El valor mínimo es 0.", "all-events": "Todos", - "entity-type": "Tipo de entidad" + "has-error": "Tiene error", + "entity-id": "Id de Entidad", + "entity-type": "Tipo de entidad", + "clear-filter": "Limpiar Filtro", + "clear-request-title": "Borrar todos los eventos", + "clear-request-text": "Estás seguro de borrar todos los eventos?" }, "extension": { "extensions": "Extensiones", @@ -1668,25 +2162,25 @@ "invalid-file-error": "Fichero de extensiones inválido" }, "filter": { - "add": "Añadir filtro", - "edit": "Editar filtro", - "name": "Nombre de filtro", - "name-required": "Se requiere nombre de filtro.", - "duplicate-filter": "Ya existe un filtro con el mismo nombre.", - "filters": "Filtros", - "unable-delete-filter-title": "Error borrando filtro", - "unable-delete-filter-text": "El filtro '{{filter}}' no puede ser borrado debido a que está siendo usado actualmente por los siguientes widgets:
{{widgetsList}}", - "duplicate-filter-error": "Se ha encontrado un filtro duplicado '{{filter}}'.
Los filtros deben ser únicos en el panel.", - "missing-key-filters-error": "No se encontró la clave de filtros para el filtro '{{filter}}'.", - "filter": "Filtro", - "editable": "Editable", - "no-filters-found": "No se encontraron filtros.", - "no-filter-text": "No se ha especificado filtro", - "add-filter-prompt": "Por favos, añadir filtro", - "no-filter-matching": "'{{filter}}' no encontrado.", - "create-new-filter": "Crear un filtro nuevo!", - "filter-required": "Se requiere filtro.", - "operation": { + "add": "Añadir filtro", + "edit": "Editar filtro", + "name": "Nombre de filtro", + "name-required": "Se requiere nombre de filtro.", + "duplicate-filter": "Ya existe un filtro con el mismo nombre.", + "filters": "Filtros", + "unable-delete-filter-title": "Error borrando filtro", + "unable-delete-filter-text": "El filtro '{{filter}}' no puede ser borrado debido a que está siendo usado actualmente por los siguientes widgets:
{{widgetsList}}", + "duplicate-filter-error": "Se ha encontrado un filtro duplicado '{{filter}}'.
Los filtros deben ser únicos en el panel.", + "missing-key-filters-error": "No se encontró la clave de filtros para el filtro '{{filter}}'.", + "filter": "Filtro", + "editable": "Editable", + "no-filters-found": "No se encontraron filtros.", + "no-filter-text": "No se ha especificado filtro", + "add-filter-prompt": "Por favos, añadir filtro", + "no-filter-matching": "'{{filter}}' no encontrado.", + "create-new-filter": "Crear un filtro nuevo!", + "filter-required": "Se requiere filtro.", + "operation": { "operation": "Operación", "equal": "igual", "not-equal": "no igual", @@ -1699,7 +2193,9 @@ "greater-or-equal": "mayor o igual", "less-or-equal": "menor o igual", "and": "y", - "or": "o" + "or": "o", + "in": "en", + "not-in": "no en" }, "ignore-case": "Ignorar mayús/minus", "value": "Valor", @@ -1725,7 +2221,8 @@ "key-type": "Tipo de clave", "attribute": "Atributo", "timeseries": "Timeseries", - "entity-field": "Campo de entidad" + "entity-field": "Campo de entidad", + "constant": "Constante" }, "value-type": { "value-type": "Tipo de valor", @@ -1752,7 +2249,9 @@ "no-dynamic-value": "Sin valor dinámico", "source-attribute": "Atributo de origen", "switch-to-dynamic-value": "Cambiar a valor dinámico", - "switch-to-default-value": "Cambiar a valor por defecto" + "switch-to-default-value": "Cambiar a valor por defecto", + "inherit-owner": "Heredar de propietario", + "source-attribute-not-set": "Si los atributos de origen no están seleccionados" }, "fullscreen": { "expand": "Expandir a Pantalla Completa", @@ -1851,7 +2350,8 @@ "scroll-to-top": "Ir hacia arriba" }, "help": { - "goto-help-page": "Ir a la página de ayuda" + "goto-help-page": "Ir a la página de ayuda", + "show-help": "Mostrar ayuda" }, "home": { "home": "Principal", @@ -1861,17 +2361,31 @@ "avatar": "Avatar", "open-user-menu": "Abrir menú de usuario" }, + "file-input": { + "browse-file": "Navegar fichero", + "browse-files": "Navegar ficheros" + }, + "image-input": { + "drop-image-or": "Arrastrar y soltar una imagen o", + "drop-images-or": "Arrastrar y soltar imagenes o", + "no-images": "No hay imágenes seleccionadas", + "images": "imágenes" + }, "import": { "no-file": "Ningún archivo seleccionado", "drop-file": "Suelte un archivo JSON o haga clic para seleccionar un archivo para cargar.", + "drop-json-file-or": "Suele un archivo JSON o", "drop-file-csv": "Suelte un archivo CSV o haga clic para seleccionar un archivo para cargar.", + "drop-file-csv-or": "Suelte un archivo CSV o", "column-value": "Valor", "column-title": "Título", "column-example": "Datos de ejemplo", "column-key": "Clave de atributo/telemetría", + "credentials": "Credenciales", "csv-delimiter": "Delimitador CSV", "csv-first-line-header": "La primera línea contiene nombres de columna.", "csv-update-data": "Actualizar atributos/telemetría", + "details": "Detalles", "import-csv-number-columns-error": "Un archivo debe contener al menos dos columnas", "import-csv-invalid-format-error": "Formato de archivo inválido. Línea: '{{line}}'", "column-type": { @@ -1885,9 +2399,30 @@ "timeseries": "Series de tiempo", "entity-field": "Campo de entidad", "access-token": "Token de acceso", + "x509": "X.509", + "mqtt": { + "client-id": "Client ID MQTT", + "user-name": "Usuario MQTT", + "password": "Contraseña MQTT" + }, + "lwm2m": { + "client-endpoint": "Nombre endpoint cliente LwM2M", + "security-config-mode": "Configuración de seguridad LwM2M", + "client-identity": "Identidad cliente LwM2M", + "client-key": "Clave cliente LwM2M", + "client-cert": "Clave pública cliente LwM2M", + "bootstrap-server-security-mode": "Modo seguridad servidor Bootstrap LwM2M", + "bootstrap-server-secret-key": "Clave secreta servidor Bootstrap LwM2M", + "bootstrap-server-public-key-id": "Clave pública o id servidor Bootstrap LwM2M", + "lwm2m-server-security-mode": "Modo seguridad servidor LwM2M", + "lwm2m-server-secret-key": "Clave secreta servidor LwM2M", + "lwm2m-server-public-key-id": "Clave pública servidor LwM2M" + }, "isgateway": "Es Gateway", "activity-time-from-gateway-device": "Fecha de actividad desde el dispositivo gateway", - "description": "Descripción" + "description": "Descripción", + "routing-key": "Clave Edge", + "secret": "Secreto Edge" }, "stepper-text": { "select-file": "Seleccione un archivo", @@ -1896,7 +2431,7 @@ "creat-entities": "Creando nuevas entidades" }, "message": { - "create-entities": "Se crearon{{count}} nuevas entidades correctamente.", + "create-entities": "Se crearon {{count}} nuevas entidades correctamente.", "update-entities": "{{count}} entidades se actualizaron correctamente.", "error-entities": "Se produjo un error al crear {{count}} entidades." } @@ -1940,6 +2475,8 @@ "avg": "promedio", "total": "total", "comparison-time-ago": { + "previousInterval": "(intervalo anterior)", + "customInterval": "(intervalo personalizado)", "days": "(hace un día)", "weeks": "(hace una semana)", "months": "(hace un mes)", @@ -1951,6 +2488,7 @@ "request-password-reset": "Solicitar restablecer contraseña", "reset-password": "Restablecer contraseña", "create-password": "Crear contraseña", + "two-factor-authentication": "Two factor authentication", "passwords-mismatch-error": "¡Las contraseñas introducidas deben ser iguales!", "password-again": "Repita la contraseña de nuevo", "sign-in": "Por favor, inicie sesión", @@ -1963,9 +2501,93 @@ "new-password-again": "Repita la nueva contraseña", "password-link-sent-message": "Se ha enviado el enlace de restablecimiento de contraseña con éxito!", "email": "Email", - "login-with": "Iniciar sesión con {{name}}", + "login-with": "Login con {{name}}", "or": "o", - "error": "Error de login" + "error": "Error de Login", + "verify-your-identity": "Verify your identity", + "select-way-to-verify": "Select a way to verify", + "resend-code": "Resend code", + "resend-code-wait": "Resend code in { time, plural, 1 {1 second} other {# seconds} }", + "try-another-way": "Try another way", + "totp-auth-description": "Please enter the security code from your authenticator app.", + "totp-auth-placeholder": "Code", + "sms-auth-description": "A security code has been sent to your phone at {{contact}}.", + "sms-auth-placeholder": "SMS code", + "email-auth-description": "A security code has been sent to your email address at {{contact}}.", + "email-auth-placeholder": "Email code", + "backup-code-auth-description": "Please enter one of your backup codes.", + "backup-code-auth-placeholder": "Backup code" + }, + "markdown": { + "edit": "Editar", + "preview": "Previsualizar", + "copy-code": "Click para copiar", + "copied": "Copiado!" + }, + "ota-update": { + "add": "Añadir paquete", + "assign-firmware": "Firmware asignado", + "assign-firmware-required": "Firmware asignado requerido", + "assign-software": "Software asignado", + "assign-software-required": "Software asignado requerido", + "auto-generate-checksum": "Auto-generar checksum", + "checksum": "Checksum", + "checksum-hint": "Si el checksum está vacío, se generará automáticamente", + "checksum-algorithm": "Algoritmo checksum", + "checksum-copied-message": "El checksum del paquete se ha copiado al portapapeles", + "change-firmware": "El cambio del firmware provocará la actualización de { count, plural, 1 {1 dispositivo} other {# dispositivos} }.", + "change-software": "El cambio del software provocará la actualización de { count, plural, 1 {1 dispositivo} other {# dispositivos} }.", + "chose-compatible-device-profile": "El paquete subido, sólamente estará disponible para los dispositivos con el perfil seleccionado.", + "chose-firmware-distributed-device": "Elige el firmware que se distribuirá a los dispositivos", + "chose-software-distributed-device": "Elige el software que se distribuirá a los dispositivos", + "content-type": "Tipo de contenido", + "copy-checksum": "Copiar checksum", + "copy-direct-url": "Copiar URL directa", + "copyId": "Copiar Id de paquete", + "copied": "Copiado!", + "delete": "Borrar paquete", + "delete-ota-update-text": "Atención, tras la confirmación la actualización OTA será irrecuperable.", + "delete-ota-update-title": "Estás seguro de borrar la actualización OTA '{{title}}'?", + "delete-ota-updates-text": "Atención, tras la confirmación todas las actualizaciones OTA seleccionadas se borrarán.", + "delete-ota-updates-title": "Estás seguro de borrar { count, plural, 1 {1 Actualización OTA} other {# Actualizaciones OTA} }?", + "description": "Descripción", + "direct-url": "URL Directa", + "direct-url-copied-message": "La URL directa del paquete se ha copiado al portapapeles", + "direct-url-required": "URL Directa requerida", + "download": "Descargar paquete", + "drop-file": "Arrastra un fichero o haz click para seleccionar un fichero a subir.", + "drop-package-file-or": "Arrastrar y soltar un fichero o", + "file-name": "Nombre del fichero", + "file-size": "Tamaño del fichero", + "file-size-bytes": "Tamaño del fichero en bytes", + "idCopiedMessage": "El Id del paquete se ha copiado al portapapeles", + "no-firmware-matching": "No se ha encontrado ningún paquete de firmware OTA compatible que coincidan con '{{entity}}'.", + "no-firmware-text": "No hay aprovisionado ningún paquete de firmware OTA.", + "no-packages-text": "No se han encontrado paquetes", + "no-software-matching": "No se ha encontrado ningún paquete de software OTA compatible que coincidan con '{{entity}}'.", + "no-software-text": "No hay aprovisionado ningún paquete de software OTA.", + "ota-update": "Actualización OTA", + "ota-update-details": "Detalles de actualización OTA", + "ota-updates": "Actualizaciones OTA", + "package-type": "Tipo de paquete", + "packages-repository": "Repositorio de paquetes", + "search": "Buscar paquetes", + "selected-package": "{ count, plural, 1 {1 paquete} other {# paquetes} } selected", + "title": "Título", + "title-required": "Título requerido.", + "title-max-length": "El título debe ser menor de 256", + "types": { + "firmware": "Firmware", + "software": "Software" + }, + "upload-binary-file": "Subir fichero binario", + "use-external-url": "Usar una URL externa", + "version": "Versión", + "version-required": "Versión requerida.", + "version-tag": "Tag de Versión", + "version-tag-hint": "El tag de versión debe coincidir con la versión reportada por el dispositivo.", + "version-max-length": "Versión debe ser menor que 256", + "warning-after-save-no-edit": "Una vez que el paquete se haya subido, no se podrá modificar el título, versión, perfil de dispositivo y tipo de paquete." }, "position": { "top": "Superior", @@ -1977,7 +2599,68 @@ "profile": "Perfil", "last-login-time": "Último acceso", "change-password": "Cambiar contraseña", - "current-password": "Contraseña actual" + "current-password": "Contraseña actual", + "copy-jwt-token": "Copiar JWT", + "valid-till": "Válido hasta {{expirationData}}", + "tokenCopiedSuccessMessage": "JWT copiado al portapapeles", + "tokenCopiedWarnMessage": "JWT caducado, por favor actualiza la página." + }, + "security": { + "security": "Security", + "2fa": { + "2fa": "Two-factor authentication", + "2fa-description": "Two-factor authentication protects your account from unauthorized access. All you have to do is enter a security code when you log in.", + "authenticate-with": "You can authenticate with:", + "disable-2fa-provider-text": "Disabling {{name}} will make your account less secure", + "disable-2fa-provider-title": "Are you sure you want to disable {{name}}?", + "get-new-code": "Get new code", + "main-2fa-method": "Use as main two-factor authentication method", + "dialog": { + "activation-step-description-email": "The next time you login in, you will be prompted to enter the security code that will be sent to your email address.", + "activation-step-description-sms": "The next time you login in, you will be prompted to enter the security code that will be sent to the phone number.", + "activation-step-description-totp": "The next time you login in, you will need to provide a two-factor authentication code.", + "activation-step-label": "Activation", + "backup-code-description": "Print out the codes so you have them handy when you need to use them to log in to your account. You can use each backup code once.", + "backup-code-warn": "Once you leave this page, these codes cannot be shown again. Store them safely using the options below.", + "download-txt": "Download (txt)", + "email-step-description": "Enter an email to use as your authenticator.", + "email-step-label": "Email", + "enable-email-title": "Enable email authenticator", + "enable-sms-title": "Enable SMS authenticator", + "enable-totp-title": "Enable authenticator app", + "enter-verification-code": "Enter the 6-digit code here", + "get-backup-code-title": "Get backup code", + "next": "Next", + "scan-qr-code": "Scan this QR code with your verification app", + "send-code": "Send code", + "sms-step-description": "Enter a phone number to use as your authenticator.", + "sms-step-label": "Phone Number", + "success": "Success!", + "totp-step-description-install": "You can install apps like Google Authenticator, Authy, or Duo.", + "totp-step-description-open": "Open the authenticator app on your mobile phone.", + "totp-step-label": "Get app", + "verification-code": "6-digit code", + "verification-code-invalid": "Invalid verification code format", + "verification-code-incorrect": "Verification code is incorrect", + "verification-code-many-request": "Too many requests check verification code", + "verification-step-description": "Enter a 6-digit code we just sent to {{address}}", + "verification-step-label": "Verification" + }, + "provider": { + "email": "Email", + "email-description": "Use a security code sent to your email address to authenticate.", + "email-hint": "Authentication codes are sent via email to {{ info }}", + "sms": "SMS", + "sms-description": "Use your phone to authenticate. We'll send you a security code via SMS message when you log in.", + "sms-hint": "Authentication codes are sent by text message to {{ info }}", + "totp": "Authenticator app", + "totp-description": "Use apps like Google Authenticator, Authy, or Duo on your phone to authenticate. It will generate a security code for logging in.", + "totp-hint": "Authenticator app is set up for your account", + "backup_code": "Backup code", + "backup-code-description": "These printable one-time passcodes allow you to sign in when away from your phone, like when you’re traveling.", + "backup-code-hint": "{{ info }} single-use codes are active at this time" + } + } }, "relation": { "relations": "Relaciones", @@ -2003,6 +2686,7 @@ "delete": "Borrar relación", "relation-type": "Tipo de relación", "relation-type-required": "Tipo de relación requerido.", + "relation-type-max-length": "Tipo de relación debe ser menor de 256", "any-relation-type": "Cualquier tipo", "add": "Añadir relación", "edit": "Editar relación", @@ -2022,6 +2706,35 @@ "invalid-additional-info": "Error al analizar el fichero JSON de información adicional.", "no-relations-text": "No se encontraron relaciones" }, + "resource": { + "add": "Añadir Recurso", + "copyId": "Copiar Id de recurso", + "delete": "Borrar recurso", + "delete-resource-text": "Atención, tras la confirmación el recurso será irrecuperable.", + "delete-resource-title": "Estás seguro de borrar el recurso '{{resourceTitle}}'?", + "delete-resources-action-title": "Borrar { count, plural, 1 {1 recurso} other {# recursos} }", + "delete-resources-text": "Los recursos serán borrados, incluso si están siendo usados en los perfiles de dispositivo.", + "delete-resources-title": "Estás seguro de borrar { count, plural, 1 {1 recurso} other {# recursos} }?", + "download": "Descargar recurso", + "drop-file": "Arrastra un fichero o haz click para seleccionar un fichero a subir.", + "drop-resource-file-or": "Arrastrar y soltar un fichero o", + "empty": "El recurso está vacío", + "file-name": "Nombre de fichero", + "idCopiedMessage": "El Id de recurso ha sido copiado al portapapeles", + "no-resource-matching": "No se han encontrado recursos que coincidan con '{{widgetsBundle}}'.", + "no-resource-text": "No se encontraron recursos", + "open-widgets-bundle": "Abrir paquete de widgets", + "resource": "Recurso", + "resource-library-details": "Detalles de recurso", + "resource-type": "Tipo de recurso", + "resources-library": "Librería de recursos", + "search": "Buscar recursos", + "selected-resources": "{ count, plural, 1 {1 recurso} other {# recursos} } seleccionados", + "system": "Sistema", + "title": "Título", + "title-required": "Título requerido.", + "title-max-length": "El título debe ser menor de 256" + }, "rulechain": { "rulechain": "Cadena de Regla", "rulechains": "Cadenas de Reglas", @@ -2029,6 +2742,7 @@ "delete": "Borrar cadena de reglas", "name": "Nombre", "name-required": "Nombre requerido.", + "name-max-length": "Nombre debe ser menor de 256", "description": "Descripción", "add": "Añadir Cadena", "set-root": "Hacer la cadena de reglas Raíz", @@ -2061,14 +2775,12 @@ "search": "Buscar cadenas de reglas", "selected-rulechains": "{ count, plural, 1 {1 cadena de reglas} other {# cadenas de reglas} } seleccionadas", "open-rulechain": "Abrir cadena de reglas", - "assign-rulechains": "Asignar cadenas de reglas", "assign-new-rulechain": "Asignar nueva cadena de reglas", - "delete-rulechains": "Eliminar cadenas de reglas", - "unassign-rulechain": "Anular asignación de cadena de reglas", - "unassign-rulechains": "Anular asignación de cadenas de reglas", - "unassign-rulechain-title": "¿Está seguro de que desea desasignar la cadena de reglas '{{ruleChainName}}'?", + "edge-template-root": "Raíz de plantilla", + "assign-to-edge": "Asignar a Edge", + "edge-rulechain": "Cadena de reglas de borde", "unassign-rulechain-from-edge-text": "Después de la confirmación, la cadena de reglas quedará sin asignar y el borde no podrá acceder a ella", - "unassign-rulechains-from-edge-action-title": "Anular asignación {count, plural, 1 {1 cadena de reglas} other {# cadenas de reglas} } des bordes", + "unassign-rulechains-from-edge-title": "Estás seguro de desasignar { count, plural, 1 {1 cadena de reglas} other {# cadenas de reglas} }?", "unassign-rulechains-from-edge-text": "Después de la confirmación, todas las cadenas de reglas seleccionadas quedarán sin asignar y el borde no podrá acceder a ellas", "assign-rulechain-to-edge-title": "Asignar cadena (s) de reglas a borde", "assign-rulechain-to-edge-text": "Seleccione las cadenas de reglas para asignar al borde", @@ -2082,9 +2794,8 @@ "unset-auto-assign-to-edge": "Desmarcar asignar cadena de reglas a los bordes en la creación", "unset-auto-assign-to-edge-title": "¿Está seguro de que desea anular la asignación de la cadena de reglas de borde '{{ruleChainName}}' a los bordes en la creación?", "unset-auto-assign-to-edge-text": "Después de la confirmación, la cadena de reglas de borde ya no se asignará automáticamente a los bordes en la creación.", - "edge-template-root": "Raíz de plantilla", - "assign-to-edge": "Asignar a Edge", - "edge-rulechain": "Cadena de regla de borde" + "unassign-rulechain-title": "¿Está seguro de que desea desasignar la cadena de reglas '{{ruleChainName}}'?", + "unassign-rulechains": "Anular asignación de cadenas de reglas" }, "rulenode": { "details": "Detalles", @@ -2094,6 +2805,7 @@ "add": "Añadir nodo de reglas", "name": "Nombre", "name-required": "El nombre es requerido.", + "name-max-length": "Nombre debe ser menor de 256", "type": "Tipo", "description": "Descripción", "delete": "Eliminar nodo de reglas", @@ -2101,6 +2813,7 @@ "deselect-all-objects": "Deshacer selección de todos los nodos y conexiones", "delete-selected-objects": "Eliminar nodos y conexiones seleccionados", "delete-selected": "Eliminar seleccionado", + "create-nested-rulechain": "Crear cadena de reglas anidada", "select-all": "Seleccionar todos", "copy-selected": "Copiar seleccionado", "deselect-all": "Deshacer selección de todos", @@ -2131,6 +2844,8 @@ "type-external-details": "Interactuar con sistemas externos", "type-rule-chain": "Cadena de reglas", "type-rule-chain-details": "Reenvíar los mensajes entrantes a la cadena de reglas especificada", + "type-flow": "Flujo", + "type-flow-details": "Organiza el flujo de mensajes", "type-input": "Entrada", "type-input-details": "Entrada lógica de la Cadena de Reglas, reenvíar los mensajes entrantes al siguiente nodo de regla relacionado.", "type-unknown": "Desconocido", @@ -2154,12 +2869,89 @@ "timezone": "Zona Horaria", "select-timezone": "Seleccionar zona horaria", "no-timezones-matching": "No hay zonas horarias que coincidan con '{{timezone}}'.", - "timezone-required": "Se requiere zona horaria." + "timezone-required": "Se requiere zona horaria.", + "browser-time": "Hora del navegador" }, "queue": { - "select_name": "Selecciona el nombre de la cola", - "name": "Nombre Cola", - "name_required": "Necesario especificar el nombre de cola" + "queue-name": "Queue", + "no-queues-matching": "No se encontraron colas que coincidan con '{{queue}}'.", + "select_name": "Selecciona el nombre de la cola", + "name": "Nombre Cola", + "name_required": "Necesario especificar el nombre de cola", + "name-unique": "Queue name is not unique!", + "queue-required": "Queue is required!", + "topic-required": "Queue topic is required!", + "poll-interval-required": "Poll interval is required!", + "poll-interval-min-value": "Poll interval value can't be less then 1", + "partitions-required": "Partitions is required!", + "partitions-min-value": "Partitions value can't be less then 1", + "pack-processing-timeout-required": "Processing timeout is required", + "pack-processing-timeout-min-value": "Processing timeout value can't be less then 1", + "batch-size-required": "Batch size is required!", + "batch-size-min-value": "Batch size value can't be less then 1", + "retries-required": "Retries is required!", + "retries-min-value": "Retries value can't be negative", + "failure-percentage-required": "Failure percentage is required!", + "failure-percentage-min-value": "Failure percentage value can't be less then 0", + "failure-percentage-max-value": "Failure percentage value can't be more then 100", + "pause-between-retries-required": "Pause between retries is required!", + "pause-between-retries-min-value": "Pause between retries value can't be less then 1", + "max-pause-between-retries-required": "Max pause between retries is required!", + "max-pause-between-retries-min-value": "Max pause between retries value can't be less then 1", + "submit-strategy-type-required": "Submit strategy type is required!", + "processing-strategy-type-required": "Processing strategy type is required!", + "queues": "Queues", + "selected-queues": "{ count, plural, 1 {1 queue} other {# queues} } selected", + "delete-queue-title": "Are you sure you want to delete the queue '{{queueName}}'?", + "delete-queues-title": "Are you sure you want to delete { count, plural, 1 {1 queue} other {# queues} }?", + "delete-queue-text": "Be careful, after the confirmation the queue and all related data will become unrecoverable.", + "delete-queues-text": "After the confirmation all selected queues will be deleted and won't be accessible.", + "search": "Search queue", + "add" : "Add queue", + "details": "Queue details", + "topic": "Topic", + "submit-strategy": "Submit Strategy", + "processing-strategy": "Processing Strategy", + "poll-interval": "Poll interval", + "partitions": "Partitions", + "consumer-per-partition": "Consumer per partition", + "consumer-per-partition-hint": "Enable separate consumer(s) per each partition", + "processing-timeout": "Processing timeout, ms", + "batch-size": "Batch size", + "retries": "Retries (0 - unlimited)", + "failure-percentage": "Failure Percentage", + "pause-between-retries": "Pause between retries", + "max-pause-between-retries": "Maximal pause between retries", + "delete": "Delete queue", + "copyId": "Copy queue Id", + "idCopiedMessage": "Queue Id has been copied to clipboard", + "description": "Description", + "description-hint": "This text will be displayed in the Queue description instead of the selected strategy", + "alt-description": "Submit Strategy: {{submitStrategy}}, Processing Strategy: {{processingStrategy}}", + "strategies": { + "sequential-by-originator-label": "Sequential by originator", + "sequential-by-originator-hint": "New message for e.g. device A is not submitted until previous message for device A is acknowledged", + "sequential-by-tenant-label": "Sequential by tenant", + "sequential-by-tenant-hint": "New message for e.g tenant A is not submitted until previous message for tenant A is acknowledged", + "sequential-label": "Sequential", + "sequential-hint": "New message is not submitted until previous message is acknowledged", + "burst-label": "Burst", + "burst-hint": "All messages are submitted to the rule chains in the order they arrive", + "batch-label": "Batch", + "batch-hint": "New batch is not submitted until previous batch is acknowledged", + "skip-all-failures-label": "Skip all failures", + "skip-all-failures-hint": "Ignore all failures", + "skip-all-failures-and-timeouts-label": "Skip all failures and timeouts", + "skip-all-failures-and-timeouts-hint": "Ignore all failures and timeouts", + "retry-all-label": "Retry all", + "retry-all-hint": "Retry all messages from processing pack", + "retry-failed-label": "Retry failed", + "retry-failed-hint": "Retry all failed messages from processing pack", + "retry-timeout-label": "Retry timeout", + "retry-timeout-hint": "Retry all timed-out messages from processing pack", + "retry-failed-and-timeout-label": "Retry failed and timeout", + "retry-failed-and-timeout-hint": "Retry all failed and timed-out messages from processing pack" + } }, "tenant": { "tenant": "Propietario", @@ -2172,6 +2964,7 @@ "add-tenant-text": "Agregar nuevo propietario", "no-tenants-text": "Ningún propietario encontrado", "tenant-details": "Detalles del propietario", + "title-max-length": "Título debe ser menor de 256", "delete-tenant-title": "¿Quieres eliminar el propietario '{{tenantTitle}}'?", "delete-tenant-text": "Atención, tras la confirmación el propietario será eliminado y la información relacionada será irrecuperable.", "delete-tenants-title": "¿Quieres eliminar { count, plural, 1 {1 propietario} other {# propietarios} }?", @@ -2201,6 +2994,7 @@ "edit": "Editar perfil de propietario", "tenant-profile-details": "Detalles perfil de propietario", "no-tenant-profiles-text": "No se encontraron perfiles de propietario", + "name-max-length": "El nombre debe ser menor de 256", "search": "Buscar perfiles de propietario", "selected-tenant-profiles": "{ count, plural, 1 {1 perfil de propietario} other {# perfiles de propietario} } seleccionados", "no-tenant-profiles-matching": "No se han encontrado perfiles de propietario que coincidan con '{{entity}}'.", @@ -2223,6 +3017,12 @@ "set-default-tenant-profile-text": "Tras la confirmación, el perfil propietario será marcado por defecto y será usado por los nuevos perfiles propietarios que no tengan perfil específico.", "no-tenant-profiles-found": "No se encontraron perfiles de propietario.", "create-new-tenant-profile": "Crear un nuevo perfil!", + "create-tenant-profile": "Crear un nuevo perfil de propietario", + "import": "Importar perfil de propietario", + "export": "Exportar perfil de propietario", + "export-failed-error": "No se ha podido exportar el perfil de propietario: {{error}}", + "tenant-profile-file": "Archivo de perfil de propietario", + "invalid-tenant-profile-file-error": "No se ha podido importar el perfil de propietario: Estructura de datos inválida.", "maximum-devices": "Nº Máximo de dispositivos (0 - sin límite)", "maximum-devices-required": "Nº Máximo de dispositivos requerido.", "maximum-devices-range": "Nº Máximo de dispositivos no puede ser negativo", @@ -2241,6 +3041,12 @@ "maximum-rule-chains": "Nº Máximo de cadenas de reglas (0 - sin límite)", "maximum-rule-chains-required": "Nº Máximo de cadenas de reglas requerido.", "maximum-rule-chains-range": "Nº Máximo de cadenas de reglas no puede ser negativo", + "maximum-resources-sum-data-size": "Tamaño máximo de ficheros de recursos en bytes (0 - sin límite)", + "maximum-resources-sum-data-size-required": "Tamaño máximo de ficheros de recursos requerido.", + "maximum-resources-sum-data-size-range": "Tamaño máximo de ficheros de recursos no puede ser negativo", + "maximum-ota-packages-sum-data-size": "Tamaño máximo de paquetes OTA en bytes (0 - sin límite)", + "maximum-ota-package-sum-data-size-required": "Tamaño máximo de paquetes OTA requerido.", + "maximum-ota-package-sum-data-size-range": "Tamaño máximo de paquetes OTA no puede ser negativo", "transport-tenant-msg-rate-limit": "Tasa de mensajes de transporte por propietario.", "transport-tenant-telemetry-msg-rate-limit": "Tasa de mensajes de telemetría por propietario.", "transport-tenant-telemetry-data-points-rate-limit": "Tasa de datapoints por propietario.", @@ -2265,6 +3071,12 @@ "default-storage-ttl-days": "Días por defecto grabado TTL (0 - sin límite)", "default-storage-ttl-days-required": "Días por defecto TTL requerido.", "default-storage-ttl-days-range": "Días por defecto TTL no puede ser negativo", + "alarms-ttl-days": "Días de TTL alarmas (0 - sin límite)", + "alarms-ttl-days-required": "Días de TTL alarmas requerido", + "alarms-ttl-days-days-range": "Días de TTL alarmas no puede ser negativo", + "rpc-ttl-days": "Días TTL RPC (0 - sin límite)", + "rpc-ttl-days-required": "Días TTL RPC requerido", + "rpc-ttl-days-days-range": "Días TTL RPC no puede ser negativo", "max-rule-node-executions-per-message": "Nº Máximo de ejecuciones (cadena de reglas) por mensaje (0 - sin límite)", "max-rule-node-executions-per-message-required": "Nº Máximo de ejecuciones por mensaje requerido.", "max-rule-node-executions-per-message-range": "Nº Máximo de ejecuciones por mensaje no puede ser negativo", @@ -2273,20 +3085,47 @@ "max-emails-range": "Nº Máximo de emails no puede ser negativo", "max-sms": "Nº Máximo de mensajes SMS (0 - sin límite)", "max-sms-required": "Nº Máximo de mensajes SMS requerido.", - "max-sms-range": "Nº Máximo de mensajes SMS no puede ser negativo" + "max-sms-range": "Nº Máximo de mensajes SMS no puede ser negativo", + "max-created-alarms": "Nº Máximo de alarmas creadas (0 - sin límite)", + "max-created-alarms-required": "Nº Máximo de alarmas creadas requerido.", + "max-created-alarms-range": "Nº Máximo de alarmas creadas no puede ser negativo", + "no-queue": "No Queue configured", + "add-queue": "Add Queue", + "queues-with-count": "Queues ({{count}})" }, "timeinterval": { - "seconds-interval": "{ seconds, plural, 1 {1 segundo} other {# segundos} }", - "minutes-interval": "{ minutes, plural, 1 {1 minuto} other {# minutos} }", - "hours-interval": "{ hours, plural, 1 {1 hora} other {# horas} }", - "days-interval": "{ days, plural, 1 {1 día} other {# días} }", - "days": "Días", - "hours": "Horas", - "minutes": "Minutos", - "seconds": "Segundos", - "advanced": "Avanzado" + "seconds-interval": "{ seconds, plural, 1 {1 segundo} other {# segundos} }", + "minutes-interval": "{ minutes, plural, 1 {1 minuto} other {# minutos} }", + "hours-interval": "{ hours, plural, 1 {1 hora} other {# horas} }", + "days-interval": "{ days, plural, 1 {1 día} other {# días} }", + "days": "Días", + "hours": "Horas", + "minutes": "Minutos", + "seconds": "Segundos", + "advanced": "Avanzado", + "predefined": { + "yesterday": "Ayer", + "day-before-yesterday": "Anteayer", + "this-day-last-week": "Hoy hace una semana", + "previous-week": "Semana anterior (Dom - Sáb)", + "previous-week-iso": "Semana anterior (Lun - Dom)", + "previous-month": "Mes anterior", + "previous-year": "Año anterior", + "current-hour": "Hora actual", + "current-day": "Día actual", + "current-day-so-far": "Día actual hasta ahora", + "current-week": "Semana actual (Dom - Sáb)", + "current-week-iso": "Semana actual (Lun - Dom)", + "current-week-so-far": "Semana actual hasta hoy (Dom - Sáb)", + "current-week-iso-so-far": "Semana actual hasta hoy (Lun - Dom)", + "current-month": "Mes actual", + "current-month-so-far": "Mes actual hasta hoy", + "current-year": "Año actual", + "current-year-so-far": "Año actual hasta ahora" + } }, "timeunit": { + "milliseconds": "Milisegundos", "seconds": "Segundos", "minutes": "Minutos", "hours": "Horas", @@ -2305,7 +3144,8 @@ "date-range": "Rango de fechas", "last": "Últimos(s)", "time-period": "Período de tiempo", - "hide": "Ocultar" + "hide": "Ocultar", + "interval": "Intervalo" }, "user": { "user": "Usuario", @@ -2354,7 +3194,9 @@ "disable-account": "Deshabilitar cuenta de usuario", "enable-account": "Habilitar cuenta de usuario", "enable-account-message": "¡La cuenta de usuario se ha habilitado correctamente!", - "disable-account-message": "¡La cuenta de usuario se deshabilitó correctamente!" + "disable-account-message": "¡La cuenta de usuario se deshabilitó correctamente!", + "copyId": "Copiar Id de usuario", + "idCopiedMessage": "El Id de usuario se ha copiado al portapapeles" }, "value": { "type": "Tipo de valor", @@ -2381,6 +3223,7 @@ "widget": { "widget-library": "Bibloteca de Widgets", "widget-bundle": "Paquetes de Widgets", + "all-bundles": "Todos los paquetes", "select-widgets-bundle": "Seleccionar paquete de widgets", "management": "Gestión de Widgets", "editor": "Editor de widgets", @@ -2420,6 +3263,13 @@ "css": "CSS", "settings-schema": "Esquema de configuración", "datakey-settings-schema": "Esquema de configuración de clave de datos", + "latest-datakey-settings-schema": "Esquema de últimos valores", + "widget-settings": "Ajustes de widget", + "description": "Descripción", + "image-preview": "Imagen previsualización", + "settings-form-selector": "Selector formulario de ajustes", + "data-key-settings-form-selector": "Selector formulario de ajustes claves de datos", + "latest-data-key-settings-form-selector": "Selector formulario de últimos valores", "javascript": "Javascript", "js": "JS", "remove-widget-type-title": "¿Eliminar el tipo del widget '{{widgetName}}'?", @@ -2433,7 +3283,10 @@ "export": "Exportar widget", "no-data": "No hay datos para mostrar en widget", "data-overflow": "El widget muestra {{count}} de {{total}} entidades", - "alarm-data-overflow": "El widget muestra alarmas para {{allowedEntities}} entidades (máximo permitido) de {{totalEntities}} entidades" + "alarm-data-overflow": "El widget muestra alarmas para {{allowedEntities}} entidades (máximo permitido) de {{totalEntities}} entidades", + "search": "Buscar widget", + "filter": "Filtro tipo de widget", + "loading-widgets": "Cargando widgets..." }, "widget-action": { "header-button": "Botón de encabezado widget", @@ -2442,18 +3295,52 @@ "open-dashboard": "Navegar hacia otro panel", "custom": "Acción personalizada", "custom-pretty": "Acción personalizada (con plantilla HTML)", + "mobile-action": "Acción en dispositivo móvil", "target-dashboard-state": "Estado de panel de destino", "target-dashboard-state-required": "Se requiere estado de panel de destino", "set-entity-from-widget": "Establecer entidad desde widget", "target-dashboard": "Panel de destino", "open-right-layout": "Abrir diseño de panel (derecho)(vista móvil)", + "state-display-type": "Opciones de display de panel", + "open-normal": "Normal", "open-in-separate-dialog": "Abrir en un diálogo separado", + "open-in-popover": "Abrir en popover", "dialog-title": "Título del diálogo", "dialog-hide-dashboard-toolbar": "Ocultar barra de herramientas en el diálogo", "dialog-width": "Ancho de diálogo en porcentaje relativo al ancho del viewport", "dialog-height": "Alto de diálogo en porcentaje relativo al alto del viewport", "dialog-size-range-error": "El tamaño del diálogo debe ser entre un rango de 1 a 100", - "open-new-browser-tab": "Abrir en una nueva pestaña" + "popover-preferred-placement": "Ubicación preferida popover", + "popover-placement-top": "Superior", + "popover-placement-topLeft": "Superior izquierda", + "popover-placement-topRight": "Superior derecha", + "popover-placement-right": "Derecha", + "popover-placement-rightTop": "Derecha superior", + "popover-placement-rightBottom": "Derecha inferior", + "popover-placement-bottom": "Inferior", + "popover-placement-bottomLeft": "Inferior izquierda", + "popover-placement-bottomRight": "Inferior derecha", + "popover-placement-left": "Izquierda", + "popover-placement-leftTop": "Izquierda superior", + "popover-placement-leftBottom": "Izquierda inferior", + "popover-hide-on-click-outside": "Ocultar en click fuera del popover", + "popover-hide-dashboard-toolbar": "Ocultar caja de herramientas en popover", + "popover-width": "Ancho de popover en unidades de navegador (ej. 100px, 25vw)", + "popover-height": "Altura de popover en unidades de navegador (ej. 100px, 25vh)", + "popover-style": "Estilo de popover", + "open-new-browser-tab": "Abrir en una nueva pestaña", + "mobile": { + "action-type": "Tipo de acción móvil", + "action-type-required": "Tipo de acción móvil requerida", + "take-picture-from-gallery": "Tomar foto de galería", + "take-photo": "Tomar foto", + "map-direction": "Abrir indicaciones en mapa", + "map-location": "Abrir localización en mapa", + "scan-qr-code": "Escanear código QR", + "make-phone-call": "Hacer llamada telefónica", + "get-location": "Obtener localización del teléfono", + "take-screenshot": "Obtener captura de pantalla" + } }, "widgets-bundle": { "current": "Paquete actual", @@ -2462,6 +3349,9 @@ "delete": "Eliminar paquete de widgets", "title": "Título", "title-required": "Título requerido.", + "title-max-length": "El título debe ser menor de 256", + "description": "Descripción", + "image-preview": "Imagen previsualización", "add-widgets-bundle-text": "Agregar nuevo paquete de widgets", "no-widgets-bundles-text": "Ningún paquete de widgets encontrado", "empty": "Paquete de widgets vacío.", @@ -2483,7 +3373,8 @@ "invalid-widgets-bundle-file-error": "Imposible importar paquete de widgets: Estructura de datos inválida.", "search": "Buscar paquete de widgets", "selected-widgets-bundles": "{ count, plural, 1 {1 paquete de widgets} other {# paquetes de widgets} } seleccionados", - "open-widgets-bundle": "Abrir paquete de widgets" + "open-widgets-bundle": "Abrir paquete de widgets", + "loading-widgets-bundles": "Cargando paquete de widgets..." }, "widget-config": { "data": "Datos", @@ -2500,15 +3391,18 @@ "padding": "Relleno", "margin": "Margen", "widget-style": "Estilo de widget", + "widget-css": "CSS de widget", "title-style": "Estilo de título", "mobile-mode-settings": "Ajustes móvil.", "order": "Orden", "height": "Altura", + "mobile-hide": "Ocultar widget en modo móvil", "units": "Caracter especial a mostrar en el siguiente valor", "decimals": "Números de dígitos después de la coma", "timewindow": "Ventana de tiempo", "use-dashboard-timewindow": "Usar ventana de tiempo del Panel", "display-timewindow": "Mostrar ventana de tiempo", + "legend": "Leyenda", "display-legend": "Mostrar leyenda", "datasources": "Set de datos", "maximum-datasources": "Un máximo de { count, plural, 1 {1 set de datos es permitido.} other {# set de datos son permitidos} }", @@ -2529,15 +3423,22 @@ "action-name-required": "Nombre de accion requerido.", "action-name-not-unique": "Existe una acción con el mismo nombre.
El nombre de acción debe ser único dentro de la misma fuente de acción (origen).", "action-icon": "Icono", + "show-hide-action-using-function": "Mostrar/Ocultar acción usando función", "action-type": "Tipo", "action-type-required": "Tipo de acción requerido.", "edit-action": "Editar acción", "delete-action": "Borrar acción", "delete-action-title": "Borrar acción de widget", "delete-action-text": "Eliminar la acción de widget con el nombre '{{actionName}}'?", - "display-icon": "Mostrar icono del título", + "title-icon": "Título de icono", + "display-icon": "Mostrar título de icono", "icon-color": "Color del icono", - "icon-size": "Tamaño del icono" + "icon-size": "Tamaño del icono", + "advanced-settings": "Ajustes avanzados", + "data-settings": "Ajustes de datos", + "no-data-display-message": "\"No hay datos que mostrar\" mensaje alternativo", + "data-page-size": "Nº Máximo de entidades por origen de datos", + "settings-component-not-found": "Componente de ajustes no encontrado para el selector '{{selector}}'" }, "widget-type": { "import": "Importar tipo de widget", @@ -2548,7 +3449,146 @@ "invalid-widget-type-file-error": "No se puede importar tipo de widget: Estructura de datos del tipo de widget es inválida." }, "widgets": { + "chart": { + "common-settings": "Common settings", + "enable-stacking-mode": "Enable stacking mode", + "line-shadow-size": "Line shadow size", + "display-smooth-lines": "Display smooth (curved) lines", + "default-bar-width": "Default bar width for non-aggregated data (milliseconds)", + "bar-alignment": "Bar alignment", + "bar-alignment-left": "Left", + "bar-alignment-right": "Right", + "bar-alignment-center": "Center", + "default-font-size": "Default font size", + "default-font-color": "Default font color", + "thresholds-line-width": "Default line width for all thresholds", + "tooltip-settings": "Tooltip settings", + "show-tooltip": "Show tooltip", + "hover-individual-points": "Hover individual points", + "show-cumulative-values": "Show cumulative values in stacking mode", + "hide-zero-false-values": "Hide zero/false values from tooltip", + "tooltip-value-format-function": "Tooltip value format function", + "grid-settings": "Grid settings", + "show-vertical-lines": "Show vertical lines", + "show-horizontal-lines": "Show horizontal lines", + "grid-outline-border-width": "Grid outline/border width (px)", + "primary-color": "Primary color", + "background-color": "Background color", + "ticks-color": "Ticks color", + "xaxis-settings": "X axis settings", + "axis-title": "Axis title", + "xaxis-tick-labels-settings": "X axis tick labels settings", + "show-tick-labels": "Show axis tick labels", + "yaxis-settings": "Y axis settings", + "min-scale-value": "Minimum value on the scale", + "max-scale-value": "Maximum value on the scale", + "yaxis-tick-labels-settings": "Y axis tick labels settings", + "tick-step-size": "Step size between ticks", + "number-of-decimals": "The number of decimals to display", + "ticks-formatter-function": "Ticks formatter function", + "comparison-settings": "Comparison settings", + "enable-comparison": "Enable comparison", + "time-for-comparison": "Comparison period", + "time-for-comparison-previous-interval": "Previous interval (default)", + "time-for-comparison-days": "Day ago", + "time-for-comparison-weeks": "Week ago", + "time-for-comparison-months": "Month ago", + "time-for-comparison-years": "Year ago", + "time-for-comparison-custom-interval": "Custom interval", + "custom-interval-value": "Custom interval value (ms)", + "comparison-x-axis-settings": "Comparison X axis settings", + "axis-position": "Axis position", + "axis-position-top": "Top (default)", + "axis-position-bottom": "Bottom", + "custom-legend-settings": "Custom legend settings", + "enable-custom-legend": "Enable custom legend (this will allow you to use attribute/timeseries values in key labels)", + "key-name": "Key name", + "key-name-required": "Key name is required", + "key-type": "Key type", + "key-type-attribute": "Attribute", + "key-type-timeseries": "Timeseries", + "label-keys-list": "Keys list to use in labels", + "no-label-keys": "No keys configured", + "add-label-key": "Add new key", + "line-width": "Line width", + "color": "Color", + "data-is-hidden-by-default": "Data is hidden by default", + "disable-data-hiding": "Disable data hiding", + "remove-from-legend": "Remove datakey from legend", + "exclude-from-stacking": "Exclude from stacking(available in \"Stacking\" mode)", + "line-settings": "Line settings", + "show-line": "Show line", + "fill-line": "Fill line", + "points-settings": "Points settings", + "show-points": "Show points", + "points-line-width": "Line width of points", + "points-radius": "Radius of points", + "point-shape": "Point shape", + "point-shape-circle": "Circle", + "point-shape-cross": "Cross", + "point-shape-diamond": "Diamond", + "point-shape-square": "Square", + "point-shape-triangle": "Triangle", + "point-shape-custom": "Custom function", + "point-shape-draw-function": "Point shape draw function", + "show-separate-axis": "Show separate axis", + "axis-position-left": "Left", + "axis-position-right": "Right", + "thresholds": "Thresholds", + "no-thresholds": "No thresholds configured", + "add-threshold": "Add new threshold", + "show-values-for-comparison": "Show historical values for comparison", + "comparison-values-label": "Historical values label", + "threshold-settings": "Threshold settings", + "use-as-threshold": "Use key value as threshold", + "threshold-line-width": "Threshold line width", + "threshold-color": "Threshold color", + "common-pie-settings": "Common pie settings", + "radius": "Radius", + "inner-radius": "Inner radius", + "tilt": "Tilt", + "stroke-settings": "Stroke settings", + "width-pixels": "Width (pixels)", + "show-labels": "Show labels", + "animation-settings": "Animation settings", + "animated-pie": "Enable pie animation (experimental)", + "border-settings": "Border settings", + "border-width": "Border width", + "border-color": "Border color", + "legend-settings": "Legend settings", + "display-legend": "Display legend", + "labels-font-color": "Labels font color" + }, + "dashboard-state": { + "dashboard-state-settings": "Dashboard state settings", + "dashboard-state": "Dashboard state id", + "autofill-state-layout": "Autofill state layout height by default", + "default-margin": "Default widgets margin", + "default-background-color": "Default background color", + "sync-parent-state-params": "Sync state params with parent dashboard" + }, "date-range-navigator": { + "date-range-picker-settings": "Date range picker settings", + "hide-date-range-picker": "Hide date range picker", + "picker-one-panel": "Date range picker one panel", + "picker-auto-confirm": "Date range picker auto confirm", + "picker-show-template": "Date range picker show template", + "first-day-of-week": "First day of the week", + "interval-settings": "Interval settings", + "hide-interval": "Hide interval", + "initial-interval": "Initial interval", + "interval-hour": "Hour", + "interval-day": "Day", + "interval-week": "Week", + "interval-two-weeks": "2 weeks", + "interval-month": "Month", + "interval-three-months": "3 months", + "interval-six-months": "6 months", + "step-settings": "Step settings", + "hide-step-size": "Hide step size", + "initial-step-size": "Initial step size", + "hide-labels": "Hide labels", + "use-session-storage": "Use session storage", "localizationMap": { "Sun": "Dom.", "Mon": "Lun.", @@ -2605,6 +3645,176 @@ "Ok": "Ok" } }, + "entities-hierarchy": { + "hierarchy-data-settings": "Hierarchy data settings", + "relations-query-function": "Node relations query function", + "has-children-function": "Node has children function", + "node-state-settings": "Node state settings", + "node-opened-function": "Default node opened function", + "node-disabled-function": "Node disabled function", + "display-settings": "Display settings", + "node-icon-function": "Node icon function", + "node-text-function": "Node text function", + "sort-settings": "Sort settings", + "nodes-sort-function": "Nodes sort function" + }, + "edge": { + "display-default-title": "Display default title" + }, + "gateway": { + "general-settings": "General settings", + "widget-title": "Widget title", + "default-archive-file-name": "Default archive file name", + "device-type-for-new-gateway": "Device type for new gateway", + "messages-settings": "Messages settings", + "save-config-success-message": "Text message about successfully saved gateway configuration", + "device-name-exists-message": "Text message when device with entered name is already exists", + "gateway-title": "Gateway form", + "read-only": "Read only", + "events-title": "Gateway events form title", + "events-filter": "Events filter", + "event-key-contains": "Event key contains..." + }, + "gauge": { + "default-color": "Default color", + "radial-gauge-settings": "Radial gauge settings", + "ticks-settings": "Ticks settings", + "min-value": "Minimum value", + "max-value": "Maximum value", + "start-ticks-angle": "Start ticks angle", + "ticks-angle": "Ticks angle", + "major-ticks-count": "Major ticks count", + "major-ticks-color": "Major ticks color", + "minor-ticks-count": "Minor ticks count", + "minor-ticks-color": "Minor ticks color", + "tick-numbers-font": "Tick numbers font", + "unit-title-settings": "Unit title settings", + "show-unit-title": "Show unit title", + "unit-title": "Unit title", + "title-font": "Title text font", + "units-settings": "Units settings", + "units-font": "Units text font", + "value-box-settings": "Value box settings", + "show-value-box": "Show value box", + "value-int": "Digits count for integer part of value", + "value-font": "Value text font", + "value-box-rect-stroke-color": "Value box rectangle stroke color", + "value-box-rect-stroke-color-end": "Value box rectangle stroke color - end gradient", + "value-box-background-color": "Value box background color", + "value-box-shadow-color": "Value box shadow color", + "plate-settings": "Plate settings", + "show-plate-border": "Show plate border", + "plate-color": "Plate color", + "needle-settings": "Needle settings", + "needle-circle-size": "Needle circle size", + "needle-color": "Needle color", + "needle-color-end": "Needle color - end gradient", + "needle-color-shadow-up": "Upper half of the needle shadow color", + "needle-color-shadow-down": "Drop shadow needle color", + "highlights-settings": "Highlights settings", + "highlights-width": "Highlights width", + "highlights": "Highlights", + "highlight-from": "From", + "highlight-to": "To", + "highlight-color": "Color", + "no-highlights": "No highlights configured", + "add-highlight": "Add highlight", + "animation-settings": "Animation settings", + "enable-animation": "Enable animation", + "animation-duration": "Animation duration", + "animation-rule": "Animation rule", + "animation-linear": "Linear", + "animation-quad": "Quad", + "animation-quint": "Quint", + "animation-cycle": "Cycle", + "animation-bounce": "Bounce", + "animation-elastic": "Elastic", + "animation-dequad": "Dequad", + "animation-dequint": "Dequint", + "animation-decycle": "Decycle", + "animation-debounce": "Debounce", + "animation-delastic": "Delastic", + "linear-gauge-settings": "Linear gauge settings", + "bar-stroke-width": "Bar stroke width", + "bar-stroke-color": "Bar stroke color", + "bar-background-color": "Gauge bar background color", + "bar-background-color-end": "Bar background color - end gradient", + "progress-bar-color": "Progress bar color", + "progress-bar-color-end": "Progress bar color - end gradient", + "major-ticks-names": "Major ticks names", + "show-stroke-ticks": "Show ticks stroke", + "major-ticks-font": "Major ticks font", + "border-color": "Border color", + "border-width": "Border width", + "needle-circle-color": "Needle circle color", + "animation-target": "Animation target", + "animation-target-needle": "Needle", + "animation-target-plate": "Plate", + "common-settings": "Common gauge settings", + "gauge-type": "Gauge type", + "gauge-type-arc": "Arc", + "gauge-type-donut": "Donut", + "gauge-type-horizontal-bar": "Horizontal bar", + "gauge-type-vertical-bar": "Vertical bar", + "donut-start-angle": "Angle to start from", + "bar-settings": "Gauge bar settings", + "relative-bar-width": "Relative bar width", + "neon-glow-brightness": "Neon glow effect brightness, (0-100), 0 - disable effect", + "stripes-thickness": "Thickness of the stripes, 0 - no stripes", + "rounded-line-cap": "Display rounded line cap", + "bar-color-settings": "Bar color settings", + "use-precise-level-color-values": "Use precise color levels", + "bar-colors": "Bar colors, from lower to upper", + "color": "Color", + "no-bar-colors": "No bar colors configured", + "add-bar-color": "Add bar color", + "from": "From", + "to": "To", + "fixed-level-colors": "Bar colors using boundary values", + "gauge-title-settings": "Gauge title settings", + "show-gauge-title": "Show gauge title", + "gauge-title": "Gauge title", + "gauge-title-font": "Gauge title font", + "unit-title-and-timestamp-settings": "Unit title and timestamp settings", + "show-timestamp": "Show value timestamp", + "timestamp-format": "Timestamp format", + "label-font": "Font of label showing under value", + "value-settings": "Value settings", + "show-value": "Show value text", + "min-max-settings": "Minimum/maximum labels settings", + "show-min-max": "Show min and max values", + "min-max-font": "Font of minimum and maximum labels", + "show-ticks": "Show ticks", + "tick-width": "Tick width", + "tick-color": "Tick color", + "tick-values": "Tick values", + "no-tick-values": "No tick values configured", + "add-tick-value": "Add tick value" + }, + "gpio": { + "pin": "Pin", + "label": "Label", + "row": "Row", + "column": "Column", + "color": "Color", + "panel-settings": "Panel settings", + "background-color": "Background color", + "gpio-switches": "GPIO switches", + "no-gpio-switches": "No GPIO switches configured", + "add-gpio-switch": "Add GPIO switch", + "gpio-status-request": "GPIO status request", + "method-name": "Method name", + "method-body": "Method body", + "gpio-status-change-request": "GPIO status change request", + "parse-gpio-status-function": "Parse gpio status function", + "gpio-leds": "GPIO leds", + "no-gpio-leds": "No GPIO leds configured", + "add-gpio-led": "Add GPIO led" + }, + "html-card": { + "html": "HTML", + "css": "CSS" + }, "input-widgets": { "attribute-not-allowed": "El parámetro de atributo no se puede usar en este widget", "blocked-location": "La función de geolocalización está bloqueada en tu navegador", @@ -2649,7 +3859,570 @@ "update-successful": "Actualización exitosa", "update-attribute": "Actualizar atributo", "update-timeseries": "Actualizar series de tiempo", - "value": "Valor" + "value": "Valor", + "general-settings": "General settings", + "widget-title": "Widget title", + "claim-button-label": "Claiming button label", + "show-secret-key-field": "Show 'Secret key' input field", + "labels-settings": "Labels settings", + "show-labels": "Show labels", + "device-name-label": "Label for device name input field", + "secret-key-label": "Label for secret key input field", + "messages-settings": "Messages settings", + "claim-device-success-message": "Text message of successful device claiming", + "claim-device-not-found-message": "Text message when device not found", + "claim-device-failed-message": "Text message of failed device claiming", + "claim-device-name-required-message": "'Device name required' error message", + "claim-device-secret-key-required-message": "'Secret key required' error message", + "show-label": "Show label", + "label": "Label", + "required": "Required", + "required-error-message": "'Required' error message", + "show-result-message": "Show result message", + "integer-field-settings": "Integer field settings", + "min-value": "Min value", + "max-value": "Max value", + "double-field-settings": "Double field settings", + "text-field-settings": "Text field settings", + "min-length": "Min length", + "max-length": "Max length", + "checkbox-settings": "Checkbox settings", + "true-label": "Checked label", + "false-label": "Unchecked label", + "image-input-settings": "Image input settings", + "display-preview": "Display preview", + "display-clear-button": "Display clear button", + "display-apply-button": "Display apply button", + "display-discard-button": "Display discard button", + "datetime-field-settings": "Date/time field settings", + "display-time-input": "Display time input", + "latitude-key-name": "Latitude key name", + "longitude-key-name": "Longitude key name", + "show-get-location-button": "Show button 'Get current location'", + "use-high-accuracy": "Use high accuracy", + "location-fields-settings": "Location fields settings", + "latitude-label": "Label for latitude", + "longitude-label": "Label for longitude", + "input-fields-alignment": "Input fields alignment", + "input-fields-alignment-column": "Column (default)", + "input-fields-alignment-row": "Row", + "latitude-field-required": "Latitude field required", + "longitude-field-required": "Longitude field required", + "attribute-settings": "Attribute settings", + "widget-mode": "Widget mode", + "widget-mode-update-attribute": "Update attribute", + "widget-mode-update-timeseries": "Update timeseries", + "attribute-scope": "Attribute scope", + "attribute-scope-server": "Server attribute", + "attribute-scope-shared": "Shared attribute", + "value-required": "Value required", + "image-settings": "Image settings", + "image-format": "Image format", + "image-format-jpeg": "JPEG", + "image-format-png": "PNG", + "image-format-webp": "WEBP", + "image-quality": "Image quality that use lossy compression such as jpeg and webp", + "max-image-width": "Maximum image width", + "max-image-height": "Maximum image height", + "action-buttons": "Action buttons", + "show-action-buttons": "Show action buttons", + "update-all-values": "Update all values, not only modified", + "save-button-label": "'SAVE' button label", + "reset-button-label": "'UNDO' button label", + "group-settings": "Group settings", + "show-group-title": "Show title for group of fields, related to different entities", + "group-title": "Group title", + "fields-alignment": "Fields alignment", + "fields-alignment-row": "Row (default)", + "fields-alignment-column": "Column", + "fields-in-row": "Number of fields in the row", + "option-value": "Value (write 'null' for create empty option)", + "option-label": "Label", + "hide-input-field": "Hide input field", + "datakey-type": "Datakey type", + "datakey-type-server": "Server attribute (default)", + "datakey-type-shared": "Shared attribute", + "datakey-type-timeseries": "Timeseries", + "datakey-value-type": "Datakey value type", + "datakey-value-type-string": "String", + "datakey-value-type-double": "Double", + "datakey-value-type-integer": "Integer", + "datakey-value-type-boolean-checkbox": "Boolean (Checkbox)", + "datakey-value-type-boolean-switch": "Boolean (Switch)", + "datakey-value-type-date-time": "Date & Time", + "datakey-value-type-date": "Date", + "datakey-value-type-time": "Time", + "datakey-value-type-select": "Select", + "value-is-required": "Value is required", + "ability-to-edit-attribute": "Ability to edit attribute", + "ability-to-edit-attribute-editable": "Editable (default)", + "ability-to-edit-attribute-disabled": "Disabled", + "ability-to-edit-attribute-readonly": "Read-only", + "disable-on-datakey-name": "Disable on false value of another datakey (specify datakey name)", + "slide-toggle-settings": "Slide toggle settings", + "slide-toggle-label-position": "Slide toggle label position", + "slide-toggle-label-position-after": "After", + "slide-toggle-label-position-before": "Before", + "select-options": "Select options", + "no-select-options": "No select options configured", + "add-select-option": "Add select option", + "numeric-field-settings": "Numeric field settings", + "step-interval": "Step interval between values", + "error-messages": "Error messages", + "min-value-error-message": "'Min value' error message", + "max-value-error-message": "'Max value' error message", + "invalid-date-error-message": "'Invalid date' error message", + "icon-settings": "Icon settings", + "use-custom-icon": "Use custom icon", + "input-cell-icon": "Icon to show before input cell", + "value-conversion-settings": "Value conversion settings", + "get-value-settings": "Get value settings", + "use-get-value-function": "Use getValue function", + "get-value-function": "getValue function", + "set-value-settings": "Set value settings", + "use-set-value-function": "Use setValue function", + "set-value-function": "setValue function" + }, + "invalid-qr-code-text": "Invalid input text for QR code. Input should have a string type", + "qr-code": { + "use-qr-code-text-function": "Use QR code text function", + "qr-code-text-pattern": "QR code text pattern (for ex. '${entityName} | ${keyName} - some text.')", + "qr-code-text-pattern-required": "QR code text pattern is required.", + "qr-code-text-function": "QR code text function" + }, + "label-widget": { + "label-pattern": "Pattern", + "label-pattern-hint": "Hint: for ex. 'Text ${keyName} units.' or ${#<key index>} units'", + "label-pattern-required": "Pattern is required", + "label-position": "Position (Percentage relative to background)", + "x-pos": "X", + "y-pos": "Y", + "background-color": "Background color", + "font-settings": "Font settings", + "background-image": "Background image", + "labels": "Labels", + "no-labels": "No labels configured", + "add-label": "Add label" + }, + "navigation": { + "title": "Title", + "navigation-path": "Navigation path", + "filter-type": "Filter type", + "filter-type-all": "All items", + "filter-type-include": "Include items", + "filter-type-exclude": "Exclude items", + "items": "Items", + "enter-urls-to-filter": "Enter urls to filter..." + }, + "persistent-table": { + "rpc-id": "RPC ID", + "message-type": "Message type", + "method": "Method", + "params": "Params", + "created-time": "Created time", + "expiration-time": "Expiration time", + "retries": "Retries", + "status": "Status", + "filter": "Filter", + "refresh": "Refresh", + "add": "Add RPC request", + "details": "Details", + "delete": "Delete", + "delete-request-title": "Delete Persistent RPC request", + "delete-request-text": "Are you sure you want to delete request?", + "details-title": "Details RPC ID: ", + "additional-info": "Additional info", + "response": "Response", + "any-status": "Any status", + "rpc-status-list": "RPC status list", + "no-request-prompt": "No request to display", + "send-request": "Send request", + "add-title": "Create Persistent RPC request", + "method-error": "Method is required.", + "timeout-error": "Min timeout value is 5000 (5 seconds).", + "white-space-error": "White space is not allowed.", + "rpc-status": { + "QUEUED": "QUEUED", + "SENT": "SENT", + "DELIVERED": "DELIVERED", + "SUCCESSFUL": "SUCCESSFUL", + "TIMEOUT": "TIMEOUT", + "EXPIRED": "EXPIRED", + "FAILED": "FAILED" + }, + "rpc-search-status-all": "ALL", + "message-types": { + "false": "Two-way", + "true": "One-way" + }, + "general-settings": "General settings", + "enable-filter": "Enable filter", + "enable-sticky-header": "Display header while scrolling", + "enable-sticky-action": "Display actions column while scrolling", + "display-request-details": "Display request details", + "allow-send-request": "Allow send RPC request", + "allow-delete-request": "Allow delete request", + "columns-settings": "Columns settings", + "display-columns": "Columns to display", + "column": "Column", + "no-columns-found": "No columns found", + "no-columns-matching": "'{{column}}' not found." + }, + "rpc": { + "value-settings": "Value settings", + "initial-value": "Initial value", + "retrieve-value-settings": "Retrieve on/off value settings", + "retrieve-value-method": "Retrieve value using method", + "retrieve-value-method-none": "Don't retrieve", + "retrieve-value-method-rpc": "Call RPC get value method", + "retrieve-value-method-attribute": "Subscribe for attribute", + "retrieve-value-method-timeseries": "Subscribe for timeseries", + "attribute-value-key": "Attribute key", + "timeseries-value-key": "Timeseries key", + "get-value-method": "RPC get value method", + "parse-value-function": "Parse value function", + "update-value-settings": "Update value settings", + "set-value-method": "RPC set value method", + "convert-value-function": "Convert value function", + "rpc-settings": "RPC settings", + "request-timeout": "RPC request timeout (ms)", + "persistent-rpc-settings": "Persistent RPC settings", + "request-persistent": "RPC request persistent", + "persistent-polling-interval": "Polling interval (ms) to get persistent RPC command response", + "common-settings": "Common settings", + "switch-title": "Switch title", + "show-on-off-labels": "Show on/off labels", + "slide-toggle-label": "Slide toggle label", + "label-position": "Label position", + "label-position-before": "Before", + "label-position-after": "After", + "slider-color": "Slider color", + "slider-color-primary": "Primary", + "slider-color-accent": "Accent", + "slider-color-warn": "Warn", + "button-style": "Button style", + "button-raised": "Raised button", + "button-primary": "Primary color", + "button-background-color": "Button background color", + "button-text-color": "Button text color", + "widget-title": "Widget title", + "button-label": "Button label", + "device-attribute-scope": "Device attribute scope", + "server-attribute": "Server attribute", + "shared-attribute": "Shared attribute", + "device-attribute-parameters": "Device attribute parameters", + "is-one-way-command": "Is one way command", + "rpc-method": "RPC method", + "rpc-method-params": "RPC method params", + "show-rpc-error": "Show RPC command execution error", + "led-title": "LED title", + "led-color": "LED color", + "check-status-settings": "Check status settings", + "perform-rpc-status-check": "Perform RPC device status check", + "retrieve-led-status-value-method": "Retrieve led status value using method", + "led-status-value-attribute": "Device attribute containing led status value", + "led-status-value-timeseries": "Device timeseries containing led status value", + "check-status-method": "RPC check device status method", + "parse-led-status-value-function": "Parse led status value function", + "knob-title": "Knob title", + "min-value": "Minimum value", + "max-value": "Maximum value" + }, + "maps": { + "select-entity": "Select entity", + "select-entity-hint": "Hint: after selection click at the map to set position", + "tooltips": { + "placeMarker": "Click to place '{{entityName}}' entity", + "firstVertex": "Polygon for '{{entityName}}': click to place first point", + "firstVertex-cut": "Click to place first point", + "continueLine": "Polygon for '{{entityName}}': click to continue drawing", + "continueLine-cut": "Click to continue drawing", + "finishLine": "Click any existing marker to finish", + "finishPoly": "Polygon for '{{entityName}}': click first marker to finish and save", + "finishPoly-cut": "Click first marker to finish and save", + "finishRect": "Polygon for '{{entityName}}': click to finish and save", + "startCircle": "Circle for '{{entityName}}': click to place circle center", + "finishCircle": "Circle for '{{entityName}}': click to finish circle", + "placeCircleMarker": "Click to place circle marker" + }, + "actions": { + "finish": "Finish", + "cancel": "Cancel", + "removeLastVertex": "Remove last point" + }, + "buttonTitles": { + "drawMarkerButton": "Place entity", + "drawPolyButton": "Create polygon", + "drawLineButton": "Create polyline", + "drawCircleButton": "Create circle", + "drawRectButton": "Create rectangle", + "editButton": "Edit mode", + "dragButton": "Drag-drop mode", + "cutButton": "Cut polygon area", + "deleteButton": "Remove", + "drawCircleMarkerButton": "Create circle marker", + "rotateButton": "Rotate polygon" + }, + "map-provider-settings": "Map provider settings", + "map-provider": "Map provider", + "map-provider-google": "Google maps", + "map-provider-openstreet": "OpenStreet maps", + "map-provider-here": "HERE maps", + "map-provider-image": "Image map", + "map-provider-tencent": "Tencent maps", + "openstreet-provider": "OpenStreet map provider", + "openstreet-provider-mapnik": "OpenStreetMap.Mapnik (Default)", + "openstreet-provider-hot": "OpenStreetMap.HOT", + "openstreet-provider-esri-street": "Esri.WorldStreetMap", + "openstreet-provider-esri-topo": "Esri.WorldTopoMap", + "openstreet-provider-cartodb-positron": "CartoDB.Positron", + "openstreet-provider-cartodb-dark-matter": "CartoDB.DarkMatter", + "use-custom-provider": "Use custom provider", + "custom-provider-tile-url": "Custom provider tile URL", + "google-maps-api-key": "Google Maps API Key", + "default-map-type": "Default map type", + "google-map-type-roadmap": "Roadmap", + "google-map-type-satelite": "Satellite", + "google-map-type-hybrid": "Hybrid", + "google-map-type-terrain": "Terrain", + "map-layer": "Map layer", + "here-map-normal-day": "HERE.normalDay (Default)", + "here-map-normal-night": "HERE.normalNight", + "here-map-hybrid-day": "HERE.hybridDay", + "here-map-terrain-day": "HERE.terrainDay", + "credentials": "Credentials", + "here-app-id": "HERE app id", + "here-app-code": "HERE app code", + "tencent-maps-api-key": "Tencent Maps API Key", + "tencent-map-type-roadmap": "Roadmap", + "tencent-map-type-satelite": "Satellite", + "tencent-map-type-hybrid": "Hybrid", + "image-map-background": "Image map background", + "image-map-background-from-entity-attribute": "Take image map background from entity attribute", + "image-url-source-entity-alias": "Image URL source entity alias", + "image-url-source-entity-attribute": "Image URL source entity attribute", + "common-map-settings": "Common map settings", + "x-pos-key-name": "X position key name", + "y-pos-key-name": "Y position key name", + "latitude-key-name": "Latitude key name", + "longitude-key-name": "Longitude key name", + "default-map-zoom-level": "Default map zoom level (0 - 20)", + "default-map-center-position": "Default map center position (0,0)", + "disable-scroll-zooming": "Disable scroll zooming", + "disable-zoom-control-buttons": "Disable zoom control buttons", + "fit-map-bounds": "Fit map bounds to cover all markers", + "use-default-map-center-position": "Use default map center position", + "entities-limit": "Limit of entities to load", + "markers-settings": "Markers settings", + "marker-offset-x": "Marker X offset relative to position multiplied by marker width", + "marker-offset-y": "Marker Y offset relative to position multiplied by marker height", + "position-function": "Position conversion function, should return x,y coordinates as double from 0 to 1 each", + "draggable-marker": "Draggable marker", + "label": "Label", + "show-label": "Show label", + "use-label-function": "Use label function", + "label-pattern": "Label (pattern examples: '${entityName}', '${entityName}: (Text ${keyName} units.)' )", + "label-function": "Label function", + "tooltip": "Tooltip", + "show-tooltip": "Show tooltip", + "show-tooltip-action": "Action for displaying the tooltip", + "show-tooltip-action-click": "Show tooltip on click (Default)", + "show-tooltip-action-hover": "Show tooltip on hover", + "auto-close-tooltips": "Auto-close tooltips", + "use-tooltip-function": "Use tooltip function", + "tooltip-pattern": "Tooltip (for ex. 'Text ${keyName} units.' or Link text')", + "tooltip-function": "Tooltip function", + "tooltip-offset-x": "Tooltip X offset relative to marker anchor multiplied by marker width", + "tooltip-offset-y": "Tooltip Y offset relative to marker anchor multiplied by marker height", + "color": "Color", + "use-color-function": "Use color function", + "color-function": "Color function", + "marker-image": "Marker image", + "use-marker-image-function": "Use marker image function", + "custom-marker-image": "Custom marker image", + "custom-marker-image-size": "Custom marker image size (px)", + "marker-image-function": "Marker image function", + "marker-images": "Marker images", + "polygon-settings": "Polygon settings", + "show-polygon": "Show polygon", + "polygon-key-name": "Polygon key name", + "enable-polygon-edit": "Enable polygon edit", + "polygon-label": "Polygon label", + "show-polygon-label": "Show polygon label", + "use-polygon-label-function": "Use polygon label function", + "polygon-label-pattern": "Polygon label (pattern examples: '${entityName}', '${entityName}: (Text ${keyName} units.)' )", + "polygon-label-function": "Polygon label function", + "polygon-tooltip": "Polygon tooltip", + "show-polygon-tooltip": "Show polygon tooltip", + "auto-close-polygon-tooltips": "Auto-close polygon tooltips", + "use-polygon-tooltip-function": "Use polygon tooltip function", + "polygon-tooltip-pattern": "Tooltip (for ex. 'Text ${keyName} units.' or Link text')", + "polygon-tooltip-function": "Polygon tooltip function", + "polygon-color": "Polygon color", + "polygon-opacity": "Polygon opacity", + "use-polygon-color-function": "Use polygon color function", + "polygon-color-function": "Polygon color function", + "polygon-stroke": "Polygon stroke", + "stroke-color": "Stroke color", + "stroke-opacity": "Stroke opacity", + "stroke-weight": "Stroke weight", + "use-polygon-stroke-color-function": "Use polygon stroke color function", + "polygon-stroke-color-function": "Polygon stroke color function", + "circle-settings": "Circle settings", + "show-circle": "Show circle", + "circle-key-name": "Circle key name", + "enable-circle-edit": "Enable circle edit", + "circle-label": "Circle label", + "show-circle-label": "Show circle label", + "use-circle-label-function": "Use circle label function", + "circle-label-pattern": "Circle label (pattern examples: '${entityName}', '${entityName}: (Text ${keyName} units.)' )", + "circle-label-function": "Circle label function", + "circle-tooltip": "Circle tooltip", + "show-circle-tooltip": "Show circle tooltip", + "auto-close-circle-tooltips": "Auto-close circle tooltips", + "use-circle-tooltip-function": "Use circle tooltip function", + "circle-tooltip-pattern": "Tooltip (for ex. 'Text ${keyName} units.' or Link text')", + "circle-tooltip-function": "Circle tooltip function", + "circle-fill-color": "Circle fill color", + "circle-fill-color-opacity": "Circle fill color opacity", + "use-circle-fill-color-function": "Use circle fill color function", + "circle-fill-color-function": "Circle fill color function", + "circle-stroke": "Circle stroke", + "use-circle-stroke-color-function": "Use circle stroke color function", + "circle-stroke-color-function": "Circle stroke color function", + "markers-clustering-settings": "Markers clustering settings", + "use-map-markers-clustering": "Use map markers clustering", + "zoom-on-cluster-click": "Zoom when clicking on a cluster", + "max-cluster-zoom": "The maximum zoom level when a marker can be part of a cluster (0 - 18)", + "max-cluster-radius-pixels": "Maximum radius that a cluster will cover in pixels", + "cluster-zoom-animation": "Show animation on markers when zooming", + "show-markers-bounds-on-cluster-mouse-over": "Show the bounds of markers when mouse over a cluster", + "spiderfy-max-zoom-level": "Spiderfy at the max zoom level (to see all cluster markers)", + "load-optimization": "Load optimization", + "cluster-chunked-loading": "Use chunks for adding markers so that the page does not freeze", + "cluster-markers-lazy-load": "Use lazy load for adding markers", + "editor-settings": "Editor settings", + "enable-snapping": "Enable snapping to other vertices for precision drawing", + "init-draggable-mode": "Initialize map in draggable mode", + "hide-all-edit-buttons": "Hide all edit control buttons", + "hide-draw-buttons": "Hide draw buttons", + "hide-edit-buttons": "Hide edit buttons", + "hide-remove-button": "Hide remove button", + "route-map-settings": "Route map settings", + "trip-animation-settings": "Trip animation settings", + "normalization-step": "Normalization data step (ms)", + "tooltip-background-color": "Tooltip background color", + "tooltip-font-color": "Tooltip font color", + "tooltip-opacity": "Tooltip opacity (0-1)", + "auto-close-tooltip": "Auto-close tooltip", + "rotation-angle": "Set additional rotation angle for marker (deg)", + "path-settings": "Path settings", + "path-color": "Path color", + "use-path-color-function": "Use path color function", + "path-color-function": "Path color function", + "path-decorator": "Path decorator", + "use-path-decorator": "Use path decorator", + "decorator-symbol": "Decorator symbol", + "decorator-symbol-arrow-head": "Arrow", + "decorator-symbol-dash": "Dash", + "decorator-symbol-size": "Decorator symbol size (px)", + "use-path-decorator-custom-color": "Use path decorator custom color", + "decorator-custom-color": "Decorator custom color", + "decorator-offset": "Decorator offset", + "end-decorator-offset": "End decorator offset", + "decorator-repeat": "Decorator repeat", + "points-settings": "Points settings", + "show-points": "Show points", + "point-color": "Point color", + "point-size": "Point size (px)", + "use-point-color-function": "Use point color function", + "point-color-function": "Point color function", + "use-point-as-anchor": "Use point as anchor", + "point-as-anchor-function": "Point as anchor function", + "independent-point-tooltip": "Independent point tooltip" + }, + "markdown": { + "use-markdown-text-function": "Use markdown/HTML value function", + "markdown-text-function": "Markdown/HTML value function", + "markdown-text-pattern": "Markdown/HTML pattern (markdown or HTML with variables, for ex. '${entityName} or ${keyName} - some text.')", + "markdown-css": "Markdown/HTML CSS" + }, + "simple-card": { + "label-position": "Label position", + "label-position-left": "Left", + "label-position-top": "Top" + }, + "table": { + "common-table-settings": "Common Table Settings", + "enable-search": "Enable search", + "enable-sticky-header": "Always display header", + "enable-sticky-action": "Always display actions column", + "hidden-cell-button-display-mode": "Hidden cell button actions display mode", + "show-empty-space-hidden-action": "Show empty space instead of hidden cell button action", + "dont-reserve-space-hidden-action": "Don't reserve space for hidden action buttons", + "display-timestamp": "Display timestamp column", + "display-milliseconds": "Display timestamp milliseconds", + "display-pagination": "Display pagination", + "default-page-size": "Default page size", + "use-entity-label-tab-name": "Use entity label in tab name", + "hide-empty-lines": "Hide empty lines", + "row-style": "Row style", + "use-row-style-function": "Use row style function", + "row-style-function": "Row style function", + "cell-style": "Cell style", + "use-cell-style-function": "Use cell style function", + "cell-style-function": "Cell style function", + "cell-content": "Cell content", + "use-cell-content-function": "Use cell content function", + "cell-content-function": "Cell content function", + "show-latest-data-column": "Show latest data column", + "latest-data-column-order": "Latest data column order", + "entities-table-title": "Entities table title", + "enable-select-column-display": "Enable select columns to display", + "display-entity-name": "Display entity name column", + "entity-name-column-title": "Entity name column title", + "display-entity-label": "Display entity label column", + "entity-label-column-title": "Entity label column title", + "display-entity-type": "Display entity type column", + "default-sort-order": "Default sort order", + "column-width": "Column width (px or %)", + "default-column-visibility": "Default column visibility", + "column-visibility-visible": "Visible", + "column-visibility-hidden": "Hidden", + "column-selection-to-display": "Column selection in 'Columns to Display'", + "column-selection-to-display-enabled": "Enabled", + "column-selection-to-display-disabled": "Disabled", + "alarms-table-title": "Alarms table title", + "enable-alarms-selection": "Enable alarms selection", + "enable-alarms-search": "Enable alarms search", + "enable-alarm-filter": "Enable alarm filter", + "display-alarm-details": "Display alarm details", + "allow-alarms-ack": "Allow alarms acknowledgment", + "allow-alarms-clear": "Allow alarms clear" + }, + "value-source": { + "value-source": "Value source", + "predefined-value": "Predefined value", + "entity-attribute": "Value taken from entity attribute", + "value": "Value", + "source-entity-alias": "Source entity alias", + "source-entity-attribute": "Source entity attribute" + }, + "widget-font": { + "font-family": "Font family", + "size": "Size", + "relative-font-size": "Relative font size (percents)", + "font-style": "Style", + "font-style-normal": "Normal", + "font-style-italic": "Italic", + "font-style-oblique": "Oblique", + "font-weight": "Weight", + "font-weight-normal": "Normal", + "font-weight-bold": "Bold", + "font-weight-bolder": "Bolder", + "font-weight-lighter": "Lighter", + "color": "Color", + "shadow-color": "Shadow color" } }, "icon": { @@ -2664,6 +4437,7 @@ "row-click": "En click de fila", "polygon-click": "Clic en polígono", "marker-click": "En click de marcador", + "circle-click": "En click de círculo", "tooltip-tag-action": "Acción de la etiqueta Tooltip", "node-selected": "Clic en el nodo seleccionado", "element-click": "Clic en el elemento HTML", @@ -2672,6 +4446,6 @@ } }, "language": { - "language": "Lenguaje" + "language": "Idioma" } } From 0ba1dc6d481d5ec443e42f0f3def57a323d8f215 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20N=C3=BA=C3=B1ez?= Date: Fri, 3 Jun 2022 11:40:25 +0200 Subject: [PATCH 40/86] Add security and 2FA translations --- .../assets/locale/locale.constant-es_ES.json | 406 +++++++++--------- 1 file changed, 203 insertions(+), 203 deletions(-) diff --git a/ui-ngx/src/assets/locale/locale.constant-es_ES.json b/ui-ngx/src/assets/locale/locale.constant-es_ES.json index 578153c62f..ddc8847ce8 100644 --- a/ui-ngx/src/assets/locale/locale.constant-es_ES.json +++ b/ui-ngx/src/assets/locale/locale.constant-es_ES.json @@ -238,23 +238,23 @@ "domain-schema-mixed": "HTTP+HTTPS", "enable": "Activar ajustes OAuth2", "domains": "Dominios", - "mobile-apps": "Aplicaciones móviles", - "no-mobile-apps": "No hay aplicaciones configuradas", - "mobile-package": "Paquete de aplicación", - "mobile-package-placeholder": "Ej.: mi.ejemplo.app", - "mobile-package-hint": "Para Android: El ID único de aplicación. Para iOS: Identificador Product bundle.", - "mobile-package-unique": "El paquete de aplicación debe ser único.", - "mobile-app-secret": "Secreto de aplicación", - "invalid-mobile-app-secret": "El secreto de aplicación sólo puede contener carácteres alfanuméricos y debe tener entre 16 y 2048 carácteres de longitud.", - "copy-mobile-app-secret": "Copiar secreto de aplicación", - "add-mobile-app": "Añadir aplicación", - "delete-mobile-app": "Borrar información de aplicación", - "providers": "Proveedores", - "platform-web": "Web", - "platform-android": "Android", - "platform-ios": "iOS", - "all-platforms": "Todas las plataformas", - "allowed-platforms": "Plataformas permitidas" + "mobile-apps": "Aplicaciones móviles", + "no-mobile-apps": "No hay aplicaciones configuradas", + "mobile-package": "Paquete de aplicación", + "mobile-package-placeholder": "Ej.: mi.ejemplo.app", + "mobile-package-hint": "Para Android: El ID único de aplicación. Para iOS: Identificador Product bundle.", + "mobile-package-unique": "El paquete de aplicación debe ser único.", + "mobile-app-secret": "Secreto de aplicación", + "invalid-mobile-app-secret": "El secreto de aplicación sólo puede contener carácteres alfanuméricos y debe tener entre 16 y 2048 carácteres de longitud.", + "copy-mobile-app-secret": "Copiar secreto de aplicación", + "add-mobile-app": "Añadir aplicación", + "delete-mobile-app": "Borrar información de aplicación", + "providers": "Proveedores", + "platform-web": "Web", + "platform-android": "Android", + "platform-ios": "iOS", + "all-platforms": "Todas las plataformas", + "allowed-platforms": "Plataformas permitidas" }, "smpp-provider": { "smpp-version": "Versión SMPP", @@ -299,61 +299,61 @@ "npi-private-numbering-plan": "9 - Privado", "npi-ermes-numbering-plan": "10 - ERMES (ETSI DE/PS 3 01-3)", "npi-internet": "13 - Internet (IP)", - "npi-wap-client-id": "18 - WAP Client Id (to be defined by WAP Forum)", - "scheme-smsc": "0 - SMSC Default Alphabet (ASCII for short and long code and to GSM for toll-free)", - "scheme-ia5": "1 - IA5 (ASCII for short and long code, Latin 9 for toll-free (ISO-8859-9))", - "scheme-octet-unspecified-2": "2 - Octet Unspecified (8-bit binary)", + "npi-wap-client-id": "18 - WAP Client Id (a definir por WAP Forum)", + "scheme-smsc": "0 - Alfabeto por defecto SMSC (ASCII para códigos cortos y largos y GSM para gratuitos)", + "scheme-ia5": "1 - IA5 (ASCII para códigos cortos y largos, Latin 9 para gratuitos (ISO-8859-9))", + "scheme-octet-unspecified-2": "2 - Octetos sin especificar (binario 8-bit)", "scheme-latin-1": "3 - Latin 1 (ISO-8859-1)", - "scheme-octet-unspecified-4": "4 - Octet Unspecified (8-bit binary)", + "scheme-octet-unspecified-4": "4 - Octetos sin especificar (binario 8-bit)", "scheme-jis": "5 - JIS (X 0208-1990)", - "scheme-cyrillic": "6 - Cyrillic (ISO-8859-5)", - "scheme-latin-hebrew": "7 - Latin/Hebrew (ISO-8859-8)", + "scheme-cyrillic": "6 - Ciríllico (ISO-8859-5)", + "scheme-latin-hebrew": "7 - Latin/Hebreo (ISO-8859-8)", "scheme-ucs-utf": "8 - UCS2/UTF-16 (ISO/IEC-10646)", - "scheme-pictogram-encoding": "9 - Pictogram Encoding", - "scheme-music-codes": "10 - Music Codes (ISO-2022-JP)", - "scheme-extended-kanji-jis": "13 - Extended Kanji JIS (X 0212-1990)", - "scheme-korean-graphic-character-set": "14 - Korean Graphic Character Set (KS C 5601/KS X 1001)" + "scheme-pictogram-encoding": "9 - Codificación por Pictograma", + "scheme-music-codes": "10 - Códigos musicales (ISO-2022-JP)", + "scheme-extended-kanji-jis": "13 - Kanji extendido JIS (X 0212-1990)", + "scheme-korean-graphic-character-set": "14 - Set de carácteres Koreanos (KS C 5601/KS X 1001)" }, - "queue-select-name": "Select queue name", - "queue-name": "Name", - "queue-name-required": "Queue name is required!", - "queues": "Queues", - "queue-partitions": "Partitions", - "queue-submit-strategy": "Submit strategy", - "queue-processing-strategy": "Processing strategy", - "queue-configuration": "Queue configuration", + "queue-select-name": "Seleccionar nombre de cola", + "queue-name": "Nombre", + "queue-name-required": "Nombre de cola requerido!", + "queues": "Colas", + "queue-partitions": "Particiones", + "queue-submit-strategy": "Estrategia de envíos", + "queue-processing-strategy": "Estrategia de procesamiento", + "queue-configuration": "Configuración Cola", "2fa": { - "2fa": "Two-factor authentication", - "available-providers": "Available providers", - "issuer-name": "Issuer name", - "issuer-name-required": "Issuer name is required.", - "max-verification-failures-before-user-lockout": "Max verification failures before user lockout", - "max-verification-failures-before-user-lockout-pattern": "Max verification failures must be a positive integer.", - "number-of-checking-attempts": "Number of checking attempts", - "number-of-checking-attempts-pattern": "Number of checking attempts must be a positive integer.", - "number-of-checking-attempts-required": "Number of checking attempts is required.", - "number-of-codes": "Number of codes", - "number-of-codes-pattern": "Number of codes must be a positive integer.", - "number-of-codes-required": "Number of codes is required.", - "provider": "Provider", - "retry-verification-code-period": "Retry verification code period (sec)", - "retry-verification-code-period-pattern": "Minimal period time is 5 sec", - "retry-verification-code-period-required": "Retry verification code period is required.", - "total-allowed-time-for-verification": "Total allowed time for verification (sec)", - "total-allowed-time-for-verification-pattern": "Minimal total allowed time is 60 sec", - "total-allowed-time-for-verification-required": "Total allowed time is required.", - "use-system-two-factor-auth-settings": "Use system two factor auth settings", - "verification-code-check-rate-limit": "Verification code check rate limit", - "verification-code-lifetime": "Verification code lifetime (sec)", - "verification-code-lifetime-pattern": "Verification code lifetime must be a positive integer.", - "verification-code-lifetime-required": "Verification code lifetime is required.", - "verification-message-template": "Verification message template", - "verification-limitations": "Verification limitations", - "verification-message-template-pattern": "Verification message need to contains pattern: ${code}", - "verification-message-template-required": "Verification message template is required.", - "within-time": "Within time (sec)", - "within-time-pattern": "Time must be a positive integer.", - "within-time-required": "Time is required." + "2fa": "Autenticación de dos factores (2FA)", + "available-providers": "Proveedores disponibles", + "issuer-name": "Nombre de emisor", + "issuer-name-required": "Nombre de emisor requerido.", + "max-verification-failures-before-user-lockout": "Máximo de fallos de verificación antes de bloquear cuenta", + "max-verification-failures-before-user-lockout-pattern": "Máximo de fallos debe ser un número entero positivo.", + "number-of-checking-attempts": "Número de intentos de verificación", + "number-of-checking-attempts-pattern": "Número de intentos debe ser un número entero positivo.", + "number-of-checking-attempts-required": "Número de intentos requerido.", + "number-of-codes": "Número de códigos", + "number-of-codes-pattern": "Número de códigos debe ser un número entero positivo.", + "number-of-codes-required": "Número de códigos requerido.", + "provider": "Proveedor", + "retry-verification-code-period": "Reintentos de código de verificación (sec)", + "retry-verification-code-period-pattern": "El período mínimo es de 5 sec", + "retry-verification-code-period-required": "Reintentos requerido.", + "total-allowed-time-for-verification": "Total de tiempo permitido para verificación (sec)", + "total-allowed-time-for-verification-pattern": "El mínimo del total de tiempo perminito es de 60 sec", + "total-allowed-time-for-verification-required": "Total de tiempo requerido.", + "use-system-two-factor-auth-settings": "Usar ajustes 2FA del sistema", + "verification-code-check-rate-limit": "Límite de chequeo del código de verificación", + "verification-code-lifetime": "Tiempo de vida del código de verificación (sec)", + "verification-code-lifetime-pattern": "Tiempo de vida del código de verificación debe ser un número entero positivo.", + "verification-code-lifetime-required": "Tiempo de vida requerido.", + "verification-message-template": "Plantilla del mensaje de verificación", + "verification-limitations": "Límites de verificación", + "verification-message-template-pattern": "El mensaje de verificación debe contener el patrón: ${code}", + "verification-message-template-required": "Plantilla de mensaje de verificación requerida.", + "within-time": "Rango de tiempo (sec)", + "within-time-pattern": "Tiempo debe ser un número entero positivo.", + "within-time-required": "Tiempo requerido." } }, "alarm": { @@ -2401,22 +2401,22 @@ "access-token": "Token de acceso", "x509": "X.509", "mqtt": { - "client-id": "Client ID MQTT", - "user-name": "Usuario MQTT", - "password": "Contraseña MQTT" + "client-id": "Client ID MQTT", + "user-name": "Usuario MQTT", + "password": "Contraseña MQTT" }, "lwm2m": { - "client-endpoint": "Nombre endpoint cliente LwM2M", - "security-config-mode": "Configuración de seguridad LwM2M", - "client-identity": "Identidad cliente LwM2M", - "client-key": "Clave cliente LwM2M", - "client-cert": "Clave pública cliente LwM2M", - "bootstrap-server-security-mode": "Modo seguridad servidor Bootstrap LwM2M", - "bootstrap-server-secret-key": "Clave secreta servidor Bootstrap LwM2M", - "bootstrap-server-public-key-id": "Clave pública o id servidor Bootstrap LwM2M", - "lwm2m-server-security-mode": "Modo seguridad servidor LwM2M", - "lwm2m-server-secret-key": "Clave secreta servidor LwM2M", - "lwm2m-server-public-key-id": "Clave pública servidor LwM2M" + "client-endpoint": "Nombre endpoint cliente LwM2M", + "security-config-mode": "Configuración de seguridad LwM2M", + "client-identity": "Identidad cliente LwM2M", + "client-key": "Clave cliente LwM2M", + "client-cert": "Clave pública cliente LwM2M", + "bootstrap-server-security-mode": "Modo seguridad servidor Bootstrap LwM2M", + "bootstrap-server-secret-key": "Clave secreta servidor Bootstrap LwM2M", + "bootstrap-server-public-key-id": "Clave pública o id servidor Bootstrap LwM2M", + "lwm2m-server-security-mode": "Modo seguridad servidor LwM2M", + "lwm2m-server-secret-key": "Clave secreta servidor LwM2M", + "lwm2m-server-public-key-id": "Clave pública servidor LwM2M" }, "isgateway": "Es Gateway", "activity-time-from-gateway-device": "Fecha de actividad desde el dispositivo gateway", @@ -2504,19 +2504,19 @@ "login-with": "Login con {{name}}", "or": "o", "error": "Error de Login", - "verify-your-identity": "Verify your identity", - "select-way-to-verify": "Select a way to verify", - "resend-code": "Resend code", - "resend-code-wait": "Resend code in { time, plural, 1 {1 second} other {# seconds} }", - "try-another-way": "Try another way", - "totp-auth-description": "Please enter the security code from your authenticator app.", - "totp-auth-placeholder": "Code", - "sms-auth-description": "A security code has been sent to your phone at {{contact}}.", - "sms-auth-placeholder": "SMS code", - "email-auth-description": "A security code has been sent to your email address at {{contact}}.", - "email-auth-placeholder": "Email code", - "backup-code-auth-description": "Please enter one of your backup codes.", - "backup-code-auth-placeholder": "Backup code" + "verify-your-identity": "Verificar identidad", + "select-way-to-verify": "Selecciona el modo de verificación", + "resend-code": "Reenviar código", + "resend-code-wait": "Reenviar código en { time, plural, 1 {1 segundo} other {# segundos} }", + "try-another-way": "Otros modos de verificación", + "totp-auth-description": "Por favor, introduce el código de seguridad de tu aplicación de autenticación.", + "totp-auth-placeholder": "Código", + "sms-auth-description": "Se ha enviado un código de verificación a tu número: {{contact}} proporcionado.", + "sms-auth-placeholder": "Código SMS", + "email-auth-description": "Se ha enviado un código de verificación al email {{contact}} proporcionado.", + "email-auth-placeholder": "Código Email", + "backup-code-auth-description": "Por favor, introduce el código de backup.", + "backup-code-auth-placeholder": "Código de Backup" }, "markdown": { "edit": "Editar", @@ -2525,69 +2525,69 @@ "copied": "Copiado!" }, "ota-update": { - "add": "Añadir paquete", - "assign-firmware": "Firmware asignado", - "assign-firmware-required": "Firmware asignado requerido", - "assign-software": "Software asignado", - "assign-software-required": "Software asignado requerido", - "auto-generate-checksum": "Auto-generar checksum", - "checksum": "Checksum", - "checksum-hint": "Si el checksum está vacío, se generará automáticamente", - "checksum-algorithm": "Algoritmo checksum", - "checksum-copied-message": "El checksum del paquete se ha copiado al portapapeles", - "change-firmware": "El cambio del firmware provocará la actualización de { count, plural, 1 {1 dispositivo} other {# dispositivos} }.", - "change-software": "El cambio del software provocará la actualización de { count, plural, 1 {1 dispositivo} other {# dispositivos} }.", - "chose-compatible-device-profile": "El paquete subido, sólamente estará disponible para los dispositivos con el perfil seleccionado.", - "chose-firmware-distributed-device": "Elige el firmware que se distribuirá a los dispositivos", - "chose-software-distributed-device": "Elige el software que se distribuirá a los dispositivos", - "content-type": "Tipo de contenido", - "copy-checksum": "Copiar checksum", - "copy-direct-url": "Copiar URL directa", - "copyId": "Copiar Id de paquete", - "copied": "Copiado!", - "delete": "Borrar paquete", - "delete-ota-update-text": "Atención, tras la confirmación la actualización OTA será irrecuperable.", - "delete-ota-update-title": "Estás seguro de borrar la actualización OTA '{{title}}'?", - "delete-ota-updates-text": "Atención, tras la confirmación todas las actualizaciones OTA seleccionadas se borrarán.", - "delete-ota-updates-title": "Estás seguro de borrar { count, plural, 1 {1 Actualización OTA} other {# Actualizaciones OTA} }?", - "description": "Descripción", - "direct-url": "URL Directa", - "direct-url-copied-message": "La URL directa del paquete se ha copiado al portapapeles", - "direct-url-required": "URL Directa requerida", - "download": "Descargar paquete", - "drop-file": "Arrastra un fichero o haz click para seleccionar un fichero a subir.", - "drop-package-file-or": "Arrastrar y soltar un fichero o", - "file-name": "Nombre del fichero", - "file-size": "Tamaño del fichero", - "file-size-bytes": "Tamaño del fichero en bytes", - "idCopiedMessage": "El Id del paquete se ha copiado al portapapeles", - "no-firmware-matching": "No se ha encontrado ningún paquete de firmware OTA compatible que coincidan con '{{entity}}'.", - "no-firmware-text": "No hay aprovisionado ningún paquete de firmware OTA.", - "no-packages-text": "No se han encontrado paquetes", - "no-software-matching": "No se ha encontrado ningún paquete de software OTA compatible que coincidan con '{{entity}}'.", - "no-software-text": "No hay aprovisionado ningún paquete de software OTA.", - "ota-update": "Actualización OTA", - "ota-update-details": "Detalles de actualización OTA", - "ota-updates": "Actualizaciones OTA", - "package-type": "Tipo de paquete", - "packages-repository": "Repositorio de paquetes", - "search": "Buscar paquetes", - "selected-package": "{ count, plural, 1 {1 paquete} other {# paquetes} } selected", - "title": "Título", - "title-required": "Título requerido.", - "title-max-length": "El título debe ser menor de 256", - "types": { - "firmware": "Firmware", - "software": "Software" - }, - "upload-binary-file": "Subir fichero binario", - "use-external-url": "Usar una URL externa", - "version": "Versión", - "version-required": "Versión requerida.", - "version-tag": "Tag de Versión", - "version-tag-hint": "El tag de versión debe coincidir con la versión reportada por el dispositivo.", - "version-max-length": "Versión debe ser menor que 256", - "warning-after-save-no-edit": "Una vez que el paquete se haya subido, no se podrá modificar el título, versión, perfil de dispositivo y tipo de paquete." + "add": "Añadir paquete", + "assign-firmware": "Firmware asignado", + "assign-firmware-required": "Firmware asignado requerido", + "assign-software": "Software asignado", + "assign-software-required": "Software asignado requerido", + "auto-generate-checksum": "Auto-generar checksum", + "checksum": "Checksum", + "checksum-hint": "Si el checksum está vacío, se generará automáticamente", + "checksum-algorithm": "Algoritmo checksum", + "checksum-copied-message": "El checksum del paquete se ha copiado al portapapeles", + "change-firmware": "El cambio del firmware provocará la actualización de { count, plural, 1 {1 dispositivo} other {# dispositivos} }.", + "change-software": "El cambio del software provocará la actualización de { count, plural, 1 {1 dispositivo} other {# dispositivos} }.", + "chose-compatible-device-profile": "El paquete subido, sólamente estará disponible para los dispositivos con el perfil seleccionado.", + "chose-firmware-distributed-device": "Elige el firmware que se distribuirá a los dispositivos", + "chose-software-distributed-device": "Elige el software que se distribuirá a los dispositivos", + "content-type": "Tipo de contenido", + "copy-checksum": "Copiar checksum", + "copy-direct-url": "Copiar URL directa", + "copyId": "Copiar Id de paquete", + "copied": "Copiado!", + "delete": "Borrar paquete", + "delete-ota-update-text": "Atención, tras la confirmación la actualización OTA será irrecuperable.", + "delete-ota-update-title": "Estás seguro de borrar la actualización OTA '{{title}}'?", + "delete-ota-updates-text": "Atención, tras la confirmación todas las actualizaciones OTA seleccionadas se borrarán.", + "delete-ota-updates-title": "Estás seguro de borrar { count, plural, 1 {1 Actualización OTA} other {# Actualizaciones OTA} }?", + "description": "Descripción", + "direct-url": "URL Directa", + "direct-url-copied-message": "La URL directa del paquete se ha copiado al portapapeles", + "direct-url-required": "URL Directa requerida", + "download": "Descargar paquete", + "drop-file": "Arrastra un fichero o haz click para seleccionar un fichero a subir.", + "drop-package-file-or": "Arrastrar y soltar un fichero o", + "file-name": "Nombre del fichero", + "file-size": "Tamaño del fichero", + "file-size-bytes": "Tamaño del fichero en bytes", + "idCopiedMessage": "El Id del paquete se ha copiado al portapapeles", + "no-firmware-matching": "No se ha encontrado ningún paquete de firmware OTA compatible que coincidan con '{{entity}}'.", + "no-firmware-text": "No hay aprovisionado ningún paquete de firmware OTA.", + "no-packages-text": "No se han encontrado paquetes", + "no-software-matching": "No se ha encontrado ningún paquete de software OTA compatible que coincidan con '{{entity}}'.", + "no-software-text": "No hay aprovisionado ningún paquete de software OTA.", + "ota-update": "Actualización OTA", + "ota-update-details": "Detalles de actualización OTA", + "ota-updates": "Actualizaciones OTA", + "package-type": "Tipo de paquete", + "packages-repository": "Repositorio de paquetes", + "search": "Buscar paquetes", + "selected-package": "{ count, plural, 1 {1 paquete} other {# paquetes} } selected", + "title": "Título", + "title-required": "Título requerido.", + "title-max-length": "El título debe ser menor de 256", + "types": { + "firmware": "Firmware", + "software": "Software" + }, + "upload-binary-file": "Subir fichero binario", + "use-external-url": "Usar una URL externa", + "version": "Versión", + "version-required": "Versión requerida.", + "version-tag": "Tag de Versión", + "version-tag-hint": "El tag de versión debe coincidir con la versión reportada por el dispositivo.", + "version-max-length": "Versión debe ser menor que 256", + "warning-after-save-no-edit": "Una vez que el paquete se haya subido, no se podrá modificar el título, versión, perfil de dispositivo y tipo de paquete." }, "position": { "top": "Superior", @@ -2606,59 +2606,59 @@ "tokenCopiedWarnMessage": "JWT caducado, por favor actualiza la página." }, "security": { - "security": "Security", + "security": "Seguridad", "2fa": { - "2fa": "Two-factor authentication", - "2fa-description": "Two-factor authentication protects your account from unauthorized access. All you have to do is enter a security code when you log in.", - "authenticate-with": "You can authenticate with:", - "disable-2fa-provider-text": "Disabling {{name}} will make your account less secure", - "disable-2fa-provider-title": "Are you sure you want to disable {{name}}?", - "get-new-code": "Get new code", - "main-2fa-method": "Use as main two-factor authentication method", + "2fa": "Autenticación de doble factor (2FA)", + "2fa-description": "La autenticación de doble factor proteje tu cuenta de accesos no autorizados. Lo único que tienes que hacer es entrar un código de seguridad al hacer login.", + "authenticate-with": "Puedes autenticarte con:", + "disable-2fa-provider-text": "Desactivar {{name}} hará tu cuenta menos segura", + "disable-2fa-provider-title": "Estás seguro de desactivar {{name}}?", + "get-new-code": "Obtener un nuevo código", + "main-2fa-method": "Usar como método de autenticación de doble factor principal", "dialog": { - "activation-step-description-email": "The next time you login in, you will be prompted to enter the security code that will be sent to your email address.", - "activation-step-description-sms": "The next time you login in, you will be prompted to enter the security code that will be sent to the phone number.", - "activation-step-description-totp": "The next time you login in, you will need to provide a two-factor authentication code.", - "activation-step-label": "Activation", - "backup-code-description": "Print out the codes so you have them handy when you need to use them to log in to your account. You can use each backup code once.", - "backup-code-warn": "Once you leave this page, these codes cannot be shown again. Store them safely using the options below.", - "download-txt": "Download (txt)", - "email-step-description": "Enter an email to use as your authenticator.", + "activation-step-description-email": "La próxima vez que hagas log-in, se deberá introducir el código de seguridad que se enviará a tu dirección de email.", + "activation-step-description-sms": "La próxima vez que hagas log-in, se deberá introducir el código de seguridad que se enviará a tu número de teléfono.", + "activation-step-description-totp": "La próxima vez que hagas log-in, se deberá introducir el código de seguridad de doble factor.", + "activation-step-label": "Activación", + "backup-code-description": "Imprime los códigos y guárdalos en un lugar seguro, se necesitarán para hacer login en tu cuenta. Puedes usar cada código de backup sólo una vez.", + "backup-code-warn": "Una vez que salgas de esta página, estos códigos no se volverán a mostrar. Guárdalos en un lugar seguro usando las opciones a continuación.", + "download-txt": "Descargar (txt)", + "email-step-description": "Introduce tu email para usar como autenticador.", "email-step-label": "Email", - "enable-email-title": "Enable email authenticator", - "enable-sms-title": "Enable SMS authenticator", - "enable-totp-title": "Enable authenticator app", - "enter-verification-code": "Enter the 6-digit code here", - "get-backup-code-title": "Get backup code", - "next": "Next", - "scan-qr-code": "Scan this QR code with your verification app", - "send-code": "Send code", - "sms-step-description": "Enter a phone number to use as your authenticator.", - "sms-step-label": "Phone Number", - "success": "Success!", - "totp-step-description-install": "You can install apps like Google Authenticator, Authy, or Duo.", - "totp-step-description-open": "Open the authenticator app on your mobile phone.", - "totp-step-label": "Get app", - "verification-code": "6-digit code", - "verification-code-invalid": "Invalid verification code format", - "verification-code-incorrect": "Verification code is incorrect", - "verification-code-many-request": "Too many requests check verification code", - "verification-step-description": "Enter a 6-digit code we just sent to {{address}}", - "verification-step-label": "Verification" + "enable-email-title": "Activar autenticador por email", + "enable-sms-title": "Activar autenticador por SMS", + "enable-totp-title": "Activar autenticador por app", + "enter-verification-code": "Entra el código de 6-dígitos", + "get-backup-code-title": "Obtener copia de seguridad", + "next": "Siguiente", + "scan-qr-code": "Escanea el código QR con tu aplicación de autenticación", + "send-code": "Enviar código", + "sms-step-description": "Introduce tu número de teléfono para usar como autenticador.", + "sms-step-label": "Número de teléfono", + "success": "Éxito!", + "totp-step-description-install": "Puedes instalar la aplicación Google Authenticator, Authy, o Duo.", + "totp-step-description-open": "Abre la aplicación de autenticación en tu teléfono móvil.", + "totp-step-label": "Obtener app", + "verification-code": "Código de 6-dígitos", + "verification-code-invalid": "Formáto de código inválido", + "verification-code-incorrect": "El código de verificación es incorrecto", + "verification-code-many-request": "Demasiadas solicitudes, revisa el código de verificación", + "verification-step-description": "Introduce el código de 6-dígitos que acabamos de enviar a {{address}}", + "verification-step-label": "Verificación" }, "provider": { "email": "Email", - "email-description": "Use a security code sent to your email address to authenticate.", - "email-hint": "Authentication codes are sent via email to {{ info }}", + "email-description": "Usar un código de seguridad enviado a tu email para autenticarte.", + "email-hint": "Los códigos de autenticación se han enviado por email a {{ info }}", "sms": "SMS", - "sms-description": "Use your phone to authenticate. We'll send you a security code via SMS message when you log in.", - "sms-hint": "Authentication codes are sent by text message to {{ info }}", - "totp": "Authenticator app", - "totp-description": "Use apps like Google Authenticator, Authy, or Duo on your phone to authenticate. It will generate a security code for logging in.", - "totp-hint": "Authenticator app is set up for your account", - "backup_code": "Backup code", - "backup-code-description": "These printable one-time passcodes allow you to sign in when away from your phone, like when you’re traveling.", - "backup-code-hint": "{{ info }} single-use codes are active at this time" + "sms-description": "Usar tu teléfono para autenticarte. Enviaremos un código de seguridad vía SMS.", + "sms-hint": "Los códigos de autenticación se han enviado por mensaje de texto SMS a {{ info }}", + "totp": "App de autenticación", + "totp-description": "Usar aplicaciones como Google Authenticator, Authy, o Duo en tu teléfono para autenticarte. Se generará un código de seguridad para hacer login.", + "totp-hint": "La aplicación de autenticación se ha configurado en tu cuenta", + "backup_code": "Código Backup", + "backup-code-description": "Estos códigos de seguridad imprimibles son de un solo uso, te permiten identificarte cuando no tengas el teléfono a mano, útil cuando se viaja.", + "backup-code-hint": "{{ info }} códigos de un solo uso activos en este momento" } } }, From 9382f6928c6d4bfb2eb39c375f3118b827c02687 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20N=C3=BA=C3=B1ez?= Date: Fri, 3 Jun 2022 12:51:19 +0200 Subject: [PATCH 41/86] Add queues tranlations --- .../assets/locale/locale.constant-es_ES.json | 144 +++++++++--------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/ui-ngx/src/assets/locale/locale.constant-es_ES.json b/ui-ngx/src/assets/locale/locale.constant-es_ES.json index ddc8847ce8..ea6196fa8a 100644 --- a/ui-ngx/src/assets/locale/locale.constant-es_ES.json +++ b/ui-ngx/src/assets/locale/locale.constant-es_ES.json @@ -2873,84 +2873,84 @@ "browser-time": "Hora del navegador" }, "queue": { - "queue-name": "Queue", + "queue-name": "Cola", "no-queues-matching": "No se encontraron colas que coincidan con '{{queue}}'.", "select_name": "Selecciona el nombre de la cola", "name": "Nombre Cola", "name_required": "Necesario especificar el nombre de cola", - "name-unique": "Queue name is not unique!", - "queue-required": "Queue is required!", - "topic-required": "Queue topic is required!", - "poll-interval-required": "Poll interval is required!", - "poll-interval-min-value": "Poll interval value can't be less then 1", - "partitions-required": "Partitions is required!", - "partitions-min-value": "Partitions value can't be less then 1", - "pack-processing-timeout-required": "Processing timeout is required", - "pack-processing-timeout-min-value": "Processing timeout value can't be less then 1", - "batch-size-required": "Batch size is required!", - "batch-size-min-value": "Batch size value can't be less then 1", - "retries-required": "Retries is required!", - "retries-min-value": "Retries value can't be negative", - "failure-percentage-required": "Failure percentage is required!", - "failure-percentage-min-value": "Failure percentage value can't be less then 0", - "failure-percentage-max-value": "Failure percentage value can't be more then 100", - "pause-between-retries-required": "Pause between retries is required!", - "pause-between-retries-min-value": "Pause between retries value can't be less then 1", - "max-pause-between-retries-required": "Max pause between retries is required!", - "max-pause-between-retries-min-value": "Max pause between retries value can't be less then 1", - "submit-strategy-type-required": "Submit strategy type is required!", - "processing-strategy-type-required": "Processing strategy type is required!", - "queues": "Queues", - "selected-queues": "{ count, plural, 1 {1 queue} other {# queues} } selected", - "delete-queue-title": "Are you sure you want to delete the queue '{{queueName}}'?", - "delete-queues-title": "Are you sure you want to delete { count, plural, 1 {1 queue} other {# queues} }?", - "delete-queue-text": "Be careful, after the confirmation the queue and all related data will become unrecoverable.", - "delete-queues-text": "After the confirmation all selected queues will be deleted and won't be accessible.", - "search": "Search queue", - "add" : "Add queue", - "details": "Queue details", + "name-unique": "El nombre de cola ya existe!", + "queue-required": "Cola requerida!", + "topic-required": "Topic cola requerido!", + "poll-interval-required": "Intervalo de obtención requerido!", + "poll-interval-min-value": "El intervalo no debe ser menor de 1", + "partitions-required": "Particiones requeridas!", + "partitions-min-value": "El valor de particion no debe ser menor de 1", + "pack-processing-timeout-required": "Timeout de procesamiento", + "pack-processing-timeout-min-value": "Timeout de procesamiento no puede ser menor de 1", + "batch-size-required": "Tamaño del lote requerido!", + "batch-size-min-value": "El valor de tamaño de lote no puede ser menor de 1", + "retries-required": "Reintentos requerido!", + "retries-min-value": "El valor de reintentos no puede ser negativo", + "failure-percentage-required": "Porcentaje de fallos requerido!", + "failure-percentage-min-value": "Porcentaje de fallos no puede ser menor de 0", + "failure-percentage-max-value": "Porcentaje de fallos no puede ser mayor de 100", + "pause-between-retries-required": "Pausa entre reintentos requerido!", + "pause-between-retries-min-value": "Pausa mínima entre reintentos no puede ser menor de 1", + "max-pause-between-retries-required": "Pausa máxima entre reintentos requerido!", + "max-pause-between-retries-min-value": "Pausa máxima entre reintentos no puede ser menor de 1", + "submit-strategy-type-required": "Estrategia de envío requerida!", + "processing-strategy-type-required": "Estrategia de procesamiento requerida!", + "queues": "Colas", + "selected-queues": "{ count, plural, 1 {1 cola} other {# colas} } seleccionadas", + "delete-queue-title": "Estás seguro de borrar la cola '{{queueName}}'?", + "delete-queues-title": "Estás seguro de borrar { count, plural, 1 {1 cola} other {# colas} }?", + "delete-queue-text": "Atención, tras la confirmacion la cola y todos sus datos relacionados serán irrecuperables.", + "delete-queues-text": "Atención, tras la confirmación todas las colas se borrarán y no serán accesibles.", + "search": "Buscar cola", + "add" : "Añadir cola", + "details": "Detalles cola", "topic": "Topic", - "submit-strategy": "Submit Strategy", - "processing-strategy": "Processing Strategy", - "poll-interval": "Poll interval", - "partitions": "Partitions", - "consumer-per-partition": "Consumer per partition", - "consumer-per-partition-hint": "Enable separate consumer(s) per each partition", - "processing-timeout": "Processing timeout, ms", - "batch-size": "Batch size", - "retries": "Retries (0 - unlimited)", - "failure-percentage": "Failure Percentage", - "pause-between-retries": "Pause between retries", - "max-pause-between-retries": "Maximal pause between retries", - "delete": "Delete queue", - "copyId": "Copy queue Id", - "idCopiedMessage": "Queue Id has been copied to clipboard", - "description": "Description", - "description-hint": "This text will be displayed in the Queue description instead of the selected strategy", - "alt-description": "Submit Strategy: {{submitStrategy}}, Processing Strategy: {{processingStrategy}}", + "submit-strategy": "Estrategia de envío", + "processing-strategy": "Estrategia de procesamiento", + "poll-interval": "Intervalo de obtención", + "partitions": "Particiones", + "consumer-per-partition": "Consumidores por partición", + "consumer-per-partition-hint": "Activar consumidores separados para cada partición", + "processing-timeout": "Timeout de procesamiento, ms", + "batch-size": "Tamaño de lote", + "retries": "Reintentos (0 - ilimitados)", + "failure-percentage": "Porcentaje de fallos", + "pause-between-retries": "Pausa entre reintentos", + "max-pause-between-retries": "Pausa máxima entre reintentos", + "delete": "Borrar cola", + "copyId": "Copiar Id de cola", + "idCopiedMessage": "La Id de cola se ha copiado al portapapeles", + "description": "Descripción", + "description-hint": "Este texto se mostrará en la descripción de la cola, en lugar de la estrategia seleccionada", + "alt-description": "Estrategia de envío: {{submitStrategy}}, Estrategia de procesamiento: {{processingStrategy}}", "strategies": { - "sequential-by-originator-label": "Sequential by originator", - "sequential-by-originator-hint": "New message for e.g. device A is not submitted until previous message for device A is acknowledged", - "sequential-by-tenant-label": "Sequential by tenant", - "sequential-by-tenant-hint": "New message for e.g tenant A is not submitted until previous message for tenant A is acknowledged", - "sequential-label": "Sequential", - "sequential-hint": "New message is not submitted until previous message is acknowledged", - "burst-label": "Burst", - "burst-hint": "All messages are submitted to the rule chains in the order they arrive", - "batch-label": "Batch", - "batch-hint": "New batch is not submitted until previous batch is acknowledged", - "skip-all-failures-label": "Skip all failures", - "skip-all-failures-hint": "Ignore all failures", - "skip-all-failures-and-timeouts-label": "Skip all failures and timeouts", - "skip-all-failures-and-timeouts-hint": "Ignore all failures and timeouts", - "retry-all-label": "Retry all", - "retry-all-hint": "Retry all messages from processing pack", - "retry-failed-label": "Retry failed", - "retry-failed-hint": "Retry all failed messages from processing pack", - "retry-timeout-label": "Retry timeout", - "retry-timeout-hint": "Retry all timed-out messages from processing pack", - "retry-failed-and-timeout-label": "Retry failed and timeout", - "retry-failed-and-timeout-hint": "Retry all failed and timed-out messages from processing pack" + "sequential-by-originator-label": "Secuencial por iniciador", + "sequential-by-originator-hint": "El nuevo mensaje por ejemplo dispositivo A, no se enviará hasta que el mensaje anterior del dispositivo A sea admitido/procesado", + "sequential-by-tenant-label": "Secuencial por propietario", + "sequential-by-tenant-hint": "El nuevo mensaje, por ejemplo Propietario A, no se enviará hasta que el mensaje anterior del Propietario A sea admitido/procesado", + "sequential-label": "Secuencial", + "sequential-hint": "El nuevo mensaje no se enviará hasta que el mensaje anterior sea admitido/procesado", + "burst-label": "Ráfaga (Burst)", + "burst-hint": "Todos los mensajes se enviarán hacia las cadenas de reglas en el órden que lleguen", + "batch-label": "Lotes (Batch)", + "batch-hint": "El nuevo lote, no se enviará hasta que el anterior lote sea admitido/procesado", + "skip-all-failures-label": "Omitir todos los fallos", + "skip-all-failures-hint": "Ignorar todos los fallos", + "skip-all-failures-and-timeouts-label": "Omitir todos los fallos y timeouts", + "skip-all-failures-and-timeouts-hint": "Ignorar todos los fallos y timeouts", + "retry-all-label": "Reintentar todos", + "retry-all-hint": "Reintentar todos los mensajes del lote de procesamiento", + "retry-failed-label": "Reintentar fallidos", + "retry-failed-hint": "Reintentar todos los mensajes fallidos del lote de procesamiento", + "retry-timeout-label": "Timeout de reintentos", + "retry-timeout-hint": "Reintentar todos los mensajes que den timeout del lote de procesamiento", + "retry-failed-and-timeout-label": "Reintentar fallidos y timeouts", + "retry-failed-and-timeout-hint": "Reintentar todos los mensajes fallidos y que den timeout del lote de procesamiento" } }, "tenant": { From 1db2fb7d4987976b1a288485e582b01734b48c80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Javier=20N=C3=BA=C3=B1ez?= Date: Fri, 3 Jun 2022 19:05:41 +0200 Subject: [PATCH 42/86] Add widgets translation --- .../assets/locale/locale.constant-es_ES.json | 1544 ++++++++--------- 1 file changed, 772 insertions(+), 772 deletions(-) diff --git a/ui-ngx/src/assets/locale/locale.constant-es_ES.json b/ui-ngx/src/assets/locale/locale.constant-es_ES.json index ea6196fa8a..56b85eac62 100644 --- a/ui-ngx/src/assets/locale/locale.constant-es_ES.json +++ b/ui-ngx/src/assets/locale/locale.constant-es_ES.json @@ -3450,145 +3450,145 @@ }, "widgets": { "chart": { - "common-settings": "Common settings", - "enable-stacking-mode": "Enable stacking mode", - "line-shadow-size": "Line shadow size", - "display-smooth-lines": "Display smooth (curved) lines", - "default-bar-width": "Default bar width for non-aggregated data (milliseconds)", - "bar-alignment": "Bar alignment", - "bar-alignment-left": "Left", - "bar-alignment-right": "Right", - "bar-alignment-center": "Center", - "default-font-size": "Default font size", - "default-font-color": "Default font color", - "thresholds-line-width": "Default line width for all thresholds", - "tooltip-settings": "Tooltip settings", - "show-tooltip": "Show tooltip", - "hover-individual-points": "Hover individual points", - "show-cumulative-values": "Show cumulative values in stacking mode", - "hide-zero-false-values": "Hide zero/false values from tooltip", - "tooltip-value-format-function": "Tooltip value format function", - "grid-settings": "Grid settings", - "show-vertical-lines": "Show vertical lines", - "show-horizontal-lines": "Show horizontal lines", - "grid-outline-border-width": "Grid outline/border width (px)", - "primary-color": "Primary color", - "background-color": "Background color", - "ticks-color": "Ticks color", - "xaxis-settings": "X axis settings", - "axis-title": "Axis title", - "xaxis-tick-labels-settings": "X axis tick labels settings", - "show-tick-labels": "Show axis tick labels", - "yaxis-settings": "Y axis settings", - "min-scale-value": "Minimum value on the scale", - "max-scale-value": "Maximum value on the scale", - "yaxis-tick-labels-settings": "Y axis tick labels settings", - "tick-step-size": "Step size between ticks", - "number-of-decimals": "The number of decimals to display", - "ticks-formatter-function": "Ticks formatter function", - "comparison-settings": "Comparison settings", - "enable-comparison": "Enable comparison", - "time-for-comparison": "Comparison period", - "time-for-comparison-previous-interval": "Previous interval (default)", - "time-for-comparison-days": "Day ago", - "time-for-comparison-weeks": "Week ago", - "time-for-comparison-months": "Month ago", - "time-for-comparison-years": "Year ago", - "time-for-comparison-custom-interval": "Custom interval", - "custom-interval-value": "Custom interval value (ms)", - "comparison-x-axis-settings": "Comparison X axis settings", - "axis-position": "Axis position", - "axis-position-top": "Top (default)", - "axis-position-bottom": "Bottom", - "custom-legend-settings": "Custom legend settings", - "enable-custom-legend": "Enable custom legend (this will allow you to use attribute/timeseries values in key labels)", - "key-name": "Key name", - "key-name-required": "Key name is required", - "key-type": "Key type", - "key-type-attribute": "Attribute", + "common-settings": "Ajustes comunes", + "enable-stacking-mode": "Activar modo de apilamiento (stacking)", + "line-shadow-size": "Tamaño de sombra (línea)", + "display-smooth-lines": "Mostrar líneas suaves (curvas)", + "default-bar-width": "Ancho de barra por defecto para datos no agregados (millisegundos)", + "bar-alignment": "Alineación barra", + "bar-alignment-left": "Izquierda", + "bar-alignment-right": "Derecha", + "bar-alignment-center": "Centro", + "default-font-size": "Tamaño de fuente por defecto", + "default-font-color": "Color de fuente por defecto", + "thresholds-line-width": "Ancho de línea por defecto para todos los umbrales", + "tooltip-settings": "Ajustes de sugerencias (tooltip)", + "show-tooltip": "Mostrar sugerencias", + "hover-individual-points": "Hover sobre puntos individuales", + "show-cumulative-values": "Mostrar valores acumulados en modo apilado", + "hide-zero-false-values": "Ocultar valores cero/false en sugerencias", + "tooltip-value-format-function": "Función de formateo de valores en sugerencias (tooltip)", + "grid-settings": "Ajustes de cuadrícula", + "show-vertical-lines": "Mostrar líneas verticales", + "show-horizontal-lines": "Mostrar líneas horizontales", + "grid-outline-border-width": "Ancho de cuadrícula/contorno en px", + "primary-color": "Color primario", + "background-color": "Color de fondo", + "ticks-color": "Color de ticks", + "xaxis-settings": "Ajustes eje X", + "axis-title": "Título de eje", + "xaxis-tick-labels-settings": "Ajustes de etiquetas en ticks eje X", + "show-tick-labels": "Mostrar etiquetas en ticks", + "yaxis-settings": "Ajustes eje Y", + "min-scale-value": "Valor mínimo en la escala", + "max-scale-value": "Valor máximo en la escala", + "yaxis-tick-labels-settings": "Ajustes de etiquetas en ticks eje Y", + "tick-step-size": "Tamaño de paso entre ticks", + "number-of-decimals": "Número de decimales", + "ticks-formatter-function": "Función de formateo de ticks", + "comparison-settings": "Ajustes de comparación", + "enable-comparison": "Activar comparación", + "time-for-comparison": "Período de comparación", + "time-for-comparison-previous-interval": "Intervalo anterior (por defecto)", + "time-for-comparison-days": "Hace un día", + "time-for-comparison-weeks": "Hace una semana", + "time-for-comparison-months": "Hace un mes", + "time-for-comparison-years": "Hace un año", + "time-for-comparison-custom-interval": "Intervalo personalizado", + "custom-interval-value": "Valor de intervalo personalizado (ms)", + "comparison-x-axis-settings": "Ajustes comparación eje X", + "axis-position": "Posición eje", + "axis-position-top": "Superior (por defecto)", + "axis-position-bottom": "Inferior", + "custom-legend-settings": "Ajustes leyenda", + "enable-custom-legend": "Activar leyenda personalizada (habilita poder usar valores de atributos/timeseries en las etiquetas)", + "key-name": "Nombre clave", + "key-name-required": "Nombre clave requerido", + "key-type": "Tipo clave", + "key-type-attribute": "Atributo", "key-type-timeseries": "Timeseries", - "label-keys-list": "Keys list to use in labels", - "no-label-keys": "No keys configured", - "add-label-key": "Add new key", - "line-width": "Line width", + "label-keys-list": "Lista de claves para usar en etiquetas", + "no-label-keys": "No hay claves configuradas", + "add-label-key": "Añadir nueva clave", + "line-width": "Ancho de línea", "color": "Color", - "data-is-hidden-by-default": "Data is hidden by default", - "disable-data-hiding": "Disable data hiding", - "remove-from-legend": "Remove datakey from legend", - "exclude-from-stacking": "Exclude from stacking(available in \"Stacking\" mode)", - "line-settings": "Line settings", - "show-line": "Show line", - "fill-line": "Fill line", - "points-settings": "Points settings", - "show-points": "Show points", - "points-line-width": "Line width of points", - "points-radius": "Radius of points", - "point-shape": "Point shape", - "point-shape-circle": "Circle", - "point-shape-cross": "Cross", - "point-shape-diamond": "Diamond", - "point-shape-square": "Square", - "point-shape-triangle": "Triangle", - "point-shape-custom": "Custom function", - "point-shape-draw-function": "Point shape draw function", - "show-separate-axis": "Show separate axis", - "axis-position-left": "Left", - "axis-position-right": "Right", - "thresholds": "Thresholds", - "no-thresholds": "No thresholds configured", - "add-threshold": "Add new threshold", - "show-values-for-comparison": "Show historical values for comparison", - "comparison-values-label": "Historical values label", - "threshold-settings": "Threshold settings", - "use-as-threshold": "Use key value as threshold", - "threshold-line-width": "Threshold line width", - "threshold-color": "Threshold color", - "common-pie-settings": "Common pie settings", - "radius": "Radius", - "inner-radius": "Inner radius", - "tilt": "Tilt", - "stroke-settings": "Stroke settings", - "width-pixels": "Width (pixels)", - "show-labels": "Show labels", - "animation-settings": "Animation settings", - "animated-pie": "Enable pie animation (experimental)", - "border-settings": "Border settings", - "border-width": "Border width", - "border-color": "Border color", - "legend-settings": "Legend settings", - "display-legend": "Display legend", - "labels-font-color": "Labels font color" + "data-is-hidden-by-default": "Ocultar datos por defecto", + "disable-data-hiding": "Desactivar ocultación de datos", + "remove-from-legend": "Quitar clave de la leyenda", + "exclude-from-stacking": "Excluir del modo apilado(disponible en el modo \"Apilado\")", + "line-settings": "Ajustes de línea", + "show-line": "Mostrar línea", + "fill-line": "Rellenar línea", + "points-settings": "Ajustes de puntos", + "show-points": "Mostrar puntos", + "points-line-width": "Ancho de línea en puntos", + "points-radius": "Radio de los puntos", + "point-shape": "Forma del punto", + "point-shape-circle": "Círculo", + "point-shape-cross": "Cruz", + "point-shape-diamond": "Diamante", + "point-shape-square": "Cuadrado", + "point-shape-triangle": "Triángulo", + "point-shape-custom": "Función personalizada", + "point-shape-draw-function": "Función de forma del punto", + "show-separate-axis": "Mostrar eje separado", + "axis-position-left": "Izquieda", + "axis-position-right": "Derecha", + "thresholds": "Umbrales", + "no-thresholds": "No hay umbrales configurados", + "add-threshold": "Añadir nuevo umbral", + "show-values-for-comparison": "Mostrar valores históricos para su comparación", + "comparison-values-label": "Etiqueta de valores históricos", + "threshold-settings": "Ajustes de umbrales", + "use-as-threshold": "Usar valor de clave como umbral", + "threshold-line-width": "Ancho de línea (para umbral)", + "threshold-color": "Color umbral", + "common-pie-settings": "Ajustes comunes diagrama de sectores", + "radius": "Radio", + "inner-radius": "Radio interior", + "tilt": "Inclinación", + "stroke-settings": "Ajustes de trazo", + "width-pixels": "Ancho (pixels)", + "show-labels": "Mostrar etiquetas", + "animation-settings": "Ajustes de animación", + "animated-pie": "Activar animación (experimental)", + "border-settings": "Ajustes de bordes", + "border-width": "Ancho de borde", + "border-color": "Color de borde", + "legend-settings": "Ajustes de leyenda", + "display-legend": "Mostrar leyenda", + "labels-font-color": "Color de texto en leyenda" }, "dashboard-state": { - "dashboard-state-settings": "Dashboard state settings", - "dashboard-state": "Dashboard state id", - "autofill-state-layout": "Autofill state layout height by default", - "default-margin": "Default widgets margin", - "default-background-color": "Default background color", - "sync-parent-state-params": "Sync state params with parent dashboard" + "dashboard-state-settings": "Ajustes estado de panel", + "dashboard-state": "Id de estado panel", + "autofill-state-layout": "Auto-rellenar altura por defecto (obtenida del estado)", + "default-margin": "Márgen entre widgets por defecto", + "default-background-color": "Color de fondo por defecto", + "sync-parent-state-params": "Sincronizar parámetros de estado con el panel padre" }, "date-range-navigator": { - "date-range-picker-settings": "Date range picker settings", - "hide-date-range-picker": "Hide date range picker", - "picker-one-panel": "Date range picker one panel", - "picker-auto-confirm": "Date range picker auto confirm", - "picker-show-template": "Date range picker show template", - "first-day-of-week": "First day of the week", - "interval-settings": "Interval settings", - "hide-interval": "Hide interval", - "initial-interval": "Initial interval", - "interval-hour": "Hour", - "interval-day": "Day", - "interval-week": "Week", - "interval-two-weeks": "2 weeks", - "interval-month": "Month", - "interval-three-months": "3 months", - "interval-six-months": "6 months", - "step-settings": "Step settings", - "hide-step-size": "Hide step size", - "initial-step-size": "Initial step size", - "hide-labels": "Hide labels", - "use-session-storage": "Use session storage", + "date-range-picker-settings": "Ajustes del selector de fechas", + "hide-date-range-picker": "Ocultar el selector de fechas", + "picker-one-panel": "Selector de fechas para un panel", + "picker-auto-confirm": "Auto-confirmar en selector de fechas", + "picker-show-template": "Mostrar plantilla de selector de fechas", + "first-day-of-week": "Primer día de la semana", + "interval-settings": "Ajustes de intervalo", + "hide-interval": "Ocultar intervalo", + "initial-interval": "Intervalo inicial", + "interval-hour": "Hora", + "interval-day": "Día", + "interval-week": "Semana", + "interval-two-weeks": "2 semanas", + "interval-month": "Mes", + "interval-three-months": "3 meses", + "interval-six-months": "6 meses", + "step-settings": "Ajustes de paso", + "hide-step-size": "Ocultar tamaño de paso", + "initial-step-size": "Tamaño de paso inicial", + "hide-labels": "Ocultar etiquetas", + "use-session-storage": "Usar almacenamiento de sesión", "localizationMap": { "Sun": "Dom.", "Mon": "Lun.", @@ -3646,170 +3646,170 @@ } }, "entities-hierarchy": { - "hierarchy-data-settings": "Hierarchy data settings", - "relations-query-function": "Node relations query function", - "has-children-function": "Node has children function", - "node-state-settings": "Node state settings", - "node-opened-function": "Default node opened function", - "node-disabled-function": "Node disabled function", - "display-settings": "Display settings", - "node-icon-function": "Node icon function", - "node-text-function": "Node text function", - "sort-settings": "Sort settings", - "nodes-sort-function": "Nodes sort function" + "hierarchy-data-settings": "Ajustes de datos de jerarquía", + "relations-query-function": "Función de obtención de relaciones", + "has-children-function": "El nodo tiene una función hija", + "node-state-settings": "Ajustes estado nodo", + "node-opened-function": "Función por defecto al abrir nodo", + "node-disabled-function": "Función con nodo desactivado", + "display-settings": "Mostrar ajustes", + "node-icon-function": "Función de icono nodo", + "node-text-function": "Función de texto nodo", + "sort-settings": "Ajustes de ordenación", + "nodes-sort-function": "Función de ordenación" }, "edge": { - "display-default-title": "Display default title" + "display-default-title": "Mostrar título por defecto" }, "gateway": { - "general-settings": "General settings", - "widget-title": "Widget title", - "default-archive-file-name": "Default archive file name", - "device-type-for-new-gateway": "Device type for new gateway", - "messages-settings": "Messages settings", - "save-config-success-message": "Text message about successfully saved gateway configuration", - "device-name-exists-message": "Text message when device with entered name is already exists", - "gateway-title": "Gateway form", - "read-only": "Read only", - "events-title": "Gateway events form title", - "events-filter": "Events filter", - "event-key-contains": "Event key contains..." + "general-settings": "Ajustes generales", + "widget-title": "Título del widget", + "default-archive-file-name": "Nombre del fichero por defecto", + "device-type-for-new-gateway": "Tipo de dispositivo para nuevo gateway", + "messages-settings": "Ajustes de mensajes", + "save-config-success-message": "Mensaje de éxito grabando configuración", + "device-name-exists-message": "Mensaje de texto cuando el nombre del dispositivo ya exista", + "gateway-title": "Formulario Gateway", + "read-only": "Solo lectura", + "events-title": "Título del formulario de eventos", + "events-filter": "Filtro de eventos", + "event-key-contains": "La clave de evento contiene..." }, "gauge": { - "default-color": "Default color", - "radial-gauge-settings": "Radial gauge settings", - "ticks-settings": "Ticks settings", - "min-value": "Minimum value", - "max-value": "Maximum value", - "start-ticks-angle": "Start ticks angle", - "ticks-angle": "Ticks angle", - "major-ticks-count": "Major ticks count", - "major-ticks-color": "Major ticks color", - "minor-ticks-count": "Minor ticks count", - "minor-ticks-color": "Minor ticks color", - "tick-numbers-font": "Tick numbers font", - "unit-title-settings": "Unit title settings", - "show-unit-title": "Show unit title", - "unit-title": "Unit title", - "title-font": "Title text font", - "units-settings": "Units settings", - "units-font": "Units text font", - "value-box-settings": "Value box settings", - "show-value-box": "Show value box", - "value-int": "Digits count for integer part of value", - "value-font": "Value text font", - "value-box-rect-stroke-color": "Value box rectangle stroke color", - "value-box-rect-stroke-color-end": "Value box rectangle stroke color - end gradient", - "value-box-background-color": "Value box background color", - "value-box-shadow-color": "Value box shadow color", - "plate-settings": "Plate settings", - "show-plate-border": "Show plate border", - "plate-color": "Plate color", - "needle-settings": "Needle settings", - "needle-circle-size": "Needle circle size", - "needle-color": "Needle color", - "needle-color-end": "Needle color - end gradient", - "needle-color-shadow-up": "Upper half of the needle shadow color", - "needle-color-shadow-down": "Drop shadow needle color", - "highlights-settings": "Highlights settings", - "highlights-width": "Highlights width", - "highlights": "Highlights", - "highlight-from": "From", - "highlight-to": "To", + "default-color": "Color por defecto", + "radial-gauge-settings": "Ajustes de indicador radial", + "ticks-settings": "Ajustes de ticks", + "min-value": "Valor mínimo", + "max-value": "Valor máximo", + "start-ticks-angle": "Ángulo de inicio ticks", + "ticks-angle": "Ángulo Ticks", + "major-ticks-count": "Nº de ticks principales", + "major-ticks-color": "Color Nº de ticks principales", + "minor-ticks-count": "Nº de ticks secundarios", + "minor-ticks-color": "Color Nº de ticks secundarios", + "tick-numbers-font": "Fuente del tick", + "unit-title-settings": "Ajustes de unidad (título)", + "show-unit-title": "Mostrar unidades (título)", + "unit-title": "Título de unidad", + "title-font": "Fuente de texto del título", + "units-settings": "Ajustes de unidades", + "units-font": "Fuente de texto de las unidades", + "value-box-settings": "Ajustes de valor", + "show-value-box": "Mostrar valor", + "value-int": "Nº de dígitos para la parte entera del valor", + "value-font": "Fuente de texto del valor", + "value-box-rect-stroke-color": "Color del trazo del rectángulo (valor)", + "value-box-rect-stroke-color-end": "Color del trazo del rectángulo (valor) - gradiente final", + "value-box-background-color": "Color de fondo del valor", + "value-box-shadow-color": "Color de sombra del valor", + "plate-settings": "Ajustes de la placa", + "show-plate-border": "Mostrar borde de la placa", + "plate-color": "Color de la placa", + "needle-settings": "Ajustes de la aguja", + "needle-circle-size": "Tamaño del círculo de la aguja", + "needle-color": "Color de la aguja", + "needle-color-end": "Color de la aguja - gradiente final", + "needle-color-shadow-up": "Color de sombreado de la mitad superior de la aguja", + "needle-color-shadow-down": "Color de sombra de la aguja", + "highlights-settings": "Ajustes de resalto", + "highlights-width": "Ancho del resalto", + "highlights": "Resaltos", + "highlight-from": "De", + "highlight-to": "A", "highlight-color": "Color", - "no-highlights": "No highlights configured", - "add-highlight": "Add highlight", - "animation-settings": "Animation settings", - "enable-animation": "Enable animation", - "animation-duration": "Animation duration", - "animation-rule": "Animation rule", - "animation-linear": "Linear", + "no-highlights": "No hay resaltos configurados", + "add-highlight": "Añadir resalto", + "animation-settings": "Ajustes de animación", + "enable-animation": "Activar animación", + "animation-duration": "Duración de animación", + "animation-rule": "Regla de animación", + "animation-linear": "Lineal", "animation-quad": "Quad", "animation-quint": "Quint", - "animation-cycle": "Cycle", - "animation-bounce": "Bounce", + "animation-cycle": "Ciclo (cycle)", + "animation-bounce": "Rebote (bounce)", "animation-elastic": "Elastic", "animation-dequad": "Dequad", "animation-dequint": "Dequint", "animation-decycle": "Decycle", "animation-debounce": "Debounce", "animation-delastic": "Delastic", - "linear-gauge-settings": "Linear gauge settings", - "bar-stroke-width": "Bar stroke width", - "bar-stroke-color": "Bar stroke color", - "bar-background-color": "Gauge bar background color", - "bar-background-color-end": "Bar background color - end gradient", - "progress-bar-color": "Progress bar color", - "progress-bar-color-end": "Progress bar color - end gradient", - "major-ticks-names": "Major ticks names", - "show-stroke-ticks": "Show ticks stroke", - "major-ticks-font": "Major ticks font", - "border-color": "Border color", - "border-width": "Border width", - "needle-circle-color": "Needle circle color", - "animation-target": "Animation target", - "animation-target-needle": "Needle", - "animation-target-plate": "Plate", - "common-settings": "Common gauge settings", - "gauge-type": "Gauge type", - "gauge-type-arc": "Arc", + "linear-gauge-settings": "Ajustes de indicador lineal", + "bar-stroke-width": "Ancho del trazo", + "bar-stroke-color": "Color del trazo", + "bar-background-color": "Color de fondo del indicador", + "bar-background-color-end": "Color de fondo del indicador - gradiente final", + "progress-bar-color": "Color de la barra de progreso", + "progress-bar-color-end": "Color de la barra de progreso - gradiente final", + "major-ticks-names": "Nombre de ticks principales", + "show-stroke-ticks": "Mostrar trazo de ticks", + "major-ticks-font": "Fuente de ticks principales", + "border-color": "Color del borde", + "border-width": "Ancho del borde", + "needle-circle-color": "Color del círculo de la aguja", + "animation-target": "Destino de la animación", + "animation-target-needle": "Aguja", + "animation-target-plate": "Placa", + "common-settings": "Ajustes comunes del indicador", + "gauge-type": "Tipo de indicador", + "gauge-type-arc": "Arco", "gauge-type-donut": "Donut", - "gauge-type-horizontal-bar": "Horizontal bar", - "gauge-type-vertical-bar": "Vertical bar", - "donut-start-angle": "Angle to start from", - "bar-settings": "Gauge bar settings", - "relative-bar-width": "Relative bar width", - "neon-glow-brightness": "Neon glow effect brightness, (0-100), 0 - disable effect", - "stripes-thickness": "Thickness of the stripes, 0 - no stripes", - "rounded-line-cap": "Display rounded line cap", - "bar-color-settings": "Bar color settings", - "use-precise-level-color-values": "Use precise color levels", - "bar-colors": "Bar colors, from lower to upper", + "gauge-type-horizontal-bar": "Barra horizontal", + "gauge-type-vertical-bar": "Barra vertical", + "donut-start-angle": "Ángulo de inicio", + "bar-settings": "Ajustes de barra indicadora", + "relative-bar-width": "Ancho relativo", + "neon-glow-brightness": "Efecto brillo de neon, (0-100), 0 - desactiva efecto", + "stripes-thickness": "Grosor de las rayas, 0 - sin rayas", + "rounded-line-cap": "Mostrar tapa de línea redondeada", + "bar-color-settings": "Ajustes de color de barra", + "use-precise-level-color-values": "Usar niveles precisos de color", + "bar-colors": "Colores de la barra, del más bajo al más alto", "color": "Color", - "no-bar-colors": "No bar colors configured", - "add-bar-color": "Add bar color", - "from": "From", - "to": "To", - "fixed-level-colors": "Bar colors using boundary values", - "gauge-title-settings": "Gauge title settings", - "show-gauge-title": "Show gauge title", - "gauge-title": "Gauge title", - "gauge-title-font": "Gauge title font", - "unit-title-and-timestamp-settings": "Unit title and timestamp settings", - "show-timestamp": "Show value timestamp", - "timestamp-format": "Timestamp format", - "label-font": "Font of label showing under value", - "value-settings": "Value settings", - "show-value": "Show value text", - "min-max-settings": "Minimum/maximum labels settings", - "show-min-max": "Show min and max values", - "min-max-font": "Font of minimum and maximum labels", - "show-ticks": "Show ticks", - "tick-width": "Tick width", - "tick-color": "Tick color", - "tick-values": "Tick values", - "no-tick-values": "No tick values configured", - "add-tick-value": "Add tick value" + "no-bar-colors": "No hay colores configurados", + "add-bar-color": "Añadir color", + "from": "De", + "to": "A", + "fixed-level-colors": "Colores de barra usando valores límite", + "gauge-title-settings": "Ajustes de título del indicador", + "show-gauge-title": "Mostrar título de indicador", + "gauge-title": "Título de indicador", + "gauge-title-font": "Fuente del título del indicador", + "unit-title-and-timestamp-settings": "Ajustes del título de unidades y timestamp", + "show-timestamp": "Mostrar valor timestamp", + "timestamp-format": "Formato timestamp", + "label-font": "Fuente de la etiqueta que se muestra bajo el valor", + "value-settings": "Ajustes del valor", + "show-value": "Mostrar texto del valor", + "min-max-settings": "Etiqueta mínimo/máximo", + "show-min-max": "Mostrar valores mínimos y máximos", + "min-max-font": "Fuente de los valores mínimo y máximo", + "show-ticks": "Mostrar ticks", + "tick-width": "Ancho de tick", + "tick-color": "Color de tick", + "tick-values": "Valores de tick", + "no-tick-values": "No hay valores configurados", + "add-tick-value": "Añadir valor de tick" }, "gpio": { "pin": "Pin", - "label": "Label", - "row": "Row", - "column": "Column", + "label": "Etiqueta", + "row": "Fila", + "column": "Columna", "color": "Color", - "panel-settings": "Panel settings", - "background-color": "Background color", - "gpio-switches": "GPIO switches", - "no-gpio-switches": "No GPIO switches configured", - "add-gpio-switch": "Add GPIO switch", - "gpio-status-request": "GPIO status request", - "method-name": "Method name", - "method-body": "Method body", - "gpio-status-change-request": "GPIO status change request", - "parse-gpio-status-function": "Parse gpio status function", - "gpio-leds": "GPIO leds", - "no-gpio-leds": "No GPIO leds configured", - "add-gpio-led": "Add GPIO led" + "panel-settings": "Ajustes de panel", + "background-color": "Color de fondo", + "gpio-switches": "switches GPIO", + "no-gpio-switches": "No hay switches GPIO configurados", + "add-gpio-switch": "Añadir switch GPIO", + "gpio-status-request": "Solicitud estado GPIO", + "method-name": "Nombre del método RPC", + "method-body": "Cuerpo del método RPC", + "gpio-status-change-request": "Solicitud de cambio de estado GPIO", + "parse-gpio-status-function": "Función de parseado de estado GPIO", + "gpio-leds": "Leds GPIO", + "no-gpio-leds": "No hay Leds GPIO configurados", + "add-gpio-led": "Añadir led GPIO" }, "html-card": { "html": "HTML", @@ -3860,569 +3860,569 @@ "update-attribute": "Actualizar atributo", "update-timeseries": "Actualizar series de tiempo", "value": "Valor", - "general-settings": "General settings", - "widget-title": "Widget title", - "claim-button-label": "Claiming button label", - "show-secret-key-field": "Show 'Secret key' input field", - "labels-settings": "Labels settings", - "show-labels": "Show labels", - "device-name-label": "Label for device name input field", - "secret-key-label": "Label for secret key input field", - "messages-settings": "Messages settings", - "claim-device-success-message": "Text message of successful device claiming", - "claim-device-not-found-message": "Text message when device not found", - "claim-device-failed-message": "Text message of failed device claiming", - "claim-device-name-required-message": "'Device name required' error message", - "claim-device-secret-key-required-message": "'Secret key required' error message", - "show-label": "Show label", - "label": "Label", - "required": "Required", - "required-error-message": "'Required' error message", - "show-result-message": "Show result message", - "integer-field-settings": "Integer field settings", - "min-value": "Min value", - "max-value": "Max value", - "double-field-settings": "Double field settings", - "text-field-settings": "Text field settings", - "min-length": "Min length", - "max-length": "Max length", - "checkbox-settings": "Checkbox settings", - "true-label": "Checked label", - "false-label": "Unchecked label", - "image-input-settings": "Image input settings", - "display-preview": "Display preview", - "display-clear-button": "Display clear button", - "display-apply-button": "Display apply button", - "display-discard-button": "Display discard button", - "datetime-field-settings": "Date/time field settings", - "display-time-input": "Display time input", - "latitude-key-name": "Latitude key name", - "longitude-key-name": "Longitude key name", - "show-get-location-button": "Show button 'Get current location'", - "use-high-accuracy": "Use high accuracy", - "location-fields-settings": "Location fields settings", - "latitude-label": "Label for latitude", - "longitude-label": "Label for longitude", - "input-fields-alignment": "Input fields alignment", - "input-fields-alignment-column": "Column (default)", - "input-fields-alignment-row": "Row", - "latitude-field-required": "Latitude field required", - "longitude-field-required": "Longitude field required", - "attribute-settings": "Attribute settings", - "widget-mode": "Widget mode", - "widget-mode-update-attribute": "Update attribute", - "widget-mode-update-timeseries": "Update timeseries", - "attribute-scope": "Attribute scope", - "attribute-scope-server": "Server attribute", - "attribute-scope-shared": "Shared attribute", - "value-required": "Value required", - "image-settings": "Image settings", - "image-format": "Image format", + "general-settings": "Ajustes Generales", + "widget-title": "Título del widget", + "claim-button-label": "Etiqueta del botón de reclamar", + "show-secret-key-field": "Mostrar el campo 'Clave Secreta'", + "labels-settings": "Ajustes de etiquetas", + "show-labels": "Mostrar etiquetas", + "device-name-label": "Etiqueta para el campo de entrada 'Nombre de Dispositivo'", + "secret-key-label": "Etiqueta para el campo de entrara 'Clave Secreta'", + "messages-settings": "Ajustes de mensajes", + "claim-device-success-message": "Mensaje a mostrar cuando el dispositivo se haya reclamado ok", + "claim-device-not-found-message": "Mensaje a mostrar cuando el dispositivo no se encuentre", + "claim-device-failed-message": "Mensaje a mostrar cuando ocurra un error reclamando el dispositivo", + "claim-device-name-required-message": "Mensaje de error a mostrar con 'Nombre de dispositivo requerido'", + "claim-device-secret-key-required-message": "Mensaje de error a mostrar con 'Clave Secreta requerida'", + "show-label": "Mostrar etiqueta", + "label": "Etiqueta", + "required": "Requerido", + "required-error-message": "Error a mostrar con campo 'Requerido'", + "show-result-message": "Mensaje para mostrar resultado", + "integer-field-settings": "Ajustes de campos tipo entero", + "min-value": "Valor Mínimo", + "max-value": "Valor Máximo", + "double-field-settings": "Ajustes de campos tipo double", + "text-field-settings": "Ajustes de campos tipo texto", + "min-length": "Longitud mínima", + "max-length": "Longitud máxima", + "checkbox-settings": "Ajustes de campos tipo checkbox", + "true-label": "Etiqueta checked", + "false-label": "Etiqueta unchecked", + "image-input-settings": "Ajustes de campos tipo entrada de imagen", + "display-preview": "Mostrar previsualización", + "display-clear-button": "Mostrar botón de borrar", + "display-apply-button": "Mostrar botón de aplicar", + "display-discard-button": "Mostrar botón de descartar", + "datetime-field-settings": "Ajustes de campos tipo Fecha/Hora", + "display-time-input": "Mostrar entrada de hora", + "latitude-key-name": "Nombre clave latitud", + "longitude-key-name": "Nombre clave longitud", + "show-get-location-button": "Mostrar botón 'Obtener localización actual'", + "use-high-accuracy": "Usar alta precisión", + "location-fields-settings": "Ajustes de campos de localización", + "latitude-label": "Etiqueta para latitud", + "longitude-label": "Etiqueta para longitud", + "input-fields-alignment": "Alineado de campos de entrada", + "input-fields-alignment-column": "Columna (por defecto)", + "input-fields-alignment-row": "Fila", + "latitude-field-required": "Campo latitud requerido", + "longitude-field-required": "Campo longitud requerido", + "attribute-settings": "Ajustes de atributos", + "widget-mode": "Modo del widget", + "widget-mode-update-attribute": "Actualizar atributo", + "widget-mode-update-timeseries": "Actualizar timeseries", + "attribute-scope": "Alcance de atributos", + "attribute-scope-server": "Atributos de servidor", + "attribute-scope-shared": "Atributos compartidos", + "value-required": "Valor requerido", + "image-settings": "Ajustes de imagen", + "image-format": "Formato de imagen", "image-format-jpeg": "JPEG", "image-format-png": "PNG", "image-format-webp": "WEBP", - "image-quality": "Image quality that use lossy compression such as jpeg and webp", - "max-image-width": "Maximum image width", - "max-image-height": "Maximum image height", - "action-buttons": "Action buttons", - "show-action-buttons": "Show action buttons", - "update-all-values": "Update all values, not only modified", - "save-button-label": "'SAVE' button label", - "reset-button-label": "'UNDO' button label", - "group-settings": "Group settings", - "show-group-title": "Show title for group of fields, related to different entities", - "group-title": "Group title", - "fields-alignment": "Fields alignment", - "fields-alignment-row": "Row (default)", - "fields-alignment-column": "Column", - "fields-in-row": "Number of fields in the row", - "option-value": "Value (write 'null' for create empty option)", - "option-label": "Label", - "hide-input-field": "Hide input field", - "datakey-type": "Datakey type", - "datakey-type-server": "Server attribute (default)", - "datakey-type-shared": "Shared attribute", + "image-quality": "Calidad de imagen que usa compresión con pérdida como jpeg y webp", + "max-image-width": "Máximo ancho de imagen", + "max-image-height": "Máximo alto de imagen", + "action-buttons": "Botones de acción", + "show-action-buttons": "Mostrar botones de acción", + "update-all-values": "Actualizar todos los valores, no sólo los modificados", + "save-button-label": "Etiqueta de botón 'GRABAR'", + "reset-button-label": "Etiqueta de botón 'DESHACER'", + "group-settings": "Ajustes de grupo", + "show-group-title": "Mostrar título para el grupo de campos relacionados con diferentes entidades", + "group-title": "Título del grupo", + "fields-alignment": "Alineado de campos", + "fields-alignment-row": "Fila (por defecto)", + "fields-alignment-column": "Columna", + "fields-in-row": "Número de campos en la fila", + "option-value": "Valor (escribe 'null' para crear una opción vacía)", + "option-label": "Etiqueta", + "hide-input-field": "Ocultar campo de entrada", + "datakey-type": "Tipo de clave de datos", + "datakey-type-server": "Atributo de servidor (por defecto)", + "datakey-type-shared": "Atributo compartido", "datakey-type-timeseries": "Timeseries", - "datakey-value-type": "Datakey value type", + "datakey-value-type": "Tipo de valor de la clave de datos", "datakey-value-type-string": "String", "datakey-value-type-double": "Double", - "datakey-value-type-integer": "Integer", + "datakey-value-type-integer": "Entero", "datakey-value-type-boolean-checkbox": "Boolean (Checkbox)", "datakey-value-type-boolean-switch": "Boolean (Switch)", - "datakey-value-type-date-time": "Date & Time", - "datakey-value-type-date": "Date", - "datakey-value-type-time": "Time", - "datakey-value-type-select": "Select", - "value-is-required": "Value is required", - "ability-to-edit-attribute": "Ability to edit attribute", - "ability-to-edit-attribute-editable": "Editable (default)", - "ability-to-edit-attribute-disabled": "Disabled", - "ability-to-edit-attribute-readonly": "Read-only", - "disable-on-datakey-name": "Disable on false value of another datakey (specify datakey name)", - "slide-toggle-settings": "Slide toggle settings", - "slide-toggle-label-position": "Slide toggle label position", - "slide-toggle-label-position-after": "After", - "slide-toggle-label-position-before": "Before", - "select-options": "Select options", - "no-select-options": "No select options configured", - "add-select-option": "Add select option", - "numeric-field-settings": "Numeric field settings", - "step-interval": "Step interval between values", - "error-messages": "Error messages", - "min-value-error-message": "'Min value' error message", - "max-value-error-message": "'Max value' error message", - "invalid-date-error-message": "'Invalid date' error message", - "icon-settings": "Icon settings", - "use-custom-icon": "Use custom icon", - "input-cell-icon": "Icon to show before input cell", - "value-conversion-settings": "Value conversion settings", - "get-value-settings": "Get value settings", - "use-get-value-function": "Use getValue function", - "get-value-function": "getValue function", - "set-value-settings": "Set value settings", - "use-set-value-function": "Use setValue function", - "set-value-function": "setValue function" + "datakey-value-type-date-time": "Fecha & Hora", + "datakey-value-type-date": "Fecha", + "datakey-value-type-time": "Hora", + "datakey-value-type-select": "Selección", + "value-is-required": "Valor requerido", + "ability-to-edit-attribute": "Posibilidad de editar atributo", + "ability-to-edit-attribute-editable": "Editable (por defecto)", + "ability-to-edit-attribute-disabled": "Desactivado", + "ability-to-edit-attribute-readonly": "Sólo lectura", + "disable-on-datakey-name": "Desactivar cuando otra clave de datos sea false (especificar nombre de clave de datos)", + "slide-toggle-settings": "Ajustes de deslizador", + "slide-toggle-label-position": "Posición de etiqueta", + "slide-toggle-label-position-after": "Después", + "slide-toggle-label-position-before": "Antes", + "select-options": "Seleccionar opciones", + "no-select-options": "No hay opciones configuradas", + "add-select-option": "Añadir opción", + "numeric-field-settings": "Ajustes de campos numéricos", + "step-interval": "Pasos entre valores (intervalo)", + "error-messages": "Mensajes de erro", + "min-value-error-message": "Mensaje de error de 'Valor Mínimo'", + "max-value-error-message": "Mensaje de error de 'Valor Máximo'", + "invalid-date-error-message": "Mensaje de erro de 'Fecha Inválida'", + "icon-settings": "Ajustes de iconos", + "use-custom-icon": "Usar icono personalizado", + "input-cell-icon": "Icono a mostrar antes del campo de entrada", + "value-conversion-settings": "Ajustes de conversión de valor", + "get-value-settings": "Ajustes de obtención de valores", + "use-get-value-function": "Usar función getValue", + "get-value-function": "Función getValue", + "set-value-settings": "Ajustes de establecimiento de valores", + "use-set-value-function": "Usar función setValue", + "set-value-function": "Función setValue" }, - "invalid-qr-code-text": "Invalid input text for QR code. Input should have a string type", + "invalid-qr-code-text": "Texto de entrara inválido para el código QR. La entrada debe ser de tipo string", "qr-code": { - "use-qr-code-text-function": "Use QR code text function", - "qr-code-text-pattern": "QR code text pattern (for ex. '${entityName} | ${keyName} - some text.')", - "qr-code-text-pattern-required": "QR code text pattern is required.", - "qr-code-text-function": "QR code text function" + "use-qr-code-text-function": "Usar función de texto QR", + "qr-code-text-pattern": "Patrón del código QR (por ej. '${entityName} | ${keyName} - texto adicional.')", + "qr-code-text-pattern-required": "Se requiere patrón del código QR.", + "qr-code-text-function": "Función del código QR" }, "label-widget": { - "label-pattern": "Pattern", - "label-pattern-hint": "Hint: for ex. 'Text ${keyName} units.' or ${#<key index>} units'", - "label-pattern-required": "Pattern is required", - "label-position": "Position (Percentage relative to background)", + "label-pattern": "Patrón", + "label-pattern-hint": "Ayuda: por ej. 'Texto ${keyName} unidades.' o ${#<key index>} unidades'", + "label-pattern-required": "Se requiere patrón", + "label-position": "Posición (Porcentaje relativo al fondo)", "x-pos": "X", "y-pos": "Y", - "background-color": "Background color", - "font-settings": "Font settings", - "background-image": "Background image", - "labels": "Labels", - "no-labels": "No labels configured", - "add-label": "Add label" + "background-color": "Color de fondo", + "font-settings": "Ajustes de fuente", + "background-image": "Imagen de fondo", + "labels": "Etiquetas", + "no-labels": "No hay etiquetas configuradas", + "add-label": "Añadir etiqueta" }, "navigation": { - "title": "Title", - "navigation-path": "Navigation path", - "filter-type": "Filter type", - "filter-type-all": "All items", - "filter-type-include": "Include items", - "filter-type-exclude": "Exclude items", - "items": "Items", - "enter-urls-to-filter": "Enter urls to filter..." + "title": "Título", + "navigation-path": "Ruta de navegación", + "filter-type": "Tipo de filtro", + "filter-type-all": "Todos los objetos", + "filter-type-include": "Incluir objetos", + "filter-type-exclude": "Excluir objetos", + "items": "Objetos", + "enter-urls-to-filter": "Especificar URLs a filtrar..." }, "persistent-table": { - "rpc-id": "RPC ID", - "message-type": "Message type", - "method": "Method", - "params": "Params", - "created-time": "Created time", - "expiration-time": "Expiration time", - "retries": "Retries", - "status": "Status", - "filter": "Filter", - "refresh": "Refresh", - "add": "Add RPC request", - "details": "Details", - "delete": "Delete", - "delete-request-title": "Delete Persistent RPC request", - "delete-request-text": "Are you sure you want to delete request?", - "details-title": "Details RPC ID: ", - "additional-info": "Additional info", - "response": "Response", - "any-status": "Any status", - "rpc-status-list": "RPC status list", - "no-request-prompt": "No request to display", - "send-request": "Send request", - "add-title": "Create Persistent RPC request", - "method-error": "Method is required.", - "timeout-error": "Min timeout value is 5000 (5 seconds).", - "white-space-error": "White space is not allowed.", + "rpc-id": "ID RPC", + "message-type": "Tipo de mensaje", + "method": "Método", + "params": "Parémetros", + "created-time": "Hora de creación", + "expiration-time": "Hora de expiración", + "retries": "Reintentos", + "status": "Estado", + "filter": "Filtro", + "refresh": "Actualizar", + "add": "Añadir petición RPC", + "details": "Detalles", + "delete": "Borrar", + "delete-request-title": "Borrar petición RPC persistente", + "delete-request-text": "Estas seguro de borrar la petición?", + "details-title": "Detalles ID RPC: ", + "additional-info": "Información adicional", + "response": "Respuesta", + "any-status": "Cualquier estado", + "rpc-status-list": "Lista de estados RPC", + "no-request-prompt": "No hay peticiones a mostrar", + "send-request": "Enviar petición", + "add-title": "Crear una petición RPC persistente", + "method-error": "Se requiere método.", + "timeout-error": "El valor mínimo de timeout es 5000 (5 segundos).", + "white-space-error": "No se permiten espacios en blanco.", "rpc-status": { - "QUEUED": "QUEUED", - "SENT": "SENT", - "DELIVERED": "DELIVERED", - "SUCCESSFUL": "SUCCESSFUL", + "QUEUED": "EN COLA", + "SENT": "ENVIADO", + "DELIVERED": "ENTREGADO", + "SUCCESSFUL": "CORRECTO", "TIMEOUT": "TIMEOUT", - "EXPIRED": "EXPIRED", - "FAILED": "FAILED" + "EXPIRED": "EXPIRADO", + "FAILED": "FALLO" }, - "rpc-search-status-all": "ALL", + "rpc-search-status-all": "TODOS", "message-types": { "false": "Two-way", "true": "One-way" }, - "general-settings": "General settings", - "enable-filter": "Enable filter", - "enable-sticky-header": "Display header while scrolling", - "enable-sticky-action": "Display actions column while scrolling", - "display-request-details": "Display request details", - "allow-send-request": "Allow send RPC request", - "allow-delete-request": "Allow delete request", - "columns-settings": "Columns settings", - "display-columns": "Columns to display", - "column": "Column", - "no-columns-found": "No columns found", - "no-columns-matching": "'{{column}}' not found." + "general-settings": "Ajustes Generales", + "enable-filter": "Activar filtro", + "enable-sticky-header": "Mostrar encabezado mientras se hace scroll", + "enable-sticky-action": "Mostrar columna de acciones mientras se hace scroll", + "display-request-details": "Mostrar detalles de petición", + "allow-send-request": "Permitir enviar petición RPC", + "allow-delete-request": "Permitir borrar petición", + "columns-settings": "Ajustes de columnas", + "display-columns": "Columnas a mostrar", + "column": "Columna", + "no-columns-found": "No se encontraron columnas", + "no-columns-matching": "'{{column}}' no encontrada." }, "rpc": { - "value-settings": "Value settings", - "initial-value": "Initial value", - "retrieve-value-settings": "Retrieve on/off value settings", - "retrieve-value-method": "Retrieve value using method", - "retrieve-value-method-none": "Don't retrieve", - "retrieve-value-method-rpc": "Call RPC get value method", - "retrieve-value-method-attribute": "Subscribe for attribute", - "retrieve-value-method-timeseries": "Subscribe for timeseries", - "attribute-value-key": "Attribute key", - "timeseries-value-key": "Timeseries key", - "get-value-method": "RPC get value method", - "parse-value-function": "Parse value function", - "update-value-settings": "Update value settings", - "set-value-method": "RPC set value method", - "convert-value-function": "Convert value function", - "rpc-settings": "RPC settings", - "request-timeout": "RPC request timeout (ms)", - "persistent-rpc-settings": "Persistent RPC settings", - "request-persistent": "RPC request persistent", - "persistent-polling-interval": "Polling interval (ms) to get persistent RPC command response", - "common-settings": "Common settings", - "switch-title": "Switch title", - "show-on-off-labels": "Show on/off labels", - "slide-toggle-label": "Slide toggle label", - "label-position": "Label position", - "label-position-before": "Before", - "label-position-after": "After", - "slider-color": "Slider color", - "slider-color-primary": "Primary", - "slider-color-accent": "Accent", - "slider-color-warn": "Warn", - "button-style": "Button style", - "button-raised": "Raised button", - "button-primary": "Primary color", - "button-background-color": "Button background color", - "button-text-color": "Button text color", - "widget-title": "Widget title", - "button-label": "Button label", - "device-attribute-scope": "Device attribute scope", - "server-attribute": "Server attribute", - "shared-attribute": "Shared attribute", - "device-attribute-parameters": "Device attribute parameters", - "is-one-way-command": "Is one way command", - "rpc-method": "RPC method", - "rpc-method-params": "RPC method params", - "show-rpc-error": "Show RPC command execution error", - "led-title": "LED title", - "led-color": "LED color", - "check-status-settings": "Check status settings", - "perform-rpc-status-check": "Perform RPC device status check", - "retrieve-led-status-value-method": "Retrieve led status value using method", - "led-status-value-attribute": "Device attribute containing led status value", - "led-status-value-timeseries": "Device timeseries containing led status value", - "check-status-method": "RPC check device status method", - "parse-led-status-value-function": "Parse led status value function", - "knob-title": "Knob title", - "min-value": "Minimum value", - "max-value": "Maximum value" + "value-settings": "Ajustes de valor", + "initial-value": "Valor inicial", + "retrieve-value-settings": "Obtener ajustes valores on/off", + "retrieve-value-method": "Obtener valor usando método", + "retrieve-value-method-none": "No obtener", + "retrieve-value-method-rpc": "Método para llamada RPC de obtención de valor", + "retrieve-value-method-attribute": "Suscribir por atributo", + "retrieve-value-method-timeseries": "Suscribir por timeseries", + "attribute-value-key": "Clave de atributo", + "timeseries-value-key": "Clave de timeseries", + "get-value-method": "Metodo para obtener valor vía RPC", + "parse-value-function": "Función de parseo de valor", + "update-value-settings": "Ajustes de actualización de valor", + "set-value-method": "Método para establecer valor vía RPC", + "convert-value-function": "Función de conversión", + "rpc-settings": "Ajustes RPC", + "request-timeout": "Timeout de petición RPC (ms)", + "persistent-rpc-settings": "Ajustes de RPC persistente", + "request-persistent": "Petición RPC persistente", + "persistent-polling-interval": "Intervalo de sondeo (ms) para obtener respuesta del comando RPC persistente", + "common-settings": "Ajustes comunes", + "switch-title": "Título del switch", + "show-on-off-labels": "Mostrar etiquetas on/off", + "slide-toggle-label": "Etiqueta de interruptor deslizante", + "label-position": "Posición de etiqueta", + "label-position-before": "Antes", + "label-position-after": "Después", + "slider-color": "Color del deslizador", + "slider-color-primary": "Primario", + "slider-color-accent": "Acento", + "slider-color-warn": "Aviso", + "button-style": "Estilo de botón", + "button-raised": "Botón levantado", + "button-primary": "Color primario", + "button-background-color": "Color de fondo", + "button-text-color": "Color de texto", + "widget-title": "Título del widget", + "button-label": "Etiqueta del botón", + "device-attribute-scope": "Alcance de atributos del dispositivo", + "server-attribute": "Atributos de servidor", + "shared-attribute": "Atributos compartidos", + "device-attribute-parameters": "Parámetros de atributos del dispositivo", + "is-one-way-command": "Es un comando de una vía (one way)", + "rpc-method": "Método RPC", + "rpc-method-params": "Parámetros método RPC", + "show-rpc-error": "Mostrar errores de ejecución de RPC", + "led-title": "Título LED", + "led-color": "Color LED", + "check-status-settings": "Ajustes de comprobación de estado", + "perform-rpc-status-check": "Realizar comprobación del dispositivo RPC", + "retrieve-led-status-value-method": "Obtener estado del led usando método", + "led-status-value-attribute": "Atributo del dispositivo que contiene el valor del estado del led", + "led-status-value-timeseries": "Timeseries del dispositivo que contiene el valor del estado del led", + "check-status-method": "Método RPC para chequear el estado del dispositivo", + "parse-led-status-value-function": "Función de parseo para el estado del led", + "knob-title": "Título de mando", + "min-value": "Valor mínimo", + "max-value": "Valor máximo" }, "maps": { - "select-entity": "Select entity", - "select-entity-hint": "Hint: after selection click at the map to set position", + "select-entity": "Seleccionar entidad", + "select-entity-hint": "Ayuda: tras la selección haz click en el mapa para establecer la posición", "tooltips": { - "placeMarker": "Click to place '{{entityName}}' entity", - "firstVertex": "Polygon for '{{entityName}}': click to place first point", - "firstVertex-cut": "Click to place first point", - "continueLine": "Polygon for '{{entityName}}': click to continue drawing", - "continueLine-cut": "Click to continue drawing", - "finishLine": "Click any existing marker to finish", - "finishPoly": "Polygon for '{{entityName}}': click first marker to finish and save", - "finishPoly-cut": "Click first marker to finish and save", - "finishRect": "Polygon for '{{entityName}}': click to finish and save", - "startCircle": "Circle for '{{entityName}}': click to place circle center", - "finishCircle": "Circle for '{{entityName}}': click to finish circle", - "placeCircleMarker": "Click to place circle marker" + "placeMarker": "Click para colocar la entidad '{{entityName}}'", + "firstVertex": "Polígono para la entidad '{{entityName}}': click para colocar el primer punto", + "firstVertex-cut": "Click para colocar el primer punto", + "continueLine": "Polígono para la entidad '{{entityName}}': click para continuar dibujando", + "continueLine-cut": "Click para continuar dibujando", + "finishLine": "Click en cualquier marcador existente para finalizar", + "finishPoly": "Polígono para la entidad '{{entityName}}': click en el primer marcador para finalizar y grabar los cambios", + "finishPoly-cut": "Click en el primer marcador para finalizar y grabar los cambios", + "finishRect": "Polígono para la entidad '{{entityName}}': click para finalizar y grabar los cambios", + "startCircle": "Círculo para la entidad '{{entityName}}': click para establecer el centro del círculo", + "finishCircle": "Círculo para la entidad '{{entityName}}': click para finalizar el círculo", + "placeCircleMarker": "Click para colocar el marcador del círculo" }, "actions": { - "finish": "Finish", - "cancel": "Cancel", - "removeLastVertex": "Remove last point" + "finish": "Finalizar", + "cancel": "Cancelar", + "removeLastVertex": "Quitar último punto" }, "buttonTitles": { - "drawMarkerButton": "Place entity", - "drawPolyButton": "Create polygon", - "drawLineButton": "Create polyline", - "drawCircleButton": "Create circle", - "drawRectButton": "Create rectangle", - "editButton": "Edit mode", - "dragButton": "Drag-drop mode", - "cutButton": "Cut polygon area", - "deleteButton": "Remove", - "drawCircleMarkerButton": "Create circle marker", - "rotateButton": "Rotate polygon" + "drawMarkerButton": "Establecer entidad", + "drawPolyButton": "Crear polígono", + "drawLineButton": "Crear polilínea", + "drawCircleButton": "Crear círculo", + "drawRectButton": "Crear rectángulo", + "editButton": "Modo de edición", + "dragButton": "Modo Arrastrar-soltar", + "cutButton": "Cortar el área del polígono", + "deleteButton": "Borrar", + "drawCircleMarkerButton": "Crear marcador de círculo", + "rotateButton": "Rotar polígono" }, - "map-provider-settings": "Map provider settings", - "map-provider": "Map provider", + "map-provider-settings": "Ajustes proveedor de mapas", + "map-provider": "Proveedor de mapas", "map-provider-google": "Google maps", "map-provider-openstreet": "OpenStreet maps", "map-provider-here": "HERE maps", - "map-provider-image": "Image map", + "map-provider-image": "Mapa de imagen", "map-provider-tencent": "Tencent maps", - "openstreet-provider": "OpenStreet map provider", + "openstreet-provider": "Proveedor OpenStreet map", "openstreet-provider-mapnik": "OpenStreetMap.Mapnik (Default)", "openstreet-provider-hot": "OpenStreetMap.HOT", "openstreet-provider-esri-street": "Esri.WorldStreetMap", "openstreet-provider-esri-topo": "Esri.WorldTopoMap", "openstreet-provider-cartodb-positron": "CartoDB.Positron", "openstreet-provider-cartodb-dark-matter": "CartoDB.DarkMatter", - "use-custom-provider": "Use custom provider", - "custom-provider-tile-url": "Custom provider tile URL", - "google-maps-api-key": "Google Maps API Key", - "default-map-type": "Default map type", - "google-map-type-roadmap": "Roadmap", - "google-map-type-satelite": "Satellite", - "google-map-type-hybrid": "Hybrid", - "google-map-type-terrain": "Terrain", - "map-layer": "Map layer", - "here-map-normal-day": "HERE.normalDay (Default)", + "use-custom-provider": "Usar proveedor personalizado", + "custom-provider-tile-url": "URL de proveedor personalizado", + "google-maps-api-key": "API Key Google Maps", + "default-map-type": "Tipo de mapa por defecto", + "google-map-type-roadmap": "Carretera", + "google-map-type-satelite": "Satelite", + "google-map-type-hybrid": "Híbrido", + "google-map-type-terrain": "Terreno", + "map-layer": "Capa de mapa", + "here-map-normal-day": "HERE.normalDay (Defecto)", "here-map-normal-night": "HERE.normalNight", "here-map-hybrid-day": "HERE.hybridDay", "here-map-terrain-day": "HERE.terrainDay", - "credentials": "Credentials", + "credentials": "Credenciales", "here-app-id": "HERE app id", "here-app-code": "HERE app code", - "tencent-maps-api-key": "Tencent Maps API Key", - "tencent-map-type-roadmap": "Roadmap", - "tencent-map-type-satelite": "Satellite", - "tencent-map-type-hybrid": "Hybrid", - "image-map-background": "Image map background", - "image-map-background-from-entity-attribute": "Take image map background from entity attribute", - "image-url-source-entity-alias": "Image URL source entity alias", - "image-url-source-entity-attribute": "Image URL source entity attribute", - "common-map-settings": "Common map settings", - "x-pos-key-name": "X position key name", - "y-pos-key-name": "Y position key name", - "latitude-key-name": "Latitude key name", - "longitude-key-name": "Longitude key name", - "default-map-zoom-level": "Default map zoom level (0 - 20)", - "default-map-center-position": "Default map center position (0,0)", - "disable-scroll-zooming": "Disable scroll zooming", - "disable-zoom-control-buttons": "Disable zoom control buttons", - "fit-map-bounds": "Fit map bounds to cover all markers", - "use-default-map-center-position": "Use default map center position", - "entities-limit": "Limit of entities to load", - "markers-settings": "Markers settings", - "marker-offset-x": "Marker X offset relative to position multiplied by marker width", - "marker-offset-y": "Marker Y offset relative to position multiplied by marker height", - "position-function": "Position conversion function, should return x,y coordinates as double from 0 to 1 each", - "draggable-marker": "Draggable marker", - "label": "Label", - "show-label": "Show label", - "use-label-function": "Use label function", - "label-pattern": "Label (pattern examples: '${entityName}', '${entityName}: (Text ${keyName} units.)' )", - "label-function": "Label function", - "tooltip": "Tooltip", - "show-tooltip": "Show tooltip", - "show-tooltip-action": "Action for displaying the tooltip", - "show-tooltip-action-click": "Show tooltip on click (Default)", - "show-tooltip-action-hover": "Show tooltip on hover", - "auto-close-tooltips": "Auto-close tooltips", - "use-tooltip-function": "Use tooltip function", - "tooltip-pattern": "Tooltip (for ex. 'Text ${keyName} units.' or Link text')", - "tooltip-function": "Tooltip function", - "tooltip-offset-x": "Tooltip X offset relative to marker anchor multiplied by marker width", - "tooltip-offset-y": "Tooltip Y offset relative to marker anchor multiplied by marker height", + "tencent-maps-api-key": "API Key Tencent Maps", + "tencent-map-type-roadmap": "Carretera", + "tencent-map-type-satelite": "Satelite", + "tencent-map-type-hybrid": "Híbrido", + "image-map-background": "Fondo de mapa de imagen", + "image-map-background-from-entity-attribute": "Obtener imagen de fondo desde un atributo de la entidad", + "image-url-source-entity-alias": "Alias de entidad para URL de imagen", + "image-url-source-entity-attribute": "Atributo de entidad para URL de imagen", + "common-map-settings": "Ajustes comunes de mapas", + "x-pos-key-name": "Clave para posición X", + "y-pos-key-name": "Clave para posición Y", + "latitude-key-name": "Clave para latitud", + "longitude-key-name": "Clave para longitud", + "default-map-zoom-level": "Nivel de zoom por defecto (0 - 20)", + "default-map-center-position": "Posición central del mapa por defecto (0,0)", + "disable-scroll-zooming": "Desactivar zoom en scroll", + "disable-zoom-control-buttons": "Desactivar botones de zoom", + "fit-map-bounds": "Ajustar los límites del mapa para cubrir todos los marcadores", + "use-default-map-center-position": "Usar posición central por defecto", + "entities-limit": "Límite de entidades a cargar", + "markers-settings": "Ajustes de los marcadores", + "marker-offset-x": "Offset X relativo a la posición multiplicado por el ancho del marcador", + "marker-offset-y": "Offset Y relativo a la posición multiplicado por el alto del marcador", + "position-function": "Función de conversión de posición, debe retornar coordenadas x,y como valor double de 0 a 1", + "draggable-marker": "Marcador arrastrable", + "label": "Etiqueta", + "show-label": "Mostrar etiqueta", + "use-label-function": "Usar función de etiqueta", + "label-pattern": "Etiqueta (Ejemplos de patrón: '${entityName}', '${entityName}: (Texto ${keyName} unidades.)' )", + "label-function": "Función de etiqueta", + "tooltip": "Sugerencias (tooltip)", + "show-tooltip": "Mostrar sugerencias", + "show-tooltip-action": "Acción para mostrar las sugerencias", + "show-tooltip-action-click": "Mostrar sugerencias tooltip en click (por defecto)", + "show-tooltip-action-hover": "Mostrar sugerencias on hover", + "auto-close-tooltips": "Auto-cerrar sugerencias", + "use-tooltip-function": "Función de sugerencias", + "tooltip-pattern": "Sugerencia (Por ej. 'Texto ${keyName} unidades.' o Texto Link')", + "tooltip-function": "Función de sugerencia", + "tooltip-offset-x": "Offset X relativo al ancla del marcador multiplicado por el ancho", + "tooltip-offset-y": "Offset Y relativo al ancla del marcador multiplicado por la altura", "color": "Color", - "use-color-function": "Use color function", - "color-function": "Color function", - "marker-image": "Marker image", - "use-marker-image-function": "Use marker image function", - "custom-marker-image": "Custom marker image", - "custom-marker-image-size": "Custom marker image size (px)", - "marker-image-function": "Marker image function", - "marker-images": "Marker images", - "polygon-settings": "Polygon settings", - "show-polygon": "Show polygon", - "polygon-key-name": "Polygon key name", - "enable-polygon-edit": "Enable polygon edit", - "polygon-label": "Polygon label", - "show-polygon-label": "Show polygon label", - "use-polygon-label-function": "Use polygon label function", - "polygon-label-pattern": "Polygon label (pattern examples: '${entityName}', '${entityName}: (Text ${keyName} units.)' )", - "polygon-label-function": "Polygon label function", - "polygon-tooltip": "Polygon tooltip", - "show-polygon-tooltip": "Show polygon tooltip", - "auto-close-polygon-tooltips": "Auto-close polygon tooltips", - "use-polygon-tooltip-function": "Use polygon tooltip function", - "polygon-tooltip-pattern": "Tooltip (for ex. 'Text ${keyName} units.' or Link text')", - "polygon-tooltip-function": "Polygon tooltip function", - "polygon-color": "Polygon color", - "polygon-opacity": "Polygon opacity", - "use-polygon-color-function": "Use polygon color function", - "polygon-color-function": "Polygon color function", - "polygon-stroke": "Polygon stroke", - "stroke-color": "Stroke color", - "stroke-opacity": "Stroke opacity", - "stroke-weight": "Stroke weight", - "use-polygon-stroke-color-function": "Use polygon stroke color function", - "polygon-stroke-color-function": "Polygon stroke color function", - "circle-settings": "Circle settings", - "show-circle": "Show circle", - "circle-key-name": "Circle key name", - "enable-circle-edit": "Enable circle edit", - "circle-label": "Circle label", - "show-circle-label": "Show circle label", - "use-circle-label-function": "Use circle label function", - "circle-label-pattern": "Circle label (pattern examples: '${entityName}', '${entityName}: (Text ${keyName} units.)' )", - "circle-label-function": "Circle label function", - "circle-tooltip": "Circle tooltip", - "show-circle-tooltip": "Show circle tooltip", - "auto-close-circle-tooltips": "Auto-close circle tooltips", - "use-circle-tooltip-function": "Use circle tooltip function", - "circle-tooltip-pattern": "Tooltip (for ex. 'Text ${keyName} units.' or Link text')", - "circle-tooltip-function": "Circle tooltip function", - "circle-fill-color": "Circle fill color", - "circle-fill-color-opacity": "Circle fill color opacity", - "use-circle-fill-color-function": "Use circle fill color function", - "circle-fill-color-function": "Circle fill color function", - "circle-stroke": "Circle stroke", - "use-circle-stroke-color-function": "Use circle stroke color function", - "circle-stroke-color-function": "Circle stroke color function", - "markers-clustering-settings": "Markers clustering settings", - "use-map-markers-clustering": "Use map markers clustering", - "zoom-on-cluster-click": "Zoom when clicking on a cluster", - "max-cluster-zoom": "The maximum zoom level when a marker can be part of a cluster (0 - 18)", - "max-cluster-radius-pixels": "Maximum radius that a cluster will cover in pixels", - "cluster-zoom-animation": "Show animation on markers when zooming", - "show-markers-bounds-on-cluster-mouse-over": "Show the bounds of markers when mouse over a cluster", - "spiderfy-max-zoom-level": "Spiderfy at the max zoom level (to see all cluster markers)", - "load-optimization": "Load optimization", - "cluster-chunked-loading": "Use chunks for adding markers so that the page does not freeze", - "cluster-markers-lazy-load": "Use lazy load for adding markers", - "editor-settings": "Editor settings", - "enable-snapping": "Enable snapping to other vertices for precision drawing", - "init-draggable-mode": "Initialize map in draggable mode", - "hide-all-edit-buttons": "Hide all edit control buttons", - "hide-draw-buttons": "Hide draw buttons", - "hide-edit-buttons": "Hide edit buttons", - "hide-remove-button": "Hide remove button", - "route-map-settings": "Route map settings", - "trip-animation-settings": "Trip animation settings", - "normalization-step": "Normalization data step (ms)", - "tooltip-background-color": "Tooltip background color", - "tooltip-font-color": "Tooltip font color", - "tooltip-opacity": "Tooltip opacity (0-1)", - "auto-close-tooltip": "Auto-close tooltip", - "rotation-angle": "Set additional rotation angle for marker (deg)", - "path-settings": "Path settings", - "path-color": "Path color", - "use-path-color-function": "Use path color function", - "path-color-function": "Path color function", - "path-decorator": "Path decorator", - "use-path-decorator": "Use path decorator", - "decorator-symbol": "Decorator symbol", - "decorator-symbol-arrow-head": "Arrow", - "decorator-symbol-dash": "Dash", - "decorator-symbol-size": "Decorator symbol size (px)", - "use-path-decorator-custom-color": "Use path decorator custom color", - "decorator-custom-color": "Decorator custom color", - "decorator-offset": "Decorator offset", - "end-decorator-offset": "End decorator offset", - "decorator-repeat": "Decorator repeat", - "points-settings": "Points settings", - "show-points": "Show points", - "point-color": "Point color", - "point-size": "Point size (px)", - "use-point-color-function": "Use point color function", - "point-color-function": "Point color function", - "use-point-as-anchor": "Use point as anchor", - "point-as-anchor-function": "Point as anchor function", - "independent-point-tooltip": "Independent point tooltip" + "use-color-function": "Usar función de color", + "color-function": "Función de color", + "marker-image": "Imagen de marcador", + "use-marker-image-function": "Usar función de imagen de marcador", + "custom-marker-image": "Imagen de marcador personalizada", + "custom-marker-image-size": "Tamaño de imagen personalizada (px)", + "marker-image-function": "Función de imagen de marcador", + "marker-images": "Imagenes de marcador", + "polygon-settings": "Ajustes de polígono", + "show-polygon": "Mostrar polígono", + "polygon-key-name": "Clave del polígono", + "enable-polygon-edit": "Polígono editable", + "polygon-label": "Etiqueta del polígono", + "show-polygon-label": "Mostrar etiqueta del polígono", + "use-polygon-label-function": "Usar funciones de etiqueta en el polígono", + "polygon-label-pattern": "Etiqueta del polígono (Ejemplos de patrón: '${entityName}', '${entityName}: (Texto ${keyName} unidades.)' )", + "polygon-label-function": "Función de etiqueta del polígono", + "polygon-tooltip": "Sugerencia polígono", + "show-polygon-tooltip": "Mostrar sugerencias", + "auto-close-polygon-tooltips": "Auto-cerrar sugerencias polígono", + "use-polygon-tooltip-function": "Usar función de sugerencias en el polígono", + "polygon-tooltip-pattern": "Sugerencias (por ej. 'Texto ${keyName} unidades.' o Texto Link')", + "polygon-tooltip-function": "Función de sugerencia de polígono", + "polygon-color": "Color de polígono", + "polygon-opacity": "Opacidad de polígono", + "use-polygon-color-function": "Usar función de color en polígono", + "polygon-color-function": "Función de color de polígono", + "polygon-stroke": "Trazo de polígono", + "stroke-color": "Color de trazo", + "stroke-opacity": "Opacidad de trazo", + "stroke-weight": "Peso de trazo", + "use-polygon-stroke-color-function": "Usar función de color de trazo en polígono", + "polygon-stroke-color-function": "Función de color de trazo", + "circle-settings": "Ajustes de círculo", + "show-circle": "Mostrar círculo", + "circle-key-name": "Clave de círculo", + "enable-circle-edit": "Activar edición de círculo", + "circle-label": "Etiqueta de círculo", + "show-circle-label": "Mostrar etiqueta de círculo", + "use-circle-label-function": "Usar función para etiqueta de círculo", + "circle-label-pattern": "Etiqueta de círculo (Ejemplos patrón: '${entityName}', '${entityName}: (Texto ${keyName} unidades.)' )", + "circle-label-function": "Funcion de etiqueta de círculo", + "circle-tooltip": "Sugerencias de círculo", + "show-circle-tooltip": "Mostrar sugerencias de círculo", + "auto-close-circle-tooltips": "Auto-cerrar sugerencias", + "use-circle-tooltip-function": "Usar función de sugerencias en círculo", + "circle-tooltip-pattern": "Sugerencia (por ej. 'Texto ${keyName} unidades.' o Texto Link')", + "circle-tooltip-function": "Función de sugerencia círculo", + "circle-fill-color": "Color de relleno círculo", + "circle-fill-color-opacity": "Opacidad color de relleno", + "use-circle-fill-color-function": "Usar función de color de relleno", + "circle-fill-color-function": "Función de color de relleno", + "circle-stroke": "Trazo del círculo", + "use-circle-stroke-color-function": "Usar función de color de trazo", + "circle-stroke-color-function": "Función de color de trazo", + "markers-clustering-settings": "Ajustes de agrupación de marcadores", + "use-map-markers-clustering": "Usar agrupación de marcadores en mapa", + "zoom-on-cluster-click": "Zoom cuando se haga click en un grupo", + "max-cluster-zoom": "Nivel máximo de zoom en la que un marcador puede ser parte de un grupo (0 - 18)", + "max-cluster-radius-pixels": "Radio máximo que un grupo cubre en píxeles", + "cluster-zoom-animation": "Mostrar animacion en marcadores cuando se haga zoom", + "show-markers-bounds-on-cluster-mouse-over": "Mostrar los limites de los marcadores cuando el raton pase por encima de un grupo", + "spiderfy-max-zoom-level": "Spiderfy al máximo nivel de zoom (para ver todos los marcadores)", + "load-optimization": "Optimización de carga", + "cluster-chunked-loading": "Usar fragmentos para añadir marcadores para que la página no se congele", + "cluster-markers-lazy-load": "Usar lazy load al añadir marcadores", + "editor-settings": "Ajustes del editor", + "enable-snapping": "Habilitar ajuste a otros vértices para dibujar con precisión", + "init-draggable-mode": "Inicializar mapa en modo arrastre", + "hide-all-edit-buttons": "Ocultar todos los botones de edición", + "hide-draw-buttons": "Ocultar botones de dibujo", + "hide-edit-buttons": "Ocultar botones de edición", + "hide-remove-button": "Ocultar botones de borrado", + "route-map-settings": "Ajustes de mapa de ruta", + "trip-animation-settings": "Ajustes de animación de ruta", + "normalization-step": "Pasos de normalización (ms)", + "tooltip-background-color": "Color de fondo de la sugerencia", + "tooltip-font-color": "Color de fuente de las sugerencias", + "tooltip-opacity": "Opacidad de las sugerencias (0-1)", + "auto-close-tooltip": "Auto-cerrar sugerencias", + "rotation-angle": "Ángulo de rotación adicional para el marcador (grados)", + "path-settings": "Ajustes de ruta", + "path-color": "Color de ruta", + "use-path-color-function": "Usar función de color de ruta", + "path-color-function": "Función de color de ruta", + "path-decorator": "Decorador de ruta", + "use-path-decorator": "Usar decorador de ruta", + "decorator-symbol": "Símbolo del decorador", + "decorator-symbol-arrow-head": "Flecha", + "decorator-symbol-dash": "Estrella", + "decorator-symbol-size": "Tamaño del decorador (px)", + "use-path-decorator-custom-color": "Usar color personalizado en el decorador", + "decorator-custom-color": "Color personalizado del decorador", + "decorator-offset": "Offset decorador", + "end-decorator-offset": "Offset final del decorador", + "decorator-repeat": "Repetición del decorador", + "points-settings": "Ajustes de puntos", + "show-points": "Mostrar puntos", + "point-color": "Color de puntos", + "point-size": "Tamaño de puntos (px)", + "use-point-color-function": "Usar función de color de puntos", + "point-color-function": "Función de color de puntos", + "use-point-as-anchor": "Usar punto como ancla", + "point-as-anchor-function": "Función de punto como ancla", + "independent-point-tooltip": "Sugerencia independiente en punto" }, "markdown": { - "use-markdown-text-function": "Use markdown/HTML value function", - "markdown-text-function": "Markdown/HTML value function", - "markdown-text-pattern": "Markdown/HTML pattern (markdown or HTML with variables, for ex. '${entityName} or ${keyName} - some text.')", + "use-markdown-text-function": "Usar función markdown/HTML", + "markdown-text-function": "Función de valor Markdown/HTML", + "markdown-text-pattern": "Patrón de Markdown/HTML (markdown o HTML con variables, por ej. '${entityName} o ${keyName} - texto.')", "markdown-css": "Markdown/HTML CSS" }, "simple-card": { - "label-position": "Label position", - "label-position-left": "Left", - "label-position-top": "Top" + "label-position": "Posición etiqueta", + "label-position-left": "Izquierda", + "label-position-top": "Superior" }, "table": { - "common-table-settings": "Common Table Settings", - "enable-search": "Enable search", - "enable-sticky-header": "Always display header", - "enable-sticky-action": "Always display actions column", - "hidden-cell-button-display-mode": "Hidden cell button actions display mode", - "show-empty-space-hidden-action": "Show empty space instead of hidden cell button action", - "dont-reserve-space-hidden-action": "Don't reserve space for hidden action buttons", - "display-timestamp": "Display timestamp column", - "display-milliseconds": "Display timestamp milliseconds", - "display-pagination": "Display pagination", - "default-page-size": "Default page size", - "use-entity-label-tab-name": "Use entity label in tab name", - "hide-empty-lines": "Hide empty lines", - "row-style": "Row style", - "use-row-style-function": "Use row style function", - "row-style-function": "Row style function", - "cell-style": "Cell style", - "use-cell-style-function": "Use cell style function", - "cell-style-function": "Cell style function", - "cell-content": "Cell content", - "use-cell-content-function": "Use cell content function", - "cell-content-function": "Cell content function", - "show-latest-data-column": "Show latest data column", - "latest-data-column-order": "Latest data column order", - "entities-table-title": "Entities table title", - "enable-select-column-display": "Enable select columns to display", - "display-entity-name": "Display entity name column", - "entity-name-column-title": "Entity name column title", - "display-entity-label": "Display entity label column", - "entity-label-column-title": "Entity label column title", - "display-entity-type": "Display entity type column", - "default-sort-order": "Default sort order", - "column-width": "Column width (px or %)", - "default-column-visibility": "Default column visibility", + "common-table-settings": "Ajustes comunes en tablas", + "enable-search": "Activar búsqueda", + "enable-sticky-header": "Mostrar siempre el encabezado", + "enable-sticky-action": "Mostrar siempre la columna de acciones", + "hidden-cell-button-display-mode": "Visualización de botones de acción oculta", + "show-empty-space-hidden-action": "Mostrar espacio vacío en lugar de celda oculta", + "dont-reserve-space-hidden-action": "No reservar espacio para los botones en celda oculta", + "display-timestamp": "Mostrar columna timestamp", + "display-milliseconds": "Mostrar milisegundos", + "display-pagination": "Mostrar páginas", + "default-page-size": "Tamaño de página por defecto", + "use-entity-label-tab-name": "Usar etiqueta de entidad en el nombre de la tabla", + "hide-empty-lines": "Ocultar líneas vacías", + "row-style": "Estilo de fila", + "use-row-style-function": "Usar función de estilo de fila", + "row-style-function": "Función de estilo de fila", + "cell-style": "Estilo de celda", + "use-cell-style-function": "Usar función de estilo de celda", + "cell-style-function": "Función de estilo de celda", + "cell-content": "Contenido de celda", + "use-cell-content-function": "Usar función de contenido de celda", + "cell-content-function": "Función de contenido de celda", + "show-latest-data-column": "Mostrar columna de últimos datos", + "latest-data-column-order": "Órden de columna de últimos datos", + "entities-table-title": "Título de tabla de entidades", + "enable-select-column-display": "Activar posibilidad de seleccionar columnas a mostrar", + "display-entity-name": "Mostrar columna de nombre de entidad", + "entity-name-column-title": "Título de columna en nombre de entidad", + "display-entity-label": "Mostrar columna de etiqueta de entidad", + "entity-label-column-title": "Título de columna en etiqueta de entidad", + "display-entity-type": "Mostrar columna de tipo de entidad", + "default-sort-order": "Ordenación por defecto", + "column-width": "Ancho de columna (px o %)", + "default-column-visibility": "Visibilidad por defecto en columna", "column-visibility-visible": "Visible", - "column-visibility-hidden": "Hidden", - "column-selection-to-display": "Column selection in 'Columns to Display'", - "column-selection-to-display-enabled": "Enabled", - "column-selection-to-display-disabled": "Disabled", - "alarms-table-title": "Alarms table title", - "enable-alarms-selection": "Enable alarms selection", - "enable-alarms-search": "Enable alarms search", - "enable-alarm-filter": "Enable alarm filter", - "display-alarm-details": "Display alarm details", - "allow-alarms-ack": "Allow alarms acknowledgment", - "allow-alarms-clear": "Allow alarms clear" + "column-visibility-hidden": "Oculta", + "column-selection-to-display": "Selección de columnas en 'Columnas a Mostrar'", + "column-selection-to-display-enabled": "Activada", + "column-selection-to-display-disabled": "Desactivada", + "alarms-table-title": "Título de tabla de alarmas", + "enable-alarms-selection": "Activar selección de alarmas", + "enable-alarms-search": "Activar búsqueda de alarmas", + "enable-alarm-filter": "Activar filtro de alarmas", + "display-alarm-details": "Mostrar detalles de alarma", + "allow-alarms-ack": "Permitir reconocimiento de alarmas", + "allow-alarms-clear": "Permitir borrado de alarmas" }, "value-source": { - "value-source": "Value source", - "predefined-value": "Predefined value", - "entity-attribute": "Value taken from entity attribute", - "value": "Value", - "source-entity-alias": "Source entity alias", - "source-entity-attribute": "Source entity attribute" + "value-source": "Origen valor", + "predefined-value": "Valor predefinido", + "entity-attribute": "Valor tomado de un atributo de entidad", + "value": "Valor", + "source-entity-alias": "Alias entidad de origen", + "source-entity-attribute": "Atributo entidad de origen" }, "widget-font": { - "font-family": "Font family", - "size": "Size", - "relative-font-size": "Relative font size (percents)", - "font-style": "Style", + "font-family": "Familia (font family)", + "size": "Tamaño", + "relative-font-size": "Tamaño fuente relativo (porcentaje)", + "font-style": "Estilo", "font-style-normal": "Normal", - "font-style-italic": "Italic", - "font-style-oblique": "Oblique", - "font-weight": "Weight", + "font-style-italic": "Cursiva", + "font-style-oblique": "Subrayada", + "font-weight": "Peso", "font-weight-normal": "Normal", - "font-weight-bold": "Bold", - "font-weight-bolder": "Bolder", + "font-weight-bold": "Negrita", + "font-weight-bolder": "Negrita+", "font-weight-lighter": "Lighter", "color": "Color", - "shadow-color": "Shadow color" + "shadow-color": "Color sombra" } }, "icon": { From 9669da0442bb0243c16e8f3651439b6a45d0aac8 Mon Sep 17 00:00:00 2001 From: devaskim Date: Fri, 3 Jun 2022 23:06:34 +0500 Subject: [PATCH 43/86] Add resource service to widget context. --- .../widget/dynamic-widget.component.ts | 2 ++ .../app/modules/home/models/services.map.ts | 4 +++- .../home/models/widget-component.models.ts | 2 ++ .../models/ace/service-completion.models.ts | 19 +++++++++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts index 7aa0f6933e..a76a65ab96 100644 --- a/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/dynamic-widget.component.ts @@ -38,6 +38,7 @@ import { EntityRelationService } from '@core/http/entity-relation.service'; import { EntityService } from '@core/http/entity.service'; import { DialogService } from '@core/services/dialog.service'; import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service'; +import { ResourceService } from '@core/http/resource.service'; import { DatePipe } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; import { DomSanitizer } from '@angular/platform-browser'; @@ -76,6 +77,7 @@ export class DynamicWidgetComponent extends PageComponent implements IDynamicWid this.ctx.entityService = $injector.get(EntityService); this.ctx.dialogs = $injector.get(DialogService); this.ctx.customDialog = $injector.get(CustomDialogService); + this.ctx.resourceService = $injector.get(ResourceService); this.ctx.date = $injector.get(DatePipe); this.ctx.translate = $injector.get(TranslateService); this.ctx.http = $injector.get(HttpClient); diff --git a/ui-ngx/src/app/modules/home/models/services.map.ts b/ui-ngx/src/app/modules/home/models/services.map.ts index 1f3a2bf5ae..e2ad5f1ad6 100644 --- a/ui-ngx/src/app/modules/home/models/services.map.ts +++ b/ui-ngx/src/app/modules/home/models/services.map.ts @@ -36,6 +36,7 @@ import { BroadcastService } from '@core/services/broadcast.service'; import { ImportExportService } from '@home/components/import-export/import-export.service'; import { DeviceProfileService } from '@core/http/device-profile.service'; import { OtaPackageService } from '@core/http/ota-package.service'; +import { ResourceService } from '@core/http/resource.service'; export const ServicesMap = new Map>( [ @@ -59,6 +60,7 @@ export const ServicesMap = new Map>( ['router', Router], ['importExport', ImportExportService], ['deviceProfileService', DeviceProfileService], - ['otaPackageService', OtaPackageService] + ['otaPackageService', OtaPackageService], + ['resourceService', ResourceService] ] ); diff --git a/ui-ngx/src/app/modules/home/models/widget-component.models.ts b/ui-ngx/src/app/modules/home/models/widget-component.models.ts index 3bb727f4f5..0d8700145e 100644 --- a/ui-ngx/src/app/modules/home/models/widget-component.models.ts +++ b/ui-ngx/src/app/modules/home/models/widget-component.models.ts @@ -72,6 +72,7 @@ import { EntityRelationService } from '@core/http/entity-relation.service'; import { EntityService } from '@core/http/entity.service'; import { DialogService } from '@core/services/dialog.service'; import { CustomDialogService } from '@home/components/widget/dialog/custom-dialog.service'; +import { ResourceService } from '@core/http/resource.service'; import { DatePipe } from '@angular/common'; import { TranslateService } from '@ngx-translate/core'; import { PageLink } from '@shared/models/page/page-link'; @@ -168,6 +169,7 @@ export class WidgetContext { entityService: EntityService; dialogs: DialogService; customDialog: CustomDialogService; + resourceService: ResourceService; date: DatePipe; translate: TranslateService; http: HttpClient; diff --git a/ui-ngx/src/app/shared/models/ace/service-completion.models.ts b/ui-ngx/src/app/shared/models/ace/service-completion.models.ts index 25c5b5dc7d..bcad0a000c 100644 --- a/ui-ngx/src/app/shared/models/ace/service-completion.models.ts +++ b/ui-ngx/src/app/shared/models/ace/service-completion.models.ts @@ -100,6 +100,8 @@ export const importEntitiesResultInfoHref = 'CustomDialogComponent'; +export const resourceInfoHref = 'Resource info'; + export const pageLinkArg: FunctionArg = { name: 'pageLink', type: 'PageLink', @@ -1300,6 +1302,23 @@ export const serviceCompletions: TbEditorCompletions = { }, } }, + resourceService: { + description: 'Resource Service API
' + + 'See ResourceService for API reference.', + meta: 'service', + type: 'ResourceService', + children: { + getResources: { + description: 'Find resources by search text', + meta: 'function', + args: [ + pageLinkArg, + requestConfigArg + ], + return: observablePageDataReturnType(resourceInfoHref) + }, + } + }, dialogs: { description: 'Dialogs Service API
' + 'See DialogService for API reference.', From 6f21de1d4d46f28db76fc46f856fe87e53594dab Mon Sep 17 00:00:00 2001 From: fe-dev Date: Mon, 6 Jun 2022 13:33:01 +0300 Subject: [PATCH 44/86] UI: Fix translation, console error and add height for menu visability --- ui-ngx/src/app/core/services/menu.service.ts | 2 +- .../home/components/profile/tenant-profile-data.component.ts | 2 +- .../app/modules/home/components/queue/queue-form.component.html | 2 +- ui-ngx/src/app/shared/models/queue.models.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ui-ngx/src/app/core/services/menu.service.ts b/ui-ngx/src/app/core/services/menu.service.ts index a655b0d8b1..f042ff6b5e 100644 --- a/ui-ngx/src/app/core/services/menu.service.ts +++ b/ui-ngx/src/app/core/services/menu.service.ts @@ -108,7 +108,7 @@ export class MenuService { name: 'admin.system-settings', type: 'toggle', path: '/settings', - height: '280px', + height: '320px', icon: 'settings', pages: [ { diff --git a/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.ts b/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.ts index dacf3df551..a6b02305d5 100644 --- a/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.ts +++ b/ui-ngx/src/app/modules/home/components/profile/tenant-profile-data.component.ts @@ -95,7 +95,7 @@ export class TenantProfileDataComponent implements ControlValueAccessor, OnInit, if (this.tenantProfileDataFormGroup.valid) { tenantProfileData = this.tenantProfileDataFormGroup.getRawValue(); } - this.propagateChange(tenantProfileData.configuration); + this.propagateChange(tenantProfileData?.configuration); } } diff --git a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.html b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.html index 5dee2afa87..fce4a9e499 100644 --- a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.html +++ b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.html @@ -16,7 +16,7 @@ --> -
+ admin.queue-name diff --git a/ui-ngx/src/app/shared/models/queue.models.ts b/ui-ngx/src/app/shared/models/queue.models.ts index dc90781d30..5814a6eeb9 100644 --- a/ui-ngx/src/app/shared/models/queue.models.ts +++ b/ui-ngx/src/app/shared/models/queue.models.ts @@ -75,7 +75,7 @@ export const QueueProcessingStrategyTypesMap = new Map Date: Mon, 6 Jun 2022 15:18:28 +0300 Subject: [PATCH 45/86] UI: Add translate for table cell --- .../pages/admin/queue/queues-table-config.resolver.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/admin/queue/queues-table-config.resolver.ts b/ui-ngx/src/app/modules/home/pages/admin/queue/queues-table-config.resolver.ts index 5af2735a49..24f33a8a03 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/queue/queues-table-config.resolver.ts +++ b/ui-ngx/src/app/modules/home/pages/admin/queue/queues-table-config.resolver.ts @@ -17,7 +17,12 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, Resolve, Router } from '@angular/router'; import { EntityTableColumn, EntityTableConfig } from '@home/models/entity/entities-table-config.models'; -import { QueueInfo, ServiceType } from '@shared/models/queue.models'; +import { + QueueInfo, + QueueProcessingStrategyTypesMap, + QueueSubmitStrategyTypesMap, + ServiceType +} from '@shared/models/queue.models'; import { select, Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { BroadcastService } from '@core/services/broadcast.service'; @@ -83,14 +88,14 @@ export class QueuesTableConfigResolver implements Resolve('partitions', 'admin.queue-partitions', '25%'), new EntityTableColumn('submitStrategy', 'admin.queue-submit-strategy', '25%', (entity: QueueInfo) => { - return entity.submitStrategy.type; + return this.translate.instant(QueueSubmitStrategyTypesMap.get(entity.submitStrategy.type).label); }, () => ({}), false ), new EntityTableColumn('processingStrategy', 'admin.queue-processing-strategy', '25%', (entity: QueueInfo) => { - return entity.processingStrategy.type; + return this.translate.instant(QueueProcessingStrategyTypesMap.get(entity.processingStrategy.type).label); }, () => ({}), false From 2fecf128a099b249da8b48851d2d97c3080e17d4 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Mon, 6 Jun 2022 16:13:33 +0300 Subject: [PATCH 46/86] UI: add for expansion panel header fix height --- .../modules/home/components/queue/queue-form.component.scss | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.scss b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.scss index c42c4d714d..13128ad29a 100644 --- a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.scss +++ b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.scss @@ -17,6 +17,10 @@ .queue-strategy { padding-bottom: 16px; + .mat-expansion-panel-header { + height: 50px; + } + .mat-expansion-panel-body { padding-bottom: 0 !important; } From b61ce04420ace1597bf6f6a014d969e06e5d4f7c Mon Sep 17 00:00:00 2001 From: fe-dev Date: Mon, 6 Jun 2022 17:47:02 +0300 Subject: [PATCH 47/86] UI: Fixed description for default created queues --- .../app/modules/home/components/queue/queue-form.component.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.ts b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.ts index bb86b1edcb..b84dfc9985 100644 --- a/ui-ngx/src/app/modules/home/components/queue/queue-form.component.ts +++ b/ui-ngx/src/app/modules/home/components/queue/queue-form.component.ts @@ -158,6 +158,8 @@ export class QueueFormComponent implements ControlValueAccessor, OnInit, OnDestr this.modelValue = value; if (isDefinedAndNotNull(this.modelValue)) { this.queueFormGroup.patchValue(this.modelValue, {emitEvent: false}); + this.queueFormGroup.get('additionalInfo').get('description') + .patchValue(this.modelValue.additionalInfo?.description, {emitEvent: false}); this.submitStrategyTypeChanged(); } if (!this.disabled && !this.queueFormGroup.valid) { From 16891917ee7a7a53793c55668bfa8d20477d6239 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Mon, 6 Jun 2022 18:41:58 +0300 Subject: [PATCH 48/86] Minor fixes for 2FA --- .../mfa/config/DefaultTwoFaConfigManager.java | 27 ++++++++++++++++--- .../model/mfa/PlatformTwoFaSettings.java | 2 ++ ui-ngx/src/app/core/services/menu.service.ts | 2 +- .../email-auth-dialog.component.scss | 15 ----------- .../home/pages/security/security.component.ts | 14 +++++----- .../login/two-factor-auth-login.component.ts | 9 +++++++ .../shared/models/two-factor-auth.models.ts | 7 +++-- 7 files changed, 47 insertions(+), 29 deletions(-) delete mode 100644 ui-ngx/src/app/modules/home/pages/profile/authentication-dialog/email-auth-dialog.component.scss diff --git a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/config/DefaultTwoFaConfigManager.java b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/config/DefaultTwoFaConfigManager.java index 23e6dc065f..ad2ecebd2c 100644 --- a/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/config/DefaultTwoFaConfigManager.java +++ b/application/src/main/java/org/thingsboard/server/service/security/auth/mfa/config/DefaultTwoFaConfigManager.java @@ -56,12 +56,31 @@ public class DefaultTwoFaConfigManager implements TwoFaConfigManager { @Override public Optional getAccountTwoFaSettings(TenantId tenantId, UserId userId) { + PlatformTwoFaSettings platformTwoFaSettings = getPlatformTwoFaSettings(tenantId, true).orElse(null); return Optional.ofNullable(userAuthSettingsDao.findByUserId(userId)) - .flatMap(userAuthSettings -> Optional.ofNullable(userAuthSettings.getTwoFaSettings())) - .map(twoFaSettings -> { - twoFaSettings.getConfigs().keySet().removeIf(providerType -> { - return getTwoFaProviderConfig(tenantId, providerType).isEmpty(); + .map(userAuthSettings -> { + AccountTwoFaSettings twoFaSettings = userAuthSettings.getTwoFaSettings(); + if (twoFaSettings == null) return null; + boolean updateNeeded; + + Map configs = twoFaSettings.getConfigs(); + updateNeeded = configs.keySet().removeIf(providerType -> { + return platformTwoFaSettings == null || platformTwoFaSettings.getProviderConfig(providerType).isEmpty(); }); + if (configs.size() == 1 && configs.containsKey(TwoFaProviderType.BACKUP_CODE)) { + configs.remove(TwoFaProviderType.BACKUP_CODE); + updateNeeded = true; + } + if (!configs.isEmpty() && configs.values().stream().noneMatch(TwoFaAccountConfig::isUseByDefault)) { + configs.values().stream() + .filter(config -> config.getProviderType() != TwoFaProviderType.BACKUP_CODE) + .findFirst().ifPresent(config -> config.setUseByDefault(true)); + updateNeeded = true; + } + + if (updateNeeded) { + twoFaSettings = saveAccountTwoFaSettings(tenantId, userId, twoFaSettings); + } return twoFaSettings; }); } diff --git a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/PlatformTwoFaSettings.java b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/PlatformTwoFaSettings.java index fd72e7a027..ec2acf8733 100644 --- a/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/PlatformTwoFaSettings.java +++ b/common/data/src/main/java/org/thingsboard/server/common/data/security/model/mfa/PlatformTwoFaSettings.java @@ -35,12 +35,14 @@ public class PlatformTwoFaSettings { @NotNull private List providers; + @NotNull @Min(value = 5, message = "minimum verification code sent period must be greater than or equal 5") private Integer minVerificationCodeSendPeriod; @Pattern(regexp = "[1-9]\\d*:[1-9]\\d*", message = "verification code check rate limit configuration is invalid") private String verificationCodeCheckRateLimit; @Min(value = 0, message = "maximum number of verification failure before user lockout must be positive") private Integer maxVerificationFailuresBeforeUserLockout; + @NotNull @Min(value = 60, message = "total amount of time allotted for verification must be greater than or equal 60") private Integer totalAllowedTimeForVerification; diff --git a/ui-ngx/src/app/core/services/menu.service.ts b/ui-ngx/src/app/core/services/menu.service.ts index a655b0d8b1..c9ff9f7da7 100644 --- a/ui-ngx/src/app/core/services/menu.service.ts +++ b/ui-ngx/src/app/core/services/menu.service.ts @@ -376,7 +376,7 @@ export class MenuService { name: 'admin.system-settings', type: 'toggle', path: '/settings', - height: '120px', + height: '80px', icon: 'settings', pages: [ { diff --git a/ui-ngx/src/app/modules/home/pages/profile/authentication-dialog/email-auth-dialog.component.scss b/ui-ngx/src/app/modules/home/pages/profile/authentication-dialog/email-auth-dialog.component.scss deleted file mode 100644 index ec6f008a80..0000000000 --- a/ui-ngx/src/app/modules/home/pages/profile/authentication-dialog/email-auth-dialog.component.scss +++ /dev/null @@ -1,15 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ diff --git a/ui-ngx/src/app/modules/home/pages/security/security.component.ts b/ui-ngx/src/app/modules/home/pages/security/security.component.ts index ab7d470e9e..560ec2b7d2 100644 --- a/ui-ngx/src/app/modules/home/pages/security/security.component.ts +++ b/ui-ngx/src/app/modules/home/pages/security/security.component.ts @@ -29,6 +29,7 @@ import { DatePipe } from '@angular/common'; import { ClipboardService } from 'ngx-clipboard'; import { TwoFactorAuthenticationService } from '@core/http/two-factor-authentication.service'; import { + AccountTwoFaSettingProviders, AccountTwoFaSettings, BackupCodeTwoFactorAuthAccountConfig, EmailTwoFactorAuthAccountConfig, @@ -49,7 +50,7 @@ import { isDefinedAndNotNull } from '@core/utils'; export class SecurityComponent extends PageComponent implements OnInit, OnDestroy { private readonly destroy$ = new Subject(); - private accountConfig: AccountTwoFaSettings; + private accountConfig: AccountTwoFaSettingProviders; twoFactorAuth: FormGroup; user: User; @@ -128,12 +129,11 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro } private processTwoFactorAuthConfig(setting: AccountTwoFaSettings) { - this.accountConfig = setting; - const configs = this.accountConfig.configs; + this.accountConfig = setting?.configs || {}; Object.values(TwoFactorAuthProviderType).forEach(provider => { - if (configs[provider]) { + if (this.accountConfig[provider]) { this.twoFactorAuth.get(provider).setValue(true); - if (configs[provider].useByDefault) { + if (this.accountConfig[provider].useByDefault) { this.useByDefault = provider; } } else { @@ -216,7 +216,7 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro } generateNewBackupCode() { - const codeLeft = this.accountConfig.configs[TwoFactorAuthProviderType.BACKUP_CODE].codesLeft; + const codeLeft = (this.accountConfig[TwoFactorAuthProviderType.BACKUP_CODE] as BackupCodeTwoFactorAuthAccountConfig).codesLeft; let subscription: Observable; if (codeLeft) { subscription = this.dialogService.confirm( @@ -240,7 +240,7 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro providerDataInfo(provider: TwoFactorAuthProviderType) { const info = {info: null}; - const providerConfig = this.accountConfig.configs[provider]; + const providerConfig = this.accountConfig[provider]; if (isDefinedAndNotNull(providerConfig)) { switch (provider) { case TwoFactorAuthProviderType.EMAIL: diff --git a/ui-ngx/src/app/modules/login/pages/login/two-factor-auth-login.component.ts b/ui-ngx/src/app/modules/login/pages/login/two-factor-auth-login.component.ts index 73401f2a0c..89105cd18e 100644 --- a/ui-ngx/src/app/modules/login/pages/login/two-factor-auth-login.component.ts +++ b/ui-ngx/src/app/modules/login/pages/login/two-factor-auth-login.component.ts @@ -29,6 +29,7 @@ import { import { TranslateService } from '@ngx-translate/core'; import { interval, Subscription } from 'rxjs'; import { isEqual } from '@core/utils'; +import {ActionNotificationShow} from "@core/notification/notification.actions"; @Component({ selector: 'tb-two-factor-auth-login', @@ -118,6 +119,14 @@ export class TwoFactorAuthLoginComponent extends PageComponent implements OnInit } this.verificationForm.get('verificationCode').setErrors(errors); }, 5000); + } else { + this.store.dispatch(new ActionNotificationShow( + { + message: error.error.message, + type: 'error', + verticalPosition: 'top', + horizontalPosition: 'left' + })); } } ); diff --git a/ui-ngx/src/app/shared/models/two-factor-auth.models.ts b/ui-ngx/src/app/shared/models/two-factor-auth.models.ts index 10040e00e7..d7961050ed 100644 --- a/ui-ngx/src/app/shared/models/two-factor-auth.models.ts +++ b/ui-ngx/src/app/shared/models/two-factor-auth.models.ts @@ -88,9 +88,12 @@ export interface BackupCodeTwoFactorAuthAccountConfig extends GeneralTwoFactorAu export type TwoFactorAuthAccountConfig = TotpTwoFactorAuthAccountConfig | SmsTwoFactorAuthAccountConfig | EmailTwoFactorAuthAccountConfig | BackupCodeTwoFactorAuthAccountConfig; - export interface AccountTwoFaSettings { - configs: {TwoFactorAuthProviderType: TwoFactorAuthAccountConfig}; + configs: AccountTwoFaSettingProviders; +} + +export type AccountTwoFaSettingProviders = { + [key in TwoFactorAuthProviderType]?: TwoFactorAuthAccountConfig; } export interface TwoFaProviderInfo { From 4082d901d020f6a3d75dc674d0fb68394b87fb23 Mon Sep 17 00:00:00 2001 From: kalutkaz Date: Tue, 7 Jun 2022 11:27:06 +0300 Subject: [PATCH 49/86] update Pie widgets --- .../data/json/system/widget_bundles/charts.json | 4 ++-- .../home/components/widget/lib/flot-widget.ts | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/application/src/main/data/json/system/widget_bundles/charts.json b/application/src/main/data/json/system/widget_bundles/charts.json index 2772c696bf..de32604dbb 100644 --- a/application/src/main/data/json/system/widget_bundles/charts.json +++ b/application/src/main/data/json/system/widget_bundles/charts.json @@ -54,7 +54,7 @@ }, { "alias": "pie", - "name": "Pie- Flot", + "name": "Pie - Flot", "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAACgCAIAAADGnbT+AAAABmJLR0QA/wD/AP+gvaeTAAAZTElEQVR42u2deXwUVbbH/e+tM/Pe5/Oe82beNjo6znvjvFFnRkFxF1f2RREQWQQEEZFNFDUCOjAoCKjsq+xG1hBCWAJkJSEJCQGyJyQkZN+7urq7lvt+1RU61dWd0Emqqm911/2cPzq9pdP1zT3nnnvO795BrGENHcYd1ldgDQss3YYoiDcr+NQkLvqQc/sGx5eL2Q9n2aePt49/lRk1gBn0jNeTk+4kKb8iab8jGX1JzkCS9xYp/YxUriMNsYQtJUSwvs4wBovjhGtXXAf2OZZF2KeNs738hO3Zh7swr9ee/5uuLOFnJP1PJG8iqVxLWtOIwFpghfrgef7yJefWdex7k20v9euapJ6DpbL4f5AmtpKFpPFMWEEW+mCJba3ciShHxAfwaN2CSRuwvCazfyJXhpHq3YRrssAyLU92O3fmBPvJHNuL/XrMk8ZgdUxj/0hyBpPaH0J4DgtBsISyUuemb5khz/aeJ73A8ljSz0nBdNKWaYFFdQjFnY6xz5igIU+6g+WxrKdJbSQRXRZYNA2Xkzt53P7mCD2QMggs2S7cI6UtQsI/mhwsp9MVuZsZ/oJ+SBkKlmwp/00qVhPBboEVlEhKwFqPeX2Q3kgFAaz22esucnMzEXkLLAOjqUvp9kmvG4NU0MCSLeMR0nTeAkv/JEJDvWPZZ7bnHjGSqmCCJdnfkrwJxFVrgaUTUyJ39AAz+FmDkaIALDkx8QtStRXfggWWxhMVu3B2UJCiBSzZsOftvGmBpc1AdkrbbKeJwZKnLqTsLbB6NRwOVLAEFynqwJIN1RMCY4HVI/dXU4WKKBqoohEsacHYh7AlFljdTChcSApWnG4asOStxsaTFlgB79Ac+sHWvw89VNELllQo8fek4jsLrNvnFFw7NlGFFO1gyVY0l7YcPU1guZxsxPxuXW/7lDH2ccP9PsQMec6x8i+OpREd9wx73rlulVRRM3pQqIEFuzaWquIIasByONC/EOBlZka+BESE4kLpdcsi/D6Hi4mSZsD6uvaXDHxKrLop5Ofy2RmoKWVee0W6//m+zIgXQwQsKcs1mJ6tazrAcrDsvBkBUoVnYgdanuE6A4ud+w68qhIs9qNZuEeqTu7fR2xscKxahjudG9YIuVdCByxYdn/C2yywblE1a0rgXol9f6pr/0601rj2bPcP1suPCxU3hMI8L7A+nYceL0xRuC1WVznXfs2MGUxYO/v+2yEFlsTWCzRUdAUbLI7DXNKzgLozsFz7vseUhhyYlysc+bLIMPCPgFJ6dMoYZDTwY+jEWEq7/AoRHGEMlig4Pl/Y45WaX7DsU8aiRhkNgzINHrCkh2ZM4M7EcvFxQNmx+EOxuZEZ2j80wZJi+dHBbZ0NJljONct7kwLwA1b/PgjPxdpqhOq+YHXE/oOeERvq5PIbrAMCyZmZDyxY8QfhCJaUBe1dbskXLOf61e57PsOmNUwui5A2sF941OuFRyL5zIv2qW9g16i9dGLm5BAEC4Zu7LACi8/OtL3wmOZgiS3Nfn8dInelQ8RyAZ0XfGYanxzPDHyaO3Uc81xogoW8fJD2fIIAltjUiOxl77Phfmasb1cg/+kx6XcxNtzoSKI+31coKoDsh0RhVaVzw2rccHy5RLS1hSZYcpmNJFUSHjOWkH8NSQHNwfKlQRVjIQcmlBbLvdHwhnziOUycXPRhoSg/ZMGCpf/Z+Bqb4AXvrN0+a6rBYEl2q+Me+Qg8Kj2npZmdMy2UwYLlTwmrdIPo2rsjmLvL/ftA/koV2ocmWLC6A6EJVp29flHKkjp7ndotFubZXnmKwoqGUAMLxVuOG6EGlkjEiOTFAw4Nee3Y6MTKJB+3yLJzpltgGZGRN6rPxyCwTpSeBFWyDTw0dEvONk7g1W4xco8Flu5WtSN0wGpgG1+NGu0BS7Y55+bXMDVqt1h+3Tb4GQssHS35F8b0vhoB1vKLK1RUyQbaEioS/RRmBVxCY4HVE8sdHwpgZdde9kuVxy1uyN7kElxqt9jrDR8LrK6sOd7cYAmiMP30zC7Akm3W2Tk3bVXq194otw3pb4GlT+vYw3rXPugLVuz1k7elSraRUa+fv+Hzb+RyOT6db4Gli1XvMitYTt45/sRbAYIl28r01Q5eXaEGtb6QAiv+J+TKSHJ9CSmaRzL7eVVQQY/U16CEKwXdvyTF8yVZ79R7NdLfulvXQlMdwYosONAtqmR7N25WRVuF2i1WVtj0l+0zAqzkfydtWV7vVrGm/SHmmr8EIC+JeCf+C2Gvk7YMKTaClDc02WQF+ZT/7NWH0bMhUS+wMPGMOf5mD8CCjYgaFVd+zo9bXLTA9GBV73TDtJok/iu5+EB7KhwnDMhTSOpvOyz7RSmZWX+kvf0Gt3HUCspgnDWkYIa7ju9D6eSLXmpS6tbVoxdYh4uO9owqpVtkefVczSecNTdYrgapGl32brDy5dIb5k/utEYv61npNlwnYm1MUbjNlkntqam/kbpxsp6jthJQF7A4gXszZlIvwYJhRVneWq52DjXV9tcGmBWspH+TJh5VHhyTk9pj/lIqdIH+u2dq4VulJ99YITlHlME0xEg/9j7SQsQmcqYBC46s91TJNuzoyKNFx3zI5RxLFpp+VZj5qDR7MXmSg1M9hNAeAwqRHU/uR2r2kbqDkltEmO+qk3LoFFc96ALW7HPztAJLthXpX7NcMN2i9mAhikc8LjrJpSd8jtz5Z4kbKPdh/ehnzruTOKskfSxok6b8lx8oe3B2gSnAym3I05Yq2aaeeqe0RV1iK9bV2kcPMh9YWOW1pkvxuMSHz6OF70m/pTSik6hoPWk6K6kpO9xBgrOaXHqqt59HhzNXtAdrVcY3eoAlu8WY0hPq38fzjuWLzQRWwk9JU5z0Pshj+W1/gJwaFmsIs/x4z35S7JV2v/QO9cekpWXNHikN0cuPVDiTdrCwjkMOXSewZPviwjKbSy1PwKcl6yqppRlY4EaOacq+6FQ0BgNHB/g9+tCWTa4vdq8NS0nxgvaaY6651zWAd2qed9AYrNNlZ3SlSraJsZPzGvLVbrGh3j52KO1gVax25+TqSPmXHVbykcIrZUguEikuP2V6LxHmqjTh4Ta8IVJcCMKg0Y2Ma++9s9aCuRqD9XFShAFgwYYeGXm0+JivW3SuXEo1WC0X/M3zpbf0PF6UfkQnYBdutN0nPtauy43EWPbzWkggDaEXrFZn6+DDw40BS7YlF/7S6mxT7/9kZdj6Pxr6m9DwqkjWe3KtvY/8+BZKwQq8lkFDm3Bi8rWGXLVbbG3R9rCdEKxu8DXkyegEC004xoMFG3Jk+KHCI6KqTUAQeik6EnZgSQI19IGFKtARR0cFBSzZFqd8AV+sDroyL2riFsMCLGTXtFMx1QysrNrsIFIl2/gTk67WX/Nxi60QzbLACmxtkUIdWNuu7Ag6WDCsHiLzD/hxixvXWGDd3q5/Th1YaOeiASzZFiZ+2sg2qVeL13IC6aYPa7CynqELLFQhDzkygh6wYCgzvFSTpXaLba32qWMtsDpPOvxM2henB6ycuitUUSXboMPD9uTuQ6eQN1yic9sGC6xOTdodpwasAwWHKASrK7eYd7VbAl1hBFblOorA+ip9JbVgwcYeH3+pVu0WCcPY351ogeVzEuIkisAKpCs1uIaW642XN/sqkTgDOxMqjMBCZwclYKHCHblvysGSbUH8wnq2Xu0WC3JtrzxpgdVRv6pFk7QGYKEN0BRUyTY6etzFap/4FLqVs9+2wGo3NALRABauk4nAkt0i0rm86CPQtX+nBZZkDbFUgIW6KHOBJdu88wtq7WqlKKGkyDbg6XAH6+YWKsDakrPdjGDJupUJFT66ldIZd9PDGiy5+SzoYKE3y6RgKVaLnNotHtwfvmDlT6UCLMPKkfWz98/NrWaq1W7xRpnt1gka4QVWziAqwII+jNnBcrvFMUmVyT6boE72o/fDDiz00NIA1qTYqd2v+Rzx+YWlu3P3brq81bdtesaZ9+Cevr+6a1HK5wMPD1VmCjbnbN1+5Xt06eiEF5RIsKGudotHIsMLrIt/oAIsXO9u1h2MK24uUb6DUpoGSt2iKCq3t+W6CbQrQmW5sKkI96CvUBYdQfUVtmu0ZWtm3OzKtptd/cEhD1bKr6gACw3K3bpyp8vi3DAdgWrytNPvymdVQIYUD70RMx7ppRZnyztnZo46Nja9Gk12ZG3Wejz0WfISlO9hHYeahSZH03dZ63Dn1ivb8xsLNJ+33LqVCeELFmqUaQBL6a0CMVSmo0DeswuEgk9yqzH/o8RPiCRWc1Z+CK4QP6KtHrfhOjGTye1lNUwtfOjE2ClovF6QsFA/t+irWykN1O+iWRRVAGhKhpTjleHk0uPkwq87mv5CYVfHhGBhKsLE4/nxVNlpvAmKW3B78slpmJYKGguRBZAnJE/R87iYCXbOjiejRAclVlgxIOOPH3WN6BHt3Wit6MZ3AVVPKC+0JJOGaKlNHgkhibxhkqILRPpk5TRTlPtRAdahoT2+crPOzsXshYsHByffsz9fipTh4HDkDtwibnjEIFD9DGVlrN3gFpelLW92tLwe/Ybeq8W/pn2lYVMU4RolrVGQV/sjqfhWEquF4AzIQ00BIpvzf0dHK+xPTDljKaN4xONITs49/4HnThADKSx4PflUgeiS477d1ZjwcIwKXBWYRljmgVJzmxn3vnpLUdcBHTaokrakkvoo94T3uSRpBJ3IS09KEx48lEEz1k+pAKtn7YSYhwqaCuH4wIdyRQY3h/vBHHhCGyreH1kJ1WtBGw68wJPlzT4UiM6LX6A5VXC+qtTDyjTnq4fsC8461mc6owq5tJt8YaNQw4iMi/DGHKoFVwvVNQiHeFxt0Ryp0bTd1WrUbg89SxrAAgQ9kPRAHyJeixhcef/e3P24c3Xmt55oDD+WtZapTndCTD311HS8Q2pVGpaWUKZEGkJbqoZHvYrFqfLP3HPVddfati7s7rVt/Xbaxh9jP09y7MhxnSrlMqv50mahkRUdHA7pMIQ8HMBku0Iaz0i6WTdWSdLwODkHMjXpD5Hk/whYAv4uKsDC6qy7PQ7ykYV78/arHkISC/fvurZH/nHa6RnEWyIQ01hJc+muXOkJ2ISR979XZ35jczFadmEcGlZp80plxV3n7lnf1jVYgdgTu5jJMezSFMfeq64TJRJ5ZS1ik0N08kaRJwd5IK96d0eQB/IuPugO8txgQdiNBrDkFFTghgwWXoXQGycMeExe+k05NQ0ZBBiYW5+9EXMVnolTnDyv/TgxAndiwsNteMOUmxeQPoUYCTKuGoKFHKzyD7xUzf/vRg2ouq09tLXt9cP2j887NmS6oou41Eq+qFGok1ytaJSrZaRVrS2bCrAikhd167JhBvJ9E0w/8qNIZV1vaa9gRIYdGzuqVadMlbxz3MA2ELd80kcJn2hF1YnrXmVuZS3Cn7fZDKAqEHvQTd4n8Y5v0p2H8rkLlVKQV2cX25wiJxCqhgZgKaNvDSulxsVMDMSrQq9Bw4p7TJzKPw3h0dO7GUqouq3dt77tlf3MO7Hs12nOfddc58v4q3VCRavY6pRcrWg6sLArHALVDVKmI3W5UvSB5cjwg3azUBWI/X5z24DIjiDvXBl/rV7wBHkibWBFl8SEAFWzz81X9kwjlH47hg0lqgKxR7YzWNVevMlTARa2is1O1fiYt1Qpq0UJjnCjymMplXSAZa72L7+p2jaXl5DpxkuusKUKVsuIVICFTQ/PSs10hpRVNVPj5dmLuF+vC1+q/m+zjZYYy9TVydjkVv4h2KX57Ya2cJ6uhh6wUwQW5aIgnVl8RaLyr0BO6MEttnCmCjYvzkERWEeKokxH1Z7cvco/AXvJj+9kwpwq2O6rLorAKm4uNhdVqzLWKD+/nSNwARZVsNx6gSKwkAFC+5RZqPowYaGyXwPbcJOPsxZSsPs32bTalNRM3BZVnaagasqp6aq+Z9RXWUjJNuaoZmeAaQYWKhTop2pU9FgUzis/9pp0p8WTx1amOqkDCwfa0J6yOjKs3l0N0bHmKODutnhSWEY1Tx1Y8C/BPfLktoYKQeUHTq7gf7PegqnD/rjNpmHVl5aHNOHsU2qpSqvyUvHLbxD+EPYpK5XNPcPSVd3gGWfK4+ikCi38ys9ZZRMf/d6iSm3HizhKwTL+IMxADCXO3h9SfGGflQhVG6ICfDOUgtWDMmW9DU36yto91O++cdRKhPqxt0+w2pKgMVhny8/TQ9XMuFnKdlPwNeeMlQj1b2hWoxosNNiMiKJibYhDmvBhlJ/trylWyqrT9aDmvRgag0WkdtNvgk4V6sMgdaT8VHuvuiyAOrPFiQ7NMdAeLBo2pMtby72Wq2g3XWcB1KmhmccEYGGg4y+IVKGRVflhcmqF322ykgudGhoVKW3/8h3Q7AsWVcdLTig/STlN7aZ0GqZz04CFQ7b005/twjZd3qJqN312j5Wy6srw/eikGaELWMRbr9YY+wJakoqUlYMnIw5aKavb2F6N6kWNAwviad1VU+5du+k8Vbvp9FgrZXUb67PDxnLEZGBhHCw06DxfSHOr2k2XJBpRu4d+npkn2VUXnRHxjs62iXDxVH36D221QUALSTWIaYVGebvRYDl5FxQ79KYKCmnYo1T+3i1ZRqSssI19vdlrjlQmYCF7NOsUe76cRyHKD7kuZe3vjVYBC1UIxbQ4xL47JLagvGX8CgNiJ7oK1OgIFrmlpK1ru2mVzesMHGxNGJOyinbXAnyb7vyfjW399zKVbZKE1ZO7GJkem0t0/2tJH0kJ1oRjdjyAplB8SMgPQQoLdy5NdmbV8AaDBalLXS+9vmAh7plxRsdeVpXUVnqVce2mQArikZ5ft/2y5FZkHRGA9WMeB4YmRrMqsKbGsJjbZHFACAzBZaPnDLpqow4bus4YGMnorWp0h87vT7LrLutE1dkb57wy/k0CwpdgxSuoR8VneHm/V6Q1LsquAuuR7dJkFpnr2nDJiRkOzz9bxkfmGrrdhGpsTfRkggwWxtLU5Xq3mzbYxaeCoZA2JYZFSAcpUdHtFlWP+oIl97AfLeBiiqUpDSJp+OQG/z98eM5hwEU3AixoskP/WEOqVqSvUr4/2k2HBandFLo0jDucQjLWN8HhFyyl/Abar1HJgynk4e02Y0JDQIyPGiJguaP4WK2o+iBe3W46JdgKaYjZ8+oFBE+DIpnAwdqZ44IDHfCDFPjjaRAPMiCjC+VSY664QWAhJ66J/uzkU9NU7aYLzwWn3fSBLTZMOZ4fITiLD7Mi1RkgWHCImGif2cMk3eBPl3K/32zDJUcaQtfPPP6YnRg17jDsN+EUiV624Y+KHqNqN/0uI2i1e/Bi2DW6/1bdBBpffSnvDCysCiH+CQla3MY2+V+SpVfNj3Og6ly/D/ynbbZaRgxBsDBwvlLv2k3rle92tDCY7aabsqT8QkYVj1wUwnZMPwi2VM0/nYE19qi9oEG4b0P7cjK2hEMvA3SOURel30rwdCln5LU2FCyMrzN6qN1d1FysfB/oZN4XVIW0e9e34UQdOXKXCKvmh/xoDzx493z4wT8y1bb28H/0Eb1irIh4h8EX2miwcAxOD+T/cAKF8k0QKSvjmyAaRCX7fm/rZSHhPe43uVe3tuyX9jMsR0IcLCJJnNV065zBHwsOKl+O/+/HrHbT7uQXcLiG8Vc5CGARt4J3gIcM4uxn5QtxtsdL+63avW60oaZW8kG5xMEBCyOqOPq2VH2c9Jmq3RRRi4ULJYUxlIKFseHypi6owgH3vGC1m/bcliQ5gnhxgwkWah+WpX3pv900+k3UoCqf/FWq1W7aDZt9mhVEEqZgub0bF5G82F+7abPyacjxWKx0S4iBD/Ypc0EGS05ALEhYqATLc16hPFBYco+lkNYdHVEHH/SrSgFYMlsfJ0XIVGXWZCkfstpNu0uVJ2drgSUNdENAAulYSbTyTpSHo57EwiVAe+s4S8NcRRdYUrwleqWHcTojasktXAI/qoQX6bmYNIHl7RzJq4eslFWghn4ykbIrSClYM09ZKatA98KDmAU1H1iJN/g/WmIeAZRYBWvHxqxgYdxsE30LUSzzmKem2QKrB0tFIrd0Wqaq2sPXYudovnR0gyWPY0VcEBsGKXR/BteChixYGPV2EdsUFlUo7pDLTS2wtBzoY3kgXM8pwVIGDdOieS6WmcAi7gN257o7PMMHKVQ/o3e5ySGa60qZDCx5QJslTE7axdIvs5o34zUyJVjEXfd3II/rG7rF75CiOFzACaJJr49pwZKHSyAH8zlZlSpkDP8t2y67nLypr4zJwfLgBakqCE2FwCy1I8fl4EPgmoQEWPJAqwVU9tDzacbQHh8bWoTmdXyhDJZnFDUJixIcpjhA9cEtNuTQc+uF0LsKIQiWPND7C3GzGbEsdGZp4wmypZBcO1nCuYRQ/fpDFyzPQKkuNoWgihb05CqSnJBSxlpP27NMLbCCPFBgmV0jrM1wojDcMA1cFOyjYhEiR/jVghg+X3Y4gaUcWMxfrhWwloSiFYpzNOQMJEGTGLlytKwheOKF8PyCwxUs38kM4tgomkPSFSdNoH58UjSLmQY6ETg/AusACKzBk3oM4sfP72NeO2yHvPYHZx1opoVWEV5ew4jWl2mBZQ0LLGuYbfw/UfikHjIsMFkAAAAASUVORK5CYII=", "description": "Displays latest values of the attributes or timeseries data for multiple entities in a pie chart. Supports numeric values only.", "descriptor": { @@ -69,7 +69,7 @@ "dataKeySettingsSchema": "{}\n", "settingsDirective": "tb-flot-pie-widget-settings", "dataKeySettingsDirective": "tb-flot-pie-key-settings", - "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"First\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = (prevValue-50) + Math.random() * 2 - 1;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value+50;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Second\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.6114638304362894,\"funcBody\":\"var value = (prevValue-20) + Math.random() * 2 - 1;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value+20;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Third\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.9955906536344441,\"funcBody\":\"var value = (prevValue-40) + Math.random() * 2 - 1;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value+40;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Fourth\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.9430835931647599,\"funcBody\":\"var value = (prevValue-50) + Math.random() * 2 - 1;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value+50;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"radius\":1,\"fontColor\":\"#545454\",\"fontSize\":10,\"decimals\":1,\"legend\":{\"show\":true,\"position\":\"nw\",\"labelBoxBorderColor\":\"#CCCCCC\",\"backgroundColor\":\"#F0F0F0\",\"backgroundOpacity\":0.85},\"innerRadius\":0,\"showLabels\":true,\"showPercentages\":true,\"stroke\":{\"width\":5},\"tilt\":1,\"animatedPie\":false},\"title\":\"Pie- Flot\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" + "defaultConfig": "{\"datasources\":[{\"type\":\"function\",\"name\":\"function\",\"dataKeys\":[{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"First\",\"color\":\"#2196f3\",\"settings\":{},\"_hash\":0.15479322438769105,\"funcBody\":\"var value = (prevValue-50) + Math.random() * 2 - 1;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value+50;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Second\",\"color\":\"#4caf50\",\"settings\":{},\"_hash\":0.6114638304362894,\"funcBody\":\"var value = (prevValue-20) + Math.random() * 2 - 1;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value+20;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Third\",\"color\":\"#f44336\",\"settings\":{},\"_hash\":0.9955906536344441,\"funcBody\":\"var value = (prevValue-40) + Math.random() * 2 - 1;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value+40;\"},{\"name\":\"f(x)\",\"type\":\"function\",\"label\":\"Fourth\",\"color\":\"#ffc107\",\"settings\":{},\"_hash\":0.9430835931647599,\"funcBody\":\"var value = (prevValue-50) + Math.random() * 2 - 1;\\nif (value < 0) {\\n\\tvalue = 0;\\n} else if (value > 100) {\\n\\tvalue = 100;\\n}\\nreturn value+50;\"}]}],\"timewindow\":{\"realtime\":{\"timewindowMs\":60000}},\"showTitle\":true,\"backgroundColor\":\"#fff\",\"color\":\"rgba(0, 0, 0, 0.87)\",\"padding\":\"8px\",\"settings\":{\"radius\":1,\"fontColor\":\"#545454\",\"fontSize\":10,\"decimals\":1,\"legend\":{\"show\":true,\"position\":\"nw\",\"labelBoxBorderColor\":\"#CCCCCC\",\"backgroundColor\":\"#F0F0F0\",\"backgroundOpacity\":0.85},\"innerRadius\":0,\"showLabels\":true,\"showPercentages\":true,\"stroke\":{\"width\":5},\"tilt\":1,\"animatedPie\":false},\"title\":\"Pie - Flot\",\"dropShadow\":true,\"enableFullscreen\":true,\"titleStyle\":{\"fontSize\":\"16px\",\"fontWeight\":400}}" } }, { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts index 979d60bb5b..fef3e487e9 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts @@ -312,6 +312,7 @@ export class TbFlot { if (this.settings.stroke) { this.options.series.pie.stroke.color = this.settings.stroke.color || '#fff'; this.options.series.pie.stroke.width = this.settings.stroke.width || 0; + this.scalingPieRadius(); } if (this.options.series.pie.label.show) { @@ -690,6 +691,16 @@ export class TbFlot { } } + private scalingPieRadius() { + // if (this.options.series.pie.stroke?.color !== '#fff' && this.options.series.pie.stroke?.width !== 0) { + let scalingLine; + this.ctx.width > this.ctx.height ? scalingLine = this.ctx.height : scalingLine = this.ctx.width; + let changeRadius = this.options.series.pie.stroke.width / scalingLine; + this.options.series.pie.radius = changeRadius < 1 ? this.settings.radius - changeRadius : 0; + console.log(this.options.series.pie.radius); + // } + } + public resize() { if (this.resizeTimeoutHandle) { clearTimeout(this.resizeTimeoutHandle); @@ -698,10 +709,15 @@ export class TbFlot { if (this.plot && this.plotInited) { const width = this.$element.width(); const height = this.$element.height(); + // if (this.chartType === 'pie') { + // this.scalingPieRadius(); + // } if (width && height) { this.plot.resize(); if (this.chartType !== 'pie') { this.plot.setupGrid(); + } else { + this.scalingPieRadius(); } this.plot.draw(); } else { From 3b70c334ccb63fa17626128674f89146bde25481 Mon Sep 17 00:00:00 2001 From: Viacheslav Klimov Date: Tue, 7 Jun 2022 13:04:37 +0300 Subject: [PATCH 50/86] Update 2fa tests --- .../server/controller/TwoFactorAuthConfigTest.java | 7 ++++++- .../thingsboard/server/controller/TwoFactorAuthTest.java | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java index ee93cadaa4..db15e6fd82 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthConfigTest.java @@ -96,6 +96,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest { PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings(); twoFaSettings.setProviders(List.of(totpTwoFaProviderConfig, smsTwoFaProviderConfig)); + twoFaSettings.setMinVerificationCodeSendPeriod(5); twoFaSettings.setVerificationCodeCheckRateLimit("3:900"); twoFaSettings.setMaxVerificationFailuresBeforeUserLockout(10); twoFaSettings.setTotalAllowedTimeForVerification(3600); @@ -117,6 +118,7 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest { twoFaSettings.setVerificationCodeCheckRateLimit("0:12"); twoFaSettings.setMaxVerificationFailuresBeforeUserLockout(-1); twoFaSettings.setTotalAllowedTimeForVerification(0); + twoFaSettings.setMinVerificationCodeSendPeriod(5); String errorMessage = getErrorMessage(doPost("/api/2fa/settings", twoFaSettings) .andExpect(status().isBadRequest())); @@ -156,6 +158,8 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest { private String savePlatformTwoFaSettingsAndGetError(TwoFaProviderConfig invalidTwoFaProviderConfig) throws Exception { PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings(); twoFaSettings.setProviders(Collections.singletonList(invalidTwoFaProviderConfig)); + twoFaSettings.setMinVerificationCodeSendPeriod(5); + twoFaSettings.setTotalAllowedTimeForVerification(100); return getErrorMessage(doPost("/api/2fa/settings", twoFaSettings) .andExpect(status().isBadRequest())); @@ -432,8 +436,9 @@ public abstract class TwoFactorAuthConfigTest extends AbstractControllerTest { private void saveProvidersConfigs(TwoFaProviderConfig... providerConfigs) throws Exception { PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings(); - twoFaSettings.setProviders(Arrays.stream(providerConfigs).collect(Collectors.toList())); + twoFaSettings.setMinVerificationCodeSendPeriod(5); + twoFaSettings.setTotalAllowedTimeForVerification(100); doPost("/api/2fa/settings", twoFaSettings).andExpect(status().isOk()); } diff --git a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java index b825571694..9c30ebbbd0 100644 --- a/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/TwoFactorAuthTest.java @@ -355,6 +355,8 @@ public abstract class TwoFactorAuthTest extends AbstractControllerTest { emailTwoFaProviderConfig.setVerificationCodeLifetime(60); platformTwoFaSettings.setProviders(List.of(totpTwoFaProviderConfig, smsTwoFaProviderConfig, emailTwoFaProviderConfig)); + platformTwoFaSettings.setMinVerificationCodeSendPeriod(5); + platformTwoFaSettings.setTotalAllowedTimeForVerification(100); twoFaConfigManager.savePlatformTwoFaSettings(TenantId.SYS_TENANT_ID, platformTwoFaSettings); User twoFaUser = new User(); @@ -409,6 +411,8 @@ public abstract class TwoFactorAuthTest extends AbstractControllerTest { PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings(); twoFaSettings.setProviders(Arrays.stream(new TwoFaProviderConfig[]{totpTwoFaProviderConfig}).collect(Collectors.toList())); + twoFaSettings.setMinVerificationCodeSendPeriod(5); + twoFaSettings.setTotalAllowedTimeForVerification(100); Arrays.stream(customizer).forEach(c -> c.accept(twoFaSettings)); twoFaConfigManager.savePlatformTwoFaSettings(TenantId.SYS_TENANT_ID, twoFaSettings); @@ -425,6 +429,8 @@ public abstract class TwoFactorAuthTest extends AbstractControllerTest { PlatformTwoFaSettings twoFaSettings = new PlatformTwoFaSettings(); twoFaSettings.setProviders(Arrays.stream(new TwoFaProviderConfig[]{smsTwoFaProviderConfig}).collect(Collectors.toList())); + twoFaSettings.setMinVerificationCodeSendPeriod(5); + twoFaSettings.setTotalAllowedTimeForVerification(100); twoFaConfigManager.savePlatformTwoFaSettings(TenantId.SYS_TENANT_ID, twoFaSettings); SmsTwoFaAccountConfig smsTwoFaAccountConfig = new SmsTwoFaAccountConfig(); From c2c59114dbea1f7a9c63ed309872a529773a51a0 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Tue, 7 Jun 2022 13:07:57 +0300 Subject: [PATCH 51/86] UI: add phone input with country flags for sms authenticator --- .../sms-auth-dialog.component.html | 15 +-------------- .../shared/components/phone-input.component.html | 6 ++---- .../shared/components/phone-input.component.scss | 1 + .../shared/components/phone-input.component.ts | 16 ++++++---------- .../src/assets/locale/locale.constant-en_US.json | 3 ++- 5 files changed, 12 insertions(+), 29 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html b/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html index d4fb60095a..bb547f56a3 100644 --- a/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html @@ -37,20 +37,7 @@

security.2fa.dialog.sms-step-description

- - - - - {{ 'admin.number-to-required' | translate }} - - - {{ 'admin.phone-number-pattern' | translate }} - - - +
- + phone-input.phone-input-label + {{ 'phone-input.phone-input-required' | translate }} {{ 'phone-input.phone-input-validation' | translate }} - - {{ 'phone-input.phone-input-pattern' | translate }} -
diff --git a/ui-ngx/src/app/shared/components/phone-input.component.scss b/ui-ngx/src/app/shared/components/phone-input.component.scss index 0145a13d62..872c686af0 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.scss +++ b/ui-ngx/src/app/shared/components/phone-input.component.scss @@ -21,6 +21,7 @@ .phone-input { width: 100%; + max-width: 290px; } } diff --git a/ui-ngx/src/app/shared/components/phone-input.component.ts b/ui-ngx/src/app/shared/components/phone-input.component.ts index 536b1cc723..bbee8098f6 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.ts +++ b/ui-ngx/src/app/shared/components/phone-input.component.ts @@ -33,6 +33,7 @@ import examples from 'libphonenumber-js/examples.mobile.json'; import { CountryCode, getExampleNumber, parsePhoneNumberFromString } from 'libphonenumber-js'; import { phoneNumberPattern } from '@shared/models/settings.models'; import { Subscription } from 'rxjs'; +import { FloatLabelType, MatFormFieldAppearance } from '@angular/material/form-field/form-field'; @Component({ selector: 'tb-phone-input', @@ -58,15 +59,8 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida @Input() defaultCountry: CountryCode = 'US'; @Input() enableFlagsSelect = true; @Input() required = true; - - private floatLabel = 'always'; - get showLabel(): string { - return this.floatLabel; - } - @Input() - set showLabel(value) { - this.floatLabel = value ? 'always' : 'never'; - } + @Input() floatLabel: FloatLabelType = 'always'; + @Input() appearance: MatFormFieldAppearance = 'legacy'; allCountries: Array = []; phonePlaceholder: string; @@ -134,6 +128,8 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida focus() { const phoneNumber = this.phoneFormGroup.get('phoneNumber'); + this.phoneFormGroup.markAsPristine(); + this.phoneFormGroup.markAsUntouched(); if (!phoneNumber.value) { phoneNumber.patchValue(this.countryCallingCode); } @@ -220,7 +216,7 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida private updateModel() { const phoneNumber = this.phoneFormGroup.get('phoneNumber'); - if (phoneNumber.valid && this.modelValue !== phoneNumber.value) { + if (phoneNumber.valid && phoneNumber.value) { this.modelValue = phoneNumber.value; this.propagateChange(this.modelValue); } else { diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index b4bd223ed4..d8a08a5677 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -4435,7 +4435,8 @@ "phone-input-label": "Phone number", "phone-input-required": "Phone number is required", "phone-input-validation": "Phone number is invalid or not possible", - "phone-input-pattern": "Invalid phone number. Should be in E.164 format, ex. {{phoneNumber}}" + "phone-input-pattern": "Invalid phone number. Should be in E.164 format, ex. {{phoneNumber}}", + "phone-input-hint": "Phone Number in E.164 format, ex. {{phoneNumber}}" }, "custom": { "widget-action": { From 676a2b645ade72c30f537424397ac1b1f9e35344 Mon Sep 17 00:00:00 2001 From: kalutkaz Date: Tue, 7 Jun 2022 13:26:04 +0300 Subject: [PATCH 52/86] deleteMinWidth --- .../date-range-navigator-panel.component.scss | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/date-range-navigator/date-range-navigator-panel.component.scss b/ui-ngx/src/app/modules/home/components/widget/lib/date-range-navigator/date-range-navigator-panel.component.scss index 036398d48e..9ed640d33d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/date-range-navigator/date-range-navigator-panel.component.scss +++ b/ui-ngx/src/app/modules/home/components/widget/lib/date-range-navigator/date-range-navigator-panel.component.scss @@ -29,7 +29,6 @@ .mat-padding { padding: 16px; - min-width: 560px; } - + } From 25f3cf640a3774ac7d5b62c05122c4a1e14d9c82 Mon Sep 17 00:00:00 2001 From: kalutkaz Date: Thu, 9 Jun 2022 13:25:19 +0300 Subject: [PATCH 53/86] updated scaling radius object --- .../home/components/widget/lib/flot-widget.ts | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts index fef3e487e9..3c93d03e84 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/flot-widget.ts @@ -312,7 +312,9 @@ export class TbFlot { if (this.settings.stroke) { this.options.series.pie.stroke.color = this.settings.stroke.color || '#fff'; this.options.series.pie.stroke.width = this.settings.stroke.width || 0; - this.scalingPieRadius(); + if (this.options.series.pie.stroke.width) { + this.scalingPieRadius(); + } } if (this.options.series.pie.label.show) { @@ -692,13 +694,10 @@ export class TbFlot { } private scalingPieRadius() { - // if (this.options.series.pie.stroke?.color !== '#fff' && this.options.series.pie.stroke?.width !== 0) { let scalingLine; this.ctx.width > this.ctx.height ? scalingLine = this.ctx.height : scalingLine = this.ctx.width; let changeRadius = this.options.series.pie.stroke.width / scalingLine; this.options.series.pie.radius = changeRadius < 1 ? this.settings.radius - changeRadius : 0; - console.log(this.options.series.pie.radius); - // } } public resize() { @@ -707,21 +706,21 @@ export class TbFlot { this.resizeTimeoutHandle = null; } if (this.plot && this.plotInited) { - const width = this.$element.width(); - const height = this.$element.height(); - // if (this.chartType === 'pie') { - // this.scalingPieRadius(); - // } - if (width && height) { - this.plot.resize(); - if (this.chartType !== 'pie') { - this.plot.setupGrid(); - } else { + if (this.chartType === 'pie' && this.settings.stroke?.width) { this.scalingPieRadius(); - } - this.plot.draw(); + this.redrawPlot(); } else { - this.resizeTimeoutHandle = setTimeout(this.resize.bind(this), 30); + const width = this.$element.width(); + const height = this.$element.height(); + if (width && height) { + this.plot.resize(); + if (this.chartType !== 'pie') { + this.plot.setupGrid(); + } + this.plot.draw(); + } else { + this.resizeTimeoutHandle = setTimeout(this.resize.bind(this), 30); + } } } } From 863200d6e7b7ddffa0a6e42feaf3dcddccb739f1 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Thu, 9 Jun 2022 18:02:31 +0300 Subject: [PATCH 54/86] UI: refactoring --- .../home/components/entity/entities-table.component.html | 2 +- .../home/components/entity/entities-table.component.ts | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html index c3350c63a4..5f023b2efb 100644 --- a/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html +++ b/ui-ngx/src/app/modules/home/components/entity/entities-table.component.html @@ -262,7 +262,7 @@ class="no-data-found">{{ 'common.loading' | translate }}
- { - this.paginator.pageIndex = Number(params.page) || 0; - this.paginator.pageSize = Number(params.pageSize) || this.defaultPageSize; + if (this.displayPagination) { + this.paginator.pageIndex = Number(params.page) || 0; + this.paginator.pageSize = Number(params.pageSize) || this.defaultPageSize; + } this.sort.active = params.property || this.entitiesTableConfig.defaultSortOrder.property; this.sort.direction = (params.direction || this.entitiesTableConfig.defaultSortOrder.direction).toLowerCase() as SortDirection; if (params.hasOwnProperty('textSearch') && !isEmptyStr(params.textSearch)) { From fedd644516e58c1215640154e65ae6e904f385e6 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Thu, 9 Jun 2022 18:20:34 +0300 Subject: [PATCH 55/86] UI: move change password with profile to security --- ui-ngx/src/app/core/auth/auth.service.ts | 11 +- .../change-password-dialog.component.html | 64 --------- .../change-password-dialog.component.scss | 17 --- .../change-password-dialog.component.ts | 70 ---------- .../home/pages/profile/profile.component.html | 18 --- .../home/pages/profile/profile.component.scss | 6 - .../home/pages/profile/profile.component.ts | 55 +------- .../home/pages/profile/profile.module.ts | 4 +- .../pages/security/security.component.html | 115 +++++++++++++--- .../pages/security/security.component.scss | 55 ++++++-- .../home/pages/security/security.component.ts | 127 +++++++++++++++++- .../assets/locale/locale.constant-en_US.json | 21 ++- .../assets/locale/locale.constant-ru_RU.json | 1 - .../assets/locale/locale.constant-uk_UA.json | 1 - .../assets/locale/locale.constant-zh_CN.json | 1 - ui-ngx/src/theme.scss | 7 + 16 files changed, 305 insertions(+), 268 deletions(-) delete mode 100644 ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.html delete mode 100644 ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.scss delete mode 100644 ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.ts diff --git a/ui-ngx/src/app/core/auth/auth.service.ts b/ui-ngx/src/app/core/auth/auth.service.ts index 527c4cb6de..e26d7813da 100644 --- a/ui-ngx/src/app/core/auth/auth.service.ts +++ b/ui-ngx/src/app/core/auth/auth.service.ts @@ -23,7 +23,7 @@ import { catchError, map, mergeMap, tap } from 'rxjs/operators'; import { LoginRequest, LoginResponse, PublicLoginRequest } from '@shared/models/login.models'; import { ActivatedRoute, Router, UrlTree } from '@angular/router'; -import { defaultHttpOptions } from '../http/http-utils'; +import { defaultHttpOptions, defaultHttpOptionsFromConfig, RequestConfig } from '../http/http-utils'; import { UserService } from '../http/user.service'; import { Store } from '@ngrx/store'; import { AppState } from '../core.state'; @@ -47,6 +47,7 @@ import { AlertDialogComponent } from '@shared/components/dialog/alert-dialog.com import { OAuth2ClientInfo, PlatformType } from '@shared/models/oauth2.models'; import { isMobileApp } from '@core/utils'; import { TwoFactorAuthProviderType, TwoFaProviderInfo } from '@shared/models/two-factor-auth.models'; +import { UserPasswordPolicy } from '@shared/models/settings.models'; @Injectable({ providedIn: 'root' @@ -163,14 +164,18 @@ export class AuthService { )); } - public changePassword(currentPassword: string, newPassword: string) { - return this.http.post('/api/auth/changePassword', {currentPassword, newPassword}, defaultHttpOptions()).pipe( + public changePassword(currentPassword: string, newPassword: string, config?: RequestConfig) { + return this.http.post('/api/auth/changePassword', {currentPassword, newPassword}, defaultHttpOptionsFromConfig(config)).pipe( tap((loginResponse: LoginResponse) => { this.setUserFromJwtToken(loginResponse.token, loginResponse.refreshToken, false); } )); } + public getUserPasswordPolicy() { + return this.http.get(`/api/noauth/userPasswordPolicy`, defaultHttpOptions()); + } + public activateByEmailCode(emailCode: string): Observable { return this.http.post(`/api/noauth/activateByEmailCode?emailCode=${emailCode}`, null, defaultHttpOptions()); diff --git a/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.html b/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.html deleted file mode 100644 index b5f6d81459..0000000000 --- a/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.html +++ /dev/null @@ -1,64 +0,0 @@ - -
- -

profile.change-password

- - -
- - -
-
- - profile.current-password - - lock - - - - login.new-password - - lock - - - - login.new-password-again - - lock - - -
-
- - -
-
diff --git a/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.scss b/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.scss deleted file mode 100644 index 2d8406456a..0000000000 --- a/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.scss +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -:host { -} diff --git a/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.ts b/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.ts deleted file mode 100644 index 782bcb0f4d..0000000000 --- a/ui-ngx/src/app/modules/home/pages/profile/change-password-dialog.component.ts +++ /dev/null @@ -1,70 +0,0 @@ -/// -/// Copyright © 2016-2022 The Thingsboard Authors -/// -/// Licensed under the Apache License, Version 2.0 (the "License"); -/// you may not use this file except in compliance with the License. -/// You may obtain a copy of the License at -/// -/// http://www.apache.org/licenses/LICENSE-2.0 -/// -/// Unless required by applicable law or agreed to in writing, software -/// distributed under the License is distributed on an "AS IS" BASIS, -/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -/// See the License for the specific language governing permissions and -/// limitations under the License. -/// - -import { Component, OnInit } from '@angular/core'; -import { MatDialogRef } from '@angular/material/dialog'; -import { Store } from '@ngrx/store'; -import { AppState } from '@core/core.state'; -import { FormBuilder, FormGroup } from '@angular/forms'; -import { ActionNotificationShow } from '@core/notification/notification.actions'; -import { TranslateService } from '@ngx-translate/core'; -import { AuthService } from '@core/auth/auth.service'; -import { DialogComponent } from '@shared/components/dialog.component'; -import { Router } from '@angular/router'; - -@Component({ - selector: 'tb-change-password-dialog', - templateUrl: './change-password-dialog.component.html', - styleUrls: ['./change-password-dialog.component.scss'] -}) -export class ChangePasswordDialogComponent extends DialogComponent implements OnInit { - - changePassword: FormGroup; - - constructor(protected store: Store, - protected router: Router, - private translate: TranslateService, - private authService: AuthService, - public dialogRef: MatDialogRef, - public fb: FormBuilder) { - super(store, router, dialogRef); - } - - ngOnInit(): void { - this.buildChangePasswordForm(); - } - - buildChangePasswordForm() { - this.changePassword = this.fb.group({ - currentPassword: [''], - newPassword: [''], - newPassword2: [''] - }); - } - - onChangePassword(): void { - if (this.changePassword.get('newPassword').value !== this.changePassword.get('newPassword2').value) { - this.store.dispatch(new ActionNotificationShow({ message: this.translate.instant('login.passwords-mismatch-error'), - type: 'error' })); - } else { - this.authService.changePassword( - this.changePassword.get('currentPassword').value, - this.changePassword.get('newPassword').value).subscribe(() => { - this.dialogRef.close(true); - }); - } - } -} diff --git a/ui-ngx/src/app/modules/home/pages/profile/profile.component.html b/ui-ngx/src/app/modules/home/pages/profile/profile.component.html index 7300f7ea7c..3a15616055 100644 --- a/ui-ngx/src/app/modules/home/pages/profile/profile.component.html +++ b/ui-ngx/src/app/modules/home/pages/profile/profile.component.html @@ -78,24 +78,6 @@ {{ 'dashboard.home-dashboard-hide-toolbar' | translate }}
-
-
- -
-
- -
{{ expirationJwtData }}
-
-
-
{{ expirationJwtData }}
+ + +
+
+
+

profile.change-password

+ + profile.current-password + + + + {{ 'security.password-requirement.incorrect-password-try-again' | translate }} + + + + login.new-password + + + + {{ 'security.password-requirement.password-not-meet-requirements' | translate }} + + + {{ changePassword.get('newPassword').getError('alreadyUsed') }} + + + {{ 'security.password-requirement.password-should-difference' | translate }} + + + {{ 'security.password-requirement.password-should-not-contain-spaces' | translate }} + + +
+ +
+ + login.new-password-again + + + + {{ 'security.password-requirement.new-passwords-not-match' | translate }} + + +
+ +
+ +
+
+ +
+

security.password-requirement.password-requirements

+

security.password-requirement.at-least

+

+ + {{ 'security.password-requirement.uppercase-letter' | translate : {count: passwordPolicy.minimumUppercaseLetters} }} +

+

+ + {{ 'security.password-requirement.lowercase-letter' | translate : {count: passwordPolicy.minimumLowercaseLetters} }} +

+

+ + {{ 'security.password-requirement.digit' | translate : {count: passwordPolicy.minimumDigits} }} +

+

+ + {{ 'security.password-requirement.special-character' | translate : {count: passwordPolicy.minimumSpecialCharacters} }} +

+

+ + {{ 'security.password-requirement.character' | translate : {count: passwordPolicy.minimumLength} }} +

+
+
+
+ + +
+
+
+
- admin.2fa.2fa + admin.2fa.2fa
security.2fa.2fa-description
diff --git a/ui-ngx/src/app/modules/home/pages/security/security.component.scss b/ui-ngx/src/app/modules/home/pages/security/security.component.scss index 7dad927038..16f19e09bf 100644 --- a/ui-ngx/src/app/modules/home/pages/security/security.component.scss +++ b/ui-ngx/src/app/modules/home/pages/security/security.component.scss @@ -21,6 +21,7 @@ } mat-card.profile-card { + padding: 24px; @media #{$mat-gt-sm} { width: 70%; } @@ -31,23 +32,54 @@ width: 45%; } - .mat-subheader { - line-height: 24px; - color: rgba(0, 0, 0, 0.54); + .card-title { + font: 500 18px / 24px Roboto, "Helvetica Neue", sans-serif; + letter-spacing: 0.15px; + margin-top: 0; + } + + .mat-h4 { + font-weight: 500; font-size: 14px; - font-weight: 400; + letter-spacing: 0.25px; + margin: 0 0 4px; + } + + .change-password { + margin: 0; + + .mat-divider.mat-divider-vertical { + margin-bottom: 25px; + } + + .mat-form-field { + margin-bottom: 4px; + } + + .password-requirements > p { + margin: 0 0 8px; + letter-spacing: 0.25px; + color: rgba(0, 0, 0, 0.87); + } + + .mat-icon[data-mat-icon-name="check"] { + color: #24A148; + } } - .profile-last-login-ts { - font-size: 16px; - font-weight: 400; + .auth-title { + font-weight: 500; + margin: 0; } - .profile-btn-subtext { + .token-text { font: 400 14px / 16px Roboto, "Helvetica Neue", sans-serif; letter-spacing: 0.25px; - opacity: 0.6; padding: 8px 0; + + > .date { + opacity: .7; + } } } @@ -91,3 +123,8 @@ } } } +:host ::ng-deep { + .mat-form-field-appearance-fill .mat-form-field-underline::before { + background-color: transparent; + } +} diff --git a/ui-ngx/src/app/modules/home/pages/security/security.component.ts b/ui-ngx/src/app/modules/home/pages/security/security.component.ts index ab7d470e9e..8b723a0ab5 100644 --- a/ui-ngx/src/app/modules/home/pages/security/security.component.ts +++ b/ui-ngx/src/app/modules/home/pages/security/security.component.ts @@ -19,7 +19,15 @@ import { User } from '@shared/models/user.model'; import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; -import { FormBuilder, FormGroup } from '@angular/forms'; +import { + AbstractControl, + FormBuilder, + FormGroup, FormGroupDirective, + NgForm, + ValidationErrors, + ValidatorFn, + Validators +} from '@angular/forms'; import { TranslateService } from '@ngx-translate/core'; import { MatDialog } from '@angular/material/dialog'; import { DialogService } from '@core/services/dialog.service'; @@ -39,7 +47,9 @@ import { import { authenticationDialogMap } from '@home/pages/security/authentication-dialog/authentication-dialog.map'; import { takeUntil, tap } from 'rxjs/operators'; import { Observable, of, Subject } from 'rxjs'; -import { isDefinedAndNotNull } from '@core/utils'; +import { isDefinedAndNotNull, isEqual } from '@core/utils'; +import { AuthService } from '@core/auth/auth.service'; +import { UserPasswordPolicy } from '@shared/models/settings.models'; @Component({ selector: 'tb-security', @@ -52,7 +62,11 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro private accountConfig: AccountTwoFaSettings; twoFactorAuth: FormGroup; + changePassword: FormGroup; + user: User; + passwordPolicy: UserPasswordPolicy; + allowTwoFactorProviders: TwoFactorAuthProviderType[] = []; providersData = twoFactorAuthProvidersData; twoFactorAuthProviderType = TwoFactorAuthProviderType; @@ -80,6 +94,7 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro public dialogService: DialogService, public fb: FormBuilder, private datePipe: DatePipe, + private authService: AuthService, private clipboardService: ClipboardService) { super(store); } @@ -88,6 +103,8 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro this.buildTwoFactorForm(); this.user = this.route.snapshot.data.user; this.twoFactorLoad(this.route.snapshot.data.providers); + this.buildChangePasswordForm(); + this.loadPasswordPolicy(); } ngOnDestroy() { @@ -142,6 +159,75 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro }); } + private buildChangePasswordForm() { + this.changePassword = this.fb.group({ + currentPassword: [''], + newPassword: ['', Validators.required], + newPassword2: ['', this.samePasswordValidation(false, 'newPassword')] + }); + } + + private loadPasswordPolicy() { + this.authService.getUserPasswordPolicy().subscribe(policy => { + this.passwordPolicy = policy; + this.changePassword.get('newPassword').setValidators([ + this.passwordStrengthValidator(), + this.samePasswordValidation(true, 'currentPassword'), + Validators.required + ]); + this.changePassword.get('newPassword').updateValueAndValidity({emitEvent: false}); + }); + } + + private passwordStrengthValidator(): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + const value: string = control.value; + const errors: any = {}; + + if (this.passwordPolicy.minimumUppercaseLetters > 0 && + !new RegExp(`(?:.*?[A-Z]){${this.passwordPolicy.minimumUppercaseLetters}}`).test(value)) { + errors.notUpperCase = true; + } + + if (this.passwordPolicy.minimumLowercaseLetters > 0 && + !new RegExp(`(?:.*?[a-z]){${this.passwordPolicy.minimumLowercaseLetters}}`).test(value)) { + errors.notLowerCase = true; + } + + if (this.passwordPolicy.minimumDigits > 0 + && !new RegExp(`(?:.*?\\d){${this.passwordPolicy.minimumDigits}}`).test(value)) { + errors.notNumeric = true; + } + + if (this.passwordPolicy.minimumSpecialCharacters > 0 && + !new RegExp(`(?:.*?[\\W_]){${this.passwordPolicy.minimumSpecialCharacters}}`).test(value)) { + errors.notSpecial = true; + } + + if (!this.passwordPolicy.allowWhitespaces && /\s/.test(value)) { + errors.hasWhitespaces = true; + } + + if (this.passwordPolicy.minimumLength > 0 && value.length < this.passwordPolicy.minimumLength) { + errors.minLength = true; + } + + return isEqual(errors, {}) ? null : errors; + }; + } + + private samePasswordValidation(isSame: boolean, key: string): ValidatorFn { + return (control: AbstractControl): ValidationErrors | null => { + const value: string = control.value; + const keyValue = control.parent?.value[key]; + + if (isSame) { + return value === keyValue ? {samePassword: true} : null; + } + return value !== keyValue ? {differencePassword: true} : null; + }; + } + trackByProvider(i: number, provider: TwoFactorAuthProviderType) { return provider; } @@ -256,4 +342,41 @@ export class SecurityComponent extends PageComponent implements OnInit, OnDestro } return info; } + + onChangePassword(form: FormGroupDirective): void { + if (this.changePassword.valid) { + this.authService.changePassword(this.changePassword.get('currentPassword').value, + this.changePassword.get('newPassword').value, {ignoreErrors: true}).subscribe(() => { + this.discardChanges(form); + }, + (error) => { + if (error.status === 400 && error.error.message === 'Current password doesn\'t match!') { + this.changePassword.get('currentPassword').setErrors({differencePassword: true}); + } else if (error.status === 400 && error.error.message.startsWith('Password must')) { + this.loadPasswordPolicy(); + } else if (error.status === 400 && error.error.message.startsWith('Password was already used')) { + this.changePassword.get('newPassword').setErrors({alreadyUsed: error.error.message}); + } else { + this.store.dispatch(new ActionNotificationShow({ + message: error.error.message, + type: 'error', + target: 'changePassword' + })); + } + }); + } else { + this.changePassword.markAllAsTouched(); + } + } + + discardChanges(form: FormGroupDirective, event?: MouseEvent) { + if (event) { + event.stopPropagation(); + } + form.resetForm({ + currentPassword: '', + newPassword: '', + newPassword2: '' + }); + } } diff --git a/ui-ngx/src/assets/locale/locale.constant-en_US.json b/ui-ngx/src/assets/locale/locale.constant-en_US.json index 2ae0b55916..31d5229fa6 100644 --- a/ui-ngx/src/assets/locale/locale.constant-en_US.json +++ b/ui-ngx/src/assets/locale/locale.constant-en_US.json @@ -2498,7 +2498,7 @@ "password-reset": "Password reset", "expired-password-reset-message": "Your credentials has been expired! Please create new password.", "new-password": "New password", - "new-password-again": "New password again", + "new-password-again": "Confirm new password", "password-link-sent-message": "Reset link has been sent", "email": "Email", "login-with": "Login with {{name}}", @@ -2601,12 +2601,13 @@ "change-password": "Change Password", "current-password": "Current password", "copy-jwt-token": "Copy JWT token", - "valid-till": "Valid till {{expirationData}}", + "jwt-token": "JWT token", + "token-valid-till": "Token is valid till", "tokenCopiedSuccessMessage": "JWT token has been copied to clipboard", "tokenCopiedWarnMessage": "JWT token is expired! Please, refresh the page." }, "security": { - "security": "Security", + "security": "Password and authentication", "2fa": { "2fa": "Two-factor authentication", "2fa-description": "Two-factor authentication protects your account from unauthorized access. All you have to do is enter a security code when you log in.", @@ -2660,6 +2661,20 @@ "backup-code-description": "These printable one-time passcodes allow you to sign in when away from your phone, like when you’re traveling.", "backup-code-hint": "{{ info }} single-use codes are active at this time" } + }, + "password-requirement": { + "at-least": "At least:", + "character": "{ count, plural, 1 {1 character} other {# characters} }", + "digit": "{ count, plural, 1 {1 digit} other {# digits} }", + "incorrect-password-try-again": "Incorrect password. Try again", + "lowercase-letter": "{ count, plural, 1 {1 lowercase letter} other {# lowercase letters} }", + "new-passwords-not-match": "New password didn't match", + "password-should-not-contain-spaces": "Your password should not contain spaces", + "password-not-meet-requirements": "Password didn't meet requirements", + "password-requirements": "Password requirements", + "password-should-difference": "New password should be different from current", + "special-character": "{ count, plural, 1 {1 special character} other {# special characters} }", + "uppercase-letter": "{ count, plural, 1 {1 uppercase letter} other {# uppercase letters} }" } }, "relation": { diff --git a/ui-ngx/src/assets/locale/locale.constant-ru_RU.json b/ui-ngx/src/assets/locale/locale.constant-ru_RU.json index a4e894e59e..b576974b9f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-ru_RU.json +++ b/ui-ngx/src/assets/locale/locale.constant-ru_RU.json @@ -1289,7 +1289,6 @@ "change-password": "Изменить пароль", "current-password": "Текущий пароль", "copy-jwt-token": "Копировать JWT токен", - "valid-till": "Действителен до {{expirationData}}", "tokenCopiedMessage": "JWT токен скопирован в буфер обмена", "tokenCopiedWarnMessage": "JWT токен недействителен! Перезагрузите страницу." }, diff --git a/ui-ngx/src/assets/locale/locale.constant-uk_UA.json b/ui-ngx/src/assets/locale/locale.constant-uk_UA.json index eff83577fd..c624175bec 100644 --- a/ui-ngx/src/assets/locale/locale.constant-uk_UA.json +++ b/ui-ngx/src/assets/locale/locale.constant-uk_UA.json @@ -1704,7 +1704,6 @@ "change-password": "Змінити пароль", "current-password": "Поточний пароль", "copy-jwt-token": "Копіювати JWT токен", - "valid-till": "Дійсний до {{expirationData}}", "tokenCopiedMessage": "JWT токен скопійовано в буфер обміну", "tokenCopiedWarnMessage": "JWT токен не є дійсним! Перезавантажте сторінку." }, diff --git a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json index 11e34c9102..f4b6dd420f 100644 --- a/ui-ngx/src/assets/locale/locale.constant-zh_CN.json +++ b/ui-ngx/src/assets/locale/locale.constant-zh_CN.json @@ -2009,7 +2009,6 @@ "last-login-time": "最后登录", "profile": "属性", "copy-jwt-token": "复制 JWT 令牌", - "valid-till": "有效期至 {{expirationData}}", "tokenCopiedSuccessMessage": "JWT 令牌已复制到剪贴板", "tokenCopiedWarnMessage": "JWT 令牌已过期!请刷新页面。" }, diff --git a/ui-ngx/src/theme.scss b/ui-ngx/src/theme.scss index e0aac57674..cdf4d611cd 100644 --- a/ui-ngx/src/theme.scss +++ b/ui-ngx/src/theme.scss @@ -221,6 +221,7 @@ $tb-dark-theme: get-tb-dark-theme( @mixin tb-components-theme($theme) { $primary: map-get($theme, primary); + $warn: map-get($theme, warn); mat-toolbar{ &.mat-hue-3 { @@ -233,6 +234,12 @@ $tb-dark-theme: get-tb-dark-theme( div.tb-dashboard-page.mobile-app { @include mat-fab-toolbar-inverse-theme($tb-theme); } + + .same-color.mat-form-field-invalid { + .mat-form-field-suffix { + color: mat.get-color-from-palette($warn, text); + } + } } .tb-default { From dbbd8cf9ce37320a1aeaf0bb4e4979f5573be173 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Fri, 10 Jun 2022 10:09:59 +0300 Subject: [PATCH 56/86] UI: Imporvement mobile view security page --- .../app/modules/home/pages/security/security.component.scss | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/security/security.component.scss b/ui-ngx/src/app/modules/home/pages/security/security.component.scss index 16f19e09bf..b593be3a2a 100644 --- a/ui-ngx/src/app/modules/home/pages/security/security.component.scss +++ b/ui-ngx/src/app/modules/home/pages/security/security.component.scss @@ -23,10 +23,10 @@ mat-card.profile-card { padding: 24px; @media #{$mat-gt-sm} { - width: 70%; + width: 80%; } @media #{$mat-gt-md} { - width: 50%; + width: 55%; } @media #{$mat-gt-xl} { width: 45%; From eeb6ab6a6076c5f2481f00fa01d5897c781daba0 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Fri, 10 Jun 2022 10:34:31 +0300 Subject: [PATCH 57/86] UI: Refactoring code style --- .../login/two-factor-auth-login.component.ts | 15 +++++++-------- .../app/shared/models/two-factor-auth.models.ts | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/ui-ngx/src/app/modules/login/pages/login/two-factor-auth-login.component.ts b/ui-ngx/src/app/modules/login/pages/login/two-factor-auth-login.component.ts index 89105cd18e..2a98f0b530 100644 --- a/ui-ngx/src/app/modules/login/pages/login/two-factor-auth-login.component.ts +++ b/ui-ngx/src/app/modules/login/pages/login/two-factor-auth-login.component.ts @@ -29,7 +29,7 @@ import { import { TranslateService } from '@ngx-translate/core'; import { interval, Subscription } from 'rxjs'; import { isEqual } from '@core/utils'; -import {ActionNotificationShow} from "@core/notification/notification.actions"; +import { ActionNotificationShow } from '@core/notification/notification.actions'; @Component({ selector: 'tb-two-factor-auth-login', @@ -120,13 +120,12 @@ export class TwoFactorAuthLoginComponent extends PageComponent implements OnInit this.verificationForm.get('verificationCode').setErrors(errors); }, 5000); } else { - this.store.dispatch(new ActionNotificationShow( - { - message: error.error.message, - type: 'error', - verticalPosition: 'top', - horizontalPosition: 'left' - })); + this.store.dispatch(new ActionNotificationShow({ + message: error.error.message, + type: 'error', + verticalPosition: 'top', + horizontalPosition: 'left' + })); } } ); diff --git a/ui-ngx/src/app/shared/models/two-factor-auth.models.ts b/ui-ngx/src/app/shared/models/two-factor-auth.models.ts index d7961050ed..d3b2a74fbd 100644 --- a/ui-ngx/src/app/shared/models/two-factor-auth.models.ts +++ b/ui-ngx/src/app/shared/models/two-factor-auth.models.ts @@ -93,8 +93,8 @@ export interface AccountTwoFaSettings { } export type AccountTwoFaSettingProviders = { - [key in TwoFactorAuthProviderType]?: TwoFactorAuthAccountConfig; -} + [key in TwoFactorAuthProviderType]?: TwoFactorAuthAccountConfig; +}; export interface TwoFaProviderInfo { type: TwoFactorAuthProviderType; From fd53c24346f84d05b7114f918d7664afab4d0408 Mon Sep 17 00:00:00 2001 From: dlandiak Date: Fri, 10 Jun 2022 13:24:20 +0300 Subject: [PATCH 58/86] fixing slow queries logging --- .../server/dao/sql/query/DefaultEntityQueryRepository.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java index f4fa052648..23b5b12d7c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/query/DefaultEntityQueryRepository.java @@ -369,7 +369,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { try { return jdbcTemplate.queryForObject(countQuery, ctx, Long.class); } finally { - queryLog.logQuery(ctx, ctx.getQuery(), System.currentTimeMillis() - startTs); + queryLog.logQuery(ctx, countQuery, System.currentTimeMillis() - startTs); } }); } @@ -481,7 +481,7 @@ public class DefaultEntityQueryRepository implements EntityQueryRepository { try { rows = jdbcTemplate.queryForList(dataQuery, ctx); } finally { - queryLog.logQuery(ctx, countQuery, System.currentTimeMillis() - startTs); + queryLog.logQuery(ctx, dataQuery, System.currentTimeMillis() - startTs); } return EntityDataAdapter.createEntityData(pageLink, selectionMapping, rows, totalElements); }); From 9c3febf6641c9c613846e5f4edace20816ec7cfd Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Fri, 10 Jun 2022 13:49:51 +0300 Subject: [PATCH 59/86] UI: Fixed not correct work vertical resize in knob widget --- .../home/components/widget/lib/rpc/knob.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.html b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.html index 0e396d1b07..58b7d7880c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.html +++ b/ui-ngx/src/app/modules/home/components/widget/lib/rpc/knob.component.html @@ -15,8 +15,8 @@ limitations under the License. --> -
-
+
+
{{ value }} From db840bf4d88f28e3b8adaf18da49bd8d6caaaa94 Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Fri, 10 Jun 2022 15:45:26 +0300 Subject: [PATCH 60/86] UI: Fixed incorrect show edit widget panel when active add widget panel in dashboard page --- .../components/dashboard-page/dashboard-page.component.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts index c360846941..f9ec50504f 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts @@ -1127,6 +1127,13 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC editWidget($event: Event, layoutCtx: DashboardPageLayoutContext, widget: Widget) { $event.stopPropagation(); + + if (this.isAddingWidget) { + this.onAddWidgetClosed(); + this.isAddingWidgetClosed = true; + this.isEditingWidgetClosed = false; + } + if (this.editingWidgetOriginal === widget) { this.onEditWidgetClosed(); } else { From bb8e6a04439bbb0ac56ac99279f2b799e376d450 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Fri, 10 Jun 2022 17:32:12 +0300 Subject: [PATCH 61/86] Fixed bug with incorrect display of delayed status --- .../modules/home/components/edge/edge-downlink-table-config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/edge/edge-downlink-table-config.ts b/ui-ngx/src/app/modules/home/components/edge/edge-downlink-table-config.ts index 2ddc6637b3..2e3b55f32d 100644 --- a/ui-ngx/src/app/modules/home/components/edge/edge-downlink-table-config.ts +++ b/ui-ngx/src/app/modules/home/components/edge/edge-downlink-table-config.ts @@ -138,7 +138,7 @@ export class EdgeDownlinkTableConfig extends EntityTableConfig Date: Fri, 10 Jun 2022 17:38:18 +0300 Subject: [PATCH 62/86] UI: Fix bug with filter and with entity name --- .../widget/lib/alarms-table-widget.component.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts index 03379a54e0..2412f59f5f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/alarms-table-widget.component.ts @@ -290,9 +290,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, debounceTime(150), distinctUntilChanged(), tap(() => { - if (this.displayPagination) { - this.paginator.pageIndex = 0; - } + this.resetPageIndex(); this.updateData(); }) ) @@ -556,6 +554,12 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, this.ctx.detectChanges(); } + private resetPageIndex(): void { + if (this.displayPagination) { + this.paginator.pageIndex = 0; + } + } + private editAlarmFilter($event: Event) { if ($event) { $event.stopPropagation(); @@ -600,6 +604,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, this.pageLink.statusList = result.statusList; this.pageLink.severityList = result.severityList; this.pageLink.typeList = result.typeList; + this.resetPageIndex(); this.updateData(); } }); @@ -620,9 +625,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, exitFilterMode() { this.textSearchMode = false; this.pageLink.textSearch = null; - if (this.displayPagination) { - this.paginator.pageIndex = 0; - } + this.resetPageIndex(); this.updateData(); this.ctx.hideTitlePanel = false; this.ctx.detectChanges(true); @@ -959,7 +962,7 @@ export class AlarmsTableWidgetComponent extends PageComponent implements OnInit, } else if (alarmField.value === alarmFields.severity.value) { return this.translate.instant(alarmSeverityTranslations.get(value)); } else if (alarmField.value === alarmFields.status.value) { - return this.translate.instant(alarmStatusTranslations.get(value)); + return alarmStatusTranslations.get(value) ? this.translate.instant(alarmStatusTranslations.get(value)) : value; } else if (alarmField.value === alarmFields.originatorType.value) { return this.translate.instant(entityTypeTranslations.get(value).type); } else { From 0cd24bb16e26e22691f21e391f5634f4f27ac2bb Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Sun, 12 Jun 2022 20:28:12 +0300 Subject: [PATCH 63/86] refactoring: alarm - test start --- .../server/controller/AlarmController.java | 2 +- .../DefaultTbNotificationEntityService.java | 26 +--- .../entitiy/alarm/DefaultTbAlarmService.java | 10 +- .../service/entitiy/alarm/TbAlarmService.java | 3 +- .../controller/AbstractControllerTest.java | 2 +- .../controller/AbstractNotifyEntityTest.java | 132 ++++++++++++++++++ .../server/controller/AbstractWebTest.java | 11 +- .../controller/BaseAlarmControllerTest.java | 119 +++++++++++++++- .../profile/TbDeviceProfileNodeTest.java | 8 +- 9 files changed, 269 insertions(+), 44 deletions(-) create mode 100644 application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 939e9da8a0..2651277ccc 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -147,7 +147,7 @@ public class AlarmController extends BaseController { try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); - return tbAlarmService.delete(alarm, getCurrentUser()); + return tbAlarmService.delete(alarm, getCurrentUser().getCustomerId(), getCurrentUser()); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index 3361b75d23..707747ae91 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -52,6 +52,7 @@ import org.thingsboard.server.service.gateway_device.GatewayNotificationsService import org.thingsboard.server.service.security.model.SecurityUser; import java.util.List; +import java.util.Locale; @Slf4j @Service @@ -335,28 +336,7 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS return null; } - private EdgeEventActionType edgeTypeByActionType(ActionType actionType) { - switch (actionType) { - case ADDED: - return EdgeEventActionType.ADDED; - case UPDATED: - return EdgeEventActionType.UPDATED; - case ALARM_ACK: - return EdgeEventActionType.ALARM_ACK; - case ALARM_CLEAR: - return EdgeEventActionType.ALARM_CLEAR; - case DELETED: - return EdgeEventActionType.DELETED; - case RELATION_ADD_OR_UPDATE: - return EdgeEventActionType.RELATION_ADD_OR_UPDATE; - case RELATION_DELETED: - return EdgeEventActionType.RELATION_DELETED; - case ASSIGNED_TO_EDGE: - return EdgeEventActionType.ASSIGNED_TO_EDGE; - case UNASSIGNED_FROM_EDGE: - return EdgeEventActionType.UNASSIGNED_FROM_EDGE; - default: - return null; - } + public static EdgeEventActionType edgeTypeByActionType(ActionType actionType) { + return EdgeEventActionType.valueOf(actionType.toString().toUpperCase(Locale.ENGLISH)); } } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index 4930f54a5d..305fda2b2b 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -77,12 +78,13 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb } @Override - public Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException { + public Boolean delete(Alarm alarm, CustomerId customerId, SecurityUser user) throws ThingsboardException { + TenantId tenantId = alarm.getTenantId(); try { - List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); - notificationEntityService.notifyDeleteAlarm(user.getTenantId(), alarm, alarm.getOriginator(), user.getCustomerId(), + List relatedEdgeIds = findRelatedEdgeIds(tenantId, alarm.getOriginator()); + notificationEntityService.notifyDeleteAlarm(tenantId, alarm, alarm.getOriginator(), customerId, relatedEdgeIds, user, JacksonUtil.OBJECT_MAPPER.writeValueAsString(alarm)); - return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); + return alarmService.deleteAlarm(tenantId, alarm.getId()).isSuccessful(); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java index 7a6d7f6a81..f17fcb3b70 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java @@ -17,6 +17,7 @@ package org.thingsboard.server.service.entitiy.alarm; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.exception.ThingsboardException; +import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.service.security.model.SecurityUser; public interface TbAlarmService { @@ -27,5 +28,5 @@ public interface TbAlarmService { void clear(Alarm alarm, SecurityUser user) throws ThingsboardException; - Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException; + Boolean delete(Alarm alarm, CustomerId customerId, SecurityUser user) throws ThingsboardException; } diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java index 98e4c12759..ed8d8632da 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractControllerTest.java @@ -45,7 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat; @EnableWebSocket @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @Slf4j -public abstract class AbstractControllerTest extends AbstractWebTest { +public abstract class AbstractControllerTest extends AbstractNotifyEntityTest { public static final String WS_URL = "ws://localhost:"; diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java new file mode 100644 index 0000000000..a5827d6f6d --- /dev/null +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -0,0 +1,132 @@ +/** + * Copyright © 2016-2022 The Thingsboard Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.thingsboard.server.controller; + +import org.mockito.Mockito; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.thingsboard.server.cluster.TbClusterService; +import org.thingsboard.server.common.data.EntityType; +import org.thingsboard.server.common.data.HasName; +import org.thingsboard.server.common.data.audit.ActionType; +import org.thingsboard.server.common.data.id.CustomerId; +import org.thingsboard.server.common.data.id.EntityId; +import org.thingsboard.server.common.data.id.EntityIdFactory; +import org.thingsboard.server.common.data.id.TenantId; +import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.dao.audit.AuditLogService; +import org.thingsboard.server.dao.model.ModelConstants; + +import java.util.Locale; + +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; +import static org.thingsboard.server.service.entitiy.DefaultTbNotificationEntityService.edgeTypeByActionType; + +public abstract class AbstractNotifyEntityTest extends AbstractWebTest { + + @SpyBean + protected TbClusterService tbClusterService; + + @SpyBean + protected AuditLogService auditLogService; + + protected void testNotifyEntityOk(HasName entity, EntityId entityId, EntityId originatorId, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType) { + testSendNotificationMsgToEdgeServiceOk(entityId, tenantId, actionType); + testLogEntityActionOk(entity, originatorId, tenantId, customerId, userId, userName, actionType); + testPushMsgToRuleEngineOk(entity, originatorId, tenantId, customerId, userId, userName, actionType); + Mockito.reset(tbClusterService, auditLogService); + } + + protected void testNotifyEntityDeleteOk(HasName entity, EntityId entityId, EntityId originatorId, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType) { + Mockito.verify(tbClusterService, never()).sendNotificationMsgToEdgeService(Mockito.any(), + Mockito.any(), Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any(), Mockito.any()); + testLogEntityActionOk(entity, originatorId, tenantId, customerId, userId, userName, actionType); + testPushMsgToRuleEngineOk(entity, originatorId, tenantId, customerId, userId, userName, actionType); + } + + private void testNotifyEntityError(EntityId entityId, HasName entity, TenantId tenantId, + UserId userId, String userName, ActionType actionType, Exception exp, + Object... additionalInfo) { + CustomerId customer_NULL_UUID = (CustomerId) EntityIdFactory.getByTypeAndUuid(EntityType.CUSTOMER, ModelConstants.NULL_UUID); + EntityId entity_NULL_UUID = EntityIdFactory.getByTypeAndUuid(EntityType.valueOf(entity.getClass().toString().substring(entity.getClass().toString().lastIndexOf(".") + 1).toUpperCase(Locale.ENGLISH)), + ModelConstants.NULL_UUID); + testNotificationMsgToEdgeServiceNever(entityId); + if (additionalInfo.length > 0) { + Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), + Mockito.eq(customer_NULL_UUID), Mockito.eq(userId), Mockito.eq(userName), + Mockito.eq(entity_NULL_UUID), Mockito.any(entity.getClass()), Mockito.eq(actionType), + Mockito.any(exp.getClass()), Mockito.eq(additionalInfo)); + } else { + Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), + Mockito.eq(customer_NULL_UUID), Mockito.eq(userId), Mockito.eq(userName), + Mockito.eq(entity_NULL_UUID), Mockito.any(entity.getClass()), Mockito.eq(actionType), + Mockito.any(exp.getClass()), Mockito.isNull()); + } + Mockito.verify(tbClusterService, never()).pushMsgToRuleEngine(Mockito.any(), Mockito.any(entityId.getClass()), + Mockito.any(), Mockito.any()); + Mockito.reset(tbClusterService, auditLogService); + } + + protected void testNotifyEntityNever(EntityId entityId, HasName entity) { + testNotificationMsgToEdgeServiceNever(entityId); + testLogEntityActionNever(entityId, entity); + testPushMsgToRuleEngineNever(entityId); + } + + protected void testNotificationMsgToEdgeServiceNever(EntityId entityId) { + Mockito.verify(tbClusterService, never()).sendNotificationMsgToEdgeService(Mockito.any(), + Mockito.any(), Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any(), Mockito.any()); + } + + protected void testLogEntityActionNever(EntityId entityId, HasName entity) { + Mockito.verify(auditLogService, never()).logEntityAction(Mockito.any(), Mockito.any(), + Mockito.any(), Mockito.any(), Mockito.any(entityId.getClass()), Mockito.any(entity.getClass()), + Mockito.any(), Mockito.any()); + } + + protected void testPushMsgToRuleEngineNever(EntityId entityId) { + Mockito.verify(tbClusterService, never()).pushMsgToRuleEngine(Mockito.any(), + Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any()); + } + + private void testLogEntityActionOk(HasName entity, EntityId originatorId, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType) { + Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), + Mockito.eq(userId), Mockito.eq(userName), Mockito.eq(originatorId), + Mockito.eq(entity), Mockito.eq(actionType), Mockito.isNull()); + } + + private void testPushMsgToRuleEngineOk(HasName entity, EntityId originatorId, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType) { + + Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), + Mockito.eq(userId), Mockito.eq(userName), Mockito.eq(originatorId), + Mockito.eq(entity), Mockito.eq(actionType), Mockito.isNull()); + } + + private void testSendNotificationMsgToEdgeServiceOk(EntityId entityId, TenantId tenantId, ActionType actionType) { + Mockito.verify(tbClusterService, times(1)).sendNotificationMsgToEdgeService(Mockito.eq(tenantId), + Mockito.isNull(), Mockito.eq(entityId), Mockito.isNull(), Mockito.isNull(), + Mockito.eq(edgeTypeByActionType(actionType))); + } + +} diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java index b52c3028d6..2e5012851a 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractWebTest.java @@ -75,11 +75,6 @@ import org.thingsboard.server.common.data.id.UserId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.page.TimePageLink; -import org.thingsboard.server.common.data.queue.ProcessingStrategy; -import org.thingsboard.server.common.data.queue.ProcessingStrategyType; -import org.thingsboard.server.common.data.queue.Queue; -import org.thingsboard.server.common.data.queue.SubmitStrategy; -import org.thingsboard.server.common.data.queue.SubmitStrategyType; import org.thingsboard.server.common.data.security.Authority; import org.thingsboard.server.config.ThingsboardSecurityConfiguration; import org.thingsboard.server.dao.tenant.TenantProfileService; @@ -137,7 +132,9 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { protected TenantId tenantId; protected UserId tenantAdminUserId; + protected CustomerId tenantAdminCustomerId; protected CustomerId customerId; + protected UserId customerUserId; @SuppressWarnings("rawtypes") private HttpMessageConverter mappingJackson2HttpMessageConverter; @@ -202,6 +199,7 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { tenantAdmin = createUserAndLogin(tenantAdmin, TENANT_ADMIN_PASSWORD); tenantAdminUserId = tenantAdmin.getId(); + tenantAdminCustomerId = tenantAdmin.getCustomerId(); Customer customer = new Customer(); customer.setTitle("Customer"); @@ -215,7 +213,8 @@ public abstract class AbstractWebTest extends AbstractInMemoryStorageTest { customerUser.setCustomerId(savedCustomer.getId()); customerUser.setEmail(CUSTOMER_USER_EMAIL); - createUserAndLogin(customerUser, CUSTOMER_USER_PASSWORD); + customerUser = createUserAndLogin(customerUser, CUSTOMER_USER_PASSWORD); + customerUserId = customerUser.getId(); logout(); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java index ce9b6916fc..16a9f993c3 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java @@ -15,17 +15,21 @@ */ package org.thingsboard.server.controller; +import lombok.extern.slf4j.Slf4j; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; import org.thingsboard.server.common.data.Device; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmSeverity; import org.thingsboard.server.common.data.alarm.AlarmStatus; +import org.thingsboard.server.common.data.audit.ActionType; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; +@Slf4j public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public static final String TEST_ALARM_TYPE = "Test"; @@ -56,36 +60,68 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testCreateAlarmViaCustomer() throws Exception { loginCustomerUser(); - createAlarm(TEST_ALARM_TYPE); + + Mockito.reset(tbClusterService, auditLogService); + + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); logout(); } @Test public void testCreateAlarmViaTenant() throws Exception { loginTenantAdmin(); - createAlarm(TEST_ALARM_TYPE); + + Mockito.reset(tbClusterService, auditLogService); + + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); logout(); } @Test public void testUpdateAlarmViaCustomer() throws Exception { loginCustomerUser(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + alarm.setSeverity(AlarmSeverity.MAJOR); Alarm updatedAlarm = doPost("/api/alarm", alarm, Alarm.class); Assert.assertNotNull(updatedAlarm); Assert.assertEquals(AlarmSeverity.MAJOR, updatedAlarm.getSeverity()); + + testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.UPDATED); logout(); } @Test public void testUpdateAlarmViaTenant() throws Exception { loginTenantAdmin(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); + alarm.setSeverity(AlarmSeverity.MAJOR); Alarm updatedAlarm = doPost("/api/alarm", alarm, Alarm.class); Assert.assertNotNull(updatedAlarm); Assert.assertEquals(AlarmSeverity.MAJOR, updatedAlarm.getSeverity()); + + testNotifyEntityOk(updatedAlarm, updatedAlarm.getId(), updatedAlarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.UPDATED); logout(); } @@ -93,9 +129,15 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testUpdateAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); + alarm.setSeverity(AlarmSeverity.MAJOR); loginDifferentTenant(); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/alarm", alarm).andExpect(status().isForbidden()); + + testNotifyEntityNever(alarm.getId(), alarm); logout(); } @@ -103,9 +145,15 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testUpdateAlarmViaDifferentCustomer() throws Exception { loginCustomerUser(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); + loginDifferentCustomer(); alarm.setSeverity(AlarmSeverity.MAJOR); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/alarm", alarm).andExpect(status().isForbidden()); + + testNotifyEntityNever(alarm.getId(), alarm); logout(); } @@ -113,7 +161,13 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testDeleteAlarmViaCustomer() throws Exception { loginCustomerUser(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + Mockito.reset(tbClusterService, auditLogService); + doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); + + testNotifyEntityDeleteOk(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED); logout(); } @@ -121,7 +175,13 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testDeleteAlarmViaTenant() throws Exception { loginTenantAdmin(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + Mockito.reset(tbClusterService, auditLogService); + doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); + + testNotifyEntityDeleteOk(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED); logout(); } @@ -129,8 +189,15 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testDeleteAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); + loginDifferentTenant(); + + Mockito.reset(tbClusterService, auditLogService); + doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isForbidden()); + + testNotifyEntityNever(alarm.getId(), alarm); + logout(); } @@ -139,7 +206,13 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { loginCustomerUser(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); loginDifferentCustomer(); + + Mockito.reset(tbClusterService, auditLogService); + doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isForbidden()); + + testNotifyEntityNever(alarm.getId(), alarm); + logout(); } @@ -147,10 +220,17 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testClearAlarmViaCustomer() throws Exception { loginCustomerUser(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/alarm/" + alarm.getId() + "/clear").andExpect(status().isOk()); + Alarm foundAlarm = doGet("/api/alarm/" + alarm.getId(), Alarm.class); Assert.assertNotNull(foundAlarm); Assert.assertEquals(AlarmStatus.CLEARED_UNACK, foundAlarm.getStatus()); + + testNotifyEntityOk(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ALARM_CLEAR); logout(); } @@ -158,10 +238,16 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testClearAlarmViaTenant() throws Exception { loginTenantAdmin(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/alarm/" + alarm.getId() + "/clear").andExpect(status().isOk()); Alarm foundAlarm = doGet("/api/alarm/" + alarm.getId(), Alarm.class); Assert.assertNotNull(foundAlarm); Assert.assertEquals(AlarmStatus.CLEARED_UNACK, foundAlarm.getStatus()); + + testNotifyEntityOk(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_CLEAR); logout(); } @@ -169,10 +255,17 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testAcknowledgeAlarmViaCustomer() throws Exception { loginCustomerUser(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/alarm/" + alarm.getId() + "/ack").andExpect(status().isOk()); + Alarm foundAlarm = doGet("/api/alarm/" + alarm.getId(), Alarm.class); Assert.assertNotNull(foundAlarm); Assert.assertEquals(AlarmStatus.ACTIVE_ACK, foundAlarm.getStatus()); + + testNotifyEntityOk(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ALARM_ACK); logout(); } @@ -181,7 +274,12 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { loginCustomerUser(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); loginDifferentCustomer(); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/alarm/" + alarm.getId() + "/clear").andExpect(status().isForbidden()); + + testNotifyEntityNever(alarm.getId(), alarm); logout(); } @@ -190,7 +288,12 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { loginTenantAdmin(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); loginDifferentTenant(); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/alarm/" + alarm.getId() + "/clear").andExpect(status().isForbidden()); + + testNotifyEntityNever(alarm.getId(), alarm); logout(); } @@ -199,7 +302,12 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { loginCustomerUser(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); loginDifferentCustomer(); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/alarm/" + alarm.getId() + "/ack").andExpect(status().isForbidden()); + + testNotifyEntityNever(alarm.getId(), alarm); logout(); } @@ -208,7 +316,12 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { loginTenantAdmin(); Alarm alarm = createAlarm(TEST_ALARM_TYPE); loginDifferentTenant(); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/alarm/" + alarm.getId() + "/ack").andExpect(status().isForbidden()); + + testNotifyEntityNever(alarm.getId(), alarm); logout(); } @@ -221,10 +334,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { .severity(AlarmSeverity.CRITICAL) .type(type) .build(); - alarm = doPost("/api/alarm", alarm, Alarm.class); Assert.assertNotNull(alarm); - return alarm; } } diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java index 4be8372df9..9aa53b41f7 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java @@ -40,12 +40,12 @@ import org.thingsboard.server.common.data.device.profile.AlarmConditionFilter; import org.thingsboard.server.common.data.device.profile.AlarmConditionFilterKey; import org.thingsboard.server.common.data.device.profile.AlarmConditionKeyType; import org.thingsboard.server.common.data.device.profile.AlarmRule; +import org.thingsboard.server.common.data.device.profile.CustomTimeSchedule; +import org.thingsboard.server.common.data.device.profile.CustomTimeScheduleItem; import org.thingsboard.server.common.data.device.profile.DeviceProfileAlarm; import org.thingsboard.server.common.data.device.profile.DeviceProfileData; import org.thingsboard.server.common.data.device.profile.DurationAlarmConditionSpec; import org.thingsboard.server.common.data.device.profile.RepeatingAlarmConditionSpec; -import org.thingsboard.server.common.data.device.profile.CustomTimeSchedule; -import org.thingsboard.server.common.data.device.profile.CustomTimeScheduleItem; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; @@ -70,10 +70,10 @@ import org.thingsboard.server.dao.timeseries.TimeseriesService; import java.math.BigDecimal; import java.math.RoundingMode; +import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -import java.util.ArrayList; import java.util.Optional; import java.util.TreeMap; import java.util.UUID; @@ -1157,7 +1157,7 @@ public class TbDeviceProfileNodeTest { .thenReturn(listListenableFutureActiveSchedule); TbMsg theMsg = TbMsg.newMsg("ALARM", deviceId, new TbMsgMetaData(), ""); - Mockito.when(ctx.newMsg(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyString())) + Mockito.when(ctx.newMsg(Mockito.any(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyString())) .thenReturn(theMsg); ObjectNode data = mapper.createObjectNode(); From 6351366aed3c6a20daa4d3ad64e5dbc754e287a6 Mon Sep 17 00:00:00 2001 From: YevhenBondarenko Date: Mon, 13 Jun 2022 10:57:28 +0200 Subject: [PATCH 64/86] fixed device profile node --- .../rule/engine/profile/TbDeviceProfileNodeTest.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java index 4be8372df9..a8c38ce33f 100644 --- a/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java +++ b/rule-engine/rule-engine-components/src/test/java/org/thingsboard/rule/engine/profile/TbDeviceProfileNodeTest.java @@ -49,6 +49,7 @@ import org.thingsboard.server.common.data.device.profile.CustomTimeScheduleItem; import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.DeviceProfileId; +import org.thingsboard.server.common.data.id.QueueId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.AttributeKvEntry; import org.thingsboard.server.common.data.query.BooleanFilterPredicate; @@ -1157,7 +1158,7 @@ public class TbDeviceProfileNodeTest { .thenReturn(listListenableFutureActiveSchedule); TbMsg theMsg = TbMsg.newMsg("ALARM", deviceId, new TbMsgMetaData(), ""); - Mockito.when(ctx.newMsg(Mockito.anyString(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyString())) + Mockito.when(ctx.newMsg(Mockito.any(), Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any(), Mockito.anyString())) .thenReturn(theMsg); ObjectNode data = mapper.createObjectNode(); From b5f052cbc5761e4138b186e45be0daa3b07dd117 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Mon, 13 Jun 2022 12:17:15 +0300 Subject: [PATCH 65/86] Fix typo --- .../home/components/profile/alarm/alarm-schedule.component.html | 2 +- ...ustom_schedule_format.md => alarm_custom_schedule_format.md} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename ui-ngx/src/assets/help/en_US/device-profile/{alarm_сustom_schedule_format.md => alarm_custom_schedule_format.md} (100%) diff --git a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html index d859cd9201..65fe9c9636 100644 --- a/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html +++ b/ui-ngx/src/app/modules/home/components/profile/alarm/alarm-schedule.component.html @@ -74,7 +74,7 @@
- +
device-profile.schedule-days
diff --git a/ui-ngx/src/assets/help/en_US/device-profile/alarm_сustom_schedule_format.md b/ui-ngx/src/assets/help/en_US/device-profile/alarm_custom_schedule_format.md similarity index 100% rename from ui-ngx/src/assets/help/en_US/device-profile/alarm_сustom_schedule_format.md rename to ui-ngx/src/assets/help/en_US/device-profile/alarm_custom_schedule_format.md From eb105d0859c5a1e2510f6e39a4d268fb8c73d391 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Mon, 13 Jun 2022 16:37:40 +0300 Subject: [PATCH 66/86] UI: Refactoring phone input --- .../components/phone-input.component.html | 4 +- .../components/phone-input.component.scss | 5 - .../components/phone-input.component.ts | 64 +- .../src/app/shared/models/country.models.ts | 1573 +++-------------- 4 files changed, 268 insertions(+), 1378 deletions(-) diff --git a/ui-ngx/src/app/shared/components/phone-input.component.html b/ui-ngx/src/app/shared/components/phone-input.component.html index d52d7202d0..4b81391b5f 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.html +++ b/ui-ngx/src/app/shared/components/phone-input.component.html @@ -22,8 +22,8 @@ {{ flagIcon }} - {{country.flag}} - {{country.name + ' +' + country.dialCode }} + {{country.flag}} + {{' ' + country.name + ' +' + country.dialCode }}
diff --git a/ui-ngx/src/app/shared/components/phone-input.component.scss b/ui-ngx/src/app/shared/components/phone-input.component.scss index 872c686af0..d8bd9df461 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.scss +++ b/ui-ngx/src/app/shared/components/phone-input.component.scss @@ -44,11 +44,6 @@ width: 45px; height: 30px; - .country-flag { - font-size: 22px; - padding-right: 10px; - } - .mat-select-trigger { height: 100%; width: 100%; diff --git a/ui-ngx/src/app/shared/components/phone-input.component.ts b/ui-ngx/src/app/shared/components/phone-input.component.ts index bbee8098f6..f5fdf62f34 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.ts +++ b/ui-ngx/src/app/shared/components/phone-input.component.ts @@ -62,15 +62,15 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida @Input() floatLabel: FloatLabelType = 'always'; @Input() appearance: MatFormFieldAppearance = 'legacy'; - allCountries: Array = []; + allCountries: Array = this.countryCodeData.allCountries; phonePlaceholder: string; - countryCallingCode: string; flagIcon: string; - + phoneFormGroup: FormGroup; phoneNumberPattern = phoneNumberPattern; + private baseCode = 127397; + private countryCallingCode: string; private modelValue: string; - public phoneFormGroup: FormGroup; private valueChange$: Subscription = null; private propagateChange = (v: any) => { }; @@ -80,17 +80,24 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida } ngOnInit(): void { - if (this.enableFlagsSelect) { - this.fetchCountryData(); + const validators: ValidatorFn[] = [Validators.pattern(phoneNumberPattern), this.validatePhoneNumber()]; + if (this.required) { + validators.push(Validators.required); } this.phoneFormGroup = this.fb.group({ country: [this.defaultCountry, []], - phoneNumber: [null, this.required ? [Validators.required] : []] + phoneNumber: [null, validators] }); - this.phoneFormGroup.get('phoneNumber').setValidators([Validators.pattern(phoneNumberPattern), this.validatePhoneNumber()]); - this.valueChange$ = this.phoneFormGroup.get('phoneNumber').valueChanges.subscribe(() => { + this.valueChange$ = this.phoneFormGroup.get('phoneNumber').valueChanges.subscribe(value => { this.updateModel(); + if (value) { + const parsedPhoneNumber = parsePhoneNumberFromString(value); + const country = this.phoneFormGroup.get('country').value; + if (parsedPhoneNumber?.country && parsedPhoneNumber?.country !== country) { + this.phoneFormGroup.get('country').patchValue(parsedPhoneNumber.country, {emitEvent: true}); + } + } }); this.phoneFormGroup.get('country').valueChanges.subscribe(value => { @@ -101,20 +108,8 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida if (phoneNumber) { if (code !== this.countryCallingCode && phoneNumber.includes(code)) { phoneNumber = phoneNumber.replace(code, this.countryCallingCode); - } else { - phoneNumber = this.countryCallingCode; + this.phoneFormGroup.get('phoneNumber').patchValue(phoneNumber); } - this.phoneFormGroup.get('phoneNumber').patchValue(phoneNumber); - } - } - }); - - this.phoneFormGroup.get('phoneNumber').valueChanges.subscribe(value => { - if (value) { - const parsedPhoneNumber = parsePhoneNumberFromString(value); - const country = this.phoneFormGroup.get('country').value; - if (parsedPhoneNumber?.country && parsedPhoneNumber?.country !== country) { - this.phoneFormGroup.get('country').patchValue(parsedPhoneNumber.country, {emitEvent: true}); } } }); @@ -135,22 +130,21 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida } } - getFlagAndPhoneNumberData(country) { + private getFlagAndPhoneNumberData(country) { if (this.enableFlagsSelect) { this.flagIcon = this.getFlagIcon(country); } this.getPhoneNumberData(country); } - getPhoneNumberData(country): void { + private getPhoneNumberData(country): void { const phoneData = getExampleNumber(country, examples); this.phonePlaceholder = phoneData.number; this.countryCallingCode = '+' + phoneData.countryCallingCode; } - getFlagIcon(countryCode) { - const base = 127462 - 65; - return String.fromCodePoint(...countryCode.split('').map(country => base + country.charCodeAt(0))); + private getFlagIcon(countryCode) { + return String.fromCodePoint(...countryCode.split('').map(country => this.baseCode + country.charCodeAt(0))); } validatePhoneNumber(): ValidatorFn { @@ -192,21 +186,6 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida } } - protected fetchCountryData(): void { - this.allCountries = []; - this.countryCodeData.allCountries.forEach((c) => { - const cc = c[1]; - const country: Country = { - name: c[0].toString(), - iso2: c[1].toString(), - dialCode: c[2].toString(), - flag: this.getFlagIcon(cc), - }; - - this.allCountries.push(country); - }); - } - writeValue(phoneNumber): void { this.modelValue = phoneNumber; const country = phoneNumber ? parsePhoneNumberFromString(phoneNumber)?.country : this.defaultCountry; @@ -223,5 +202,4 @@ export class PhoneInputComponent implements OnInit, ControlValueAccessor, Valida this.propagateChange(null); } } - } diff --git a/ui-ngx/src/app/shared/models/country.models.ts b/ui-ngx/src/app/shared/models/country.models.ts index 10612de015..d4895fada7 100644 --- a/ui-ngx/src/app/shared/models/country.models.ts +++ b/ui-ngx/src/app/shared/models/country.models.ts @@ -24,15 +24,7 @@ export interface Country { flag: string; } -export enum SearchCountryField { - DialCode = 'dialCode', - Iso2 = 'iso2', - Name = 'name', - All = 'all' -} - - -export enum CountryISO{ +export enum CountryISO { Afghanistan = 'AF', Albania = 'AL', Algeria = 'DZ', @@ -280,1324 +272,249 @@ export enum CountryISO{ @Injectable() export class CountryData { - public allCountries = [ - [ - 'Afghanistan', - CountryISO.Afghanistan, - '93' - ], - [ - 'Albania', - CountryISO.Albania, - '355' - ], - [ - 'Algeria', - CountryISO.Algeria, - '213' - ], - [ - 'American Samoa', - CountryISO.AmericanSamoa, - '1', - 1, - [ - '684', - ] - ], - [ - 'Andorra', - CountryISO.Andorra, - '376' - ], - [ - 'Angola', - CountryISO.Angola, - '244' - ], - [ - 'Anguilla', - CountryISO.Anguilla, - '1', - 1, - [ - '264', - ] - ], - [ - 'Antigua and Barbuda', - CountryISO.AntiguaAndBarbuda, - '1', - 1, - [ - '268', - ] - ], - [ - 'Argentina', - CountryISO.Argentina, - '54' - ], - [ - 'Armenia', - CountryISO.Armenia, - '374' - ], - [ - 'Aruba', - CountryISO.Aruba, - '297' - ], - [ - 'Australia', - CountryISO.Australia, - '61', - 0 - ], - [ - 'Austria', - CountryISO.Austria, - '43' - ], - [ - 'Azerbaijan', - CountryISO.Azerbaijan, - '994' - ], - [ - 'Bahamas', - CountryISO.Bahamas, - '1', - 1, - [ - '242', - ] - ], - [ - 'Bahrain', - CountryISO.Bahrain, - '973' - ], - [ - 'Bangladesh', - CountryISO.Bangladesh, - '880' - ], - [ - 'Barbados', - CountryISO.Barbados, - '1', - 1, - [ - '246', - ] - ], - [ - 'Belarus', - CountryISO.Belarus, - '375' - ], - [ - 'Belgium', - CountryISO.Belgium, - '32' - ], - [ - 'Belize', - CountryISO.Belize, - '501' - ], - [ - 'Benin', - CountryISO.Benin, - '229' - ], - [ - 'Bermuda', - CountryISO.Bermuda, - '1', - 1, - [ - '441', - ] - ], - [ - 'Bhutan', - CountryISO.Bhutan, - '975' - ], - [ - 'Bolivia', - CountryISO.Bolivia, - '591' - ], - [ - 'Bosnia and Herzegovina', - CountryISO.BosniaAndHerzegovina, - '387' - ], - [ - 'Botswana', - CountryISO.Botswana, - '267' - ], - [ - 'Brazil', - CountryISO.Brazil, - '55' - ], - [ - 'British Indian Ocean Territory', - CountryISO.BritishIndianOceanTerritory, - '246' - ], - [ - 'British Virgin Islands', - CountryISO.BritishVirginIslands, - '1', - 1, - [ - '284', - ] - ], - [ - 'Brunei', - CountryISO.Brunei, - '673' - ], - [ - 'Bulgaria', - CountryISO.Bulgaria, - '359' - ], - [ - 'Burkina Faso', - CountryISO.BurkinaFaso, - '226' - ], - [ - 'Burundi', - CountryISO.Burundi, - '257' - ], - [ - 'Cambodia', - CountryISO.Cambodia, - '855' - ], - [ - 'Cameroon', - CountryISO.Cameroon, - '237' - ], - [ - 'Canada', - CountryISO.Canada, - '1', - 1, - [ - '204', '226', '236', '249', '250', '289', '306', '343', '365', '387', '403', '416', - '418', '431', '437', '438', '450', '506', '514', '519', '548', '579', '581', '587', - '604', '613', '639', '647', '672', '705', '709', '742', '778', '780', '782', '807', - '819', '825', '867', '873', '902', '905' - ] - ], - [ - 'Cape Verde', - CountryISO.CapeVerde, - '238' - ], - [ - 'Caribbean Netherlands', - CountryISO.CaribbeanNetherlands, - '599', - 1 - ], - [ - 'Cayman Islands', - CountryISO.CaymanIslands, - '1', - 1, - [ - '345', - ] - ], - [ - 'Central African Republic', - CountryISO.CentralAfricanRepublic, - '236' - ], - [ - 'Chad', - CountryISO.Chad, - '235' - ], - [ - 'Chile', - CountryISO.Chile, - '56' - ], - [ - 'China', - CountryISO.China, - '86' - ], - [ - 'Christmas Island', - CountryISO.ChristmasIsland, - '61', - 2 - ], - [ - 'Cocos Islands', - CountryISO.Cocos, - '61', - 1 - ], - [ - 'Colombia', - CountryISO.Colombia, - '57' - ], - [ - 'Comoros', - CountryISO.Comoros, - '269' - ], - [ - 'Congo-Kinshasa', - CountryISO.CongoDRCJamhuriYaKidemokrasiaYaKongo, - '243' - ], - [ - 'Congo-Brazzaville', - CountryISO.CongoRepublicCongoBrazzaville, - '242' - ], - [ - 'Cook Islands', - CountryISO.CookIslands, - '682' - ], - [ - 'Costa Rica', - CountryISO.CostaRica, - '506' - ], - [ - 'Côte d’Ivoire', - CountryISO.CôteDIvoire, - '225' - ], - [ - 'Croatia', - CountryISO.Croatia, - '385' - ], - [ - 'Cuba', - CountryISO.Cuba, - '53' - ], - [ - 'Curaçao', - CountryISO.Curaçao, - '599', - 0 - ], - [ - 'Cyprus', - CountryISO.Cyprus, - '357' - ], - [ - 'Czech Republic', - CountryISO.CzechRepublic, - '420' - ], - [ - 'Denmark', - CountryISO.Denmark, - '45' - ], - [ - 'Djibouti', - CountryISO.Djibouti, - '253' - ], - [ - 'Dominica', - CountryISO.Dominica, - '1767' - ], - [ - 'Dominican Republic', - CountryISO.DominicanRepublic, - '1', - 2, - ['809', '829', '849'] - ], - [ - 'Ecuador', - CountryISO.Ecuador, - '593' - ], - [ - 'Egypt', - CountryISO.Egypt, - '20' - ], - [ - 'El Salvador', - CountryISO.ElSalvador, - '503' - ], - [ - 'Equatorial Guinea', - CountryISO.EquatorialGuinea, - '240' - ], - [ - 'Eritrea', - CountryISO.Eritrea, - '291' - ], - [ - 'Estonia', - CountryISO.Estonia, - '372' - ], - [ - 'Ethiopia', - CountryISO.Ethiopia, - '251' - ], - [ - 'Falkland Islands', - CountryISO.FalklandIslands, - '500' - ], - [ - 'Faroe Islands', - CountryISO.FaroeIslands, - '298' - ], - [ - 'Fiji', - CountryISO.Fiji, - '679' - ], - [ - 'Finland', - CountryISO.Finland, - '358', - 0 - ], - [ - 'France', - CountryISO.France, - '33' - ], - [ - 'French Guiana', - CountryISO.FrenchGuiana, - '594' - ], - [ - 'French Polynesia', - CountryISO.FrenchPolynesia, - '689' - ], - [ - 'Gabon', - CountryISO.Gabon, - '241' - ], - [ - 'Gambia', - CountryISO.Gambia, - '220' - ], - [ - 'Georgia', - CountryISO.Georgia, - '995' - ], - [ - 'Germany', - CountryISO.Germany, - '49' - ], - [ - 'Ghana', - CountryISO.Ghana, - '233' - ], - [ - 'Gibraltar', - CountryISO.Gibraltar, - '350' - ], - [ - 'Greece', - CountryISO.Greece, - '30' - ], - [ - 'Greenland', - CountryISO.Greenland, - '299' - ], - [ - 'Grenada', - CountryISO.Grenada, - '1473' - ], - [ - 'Guadeloupe', - CountryISO.Guadeloupe, - '590', - 0 - ], - [ - 'Guam', - CountryISO.Guam, - '1', - 1, - [ - '671', - ] - ], - [ - 'Guatemala', - CountryISO.Guatemala, - '502' - ], - [ - 'Guernsey', - CountryISO.Guernsey, - '44', - 1, - [1481] - ], - [ - 'Guinea', - CountryISO.Guinea, - '224' - ], - [ - 'Guinea-Bissau', - CountryISO.GuineaBissau, - '245' - ], - [ - 'Guyana', - CountryISO.Guyana, - '592' - ], - [ - 'Haiti', - CountryISO.Haiti, - '509' - ], - [ - 'Honduras', - CountryISO.Honduras, - '504' - ], - [ - 'Hong Kong', - CountryISO.HongKong, - '852' - ], - [ - 'Hungary', - CountryISO.Hungary, - '36' - ], - [ - 'Iceland', - CountryISO.Iceland, - '354' - ], - [ - 'India', - CountryISO.India, - '91' - ], - [ - 'Indonesia', - CountryISO.Indonesia, - '62' - ], - [ - 'Iran', - CountryISO.Iran, - '98' - ], - [ - 'Iraq', - CountryISO.Iraq, - '964' - ], - [ - 'Ireland', - CountryISO.Ireland, - '353' - ], - [ - 'Isle of Man', - CountryISO.IsleOfMan, - '44', - 2, - [1624] - ], - [ - 'Israel', - CountryISO.Israel, - '972' - ], - [ - 'Italy', - CountryISO.Italy, - '39', - 0 - ], - [ - 'Jamaica', - CountryISO.Jamaica, - '1', - 1, - [ - '876', - ] - ], - [ - 'Japan', - CountryISO.Japan, - '81' - ], - [ - 'Jersey', - CountryISO.Jersey, - '44', - 3, - [1534] - ], - [ - 'Jordan', - CountryISO.Jordan, - '962' - ], - [ - 'Kazakhstan', - CountryISO.Kazakhstan, - '7', - 1 - ], - [ - 'Kenya', - CountryISO.Kenya, - '254' - ], - [ - 'Kiribati', - CountryISO.Kiribati, - '686' - ], - [ - 'Kosovo', - CountryISO.Kosovo, - '383' - ], - [ - 'Kuwait', - CountryISO.Kuwait, - '965' - ], - [ - 'Kyrgyzstan', - CountryISO.Kyrgyzstan, - '996' - ], - [ - 'Laos', - CountryISO.Laos, - '856' - ], - [ - 'Latvia', - CountryISO.Latvia, - '371' - ], - [ - 'Lebanon', - CountryISO.Lebanon, - '961' - ], - [ - 'Lesotho', - CountryISO.Lesotho, - '266' - ], - [ - 'Liberia', - CountryISO.Liberia, - '231' - ], - [ - 'Libya', - CountryISO.Libya, - '218' - ], - [ - 'Liechtenstein', - CountryISO.Liechtenstein, - '423' - ], - [ - 'Lithuania', - CountryISO.Lithuania, - '370' - ], - [ - 'Luxembourg', - CountryISO.Luxembourg, - '352' - ], - [ - 'Macau', - CountryISO.Macau, - '853' - ], - [ - 'Macedonia', - CountryISO.Macedonia, - '389' - ], - [ - 'Madagascar', - CountryISO.Madagascar, - '261' - ], - [ - 'Malawi', - CountryISO.Malawi, - '265' - ], - [ - 'Malaysia', - CountryISO.Malaysia, - '60' - ], - [ - 'Maldives', - CountryISO.Maldives, - '960' - ], - [ - 'Mali', - CountryISO.Mali, - '223' - ], - [ - 'Malta', - CountryISO.Malta, - '356' - ], - [ - 'Marshall Islands', - CountryISO.MarshallIslands, - '692' - ], - [ - 'Martinique', - CountryISO.Martinique, - '596' - ], - [ - 'Mauritania', - CountryISO.Mauritania, - '222' - ], - [ - 'Mauritius', - CountryISO.Mauritius, - '230' - ], - [ - 'Mayotte', - CountryISO.Mayotte, - '262', - 1 - ], - [ - 'Mexico', - CountryISO.Mexico, - '52' - ], - [ - 'Micronesia', - CountryISO.Micronesia, - '691' - ], - [ - 'Moldova', - CountryISO.Moldova, - '373' - ], - [ - 'Monaco', - CountryISO.Monaco, - '377' - ], - [ - 'Mongolia', - CountryISO.Mongolia, - '976' - ], - [ - 'Montenegro', - CountryISO.Montenegro, - '382' - ], - [ - 'Montserrat', - CountryISO.Montserrat, - '1', - 1, - [ - '664', - ] - ], - [ - 'Morocco', - CountryISO.Morocco, - '212', - 0 - ], - [ - 'Mozambique', - CountryISO.Mozambique, - '258' - ], - [ - 'Myanmar', - CountryISO.Myanmar, - '95' - ], - [ - 'Namibia', - CountryISO.Namibia, - '264' - ], - [ - 'Nauru', - CountryISO.Nauru, - '674' - ], - [ - 'Nepal', - CountryISO.Nepal, - '977' - ], - [ - 'Netherlands', - CountryISO.Netherlands, - '31' - ], - [ - 'New Caledonia', - CountryISO.NewCaledonia, - '687' - ], - [ - 'New Zealand', - CountryISO.NewZealand, - '64' - ], - [ - 'Nicaragua', - CountryISO.Nicaragua, - '505' - ], - [ - 'Niger', - CountryISO.Niger, - '227' - ], - [ - 'Nigeria', - CountryISO.Nigeria, - '234' - ], - [ - 'Niue', - CountryISO.Niue, - '683' - ], - [ - 'Norfolk Island', - CountryISO.NorfolkIsland, - '672' - ], - [ - 'North Korea', - CountryISO.NorthKorea, - '850' - ], - [ - 'Northern Mariana Islands', - CountryISO.NorthernMarianaIslands, - '1670' - ], - [ - 'Norway', - CountryISO.Norway, - '47', - 0 - ], - [ - 'Oman', - CountryISO.Oman, - '968' - ], - [ - 'Pakistan', - CountryISO.Pakistan, - '92' - ], - [ - 'Palau', - CountryISO.Palau, - '680' - ], - [ - 'Palestine', - CountryISO.Palestine, - '970' - ], - [ - 'Panama', - CountryISO.Panama, - '507' - ], - [ - 'Papua New Guinea', - CountryISO.PapuaNewGuinea, - '675' - ], - [ - 'Paraguay', - CountryISO.Paraguay, - '595' - ], - [ - 'Peru', - CountryISO.Peru, - '51' - ], - [ - 'Philippines', - CountryISO.Philippines, - '63' - ], - [ - 'Poland', - CountryISO.Poland, - '48' - ], - [ - 'Portugal', - CountryISO.Portugal, - '351' - ], - [ - 'Puerto Rico', - CountryISO.PuertoRico, - '1', - 3, - ['787', '939'] - ], - [ - 'Qatar', - CountryISO.Qatar, - '974' - ], - [ - 'Réunion', - CountryISO.Réunion, - '262', - 0 - ], - [ - 'Romania', - CountryISO.Romania, - '40' - ], - [ - 'Russia', - CountryISO.Russia, - '7', - 0 - ], - [ - 'Rwanda', - CountryISO.Rwanda, - '250' - ], - [ - 'Saint Barthélemy', - CountryISO.SaintBarthélemy, - '590', - 1 - ], - [ - 'Saint Helena', - CountryISO.SaintHelena, - '290' - ], - [ - 'Saint Kitts and Nevis', - CountryISO.SaintKittsAndNevis, - '1869' - ], - [ - 'Saint Lucia', - CountryISO.SaintLucia, - '1', - 1, - [ - '758', - ] - ], - [ - 'Saint Martin', - CountryISO.SaintMartin, - '590', - 2 - ], - [ - 'Saint Pierre and Miquelon', - CountryISO.SaintPierreAndMiquelon, - '508' - ], - [ - 'Saint Vincent and the Grenadines', - CountryISO.SaintVincentAndTheGrenadines, - '1', - 1, - [ - '784', - ] - ], - [ - 'Samoa', - CountryISO.Samoa, - '685' - ], - [ - 'San Marino', - CountryISO.SanMarino, - '378' - ], - [ - 'São Tomé and Príncipe', - CountryISO.SãoToméAndPríncipe, - '239' - ], - [ - 'Saudi Arabia', - CountryISO.SaudiArabia, - '966' - ], - [ - 'Senegal', - CountryISO.Senegal, - '221' - ], - [ - 'Serbia', - CountryISO.Serbia, - '381' - ], - [ - 'Seychelles', - CountryISO.Seychelles, - '248' - ], - [ - 'Sierra Leone', - CountryISO.SierraLeone, - '232' - ], - [ - 'Singapore', - CountryISO.Singapore, - '65' - ], - [ - 'Sint Maarten', - CountryISO.SintMaarten, - '1', - 1, - [ - '721', - ] - ], - [ - 'Slovakia', - CountryISO.Slovakia, - '421' - ], - [ - 'Slovenia', - CountryISO.Slovenia, - '386' - ], - [ - 'Solomon Islands', - CountryISO.SolomonIslands, - '677' - ], - [ - 'Somalia', - CountryISO.Somalia, - '252' - ], - [ - 'South Africa', - CountryISO.SouthAfrica, - '27' - ], - [ - 'South Korea', - CountryISO.SouthKorea, - '82' - ], - [ - 'South Sudan', - CountryISO.SouthSudan, - '211' - ], - [ - 'Spain', - CountryISO.Spain, - '34' - ], - [ - 'Sri Lanka', - CountryISO.SriLanka, - '94' - ], - [ - 'Sudan', - CountryISO.Sudan, - '249' - ], - [ - 'Suriname', - CountryISO.Suriname, - '597' - ], - [ - 'Svalbard and Jan Mayen', - CountryISO.SvalbardAndJanMayen, - '47', - 1 - ], - [ - 'Swaziland', - CountryISO.Swaziland, - '268' - ], - [ - 'Sweden', - CountryISO.Sweden, - '46' - ], - [ - 'Switzerland', - CountryISO.Switzerland, - '41' - ], - [ - 'Syria', - CountryISO.Syria, - '963' - ], - [ - 'Taiwan', - CountryISO.Taiwan, - '886' - ], - [ - 'Tajikistan', - CountryISO.Tajikistan, - '992' - ], - [ - 'Tanzania', - CountryISO.Tanzania, - '255' - ], - [ - 'Thailand', - CountryISO.Thailand, - '66' - ], - [ - 'Timor-Leste', - CountryISO.TimorLeste, - '670' - ], - [ - 'Togo', - CountryISO.Togo, - '228' - ], - [ - 'Tokelau', - CountryISO.Tokelau, - '690' - ], - [ - 'Tonga', - CountryISO.Tonga, - '676' - ], - [ - 'Trinidad and Tobago', - CountryISO.TrinidadAndTobago, - '1', - 1, - [ - '868', - ] - ], - [ - 'Tunisia', - CountryISO.Tunisia, - '216' - ], - [ - 'Turkey', - CountryISO.Turkey, - '90' - ], - [ - 'Turkmenistan', - CountryISO.Turkmenistan, - '993' - ], - [ - 'Turks and Caicos Islands', - CountryISO.TurksAndCaicosIslands, - '1649' - ], - [ - 'Tuvalu', - CountryISO.Tuvalu, - '688' - ], - [ - 'U.S. Virgin Islands', - CountryISO.USVirginIslands, - '1', - 1, - [ - '340', - ] - ], - [ - 'Uganda', - CountryISO.Uganda, - '256' - ], - [ - 'Ukraine', - CountryISO.Ukraine, - '380' - ], - [ - 'United Arab Emirates', - CountryISO.UnitedArabEmirates, - '971' - ], - [ - 'United Kingdom', - CountryISO.UnitedKingdom, - '44', - 0 - ], - [ - 'United States', - CountryISO.UnitedStates, - '1', - 0 - ], - [ - 'Uruguay', - CountryISO.Uruguay, - '598' - ], - [ - 'Uzbekistan', - CountryISO.Uzbekistan, - '998' - ], - [ - 'Vanuatu', - CountryISO.Vanuatu, - '678' - ], - [ - 'Vatican City', - CountryISO.VaticanCity, - '39', - 1 - ], - [ - 'Venezuela', - CountryISO.Venezuela, - '58' - ], - [ - 'Vietnam', - CountryISO.Vietnam, - '84' - ], - [ - 'Wallis and Futuna', - CountryISO.WallisAndFutuna, - '681' - ], - [ - 'Western Sahara', - CountryISO.WesternSahara, - '212', - 1 - ], - [ - 'Yemen', - CountryISO.Yemen, - '967' - ], - [ - 'Zambia', - CountryISO.Zambia, - '260' - ], - [ - 'Zimbabwe', - CountryISO.Zimbabwe, - '263' - ], - [ - 'Åland Islands', - CountryISO.ÅlandIslands, - '358', - 1 - ] + public allCountries: Array = [ + {name: 'Afghanistan', iso2: CountryISO.Afghanistan, dialCode: '93', flag: '🇦🇫'}, + {name: 'Albania', iso2: CountryISO.Albania, dialCode: '355', flag: '🇦🇱'}, + {name: 'Algeria', iso2: CountryISO.Algeria, dialCode: '213', flag: '🇩🇿'}, + {name: 'American Samoa', iso2: CountryISO.AmericanSamoa, dialCode: '1', flag: '🇦🇸'}, + {name: 'Andorra', iso2: CountryISO.Andorra, dialCode: '376', flag: '🇦🇩'}, + {name: 'Angola', iso2: CountryISO.Angola, dialCode: '244', flag: '🇦🇴'}, + {name: 'Anguilla', iso2: CountryISO.Anguilla, dialCode: '1', flag: '🇦🇮'}, + {name: 'Antigua and Barbuda', iso2: CountryISO.AntiguaAndBarbuda, dialCode: '1', flag: '🇦🇬'}, + {name: 'Argentina', iso2: CountryISO.Argentina, dialCode: '54', flag: '🇦🇷'}, + {name: 'Armenia', iso2: CountryISO.Armenia, dialCode: '374', flag: '🇦🇲'}, + {name: 'Aruba', iso2: CountryISO.Aruba, dialCode: '297', flag: '🇦🇼'}, + {name: 'Australia', iso2: CountryISO.Australia, dialCode: '61', flag: '🇦🇺'}, + {name: 'Austria', iso2: CountryISO.Austria, dialCode: '43', flag: '🇦🇹'}, + {name: 'Azerbaijan', iso2: CountryISO.Azerbaijan, dialCode: '994', flag: '🇦🇿'}, + {name: 'Bahamas', iso2: CountryISO.Bahamas, dialCode: '1', flag: '🇧🇸'}, + {name: 'Bahrain', iso2: CountryISO.Bahrain, dialCode: '973', flag: '🇧🇭'}, + {name: 'Bangladesh', iso2: CountryISO.Bangladesh, dialCode: '880', flag: '🇧🇩'}, + {name: 'Barbados', iso2: CountryISO.Barbados, dialCode: '1', flag: '🇧🇧'}, + {name: 'Belarus', iso2: CountryISO.Belarus, dialCode: '375', flag: '🇧🇾'}, + {name: 'Belgium', iso2: CountryISO.Belgium, dialCode: '32', flag: '🇧🇪'}, + {name: 'Belize', iso2: CountryISO.Belize, dialCode: '501', flag: '🇧🇿'}, + {name: 'Benin', iso2: CountryISO.Benin, dialCode: '229', flag: '🇧🇯'}, + {name: 'Bermuda', iso2: CountryISO.Bermuda, dialCode: '1', flag: '🇧🇲'}, + {name: 'Bhutan', iso2: CountryISO.Bhutan, dialCode: '975', flag: '🇧🇹'}, + {name: 'Bolivia', iso2: CountryISO.Bolivia, dialCode: '591', flag: '🇧🇴'}, + {name: 'Bosnia and Herzegovina', iso2: CountryISO.BosniaAndHerzegovina, dialCode: '387', flag: '🇧🇦'}, + {name: 'Botswana', iso2: CountryISO.Botswana, dialCode: '267', flag: '🇧🇼'}, + {name: 'Brazil', iso2: CountryISO.Brazil, dialCode: '55', flag: '🇧🇷'}, + {name: 'British Indian Ocean Territory', iso2: CountryISO.BritishIndianOceanTerritory, dialCode: '246', flag: '🇮🇴'}, + {name: 'British Virgin Islands', iso2: CountryISO.BritishVirginIslands, dialCode: '1', flag: '🇻🇬'}, + {name: 'Brunei', iso2: CountryISO.Brunei, dialCode: '673', flag: '🇧🇳'}, + {name: 'Bulgaria', iso2: CountryISO.Bulgaria, dialCode: '359', flag: '🇧🇬'}, + {name: 'Burkina Faso', iso2: CountryISO.BurkinaFaso, dialCode: '226', flag: '🇧🇫'}, + {name: 'Burundi', iso2: CountryISO.Burundi, dialCode: '257', flag: '🇧🇮'}, + {name: 'Cambodia', iso2: CountryISO.Cambodia, dialCode: '855', flag: '🇰🇭'}, + {name: 'Cameroon', iso2: CountryISO.Cameroon, dialCode: '237', flag: '🇨🇲'}, + {name: 'Canada', iso2: CountryISO.Canada, dialCode: '1', flag: '🇨🇦'}, + {name: 'Cape Verde', iso2: CountryISO.CapeVerde, dialCode: '238', flag: '🇨🇻'}, + {name: 'Caribbean Netherlands', iso2: CountryISO.CaribbeanNetherlands, dialCode: '599', flag: '🇧🇶'}, + {name: 'Cayman Islands', iso2: CountryISO.CaymanIslands, dialCode: '1', flag: '🇰🇾'}, + {name: 'Central African Republic', iso2: CountryISO.CentralAfricanRepublic, dialCode: '236', flag: '🇨🇫'}, + {name: 'Chad', iso2: CountryISO.Chad, dialCode: '235', flag: '🇹🇩'}, + {name: 'Chile', iso2: CountryISO.Chile, dialCode: '56', flag: '🇨🇱'}, + {name: 'China', iso2: CountryISO.China, dialCode: '86', flag: '🇨🇳'}, + {name: 'Christmas Island', iso2: CountryISO.ChristmasIsland, dialCode: '61', flag: '🇨🇽'}, + {name: 'Cocos Islands', iso2: CountryISO.Cocos, dialCode: '61', flag: '🇨🇨'}, + {name: 'Colombia', iso2: CountryISO.Colombia, dialCode: '57', flag: '🇨🇨'}, + {name: 'Comoros', iso2: CountryISO.Comoros, dialCode: '269', flag: '🇰🇲'}, + {name: 'Congo-Kinshasa', iso2: CountryISO.CongoDRCJamhuriYaKidemokrasiaYaKongo, dialCode: '243', flag: '🇨🇩'}, + {name: 'Congo-Brazzaville', iso2: CountryISO.CongoRepublicCongoBrazzaville, dialCode: '242', flag: '🇨🇬'}, + {name: 'Cook Islands', iso2: CountryISO.CookIslands, dialCode: '682', flag: '🇨🇰'}, + {name: 'Costa Rica', iso2: CountryISO.CostaRica, dialCode: '506', flag: '🇨🇷'}, + {name: 'Côte d’Ivoire', iso2: CountryISO.CôteDIvoire, dialCode: '225', flag: '🇨🇮'}, + {name: 'Croatia', iso2: CountryISO.Croatia, dialCode: '385', flag: '🇭🇷'}, + {name: 'Cuba', iso2: CountryISO.Cuba, dialCode: '53', flag: '🇨🇺'}, + {name: 'Curaçao', iso2: CountryISO.Curaçao, dialCode: '599', flag: '🇨🇼'}, + {name: 'Cyprus', iso2: CountryISO.Cyprus, dialCode: '357', flag: '🇨🇾'}, + {name: 'Czech Republic', iso2: CountryISO.CzechRepublic, dialCode: '420', flag: '🇨🇿'}, + {name: 'Denmark', iso2: CountryISO.Denmark, dialCode: '45', flag: '🇩🇰'}, + {name: 'Djibouti', iso2: CountryISO.Djibouti, dialCode: '253', flag: '🇩🇯'}, + {name: 'Dominica', iso2: CountryISO.Dominica, dialCode: '1767', flag: '🇩🇲'}, + {name: 'Dominican Republic', iso2: CountryISO.DominicanRepublic, dialCode: '1', flag: '🇩🇴'}, + {name: 'Ecuador', iso2: CountryISO.Ecuador, dialCode: '593', flag: '🇪🇨'}, + {name: 'Egypt', iso2: CountryISO.Egypt, dialCode: '20', flag: '🇪🇬'}, + {name: 'El Salvador', iso2: CountryISO.ElSalvador, dialCode: '503', flag: '🇸🇻'}, + {name: 'Equatorial Guinea', iso2: CountryISO.EquatorialGuinea, dialCode: '240', flag: '🇬🇶'}, + {name: 'Eritrea', iso2: CountryISO.Eritrea, dialCode: '291', flag: '🇪🇷'}, + {name: 'Estonia', iso2: CountryISO.Estonia, dialCode: '372', flag: '🇪🇪'}, + {name: 'Ethiopia', iso2: CountryISO.Ethiopia, dialCode: '251', flag: '🇪🇹'}, + {name: 'Falkland Islands', iso2: CountryISO.FalklandIslands, dialCode: '500', flag: '🇫🇰'}, + {name: 'Faroe Islands', iso2: CountryISO.FaroeIslands, dialCode: '298', flag: '🇫🇴'}, + {name: 'Fiji', iso2: CountryISO.Fiji, dialCode: '679', flag: '🇫🇯'}, + {name: 'Finland', iso2: CountryISO.Finland, dialCode: '358', flag: '🇫🇮'}, + {name: 'France', iso2: CountryISO.France, dialCode: '33', flag: '🇫🇷'}, + {name: 'French Guiana', iso2: CountryISO.FrenchGuiana, dialCode: '594', flag: '🇬🇫'}, + {name: 'French Polynesia', iso2: CountryISO.FrenchPolynesia, dialCode: '689', flag: '🇵🇫'}, + {name: 'Gabon', iso2: CountryISO.Gabon, dialCode: '241', flag: '🇬🇦'}, + {name: 'Gambia', iso2: CountryISO.Gambia, dialCode: '220', flag: '🇬🇲'}, + {name: 'Georgia', iso2: CountryISO.Georgia, dialCode: '995', flag: '🇬🇪'}, + {name: 'Germany', iso2: CountryISO.Germany, dialCode: '49', flag: '🇩🇪'}, + {name: 'Ghana', iso2: CountryISO.Ghana, dialCode: '233', flag: '🇬🇭'}, + {name: 'Gibraltar', iso2: CountryISO.Gibraltar, dialCode: '350', flag: '🇬🇮'}, + {name: 'Greece', iso2: CountryISO.Greece, dialCode: '30', flag: '🇬🇷'}, + {name: 'Greenland', iso2: CountryISO.Greenland, dialCode: '299', flag: '🇬🇱'}, + {name: 'Grenada', iso2: CountryISO.Grenada, dialCode: '1473', flag: '🇬🇩'}, + {name: 'Guadeloupe', iso2: CountryISO.Guadeloupe, dialCode: '590', flag: '🇬🇵'}, + {name: 'Guam', iso2: CountryISO.Guam, dialCode: '1', flag: '🇬🇺'}, + {name: 'Guatemala', iso2: CountryISO.Guatemala, dialCode: '502', flag: '🇬🇹'}, + {name: 'Guernsey', iso2: CountryISO.Guernsey, dialCode: '44', flag: '🇬🇬'}, + {name: 'Guinea', iso2: CountryISO.Guinea, dialCode: '224', flag: '🇬🇳'}, + {name: 'Guinea-Bissau', iso2: CountryISO.GuineaBissau, dialCode: '245', flag: '🇬🇼'}, + {name: 'Guyana', iso2: CountryISO.Guyana, dialCode: '592', flag: '🇬🇾'}, + {name: 'Haiti', iso2: CountryISO.Haiti, dialCode: '509', flag: '🇭🇹'}, + {name: 'Honduras', iso2: CountryISO.Honduras, dialCode: '504', flag: '🇭🇳'}, + {name: 'Hong Kong', iso2: CountryISO.HongKong, dialCode: '852', flag: '🇭🇰'}, + {name: 'Hungary', iso2: CountryISO.Hungary, dialCode: '36', flag: '🇭🇺'}, + {name: 'Iceland', iso2: CountryISO.Iceland, dialCode: '354', flag: '🇮🇸'}, + {name: 'India', iso2: CountryISO.India, dialCode: '91', flag: '🇮🇳'}, + {name: 'Indonesia', iso2: CountryISO.Indonesia, dialCode: '62', flag: '🇮🇩'}, + {name: 'Iran', iso2: CountryISO.Iran, dialCode: '98', flag: '🇮🇷'}, + {name: 'Iraq', iso2: CountryISO.Iraq, dialCode: '964', flag: '🇮🇶'}, + {name: 'Ireland', iso2: CountryISO.Ireland, dialCode: '353', flag: '🇮🇪'}, + {name: 'Isle of Man', iso2: CountryISO.IsleOfMan, dialCode: '44', flag: '🇮🇲'}, + {name: 'Israel', iso2: CountryISO.Israel, dialCode: '972', flag: '🇮🇱'}, + {name: 'Italy', iso2: CountryISO.Italy, dialCode: '39', flag: '🇮🇹'}, + {name: 'Jamaica', iso2: CountryISO.Jamaica, dialCode: '1', flag: '🇯🇲'}, + {name: 'Japan', iso2: CountryISO.Japan, dialCode: '81', flag: '🇯🇵'}, + {name: 'Jersey', iso2: CountryISO.Jersey, dialCode: '44', flag: '🇯🇪'}, + {name: 'Jordan', iso2: CountryISO.Jordan, dialCode: '962', flag: '🇯🇴'}, + {name: 'Kazakhstan', iso2: CountryISO.Kazakhstan, dialCode: '7', flag: '🇰🇿'}, + {name: 'Kenya', iso2: CountryISO.Kenya, dialCode: '254', flag: '🇰🇪'}, + {name: 'Kiribati', iso2: CountryISO.Kiribati, dialCode: '686', flag: '🇰🇮'}, + {name: 'Kosovo', iso2: CountryISO.Kosovo, dialCode: '383', flag: '🇽🇰'}, + {name: 'Kuwait', iso2: CountryISO.Kuwait, dialCode: '965', flag: '🇰🇼'}, + {name: 'Kyrgyzstan', iso2: CountryISO.Kyrgyzstan, dialCode: '996', flag: '🇰🇬'}, + {name: 'Laos', iso2: CountryISO.Laos, dialCode: '856', flag: '🇱🇦'}, + {name: 'Latvia', iso2: CountryISO.Latvia, dialCode: '371', flag: '🇱🇻'}, + {name: 'Lebanon', iso2: CountryISO.Lebanon, dialCode: '961', flag: '🇱🇧'}, + {name: 'Lesotho', iso2: CountryISO.Lesotho, dialCode: '266', flag: '🇱🇸'}, + {name: 'Liberia', iso2: CountryISO.Liberia, dialCode: '231', flag: '🇱🇷'}, + {name: 'Libya', iso2: CountryISO.Libya, dialCode: '218', flag: '🇱🇾'}, + {name: 'Liechtenstein', iso2: CountryISO.Liechtenstein, dialCode: '423', flag: '🇱🇮'}, + {name: 'Lithuania', iso2: CountryISO.Lithuania, dialCode: '370', flag: '🇱🇹'}, + {name: 'Luxembourg', iso2: CountryISO.Luxembourg, dialCode: '352', flag: '🇱🇺'}, + {name: 'Macau', iso2: CountryISO.Macau, dialCode: '853', flag: '🇲🇴'}, + {name: 'Macedonia', iso2: CountryISO.Macedonia, dialCode: '389', flag: '🇲🇰'}, + {name: 'Madagascar', iso2: CountryISO.Madagascar, dialCode: '261', flag: '🇲🇬'}, + {name: 'Malawi', iso2: CountryISO.Malawi, dialCode: '265', flag: '🇲🇼'}, + {name: 'Malaysia', iso2: CountryISO.Malaysia, dialCode: '60', flag: '🇲🇾'}, + {name: 'Maldives', iso2: CountryISO.Maldives, dialCode: '960', flag: '🇲🇻'}, + {name: 'Mali', iso2: CountryISO.Mali, dialCode: '223', flag: '🇲🇱'}, + {name: 'Malta', iso2: CountryISO.Malta, dialCode: '356', flag: '🇲🇹'}, + {name: 'Marshall Islands', iso2: CountryISO.MarshallIslands, dialCode: '692', flag: '🇲🇭'}, + {name: 'Martinique', iso2: CountryISO.Martinique, dialCode: '596', flag: '🇲🇶'}, + {name: 'Mauritania', iso2: CountryISO.Mauritania, dialCode: '222', flag: '🇲🇷'}, + {name: 'Mauritius', iso2: CountryISO.Mauritius, dialCode: '230', flag: '🇲🇺'}, + {name: 'Mayotte', iso2: CountryISO.Mayotte, dialCode: '262', flag: '🇾🇹'}, + {name: 'Mexico', iso2: CountryISO.Mexico, dialCode: '52', flag: '🇲🇽'}, + {name: 'Micronesia', iso2: CountryISO.Micronesia, dialCode: '691', flag: '🇫🇲'}, + {name: 'Moldova', iso2: CountryISO.Moldova, dialCode: '373', flag: '🇲🇩'}, + {name: 'Monaco', iso2: CountryISO.Monaco, dialCode: '377', flag: '🇲🇨'}, + {name: 'Mongolia', iso2: CountryISO.Mongolia, dialCode: '976', flag: '🇲🇳'}, + {name: 'Montenegro', iso2: CountryISO.Montenegro, dialCode: '382', flag: '🇲🇪'}, + {name: 'Montserrat', iso2: CountryISO.Montserrat, dialCode: '1', flag: '🇲🇸'}, + {name: 'Morocco', iso2: CountryISO.Morocco, dialCode: '212', flag: '🇲🇦'}, + {name: 'Mozambique', iso2: CountryISO.Mozambique, dialCode: '258', flag: '🇲🇿'}, + {name: 'Myanmar', iso2: CountryISO.Myanmar, dialCode: '95', flag: '🇲🇲'}, + {name: 'Namibia', iso2: CountryISO.Namibia, dialCode: '264', flag: '🇳🇦'}, + {name: 'Nauru', iso2: CountryISO.Nauru, dialCode: '674', flag: '🇳🇷'}, + {name: 'Nepal', iso2: CountryISO.Nepal, dialCode: '977', flag: '🇳🇵'}, + {name: 'Netherlands', iso2: CountryISO.Netherlands, dialCode: '31', flag: '🇳🇱'}, + {name: 'New Caledonia', iso2: CountryISO.NewCaledonia, dialCode: '687', flag: '🇳🇨'}, + {name: 'New Zealand', iso2: CountryISO.NewZealand, dialCode: '64', flag: '🇳🇿'}, + {name: 'Nicaragua', iso2: CountryISO.Nicaragua, dialCode: '505', flag: '🇳🇮'}, + {name: 'Niger', iso2: CountryISO.Niger, dialCode: '227', flag: '🇳🇪'}, + {name: 'Nigeria', iso2: CountryISO.Nigeria, dialCode: '234', flag: '🇳🇬'}, + {name: 'Niue', iso2: CountryISO.Niue, dialCode: '683', flag: '🇳🇺'}, + {name: 'Norfolk Island', iso2: CountryISO.NorfolkIsland, dialCode: '672', flag: '🇳🇫'}, + {name: 'North Korea', iso2: CountryISO.NorthKorea, dialCode: '850', flag: '🇰🇵'}, + {name: 'Northern Mariana Islands', iso2: CountryISO.NorthernMarianaIslands, dialCode: '1670', flag: '🇲🇵'}, + {name: 'Norway', iso2: CountryISO.Norway, dialCode: '47', flag: '🇳🇴'}, + {name: 'Oman', iso2: CountryISO.Oman, dialCode: '968', flag: '🇴🇲'}, + {name: 'Pakistan', iso2: CountryISO.Pakistan, dialCode: '92', flag: '🇵🇰'}, + {name: 'Palau', iso2: CountryISO.Palau, dialCode: '680', flag: '🇵🇼'}, + {name: 'Palestine', iso2: CountryISO.Palestine, dialCode: '970', flag: '🇵🇸'}, + {name: 'Panama', iso2: CountryISO.Panama, dialCode: '507', flag: '🇵🇦'}, + {name: 'Papua New Guinea', iso2: CountryISO.PapuaNewGuinea, dialCode: '675', flag: '🇵🇬'}, + {name: 'Paraguay', iso2: CountryISO.Paraguay, dialCode: '595', flag: '🇵🇾'}, + {name: 'Peru', iso2: CountryISO.Peru, dialCode: '51', flag: '🇵🇪'}, + {name: 'Philippines', iso2: CountryISO.Philippines, dialCode: '63', flag: '🇵🇭'}, + {name: 'Poland', iso2: CountryISO.Poland, dialCode: '48', flag: '🇵🇱'}, + {name: 'Portugal', iso2: CountryISO.Portugal, dialCode: '351', flag: '🇵🇹'}, + {name: 'Puerto Rico', iso2: CountryISO.PuertoRico, dialCode: '1', flag: '🇵🇷'}, + {name: 'Qatar', iso2: CountryISO.Qatar, dialCode: '974', flag: '🇶🇦'}, + {name: 'Réunion', iso2: CountryISO.Réunion, dialCode: '262', flag: '🇷🇪'}, + {name: 'Romania', iso2: CountryISO.Romania, dialCode: '40', flag: '🇷🇴'}, + {name: 'Russia', iso2: CountryISO.Russia, dialCode: '7', flag: '🇷🇺'}, + {name: 'Rwanda', iso2: CountryISO.Rwanda, dialCode: '250', flag: '🇷🇼'}, + {name: 'Saint Barthélemy', iso2: CountryISO.SaintBarthélemy, dialCode: '590', flag: '🇧🇱'}, + {name: 'Saint Helena', iso2: CountryISO.SaintHelena, dialCode: '290', flag: '🇸🇭'}, + {name: 'Saint Kitts and Nevis', iso2: CountryISO.SaintKittsAndNevis, dialCode: '1869', flag: '🇰🇳'}, + {name: 'Saint Lucia', iso2: CountryISO.SaintLucia, dialCode: '1', flag: '🇱🇨'}, + {name: 'Saint Martin', iso2: CountryISO.SaintMartin, dialCode: '590', flag: '🇲🇫'}, + {name: 'Saint Pierre and Miquelon', iso2: CountryISO.SaintPierreAndMiquelon, dialCode: '508', flag: '🇵🇲'}, + {name: 'Saint Vincent and the Grenadines', iso2: CountryISO.SaintVincentAndTheGrenadines, dialCode: '1', flag: '🇻🇨'}, + {name: 'Samoa', iso2: CountryISO.Samoa, dialCode: '685', flag: '🇼🇸'}, + {name: 'San Marino', iso2: CountryISO.SanMarino, dialCode: '378', flag: '🇸🇲'}, + {name: 'São Tomé and Príncipe', iso2: CountryISO.SãoToméAndPríncipe, dialCode: '239', flag: '🇸🇹'}, + {name: 'Saudi Arabia', iso2: CountryISO.SaudiArabia, dialCode: '966', flag: '🇸🇦'}, + {name: 'Senegal', iso2: CountryISO.Senegal, dialCode: '221', flag: '🇸🇳'}, + {name: 'Serbia', iso2: CountryISO.Serbia, dialCode: '381', flag: '🇷🇸'}, + {name: 'Seychelles', iso2: CountryISO.Seychelles, dialCode: '248', flag: '🇸🇨'}, + {name: 'Sierra Leone', iso2: CountryISO.SierraLeone, dialCode: '232', flag: '🇸🇱'}, + {name: 'Singapore', iso2: CountryISO.Singapore, dialCode: '65', flag: '🇸🇬'}, + {name: 'Sint Maarten', iso2: CountryISO.SintMaarten, dialCode: '1', flag: '🇸🇽'}, + {name: 'Slovakia', iso2: CountryISO.Slovakia, dialCode: '421', flag: '🇸🇰'}, + {name: 'Slovenia', iso2: CountryISO.Slovenia, dialCode: '386', flag: '🇸🇮'}, + {name: 'Solomon Islands', iso2: CountryISO.SolomonIslands, dialCode: '677', flag: '🇸🇧'}, + {name: 'Somalia', iso2: CountryISO.Somalia, dialCode: '252', flag: '🇸🇴'}, + {name: 'South Africa', iso2: CountryISO.SouthAfrica, dialCode: '27', flag: '🇿🇦'}, + {name: 'South Korea', iso2: CountryISO.SouthKorea, dialCode: '82', flag: '🇰🇷'}, + {name: 'South Sudan', iso2: CountryISO.SouthSudan, dialCode: '211', flag: '🇸🇸'}, + {name: 'Spain', iso2: CountryISO.Spain, dialCode: '34', flag: '🇪🇸'}, + {name: 'Sri Lanka', iso2: CountryISO.SriLanka, dialCode: '94', flag: '🇱🇰'}, + {name: 'Sudan', iso2: CountryISO.Sudan, dialCode: '249', flag: '🇸🇩'}, + {name: 'Suriname: ', iso2: CountryISO.Suriname, dialCode: '597', flag: '🇸🇷'}, + {name: 'Svalbard and Jan Mayen', iso2: CountryISO.SvalbardAndJanMayen, dialCode: '47', flag: '🇸🇯'}, + {name: 'Swaziland', iso2: CountryISO.Swaziland, dialCode: '268', flag: '🇸🇿'}, + {name: 'Sweden', iso2: CountryISO.Sweden, dialCode: '46', flag: '🇸🇪'}, + {name: 'Switzerland', iso2: CountryISO.Switzerland, dialCode: '41', flag: '🇨🇭'}, + {name: 'Syria', iso2: CountryISO.Syria, dialCode: '963', flag: '🇸🇾'}, + {name: 'Taiwan', iso2: CountryISO.Taiwan, dialCode: '886', flag: '🇹🇼'}, + {name: 'Tajikistan', iso2: CountryISO.Tajikistan, dialCode: '992', flag: '🇹🇯'}, + {name: 'Tanzania', iso2: CountryISO.Tanzania, dialCode: '255', flag: '🇹🇿'}, + {name: 'Thailand', iso2: CountryISO.Thailand, dialCode: '66', flag: '🇹🇭'}, + {name: 'Timor-Leste', iso2: CountryISO.TimorLeste, dialCode: '670', flag: '🇹🇱'}, + {name: 'Togo', iso2: CountryISO.Togo, dialCode: '228', flag: '🇹🇬'}, + {name: 'Tokelau', iso2: CountryISO.Tokelau, dialCode: '690', flag: '🇹🇰'}, + {name: 'Tonga', iso2: CountryISO.Tonga, dialCode: '676', flag: '🇹🇴'}, + {name: 'Trinidad and Tobago', iso2: CountryISO.TrinidadAndTobago, dialCode: '1', flag: '🇹🇹'}, + {name: 'Tunisia', iso2: CountryISO.Tunisia, dialCode: '216', flag: '🇹🇳'}, + {name: 'Turkey', iso2: CountryISO.Turkey, dialCode: '90', flag: '🇹🇷'}, + {name: 'Turkmenistan', iso2: CountryISO.Turkmenistan, dialCode: '993', flag: '🇹🇲'}, + {name: 'Turks and Caicos Islands', iso2: CountryISO.TurksAndCaicosIslands, dialCode: '1649', flag: '🇹🇨'}, + {name: 'Tuvalu', iso2: CountryISO.Tuvalu, dialCode: '688', flag: '🇹🇻'}, + {name: 'U.S. Virgin Islands', iso2: CountryISO.USVirginIslands, dialCode: '1', flag: '🇻🇮'}, + {name: 'Uganda', iso2: CountryISO.Uganda, dialCode: '256', flag: '🇺🇬'}, + {name: 'Ukraine', iso2: CountryISO.Ukraine, dialCode: '380', flag: '🇺🇦'}, + {name: 'United Arab Emirates', iso2: CountryISO.UnitedArabEmirates, dialCode: '971', flag: '🇦🇪'}, + {name: 'United Kingdom', iso2: CountryISO.UnitedKingdom, dialCode: '44', flag: '🇬🇧'}, + {name: 'United States', iso2: CountryISO.UnitedStates, dialCode: '1', flag: '🇺🇸'}, + {name: 'Uruguay', iso2: CountryISO.Uruguay, dialCode: '598', flag: '🇺🇾'}, + {name: 'Uzbekistan', iso2: CountryISO.Uzbekistan, dialCode: '998', flag: '🇺🇿'}, + {name: 'Vanuatu', iso2: CountryISO.Vanuatu, dialCode: '678', flag: '🇻🇺'}, + {name: 'Vatican City', iso2: CountryISO.VaticanCity, dialCode: '39', flag: '🇻🇦'}, + {name: 'Venezuela', iso2: CountryISO.Venezuela, dialCode: '58', flag: '🇻🇪'}, + {name: 'Vietnam', iso2: CountryISO.Vietnam, dialCode: '84', flag: '🇻🇳'}, + {name: 'Wallis and Futuna', iso2: CountryISO.WallisAndFutuna, dialCode: '681', flag: '🇼🇫'}, + {name: 'Western Sahara', iso2: CountryISO.WesternSahara, dialCode: '212', flag: '🇪🇭'}, + {name: 'Yemen', iso2: CountryISO.Yemen, dialCode: '967', flag: '🇾🇪'}, + {name: 'Zambia', iso2: CountryISO.Zambia, dialCode: '260', flag: '🇿🇲'}, + {name: 'Zimbabwe', iso2: CountryISO.Zimbabwe, dialCode: '263', flag: '🇿🇼'}, + {name: 'Åland Islands', iso2: CountryISO.ÅlandIslands, dialCode: '358', flag: '🇦🇽'} ]; } From afc3820b79a1c54330fb6d30e1808e7d49de4b34 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Mon, 13 Jun 2022 16:48:15 +0300 Subject: [PATCH 67/86] UI: Change placeholder --- ui-ngx/src/app/shared/components/phone-input.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui-ngx/src/app/shared/components/phone-input.component.html b/ui-ngx/src/app/shared/components/phone-input.component.html index 4b81391b5f..039f52a272 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.html +++ b/ui-ngx/src/app/shared/components/phone-input.component.html @@ -28,12 +28,12 @@
- phone-input.phone-input-label + security.2fa.dialog.sms-step-label Date: Mon, 13 Jun 2022 18:06:32 +0300 Subject: [PATCH 68/86] UI: Fixed vulnerabilities in tb-web-ui --- msa/web-ui/package.json | 21 +- msa/web-ui/pom.xml | 4 +- msa/web-ui/yarn.lock | 966 ++++++++++++++++++++++------------------ 3 files changed, 537 insertions(+), 454 deletions(-) diff --git a/msa/web-ui/package.json b/msa/web-ui/package.json index 1cd252e0de..81e0663613 100644 --- a/msa/web-ui/package.json +++ b/msa/web-ui/package.json @@ -13,14 +13,14 @@ }, "dependencies": { "compression": "^1.7.4", - "config": "^3.3.1", + "config": "^3.3.7", "connect-history-api-fallback": "^1.6.0", - "express": "^4.17.1", + "express": "^4.18.1", "http": "0.0.0", "http-proxy": "^1.18.1", - "js-yaml": "^3.14.0", - "winston": "^3.3.3", - "winston-daily-rotate-file": "^4.5.0" + "js-yaml": "^4.1.0", + "winston": "^3.7.2", + "winston-daily-rotate-file": "^4.7.1" }, "nyc": { "exclude": [ @@ -31,13 +31,18 @@ ] }, "devDependencies": { - "fs-extra": "^10.0.0", - "nodemon": "^2.0.12", - "pkg": "^5.3.1" + "fs-extra": "^10.1.0", + "nodemon": "^2.0.16", + "pkg": "^5.7.0" }, "pkg": { "assets": [ "node_modules/config/**/*.*" ] + }, + "resolutions": { + "color-string": "^1.5.5", + "follow-redirects": "^1.14.8", + "minimist": "^1.2.6" } } diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index f04b339a8e..c949555d46 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -80,8 +80,8 @@ install-node-and-yarn - v12.16.1 - v1.22.4 + v16.13.1 + v1.22.17 diff --git a/msa/web-ui/yarn.lock b/msa/web-ui/yarn.lock index 2c7012b515..2204573d19 100644 --- a/msa/web-ui/yarn.lock +++ b/msa/web-ui/yarn.lock @@ -2,25 +2,29 @@ # yarn lockfile v1 -"@babel/helper-validator-identifier@^7.12.11": - 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/parser@7.13.13": - version "7.13.13" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df" - integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw== - -"@babel/types@7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.12.tgz#edbf99208ef48852acdff1c8a681a1e4ade580cd" - integrity sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + +"@babel/parser@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78" + integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ== + +"@babel/types@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.10.tgz#d35d7b4467e439fcf06d195f8100e0fea7fc82c4" + integrity sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + "@dabh/diagnostics@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" @@ -73,7 +77,7 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -accepts@~1.3.5, accepts@~1.3.7: +accepts@~1.3.5: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== @@ -81,6 +85,14 @@ accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + agent-base@6: version "6.0.2" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" @@ -115,6 +127,11 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + ansi-styles@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" @@ -130,10 +147,10 @@ ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" -anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -151,12 +168,10 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-flatten@1.1.1: version "1.1.1" @@ -168,10 +183,10 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -async@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== +async@^3.2.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== at-least-node@^1.0.0: version "1.0.0" @@ -202,35 +217,37 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== dependencies: - bytes "3.1.0" + bytes "3.1.2" content-type "~1.0.4" debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" -boxen@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" - integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== +boxen@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== dependencies: ansi-align "^3.0.0" - camelcase "^5.3.1" - chalk "^3.0.0" - cli-boxes "^2.2.0" - string-width "^4.1.0" - term-size "^2.1.0" - type-fest "^0.8.1" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" widest-line "^3.1.0" + wrap-ansi "^7.0.0" brace-expansion@^1.1.7: version "1.1.11" @@ -240,7 +257,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.1, braces@~3.0.2: +braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -260,10 +277,10 @@ bytes@3.0.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== cacheable-request@^6.0.0: version "6.1.0" @@ -278,20 +295,20 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== +call-bind@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" + function-bind "^1.1.1" + get-intrinsic "^1.0.2" -chalk@^4.1.0: +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -299,20 +316,20 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@^3.2.2: - version "3.4.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" - integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== +chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: - anymatch "~3.1.1" + anymatch "~3.1.2" braces "~3.0.2" - glob-parent "~5.1.0" + glob-parent "~5.1.2" is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.4.0" + readdirp "~3.6.0" optionalDependencies: - fsevents "~2.1.2" + fsevents "~2.3.2" chownr@^1.1.1: version "1.1.4" @@ -324,10 +341,10 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -cli-boxes@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d" - integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== cliui@^7.0.2: version "7.0.4" @@ -374,10 +391,10 @@ color-name@^1.0.0, color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== +color-string@^1.5.2, color-string@^1.5.5: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -390,11 +407,6 @@ color@3.0.x: color-convert "^1.9.1" color-string "^1.5.2" -colors@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - colorspace@1.1.x: version "1.1.2" resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" @@ -428,10 +440,10 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -config@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/config/-/config-3.3.1.tgz#b6a70e2908a43b98ed20be7e367edf0cc8ed5a19" - integrity sha512-+2/KaaaAzdwUBE3jgZON11L1ggLLhpf2FsGrfqYFHZW22ySGv/HqYIXrBwKKvn+XZh1UBUjHwAcrfsSkSygT+Q== +config@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/config/-/config-3.3.7.tgz#4310410dc2bf4e0effdca21a12a4035860a24ee4" + integrity sha512-mX/n7GKDYZMqvvkY6e6oBY49W8wxdmQt+ho/5lhwFDXqQW9gI+Ahp8EKp8VAbISPnmf2+Bv5uZK7lKXZ6pf1aA== dependencies: json5 "^2.1.1" @@ -457,12 +469,12 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: - safe-buffer "5.1.2" + safe-buffer "5.2.1" content-type@~1.0.4: version "1.0.4" @@ -474,10 +486,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== core-util-is@~1.0.0: version "1.0.2" @@ -489,7 +501,7 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -debug@2.6.9, debug@^2.2.0: +debug@2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -503,10 +515,10 @@ debug@4: dependencies: ms "2.1.2" -debug@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" @@ -544,15 +556,15 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== detect-libc@^1.0.3: version "1.0.3" @@ -637,7 +649,7 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -esprima@^4.0.0, esprima@^4.0.1: +esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -667,64 +679,59 @@ expand-template@^2.0.3: resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== -express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== +express@^4.18.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== dependencies: - accepts "~1.3.7" + accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" + body-parser "1.20.0" + content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.4.0" + cookie "0.5.0" cookie-signature "1.0.6" debug "2.6.9" - depd "~1.1.2" + depd "2.0.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "~1.1.2" + finalhandler "1.2.0" fresh "0.5.2" + http-errors "2.0.0" merge-descriptors "1.0.1" methods "~1.1.2" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" + proxy-addr "~2.0.7" + qs "6.10.3" range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" -fast-glob@^3.1.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" + micromatch "^4.0.4" fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fast-safe-stringify@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" - integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== - fastq@^1.6.0: version "1.8.0" resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481" @@ -737,12 +744,12 @@ fecha@^4.2.0: resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.0.tgz#3ffb6395453e3f3efff850404f0a59b6747f5f41" integrity sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg== -file-stream-rotator@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-0.5.7.tgz#868a2e5966f7640a17dd86eda0e4467c089f6286" - integrity sha512-VYb3HZ/GiAGUCrfeakO8Mp54YGswNUHvL7P09WQcXAJNSj3iQ5QraYSp3cIn1MUyw6uzfgN/EFOarCNa4JvUHQ== +file-stream-rotator@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz#007019e735b262bb6c6f0197e58e5c87cb96cec3" + integrity sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ== dependencies: - moment "^2.11.2" + moment "^2.29.1" fill-range@^7.0.1: version "7.0.1" @@ -751,17 +758,17 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== dependencies: debug "2.6.9" encodeurl "~1.0.2" escape-html "~1.0.3" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" - statuses "~1.5.0" + statuses "2.0.1" unpipe "~1.0.0" fn.name@1.x.x: @@ -769,15 +776,15 @@ fn.name@1.x.x: resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== -follow-redirects@^1.0.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db" - integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA== +follow-redirects@^1.0.0, follow-redirects@^1.14.8: + version "1.15.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5" + integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA== -forwarded@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.2.tgz#98c23dab1175657b8c0573e8ceccd91b0ff18c84" - integrity sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ= +forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== fresh@0.5.2: version "0.5.2" @@ -797,10 +804,10 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" - integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== +fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -816,10 +823,10 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" @@ -845,6 +852,15 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -864,30 +880,30 @@ github-from-package@0.0.0: resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= -glob-parent@^5.1.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -global-dirs@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201" - integrity sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A== +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== dependencies: - ini "^1.3.5" + ini "2.0.0" -globby@^11.0.3: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" slash "^3.0.0" got@^9.6.0: @@ -922,6 +938,11 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -944,27 +965,16 @@ http-cache-semantics@^4.0.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== dependencies: - depd "~1.1.2" + depd "2.0.0" inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" http-proxy@^1.18.1: version "1.18.1" @@ -1005,10 +1015,10 @@ ignore-by-default@^1.0.1: resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= -ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== import-lazy@^2.1.0: version "2.1.0" @@ -1020,17 +1030,17 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^1.3.5, ini@~1.3.0: +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== @@ -1067,10 +1077,10 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.2.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.6.0.tgz#d7553b2526fe59b92ba3e40c8df757ec8a709e19" - integrity sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ== +is-core-module@2.9.0, is-core-module@^2.8.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" @@ -1103,18 +1113,18 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-installed-globally@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" - integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== dependencies: - global-dirs "^2.0.1" - is-path-inside "^3.0.1" + global-dirs "^3.0.0" + is-path-inside "^3.0.2" -is-npm@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" - integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== +is-npm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" + integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== is-number@^7.0.0: version "7.0.0" @@ -1126,10 +1136,10 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-path-inside@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" - integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== is-stream@^2.0.0: version "2.0.0" @@ -1151,13 +1161,12 @@ isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -js-yaml@^3.14.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: - argparse "^1.0.7" - esprima "^4.0.0" + argparse "^2.0.1" json-buffer@3.0.0: version "3.0.0" @@ -1192,7 +1201,7 @@ kuler@^2.0.0: resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== -latest-version@^5.0.0: +latest-version@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== @@ -1207,20 +1216,15 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -lodash@^4.17.19: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -logform@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2" - integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg== +logform@^2.3.2, logform@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.4.0.tgz#131651715a17d50f09c2a2c1a524ff1a4164bcfe" + integrity sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw== dependencies: - colors "^1.2.1" - fast-safe-stringify "^2.0.4" + "@colors/colors" "1.5.0" fecha "^4.2.0" ms "^2.1.1" + safe-stable-stringify "^2.3.1" triple-beam "^1.3.0" lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: @@ -1257,7 +1261,7 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= -merge2@^1.3.0: +merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -1267,19 +1271,24 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: - braces "^3.0.1" - picomatch "^2.0.5" + braces "^3.0.2" + picomatch "^2.3.1" mime-db@1.44.0, "mime-db@>= 1.43.0 < 2": version "1.44.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" @@ -1287,6 +1296,13 @@ mime-types@~2.1.24: dependencies: mime-db "1.44.0" +mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" @@ -1309,36 +1325,36 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -moment@^2.11.2: - version "2.27.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d" - integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ== +moment@^2.29.1: + version "2.29.3" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.3.tgz#edd47411c322413999f7a5940d526de183c031f3" + integrity sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw== ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - ms@2.1.2, ms@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + multistream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/multistream/-/multistream-4.1.0.tgz#7bf00dfd119556fbc153cff3de4c6d477909f5a8" @@ -1357,38 +1373,40 @@ negotiator@0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -node-abi@^2.7.0: +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +node-abi@^2.21.0: version "2.30.1" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.1.tgz#c437d4b1fe0e285aaf290d45b45d4d7afedac4cf" integrity sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w== dependencies: semver "^5.4.1" -node-fetch@^2.6.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0" - integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA== +node-fetch@^2.6.6: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" -nodemon@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.12.tgz#5dae4e162b617b91f1873b3bfea215dd71e144d5" - integrity sha512-egCTmNZdObdBxUBw6ZNwvZ/xzk24CKRs5K6d+5zbmrMr7rOpPmfPeF6OxM3DDpaRx331CQRFEktn+wrFFfBSOA== +nodemon@^2.0.16: + version "2.0.16" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.16.tgz#d71b31bfdb226c25de34afea53486c8ef225fdef" + integrity sha512-zsrcaOfTWRuUzBn3P44RDliLlp263Z/76FPoHFr3cFFkOz0lTPAcIw8dCzfdVIx/t3AtDYCZRCDkoCojJqaG3w== dependencies: - chokidar "^3.2.2" - debug "^3.2.6" + chokidar "^3.5.2" + debug "^3.2.7" ignore-by-default "^1.0.1" minimatch "^3.0.4" - pstree.remy "^1.1.7" + pstree.remy "^1.1.8" semver "^5.7.1" supports-color "^5.5.0" touch "^3.1.0" - undefsafe "^2.0.3" - update-notifier "^4.1.0" - -noop-logger@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" - integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= + undefsafe "^2.0.5" + update-notifier "^5.1.0" nopt@~1.0.10: version "1.0.10" @@ -1432,10 +1450,15 @@ object-hash@^2.0.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= +object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== dependencies: ee-first "1.1.1" @@ -1495,10 +1518,10 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-to-regexp@0.1.7: version "0.1.7" @@ -1510,49 +1533,54 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== -pkg-fetch@3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/pkg-fetch/-/pkg-fetch-3.2.2.tgz#33f391eb176c1844e93189a32f2279b36a1ec949" - integrity sha512-bLhFNT4cNnONxzbHo1H2mCCKuQkCR4dgQtv0gUZnWtp8TDP0v0UAXKHG7DXhAoTC5IYP3slLsFJtIda9ksny8g== +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-fetch@3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/pkg-fetch/-/pkg-fetch-3.4.1.tgz#be68bb9f7fdb0f6ed995abc518ab2e35aa64d2fd" + integrity sha512-fS4cdayCa1r4jHkOKGPJKnS9PEs6OWZst+s+m0+CmhmPZObMnxoRnf9T9yUWl+lzM2b5aJF7cnQIySCT7Hq8Dg== dependencies: - chalk "^4.1.0" + chalk "^4.1.2" fs-extra "^9.1.0" https-proxy-agent "^5.0.0" - node-fetch "^2.6.1" + node-fetch "^2.6.6" progress "^2.0.3" semver "^7.3.5" + tar-fs "^2.1.1" yargs "^16.2.0" -pkg@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/pkg/-/pkg-5.3.1.tgz#8f81671613b9e5bb1d83c39b2eed4799e1e679fe" - integrity sha512-jT/sptM1ZG++FNk+jnJYNoWLDQXYd7hqpnBhd5j18SNW1jJzNYo55RahuCiD0KN0PX9mb53GWCqKM0ia/mJytA== +pkg@^5.7.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/pkg/-/pkg-5.7.0.tgz#6422df05e8aa147764be6ef912921d0fa719ea95" + integrity sha512-PTiAjNq/CGAtK5qUBR6pjheqnipTFjeecgSgIKEcAOJA4GpmZeOZC8pMOoT0rfes5vHsmcFo7wbSRTAmXQurrg== dependencies: - "@babel/parser" "7.13.13" - "@babel/types" "7.13.12" - chalk "^4.1.0" + "@babel/parser" "7.17.10" + "@babel/types" "7.17.10" + chalk "^4.1.2" escodegen "^2.0.0" fs-extra "^9.1.0" - globby "^11.0.3" + globby "^11.1.0" into-stream "^6.0.0" - minimist "^1.2.5" + is-core-module "2.9.0" + minimist "^1.2.6" multistream "^4.1.0" - pkg-fetch "3.2.2" - prebuild-install "6.0.1" - progress "^2.0.3" - resolve "^1.20.0" + pkg-fetch "3.4.1" + prebuild-install "6.1.4" + resolve "^1.22.0" stream-meter "^1.0.4" - tslib "2.1.0" -prebuild-install@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.0.1.tgz#5902172f7a40eb67305b96c2a695db32636ee26d" - integrity sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ== +prebuild-install@6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.4.tgz#ae3c0142ad611d58570b89af4986088a4937e00f" + integrity sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ== dependencies: detect-libc "^1.0.3" expand-template "^2.0.3" @@ -1560,15 +1588,13 @@ prebuild-install@6.0.1: minimist "^1.2.3" mkdirp-classic "^0.5.3" napi-build-utils "^1.0.1" - node-abi "^2.7.0" - noop-logger "^0.1.1" + node-abi "^2.21.0" npmlog "^4.0.1" pump "^3.0.0" rc "^1.2.7" simple-get "^3.0.3" tar-fs "^2.0.0" tunnel-agent "^0.6.0" - which-pm-runs "^1.0.0" prelude-ls@~1.1.2: version "1.1.2" @@ -1590,15 +1616,15 @@ progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -proxy-addr@~2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" - integrity sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw== +proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== dependencies: - forwarded "~0.1.2" + forwarded "0.2.0" ipaddr.js "1.9.1" -pstree.remy@^1.1.7: +pstree.remy@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== @@ -1611,30 +1637,32 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" -pupa@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726" - integrity sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA== +pupa@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== dependencies: escape-goat "^2.0.0" -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== dependencies: - bytes "3.1.0" - http-errors "1.7.2" + bytes "3.1.2" + http-errors "2.0.0" iconv-lite "0.4.24" unpipe "1.0.0" @@ -1670,10 +1698,10 @@ readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdirp@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" - integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" @@ -1701,13 +1729,14 @@ requires-port@^1.0.0: resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= -resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== +resolve@^1.22.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" responselike@^1.0.2: version "1.0.2" @@ -1731,11 +1760,16 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-stable-stringify@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73" + integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg== + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -1758,6 +1792,13 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.3.4: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" + semver@^7.3.5: version "7.3.5" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" @@ -1765,44 +1806,53 @@ semver@^7.3.5: dependencies: lru-cache "^6.0.0" -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== dependencies: debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" + depd "2.0.0" + destroy "1.2.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" - http-errors "~1.7.2" + http-errors "2.0.0" mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" + ms "2.1.3" + on-finished "2.4.1" range-parser "~1.2.1" - statuses "~1.5.0" + statuses "2.0.1" -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.17.1" + send "0.18.0" set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" @@ -1840,20 +1890,15 @@ source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== stream-meter@^1.0.4: version "1.0.4" @@ -1906,6 +1951,15 @@ string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string-width@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -1948,6 +2002,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -1967,7 +2028,12 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -tar-fs@^2.0.0: +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tar-fs@^2.0.0, tar-fs@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== @@ -1988,11 +2054,6 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" -term-size@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.0.tgz#1f16adedfe9bdc18800e1776821734086fcc6753" - integrity sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw== - text-hex@1.0.x: version "1.0.0" resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" @@ -2015,10 +2076,10 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== touch@^3.1.0: version "3.1.0" @@ -2027,16 +2088,16 @@ touch@^3.1.0: dependencies: nopt "~1.0.10" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + triple-beam@^1.2.0, triple-beam@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== -tslib@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -2051,12 +2112,12 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-is@~1.6.17, type-is@~1.6.18: +type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -2071,12 +2132,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -undefsafe@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" - integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== - dependencies: - debug "^2.2.0" +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== unique-string@^2.0.0: version "2.0.0" @@ -2100,22 +2159,23 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= -update-notifier@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" - integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A== +update-notifier@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" + integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== dependencies: - boxen "^4.2.0" - chalk "^3.0.0" + boxen "^5.0.0" + chalk "^4.1.0" configstore "^5.0.1" has-yarn "^2.1.0" import-lazy "^2.1.0" is-ci "^2.0.0" - is-installed-globally "^0.3.1" - is-npm "^4.0.0" + is-installed-globally "^0.4.0" + is-npm "^5.0.0" is-yarn-global "^0.3.0" - latest-version "^5.0.0" - pupa "^2.0.1" + latest-version "^5.1.0" + pupa "^2.1.1" + semver "^7.3.4" semver-diff "^3.1.1" xdg-basedir "^4.0.0" @@ -2141,10 +2201,18 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -which-pm-runs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" - integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" wide-align@^1.1.0: version "1.1.3" @@ -2160,17 +2228,17 @@ widest-line@^3.1.0: dependencies: string-width "^4.0.0" -winston-daily-rotate-file@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.0.tgz#3914ac57c4bdae1138170bec85af0c2217b253b1" - integrity sha512-/HqeWiU48dzGqcrABRlxYWVMdL6l3uKCtFSJyrqK+E2rLnSFNsgYpvwx15EgTitBLNzH69lQd/+z2ASryV2aqw== +winston-daily-rotate-file@^4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz#f60a643af87f8867f23170d8cd87dbe3603a625f" + integrity sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA== dependencies: - file-stream-rotator "^0.5.7" + file-stream-rotator "^0.6.1" object-hash "^2.0.1" triple-beam "^1.3.0" - winston-transport "^4.2.0" + winston-transport "^4.4.0" -winston-transport@^4.2.0, winston-transport@^4.4.0: +winston-transport@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== @@ -2178,20 +2246,30 @@ winston-transport@^4.2.0, winston-transport@^4.4.0: readable-stream "^2.3.7" triple-beam "^1.2.0" -winston@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" - integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== +winston-transport@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa" + integrity sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q== + dependencies: + logform "^2.3.2" + readable-stream "^3.6.0" + triple-beam "^1.3.0" + +winston@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.7.2.tgz#95b4eeddbec902b3db1424932ac634f887c400b1" + integrity sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng== dependencies: "@dabh/diagnostics" "^2.0.2" - async "^3.1.0" + async "^3.2.3" is-stream "^2.0.0" - logform "^2.2.0" + logform "^2.4.0" one-time "^1.0.0" readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" stack-trace "0.0.x" triple-beam "^1.3.0" - winston-transport "^4.4.0" + winston-transport "^4.5.0" word-wrap@~1.2.3: version "1.2.3" From 258417346f2d672d2d8b795f5a05b57fd6c96937 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 14 Jun 2022 09:16:32 +0300 Subject: [PATCH 69/86] refactoring: customer - test start --- .../controller/AbstractNotifyEntityTest.java | 113 +++++++++++----- .../controller/BaseAlarmControllerTest.java | 22 +-- .../BaseCustomerControllerTest.java | 125 ++++++++++++++---- 3 files changed, 192 insertions(+), 68 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java index a5827d6f6d..6fb7b93bae 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.controller; +import lombok.extern.slf4j.Slf4j; import org.mockito.Mockito; import org.springframework.boot.test.mock.mockito.SpyBean; import org.thingsboard.server.cluster.TbClusterService; @@ -26,6 +27,8 @@ import org.thingsboard.server.common.data.id.EntityId; import org.thingsboard.server.common.data.id.EntityIdFactory; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.id.UserId; +import org.thingsboard.server.common.data.plugin.ComponentLifecycleEvent; +import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.model.ModelConstants; @@ -35,6 +38,7 @@ import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.thingsboard.server.service.entitiy.DefaultTbNotificationEntityService.edgeTypeByActionType; +@Slf4j public abstract class AbstractNotifyEntityTest extends AbstractWebTest { @SpyBean @@ -43,31 +47,53 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { @SpyBean protected AuditLogService auditLogService; - protected void testNotifyEntityOk(HasName entity, EntityId entityId, EntityId originatorId, - TenantId tenantId, CustomerId customerId, UserId userId, String userName, - ActionType actionType) { - testSendNotificationMsgToEdgeServiceOk(entityId, tenantId, actionType); - testLogEntityActionOk(entity, originatorId, tenantId, customerId, userId, userName, actionType); - testPushMsgToRuleEngineOk(entity, originatorId, tenantId, customerId, userId, userName, actionType); + protected void testNotifyEntityOne(HasName entity, EntityId entityId, EntityId originatorId, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType, Object... additionalInfo) { + testSendNotificationMsgToEdgeServiceOne(entityId, tenantId, actionType); + testLogEntityActionOne(entity, originatorId, tenantId, customerId, userId, userName, actionType, additionalInfo); + testPushMsgToRuleEngineOne(originatorId, tenantId); Mockito.reset(tbClusterService, auditLogService); } - protected void testNotifyEntityDeleteOk(HasName entity, EntityId entityId, EntityId originatorId, - TenantId tenantId, CustomerId customerId, UserId userId, String userName, - ActionType actionType) { - Mockito.verify(tbClusterService, never()).sendNotificationMsgToEdgeService(Mockito.any(), - Mockito.any(), Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any(), Mockito.any()); - testLogEntityActionOk(entity, originatorId, tenantId, customerId, userId, userName, actionType); - testPushMsgToRuleEngineOk(entity, originatorId, tenantId, customerId, userId, userName, actionType); + + protected void testNotifyEntityDeleteOneMsgToEdgeServiceNever(HasName entity, EntityId entityId, EntityId originatorId, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType, Object... additionalInfo) { + testNotificationMsgToEdgeServiceNever(entityId); + testLogEntityActionOne(entity, originatorId, tenantId, customerId, userId, userName, actionType, additionalInfo); + testPushMsgToRuleEngineOne(entityId, tenantId); + testBroadcastEntityStateChangeEventOne(entityId, tenantId); + } - private void testNotifyEntityError(EntityId entityId, HasName entity, TenantId tenantId, - UserId userId, String userName, ActionType actionType, Exception exp, - Object... additionalInfo) { + protected void testNotifyEntityOneMsgToEdgeServiceNever(HasName entity, EntityId entityId, EntityId originatorId, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType, Object... additionalInfo) { + testNotificationMsgToEdgeServiceNever(entityId); + testLogEntityActionOne(entity, originatorId, tenantId, customerId, userId, userName, actionType, additionalInfo); + testPushMsgToRuleEngineOne(originatorId, tenantId); + Mockito.reset(tbClusterService, auditLogService); + } + + protected void testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(HasName entity, EntityId entityId, EntityId originatorId, + TenantId tenantId, CustomerId customerId, UserId userId, String userName, + ActionType actionType, Object... additionalInfo) { + testNotificationMsgToEdgeServiceNever(entityId); + testLogEntityActionOne(entity, originatorId, tenantId, customerId, userId, userName, actionType, additionalInfo); + testPushMsgToRuleEngineOne(originatorId, tenantId); + testBroadcastEntityStateChangeEventOne(entityId, tenantId); + Mockito.reset(tbClusterService, auditLogService); + } + + protected void testNotifyEntityError(HasName entity, TenantId tenantId, + UserId userId, String userName, ActionType actionType, Exception exp, + Object... additionalInfo) { CustomerId customer_NULL_UUID = (CustomerId) EntityIdFactory.getByTypeAndUuid(EntityType.CUSTOMER, ModelConstants.NULL_UUID); - EntityId entity_NULL_UUID = EntityIdFactory.getByTypeAndUuid(EntityType.valueOf(entity.getClass().toString().substring(entity.getClass().toString().lastIndexOf(".") + 1).toUpperCase(Locale.ENGLISH)), + EntityId entity_NULL_UUID = EntityIdFactory.getByTypeAndUuid(EntityType.valueOf(entity.getClass().toString() + .substring(entity.getClass().toString().lastIndexOf(".") + 1).toUpperCase(Locale.ENGLISH)), ModelConstants.NULL_UUID); - testNotificationMsgToEdgeServiceNever(entityId); + testNotificationMsgToEdgeServiceNever(entity_NULL_UUID); if (additionalInfo.length > 0) { Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customer_NULL_UUID), Mockito.eq(userId), Mockito.eq(userName), @@ -77,9 +103,9 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customer_NULL_UUID), Mockito.eq(userId), Mockito.eq(userName), Mockito.eq(entity_NULL_UUID), Mockito.any(entity.getClass()), Mockito.eq(actionType), - Mockito.any(exp.getClass()), Mockito.isNull()); + Mockito.any(exp.getClass())); } - Mockito.verify(tbClusterService, never()).pushMsgToRuleEngine(Mockito.any(), Mockito.any(entityId.getClass()), + Mockito.verify(tbClusterService, never()).pushMsgToRuleEngine(Mockito.any(), Mockito.any(entity_NULL_UUID.getClass()), Mockito.any(), Mockito.any()); Mockito.reset(tbClusterService, auditLogService); } @@ -106,27 +132,46 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.any(entityId.getClass()), Mockito.any(), Mockito.any()); } - private void testLogEntityActionOk(HasName entity, EntityId originatorId, - TenantId tenantId, CustomerId customerId, UserId userId, String userName, - ActionType actionType) { - Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), - Mockito.eq(userId), Mockito.eq(userName), Mockito.eq(originatorId), - Mockito.eq(entity), Mockito.eq(actionType), Mockito.isNull()); + private void testLogEntityActionOne(HasName entity, EntityId originatorId, TenantId tenantId, CustomerId customerId, + UserId userId, String userName, ActionType actionType, Object... additionalInfo) { + if (additionalInfo.length == 0) { + Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), + Mockito.eq(userId), Mockito.eq(userName), Mockito.eq(originatorId), + Mockito.eq(entity), Mockito.eq(actionType), Mockito.isNull()); + } else { + String additionalInfoStr = extractParameter(String.class, 0, additionalInfo); + Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), + Mockito.eq(userId), Mockito.eq(userName), Mockito.eq(originatorId), + Mockito.eq(entity), Mockito.eq(actionType), Mockito.isNull(), Mockito.eq(additionalInfoStr)); + } } - private void testPushMsgToRuleEngineOk(HasName entity, EntityId originatorId, - TenantId tenantId, CustomerId customerId, UserId userId, String userName, - ActionType actionType) { - - Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customerId), - Mockito.eq(userId), Mockito.eq(userName), Mockito.eq(originatorId), - Mockito.eq(entity), Mockito.eq(actionType), Mockito.isNull()); + private void testPushMsgToRuleEngineOne(EntityId originatorId, TenantId tenantId) { + Mockito.verify(tbClusterService, times(1)).pushMsgToRuleEngine(Mockito.eq(tenantId), + Mockito.eq(originatorId), Mockito.any(TbMsg.class), Mockito.isNull()); } - private void testSendNotificationMsgToEdgeServiceOk(EntityId entityId, TenantId tenantId, ActionType actionType) { + private void testSendNotificationMsgToEdgeServiceOne(EntityId entityId, TenantId tenantId, ActionType actionType) { Mockito.verify(tbClusterService, times(1)).sendNotificationMsgToEdgeService(Mockito.eq(tenantId), Mockito.isNull(), Mockito.eq(entityId), Mockito.isNull(), Mockito.isNull(), Mockito.eq(edgeTypeByActionType(actionType))); } + private void testBroadcastEntityStateChangeEventOne(EntityId entityId, TenantId tenantId) { + Mockito.verify(tbClusterService, times(1)).broadcastEntityStateChangeEvent(Mockito.eq(tenantId), + Mockito.any(entityId.getClass()), Mockito.any(ComponentLifecycleEvent.class)); + } + + private T extractParameter(Class clazz, int index, Object... additionalInfo) { + T result = null; + if (additionalInfo != null && additionalInfo.length > index) { + Object paramObject = additionalInfo[index]; + if (clazz.isInstance(paramObject)) { + result = clazz.cast(paramObject); + } + } + return result; + } + + } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java index 16a9f993c3..d82f4175b5 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java @@ -65,7 +65,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); logout(); } @@ -78,7 +78,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); logout(); } @@ -91,7 +91,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); alarm.setSeverity(AlarmSeverity.MAJOR); @@ -99,7 +99,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { Assert.assertNotNull(updatedAlarm); Assert.assertEquals(AlarmSeverity.MAJOR, updatedAlarm.getSeverity()); - testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.UPDATED); logout(); } @@ -112,7 +112,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOk(alarm, alarm.getId(), alarm.getOriginator(), + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); alarm.setSeverity(AlarmSeverity.MAJOR); @@ -120,7 +120,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { Assert.assertNotNull(updatedAlarm); Assert.assertEquals(AlarmSeverity.MAJOR, updatedAlarm.getSeverity()); - testNotifyEntityOk(updatedAlarm, updatedAlarm.getId(), updatedAlarm.getOriginator(), + testNotifyEntityOne(updatedAlarm, updatedAlarm.getId(), updatedAlarm.getOriginator(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.UPDATED); logout(); } @@ -166,7 +166,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); - testNotifyEntityDeleteOk(alarm, alarm.getId(), alarm.getOriginator(), + testNotifyEntityOneMsgToEdgeServiceNever(alarm, alarm.getId(), alarm.getOriginator(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.DELETED); logout(); } @@ -180,7 +180,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); - testNotifyEntityDeleteOk(alarm, alarm.getId(), alarm.getOriginator(), + testNotifyEntityOneMsgToEdgeServiceNever(alarm, alarm.getId(), alarm.getOriginator(), tenantId, tenantAdminCustomerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.DELETED); logout(); } @@ -229,7 +229,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { Assert.assertNotNull(foundAlarm); Assert.assertEquals(AlarmStatus.CLEARED_UNACK, foundAlarm.getStatus()); - testNotifyEntityOk(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(), + testNotifyEntityOne(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ALARM_CLEAR); logout(); } @@ -246,7 +246,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { Assert.assertNotNull(foundAlarm); Assert.assertEquals(AlarmStatus.CLEARED_UNACK, foundAlarm.getStatus()); - testNotifyEntityOk(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(), + testNotifyEntityOne(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(), tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ALARM_CLEAR); logout(); } @@ -264,7 +264,7 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { Assert.assertNotNull(foundAlarm); Assert.assertEquals(AlarmStatus.ACTIVE_ACK, foundAlarm.getStatus()); - testNotifyEntityOk(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(), + testNotifyEntityOne(foundAlarm, foundAlarm.getId(), foundAlarm.getOriginator(), tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ALARM_ACK); logout(); } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java index a7f623d2e4..0aa81c2d18 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java @@ -25,14 +25,17 @@ import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; import org.thingsboard.common.util.ThingsBoardExecutors; import org.thingsboard.server.common.data.Customer; import org.thingsboard.server.common.data.Tenant; import org.thingsboard.server.common.data.User; +import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.page.PageData; import org.thingsboard.server.common.data.page.PageLink; import org.thingsboard.server.common.data.security.Authority; +import org.thingsboard.server.dao.exception.DataValidationException; import java.util.ArrayList; import java.util.List; @@ -86,71 +89,164 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest public void testSaveCustomer() throws Exception { Customer customer = new Customer(); customer.setTitle("My customer"); + + Mockito.reset(tbClusterService, auditLogService); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); Assert.assertNotNull(savedCustomer); Assert.assertNotNull(savedCustomer.getId()); Assert.assertTrue(savedCustomer.getCreatedTime() > 0); Assert.assertEquals(customer.getTitle(), savedCustomer.getTitle()); + + testNotifyEntityOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), + savedCustomer.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), + tenantAdmin.getEmail(), ActionType.ADDED); + savedCustomer.setTitle("My new customer"); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/customer", savedCustomer, Customer.class); + testNotifyEntityOne(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), + savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UPDATED); + Customer foundCustomer = doGet("/api/customer/" + savedCustomer.getId().getId().toString(), Customer.class); Assert.assertEquals(foundCustomer.getTitle(), savedCustomer.getTitle()); doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isOk()); + + testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), + savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.DELETED, savedCustomer.getId().getId().toString()); } @Test public void testSaveCustomerWithViolationOfValidation() throws Exception { Customer customer = new Customer(); + + Mockito.reset(tbClusterService, auditLogService); + + doPost("/api/customer", customer) + .andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Customer title should be specified"))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: empty title")); + customer.setTitle(RandomStringUtils.randomAlphabetic(300)); + doPost("/api/customer", customer).andExpect(statusReason(containsString("length of title must be equal or less than 255"))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad title")); + customer.setTitle("Normal title"); + customer.setEmail("invalid@mail"); + doPost("/api/customer", customer) + .andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Invalid email address format 'invalid@mail'"))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: invalid email")); + + customer.setEmail("normal@mail.com.ua"); + customer.setCity(RandomStringUtils.randomAlphabetic(300)); doPost("/api/customer", customer).andExpect(statusReason(containsString("length of city must be equal or less than 255"))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad City")); + customer.setCity("Normal city"); customer.setCountry(RandomStringUtils.randomAlphabetic(300)); doPost("/api/customer", customer).andExpect(statusReason(containsString("length of country must be equal or less than 255"))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad Country")); + customer.setCountry("Ukraine"); customer.setPhone(RandomStringUtils.randomAlphabetic(300)); doPost("/api/customer", customer).andExpect(statusReason(containsString("length of phone must be equal or less than 255"))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad Phone")); + customer.setPhone("+3892555554512"); customer.setState(RandomStringUtils.randomAlphabetic(300)); doPost("/api/customer", customer).andExpect(statusReason(containsString("length of state must be equal or less than 255"))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad state")); + customer.setState("Normal state"); customer.setZip(RandomStringUtils.randomAlphabetic(300)); doPost("/api/customer", customer).andExpect(statusReason(containsString("length of zip or postal code must be equal or less than 255"))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad Zip")); } @Test public void testUpdateCustomerFromDifferentTenant() throws Exception { Customer customer = new Customer(); customer.setTitle("My customer"); + + Mockito.reset(tbClusterService, auditLogService); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + + testNotifyEntityOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), + savedCustomer.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED); + doPost("/api/customer", savedCustomer, Customer.class); loginDifferentTenant(); + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/customer", savedCustomer, Customer.class, status().isForbidden()); + + testNotifyEntityNever(savedCustomer.getId(), savedCustomer); + deleteDifferentTenant(); login(tenantAdmin.getName(), "testPassword1"); + + Mockito.reset(tbClusterService, auditLogService); + doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isOk()); + + testNotifyEntityDeleteOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), + savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.DELETED, savedCustomer.getId().getId().toString()); } @Test public void testFindCustomerById() throws Exception { Customer customer = new Customer(); customer.setTitle("My customer"); + + Mockito.reset(tbClusterService, auditLogService); + Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + testNotifyEntityOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), + savedCustomer.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), + tenantAdmin.getEmail(), ActionType.ADDED); + Customer foundCustomer = doGet("/api/customer/" + savedCustomer.getId().getId().toString(), Customer.class); Assert.assertNotNull(foundCustomer); Assert.assertEquals(savedCustomer, foundCustomer); doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isOk()); + + testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), + savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.DELETED, savedCustomer.getId().getId().toString()); } @Test @@ -159,36 +255,19 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest customer.setTitle("My customer"); Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + Mockito.reset(tbClusterService, auditLogService); + doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isOk()); + testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), + savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.DELETED, savedCustomer.getId().getId().toString()); + doGet("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isNotFound()); } - @Test - public void testSaveCustomerWithEmptyTitle() throws Exception { - Customer customer = new Customer(); - doPost("/api/customer", customer) - .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Customer title should be specified"))); - } - - @Test - public void testSaveCustomerWithInvalidEmail() throws Exception { - Customer customer = new Customer(); - customer.setTitle("My customer"); - customer.setEmail("invalid@mail"); - doPost("/api/customer", customer) - .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Invalid email address format 'invalid@mail'"))); - -// loginSysAdmin(); -// -// doDelete("/api/tenant/"+savedTenant.getId().getId().toString()) -// .andExpect(status().isOk()); - } - @Test public void testFindCustomers() throws Exception { TenantId tenantId = savedTenant.getId(); From 6ebd4120c13311ded31671540df8da63247db959 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Tue, 14 Jun 2022 10:21:01 +0300 Subject: [PATCH 70/86] UI: Remove padding --- .../components/dashboard-page/add-widget-dialog.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html b/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html index 99f5e6ebfd..9fa86d8f61 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/add-widget-dialog.component.html @@ -28,7 +28,7 @@ -
+
Date: Tue, 14 Jun 2022 11:18:24 +0300 Subject: [PATCH 71/86] UI: Fixed vulnerabilities in tb-js-executor --- msa/js-executor/package.json | 35 +- msa/js-executor/pom.xml | 4 +- msa/js-executor/queue/serviceBusTemplate.js | 53 +- msa/js-executor/yarn.lock | 2317 +++++++++---------- 4 files changed, 1101 insertions(+), 1308 deletions(-) diff --git a/msa/js-executor/package.json b/msa/js-executor/package.json index 6cbfc1261d..d1df447072 100644 --- a/msa/js-executor/package.json +++ b/msa/js-executor/package.json @@ -12,20 +12,19 @@ "start-prod": "NODE_ENV=production nodemon server.js" }, "dependencies": { - "@azure/service-bus": "^1.1.9", - "@google-cloud/pubsub": "^2.5.0", - "amqplib": "^0.6.0", - "aws-sdk": "^2.741.0", - "azure-sb": "^0.11.1", - "config": "^3.3.1", - "express": "^4.17.1", - "js-yaml": "^3.14.0", - "kafkajs": "^1.15.0", - "long": "^4.0.0", + "@azure/service-bus": "^7.5.1", + "@google-cloud/pubsub": "^3.0.1", + "amqplib": "^0.10.0", + "aws-sdk": "^2.1152.0", + "config": "^3.3.7", + "express": "^4.18.1", + "js-yaml": "^4.1.0", + "kafkajs": "^2.0.2", + "long": "^5.2.0", "uuid-parse": "^1.1.0", "uuid-random": "^1.3.2", - "winston": "^3.3.3", - "winston-daily-rotate-file": "^4.5.0" + "winston": "^3.7.2", + "winston-daily-rotate-file": "^4.7.1" }, "nyc": { "exclude": [ @@ -36,13 +35,19 @@ ] }, "devDependencies": { - "fs-extra": "^10.0.0", - "nodemon": "^2.0.12", - "pkg": "^5.3.1" + "fs-extra": "^10.1.0", + "nodemon": "^2.0.16", + "pkg": "^5.7.0" }, "pkg": { "assets": [ "node_modules/config/**/*.*" ] + }, + "resolutions": { + "ansi-regex": "^5.0.1", + "color-string": "^1.5.5", + "minimist": "^1.2.6", + "node-fetch": "^2.6.7" } } diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index 5532a70b78..a910e4759f 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -71,8 +71,8 @@ install-node-and-yarn - v12.16.1 - v1.22.4 + v16.13.1 + v1.22.17 diff --git a/msa/js-executor/queue/serviceBusTemplate.js b/msa/js-executor/queue/serviceBusTemplate.js index 9016640c67..e8efae1635 100644 --- a/msa/js-executor/queue/serviceBusTemplate.js +++ b/msa/js-executor/queue/serviceBusTemplate.js @@ -18,8 +18,7 @@ const config = require('config'), JsInvokeMessageProcessor = require('../api/jsInvokeMessageProcessor'), logger = require('../config/logger')._logger('serviceBusTemplate'); -const {ServiceBusClient, ReceiveMode} = require("@azure/service-bus"); -const azure = require('azure-sb'); +const {ServiceBusClient, ServiceBusAdministrationClient} = require("@azure/service-bus"); const requestTopic = config.get('request_topic'); const namespaceName = config.get('service_bus.namespace_name'); @@ -28,7 +27,6 @@ const sasKey = config.get('service_bus.sas_key'); const queueProperties = config.get('service_bus.queue_properties'); let sbClient; -let receiverClient; let receiver; let serviceBusService; @@ -61,11 +59,10 @@ function ServiceBusProducer() { } function CustomSender(topic) { - this.queueClient = sbClient.createQueueClient(topic); - this.sender = this.queueClient.createSender(); + this.sender = sbClient.createSender(topic); this.send = async (message) => { - return this.sender.send(message); + return this.sender.sendMessages(message); } } @@ -74,8 +71,8 @@ function CustomSender(topic) { logger.info('Starting ThingsBoard JavaScript Executor Microservice...'); const connectionString = `Endpoint=sb://${namespaceName}.servicebus.windows.net/;SharedAccessKeyName=${sasKeyName};SharedAccessKey=${sasKey}`; - sbClient = ServiceBusClient.createFromConnectionString(connectionString); - serviceBusService = azure.createServiceBusService(connectionString); + sbClient = new ServiceBusClient(connectionString) + serviceBusService = new ServiceBusAdministrationClient(connectionString); parseQueueProperties(); @@ -84,9 +81,9 @@ function CustomSender(topic) { if (err) { reject(err); } else { - data.forEach(queue => { - queues.push(queue.QueueName); - }); + for (const queue of data) { + queues.push(queue.name); + } resolve(); } }); @@ -97,8 +94,7 @@ function CustomSender(topic) { queues.push(requestTopic); } - receiverClient = sbClient.createQueueClient(requestTopic); - receiver = receiverClient.createReceiver(ReceiveMode.peekLock); + receiver = sbClient.createReceiver(requestTopic, {receiveMode: 'peekLock'}); const messageProcessor = new JsInvokeMessageProcessor(new ServiceBusProducer()); @@ -111,18 +107,18 @@ function CustomSender(topic) { const errorHandler = (error) => { logger.error('Failed to receive message from queue.', error); }; - receiver.registerMessageHandler(messageHandler, errorHandler); + receiver.subscribe({processMessage: messageHandler, processError: errorHandler}) } catch (e) { logger.error('Failed to start ThingsBoard JavaScript Executor Microservice: %s', e.message); logger.error(e.stack); - exit(-1); + await exit(-1); } })(); async function createQueueIfNotExist(topic) { return new Promise((resolve, reject) => { - serviceBusService.createQueueIfNotExists(topic, queueOptions, (err) => { - if (err) { + serviceBusService.createQueue(topic, queueOptions, (err) => { + if (err && err.code !== "MessageEntityAlreadyExistsError") { reject(err); } else { resolve(); @@ -139,10 +135,10 @@ function parseQueueProperties() { properties[p.substring(0, delimiterPosition)] = p.substring(delimiterPosition + 1); }); queueOptions = { - DuplicateDetection: 'false', - MaxSizeInMegabytes: properties['maxSizeInMb'], - DefaultMessageTimeToLive: `PT${properties['messageTimeToLiveInSec']}S`, - LockDuration: `PT${properties['lockDurationInSec']}S` + requiresDuplicateDetection: false, + maxSizeInMegabytes: properties['maxSizeInMb'], + defaultMessageTimeToLive: `PT${properties['messageTimeToLiveInSec']}S`, + lockDuration: `PT${properties['lockDurationInSec']}S` }; } @@ -161,24 +157,11 @@ async function exit(status) { } } - if (receiverClient) { - try { - await receiverClient.close(); - } catch (e) { - - } - } - senderMap.forEach((k, v) => { try { v.sender.close(); } catch (e) { - } - try { - v.queueClient.close(); - } catch (e) { - } }); @@ -191,4 +174,4 @@ async function exit(status) { } logger.info('Azure Service Bus resources stopped.') process.exit(status); -} \ No newline at end of file +} diff --git a/msa/js-executor/yarn.lock b/msa/js-executor/yarn.lock index 0c46da466a..f93ad99803 100644 --- a/msa/js-executor/yarn.lock +++ b/msa/js-executor/yarn.lock @@ -9,75 +9,71 @@ dependencies: tslib "^1.9.3" -"@azure/amqp-common@1.0.0-preview.16": - version "1.0.0-preview.16" - resolved "https://registry.yarnpkg.com/@azure/amqp-common/-/amqp-common-1.0.0-preview.16.tgz#3b7a9d39f7503347530fe9afddf92fa7bfd1ec5e" - integrity sha512-rMTBh54lV6/SBujXfPX0OqN+UNpG1zR4EYY+JP66QM0D2jzNdxLiv6gart5Ersy4Tmd89MRlgikaj5+t5NsDgA== +"@azure/core-amqp@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@azure/core-amqp/-/core-amqp-3.1.0.tgz#f8e210cfbabbb5d163649eedeb80c0b69045d358" + integrity sha512-TyI0WFNrVb0EkRg36UwdcqR/7n9YpcEw64O4xVrgzMAlXIciVZpabl05C/Q0iUvLkItmez2XSVDduncjr02oGw== dependencies: - "@types/async-lock" "^1.1.0" - "@types/is-buffer" "^2.0.0" - async-lock "^1.1.3" - buffer "^5.2.1" - debug "^3.1.0" + "@azure/abort-controller" "^1.0.0" + "@azure/core-auth" "^1.3.0" + "@azure/logger" "^1.0.0" + buffer "^6.0.0" events "^3.0.0" - is-buffer "^2.0.3" - jssha "^2.3.1" + jssha "^3.1.0" process "^0.11.10" - rhea "^1.0.18" - rhea-promise "^0.1.15" - stream-browserify "^2.0.2" - tslib "^1.9.3" + rhea "^2.0.3" + rhea-promise "^2.1.0" + tslib "^2.2.0" url "^0.11.0" - util "^0.11.1" + util "^0.12.1" -"@azure/core-auth@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.1.3.tgz#94e7bbc207010e7a2fdba61565443e4e1cf1e131" - integrity sha512-A4xigW0YZZpkj1zK7dKuzbBpGwnhEcRk6WWuIshdHC32raR3EQ1j6VA9XZqE+RFsUgH6OAmIK5BWIz+mZjnd6Q== +"@azure/core-asynciterator-polyfill@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@azure/core-asynciterator-polyfill/-/core-asynciterator-polyfill-1.0.2.tgz#0dd3849fb8d97f062a39db0e5cadc9ffaf861fec" + integrity sha512-3rkP4LnnlWawl0LZptJOdXNrT/fHp2eQMadoasa6afspXdpGrtPZuAQc2PD0cpgyuoXtUWyC3tv7xfntjGS5Dw== + +"@azure/core-auth@^1.3.0": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@azure/core-auth/-/core-auth-1.3.2.tgz#6a2c248576c26df365f6c7881ca04b7f6d08e3d0" + integrity sha512-7CU6DmCHIZp5ZPiZ9r3J17lTKMmYsm/zGvNkjArQwPkrLlZ1TZ+EUYfGgh2X31OLMVAQCTJZW4cXHJi02EbJnA== dependencies: "@azure/abort-controller" "^1.0.0" - "@azure/core-tracing" "1.0.0-preview.8" - "@opentelemetry/api" "^0.6.1" - tslib "^2.0.0" + tslib "^2.2.0" -"@azure/core-http@^1.0.0": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-1.1.6.tgz#9d76bc569c9907e3224bd09c09b4ac08bde9faf8" - integrity sha512-/C+qNzhwlLKt0F6SjaBEyY2pwZvwL2LviyS5PHlCh77qWuTF1sETmYAINM88BCN+kke+UlECK4YOQaAjJwyHvQ== +"@azure/core-http@^2.0.0": + version "2.2.5" + resolved "https://registry.yarnpkg.com/@azure/core-http/-/core-http-2.2.5.tgz#e8cf8345d4a7f0ee7c8304a300c43d2df992ddbe" + integrity sha512-kctMqSQ6zfnlFpuYzfUKadeTyOQYbIQ+3Rj7dzVC3Dk1dOnHroTwR9hLYKX8/n85iJpkyaksaXpuh5L7GJRYuQ== dependencies: "@azure/abort-controller" "^1.0.0" - "@azure/core-auth" "^1.1.3" - "@azure/core-tracing" "1.0.0-preview.9" + "@azure/core-auth" "^1.3.0" + "@azure/core-tracing" "1.0.0-preview.13" "@azure/logger" "^1.0.0" - "@opentelemetry/api" "^0.10.2" "@types/node-fetch" "^2.5.0" - "@types/tunnel" "^0.0.1" - form-data "^3.0.0" - node-fetch "^2.6.0" + "@types/tunnel" "^0.0.3" + form-data "^4.0.0" + node-fetch "^2.6.7" process "^0.11.10" tough-cookie "^4.0.0" - tslib "^2.0.0" + tslib "^2.2.0" tunnel "^0.0.6" - uuid "^8.1.0" + uuid "^8.3.0" xml2js "^0.4.19" -"@azure/core-tracing@1.0.0-preview.8": - version "1.0.0-preview.8" - resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.8.tgz#1e0ff857e855edb774ffd33476003c27b5bb2705" - integrity sha512-ZKUpCd7Dlyfn7bdc+/zC/sf0aRIaNQMDuSj2RhYRFe3p70hVAnYGp3TX4cnG2yoEALp/LTj/XnZGQ8Xzf6Ja/Q== +"@azure/core-paging@^1.1.1": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@azure/core-paging/-/core-paging-1.3.0.tgz#ebf6520a931be7d5ff1cf58bc4fe6c14d6a3080d" + integrity sha512-H6Tg9eBm0brHqLy0OSAGzxIh1t4UL8eZVrSUMJ60Ra9cwq2pOskFqVpz2pYoHDsBY1jZ4V/P8LRGb5D5pmC6rg== dependencies: - "@opencensus/web-types" "0.0.7" - "@opentelemetry/api" "^0.6.1" - tslib "^1.10.0" + tslib "^2.2.0" -"@azure/core-tracing@1.0.0-preview.9": - version "1.0.0-preview.9" - resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.9.tgz#84f3b85572013f9d9b85e1e5d89787aa180787eb" - integrity sha512-zczolCLJ5QG42AEPQ+Qg9SRYNUyB+yZ5dzof4YEc+dyWczO9G2sBqbAjLB7IqrsdHN2apkiB2oXeDKCsq48jug== +"@azure/core-tracing@1.0.0-preview.13": + version "1.0.0-preview.13" + resolved "https://registry.yarnpkg.com/@azure/core-tracing/-/core-tracing-1.0.0-preview.13.tgz#55883d40ae2042f6f1e12b17dd0c0d34c536d644" + integrity sha512-KxDlhXyMlh2Jhj2ykX6vNEU0Vou4nHr025KoSEiz7cS3BNiHNaZcdECk/DmLkEB0as5T7b/TpRcehJ5yV6NeXQ== dependencies: - "@opencensus/web-types" "0.0.7" - "@opentelemetry/api" "^0.10.2" - tslib "^2.0.0" + "@opentelemetry/api" "^1.0.1" + tslib "^2.2.0" "@azure/logger@^1.0.0": version "1.0.0" @@ -86,44 +82,52 @@ dependencies: tslib "^1.9.3" -"@azure/service-bus@^1.1.9": - version "1.1.9" - resolved "https://registry.yarnpkg.com/@azure/service-bus/-/service-bus-1.1.9.tgz#856cec37d0fbd8069fd9b717afa3aa9fdb48c95b" - integrity sha512-7i+7h1gh8vUeeaHddEVg+x7lXSVqhk/f2z4x4ErZByrE0QsyibFVPpBqS3q1RIjpDgmKPxcj7Wzu7O8vJLSaRw== +"@azure/service-bus@^7.5.1": + version "7.5.1" + resolved "https://registry.yarnpkg.com/@azure/service-bus/-/service-bus-7.5.1.tgz#5c006f29cf42779c20b87431e4482150b83be736" + integrity sha512-fIbI5aJDzN2HctcS+3i7rXY3L5jWG7/SuXOq0cMpwy+aH5aHOZVoxX8eeSnUnr2jUpUflU1wJ9yiYZ/sXqZvqw== dependencies: - "@azure/amqp-common" "1.0.0-preview.16" - "@azure/core-http" "^1.0.0" - "@opentelemetry/types" "^0.2.0" + "@azure/abort-controller" "^1.0.0" + "@azure/core-amqp" "^3.1.0" + "@azure/core-asynciterator-polyfill" "^1.0.0" + "@azure/core-auth" "^1.3.0" + "@azure/core-http" "^2.0.0" + "@azure/core-paging" "^1.1.1" + "@azure/core-tracing" "1.0.0-preview.13" + "@azure/logger" "^1.0.0" "@types/is-buffer" "^2.0.0" - "@types/long" "^4.0.0" - buffer "^5.2.1" - debug "^4.1.1" + "@types/long" "^4.0.1" + buffer "^6.0.0" is-buffer "^2.0.3" + jssha "^3.1.0" long "^4.0.0" process "^0.11.10" - rhea "^1.0.23" - rhea-promise "^0.1.15" - tslib "^1.10.0" - -"@babel/helper-validator-identifier@^7.12.11": - 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/parser@7.13.13": - version "7.13.13" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.13.tgz#42f03862f4aed50461e543270916b47dd501f0df" - integrity sha512-OhsyMrqygfk5v8HmWwOzlYjJrtLaFhF34MrfG/Z73DgYCI6ojNUTUp2TYbtnjo8PegeJp12eamsNettCQjKjVw== - -"@babel/types@7.13.12": - version "7.13.12" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.12.tgz#edbf99208ef48852acdff1c8a681a1e4ade580cd" - integrity sha512-K4nY2xFN4QMvQwkQ+zmBDp6ANMbVNw6BbxWmYA4qNjhR9W+Lj/8ky5MEY2Me5r+B2c6/v6F53oMndG+f9s3IiA== - dependencies: - "@babel/helper-validator-identifier" "^7.12.11" - lodash "^4.17.19" + rhea-promise "^2.1.0" + tslib "^2.2.0" + +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + +"@babel/parser@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.10.tgz#873b16db82a8909e0fbd7f115772f4b739f6ce78" + integrity sha512-n2Q6i+fnJqzOaq2VkdXxy2TCPCWQZHiCo0XqmrCvDWcZQKRyZzYi4Z0yxlBuN0w+r2ZHmre+Q087DSrw3pbJDQ== + +"@babel/types@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.10.tgz#d35d7b4467e439fcf06d195f8100e0fea7fc82c4" + integrity sha512-9O26jG0mBYfGkUYCYZRnBwbVLd1UZOICEr2Em6InB6jVfsAv1GKgwXHmrSg+WFWDmeKTA6vyTZiN8tCSM5Oo3A== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + "@dabh/diagnostics@^2.0.2": version "2.0.2" resolved "https://registry.yarnpkg.com/@dabh/diagnostics/-/diagnostics-2.0.2.tgz#290d08f7b381b8f94607dc8f471a12c675f9db31" @@ -133,10 +137,10 @@ enabled "2.0.x" kuler "^2.0.0" -"@google-cloud/paginator@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@google-cloud/paginator/-/paginator-3.0.4.tgz#4106cadd8153d157c8afd16d66dfb89a38ba8748" - integrity sha512-fKI+jYQdV1F9jtG6tSRro3ilNSeBWVmTzxc8Z0kiPRXcj8eshh9fiF8TtxfDefyUKgTdWgHpzGBwLbZ/OGikJg== +"@google-cloud/paginator@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@google-cloud/paginator/-/paginator-4.0.0.tgz#9c3e01544717aecb9a922b4269ff298f30a0f1bb" + integrity sha512-wNmCZl+2G2DmgT/VlF+AROf80SoaC/CwS8trwmjNaq26VRNK8yPbU5F/Vy+R9oDAGKWQU2k8+Op5H4kFJVXFaQ== dependencies: arrify "^2.0.0" extend "^3.0.2" @@ -156,55 +160,45 @@ resolved "https://registry.yarnpkg.com/@google-cloud/promisify/-/promisify-2.0.2.tgz#81d654b4cb227c65c7ad2f9a7715262febd409ed" integrity sha512-EvuabjzzZ9E2+OaYf+7P9OAiiwbTxKYL0oGLnREQd+Su2NTQBpomkdlkBowFvyWsaV0d1sSGxrKpSNcrhPqbxg== -"@google-cloud/pubsub@^2.5.0": - version "2.5.0" - resolved "https://registry.yarnpkg.com/@google-cloud/pubsub/-/pubsub-2.5.0.tgz#6c696d9b448f2e1689be9a37ef0362ed173731fd" - integrity sha512-7bbbQqa+LSTopVjt20EZ8maO6rEpbO7v8EvDImHMsbRS30HJ5+kClbaQTRvhNzhc1qy221A1GbHPHMCQ/U5E3Q== +"@google-cloud/pubsub@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@google-cloud/pubsub/-/pubsub-3.0.1.tgz#3a6bb9649a1b4309d82d8670a9c01375e622692f" + integrity sha512-dznNbRd/Y8J0C0xvdvCPi3B1msK/dj/Nya+NQZ2doUOLT6eoa261tBwk9umOQs5L5GKcdlqQKbBjrNjDYVbzQA== dependencies: - "@google-cloud/paginator" "^3.0.0" + "@google-cloud/paginator" "^4.0.0" "@google-cloud/precise-date" "^2.0.0" "@google-cloud/projectify" "^2.0.0" "@google-cloud/promisify" "^2.0.0" - "@opentelemetry/api" "^0.10.0" - "@opentelemetry/tracing" "^0.10.0" + "@opentelemetry/api" "^1.0.0" + "@opentelemetry/semantic-conventions" "^1.0.0" "@types/duplexify" "^3.6.0" "@types/long" "^4.0.0" arrify "^2.0.0" extend "^3.0.2" - google-auth-library "^6.0.0" - google-gax "^2.7.0" + google-auth-library "^8.0.2" + google-gax "^3.0.1" is-stream-ended "^0.1.4" lodash.snakecase "^4.1.1" p-defer "^3.0.0" -"@grpc/grpc-js@~1.1.1": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.1.5.tgz#2d0b261cd54a529f6b78ac0de9d6fd91a9a3129c" - integrity sha512-2huf5z85TdZI4nLmJQ9Zdfd+6vmIyBDs7B4L71bTaHKA9pRsGKAH24XaktMk/xneKJIqAgeIZtg1cyivVZtvrg== +"@grpc/grpc-js@~1.6.0": + version "1.6.7" + resolved "https://registry.yarnpkg.com/@grpc/grpc-js/-/grpc-js-1.6.7.tgz#4c4fa998ff719fe859ac19fe977fdef097bb99aa" + integrity sha512-eBM03pu9hd3VqDQG+kHahiG1x80RGkkqqRb1Pchcwqej/KkAH95gAvKs6laqaHCycYaPK+TKuNQnOz9UXYA8qw== dependencies: - "@grpc/proto-loader" "^0.6.0-pre14" - "@types/node" "^12.12.47" - google-auth-library "^6.0.0" - semver "^6.2.0" - -"@grpc/proto-loader@^0.5.1": - version "0.5.5" - resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.5.5.tgz#6725e7a1827bdf8e92e29fbf4e9ef0203c0906a9" - integrity sha512-WwN9jVNdHRQoOBo9FDH7qU+mgfjPc8GygPYms3M+y3fbQLfnCe/Kv/E01t7JRgnrsOHH8euvSbed3mIalXhwqQ== - dependencies: - lodash.camelcase "^4.3.0" - protobufjs "^6.8.6" + "@grpc/proto-loader" "^0.6.4" + "@types/node" ">=12.12.47" -"@grpc/proto-loader@^0.6.0-pre14": - version "0.6.0-pre9" - resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.6.0-pre9.tgz#0c6fe42f6c5ef9ce1b3cef7be64d5b09d6fe4d6d" - integrity sha512-oM+LjpEjNzW5pNJjt4/hq1HYayNeQT+eGrOPABJnYHv7TyNPDNzkQ76rDYZF86X5swJOa4EujEMzQ9iiTdPgww== +"@grpc/proto-loader@^0.6.12", "@grpc/proto-loader@^0.6.4": + version "0.6.13" + resolved "https://registry.yarnpkg.com/@grpc/proto-loader/-/proto-loader-0.6.13.tgz#008f989b72a40c60c96cd4088522f09b05ac66bc" + integrity sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g== dependencies: "@types/long" "^4.0.1" lodash.camelcase "^4.3.0" long "^4.0.0" - protobufjs "^6.9.0" - yargs "^15.3.1" + protobufjs "^6.11.3" + yargs "^16.2.0" "@nodelib/fs.scandir@2.1.3": version "2.1.3" @@ -227,67 +221,15 @@ "@nodelib/fs.scandir" "2.1.3" fastq "^1.6.0" -"@opencensus/web-types@0.0.7": - version "0.0.7" - resolved "https://registry.yarnpkg.com/@opencensus/web-types/-/web-types-0.0.7.tgz#4426de1fe5aa8f624db395d2152b902874f0570a" - integrity sha512-xB+w7ZDAu3YBzqH44rCmG9/RlrOmFuDPt/bpf17eJr8eZSrLt7nc7LnWdxM9Mmoj/YKMHpxRg28txu3TcpiL+g== - -"@opentelemetry/api@^0.10.0", "@opentelemetry/api@^0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-0.10.2.tgz#9647b881f3e1654089ff7ea59d587b2d35060654" - integrity sha512-GtpMGd6vkzDMYcpu2t9LlhEgMy/SzBwRnz48EejlRArYqZzqSzAsKmegUK7zHgl+EOIaK9mKHhnRaQu3qw20cA== - dependencies: - "@opentelemetry/context-base" "^0.10.2" - -"@opentelemetry/api@^0.6.1": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-0.6.1.tgz#a00b504801f408230b9ad719716fe91ad888c642" - integrity sha512-wpufGZa7tTxw7eAsjXJtiyIQ42IWQdX9iUQp7ACJcKo1hCtuhLU+K2Nv1U6oRwT1oAlZTE6m4CgWKZBhOiau3Q== - dependencies: - "@opentelemetry/context-base" "^0.6.1" - -"@opentelemetry/context-base@^0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.10.2.tgz#55bea904b2b91aa8a8675df9eaba5961bddb1def" - integrity sha512-hZNKjKOYsckoOEgBziGMnBcX0M7EtstnCmwz5jZUOUYwlZ+/xxX6z3jPu1XVO2Jivk0eLfuP9GP+vFD49CMetw== +"@opentelemetry/api@^1.0.0", "@opentelemetry/api@^1.0.1": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.1.0.tgz#563539048255bbe1a5f4f586a4a10a1bb737f44a" + integrity sha512-hf+3bwuBwtXsugA2ULBc95qxrOqP2pOekLz34BJhcAKawt94vfeNyUKpYc0lZQ/3sCP6LqRa7UAdHA7i5UODzQ== -"@opentelemetry/context-base@^0.6.1": - version "0.6.1" - resolved "https://registry.yarnpkg.com/@opentelemetry/context-base/-/context-base-0.6.1.tgz#b260e454ee4f9635ea024fc83be225e397f15363" - integrity sha512-5bHhlTBBq82ti3qPT15TRxkYTFPPQWbnkkQkmHPtqiS1XcTB69cEKd3Jm7Cfi/vkPoyxapmePE9tyA7EzLt8SQ== - -"@opentelemetry/core@^0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-0.10.2.tgz#86b9e94bbcaf8e07bb86e8205aa1d53af854e7de" - integrity sha512-DhkiTp5eje2zTGd+HAIKWpGE6IR6lq7tUpYt4nnkhOi6Hq9WQAANVDCWEZEbYOw57LkdXbE50FZ/kMvHDm450Q== - dependencies: - "@opentelemetry/api" "^0.10.2" - "@opentelemetry/context-base" "^0.10.2" - semver "^7.1.3" - -"@opentelemetry/resources@^0.10.2": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-0.10.2.tgz#6e291d525450359c615aac013fd977047f2c26d7" - integrity sha512-5JGC2TPSAIHth615IURt+sSsTljY43zTfJD0JE9PHC6ipZPiQ0dpQDZOrLn8NAMfOHY1jeWwpIuLASjqbXUfuw== - dependencies: - "@opentelemetry/api" "^0.10.2" - "@opentelemetry/core" "^0.10.2" - gcp-metadata "^3.5.0" - -"@opentelemetry/tracing@^0.10.0": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/tracing/-/tracing-0.10.2.tgz#384779a6e1be988200cc316a97030d95bd8f2129" - integrity sha512-mNAhARn4dEdOjTa9OdysjI4fRHMbvr4YSbPuH7jhkyPzgoa+DnvnbY3GGpEay6kpuYJsrW8Ef9OIKAV/GndhbQ== - dependencies: - "@opentelemetry/api" "^0.10.2" - "@opentelemetry/context-base" "^0.10.2" - "@opentelemetry/core" "^0.10.2" - "@opentelemetry/resources" "^0.10.2" - -"@opentelemetry/types@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/types/-/types-0.2.0.tgz#2a0afd40fa7026e39ea56a454642bda72b172f80" - integrity sha512-GtwNB6BNDdsIPAYEdpp3JnOGO/3AJxjPvny53s3HERBdXSJTGQw8IRhiaTEX0b3w9P8+FwFZde4k+qkjn67aVw== +"@opentelemetry/semantic-conventions@^1.0.0": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.3.1.tgz#ba07b864a3c955f061aa30ea3ef7f4ae4449794a" + integrity sha512-wU5J8rUoo32oSef/rFpOT1HIjLjAv3qIDHkw1QIhODV3OpAVHi5oVzlouozg9obUmZKtbZ0qUe/m7FP0y0yBzA== "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": version "1.1.2" @@ -354,11 +296,6 @@ dependencies: defer-to-connect "^1.0.1" -"@types/async-lock@^1.1.0": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@types/async-lock/-/async-lock-1.1.2.tgz#cbc26a34b11b83b28f7783a843c393b443ef8bef" - integrity sha512-j9n4bb6RhgFIydBe0+kpjnBPYumDaDyU8zvbWykyVMkku+c2CSu31MZkLeaBfqIwU+XCxlDpYDfyMQRkM0AkeQ== - "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -396,20 +333,15 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-14.6.1.tgz#fdf6f6c6c73d3d8eee9c98a9a0485bc524b048d7" integrity sha512-HnYlg/BRF8uC1FyKRFZwRaCPTPYKa+6I8QiUZFLredaGOou481cgFS4wKRFyKvQtX8xudqkSdBczJHIYSQYKrQ== -"@types/node@^12.12.47": - version "12.12.54" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.54.tgz#a4b58d8df3a4677b6c08bfbc94b7ad7a7a5f82d1" - integrity sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w== - -"@types/node@^13.7.0": - version "13.13.15" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.15.tgz#fe1cc3aa465a3ea6858b793fd380b66c39919766" - integrity sha512-kwbcs0jySLxzLsa2nWUAGOd/s21WU1jebrEdtzhsj1D4Yps1EOuyI1Qcu+FD56dL7NRNIJtDDjcqIG22NwkgLw== +"@types/node@>=12.12.47", "@types/node@>=13.7.0": + version "17.0.42" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.42.tgz#d7e8f22700efc94d125103075c074396b5f41f9b" + integrity sha512-Q5BPGyGKcvQgAMbsr7qEGN/kIPN6zZecYYABeTDBizOsau+2NMdSVTar9UQw21A2+JyA2KRNDYaYrPB0Rpk2oQ== -"@types/tunnel@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.1.tgz#0d72774768b73df26f25df9184273a42da72b19c" - integrity sha512-AOqu6bQu5MSWwYvehMXLukFHnupHrpZ8nvgae5Ggie9UwzDR1CCwoXgSSWNZJuyOlCdfdsWMA5F2LlmvyoTv8A== +"@types/tunnel@^0.0.3": + version "0.0.3" + resolved "https://registry.yarnpkg.com/@types/tunnel/-/tunnel-0.0.3.tgz#f109e730b072b3136347561fc558c9358bb8c6e9" + integrity sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA== dependencies: "@types/node" "*" @@ -425,13 +357,13 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -accepts@~1.3.7: - version "1.3.7" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" - integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== dependencies: - mime-types "~2.1.24" - negotiator "0.6.2" + mime-types "~2.1.34" + negotiator "0.6.3" agent-base@6: version "6.0.1" @@ -440,27 +372,15 @@ agent-base@6: dependencies: debug "4" -ajv@^6.12.3: - version "6.12.4" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.4.tgz#0614facc4522127fa713445c6bfd3ebd376e2234" - integrity sha512-eienB2c9qVQs2KWexhkrdMLVDoIQCz5KSeLxwg9Lzk4DOfBtIK9PQwwufcsn1jjGuf9WZmqPMbGxOzfcuphJCQ== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -amqplib@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/amqplib/-/amqplib-0.6.0.tgz#87857c7c95d56d22438ced4cf1f7e5f0dc43b309" - integrity sha512-zXCh4jQ77TBZe1YtvZ1n7sUxnTjnNagpy8MVi2yc1ive239pS3iLwm4e4d5o4XZGx1BdTKQ/U0ZmaDU3c8MxYQ== +amqplib@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/amqplib/-/amqplib-0.10.0.tgz#766d696f8ceae097ee9eb73e6796999e5d40a1db" + integrity sha512-UueEnRGY6upiSvGsSYM22Woa1SeSukqYtqgYW4Gj8gHvbf5BRhhYRqf3kQ8aSUYYffTOZi6SeOVW2eOXt0hpPA== dependencies: bitsyntax "~0.1.0" - bluebird "^3.5.2" buffer-more-ints "~1.0.0" readable-stream "1.x >=1.1.9" - safe-buffer "~5.1.2" - url-parse "~1.4.3" + url-parse "~1.5.10" ansi-align@^3.0.0: version "3.0.0" @@ -469,25 +389,10 @@ ansi-align@^3.0.0: dependencies: string-width "^3.0.0" -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= - -ansi-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" - integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= - -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - -ansi-regex@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" - integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-regex@^2.0.0, ansi-regex@^3.0.0, ansi-regex@^4.1.0, ansi-regex@^5.0.0, ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.2.1" @@ -497,10 +402,10 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: "@types/color-name" "^1.1.1" color-convert "^2.0.1" -anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== +anymatch@~3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -518,12 +423,10 @@ are-we-there-yet@~1.1.2: delegates "^1.0.0" readable-stream "^2.0.6" -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== array-flatten@1.1.1: version "1.1.1" @@ -540,27 +443,10 @@ arrify@^2.0.0: resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== -asn1@~0.2.3: - version "0.2.4" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" - integrity sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= - -async-lock@^1.1.3: - version "1.2.4" - resolved "https://registry.yarnpkg.com/async-lock/-/async-lock-1.2.4.tgz#80d0d612383045dd0c30eb5aad08510c1397cb91" - integrity sha512-UBQJC2pbeyGutIfYmErGc9RaJYnpZ1FHaxuKwb0ahvGiiCkPUf3p67Io+YLPmmv3RHY+mF6JEtNW8FlHsraAaA== - -async@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" - integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw== +async@^3.2.3: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== asynckit@^0.4.0: version "0.4.0" @@ -572,57 +458,26 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -aws-sdk@^2.741.0: - version "2.741.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.741.0.tgz#b832d838e5f1ef9cdb2b4901ade4555b1ca4c085" - integrity sha512-bpk5VvlBSvKu3Lg30AxX+PHk+0TD69K3tYe6D6VeEFl/3XzuZ5RKTGCIl96isSMyYc5bBMhLS9pC9glrxT7OTw== +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + +aws-sdk@^2.1152.0: + version "2.1152.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.1152.0.tgz#73e4fb81b3a9c289234b5d6848bcdb854f169bdf" + integrity sha512-Lqwk0bDhm3vzpYb3AAM9VgGHeDpbB8+o7UJnP9R+CO23kJfi/XRpKihAcbyKDD/AUQ+O1LJaUVpvaJYLS9Am7w== dependencies: buffer "4.9.2" events "1.1.1" ieee754 "1.1.13" - jmespath "0.15.0" + jmespath "0.16.0" querystring "0.2.0" sax "1.2.1" url "0.10.3" - uuid "3.3.2" + uuid "8.0.0" xml2js "0.4.19" -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg= - -aws4@^1.8.0: - version "1.10.1" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.1.tgz#e1e82e4f3e999e2cfd61b161280d16a111f86428" - integrity sha512-zg7Hz2k5lI8kb7U32998pRRFin7zJlkfezGJjUc2heaD4Pw2wObakCDVzkKztTm/Ln7eiVvYsjqak0Ed4LkMDA== - -azure-common@^0.9.22: - version "0.9.25" - resolved "https://registry.yarnpkg.com/azure-common/-/azure-common-0.9.25.tgz#fc7cfb08c65398b3c90f9b9bc14a99e204319b9a" - integrity sha512-L7YO3DUQ0iwiaUyD9Wy6B66Y6HmCzMb9vxUqKklgzU+gFRRBKIMSVR4oZS6IkQfFCSm9eKwHuH2p3UdDPszd7g== - dependencies: - dateformat "1.0.2-1.2.3" - duplexer "~0.1.1" - envconf "~0.0.4" - request "^2.81.0" - through "~2.3.4" - tunnel "~0.0.2" - underscore "1.4.x" - validator "^9.4.1" - xml2js "^0.4.19" - xmlbuilder "15.1.1" - -azure-sb@^0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/azure-sb/-/azure-sb-0.11.1.tgz#15cba11c1a3b4aca68c344460b99bceec14be11a" - integrity sha512-ZYgPeSDMD99i/Em+6wT78zvBkJ/dbh2ypb4DbqQ1Flaif5vWJFzC/iKxxcq/vq+THWoO3+UbqWa0JNXnW3zAvw== - dependencies: - azure-common "^0.9.22" - mpns "2.1.3" - underscore "^1.8.3" - wns "~0.5.3" - balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -638,13 +493,6 @@ base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4= - dependencies: - tweetnacl "^0.14.3" - bignumber.js@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" @@ -673,40 +521,37 @@ bl@^4.0.3: inherits "^2.0.4" readable-stream "^3.4.0" -bluebird@^3.5.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== dependencies: - bytes "3.1.0" + bytes "3.1.2" content-type "~1.0.4" debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" -boxen@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" - integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== +boxen@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== dependencies: ansi-align "^3.0.0" - camelcase "^5.3.1" - chalk "^3.0.0" - cli-boxes "^2.2.0" - string-width "^4.1.0" - term-size "^2.1.0" - type-fest "^0.8.1" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" widest-line "^3.1.0" + wrap-ansi "^7.0.0" brace-expansion@^1.1.7: version "1.1.11" @@ -716,7 +561,7 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" -braces@^3.0.1, braces@~3.0.2: +braces@^3.0.2, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -742,14 +587,6 @@ buffer@4.9.2: ieee754 "^1.1.4" isarray "^1.0.0" -buffer@^5.2.1: - version "5.6.0" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.6.0.tgz#a31749dc7d81d84db08abf937b6b8c4033f62786" - integrity sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - buffer@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" @@ -758,10 +595,18 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +buffer@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== cacheable-request@^6.0.0: version "6.1.0" @@ -776,25 +621,20 @@ cacheable-request@^6.0.0: normalize-url "^4.1.0" responselike "^1.0.2" -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= - -chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== +call-bind@^1.0.0, call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -chalk@^4.1.0: +chalk@^4.1.0, chalk@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -802,20 +642,20 @@ chalk@^4.1.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chokidar@^3.2.2: - version "3.4.2" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" - integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== +chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== dependencies: - anymatch "~3.1.1" + anymatch "~3.1.2" braces "~3.0.2" - glob-parent "~5.1.0" + glob-parent "~5.1.2" is-binary-path "~2.1.0" is-glob "~4.0.1" normalize-path "~3.0.0" - readdirp "~3.4.0" + readdirp "~3.6.0" optionalDependencies: - fsevents "~2.1.2" + fsevents "~2.3.2" chownr@^1.1.1: version "1.1.4" @@ -827,19 +667,10 @@ ci-info@^2.0.0: resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== -cli-boxes@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.0.tgz#538ecae8f9c6ca508e3c3c95b453fe93cb4c168d" - integrity sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w== - -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== cliui@^7.0.2: version "7.0.4" @@ -886,10 +717,10 @@ color-name@^1.0.0, color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.5.2: - version "1.5.3" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" - integrity sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw== +color-string@^1.5.2, color-string@^1.5.5: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== dependencies: color-name "^1.0.0" simple-swizzle "^0.2.2" @@ -902,11 +733,6 @@ color@3.0.x: color-convert "^1.9.1" color-string "^1.5.2" -colors@^1.2.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - colorspace@1.1.x: version "1.1.2" resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" @@ -915,7 +741,7 @@ colorspace@1.1.x: color "3.0.x" text-hex "1.0.x" -combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: +combined-stream@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== @@ -927,10 +753,10 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= -config@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/config/-/config-3.3.1.tgz#b6a70e2908a43b98ed20be7e367edf0cc8ed5a19" - integrity sha512-+2/KaaaAzdwUBE3jgZON11L1ggLLhpf2FsGrfqYFHZW22ySGv/HqYIXrBwKKvn+XZh1UBUjHwAcrfsSkSygT+Q== +config@^3.3.7: + version "3.3.7" + resolved "https://registry.yarnpkg.com/config/-/config-3.3.7.tgz#4310410dc2bf4e0effdca21a12a4035860a24ee4" + integrity sha512-mX/n7GKDYZMqvvkY6e6oBY49W8wxdmQt+ho/5lhwFDXqQW9gI+Ahp8EKp8VAbISPnmf2+Bv5uZK7lKXZ6pf1aA== dependencies: json5 "^2.1.1" @@ -951,12 +777,12 @@ console-control-strings@^1.0.0, console-control-strings@~1.1.0: resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: - safe-buffer "5.1.2" + safe-buffer "5.2.1" content-type@~1.0.4: version "1.0.4" @@ -968,12 +794,12 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -core-util-is@1.0.2, core-util-is@~1.0.0: +core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= @@ -983,26 +809,14 @@ crypto-random-string@^2.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5" integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA== -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA= - dependencies: - assert-plus "^1.0.0" - -dateformat@1.0.2-1.2.3: - version "1.0.2-1.2.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.2-1.2.3.tgz#b0220c02de98617433b72851cf47de3df2cdbee9" - integrity sha1-sCIMAt6YYXQztyhRz0fePfLNvuk= - -"debug@0.8.0 - 3.5.0", debug@^3.1.0, debug@^3.2.6: +"debug@0.8.0 - 3.5.0", debug@^3.1.0: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== dependencies: ms "^2.1.1" -debug@2.6.9, debug@^2.2.0, debug@~2.6.9: +debug@2.6.9, debug@~2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== @@ -1016,10 +830,12 @@ debug@4, debug@^4.1.1: dependencies: ms "^2.1.1" -decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" decompress-response@^3.3.0: version "3.3.0" @@ -1050,6 +866,14 @@ defer-to-connect@^1.0.1: resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-1.1.3.tgz#331ae050c08dcf789f8c83a7b81f0ed94f4ac591" integrity sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ== +define-properties@^1.1.3, define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -1060,15 +884,15 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= +depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== detect-libc@^1.0.3: version "1.0.3" @@ -1094,29 +918,16 @@ duplexer3@^0.1.4: resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI= -duplexer@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - -duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== +duplexify@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" + integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" stream-shift "^1.0.0" -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha1-OoOpBOVDUyh4dMVkt1SThoSamMk= - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - ecdsa-sig-formatter@1.0.11, ecdsa-sig-formatter@^1.0.11: version "1.0.11" resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" @@ -1149,17 +960,50 @@ encodeurl@~1.0.2: resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: +end-of-stream@^1.1.0, end-of-stream@^1.4.1: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -envconf@~0.0.4: - version "0.0.4" - resolved "https://registry.yarnpkg.com/envconf/-/envconf-0.0.4.tgz#85675afba237c43f98de2d46adc0e532a4dcf48b" - integrity sha1-hWda+6I3xD+Y3i1GrcDlMqTc9Is= +es-abstract@^1.19.0, es-abstract@^1.19.5, es-abstract@^1.20.0: + version "1.20.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" + integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + regexp.prototype.flags "^1.4.3" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" escalade@^3.1.1: version "3.1.1" @@ -1188,7 +1032,7 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -esprima@^4.0.0, esprima@^4.0.1: +esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== @@ -1228,90 +1072,65 @@ expand-template@^2.0.3: resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== -express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== +express@^4.18.1: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== dependencies: - accepts "~1.3.7" + accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" + body-parser "1.20.0" + content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.4.0" + cookie "0.5.0" cookie-signature "1.0.6" debug "2.6.9" - depd "~1.1.2" + depd "2.0.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "~1.1.2" + finalhandler "1.2.0" fresh "0.5.2" + http-errors "2.0.0" merge-descriptors "1.0.1" methods "~1.1.2" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" + proxy-addr "~2.0.7" + qs "6.10.3" range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" -extend@^3.0.2, extend@~3.0.2: +extend@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha1-lpGEQOMEGnpBT4xS48V06zw+HgU= - -extsprintf@^1.2.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" - integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= - -fast-deep-equal@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.1.1: - version "3.2.4" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.4.tgz#d20aefbf99579383e7f3cc66529158c9b98554d3" - integrity sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ== +fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" + glob-parent "^5.1.2" merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + micromatch "^4.0.4" fast-levenshtein@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= -fast-safe-stringify@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" - integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== - -fast-text-encoding@^1.0.0: +fast-text-encoding@^1.0.0, fast-text-encoding@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/fast-text-encoding/-/fast-text-encoding-1.0.3.tgz#ec02ac8e01ab8a319af182dae2681213cfe9ce53" integrity sha512-dtm4QZH9nZtcDt8qJiOH9fcQd1NAgi+K1O2DbE6GG1PPCK/BWfOH3idCTRQ4ImXRUOyopDEgDEnVEE7Y/2Wrig== @@ -1328,12 +1147,12 @@ fecha@^4.2.0: resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.0.tgz#3ffb6395453e3f3efff850404f0a59b6747f5f41" integrity sha512-aN3pcx/DSmtyoovUudctc8+6Hl4T+hI9GBBHLjA76jdZl7+b1sgh5g4k+u/GL3dTy1/pnYzKp69FpJ0OicE3Wg== -file-stream-rotator@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-0.5.7.tgz#868a2e5966f7640a17dd86eda0e4467c089f6286" - integrity sha512-VYb3HZ/GiAGUCrfeakO8Mp54YGswNUHvL7P09WQcXAJNSj3iQ5QraYSp3cIn1MUyw6uzfgN/EFOarCNa4JvUHQ== +file-stream-rotator@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/file-stream-rotator/-/file-stream-rotator-0.6.1.tgz#007019e735b262bb6c6f0197e58e5c87cb96cec3" + integrity sha512-u+dBid4PvZw17PmDeRcNOtCP9CCK/9lRN2w+r1xIS7yOL9JFrIBKTvrYsxT4P0pGtThYTn++QS5ChHaUov3+zQ== dependencies: - moment "^2.11.2" + moment "^2.29.1" fill-range@^7.0.1: version "7.0.1" @@ -1342,36 +1161,30 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" - integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== dependencies: debug "2.6.9" encodeurl "~1.0.2" escape-html "~1.0.3" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" - statuses "~1.5.0" + statuses "2.0.1" unpipe "~1.0.0" -find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - fn.name@1.x.x: version "1.1.0" resolved "https://registry.yarnpkg.com/fn.name/-/fn.name-1.1.0.tgz#26cad8017967aea8731bc42961d04a3d5988accc" integrity sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw== -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" form-data@^3.0.0: version "3.0.0" @@ -1382,13 +1195,13 @@ form-data@^3.0.0: combined-stream "^1.0.8" mime-types "^2.1.12" -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== dependencies: asynckit "^0.4.0" - combined-stream "^1.0.6" + combined-stream "^1.0.8" mime-types "^2.1.12" forwarded@0.2.0: @@ -1414,10 +1227,10 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1" - integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ== +fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== dependencies: graceful-fs "^4.2.0" jsonfile "^6.0.1" @@ -1433,16 +1246,31 @@ fs-extra@^9.1.0: jsonfile "^6.0.1" universalify "^2.0.0" -fsevents@~2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + gauge@~2.7.3: version "2.7.4" resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" @@ -1457,49 +1285,50 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -gaxios@^2.1.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-2.3.4.tgz#eea99353f341c270c5f3c29fc46b8ead56f0a173" - integrity sha512-US8UMj8C5pRnao3Zykc4AAVr+cffoNKRTg9Rsf2GiuZCW69vgJj38VK2PzlPuQU73FZ/nTk9/Av6/JGcE1N9vA== +gaxios@^4.0.0: + version "4.3.3" + resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-4.3.3.tgz#d44bdefe52d34b6435cc41214fdb160b64abfc22" + integrity sha512-gSaYYIO1Y3wUtdfHmjDUZ8LWaxJQpiavzbF5Kq53akSzvmVg0RfyOcFDbO1KJ/KCGRFz2qG+lS81F0nkr7cRJA== dependencies: abort-controller "^3.0.0" extend "^3.0.2" https-proxy-agent "^5.0.0" is-stream "^2.0.0" - node-fetch "^2.3.0" + node-fetch "^2.6.7" -gaxios@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-3.1.0.tgz#95f65f5a335f61aff602fe124cfdba8524f765fa" - integrity sha512-DDTn3KXVJJigtz+g0J3vhcfbDbKtAroSTxauWsdnP57sM5KZ3d2c/3D9RKFJ86s43hfw6WULg6TXYw/AYiBlpA== +gaxios@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gaxios/-/gaxios-5.0.0.tgz#df11e5d0a45831dd39eb5fbbba0d6a6b09815e70" + integrity sha512-VD/yc5ln6XU8Ch1hyYY6kRMBE0Yc2np3fPyeJeYHhrPs1i8rgnsApPMWyrugkl7LLoSqpOJVBWlQIa87OAvt8Q== dependencies: abort-controller "^3.0.0" extend "^3.0.2" https-proxy-agent "^5.0.0" is-stream "^2.0.0" - node-fetch "^2.3.0" + node-fetch "^2.6.7" -gcp-metadata@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-3.5.0.tgz#6d28343f65a6bbf8449886a0c0e4a71c77577055" - integrity sha512-ZQf+DLZ5aKcRpLzYUyBS3yo3N0JSa82lNDO8rj3nMSlovLcz2riKFBsYgDzeXcv75oo5eqB2lx+B14UvPoCRnA== - dependencies: - gaxios "^2.1.0" - json-bigint "^0.3.0" - -gcp-metadata@^4.1.0: - version "4.1.4" - resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-4.1.4.tgz#3adadb9158c716c325849ee893741721a3c09e7e" - integrity sha512-5J/GIH0yWt/56R3dNaNWPGQ/zXsZOddYECfJaqxFWgrZ9HC2Kvc5vl9upOgUUHKzURjAVf2N+f6tEJiojqXUuA== +gcp-metadata@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gcp-metadata/-/gcp-metadata-5.0.0.tgz#a00f999f60a4461401e7c515f8a3267cfb401ee7" + integrity sha512-gfwuX3yA3nNsHSWUL4KG90UulNiq922Ukj3wLTrcnX33BB7PwB1o0ubR8KVvXu9nJH+P5w1j2SQSNNqto+H0DA== dependencies: - gaxios "^3.0.0" + gaxios "^5.0.0" json-bigint "^1.0.0" -get-caller-file@^2.0.1, get-caller-file@^2.0.5: +get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -1514,85 +1343,85 @@ get-stream@^5.1.0: dependencies: pump "^3.0.0" -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo= +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== dependencies: - assert-plus "^1.0.0" + call-bind "^1.0.2" + get-intrinsic "^1.1.1" github-from-package@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" integrity sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4= -glob-parent@^5.1.0, glob-parent@~5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" - integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== dependencies: is-glob "^4.0.1" -global-dirs@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.0.1.tgz#acdf3bb6685bcd55cb35e8a052266569e9469201" - integrity sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A== +global-dirs@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-3.0.0.tgz#70a76fe84ea315ab37b1f5576cbde7d48ef72686" + integrity sha512-v8ho2DS5RiCjftj1nD9NmnfaOzTdud7RRnVd9kFNOjqZbISlx5DQ+OrTkywgd0dIt7oFCvKetZSHoHcP3sDdiA== dependencies: - ini "^1.3.5" + ini "2.0.0" -globby@^11.0.3: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" slash "^3.0.0" -google-auth-library@^6.0.0: - version "6.0.6" - resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-6.0.6.tgz#5102e5c643baab45b4c16e9752cd56b8861f3a82" - integrity sha512-fWYdRdg55HSJoRq9k568jJA1lrhg9i2xgfhVIMJbskUmbDpJGHsbv9l41DGhCDXM21F9Kn4kUwdysgxSYBYJUw== +google-auth-library@^8.0.2: + version "8.0.2" + resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-8.0.2.tgz#5fa0f2d3795c3e4019d2bb315ade4454cc9c30b5" + integrity sha512-HoG+nWFAThLovKpvcbYzxgn+nBJPTfAwtq0GxPN821nOO+21+8oP7MoEHfd1sbDulUFFGfcjJr2CnJ4YssHcyg== dependencies: arrify "^2.0.0" base64-js "^1.3.0" ecdsa-sig-formatter "^1.0.11" fast-text-encoding "^1.0.0" - gaxios "^3.0.0" - gcp-metadata "^4.1.0" - gtoken "^5.0.0" + gaxios "^5.0.0" + gcp-metadata "^5.0.0" + gtoken "^5.3.2" jws "^4.0.0" lru-cache "^6.0.0" -google-gax@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-2.7.0.tgz#5aaff7bdbe32730f975f416dd4897c558c89ab84" - integrity sha512-0dBATy8mMVlfOBrT85Q+NzBpZ4OJZUMrPI9wJULpiIDq2w1zlN30Duor+fQUcMEjanYEc72G58M4iUVve0jfXw== +google-gax@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/google-gax/-/google-gax-3.1.0.tgz#a6fea06bfd0157969ddc0a6d04c47980978ead02" + integrity sha512-OHKVHZtaYHwxrjiI4BH+IzRWH2Q75sZg+q0/RatxLicbeeCCIug99+NKQiE39B5rLnGENtcbUjmXiqJHbSrkSg== dependencies: - "@grpc/grpc-js" "~1.1.1" - "@grpc/proto-loader" "^0.5.1" + "@grpc/grpc-js" "~1.6.0" + "@grpc/proto-loader" "^0.6.12" "@types/long" "^4.0.0" abort-controller "^3.0.0" - duplexify "^3.6.0" - google-auth-library "^6.0.0" + duplexify "^4.0.0" + fast-text-encoding "^1.0.3" + google-auth-library "^8.0.2" is-stream-ended "^0.1.4" - lodash.at "^4.6.0" - lodash.has "^4.5.2" - node-fetch "^2.6.0" - protobufjs "^6.9.0" - retry-request "^4.0.0" - semver "^6.0.0" - walkdir "^0.4.0" + node-fetch "^2.6.1" + object-hash "^3.0.0" + proto3-json-serializer "^1.0.0" + protobufjs "6.11.3" + retry-request "^5.0.0" -google-p12-pem@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-3.0.2.tgz#12d443994b6f4cd8c9e4ac479f2f18d4694cbdb8" - integrity sha512-tbjzndQvSIHGBLzHnhDs3cL4RBjLbLXc2pYvGH+imGVu5b4RMAttUTdnmW2UH0t11QeBTXZ7wlXPS7hrypO/tg== +google-p12-pem@^3.1.3: + version "3.1.4" + resolved "https://registry.yarnpkg.com/google-p12-pem/-/google-p12-pem-3.1.4.tgz#123f7b40da204de4ed1fbf2fd5be12c047fc8b3b" + integrity sha512-HHuHmkLgwjdmVRngf5+gSmpkyaRI6QmOg77J8tkNBHhNEI62sGHyw4/+UkgyZEI7h84NbWprXDJ+sa3xOYFvTg== dependencies: - node-forge "^0.9.0" + node-forge "^1.3.1" got@^9.6.0: version "9.6.0" @@ -1616,28 +1445,19 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -gtoken@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.0.3.tgz#b76ef8e9a2fed6fef165e47f7d05b60c498e4d05" - integrity sha512-Nyd1wZCMRc2dj/mAD0LlfQLcAO06uKdpKJXvK85SGrF5+5+Bpfil9u/2aw35ltvEHjvl0h5FMKN5knEU+9JrOg== +gtoken@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/gtoken/-/gtoken-5.3.2.tgz#deb7dc876abe002178e0515e383382ea9446d58f" + integrity sha512-gkvEKREW7dXWF8NV8pVrKfW7WqReAmjjkMBh6lNCCGOM4ucS0r0YyXXl0r/9Yj8wcW/32ISkfc8h5mPTDbtifQ== dependencies: - gaxios "^3.0.0" - google-p12-pem "^3.0.0" + gaxios "^4.0.0" + google-p12-pem "^3.1.3" jws "^4.0.0" - mime "^2.2.0" -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI= - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== has-flag@^3.0.0: version "3.0.0" @@ -1649,6 +1469,25 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -1671,36 +1510,16 @@ http-cache-semantics@^4.0.0: resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ== -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== dependencies: - depd "~1.1.2" + depd "2.0.0" inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha1-muzZJRFHcvPZW2WmCruPfBj7rOE= - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" https-proxy-agent@^5.0.0: version "5.0.0" @@ -1722,7 +1541,7 @@ ieee754@1.1.13, ieee754@^1.1.4: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -1732,10 +1551,10 @@ ignore-by-default@^1.0.1: resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha1-SMptcvbGo68Aqa1K5odr44ieKwk= -ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== import-lazy@^2.1.0: version "2.1.0" @@ -1747,21 +1566,30 @@ imurmurhash@^0.1.4: resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= - inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== -ini@^1.3.5, ini@~1.3.0: +ini@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" + integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== + +ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== + dependencies: + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + into-stream@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-6.0.0.tgz#4bfc1244c0128224e18b8870e85b2de8e66c6702" @@ -1775,11 +1603,26 @@ ipaddr.js@1.9.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-arrayish@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -1787,11 +1630,24 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-buffer@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== +is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + is-ci@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" @@ -1799,13 +1655,20 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.2.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.6.0.tgz#d7553b2526fe59b92ba3e40c8df757ec8a709e19" - integrity sha512-wShG8vs60jKfPWpF2KZRaAtvt3a20OAn7+IJ6hLPECpSABLcKtFKTTI4ZtH5QcBruBHlq+WsdHWyz0BCZW7svQ== +is-core-module@2.9.0, is-core-module@^2.8.1: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== dependencies: has "^1.0.3" +is-date-object@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -1828,6 +1691,13 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" @@ -1835,18 +1705,30 @@ is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" -is-installed-globally@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" - integrity sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g== +is-installed-globally@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.4.0.tgz#9a0fd407949c30f86eb6959ef1b7994ed0b7b520" + integrity sha512-iwGqO3J21aaSkC7jWnHP/difazwS7SFeIqxv6wEtLU8Y5KlzFTjyqcSIT0d8s4+dDhKytsk9PJZ2BkS5eZwQRQ== dependencies: - global-dirs "^2.0.1" - is-path-inside "^3.0.1" + global-dirs "^3.0.0" + is-path-inside "^3.0.2" -is-npm@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-4.0.0.tgz#c90dd8380696df87a7a6d823c20d0b12bbe3c84d" - integrity sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig== +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-npm@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-5.0.0.tgz#43e8d65cc56e1b67f8d47262cf667099193f45a8" + integrity sha512-WW/rQLOazUq+ST/bCAVBp/2oMERWLsR7OrKyt052dNDk4DHcDE0/7QSXITlmi+VBcV13DfIbysG3tZJm5RfdBA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" is-number@^7.0.0: version "7.0.0" @@ -1858,10 +1740,25 @@ is-obj@^2.0.0: resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== -is-path-inside@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" - integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== +is-path-inside@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" is-stream-ended@^0.1.4: version "0.1.4" @@ -1873,11 +1770,43 @@ is-stream@^2.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== -is-typedarray@^1.0.0, is-typedarray@~1.0.0: +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typed-array@^1.1.3, is-typed-array@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.9.tgz#246d77d2871e7d9f5aeb1d54b9f52c71329ece67" + integrity sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.20.0" + for-each "^0.3.3" + has-tostringtag "^1.0.0" + +is-typedarray@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + is-yarn-global@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/is-yarn-global/-/is-yarn-global-0.3.0.tgz#d502d3382590ea3004893746754c89139973e232" @@ -1893,35 +1822,17 @@ isarray@^1.0.0, isarray@~1.0.0: resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= - -jmespath@0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" - integrity sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc= - -js-yaml@^3.14.0: - version "3.14.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" - integrity sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha1-peZUwuWi3rXyAdls77yoDA7y9RM= +jmespath@0.16.0: + version "0.16.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.16.0.tgz#b15b0a85dfd4d930d43e69ed605943c802785076" + integrity sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw== -json-bigint@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-bigint/-/json-bigint-0.3.1.tgz#0c1729d679f580d550899d6a2226c228564afe60" - integrity sha512-DGWnSzmusIreWlEupsUelHrhwmPPE+FiQvg+drKfk2p+bdEYa5mp4PJ8JsCWqae0M2jQNb0HPvnwvf1qOTThzQ== +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== dependencies: - bignumber.js "^9.0.0" + argparse "^2.0.1" json-bigint@^1.0.0: version "1.0.0" @@ -1935,21 +1846,6 @@ json-buffer@3.0.0: resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" integrity sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg= -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema@0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" - integrity sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM= - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= - json5@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" @@ -1966,20 +1862,10 @@ jsonfile@^6.0.1: optionalDependencies: graceful-fs "^4.1.6" -jsprim@^1.2.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" - integrity sha1-MT5mvB5cwG5Di8G3SZwuXFastqI= - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.2.3" - verror "1.10.0" - -jssha@^2.3.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/jssha/-/jssha-2.4.2.tgz#d950b095634928bd6b2bda1d42da9a3a762d65e9" - integrity sha512-/jsi/9C0S70zfkT/4UlKQa5E1xKurDnXcQizcww9JSR/Fv+uIbWM2btG+bFcL3iNoK9jIGS0ls9HWLr1iw0kFg== +jssha@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jssha/-/jssha-3.2.0.tgz#88ec50b866dd1411deaddbe6b3e3692e4c710f16" + integrity sha512-QuruyBENDWdN4tZwJbQq7/eAK85FqrI4oDbXjy5IBhYD+2pTJyBUWZe8ctWaCkrV0gy6AaelgOZZBMeswEa/6Q== jwa@^2.0.0: version "2.0.0" @@ -1998,10 +1884,10 @@ jws@^4.0.0: jwa "^2.0.0" safe-buffer "^5.0.1" -kafkajs@^1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/kafkajs/-/kafkajs-1.15.0.tgz#a5ada0d933edca2149177393562be6fb0875ec3a" - integrity sha512-yjPyEnQCkPxAuQLIJnY5dI+xnmmgXmhuOQ1GVxClG5KTOV/rJcW1qA3UfvyEJKTp/RTSqQnUR3HJsKFvHyTpNg== +kafkajs@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/kafkajs/-/kafkajs-2.0.2.tgz#cdfc8f57aa4fd69f6d9ca1cce4ee89bbc2a3a1f9" + integrity sha512-g6CM3fAenofOjR1bfOAqeZUEaSGhNtBscNokybSdW1rmIKYNwBPC9xQzwulFJm36u/xcxXUiCl/L/qfslapihA== keyv@^3.0.0: version "3.1.0" @@ -2015,7 +1901,7 @@ kuler@^2.0.0: resolved "https://registry.yarnpkg.com/kuler/-/kuler-2.0.0.tgz#e2c570a3800388fb44407e851531c1d670b061b3" integrity sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A== -latest-version@^5.0.0: +latest-version@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-5.1.0.tgz#119dfe908fe38d15dfa43ecd13fa12ec8832face" integrity sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA== @@ -2030,47 +1916,25 @@ levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -lodash.at@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.at/-/lodash.at-4.6.0.tgz#93cdce664f0a1994ea33dd7cd40e23afd11b0ff8" - integrity sha1-k83OZk8KGZTqM9181A4jr9EbD/g= - lodash.camelcase@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= -lodash.has@^4.5.2: - version "4.5.2" - resolved "https://registry.yarnpkg.com/lodash.has/-/lodash.has-4.5.2.tgz#d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862" - integrity sha1-0Z9NwQlQWMzL4rDN9O4P5Ko3yGI= - lodash.snakecase@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= -lodash@^4.17.19: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -logform@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/logform/-/logform-2.2.0.tgz#40f036d19161fc76b68ab50fdc7fe495544492f2" - integrity sha512-N0qPlqfypFx7UHNn4B3lzS/b0uLqt2hmuoa+PpuXNYgozdJYAyauF5Ky0BWVjrxDlMWiT3qN4zPq3vVAfZy7Yg== +logform@^2.3.2, logform@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/logform/-/logform-2.4.0.tgz#131651715a17d50f09c2a2c1a524ff1a4164bcfe" + integrity sha512-CPSJw4ftjf517EhXZGGvTHHkYobo7ZCc0kvwUoOYcjfR2UVrI66RHj8MCrfAdEitdmFqbu2BYdYs8FHHZSb6iw== dependencies: - colors "^1.2.1" - fast-safe-stringify "^2.0.4" + "@colors/colors" "1.5.0" fecha "^4.2.0" ms "^2.1.1" + safe-stable-stringify "^2.3.1" triple-beam "^1.3.0" long@^4.0.0: @@ -2078,6 +1942,11 @@ long@^4.0.0: resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== +long@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-5.2.0.tgz#2696dadf4b4da2ce3f6f6b89186085d94d52fd61" + integrity sha512-9RTUNjK60eJbx3uz+TEGF7fUr29ZDxR5QzXcyDpeSfeH28S9ycINflOgOlppit5U+4kNTe83KQnMEerw7GmE8w== + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -2112,7 +1981,7 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= -merge2@^1.3.0: +merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -2122,13 +1991,13 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -micromatch@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.2.tgz#4fcb0999bf9fbc2fcbdd212f6d629b9a56c39259" - integrity sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q== +micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== dependencies: - braces "^3.0.1" - picomatch "^2.0.5" + braces "^3.0.2" + picomatch "^2.3.1" mime-db@1.44.0: version "1.44.0" @@ -2140,7 +2009,12 @@ mime-db@1.48.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.48.0.tgz#e35b31045dd7eada3aaad537ed88a33afbef2d1d" integrity sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ== -mime-types@^2.1.12, mime-types@~2.1.19: +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== @@ -2154,16 +2028,18 @@ mime-types@~2.1.24: dependencies: mime-db "1.48.0" +mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mime@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== -mime@^2.2.0: - version "2.4.6" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.6.tgz#e5b407c90db442f2beb5b162373d07b69affa4d1" - integrity sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA== - mimic-response@^1.0.0, mimic-response@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" @@ -2181,35 +2057,30 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" -minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" - integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== -moment@^2.11.2: - version "2.27.0" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.27.0.tgz#8bff4e3e26a236220dfe3e36de756b6ebaa0105d" - integrity sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ== - -mpns@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/mpns/-/mpns-2.1.3.tgz#4328bb23ca79669e3383389074c898713e22ccb9" - integrity sha512-gPLNoVqwYoKUmNYZ2shMSdaE2XvHSRxWNzyG4DUi6Av7MSujyeOw/nj61nnQeuV/vke5E0Dni468xn0qxTHIZQ== +moment@^2.29.1: + version "2.29.3" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.3.tgz#edd47411c322413999f7a5940d526de183c031f3" + integrity sha512-c6YRvhEo//6T2Jz/vVtYzqBzwvPT95JBQ+smCytzf7c50oMZRsR/a4w88aD34I+/QVSfnoAnSBFPJHItlOMJVw== ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== ms@^2.1.1: version "2.1.2" @@ -2229,53 +2100,45 @@ napi-build-utils@^1.0.1: resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== -negotiator@0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" - integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== +negotiator@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== -node-abi@^2.7.0: +node-abi@^2.21.0: version "2.30.1" resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.1.tgz#c437d4b1fe0e285aaf290d45b45d4d7afedac4cf" integrity sha512-/2D0wOQPgaUWzVSVgRMx+trKJRC2UG4SUc4oCJoXx9Uxjtp0Vy3/kt7zcbxHF8+Z/pK3UloLWzBISg72brfy1w== dependencies: semver "^5.4.1" -node-fetch@^2.3.0, node-fetch@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" - integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== - -node-fetch@^2.6.1: - version "2.6.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.2.tgz#986996818b73785e47b1965cc34eb093a1d464d0" - integrity sha512-aLoxToI6RfZ+0NOjmWAgn9+LEd30YCkJKFSyWacNZdEKTit/ZMcKjGkTRo8uWEsnIb/hfKecNPEbln02PdWbcA== +node-fetch@^2.6.1, node-fetch@^2.6.6, node-fetch@^2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" -node-forge@^0.9.0: - version "0.9.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.1.tgz#775368e6846558ab6676858a4d8c6e8d16c677b5" - integrity sha512-G6RlQt5Sb4GMBzXvhfkeFmbqR6MzhtnT7VTHuLadjkii3rdYHNdw0m8zA4BTxVIh68FicCQ2NSUANpsqkr9jvQ== +node-forge@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== -nodemon@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.12.tgz#5dae4e162b617b91f1873b3bfea215dd71e144d5" - integrity sha512-egCTmNZdObdBxUBw6ZNwvZ/xzk24CKRs5K6d+5zbmrMr7rOpPmfPeF6OxM3DDpaRx331CQRFEktn+wrFFfBSOA== +nodemon@^2.0.16: + version "2.0.16" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.16.tgz#d71b31bfdb226c25de34afea53486c8ef225fdef" + integrity sha512-zsrcaOfTWRuUzBn3P44RDliLlp263Z/76FPoHFr3cFFkOz0lTPAcIw8dCzfdVIx/t3AtDYCZRCDkoCojJqaG3w== dependencies: - chokidar "^3.2.2" - debug "^3.2.6" + chokidar "^3.5.2" + debug "^3.2.7" ignore-by-default "^1.0.1" minimatch "^3.0.4" - pstree.remy "^1.1.7" + pstree.remy "^1.1.8" semver "^5.7.1" supports-color "^5.5.0" touch "^3.1.0" - undefsafe "^2.0.3" - update-notifier "^4.1.0" - -noop-logger@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/noop-logger/-/noop-logger-0.1.1.tgz#94a2b1633c4f1317553007d8966fd0e841b6a4c2" - integrity sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI= + undefsafe "^2.0.5" + update-notifier "^5.1.0" nopt@~1.0.10: version "1.0.10" @@ -2309,11 +2172,6 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - object-assign@^4.1.0: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -2324,10 +2182,35 @@ object-hash@^2.0.1: resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-2.0.3.tgz#d12db044e03cd2ca3d77c0570d87225b02e1e6ea" integrity sha512-JPKn0GMu+Fa3zt3Bmr66JhokJU5BaNBIh4ZeTlaCBzrBsOeXzwcKKAK1tbLiPKgvwmPXsDvvLHoWh5Bm7ofIYg== -on-finished@~2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + +object-inspect@^1.12.0, object-inspect@^1.9.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + +object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +object.assign@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" + integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== + dependencies: + call-bind "^1.0.0" + define-properties "^1.1.3" + has-symbols "^1.0.1" + object-keys "^1.1.1" + +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== dependencies: ee-first "1.1.1" @@ -2372,25 +2255,6 @@ p-is-promise@^3.0.0: resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-3.0.0.tgz#58e78c7dfe2e163cf2a04ff869e7c1dba64a5971" integrity sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ== -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - package-json@^6.3.0: version "6.5.0" resolved "https://registry.yarnpkg.com/package-json/-/package-json-6.5.0.tgz#6feedaca35e75725876d0b0e64974697fed145b0" @@ -2406,15 +2270,10 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-parse@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" - integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== path-to-regexp@0.1.7: version "0.1.7" @@ -2426,54 +2285,54 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= - -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== -pkg-fetch@3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/pkg-fetch/-/pkg-fetch-3.2.2.tgz#33f391eb176c1844e93189a32f2279b36a1ec949" - integrity sha512-bLhFNT4cNnONxzbHo1H2mCCKuQkCR4dgQtv0gUZnWtp8TDP0v0UAXKHG7DXhAoTC5IYP3slLsFJtIda9ksny8g== +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pkg-fetch@3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/pkg-fetch/-/pkg-fetch-3.4.1.tgz#be68bb9f7fdb0f6ed995abc518ab2e35aa64d2fd" + integrity sha512-fS4cdayCa1r4jHkOKGPJKnS9PEs6OWZst+s+m0+CmhmPZObMnxoRnf9T9yUWl+lzM2b5aJF7cnQIySCT7Hq8Dg== dependencies: - chalk "^4.1.0" + chalk "^4.1.2" fs-extra "^9.1.0" https-proxy-agent "^5.0.0" - node-fetch "^2.6.1" + node-fetch "^2.6.6" progress "^2.0.3" semver "^7.3.5" + tar-fs "^2.1.1" yargs "^16.2.0" -pkg@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/pkg/-/pkg-5.3.1.tgz#8f81671613b9e5bb1d83c39b2eed4799e1e679fe" - integrity sha512-jT/sptM1ZG++FNk+jnJYNoWLDQXYd7hqpnBhd5j18SNW1jJzNYo55RahuCiD0KN0PX9mb53GWCqKM0ia/mJytA== +pkg@^5.7.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/pkg/-/pkg-5.7.0.tgz#6422df05e8aa147764be6ef912921d0fa719ea95" + integrity sha512-PTiAjNq/CGAtK5qUBR6pjheqnipTFjeecgSgIKEcAOJA4GpmZeOZC8pMOoT0rfes5vHsmcFo7wbSRTAmXQurrg== dependencies: - "@babel/parser" "7.13.13" - "@babel/types" "7.13.12" - chalk "^4.1.0" + "@babel/parser" "7.17.10" + "@babel/types" "7.17.10" + chalk "^4.1.2" escodegen "^2.0.0" fs-extra "^9.1.0" - globby "^11.0.3" + globby "^11.1.0" into-stream "^6.0.0" - minimist "^1.2.5" + is-core-module "2.9.0" + minimist "^1.2.6" multistream "^4.1.0" - pkg-fetch "3.2.2" - prebuild-install "6.0.1" - progress "^2.0.3" - resolve "^1.20.0" + pkg-fetch "3.4.1" + prebuild-install "6.1.4" + resolve "^1.22.0" stream-meter "^1.0.4" - tslib "2.1.0" -prebuild-install@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.0.1.tgz#5902172f7a40eb67305b96c2a695db32636ee26d" - integrity sha512-7GOJrLuow8yeiyv75rmvZyeMGzl8mdEX5gY69d6a6bHWmiPevwqFw+tQavhK0EYMaSg3/KD24cWqeQv1EWsqDQ== +prebuild-install@6.1.4: + version "6.1.4" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.4.tgz#ae3c0142ad611d58570b89af4986088a4937e00f" + integrity sha512-Z4vpywnK1lBg+zdPCVCsKq0xO66eEV9rWo2zrROGGiRS4JtueBOdlB1FnY8lcy7JsUud/Q3ijUxyWN26Ika0vQ== dependencies: detect-libc "^1.0.3" expand-template "^2.0.3" @@ -2481,15 +2340,13 @@ prebuild-install@6.0.1: minimist "^1.2.3" mkdirp-classic "^0.5.3" napi-build-utils "^1.0.1" - node-abi "^2.7.0" - noop-logger "^0.1.1" + node-abi "^2.21.0" npmlog "^4.0.1" pump "^3.0.0" rc "^1.2.7" simple-get "^3.0.3" tar-fs "^2.0.0" tunnel-agent "^0.6.0" - which-pm-runs "^1.0.0" prelude-ls@~1.1.2: version "1.1.2" @@ -2516,10 +2373,17 @@ progress@^2.0.3: resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== -protobufjs@^6.8.6, protobufjs@^6.9.0: - version "6.10.1" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.1.tgz#e6a484dd8f04b29629e9053344e3970cccf13cd2" - integrity sha512-pb8kTchL+1Ceg4lFd5XUpK8PdWacbvV5SK2ULH2ebrYtl4GjJmS24m6CKME67jzV53tbJxHlnNOSqQHbTsR9JQ== +proto3-json-serializer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/proto3-json-serializer/-/proto3-json-serializer-1.0.1.tgz#5d2b0b3c85568edb62984c94ce2e726985de44be" + integrity sha512-jtnGKL8EE1mTOl2qgMZJQXbS22dlb2K07i4b5vp8yMGMJ6mFSgBg4Ossu/g9NCuamdYXHjp3XxyWw4tJ0G/uKw== + dependencies: + protobufjs "^6.11.3" + +protobufjs@6.11.3, protobufjs@^6.11.3: + version "6.11.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.3.tgz#637a527205a35caa4f3e2a9a4a13ddffe0e7af74" + integrity sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg== dependencies: "@protobufjs/aspromise" "^1.1.2" "@protobufjs/base64" "^1.1.2" @@ -2532,10 +2396,10 @@ protobufjs@^6.8.6, protobufjs@^6.9.0: "@protobufjs/pool" "^1.1.0" "@protobufjs/utf8" "^1.1.0" "@types/long" "^4.0.1" - "@types/node" "^13.7.0" + "@types/node" ">=13.7.0" long "^4.0.0" -proxy-addr@~2.0.5: +proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== @@ -2543,12 +2407,12 @@ proxy-addr@~2.0.5: forwarded "0.2.0" ipaddr.js "1.9.1" -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== -pstree.remy@^1.1.7: +pstree.remy@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== @@ -2566,27 +2430,24 @@ punycode@1.3.2: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= -punycode@^2.1.0, punycode@^2.1.1: +punycode@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== -pupa@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.0.1.tgz#dbdc9ff48ffbea4a26a069b6f9f7abb051008726" - integrity sha512-hEJH0s8PXLY/cdXh66tNEQGndDrIKNqNC5xmrysZy3i5C3oEoLna7YAOad+7u125+zH1HNXUmGEkrhb3c2VriA== +pupa@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/pupa/-/pupa-2.1.1.tgz#f5e8fd4afc2c5d97828faa523549ed8744a20d62" + integrity sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A== dependencies: escape-goat "^2.0.0" -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== - -qs@~6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" - integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== + dependencies: + side-channel "^1.0.4" querystring@0.2.0: version "0.2.0" @@ -2603,13 +2464,13 @@ range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== dependencies: - bytes "3.1.0" - http-errors "1.7.2" + bytes "3.1.2" + http-errors "2.0.0" iconv-lite "0.4.24" unpipe "1.0.0" @@ -2633,7 +2494,7 @@ rc@^1.2.7, rc@^1.2.8: isarray "0.0.1" string_decoder "~0.10.x" -readable-stream@^2.0.0, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.3.7: +readable-stream@^2.0.0, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.3.7: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -2655,13 +2516,22 @@ readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readdirp@~3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" - integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== dependencies: picomatch "^2.2.1" +regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + functions-have-names "^1.2.2" + registry-auth-token@^4.0.0: version "4.2.0" resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-4.2.0.tgz#1d37dffda72bbecd0f581e4715540213a65eb7da" @@ -2676,54 +2546,24 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" -request@^2.81.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= -resolve@^1.20.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" - integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== +resolve@^1.22.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== dependencies: - is-core-module "^2.2.0" - path-parse "^1.0.6" + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" responselike@^1.0.2: version "1.0.2" @@ -2732,31 +2572,32 @@ responselike@^1.0.2: dependencies: lowercase-keys "^1.0.0" -retry-request@^4.0.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-4.1.3.tgz#d5f74daf261372cff58d08b0a1979b4d7cab0fde" - integrity sha512-QnRZUpuPNgX0+D1xVxul6DbJ9slvo4Rm6iV/dn63e048MvGbUZiKySVt6Tenp04JqmchxjiLltGerOJys7kJYQ== +retry-request@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/retry-request/-/retry-request-5.0.0.tgz#886ff8ec0e77fffbe66a4d5e90fd8f6646b6eae4" + integrity sha512-vBZdBxUordje9253imlmGtppC5gdcwZmNz7JnU2ui+KKFPk25keR+0c020AVV20oesYxIFOI0Kh3HE88/59ieg== dependencies: debug "^4.1.1" + extend "^3.0.2" reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -rhea-promise@^0.1.15: - version "0.1.15" - resolved "https://registry.yarnpkg.com/rhea-promise/-/rhea-promise-0.1.15.tgz#00175324352224424d59b7712faf14097a84e8f2" - integrity sha512-+6uilZXSJGyiqVeHQI3Krv6NTAd8cWRCY2uyCxmzR4/5IFtBqqFem1HV2OiwSj0Gu7OFChIJDfH2JyjN7J0vRA== +rhea-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/rhea-promise/-/rhea-promise-2.1.0.tgz#540e97f62302ad54b368b79a3560a51eefd2b063" + integrity sha512-CRMwdJ/o4oO/xKcvAwAsd0AHy5fVvSlqso7AadRmaaLGzAzc9LCoW7FOFnucI8THasVmOeCnv5c/fH/n7FcNaA== dependencies: debug "^3.1.0" - rhea "^1.0.4" - tslib "^1.9.3" + rhea "^2.0.3" + tslib "^2.2.0" -rhea@^1.0.18, rhea@^1.0.23, rhea@^1.0.4: - version "1.0.24" - resolved "https://registry.yarnpkg.com/rhea/-/rhea-1.0.24.tgz#7084e4c635aa8ba0faf2d9602ac9f97d26aedc00" - integrity sha512-PEl62U2EhxCO5wMUZ2/bCBcXAVKN9AdMSNQOrp3+R5b77TEaOSiy16MQ0sIOmzj/iqsgIAgPs1mt3FYfu1vIXA== +rhea@^2.0.3: + version "2.0.8" + resolved "https://registry.yarnpkg.com/rhea/-/rhea-2.0.8.tgz#2ac355fad923e36a995defffdf314bb1cbe562de" + integrity sha512-IgwlP4D2lzinBSll5f35tAWa30dGCZhG9Ujd1DiaB7MUGegIjAaLzqATCw3ha+h9oq9mXcitqayBbNIXYdvtFg== dependencies: debug "0.8.0 - 3.5.0" @@ -2765,17 +2606,22 @@ run-parallel@^1.1.9: resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1, safe-buffer@~5.1.2: +safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1, safe-buffer@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@^5.0.1, safe-buffer@^5.1.2, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-stable-stringify@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.3.1.tgz#ab67cbe1fe7d40603ca641c5e765cb942d04fc73" + integrity sha512-kYBSfT+troD9cDA85VDnHZ1rpHC50O0g1e6WlGHVCz/g+JS+9WKLj+XwFYyR8UbrZN8ll9HUpDAAddY58MGisg== -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: +"safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== @@ -2807,10 +2653,12 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.1.3: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== +semver@^7.3.4: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== + dependencies: + lru-cache "^6.0.0" semver@^7.3.5: version "7.3.5" @@ -2819,44 +2667,53 @@ semver@^7.3.5: dependencies: lru-cache "^6.0.0" -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== +send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== dependencies: debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" + depd "2.0.0" + destroy "1.2.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" - http-errors "~1.7.2" + http-errors "2.0.0" mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" + ms "2.1.3" + on-finished "2.4.1" range-parser "~1.2.1" - statuses "~1.5.0" + statuses "2.0.1" -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.17.1" + send "0.18.0" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.3" @@ -2894,43 +2751,15 @@ source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= - -sshpk@^1.7.0: - version "1.16.1" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.16.1.tgz#fb661c0bef29b39db40769ee39fa70093d6f6877" - integrity sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - stack-trace@0.0.x: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA= -"statuses@>= 1.5.0 < 2", statuses@~1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= - -stream-browserify@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== stream-meter@^1.0.4: version "1.0.4" @@ -2979,6 +2808,33 @@ string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" +string-width@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string.prototype.trimend@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" + integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + +string.prototype.trimstart@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" + integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" @@ -3026,6 +2882,13 @@ strip-ansi@^6.0.0: dependencies: ansi-regex "^5.0.0" +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + strip-json-comments@~2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" @@ -3045,7 +2908,12 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" -tar-fs@^2.0.0: +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tar-fs@^2.0.0, tar-fs@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" integrity sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng== @@ -3066,21 +2934,11 @@ tar-stream@^2.1.4: inherits "^2.0.3" readable-stream "^3.1.1" -term-size@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.0.tgz#1f16adedfe9bdc18800e1776821734086fcc6753" - integrity sha512-a6sumDlzyHVJWb8+YofY4TW112G6p2FCPEAFk+59gIYHv3XHRhm9ltVQ9kli4hNWeQBwSpe8cRN25x0ROunMOw== - text-hex@1.0.x: version "1.0.0" resolved "https://registry.yarnpkg.com/text-hex/-/text-hex-1.0.0.tgz#69dc9c1b17446ee79a92bf5b884bb4b9127506f5" integrity sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg== -through@~2.3.4: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -3098,10 +2956,10 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== touch@^3.1.0: version "3.1.0" @@ -3119,33 +2977,25 @@ tough-cookie@^4.0.0: punycode "^2.1.1" universalify "^0.1.2" -tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== triple-beam@^1.2.0, triple-beam@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.3.0.tgz#a595214c7298db8339eeeee083e4d10bd8cb8dd9" integrity sha512-XrHUvV5HpdLmIj4uVMxHggLbFSZYIn7HEWsqePZcI50pco+MPqJ50wMGY794X7AOOhxOBAjbkqfAbEe/QMp2Lw== -tslib@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - -tslib@^1.10.0, tslib@^1.9.3: +tslib@^1.9.3: version "1.13.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043" integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q== -tslib@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e" - integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ== +tslib@^2.2.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== tunnel-agent@^0.6.0: version "0.6.0" @@ -3154,16 +3004,11 @@ tunnel-agent@^0.6.0: dependencies: safe-buffer "^5.0.1" -tunnel@^0.0.6, tunnel@~0.0.2: +tunnel@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.6.tgz#72f1314b34a5b192db012324df2cc587ca47f92c" integrity sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg== -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= - type-check@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" @@ -3171,12 +3016,12 @@ type-check@~0.3.2: dependencies: prelude-ls "~1.1.2" -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== -type-is@~1.6.17, type-is@~1.6.18: +type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -3191,22 +3036,20 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -undefsafe@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.3.tgz#6b166e7094ad46313b2202da7ecc2cd7cc6e7aae" - integrity sha512-nrXZwwXrD/T/JXeygJqdCO6NZZ1L66HrxM/Z7mIq2oPanoN0F1nLx3lwJMu6AwJY69hdixaFQOuoYsMjE5/C2A== +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== dependencies: - debug "^2.2.0" - -underscore@1.4.x: - version "1.4.4" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.4.4.tgz#61a6a32010622afa07963bf325203cf12239d604" - integrity sha1-YaajIBBiKvoHljvzJSA88SI51gQ= + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" -underscore@^1.8.3: - version "1.10.2" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.10.2.tgz#73d6aa3668f3188e4adb0f1943bd12cfd7efaaaf" - integrity sha512-N4P+Q/BuyuEKFJ43B9gYuOj4TQUHXX+j2FqguVOpjkssLUUrnJofCcBccJSCoeturDoZU6GorDTHSvUDlSQbTg== +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== unique-string@^2.0.0: version "2.0.0" @@ -3235,32 +3078,26 @@ unpipe@1.0.0, unpipe@~1.0.0: resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw= -update-notifier@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-4.1.3.tgz#be86ee13e8ce48fb50043ff72057b5bd598e1ea3" - integrity sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A== +update-notifier@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/update-notifier/-/update-notifier-5.1.0.tgz#4ab0d7c7f36a231dd7316cf7729313f0214d9ad9" + integrity sha512-ItnICHbeMh9GqUy31hFPrD1kcuZ3rpxDZbf4KUDavXwS0bW5m7SLbDQpGX3UYr072cbrF5hFUs3r5tUsPwjfHw== dependencies: - boxen "^4.2.0" - chalk "^3.0.0" + boxen "^5.0.0" + chalk "^4.1.0" configstore "^5.0.1" has-yarn "^2.1.0" import-lazy "^2.1.0" is-ci "^2.0.0" - is-installed-globally "^0.3.1" - is-npm "^4.0.0" + is-installed-globally "^0.4.0" + is-npm "^5.0.0" is-yarn-global "^0.3.0" - latest-version "^5.0.0" - pupa "^2.0.1" + latest-version "^5.1.0" + pupa "^2.1.1" + semver "^7.3.4" semver-diff "^3.1.1" xdg-basedir "^4.0.0" -uri-js@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" - integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== - dependencies: - punycode "^2.1.0" - url-parse-lax@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" @@ -3268,10 +3105,10 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -url-parse@~1.4.3: - version "1.4.7" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" - integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== +url-parse@~1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== dependencies: querystringify "^2.1.1" requires-port "^1.0.0" @@ -3297,12 +3134,17 @@ util-deprecate@^1.0.1, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= -util@^0.11.1: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== +util@^0.12.1: + version "0.12.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253" + integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw== dependencies: - inherits "2.0.3" + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + safe-buffer "^5.1.2" + which-typed-array "^1.1.2" utils-merge@1.0.1: version "1.0.1" @@ -3319,54 +3161,56 @@ uuid-random@^1.3.2: resolved "https://registry.yarnpkg.com/uuid-random/-/uuid-random-1.3.2.tgz#96715edbaef4e84b1dcf5024b00d16f30220e2d0" integrity sha512-UOzej0Le/UgkbWEO8flm+0y+G+ljUon1QWTEZOq1rnMAsxo2+SckbiZdKzAHHlVh6gJqI1TjC/xwgR50MuCrBQ== -uuid@3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" - integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^8.1.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea" - integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ== +uuid@8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" + integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== -validator@^9.4.1: - version "9.4.1" - resolved "https://registry.yarnpkg.com/validator/-/validator-9.4.1.tgz#abf466d398b561cd243050112c6ff1de6cc12663" - integrity sha512-YV5KjzvRmSyJ1ee/Dm5UED0G+1L4GZnLN3w6/T+zZm8scVua4sOhYKWTUrKa0H/tMiJyO9QLHMPN+9mB/aMunA== +uuid@^8.3.0: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA= - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== -walkdir@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/walkdir/-/walkdir-0.4.1.tgz#dc119f83f4421df52e3061e514228a2db20afa39" - integrity sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" -which-pm-runs@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-pm-runs/-/which-pm-runs-1.0.0.tgz#670b3afbc552e0b55df6b7780ca74615f23ad1cb" - integrity sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs= +which-typed-array@^1.1.2: + version "1.1.8" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.8.tgz#0cfd53401a6f334d90ed1125754a42ed663eb01f" + integrity sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + es-abstract "^1.20.0" + for-each "^0.3.3" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.9" wide-align@^1.1.0: version "1.1.3" @@ -3382,17 +3226,17 @@ widest-line@^3.1.0: dependencies: string-width "^4.0.0" -winston-daily-rotate-file@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/winston-daily-rotate-file/-/winston-daily-rotate-file-4.5.0.tgz#3914ac57c4bdae1138170bec85af0c2217b253b1" - integrity sha512-/HqeWiU48dzGqcrABRlxYWVMdL6l3uKCtFSJyrqK+E2rLnSFNsgYpvwx15EgTitBLNzH69lQd/+z2ASryV2aqw== +winston-daily-rotate-file@^4.7.1: + version "4.7.1" + resolved "https://registry.yarnpkg.com/winston-daily-rotate-file/-/winston-daily-rotate-file-4.7.1.tgz#f60a643af87f8867f23170d8cd87dbe3603a625f" + integrity sha512-7LGPiYGBPNyGHLn9z33i96zx/bd71pjBn9tqQzO3I4Tayv94WPmBNwKC7CO1wPHdP9uvu+Md/1nr6VSH9h0iaA== dependencies: - file-stream-rotator "^0.5.7" + file-stream-rotator "^0.6.1" object-hash "^2.0.1" triple-beam "^1.3.0" - winston-transport "^4.2.0" + winston-transport "^4.4.0" -winston-transport@^4.2.0, winston-transport@^4.4.0: +winston-transport@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.4.0.tgz#17af518daa690d5b2ecccaa7acf7b20ca7925e59" integrity sha512-Lc7/p3GtqtqPBYYtS6KCN3c77/2QCev51DvcJKbkFPQNoj1sinkGwLGFDxkXY9J6p9+EPnYs+D90uwbnaiURTw== @@ -3400,40 +3244,36 @@ winston-transport@^4.2.0, winston-transport@^4.4.0: readable-stream "^2.3.7" triple-beam "^1.2.0" -winston@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/winston/-/winston-3.3.3.tgz#ae6172042cafb29786afa3d09c8ff833ab7c9170" - integrity sha512-oEXTISQnC8VlSAKf1KYSSd7J6IWuRPQqDdo8eoRNaYKLvwSb5+79Z3Yi1lrl6KDpU6/VWaxpakDAtb1oQ4n9aw== +winston-transport@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/winston-transport/-/winston-transport-4.5.0.tgz#6e7b0dd04d393171ed5e4e4905db265f7ab384fa" + integrity sha512-YpZzcUzBedhlTAfJg6vJDlyEai/IFMIVcaEZZyl3UXIl4gmqRpU7AE89AHLkbzLUsv0NVmw7ts+iztqKxxPW1Q== + dependencies: + logform "^2.3.2" + readable-stream "^3.6.0" + triple-beam "^1.3.0" + +winston@^3.7.2: + version "3.7.2" + resolved "https://registry.yarnpkg.com/winston/-/winston-3.7.2.tgz#95b4eeddbec902b3db1424932ac634f887c400b1" + integrity sha512-QziIqtojHBoyzUOdQvQiar1DH0Xp9nF1A1y7NVy2DGEsz82SBDtOalS0ulTRGVT14xPX3WRWkCsdcJKqNflKng== dependencies: "@dabh/diagnostics" "^2.0.2" - async "^3.1.0" + async "^3.2.3" is-stream "^2.0.0" - logform "^2.2.0" + logform "^2.4.0" one-time "^1.0.0" readable-stream "^3.4.0" + safe-stable-stringify "^2.3.1" stack-trace "0.0.x" triple-beam "^1.3.0" - winston-transport "^4.4.0" - -wns@~0.5.3: - version "0.5.4" - resolved "https://registry.yarnpkg.com/wns/-/wns-0.5.4.tgz#ad8e2ee60e675557da9610d94444a7f59eceaf78" - integrity sha512-WYiJ7khIwUGBD5KAm+YYmwJDDRzFRs4YGAjtbFSoRIdbn9Jcix3p9khJmpvBTXGommaKkvduAn+pc9l4d9yzVQ== + winston-transport "^4.5.0" word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -3479,11 +3319,6 @@ xml2js@^0.4.19: sax ">=0.6.0" xmlbuilder "~11.0.0" -xmlbuilder@15.1.1: - version "15.1.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-15.1.1.tgz#9dcdce49eea66d8d10b42cae94a79c3c8d0c2ec5" - integrity sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg== - xmlbuilder@~11.0.0: version "11.0.1" resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" @@ -3494,11 +3329,6 @@ xmlbuilder@~9.0.1: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= -y18n@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" - integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== - y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" @@ -3509,36 +3339,11 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yargs-parser@^18.1.2: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - yargs-parser@^20.2.2: version "20.2.9" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== -yargs@^15.3.1: - version "15.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" - integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^18.1.2" - yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" From eab4e333a9c6d4fe487343c8004484d12c0652ff Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 14 Jun 2022 12:03:05 +0300 Subject: [PATCH 72/86] refactoring: alarm - add Mockito to create --- .../controller/BaseAlarmControllerTest.java | 83 ++++++++++++++++++- 1 file changed, 79 insertions(+), 4 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java index d82f4175b5..ee1a952546 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java @@ -128,8 +128,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testUpdateAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); + alarm.setSeverity(AlarmSeverity.MAJOR); loginDifferentTenant(); @@ -144,8 +150,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testUpdateAlarmViaDifferentCustomer() throws Exception { loginCustomerUser(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + loginDifferentCustomer(); alarm.setSeverity(AlarmSeverity.MAJOR); @@ -160,10 +172,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testDeleteAlarmViaCustomer() throws Exception { loginCustomerUser(); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); testNotifyEntityOneMsgToEdgeServiceNever(alarm, alarm.getId(), alarm.getOriginator(), @@ -174,10 +190,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testDeleteAlarmViaTenant() throws Exception { loginTenantAdmin(); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); + doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); testNotifyEntityOneMsgToEdgeServiceNever(alarm, alarm.getId(), alarm.getOriginator(), @@ -188,8 +208,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testDeleteAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); + loginDifferentTenant(); Mockito.reset(tbClusterService, auditLogService); @@ -204,7 +230,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testDeleteAlarmViaAnotherCustomer() throws Exception { loginCustomerUser(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + loginDifferentCustomer(); Mockito.reset(tbClusterService, auditLogService); @@ -219,10 +252,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testClearAlarmViaCustomer() throws Exception { loginCustomerUser(); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + doPost("/api/alarm/" + alarm.getId() + "/clear").andExpect(status().isOk()); Alarm foundAlarm = doGet("/api/alarm/" + alarm.getId(), Alarm.class); @@ -237,8 +274,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testClearAlarmViaTenant() throws Exception { loginTenantAdmin(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); + Mockito.reset(tbClusterService, auditLogService); doPost("/api/alarm/" + alarm.getId() + "/clear").andExpect(status().isOk()); @@ -254,10 +297,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testAcknowledgeAlarmViaCustomer() throws Exception { loginCustomerUser(); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + doPost("/api/alarm/" + alarm.getId() + "/ack").andExpect(status().isOk()); Alarm foundAlarm = doGet("/api/alarm/" + alarm.getId(), Alarm.class); @@ -272,7 +319,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testClearAlarmViaDifferentCustomer() throws Exception { loginCustomerUser(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + loginDifferentCustomer(); Mockito.reset(tbClusterService, auditLogService); @@ -286,7 +340,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testClearAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); + loginDifferentTenant(); Mockito.reset(tbClusterService, auditLogService); @@ -300,7 +361,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testAcknowledgeAlarmViaDifferentCustomer() throws Exception { loginCustomerUser(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + loginDifferentCustomer(); Mockito.reset(tbClusterService, auditLogService); @@ -314,7 +382,14 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { @Test public void testAcknowledgeAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); + + Mockito.reset(tbClusterService, auditLogService); + Alarm alarm = createAlarm(TEST_ALARM_TYPE); + + testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), + tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); + loginDifferentTenant(); Mockito.reset(tbClusterService, auditLogService); From 8bccd857ebd741ade07e3c5f82ea2e5de83ea56c Mon Sep 17 00:00:00 2001 From: fe-dev Date: Tue, 14 Jun 2022 12:06:46 +0300 Subject: [PATCH 73/86] UI: Add input placeholder --- .../authentication-dialog/sms-auth-dialog.component.html | 6 +++++- ui-ngx/src/app/shared/components/phone-input.component.html | 4 ++-- ui-ngx/src/app/shared/components/phone-input.component.ts | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html b/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html index bb547f56a3..e216c22d3e 100644 --- a/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html @@ -37,7 +37,11 @@

security.2fa.dialog.sms-step-description

- + +
- security.2fa.dialog.sms-step-label + {{ placeholder | translate }} = this.countryCodeData.allCountries; phonePlaceholder: string; From 6d2d876d64c81ffe4320378b48891a9fd952bf09 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 14 Jun 2022 14:45:42 +0300 Subject: [PATCH 74/86] refactoring: commit1 --- .../controller/AbstractNotifyEntityTest.java | 4 - .../controller/BaseAlarmControllerTest.java | 75 +------------ .../BaseCustomerControllerTest.java | 105 +++++++++--------- 3 files changed, 57 insertions(+), 127 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java index 6fb7b93bae..40a3bac5de 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -56,7 +56,6 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.reset(tbClusterService, auditLogService); } - protected void testNotifyEntityDeleteOneMsgToEdgeServiceNever(HasName entity, EntityId entityId, EntityId originatorId, TenantId tenantId, CustomerId customerId, UserId userId, String userName, ActionType actionType, Object... additionalInfo) { @@ -64,7 +63,6 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { testLogEntityActionOne(entity, originatorId, tenantId, customerId, userId, userName, actionType, additionalInfo); testPushMsgToRuleEngineOne(entityId, tenantId); testBroadcastEntityStateChangeEventOne(entityId, tenantId); - } protected void testNotifyEntityOneMsgToEdgeServiceNever(HasName entity, EntityId entityId, EntityId originatorId, @@ -172,6 +170,4 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { } return result; } - - } diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java index ee1a952546..03d1223cc0 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseAlarmControllerTest.java @@ -87,12 +87,9 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testUpdateAlarmViaCustomer() throws Exception { loginCustomerUser(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + Mockito.reset(tbClusterService, auditLogService); alarm.setSeverity(AlarmSeverity.MAJOR); Alarm updatedAlarm = doPost("/api/alarm", alarm, Alarm.class); @@ -108,12 +105,9 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testUpdateAlarmViaTenant() throws Exception { loginTenantAdmin(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); + Mockito.reset(tbClusterService, auditLogService); alarm.setSeverity(AlarmSeverity.MAJOR); Alarm updatedAlarm = doPost("/api/alarm", alarm, Alarm.class); @@ -129,13 +123,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testUpdateAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); - alarm.setSeverity(AlarmSeverity.MAJOR); loginDifferentTenant(); @@ -151,13 +140,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testUpdateAlarmViaDifferentCustomer() throws Exception { loginCustomerUser(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); - loginDifferentCustomer(); alarm.setSeverity(AlarmSeverity.MAJOR); @@ -173,12 +157,9 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testDeleteAlarmViaCustomer() throws Exception { loginCustomerUser(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + Mockito.reset(tbClusterService, auditLogService); doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); @@ -191,12 +172,9 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testDeleteAlarmViaTenant() throws Exception { loginTenantAdmin(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); + Mockito.reset(tbClusterService, auditLogService); doDelete("/api/alarm/" + alarm.getId()).andExpect(status().isOk()); @@ -209,13 +187,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testDeleteAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); - loginDifferentTenant(); Mockito.reset(tbClusterService, auditLogService); @@ -231,13 +204,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testDeleteAlarmViaAnotherCustomer() throws Exception { loginCustomerUser(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); - loginDifferentCustomer(); Mockito.reset(tbClusterService, auditLogService); @@ -253,12 +221,9 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testClearAlarmViaCustomer() throws Exception { loginCustomerUser(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + Mockito.reset(tbClusterService, auditLogService); doPost("/api/alarm/" + alarm.getId() + "/clear").andExpect(status().isOk()); @@ -275,13 +240,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testClearAlarmViaTenant() throws Exception { loginTenantAdmin(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); - Mockito.reset(tbClusterService, auditLogService); doPost("/api/alarm/" + alarm.getId() + "/clear").andExpect(status().isOk()); @@ -298,12 +258,9 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testAcknowledgeAlarmViaCustomer() throws Exception { loginCustomerUser(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); + Mockito.reset(tbClusterService, auditLogService); doPost("/api/alarm/" + alarm.getId() + "/ack").andExpect(status().isOk()); @@ -320,13 +277,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testClearAlarmViaDifferentCustomer() throws Exception { loginCustomerUser(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); - loginDifferentCustomer(); Mockito.reset(tbClusterService, auditLogService); @@ -341,13 +293,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testClearAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); - loginDifferentTenant(); Mockito.reset(tbClusterService, auditLogService); @@ -362,13 +309,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testAcknowledgeAlarmViaDifferentCustomer() throws Exception { loginCustomerUser(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, customerUserId, CUSTOMER_USER_EMAIL, ActionType.ADDED); - loginDifferentCustomer(); Mockito.reset(tbClusterService, auditLogService); @@ -383,13 +325,8 @@ public abstract class BaseAlarmControllerTest extends AbstractControllerTest { public void testAcknowledgeAlarmViaDifferentTenant() throws Exception { loginTenantAdmin(); - Mockito.reset(tbClusterService, auditLogService); - Alarm alarm = createAlarm(TEST_ALARM_TYPE); - testNotifyEntityOne(alarm, alarm.getId(), alarm.getOriginator(), - tenantId, customerId, tenantAdminUserId, TENANT_ADMIN_EMAIL, ActionType.ADDED); - loginDifferentTenant(); Mockito.reset(tbClusterService, auditLogService); diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java index 0aa81c2d18..2ad239f354 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java @@ -93,14 +93,16 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest Mockito.reset(tbClusterService, auditLogService); Customer savedCustomer = doPost("/api/customer", customer, Customer.class); + + testNotifyEntityOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), + savedCustomer.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.ADDED); + Assert.assertNotNull(savedCustomer); Assert.assertNotNull(savedCustomer.getId()); Assert.assertTrue(savedCustomer.getCreatedTime() > 0); Assert.assertEquals(customer.getTitle(), savedCustomer.getTitle()); - testNotifyEntityOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), - savedCustomer.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), - tenantAdmin.getEmail(), ActionType.ADDED); savedCustomer.setTitle("My new customer"); @@ -108,8 +110,9 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest doPost("/api/customer", savedCustomer, Customer.class); - testNotifyEntityOne(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), - savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.UPDATED); + testNotifyEntityOne(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), savedCustomer.getTenantId(), + savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), + ActionType.UPDATED); Customer foundCustomer = doGet("/api/customer/" + savedCustomer.getId().getId().toString(), Customer.class); Assert.assertEquals(foundCustomer.getTitle(), savedCustomer.getTitle()); @@ -117,89 +120,65 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isOk()); - testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), - savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), - ActionType.DELETED, savedCustomer.getId().getId().toString()); + testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), + savedCustomer.getId(), savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), + tenantAdmin.getEmail(), ActionType.DELETED, savedCustomer.getId().getId().toString()); } @Test public void testSaveCustomerWithViolationOfValidation() throws Exception { Customer customer = new Customer(); + customer.setTitle(RandomStringUtils.randomAlphabetic(300)); Mockito.reset(tbClusterService, auditLogService); - doPost("/api/customer", customer) - .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Customer title should be specified"))); - - testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: empty title")); - - customer.setTitle(RandomStringUtils.randomAlphabetic(300)); - doPost("/api/customer", customer).andExpect(statusReason(containsString("length of title must be equal or less than 255"))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad title")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); customer.setTitle("Normal title"); - customer.setEmail("invalid@mail"); - doPost("/api/customer", customer) - .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Invalid email address format 'invalid@mail'"))); - - testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: invalid email")); - - customer.setEmail("normal@mail.com.ua"); - customer.setCity(RandomStringUtils.randomAlphabetic(300)); + doPost("/api/customer", customer).andExpect(statusReason(containsString("length of city must be equal or less than 255"))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad City")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); customer.setCity("Normal city"); customer.setCountry(RandomStringUtils.randomAlphabetic(300)); doPost("/api/customer", customer).andExpect(statusReason(containsString("length of country must be equal or less than 255"))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad Country")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); customer.setCountry("Ukraine"); customer.setPhone(RandomStringUtils.randomAlphabetic(300)); doPost("/api/customer", customer).andExpect(statusReason(containsString("length of phone must be equal or less than 255"))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad Phone")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); customer.setPhone("+3892555554512"); customer.setState(RandomStringUtils.randomAlphabetic(300)); doPost("/api/customer", customer).andExpect(statusReason(containsString("length of state must be equal or less than 255"))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad state")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); customer.setState("Normal state"); customer.setZip(RandomStringUtils.randomAlphabetic(300)); doPost("/api/customer", customer).andExpect(statusReason(containsString("length of zip or postal code must be equal or less than 255"))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("Test: bad Zip")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); } @Test public void testUpdateCustomerFromDifferentTenant() throws Exception { Customer customer = new Customer(); customer.setTitle("My customer"); - - Mockito.reset(tbClusterService, auditLogService); - Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - - testNotifyEntityOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), - savedCustomer.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED); - doPost("/api/customer", savedCustomer, Customer.class); loginDifferentTenant(); @@ -211,7 +190,6 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest testNotifyEntityNever(savedCustomer.getId(), savedCustomer); deleteDifferentTenant(); - login(tenantAdmin.getName(), "testPassword1"); Mockito.reset(tbClusterService, auditLogService); @@ -228,25 +206,20 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest public void testFindCustomerById() throws Exception { Customer customer = new Customer(); customer.setTitle("My customer"); - - Mockito.reset(tbClusterService, auditLogService); - Customer savedCustomer = doPost("/api/customer", customer, Customer.class); - testNotifyEntityOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), - savedCustomer.getTenantId(), tenantAdmin.getCustomerId(), tenantAdmin.getId(), - tenantAdmin.getEmail(), ActionType.ADDED); - Customer foundCustomer = doGet("/api/customer/" + savedCustomer.getId().getId().toString(), Customer.class); Assert.assertNotNull(foundCustomer); Assert.assertEquals(savedCustomer, foundCustomer); + Mockito.reset(tbClusterService, auditLogService); + doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isOk()); - testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), - savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), - ActionType.DELETED, savedCustomer.getId().getId().toString()); + testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), + savedCustomer.getId(), savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), + tenantAdmin.getEmail(), ActionType.DELETED, savedCustomer.getId().getId().toString()); } @Test @@ -260,14 +233,38 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest doDelete("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isOk()); - testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), savedCustomer.getId(), - savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), tenantAdmin.getEmail(), - ActionType.DELETED, savedCustomer.getId().getId().toString()); + testNotifyEntityBroadcastEntityStateChangeEventOneMsgToEdgeServiceNever(savedCustomer, savedCustomer.getId(), + savedCustomer.getId(), savedCustomer.getTenantId(), savedCustomer.getId(), tenantAdmin.getId(), + tenantAdmin.getEmail(), ActionType.DELETED, savedCustomer.getId().getId().toString()); doGet("/api/customer/" + savedCustomer.getId().getId().toString()) .andExpect(status().isNotFound()); } + @Test + public void testSaveCustomerWithEmptyTitle() throws Exception { + Customer customer = new Customer(); + doPost("/api/customer", customer) + .andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Customer title should be specified"))); + } + + @Test + public void testSaveCustomerWithInvalidEmail() throws Exception { + Customer customer = new Customer(); + customer.setTitle("My customer"); + customer.setEmail("invalid@mail"); + + Mockito.reset(tbClusterService, auditLogService); + + doPost("/api/customer", customer) + .andExpect(status().isBadRequest()) + .andExpect(statusReason(containsString("Invalid email address format 'invalid@mail'"))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); + } + @Test public void testFindCustomers() throws Exception { TenantId tenantId = savedTenant.getId(); From 51e05d1a9ad7bc60d824949d57639c56dc4d0666 Mon Sep 17 00:00:00 2001 From: fe-dev Date: Tue, 14 Jun 2022 16:14:01 +0300 Subject: [PATCH 75/86] UI: Refactoring phone input and add to test sms dialog and contact --- .../admin/send-test-sms-dialog.component.html | 16 ++++------ .../sms-auth-dialog.component.html | 2 +- .../shared/components/contact.component.html | 12 ++++---- .../components/phone-input.component.html | 2 +- .../components/phone-input.component.scss | 1 - .../components/phone-input.component.ts | 30 ++++++++++++++----- 6 files changed, 35 insertions(+), 28 deletions(-) diff --git a/ui-ngx/src/app/modules/home/pages/admin/send-test-sms-dialog.component.html b/ui-ngx/src/app/modules/home/pages/admin/send-test-sms-dialog.component.html index cc7b4d21f3..40cc60f730 100644 --- a/ui-ngx/src/app/modules/home/pages/admin/send-test-sms-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/admin/send-test-sms-dialog.component.html @@ -30,17 +30,11 @@
- - admin.number-to - - - {{ 'admin.number-to-required' | translate }} - - - {{ 'admin.phone-number-pattern' | translate }} - - - + + admin.sms-message diff --git a/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html b/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html index e216c22d3e..aace1d7152 100644 --- a/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html +++ b/ui-ngx/src/app/modules/home/pages/security/authentication-dialog/sms-auth-dialog.component.html @@ -36,7 +36,7 @@ {{ 'security.2fa.dialog.sms-step-label' | translate }}

security.2fa.dialog.sms-step-description

-
+
contact.address2 - - contact.phone - - - {{ 'contact.phone-max-length' | translate }} - - + + contact.email diff --git a/ui-ngx/src/app/shared/components/phone-input.component.html b/ui-ngx/src/app/shared/components/phone-input.component.html index c5b2ae7bc1..83db450d70 100644 --- a/ui-ngx/src/app/shared/components/phone-input.component.html +++ b/ui-ngx/src/app/shared/components/phone-input.component.html @@ -28,7 +28,7 @@
- {{ placeholder | translate }} + {{ label | translate }} = this.countryCodeData.allCountries; phonePlaceholder: string; From c9558b5e08916882ba41aabb0bc23d67548a68f0 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 14 Jun 2022 16:59:21 +0300 Subject: [PATCH 76/86] refactoring: commit2 (error) --- .../controller/AbstractNotifyEntityTest.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java index 40a3bac5de..38139d91d4 100644 --- a/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/AbstractNotifyEntityTest.java @@ -32,6 +32,8 @@ import org.thingsboard.server.common.msg.TbMsg; import org.thingsboard.server.dao.audit.AuditLogService; import org.thingsboard.server.dao.model.ModelConstants; +import java.io.PrintWriter; +import java.io.StringWriter; import java.util.Locale; import static org.mockito.Mockito.never; @@ -96,12 +98,14 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customer_NULL_UUID), Mockito.eq(userId), Mockito.eq(userName), Mockito.eq(entity_NULL_UUID), Mockito.any(entity.getClass()), Mockito.eq(actionType), - Mockito.any(exp.getClass()), Mockito.eq(additionalInfo)); + Mockito.argThat(argument -> + argument.getMessage().equals(exp.getMessage())), Mockito.eq(additionalInfo)); } else { Mockito.verify(auditLogService, times(1)).logEntityAction(Mockito.eq(tenantId), Mockito.eq(customer_NULL_UUID), Mockito.eq(userId), Mockito.eq(userName), Mockito.eq(entity_NULL_UUID), Mockito.any(entity.getClass()), Mockito.eq(actionType), - Mockito.any(exp.getClass())); + Mockito.argThat(argument -> + argument.getMessage().equals(exp.getMessage()))); } Mockito.verify(tbClusterService, never()).pushMsgToRuleEngine(Mockito.any(), Mockito.any(entity_NULL_UUID.getClass()), Mockito.any(), Mockito.any()); @@ -170,4 +174,10 @@ public abstract class AbstractNotifyEntityTest extends AbstractWebTest { } return result; } + + private String getFailureStack(Exception e) { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + return sw.toString(); + } } From 281c266d26d0d73c6a9379f006e855ddf7adf7ef Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Tue, 14 Jun 2022 17:00:55 +0300 Subject: [PATCH 77/86] refactoring: commit3 (error) --- .../BaseCustomerControllerTest.java | 47 ++++++++++++------- 1 file changed, 31 insertions(+), 16 deletions(-) diff --git a/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java b/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java index 2ad239f354..c3ae7d76f9 100644 --- a/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java +++ b/application/src/test/java/org/thingsboard/server/controller/BaseCustomerControllerTest.java @@ -128,50 +128,57 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest @Test public void testSaveCustomerWithViolationOfValidation() throws Exception { Customer customer = new Customer(); + String validationError = "Validation error: "; customer.setTitle(RandomStringUtils.randomAlphabetic(300)); Mockito.reset(tbClusterService, auditLogService); - doPost("/api/customer", customer).andExpect(statusReason(containsString("length of title must be equal or less than 255"))); + String msgError = "length of title must be equal or less than 255"; + doPost("/api/customer", customer).andExpect(statusReason(containsString(msgError))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(validationError + msgError)); customer.setTitle("Normal title"); customer.setCity(RandomStringUtils.randomAlphabetic(300)); - - doPost("/api/customer", customer).andExpect(statusReason(containsString("length of city must be equal or less than 255"))); + msgError = "length of city must be equal or less than 255"; + doPost("/api/customer", customer).andExpect(statusReason(containsString(msgError))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(validationError + msgError)); customer.setCity("Normal city"); customer.setCountry(RandomStringUtils.randomAlphabetic(300)); - doPost("/api/customer", customer).andExpect(statusReason(containsString("length of country must be equal or less than 255"))); + msgError = "length of country must be equal or less than 255"; + doPost("/api/customer", customer).andExpect(statusReason(containsString(msgError))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(validationError + msgError)); customer.setCountry("Ukraine"); customer.setPhone(RandomStringUtils.randomAlphabetic(300)); - doPost("/api/customer", customer).andExpect(statusReason(containsString("length of phone must be equal or less than 255"))); + msgError = "length of phone must be equal or less than 255"; + doPost("/api/customer", customer).andExpect(statusReason(containsString(msgError))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(validationError + msgError)); customer.setPhone("+3892555554512"); customer.setState(RandomStringUtils.randomAlphabetic(300)); - doPost("/api/customer", customer).andExpect(statusReason(containsString("length of state must be equal or less than 255"))); + msgError = "length of state must be equal or less than 255"; + doPost("/api/customer", customer).andExpect(statusReason(containsString(msgError))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(validationError + msgError)); customer.setState("Normal state"); customer.setZip(RandomStringUtils.randomAlphabetic(300)); - doPost("/api/customer", customer).andExpect(statusReason(containsString("length of zip or postal code must be equal or less than 255"))); + msgError = "length of zip or postal code must be equal or less than 255"; + doPost("/api/customer", customer).andExpect(statusReason(containsString(msgError))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(validationError + msgError)); + } @Test @@ -244,14 +251,22 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest @Test public void testSaveCustomerWithEmptyTitle() throws Exception { Customer customer = new Customer(); + String msgError = "Customer title should be specified"; + + Mockito.reset(tbClusterService, auditLogService); + doPost("/api/customer", customer) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Customer title should be specified"))); + .andExpect(statusReason(containsString(msgError))); + + testNotifyEntityError(customer, savedTenant.getId(), + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError + "!")); } @Test public void testSaveCustomerWithInvalidEmail() throws Exception { Customer customer = new Customer(); + String msgError = "Invalid email address format 'invalid@mail'"; customer.setTitle("My customer"); customer.setEmail("invalid@mail"); @@ -259,10 +274,10 @@ public abstract class BaseCustomerControllerTest extends AbstractControllerTest doPost("/api/customer", customer) .andExpect(status().isBadRequest()) - .andExpect(statusReason(containsString("Invalid email address format 'invalid@mail'"))); + .andExpect(statusReason(containsString(msgError))); testNotifyEntityError(customer, savedTenant.getId(), - tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException("")); + tenantAdmin.getId(), tenantAdmin.getEmail(), ActionType.ADDED, new DataValidationException(msgError + "!")); } @Test From 605c32123f39fb5e4a56311d8278d95cc30fff0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Kwakernaak?= <58462885+andre-aktivconsultancy@users.noreply.github.com> Date: Thu, 23 Dec 2021 10:55:20 +0100 Subject: [PATCH 78/86] ensure postgres database is always started The Postgres database would only get started on first launch. When starting a second time e.g. after a `docker-compose down` and `docker-compose up`, the database was not started resulting in a failure when ThingsBoard is starting. (cherry picked from commit 7d5153f52ee4033c8a7ffab0a678950122b982eb) --- msa/tb/docker-postgres/start-db.sh | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/msa/tb/docker-postgres/start-db.sh b/msa/tb/docker-postgres/start-db.sh index ff2805feab..def5165f7a 100644 --- a/msa/tb/docker-postgres/start-db.sh +++ b/msa/tb/docker-postgres/start-db.sh @@ -22,14 +22,22 @@ PG_CTL=$(find /usr/lib/postgresql/ -name pg_ctl) if [ ! -d ${PGDATA} ]; then mkdir -p ${PGDATA} ${PG_CTL} initdb +else + ${PG_CTL} start fi exec setsid nohup postgres >> ${PGLOG}/postgres.log 2>&1 & if [ ! -f ${firstlaunch} ]; then sleep 2 - while ! psql -U ${pkg.user} -d postgres -c "CREATE DATABASE thingsboard" + while ! psql -U thingsboard -d postgres -c "CREATE DATABASE thingsboard" do sleep 1 done -fi \ No newline at end of file +else + until pg_isready --dbname thingsboard --quiet + do + sleep 1 + echo "Waiting for db" + done +fi From 4e0e1d3caedb2884fbe7b0af8d9907d8847ed52d Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Tue, 14 Jun 2022 19:16:38 +0300 Subject: [PATCH 79/86] Postgres startup script improved. will wait for postgres is ready about 300+ seconds. Postgres may do some recovery stuff on startup. --- msa/tb/docker-cassandra/start-db.sh | 7 +++++++ msa/tb/docker-postgres/start-db.sh | 9 ++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/msa/tb/docker-cassandra/start-db.sh b/msa/tb/docker-cassandra/start-db.sh index 92423de9a8..8f8e4a7c35 100644 --- a/msa/tb/docker-cassandra/start-db.sh +++ b/msa/tb/docker-cassandra/start-db.sh @@ -32,6 +32,13 @@ if [ ! -f ${firstlaunch} ]; then do sleep 1 done +else + RETRIES="${PG_ISREADY_RETRIES:-300}" + until pg_isready -U ${pkg.user} -d thingsboard --quiet || [ $RETRIES -eq 0 ] + do + echo "Connecting to Postgres, $((RETRIES--)) attempts left..." + sleep 1 + done fi cassandra_data_dir=${CASSANDRA_DATA} diff --git a/msa/tb/docker-postgres/start-db.sh b/msa/tb/docker-postgres/start-db.sh index def5165f7a..0962968222 100644 --- a/msa/tb/docker-postgres/start-db.sh +++ b/msa/tb/docker-postgres/start-db.sh @@ -22,22 +22,21 @@ PG_CTL=$(find /usr/lib/postgresql/ -name pg_ctl) if [ ! -d ${PGDATA} ]; then mkdir -p ${PGDATA} ${PG_CTL} initdb -else - ${PG_CTL} start fi exec setsid nohup postgres >> ${PGLOG}/postgres.log 2>&1 & if [ ! -f ${firstlaunch} ]; then sleep 2 - while ! psql -U thingsboard -d postgres -c "CREATE DATABASE thingsboard" + while ! psql -U ${pkg.user} -d postgres -c "CREATE DATABASE thingsboard" do sleep 1 done else - until pg_isready --dbname thingsboard --quiet + RETRIES="${PG_ISREADY_RETRIES:-300}" + until pg_isready -U ${pkg.user} -d thingsboard --quiet || [ $RETRIES -eq 0 ] do + echo "Connecting to Postgres, $((RETRIES--)) attempts left..." sleep 1 - echo "Waiting for db" done fi From 92818934aba5e73d23a6bfd5e2bfc64d5d1969f8 Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Tue, 14 Jun 2022 22:40:01 +0300 Subject: [PATCH 80/86] Postgres startup script improved, Install db script improved. First launch file writes only ofter success install. More verbosity added during Postgresql startup --- msa/tb/docker-cassandra/start-db.sh | 26 +++++++++++++------------- msa/tb/docker-postgres/start-db.sh | 26 +++++++++++++------------- msa/tb/docker/install-tb.sh | 2 ++ msa/tb/docker/start-tb.sh | 17 ++++++++++------- 4 files changed, 38 insertions(+), 33 deletions(-) diff --git a/msa/tb/docker-cassandra/start-db.sh b/msa/tb/docker-cassandra/start-db.sh index 8f8e4a7c35..d42281d155 100644 --- a/msa/tb/docker-cassandra/start-db.sh +++ b/msa/tb/docker-cassandra/start-db.sh @@ -24,23 +24,23 @@ if [ ! -d ${PGDATA} ]; then ${PG_CTL} initdb fi -exec setsid nohup postgres >> ${PGLOG}/postgres.log 2>&1 & +echo "Starting Postgresql..." +${PG_CTL} start + +RETRIES="${PG_ISREADY_RETRIES:-300}" +until pg_isready -U ${pkg.user} -d postgres --quiet || [ $RETRIES -eq 0 ] +do + echo "Connecting to Postgres, $((RETRIES--)) attempts left..." + sleep 1 +done if [ ! -f ${firstlaunch} ]; then - sleep 2 - while ! psql -U ${pkg.user} -d postgres -c "CREATE DATABASE thingsboard" - do - sleep 1 - done -else - RETRIES="${PG_ISREADY_RETRIES:-300}" - until pg_isready -U ${pkg.user} -d thingsboard --quiet || [ $RETRIES -eq 0 ] - do - echo "Connecting to Postgres, $((RETRIES--)) attempts left..." - sleep 1 - done + echo "Creating database..." + psql -U ${pkg.user} -d postgres -c "CREATE DATABASE thingsboard" fi +echo "Postgresql is ready" + cassandra_data_dir=${CASSANDRA_DATA} cassandra_data_link=/var/lib/cassandra diff --git a/msa/tb/docker-postgres/start-db.sh b/msa/tb/docker-postgres/start-db.sh index 0962968222..917287f35c 100644 --- a/msa/tb/docker-postgres/start-db.sh +++ b/msa/tb/docker-postgres/start-db.sh @@ -24,19 +24,19 @@ if [ ! -d ${PGDATA} ]; then ${PG_CTL} initdb fi -exec setsid nohup postgres >> ${PGLOG}/postgres.log 2>&1 & +echo "Starting Postgresql..." +${PG_CTL} start + +RETRIES="${PG_ISREADY_RETRIES:-300}" +until pg_isready -U ${pkg.user} -d postgres --quiet || [ $RETRIES -eq 0 ] +do + echo "Connecting to Postgres, $((RETRIES--)) attempts left..." + sleep 1 +done if [ ! -f ${firstlaunch} ]; then - sleep 2 - while ! psql -U ${pkg.user} -d postgres -c "CREATE DATABASE thingsboard" - do - sleep 1 - done -else - RETRIES="${PG_ISREADY_RETRIES:-300}" - until pg_isready -U ${pkg.user} -d thingsboard --quiet || [ $RETRIES -eq 0 ] - do - echo "Connecting to Postgres, $((RETRIES--)) attempts left..." - sleep 1 - done + echo "Creating database..." + psql -U ${pkg.user} -d postgres -c "CREATE DATABASE thingsboard" fi + +echo "Postgresql is ready" \ No newline at end of file diff --git a/msa/tb/docker/install-tb.sh b/msa/tb/docker/install-tb.sh index ff9ae7f496..3395e63c84 100644 --- a/msa/tb/docker/install-tb.sh +++ b/msa/tb/docker/install-tb.sh @@ -46,6 +46,8 @@ source "${CONF_FOLDER}/${configfile}" echo "Starting ThingsBoard installation ..." +set -e + java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardInstallApplication \ -Dinstall.load_demo=${loadDemo} \ -Dspring.jpa.hibernate.ddl-auto=none \ diff --git a/msa/tb/docker/start-tb.sh b/msa/tb/docker/start-tb.sh index 5c3b17fb72..30a16413b6 100755 --- a/msa/tb/docker/start-tb.sh +++ b/msa/tb/docker/start-tb.sh @@ -25,15 +25,18 @@ firstlaunch=${DATA_FOLDER}/.firstlaunch source "${CONF_FOLDER}/${configfile}" if [ ! -f ${firstlaunch} ]; then - install-tb.sh --loadDemo - touch ${firstlaunch} + install-tb.sh --loadDemo && touch ${firstlaunch} fi -echo "Starting ThingsBoard ..." +if [ -f ${firstlaunch} ]; then + echo "Starting ThingsBoard ..." -java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardServerApplication \ - -Dspring.jpa.hibernate.ddl-auto=none \ - -Dlogging.config=${CONF_FOLDER}/logback.xml \ - org.springframework.boot.loader.PropertiesLauncher + java -cp ${jarfile} $JAVA_OPTS -Dloader.main=org.thingsboard.server.ThingsboardServerApplication \ + -Dspring.jpa.hibernate.ddl-auto=none \ + -Dlogging.config=${CONF_FOLDER}/logback.xml \ + org.springframework.boot.loader.PropertiesLauncher +else + echo "ERROR: ThingsBoard is not installed" +fi stop-db.sh \ No newline at end of file From 812a12039306d2441d784345c95f03dab126ae0f Mon Sep 17 00:00:00 2001 From: Vladyslav_Prykhodko Date: Wed, 15 Jun 2022 12:07:08 +0300 Subject: [PATCH 81/86] UI: Updated version node in pkg script --- msa/js-executor/package.json | 2 +- msa/web-ui/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msa/js-executor/package.json b/msa/js-executor/package.json index d1df447072..686e1cad7d 100644 --- a/msa/js-executor/package.json +++ b/msa/js-executor/package.json @@ -6,7 +6,7 @@ "main": "server.js", "bin": "server.js", "scripts": { - "pkg": "pkg -t node12-linux-x64,node12-win-x64 --out-path ./target . && node install.js", + "pkg": "pkg -t node16-linux-x64,node16-win-x64 --out-path ./target . && node install.js", "test": "echo \"Error: no test specified\" && exit 1", "start": "nodemon server.js", "start-prod": "NODE_ENV=production nodemon server.js" diff --git a/msa/web-ui/package.json b/msa/web-ui/package.json index 81e0663613..4824bcc165 100644 --- a/msa/web-ui/package.json +++ b/msa/web-ui/package.json @@ -6,7 +6,7 @@ "main": "server.js", "bin": "server.js", "scripts": { - "pkg": "pkg -t node12-linux-x64,node12-win-x64 --out-path ./target . && node install.js", + "pkg": "pkg -t node16-linux-x64,node16-win-x64 --out-path ./target . && node install.js", "test": "echo \"Error: no test specified\" && exit 1", "start": "WEB_FOLDER=./target/web nodemon server.js", "start-prod": "NODE_ENV=production nodemon server.js" From 835e8d5d1eb1d8e430655858f8e255421e482f18 Mon Sep 17 00:00:00 2001 From: nickAS21 Date: Wed, 15 Jun 2022 12:57:14 +0300 Subject: [PATCH 82/86] refactoring: commit4 --- .../server/controller/AlarmController.java | 2 +- .../DefaultTbNotificationEntityService.java | 24 +++++++++++++++++-- .../entitiy/alarm/DefaultTbAlarmService.java | 10 ++++---- .../service/entitiy/alarm/TbAlarmService.java | 3 +-- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java index 2651277ccc..939e9da8a0 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AlarmController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AlarmController.java @@ -147,7 +147,7 @@ public class AlarmController extends BaseController { try { AlarmId alarmId = new AlarmId(toUUID(strAlarmId)); Alarm alarm = checkAlarmId(alarmId, Operation.WRITE); - return tbAlarmService.delete(alarm, getCurrentUser().getCustomerId(), getCurrentUser()); + return tbAlarmService.delete(alarm, getCurrentUser()); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java index 707747ae91..c7e4f2cd0b 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/DefaultTbNotificationEntityService.java @@ -52,7 +52,6 @@ import org.thingsboard.server.service.gateway_device.GatewayNotificationsService import org.thingsboard.server.service.security.model.SecurityUser; import java.util.List; -import java.util.Locale; @Slf4j @Service @@ -337,6 +336,27 @@ public class DefaultTbNotificationEntityService implements TbNotificationEntityS } public static EdgeEventActionType edgeTypeByActionType(ActionType actionType) { - return EdgeEventActionType.valueOf(actionType.toString().toUpperCase(Locale.ENGLISH)); + switch (actionType) { + case ADDED: + return EdgeEventActionType.ADDED; + case UPDATED: + return EdgeEventActionType.UPDATED; + case ALARM_ACK: + return EdgeEventActionType.ALARM_ACK; + case ALARM_CLEAR: + return EdgeEventActionType.ALARM_CLEAR; + case DELETED: + return EdgeEventActionType.DELETED; + case RELATION_ADD_OR_UPDATE: + return EdgeEventActionType.RELATION_ADD_OR_UPDATE; + case RELATION_DELETED: + return EdgeEventActionType.RELATION_DELETED; + case ASSIGNED_TO_EDGE: + return EdgeEventActionType.ASSIGNED_TO_EDGE; + case UNASSIGNED_FROM_EDGE: + return EdgeEventActionType.UNASSIGNED_FROM_EDGE; + default: + return null; + } } } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java index 305fda2b2b..4930f54a5d 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/DefaultTbAlarmService.java @@ -23,7 +23,6 @@ import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.alarm.AlarmStatus; import org.thingsboard.server.common.data.audit.ActionType; import org.thingsboard.server.common.data.exception.ThingsboardException; -import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.common.data.id.EdgeId; import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.queue.util.TbCoreComponent; @@ -78,13 +77,12 @@ public class DefaultTbAlarmService extends AbstractTbEntityService implements Tb } @Override - public Boolean delete(Alarm alarm, CustomerId customerId, SecurityUser user) throws ThingsboardException { - TenantId tenantId = alarm.getTenantId(); + public Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException { try { - List relatedEdgeIds = findRelatedEdgeIds(tenantId, alarm.getOriginator()); - notificationEntityService.notifyDeleteAlarm(tenantId, alarm, alarm.getOriginator(), customerId, + List relatedEdgeIds = findRelatedEdgeIds(user.getTenantId(), alarm.getOriginator()); + notificationEntityService.notifyDeleteAlarm(user.getTenantId(), alarm, alarm.getOriginator(), user.getCustomerId(), relatedEdgeIds, user, JacksonUtil.OBJECT_MAPPER.writeValueAsString(alarm)); - return alarmService.deleteAlarm(tenantId, alarm.getId()).isSuccessful(); + return alarmService.deleteAlarm(user.getTenantId(), alarm.getId()).isSuccessful(); } catch (Exception e) { throw handleException(e); } diff --git a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java index f17fcb3b70..7a6d7f6a81 100644 --- a/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java +++ b/application/src/main/java/org/thingsboard/server/service/entitiy/alarm/TbAlarmService.java @@ -17,7 +17,6 @@ package org.thingsboard.server.service.entitiy.alarm; import org.thingsboard.server.common.data.alarm.Alarm; import org.thingsboard.server.common.data.exception.ThingsboardException; -import org.thingsboard.server.common.data.id.CustomerId; import org.thingsboard.server.service.security.model.SecurityUser; public interface TbAlarmService { @@ -28,5 +27,5 @@ public interface TbAlarmService { void clear(Alarm alarm, SecurityUser user) throws ThingsboardException; - Boolean delete(Alarm alarm, CustomerId customerId, SecurityUser user) throws ThingsboardException; + Boolean delete(Alarm alarm, SecurityUser user) throws ThingsboardException; } From c4bdee92dbc0d04054a71f95f754ccb5278e7e69 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Wed, 15 Jun 2022 14:04:13 +0300 Subject: [PATCH 83/86] PSQL annotation and dialect cleanup. --- ...va => SqlEntityDatabaseSchemaService.java} | 6 +- ...e.java => SqlTsDatabaseSchemaService.java} | 6 +- ....java => SqlTsDatabaseUpgradeService.java} | 4 +- .../TimescaleTsDatabaseSchemaService.java | 6 - .../TimescaleTsDatabaseUpgradeService.java | 2 - .../src/main/resources/thingsboard.yml | 3 - ...> SqlEntityDatabaseSchemaServiceTest.java} | 16 +-- .../thingsboard/server/dao/util/HsqlDao.java | 26 ---- .../thingsboard/server/dao/util/PsqlDao.java | 26 ---- .../server/dao/util/PsqlTsLatestAnyDao.java | 27 ---- .../server/dao/HsqlTsLatestDaoConfig.java | 37 ----- .../server/dao/PsqlTsDaoConfig.java | 37 ----- ...qlTsDaoConfig.java => SqlTsDaoConfig.java} | 8 +- ...oConfig.java => SqlTsLatestDaoConfig.java} | 8 +- .../server/dao/TimescaleDaoConfig.java | 2 - .../dao/TimescaleTsLatestDaoConfig.java | 4 +- .../HsqlAttributesInsertRepository.java | 76 ---------- ...ava => SqlAttributesInsertRepository.java} | 4 +- ...qlComponentDescriptorInsertRepository.java | 65 --------- ...lComponentDescriptorInsertRepository.java} | 4 +- .../sql/edge/EdgeEventInsertRepository.java | 3 +- .../dao/sql/event/EventInsertRepository.java | 2 - ...ry.java => SqlEventCleanupRepository.java} | 4 +- .../HsqlRelationInsertRepository.java | 63 --------- ....java => SqlRelationInsertRepository.java} | 4 +- .../dao/sqlts/hsql/JpaHsqlTimeseriesDao.java | 62 -------- .../insert/hsql/HsqlInsertTsRepository.java | 87 ------------ .../hsql/HsqlLatestInsertTsRepository.java | 85 ----------- .../SqlLatestInsertTsRepository.java} | 8 +- .../SqlInsertTsRepository.java} | 6 +- .../SqlPartitioningRepository.java} | 10 +- .../TimescaleInsertTsRepository.java | 2 - .../JpaSqlTimeseriesDao.java} | 32 ++--- .../{PsqlPartition.java => SqlPartition.java} | 4 +- .../server/dao/AbstractDaoServiceTest.java | 2 +- .../server/dao/AbstractJpaDaoTest.java | 2 +- .../server/dao/util/DaoTestUtil.java | 40 ------ .../server/dao/util/SqlDbType.java | 20 --- dao/src/test/resources/nosql-test.properties | 1 - dao/src/test/resources/sql-test.properties | 2 - docker/tb-node.hybrid.env | 1 - docker/tb-node.postgres.env | 1 - msa/tb/docker-cassandra/Dockerfile | 1 - msa/tb/docker-postgres/Dockerfile | 1 - msa/tb/docker-tb/Dockerfile | 61 -------- msa/tb/docker-tb/start-db.sh | 18 --- msa/tb/docker-tb/stop-db.sh | 18 --- msa/tb/pom.xml | 132 +----------------- pom.xml | 6 - 49 files changed, 55 insertions(+), 990 deletions(-) rename application/src/main/java/org/thingsboard/server/service/install/{PsqlEntityDatabaseSchemaService.java => SqlEntityDatabaseSchemaService.java} (88%) rename application/src/main/java/org/thingsboard/server/service/install/{PsqlTsDatabaseSchemaService.java => SqlTsDatabaseSchemaService.java} (85%) rename application/src/main/java/org/thingsboard/server/service/install/{PsqlTsDatabaseUpgradeService.java => SqlTsDatabaseUpgradeService.java} (98%) rename application/src/test/java/org/thingsboard/server/service/install/{PsqlEntityDatabaseSchemaServiceTest.java => SqlEntityDatabaseSchemaServiceTest.java} (66%) delete mode 100644 common/dao-api/src/main/java/org/thingsboard/server/dao/util/HsqlDao.java delete mode 100644 common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlDao.java delete mode 100644 common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/HsqlTsLatestDaoConfig.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/PsqlTsDaoConfig.java rename dao/src/main/java/org/thingsboard/server/dao/{HsqlTsDaoConfig.java => SqlTsDaoConfig.java} (87%) rename dao/src/main/java/org/thingsboard/server/dao/{PsqlTsLatestDaoConfig.java => SqlTsLatestDaoConfig.java} (86%) delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/attributes/HsqlAttributesInsertRepository.java rename dao/src/main/java/org/thingsboard/server/dao/sql/attributes/{PsqlAttributesInsertRepository.java => SqlAttributesInsertRepository.java} (85%) delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/component/HsqlComponentDescriptorInsertRepository.java rename dao/src/main/java/org/thingsboard/server/dao/sql/component/{PsqlComponentDescriptorInsertRepository.java => SqlComponentDescriptorInsertRepository.java} (94%) rename dao/src/main/java/org/thingsboard/server/dao/sql/event/{PsqlEventCleanupRepository.java => SqlEventCleanupRepository.java} (91%) delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/sql/relation/HsqlRelationInsertRepository.java rename dao/src/main/java/org/thingsboard/server/dao/sql/relation/{PsqlRelationInsertRepository.java => SqlRelationInsertRepository.java} (90%) delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/sqlts/hsql/JpaHsqlTimeseriesDao.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/hsql/HsqlInsertTsRepository.java delete mode 100644 dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/hsql/HsqlLatestInsertTsRepository.java rename dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/{psql/PsqlLatestInsertTsRepository.java => sql/SqlLatestInsertTsRepository.java} (96%) rename dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/{psql/PsqlInsertTsRepository.java => sql/SqlInsertTsRepository.java} (93%) rename dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/{psql/PsqlPartitioningRepository.java => sql/SqlPartitioningRepository.java} (80%) rename dao/src/main/java/org/thingsboard/server/dao/sqlts/{psql/JpaPsqlTimeseriesDao.java => sql/JpaSqlTimeseriesDao.java} (85%) rename dao/src/main/java/org/thingsboard/server/dao/timeseries/{PsqlPartition.java => SqlPartition.java} (92%) delete mode 100644 dao/src/test/java/org/thingsboard/server/dao/util/DaoTestUtil.java delete mode 100644 dao/src/test/java/org/thingsboard/server/dao/util/SqlDbType.java delete mode 100644 msa/tb/docker-tb/Dockerfile delete mode 100644 msa/tb/docker-tb/start-db.sh delete mode 100644 msa/tb/docker-tb/stop-db.sh diff --git a/application/src/main/java/org/thingsboard/server/service/install/PsqlEntityDatabaseSchemaService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlEntityDatabaseSchemaService.java similarity index 88% rename from application/src/main/java/org/thingsboard/server/service/install/PsqlEntityDatabaseSchemaService.java rename to application/src/main/java/org/thingsboard/server/service/install/SqlEntityDatabaseSchemaService.java index eaa9d708be..7ae155402a 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/PsqlEntityDatabaseSchemaService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlEntityDatabaseSchemaService.java @@ -18,19 +18,17 @@ package org.thingsboard.server.service.install; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; -import org.thingsboard.server.dao.util.PsqlDao; @Service -@PsqlDao @Profile("install") @Slf4j -public class PsqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaService +public class SqlEntityDatabaseSchemaService extends SqlAbstractDatabaseSchemaService implements EntityDatabaseSchemaService { public static final String SCHEMA_ENTITIES_SQL = "schema-entities.sql"; public static final String SCHEMA_ENTITIES_IDX_SQL = "schema-entities-idx.sql"; public static final String SCHEMA_ENTITIES_IDX_PSQL_ADDON_SQL = "schema-entities-idx-psql-addon.sql"; - public PsqlEntityDatabaseSchemaService() { + public SqlEntityDatabaseSchemaService() { super(SCHEMA_ENTITIES_SQL, SCHEMA_ENTITIES_IDX_SQL); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseSchemaService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseSchemaService.java similarity index 85% rename from application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseSchemaService.java rename to application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseSchemaService.java index 0e7cff7d63..f3ede624ff 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseSchemaService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseSchemaService.java @@ -18,19 +18,17 @@ package org.thingsboard.server.service.install; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.SqlTsDao; @Service @SqlTsDao -@PsqlDao @Profile("install") -public class PsqlTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaService implements TsDatabaseSchemaService { +public class SqlTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaService implements TsDatabaseSchemaService { @Value("${sql.postgres.ts_key_value_partitioning:MONTHS}") private String partitionType; - public PsqlTsDatabaseSchemaService() { + public SqlTsDatabaseSchemaService() { super("schema-ts-psql.sql", null); } diff --git a/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java similarity index 98% rename from application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java rename to application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java index 55fa73fb27..c1d41a6f6e 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/PsqlTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/SqlTsDatabaseUpgradeService.java @@ -21,7 +21,6 @@ import org.apache.commons.lang3.SystemUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.SqlTsDao; import java.io.File; @@ -36,8 +35,7 @@ import java.sql.DriverManager; @Profile("install") @Slf4j @SqlTsDao -@PsqlDao -public class PsqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeService implements DatabaseTsUpgradeService { +public class SqlTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeService implements DatabaseTsUpgradeService { @Value("${sql.postgres.ts_key_value_partitioning:MONTHS}") private String partitionType; diff --git a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseSchemaService.java b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseSchemaService.java index a0257ba0e4..409498cfd3 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseSchemaService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseSchemaService.java @@ -19,16 +19,10 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.TimescaleDBTsDao; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - @Service @TimescaleDBTsDao -@PsqlDao @Profile("install") @Slf4j public class TimescaleTsDatabaseSchemaService extends SqlAbstractDatabaseSchemaService implements TsDatabaseSchemaService { diff --git a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java index 1834ca6552..245dc4503d 100644 --- a/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java +++ b/application/src/main/java/org/thingsboard/server/service/install/TimescaleTsDatabaseUpgradeService.java @@ -22,7 +22,6 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Profile; import org.springframework.stereotype.Service; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.TimescaleDBTsDao; import java.io.File; @@ -37,7 +36,6 @@ import java.sql.DriverManager; @Profile("install") @Slf4j @TimescaleDBTsDao -@PsqlDao public class TimescaleTsDatabaseUpgradeService extends AbstractSqlTsDatabaseUpgradeService implements DatabaseTsUpgradeService { @Value("${sql.timescale.chunk_time_interval:86400000}") diff --git a/application/src/main/resources/thingsboard.yml b/application/src/main/resources/thingsboard.yml index 4f11b6880c..9f6f3099ef 100644 --- a/application/src/main/resources/thingsboard.yml +++ b/application/src/main/resources/thingsboard.yml @@ -176,8 +176,6 @@ database: ts_latest: type: "${DATABASE_TS_LATEST_TYPE:sql}" # cassandra, sql, or timescale (for hybrid mode, DATABASE_TS_TYPE value should be cassandra, or timescale) -# note: timescale works only with postgreSQL database for DATABASE_ENTITIES_TYPE. - # Cassandra driver configuration parameters cassandra: # Thingsboard cluster name @@ -535,7 +533,6 @@ spring: open-in-view: "false" hibernate: ddl-auto: "none" - database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.PostgreSQL10Dialect}" datasource: driverClassName: "${SPRING_DRIVER_CLASS_NAME:org.postgresql.Driver}" url: "${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/thingsboard}" diff --git a/application/src/test/java/org/thingsboard/server/service/install/PsqlEntityDatabaseSchemaServiceTest.java b/application/src/test/java/org/thingsboard/server/service/install/SqlEntityDatabaseSchemaServiceTest.java similarity index 66% rename from application/src/test/java/org/thingsboard/server/service/install/PsqlEntityDatabaseSchemaServiceTest.java rename to application/src/test/java/org/thingsboard/server/service/install/SqlEntityDatabaseSchemaServiceTest.java index eaea437bc7..07a32d5cdc 100644 --- a/application/src/test/java/org/thingsboard/server/service/install/PsqlEntityDatabaseSchemaServiceTest.java +++ b/application/src/test/java/org/thingsboard/server/service/install/SqlEntityDatabaseSchemaServiceTest.java @@ -23,31 +23,31 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; -public class PsqlEntityDatabaseSchemaServiceTest { +public class SqlEntityDatabaseSchemaServiceTest { @Test public void givenPsqlDbSchemaService_whenCreateDatabaseSchema_thenVerifyPsqlIndexSpecificCall() throws Exception { - PsqlEntityDatabaseSchemaService service = spy(new PsqlEntityDatabaseSchemaService()); + SqlEntityDatabaseSchemaService service = spy(new SqlEntityDatabaseSchemaService()); willDoNothing().given(service).executeQueryFromFile(anyString()); service.createDatabaseSchema(); verify(service, times(1)).createDatabaseIndexes(); - verify(service, times(1)).executeQueryFromFile(PsqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_SQL); - verify(service, times(1)).executeQueryFromFile(PsqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_IDX_SQL); - verify(service, times(1)).executeQueryFromFile(PsqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_IDX_PSQL_ADDON_SQL); + verify(service, times(1)).executeQueryFromFile(SqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_SQL); + verify(service, times(1)).executeQueryFromFile(SqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_IDX_SQL); + verify(service, times(1)).executeQueryFromFile(SqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_IDX_PSQL_ADDON_SQL); verify(service, times(3)).executeQueryFromFile(anyString()); } @Test public void givenPsqlDbSchemaService_whenCreateDatabaseIndexes_thenVerifyPsqlIndexSpecificCall() throws Exception { - PsqlEntityDatabaseSchemaService service = spy(new PsqlEntityDatabaseSchemaService()); + SqlEntityDatabaseSchemaService service = spy(new SqlEntityDatabaseSchemaService()); willDoNothing().given(service).executeQueryFromFile(anyString()); service.createDatabaseIndexes(); - verify(service, times(1)).executeQueryFromFile(PsqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_IDX_SQL); - verify(service, times(1)).executeQueryFromFile(PsqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_IDX_PSQL_ADDON_SQL); + verify(service, times(1)).executeQueryFromFile(SqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_IDX_SQL); + verify(service, times(1)).executeQueryFromFile(SqlEntityDatabaseSchemaService.SCHEMA_ENTITIES_IDX_PSQL_ADDON_SQL); verify(service, times(2)).executeQueryFromFile(anyString()); } diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/HsqlDao.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/util/HsqlDao.java deleted file mode 100644 index 949c8d3569..0000000000 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/HsqlDao.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -@ConditionalOnProperty(prefix = "spring.jpa", value = "database-platform", havingValue = "org.hibernate.dialect.HSQLDialect") -public @interface HsqlDao { -} \ No newline at end of file diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlDao.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlDao.java deleted file mode 100644 index ba30f8975a..0000000000 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlDao.java +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -@ConditionalOnProperty(prefix = "spring.jpa", value = "database-platform", havingValue = "org.hibernate.dialect.PostgreSQL10Dialect") -public @interface PsqlDao { -} \ No newline at end of file diff --git a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java b/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java deleted file mode 100644 index 368f550c14..0000000000 --- a/common/dao-api/src/main/java/org/thingsboard/server/dao/util/PsqlTsLatestAnyDao.java +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -@Retention(RetentionPolicy.RUNTIME) -@ConditionalOnExpression("('${database.ts_latest.type}'=='sql' || '${database.ts_latest.type}'=='timescale') " + - "&& '${spring.jpa.database-platform}'=='org.hibernate.dialect.PostgreSQL10Dialect'") -public @interface PsqlTsLatestAnyDao { -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/HsqlTsLatestDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/HsqlTsLatestDaoConfig.java deleted file mode 100644 index 2012ca5a82..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/HsqlTsLatestDaoConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao; - -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.thingsboard.server.dao.util.HsqlDao; -import org.thingsboard.server.dao.util.SqlTsLatestDao; -import org.thingsboard.server.dao.util.TbAutoConfiguration; - -@Configuration -@TbAutoConfiguration -@ComponentScan({"org.thingsboard.server.dao.sqlts.hsql"}) -@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.insert.latest.hsql", "org.thingsboard.server.dao.sqlts.latest"}) -@EntityScan({"org.thingsboard.server.dao.model.sqlts.latest"}) -@EnableTransactionManagement -@SqlTsLatestDao -@HsqlDao -public class HsqlTsLatestDaoConfig { - -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/PsqlTsDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/PsqlTsDaoConfig.java deleted file mode 100644 index 06c8cf4a5b..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/PsqlTsDaoConfig.java +++ /dev/null @@ -1,37 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao; - -import org.springframework.boot.autoconfigure.domain.EntityScan; -import org.springframework.context.annotation.ComponentScan; -import org.springframework.context.annotation.Configuration; -import org.springframework.data.jpa.repository.config.EnableJpaRepositories; -import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.thingsboard.server.dao.util.PsqlDao; -import org.thingsboard.server.dao.util.SqlTsDao; -import org.thingsboard.server.dao.util.TbAutoConfiguration; - -@Configuration -@TbAutoConfiguration -@ComponentScan({"org.thingsboard.server.dao.sqlts.psql", "org.thingsboard.server.dao.sqlts.insert.psql"}) -@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.ts", "org.thingsboard.server.dao.sqlts.insert.psql"}) -@EntityScan({"org.thingsboard.server.dao.model.sqlts.ts"}) -@EnableTransactionManagement -@PsqlDao -@SqlTsDao -public class PsqlTsDaoConfig { - -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/HsqlTsDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/SqlTsDaoConfig.java similarity index 87% rename from dao/src/main/java/org/thingsboard/server/dao/HsqlTsDaoConfig.java rename to dao/src/main/java/org/thingsboard/server/dao/SqlTsDaoConfig.java index 932312f96e..cd1401d60c 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/HsqlTsDaoConfig.java +++ b/dao/src/main/java/org/thingsboard/server/dao/SqlTsDaoConfig.java @@ -20,18 +20,16 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.thingsboard.server.dao.util.HsqlDao; import org.thingsboard.server.dao.util.SqlTsDao; import org.thingsboard.server.dao.util.TbAutoConfiguration; @Configuration @TbAutoConfiguration -@ComponentScan({"org.thingsboard.server.dao.sqlts.hsql"}) -@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.ts", "org.thingsboard.server.dao.sqlts.insert.hsql"}) +@ComponentScan({"org.thingsboard.server.dao.sqlts.sql", "org.thingsboard.server.dao.sqlts.insert.sql"}) +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.ts", "org.thingsboard.server.dao.sqlts.insert.sql"}) @EntityScan({"org.thingsboard.server.dao.model.sqlts.ts"}) @EnableTransactionManagement @SqlTsDao -@HsqlDao -public class HsqlTsDaoConfig { +public class SqlTsDaoConfig { } diff --git a/dao/src/main/java/org/thingsboard/server/dao/PsqlTsLatestDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/SqlTsLatestDaoConfig.java similarity index 86% rename from dao/src/main/java/org/thingsboard/server/dao/PsqlTsLatestDaoConfig.java rename to dao/src/main/java/org/thingsboard/server/dao/SqlTsLatestDaoConfig.java index 9d8d625e78..4fe4aaed43 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/PsqlTsLatestDaoConfig.java +++ b/dao/src/main/java/org/thingsboard/server/dao/SqlTsLatestDaoConfig.java @@ -20,18 +20,16 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.SqlTsLatestDao; import org.thingsboard.server.dao.util.TbAutoConfiguration; @Configuration @TbAutoConfiguration -@ComponentScan({"org.thingsboard.server.dao.sqlts.psql"}) -@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.insert.latest.psql", "org.thingsboard.server.dao.sqlts.latest"}) +@ComponentScan({"org.thingsboard.server.dao.sqlts.sql"}) +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.insert.latest.sql", "org.thingsboard.server.dao.sqlts.latest"}) @EntityScan({"org.thingsboard.server.dao.model.sqlts.latest"}) @EnableTransactionManagement @SqlTsLatestDao -@PsqlDao -public class PsqlTsLatestDaoConfig { +public class SqlTsLatestDaoConfig { } diff --git a/dao/src/main/java/org/thingsboard/server/dao/TimescaleDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/TimescaleDaoConfig.java index 0e4d4750f9..6b11ff8005 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/TimescaleDaoConfig.java +++ b/dao/src/main/java/org/thingsboard/server/dao/TimescaleDaoConfig.java @@ -20,7 +20,6 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.TbAutoConfiguration; import org.thingsboard.server.dao.util.TimescaleDBTsDao; @@ -31,7 +30,6 @@ import org.thingsboard.server.dao.util.TimescaleDBTsDao; @EntityScan({"org.thingsboard.server.dao.model.sqlts.timescale"}) @EnableTransactionManagement @TimescaleDBTsDao -@PsqlDao public class TimescaleDaoConfig { } diff --git a/dao/src/main/java/org/thingsboard/server/dao/TimescaleTsLatestDaoConfig.java b/dao/src/main/java/org/thingsboard/server/dao/TimescaleTsLatestDaoConfig.java index 02082085ba..3fd452a1b1 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/TimescaleTsLatestDaoConfig.java +++ b/dao/src/main/java/org/thingsboard/server/dao/TimescaleTsLatestDaoConfig.java @@ -20,18 +20,16 @@ import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.transaction.annotation.EnableTransactionManagement; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.TbAutoConfiguration; import org.thingsboard.server.dao.util.TimescaleDBTsLatestDao; @Configuration @TbAutoConfiguration @ComponentScan({"org.thingsboard.server.dao.sqlts.timescale"}) -@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.insert.latest.psql", "org.thingsboard.server.dao.sqlts.latest"}) +@EnableJpaRepositories({"org.thingsboard.server.dao.sqlts.insert.latest.sql", "org.thingsboard.server.dao.sqlts.latest"}) @EntityScan({"org.thingsboard.server.dao.model.sqlts.latest"}) @EnableTransactionManagement @TimescaleDBTsLatestDao -@PsqlDao public class TimescaleTsLatestDaoConfig { } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/HsqlAttributesInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/HsqlAttributesInsertRepository.java deleted file mode 100644 index 24465e0742..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/HsqlAttributesInsertRepository.java +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.sql.attributes; - -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; -import org.thingsboard.server.dao.model.sql.AttributeKvEntity; -import org.thingsboard.server.dao.util.HsqlDao; - -import java.sql.Types; -import java.util.List; - -@HsqlDao -@Repository -@Transactional -public class HsqlAttributesInsertRepository extends AttributeKvInsertRepository { - - private static final String INSERT_OR_UPDATE = - "MERGE INTO attribute_kv USING(VALUES ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) " + - "A (entity_type, entity_id, attribute_type, attribute_key, str_v, long_v, dbl_v, bool_v, json_v, last_update_ts) " + - "ON (attribute_kv.entity_type=A.entity_type " + - "AND attribute_kv.entity_id=A.entity_id " + - "AND attribute_kv.attribute_type=A.attribute_type " + - "AND attribute_kv.attribute_key=A.attribute_key) " + - "WHEN MATCHED THEN UPDATE SET attribute_kv.str_v = A.str_v, attribute_kv.long_v = A.long_v, attribute_kv.dbl_v = A.dbl_v, attribute_kv.bool_v = A.bool_v, attribute_kv.json_v = A.json_v, attribute_kv.last_update_ts = A.last_update_ts " + - "WHEN NOT MATCHED THEN INSERT (entity_type, entity_id, attribute_type, attribute_key, str_v, long_v, dbl_v, bool_v, json_v, last_update_ts) " + - "VALUES (A.entity_type, A.entity_id, A.attribute_type, A.attribute_key, A.str_v, A.long_v, A.dbl_v, A.bool_v, A.json_v, A.last_update_ts)"; - - @Override - protected void saveOrUpdate(List entities) { - entities.forEach(entity -> { - jdbcTemplate.update(INSERT_OR_UPDATE, ps -> { - ps.setString(1, entity.getId().getEntityType().name()); - ps.setObject(2, entity.getId().getEntityId()); - ps.setString(3, entity.getId().getAttributeType()); - ps.setString(4, entity.getId().getAttributeKey()); - ps.setString(5, entity.getStrValue()); - - if (entity.getLongValue() != null) { - ps.setLong(6, entity.getLongValue()); - } else { - ps.setNull(6, Types.BIGINT); - } - - if (entity.getDoubleValue() != null) { - ps.setDouble(7, entity.getDoubleValue()); - } else { - ps.setNull(7, Types.DOUBLE); - } - - if (entity.getBooleanValue() != null) { - ps.setBoolean(8, entity.getBooleanValue()); - } else { - ps.setNull(8, Types.BOOLEAN); - } - - ps.setString(9, entity.getJsonValue()); - - ps.setLong(10, entity.getLastUpdateTs()); - }); - }); - } -} \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/PsqlAttributesInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/SqlAttributesInsertRepository.java similarity index 85% rename from dao/src/main/java/org/thingsboard/server/dao/sql/attributes/PsqlAttributesInsertRepository.java rename to dao/src/main/java/org/thingsboard/server/dao/sql/attributes/SqlAttributesInsertRepository.java index 2b5b53691a..e18f5178a8 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/PsqlAttributesInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/attributes/SqlAttributesInsertRepository.java @@ -17,11 +17,9 @@ package org.thingsboard.server.dao.sql.attributes; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; -import org.thingsboard.server.dao.util.PsqlDao; -@PsqlDao @Repository @Transactional -public class PsqlAttributesInsertRepository extends AttributeKvInsertRepository { +public class SqlAttributesInsertRepository extends AttributeKvInsertRepository { } \ No newline at end of file diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/HsqlComponentDescriptorInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/HsqlComponentDescriptorInsertRepository.java deleted file mode 100644 index e735596de3..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/HsqlComponentDescriptorInsertRepository.java +++ /dev/null @@ -1,65 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.sql.component; - -import org.springframework.stereotype.Repository; -import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity; -import org.thingsboard.server.dao.util.HsqlDao; - -import javax.persistence.Query; - -@HsqlDao -@Repository -public class HsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository { - - private static final String P_KEY_CONFLICT_STATEMENT = "(component_descriptor.id=UUID(I.id))"; - private static final String UNQ_KEY_CONFLICT_STATEMENT = "(component_descriptor.clazz=I.clazz)"; - - private static final String INSERT_OR_UPDATE_ON_P_KEY_CONFLICT = getInsertString(P_KEY_CONFLICT_STATEMENT); - private static final String INSERT_OR_UPDATE_ON_UNQ_KEY_CONFLICT = getInsertString(UNQ_KEY_CONFLICT_STATEMENT); - - @Override - public ComponentDescriptorEntity saveOrUpdate(ComponentDescriptorEntity entity) { - return saveAndGet(entity, INSERT_OR_UPDATE_ON_P_KEY_CONFLICT, INSERT_OR_UPDATE_ON_UNQ_KEY_CONFLICT); - } - - @Override - protected Query getQuery(ComponentDescriptorEntity entity, String query) { - return entityManager.createNativeQuery(query, ComponentDescriptorEntity.class) - .setParameter("id", entity.getUuid().toString()) - .setParameter("created_time", entity.getCreatedTime()) - .setParameter("actions", entity.getActions()) - .setParameter("clazz", entity.getClazz()) - .setParameter("configuration_descriptor", entity.getConfigurationDescriptor().toString()) - .setParameter("name", entity.getName()) - .setParameter("scope", entity.getScope().name()) - .setParameter("search_text", entity.getSearchText()) - .setParameter("type", entity.getType().name()); - } - - @Override - protected ComponentDescriptorEntity doProcessSaveOrUpdate(ComponentDescriptorEntity entity, String query) { - getQuery(entity, query).executeUpdate(); - return entityManager.find(ComponentDescriptorEntity.class, entity.getUuid()); - } - - private static String getInsertString(String conflictStatement) { - return "MERGE INTO component_descriptor USING (VALUES :id, :created_time, :actions, :clazz, :configuration_descriptor, :name, :scope, :search_text, :type) I (id, created_time, actions, clazz, configuration_descriptor, name, scope, search_text, type) ON " - + conflictStatement - + " WHEN MATCHED THEN UPDATE SET component_descriptor.id = UUID(I.id), component_descriptor.actions = I.actions, component_descriptor.clazz = I.clazz, component_descriptor.configuration_descriptor = I.configuration_descriptor, component_descriptor.name = I.name, component_descriptor.scope = I.scope, component_descriptor.search_text = I.search_text, component_descriptor.type = I.type" + - " WHEN NOT MATCHED THEN INSERT (id, created_time, actions, clazz, configuration_descriptor, name, scope, search_text, type) VALUES (UUID(I.id), I.created_time, I.actions, I.clazz, I.configuration_descriptor, I.name, I.scope, I.search_text, I.type)"; - } -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/component/PsqlComponentDescriptorInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java similarity index 94% rename from dao/src/main/java/org/thingsboard/server/dao/sql/component/PsqlComponentDescriptorInsertRepository.java rename to dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java index 1886dd3b35..593cccee2a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/component/PsqlComponentDescriptorInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/component/SqlComponentDescriptorInsertRepository.java @@ -17,11 +17,9 @@ package org.thingsboard.server.dao.sql.component; import org.springframework.stereotype.Repository; import org.thingsboard.server.dao.model.sql.ComponentDescriptorEntity; -import org.thingsboard.server.dao.util.PsqlDao; -@PsqlDao @Repository -public class PsqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository { +public class SqlComponentDescriptorInsertRepository extends AbstractComponentDescriptorInsertRepository { private static final String ID = "id = :id"; private static final String CLAZZ_CLAZZ = "clazz = :clazz"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeEventInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeEventInsertRepository.java index c67aaabbb1..694d68556f 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeEventInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/edge/EdgeEventInsertRepository.java @@ -24,13 +24,12 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import org.thingsboard.server.dao.model.sql.EdgeEventEntity; -import org.thingsboard.server.dao.util.PsqlDao; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; -@PsqlDao + @Repository @Transactional public class EdgeEventInsertRepository { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java index 1f2d4c01be..6234db58da 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/EventInsertRepository.java @@ -25,14 +25,12 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.springframework.transaction.support.TransactionTemplate; import org.thingsboard.server.dao.model.sql.EventEntity; -import org.thingsboard.server.dao.util.PsqlDao; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; import java.util.regex.Pattern; -@PsqlDao @Repository @Transactional public class EventInsertRepository { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/event/PsqlEventCleanupRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/event/SqlEventCleanupRepository.java similarity index 91% rename from dao/src/main/java/org/thingsboard/server/dao/sql/event/PsqlEventCleanupRepository.java rename to dao/src/main/java/org/thingsboard/server/dao/sql/event/SqlEventCleanupRepository.java index 664a148948..6a17f7c740 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/event/PsqlEventCleanupRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/event/SqlEventCleanupRepository.java @@ -18,7 +18,6 @@ package org.thingsboard.server.dao.sql.event; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Repository; import org.thingsboard.server.dao.sql.JpaAbstractDaoListeningExecutorService; -import org.thingsboard.server.dao.util.PsqlDao; import java.sql.Connection; import java.sql.PreparedStatement; @@ -27,9 +26,8 @@ import java.sql.SQLException; import java.util.concurrent.TimeUnit; @Slf4j -@PsqlDao @Repository -public class PsqlEventCleanupRepository extends JpaAbstractDaoListeningExecutorService implements EventCleanupRepository { +public class SqlEventCleanupRepository extends JpaAbstractDaoListeningExecutorService implements EventCleanupRepository { @Override public void cleanupEvents(long regularEventStartTs, long regularEventEndTs, long debugEventStartTs, long debugEventEndTs) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/HsqlRelationInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/HsqlRelationInsertRepository.java deleted file mode 100644 index 5da0a8a2de..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/HsqlRelationInsertRepository.java +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.sql.relation; - -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; -import org.thingsboard.server.dao.model.sql.RelationCompositeKey; -import org.thingsboard.server.dao.model.sql.RelationEntity; -import org.thingsboard.server.dao.util.HsqlDao; - -import javax.persistence.Query; - -@HsqlDao -@Repository -@Transactional -public class HsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository { - - private static final String INSERT_ON_CONFLICT_DO_UPDATE = "MERGE INTO relation USING (VALUES :fromId, :fromType, :toId, :toType, :relationTypeGroup, :relationType, :additionalInfo) R " + - "(from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info) " + - "ON (relation.from_id = UUID(R.from_id) AND relation.from_type = R.from_type AND relation.relation_type_group = R.relation_type_group AND relation.relation_type = R.relation_type AND relation.to_id = UUID(R.to_id) AND relation.to_type = R.to_type) " + - "WHEN MATCHED THEN UPDATE SET relation.additional_info = R.additional_info " + - "WHEN NOT MATCHED THEN INSERT (from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info) VALUES (UUID(R.from_id), R.from_type, UUID(R.to_id), R.to_type, R.relation_type_group, R.relation_type, R.additional_info)"; - - protected Query getQuery(RelationEntity entity, String query) { - Query nativeQuery = entityManager.createNativeQuery(query, RelationEntity.class); - if (entity.getAdditionalInfo() == null) { - nativeQuery.setParameter("additionalInfo", null); - } else { - nativeQuery.setParameter("additionalInfo", entity.getAdditionalInfo().toString()); - } - return nativeQuery - .setParameter("fromId", entity.getFromId().toString()) - .setParameter("fromType", entity.getFromType()) - .setParameter("toId", entity.getToId().toString()) - .setParameter("toType", entity.getToType()) - .setParameter("relationTypeGroup", entity.getRelationTypeGroup()) - .setParameter("relationType", entity.getRelationType()); - } - - @Override - public RelationEntity saveOrUpdate(RelationEntity entity) { - return processSaveOrUpdate(entity); - } - - @Override - protected RelationEntity processSaveOrUpdate(RelationEntity entity) { - getQuery(entity, INSERT_ON_CONFLICT_DO_UPDATE).executeUpdate(); - return entityManager.find(RelationEntity.class, new RelationCompositeKey(entity.toData())); - } -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/PsqlRelationInsertRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/SqlRelationInsertRepository.java similarity index 90% rename from dao/src/main/java/org/thingsboard/server/dao/sql/relation/PsqlRelationInsertRepository.java rename to dao/src/main/java/org/thingsboard/server/dao/sql/relation/SqlRelationInsertRepository.java index a622d19e6d..23d24588b9 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sql/relation/PsqlRelationInsertRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sql/relation/SqlRelationInsertRepository.java @@ -18,12 +18,10 @@ package org.thingsboard.server.dao.sql.relation; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import org.thingsboard.server.dao.model.sql.RelationEntity; -import org.thingsboard.server.dao.util.PsqlDao; -@PsqlDao @Repository @Transactional -public class PsqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository { +public class SqlRelationInsertRepository extends AbstractRelationInsertRepository implements RelationInsertRepository { private static final String INSERT_ON_CONFLICT_DO_UPDATE = "INSERT INTO relation (from_id, from_type, to_id, to_type, relation_type_group, relation_type, additional_info)" + " VALUES (:fromId, :fromType, :toId, :toType, :relationTypeGroup, :relationType, :additionalInfo) " + diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/hsql/JpaHsqlTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/hsql/JpaHsqlTimeseriesDao.java deleted file mode 100644 index 770c9142d4..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/hsql/JpaHsqlTimeseriesDao.java +++ /dev/null @@ -1,62 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.sqlts.hsql; - -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; -import com.google.common.util.concurrent.MoreExecutors; -import lombok.extern.slf4j.Slf4j; -import org.springframework.stereotype.Component; -import org.thingsboard.server.common.data.id.EntityId; -import org.thingsboard.server.common.data.id.TenantId; -import org.thingsboard.server.common.data.kv.TsKvEntry; -import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; -import org.thingsboard.server.dao.sqlts.AbstractChunkedAggregationTimeseriesDao; -import org.thingsboard.server.dao.timeseries.TimeseriesDao; -import org.thingsboard.server.dao.util.HsqlDao; -import org.thingsboard.server.dao.util.SqlTsDao; - - -@Component -@Slf4j -@SqlTsDao -@HsqlDao -public class JpaHsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDao implements TimeseriesDao { - - @Override - public ListenableFuture save(TenantId tenantId, EntityId entityId, TsKvEntry tsKvEntry, long ttl) { - int dataPointDays = getDataPointDays(tsKvEntry, computeTtl(ttl)); - String strKey = tsKvEntry.getKey(); - Integer keyId = getOrSaveKeyId(strKey); - TsKvEntity entity = new TsKvEntity(); - entity.setEntityId(entityId.getId()); - entity.setTs(tsKvEntry.getTs()); - entity.setKey(keyId); - entity.setStrValue(tsKvEntry.getStrValue().orElse(null)); - entity.setDoubleValue(tsKvEntry.getDoubleValue().orElse(null)); - entity.setLongValue(tsKvEntry.getLongValue().orElse(null)); - entity.setBooleanValue(tsKvEntry.getBooleanValue().orElse(null)); - entity.setJsonValue(tsKvEntry.getJsonValue().orElse(null)); - log.trace("Saving entity: {}", entity); - return Futures.transform(tsQueue.add(entity), v -> dataPointDays, MoreExecutors.directExecutor()); - } - - @Override - public void cleanup(long systemTtl) { - - } - -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/hsql/HsqlInsertTsRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/hsql/HsqlInsertTsRepository.java deleted file mode 100644 index 596c913ed8..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/hsql/HsqlInsertTsRepository.java +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.sqlts.insert.hsql; - -import org.springframework.jdbc.core.BatchPreparedStatementSetter; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; -import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; -import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; -import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; -import org.thingsboard.server.dao.util.HsqlDao; -import org.thingsboard.server.dao.util.SqlTsDao; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; -import java.util.List; - -@SqlTsDao -@HsqlDao -@Repository -@Transactional -public class HsqlInsertTsRepository extends AbstractInsertRepository implements InsertTsRepository { - - private static final String INSERT_OR_UPDATE = - "MERGE INTO ts_kv USING(VALUES ?, ?, ?, ?, ?, ?, ?, ?) " + - "T (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) " + - "ON (ts_kv.entity_id=T.entity_id " + - "AND ts_kv.key=T.key " + - "AND ts_kv.ts=T.ts) " + - "WHEN MATCHED THEN UPDATE SET ts_kv.bool_v = T.bool_v, ts_kv.str_v = T.str_v, ts_kv.long_v = T.long_v, ts_kv.dbl_v = T.dbl_v ,ts_kv.json_v = T.json_v " + - "WHEN NOT MATCHED THEN INSERT (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) " + - "VALUES (T.entity_id, T.key, T.ts, T.bool_v, T.str_v, T.long_v, T.dbl_v, T.json_v);"; - - @Override - public void saveOrUpdate(List entities) { - jdbcTemplate.batchUpdate(INSERT_OR_UPDATE, new BatchPreparedStatementSetter() { - @Override - public void setValues(PreparedStatement ps, int i) throws SQLException { - TsKvEntity tsKvEntity = entities.get(i); - ps.setObject(1, tsKvEntity.getEntityId()); - ps.setInt(2, tsKvEntity.getKey()); - ps.setLong(3, tsKvEntity.getTs()); - - if (tsKvEntity.getBooleanValue() != null) { - ps.setBoolean(4, tsKvEntity.getBooleanValue()); - } else { - ps.setNull(4, Types.BOOLEAN); - } - - ps.setString(5, tsKvEntity.getStrValue()); - - if (tsKvEntity.getLongValue() != null) { - ps.setLong(6, tsKvEntity.getLongValue()); - } else { - ps.setNull(6, Types.BIGINT); - } - - if (tsKvEntity.getDoubleValue() != null) { - ps.setDouble(7, tsKvEntity.getDoubleValue()); - } else { - ps.setNull(7, Types.DOUBLE); - } - - ps.setString(8, tsKvEntity.getJsonValue()); - } - - @Override - public int getBatchSize() { - return entities.size(); - } - }); - } -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/hsql/HsqlLatestInsertTsRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/hsql/HsqlLatestInsertTsRepository.java deleted file mode 100644 index c69bb6b1d5..0000000000 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/hsql/HsqlLatestInsertTsRepository.java +++ /dev/null @@ -1,85 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.sqlts.insert.latest.hsql; - -import org.springframework.jdbc.core.BatchPreparedStatementSetter; -import org.springframework.stereotype.Repository; -import org.springframework.transaction.annotation.Transactional; -import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; -import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; -import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository; -import org.thingsboard.server.dao.util.HsqlDao; -import org.thingsboard.server.dao.util.SqlTsLatestDao; - -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.sql.Types; -import java.util.List; - -@SqlTsLatestDao -@HsqlDao -@Repository -@Transactional -public class HsqlLatestInsertTsRepository extends AbstractInsertRepository implements InsertLatestTsRepository { - - private static final String INSERT_OR_UPDATE = - "MERGE INTO ts_kv_latest USING(VALUES ?, ?, ?, ?, ?, ?, ?, ?) " + - "T (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) " + - "ON (ts_kv_latest.entity_id=T.entity_id " + - "AND ts_kv_latest.key=T.key) " + - "WHEN MATCHED THEN UPDATE SET ts_kv_latest.ts = T.ts, ts_kv_latest.bool_v = T.bool_v, ts_kv_latest.str_v = T.str_v, ts_kv_latest.long_v = T.long_v, ts_kv_latest.dbl_v = T.dbl_v, ts_kv_latest.json_v = T.json_v " + - "WHEN NOT MATCHED THEN INSERT (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) " + - "VALUES (T.entity_id, T.key, T.ts, T.bool_v, T.str_v, T.long_v, T.dbl_v, T.json_v);"; - - @Override - public void saveOrUpdate(List entities) { - jdbcTemplate.batchUpdate(INSERT_OR_UPDATE, new BatchPreparedStatementSetter() { - @Override - public void setValues(PreparedStatement ps, int i) throws SQLException { - ps.setObject(1, entities.get(i).getEntityId()); - ps.setInt(2, entities.get(i).getKey()); - ps.setLong(3, entities.get(i).getTs()); - - if (entities.get(i).getBooleanValue() != null) { - ps.setBoolean(4, entities.get(i).getBooleanValue()); - } else { - ps.setNull(4, Types.BOOLEAN); - } - - ps.setString(5, entities.get(i).getStrValue()); - - if (entities.get(i).getLongValue() != null) { - ps.setLong(6, entities.get(i).getLongValue()); - } else { - ps.setNull(6, Types.BIGINT); - } - - if (entities.get(i).getDoubleValue() != null) { - ps.setDouble(7, entities.get(i).getDoubleValue()); - } else { - ps.setNull(7, Types.DOUBLE); - } - - ps.setString(8, entities.get(i).getJsonValue()); - } - - @Override - public int getBatchSize() { - return entities.size(); - } - }); - } -} diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/psql/PsqlLatestInsertTsRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/sql/SqlLatestInsertTsRepository.java similarity index 96% rename from dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/psql/PsqlLatestInsertTsRepository.java rename to dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/sql/SqlLatestInsertTsRepository.java index 726cf56826..451ba29987 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/psql/PsqlLatestInsertTsRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/latest/sql/SqlLatestInsertTsRepository.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.sqlts.insert.latest.psql; +package org.thingsboard.server.dao.sqlts.insert.latest.sql; import org.springframework.beans.factory.annotation.Value; import org.springframework.jdbc.core.BatchPreparedStatementSetter; @@ -24,7 +24,7 @@ import org.springframework.transaction.support.TransactionCallbackWithoutResult; import org.thingsboard.server.dao.model.sqlts.latest.TsKvLatestEntity; import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; import org.thingsboard.server.dao.sqlts.insert.latest.InsertLatestTsRepository; -import org.thingsboard.server.dao.util.PsqlTsLatestAnyDao; +import org.thingsboard.server.dao.util.SqlTsLatestAnyDao; import java.sql.PreparedStatement; import java.sql.SQLException; @@ -33,10 +33,10 @@ import java.util.ArrayList; import java.util.List; -@PsqlTsLatestAnyDao +@SqlTsLatestAnyDao @Repository @Transactional -public class PsqlLatestInsertTsRepository extends AbstractInsertRepository implements InsertLatestTsRepository { +public class SqlLatestInsertTsRepository extends AbstractInsertRepository implements InsertLatestTsRepository { @Value("${sql.ts_latest.update_by_latest_ts:true}") private Boolean updateByLatestTs; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/psql/PsqlInsertTsRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlInsertTsRepository.java similarity index 93% rename from dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/psql/PsqlInsertTsRepository.java rename to dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlInsertTsRepository.java index adae2c8f3b..c61c852d63 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/psql/PsqlInsertTsRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlInsertTsRepository.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.sqlts.insert.psql; +package org.thingsboard.server.dao.sqlts.insert.sql; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.stereotype.Repository; @@ -21,7 +21,6 @@ import org.springframework.transaction.annotation.Transactional; import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.SqlTsDao; import java.sql.PreparedStatement; @@ -30,10 +29,9 @@ import java.sql.Types; import java.util.List; @SqlTsDao -@PsqlDao @Repository @Transactional -public class PsqlInsertTsRepository extends AbstractInsertRepository implements InsertTsRepository { +public class SqlInsertTsRepository extends AbstractInsertRepository implements InsertTsRepository { private static final String INSERT_ON_CONFLICT_DO_UPDATE = "INSERT INTO ts_kv (entity_id, key, ts, bool_v, str_v, long_v, dbl_v, json_v) VALUES (?, ?, ?, ?, ?, ?, ?, cast(? AS json)) " + "ON CONFLICT (entity_id, key, ts) DO UPDATE SET bool_v = ?, str_v = ?, long_v = ?, dbl_v = ?, json_v = cast(? AS json);"; diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/psql/PsqlPartitioningRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlPartitioningRepository.java similarity index 80% rename from dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/psql/PsqlPartitioningRepository.java rename to dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlPartitioningRepository.java index 5821b0f7c8..899a195538 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/psql/PsqlPartitioningRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/sql/SqlPartitioningRepository.java @@ -13,27 +13,25 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.sqlts.insert.psql; +package org.thingsboard.server.dao.sqlts.insert.sql; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; -import org.thingsboard.server.dao.timeseries.PsqlPartition; -import org.thingsboard.server.dao.util.PsqlDao; +import org.thingsboard.server.dao.timeseries.SqlPartition; import org.thingsboard.server.dao.util.SqlTsDao; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @SqlTsDao -@PsqlDao @Repository @Transactional -public class PsqlPartitioningRepository { +public class SqlPartitioningRepository { @PersistenceContext private EntityManager entityManager; - public void save(PsqlPartition partition) { + public void save(SqlPartition partition) { entityManager.createNativeQuery(partition.getQuery()) .executeUpdate(); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/timescale/TimescaleInsertTsRepository.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/timescale/TimescaleInsertTsRepository.java index ae8f5d8376..02e71c1c7d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/timescale/TimescaleInsertTsRepository.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/insert/timescale/TimescaleInsertTsRepository.java @@ -21,7 +21,6 @@ import org.springframework.transaction.annotation.Transactional; import org.thingsboard.server.dao.model.sqlts.timescale.ts.TimescaleTsKvEntity; import org.thingsboard.server.dao.sqlts.insert.AbstractInsertRepository; import org.thingsboard.server.dao.sqlts.insert.InsertTsRepository; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.TimescaleDBTsDao; import java.sql.PreparedStatement; @@ -30,7 +29,6 @@ import java.sql.Types; import java.util.List; @TimescaleDBTsDao -@PsqlDao @Repository @Transactional public class TimescaleInsertTsRepository extends AbstractInsertRepository implements InsertTsRepository { diff --git a/dao/src/main/java/org/thingsboard/server/dao/sqlts/psql/JpaPsqlTimeseriesDao.java b/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java similarity index 85% rename from dao/src/main/java/org/thingsboard/server/dao/sqlts/psql/JpaPsqlTimeseriesDao.java rename to dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java index 22639dab5a..ce173e046b 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/sqlts/psql/JpaPsqlTimeseriesDao.java +++ b/dao/src/main/java/org/thingsboard/server/dao/sqlts/sql/JpaSqlTimeseriesDao.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.thingsboard.server.dao.sqlts.psql; +package org.thingsboard.server.dao.sqlts.sql; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; @@ -29,10 +29,9 @@ import org.thingsboard.server.common.data.id.TenantId; import org.thingsboard.server.common.data.kv.TsKvEntry; import org.thingsboard.server.dao.model.sqlts.ts.TsKvEntity; import org.thingsboard.server.dao.sqlts.AbstractChunkedAggregationTimeseriesDao; -import org.thingsboard.server.dao.sqlts.insert.psql.PsqlPartitioningRepository; -import org.thingsboard.server.dao.timeseries.PsqlPartition; +import org.thingsboard.server.dao.sqlts.insert.sql.SqlPartitioningRepository; +import org.thingsboard.server.dao.timeseries.SqlPartition; import org.thingsboard.server.dao.timeseries.SqlTsPartitionDate; -import org.thingsboard.server.dao.util.PsqlDao; import org.thingsboard.server.dao.util.SqlTsDao; import java.sql.Connection; @@ -52,15 +51,14 @@ import java.util.concurrent.locks.ReentrantLock; @Component @Slf4j -@PsqlDao @SqlTsDao -public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDao { +public class JpaSqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDao { - private final Map partitions = new ConcurrentHashMap<>(); + private final Map partitions = new ConcurrentHashMap<>(); private static final ReentrantLock partitionCreationLock = new ReentrantLock(); @Autowired - private PsqlPartitioningRepository partitioningRepository; + private SqlPartitioningRepository partitioningRepository; private SqlTsPartitionDate tsFormat; @@ -134,24 +132,24 @@ public class JpaPsqlTimeseriesDao extends AbstractChunkedAggregationTimeseriesDa long partitionEndTs = toMills(localDateTimeEnd); ZonedDateTime zonedDateTime = localDateTimeStart.atZone(ZoneOffset.UTC); String partitionDate = zonedDateTime.format(DateTimeFormatter.ofPattern(tsFormat.getPattern())); - savePartition(new PsqlPartition(partitionStartTs, partitionEndTs, partitionDate)); + savePartition(new SqlPartition(partitionStartTs, partitionEndTs, partitionDate)); } } } - private void savePartition(PsqlPartition psqlPartition) { - if (!partitions.containsKey(psqlPartition.getStart())) { + private void savePartition(SqlPartition sqlPartition) { + if (!partitions.containsKey(sqlPartition.getStart())) { partitionCreationLock.lock(); try { - log.trace("Saving partition: {}", psqlPartition); - partitioningRepository.save(psqlPartition); - log.trace("Adding partition to Set: {}", psqlPartition); - partitions.put(psqlPartition.getStart(), psqlPartition); + log.trace("Saving partition: {}", sqlPartition); + partitioningRepository.save(sqlPartition); + log.trace("Adding partition to Set: {}", sqlPartition); + partitions.put(sqlPartition.getStart(), sqlPartition); } catch (DataIntegrityViolationException ex) { log.trace("Error occurred during partition save:", ex); if (ex.getCause() instanceof ConstraintViolationException) { - log.warn("Saving partition [{}] rejected. Timeseries data will save to the ts_kv_indefinite (DEFAULT) partition.", psqlPartition.getPartitionDate()); - partitions.put(psqlPartition.getStart(), psqlPartition); + log.warn("Saving partition [{}] rejected. Timeseries data will save to the ts_kv_indefinite (DEFAULT) partition.", sqlPartition.getPartitionDate()); + partitions.put(sqlPartition.getStart(), sqlPartition); } else { throw new RuntimeException(ex); } diff --git a/dao/src/main/java/org/thingsboard/server/dao/timeseries/PsqlPartition.java b/dao/src/main/java/org/thingsboard/server/dao/timeseries/SqlPartition.java similarity index 92% rename from dao/src/main/java/org/thingsboard/server/dao/timeseries/PsqlPartition.java rename to dao/src/main/java/org/thingsboard/server/dao/timeseries/SqlPartition.java index fe3019ea25..5c47689b6d 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/timeseries/PsqlPartition.java +++ b/dao/src/main/java/org/thingsboard/server/dao/timeseries/SqlPartition.java @@ -18,7 +18,7 @@ package org.thingsboard.server.dao.timeseries; import lombok.Data; @Data -public class PsqlPartition { +public class SqlPartition { private static final String TABLE_REGEX = "ts_kv_"; @@ -27,7 +27,7 @@ public class PsqlPartition { private String partitionDate; private String query; - public PsqlPartition(long start, long end, String partitionDate) { + public SqlPartition(long start, long end, String partitionDate) { this.start = start; this.end = end; this.partitionDate = partitionDate; diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java index d54933a19d..9d5e080e2a 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractDaoServiceTest.java @@ -28,7 +28,7 @@ import org.thingsboard.server.common.stats.StatsFactory; import org.thingsboard.server.dao.service.DaoSqlTest; @RunWith(SpringRunner.class) -@ContextConfiguration(classes = {JpaDaoConfig.class, PsqlTsDaoConfig.class, PsqlTsLatestDaoConfig.class, SqlTimeseriesDaoConfig.class}) +@ContextConfiguration(classes = {JpaDaoConfig.class, SqlTsDaoConfig.class, SqlTsLatestDaoConfig.class, SqlTimeseriesDaoConfig.class}) @DaoSqlTest @DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS) @TestExecutionListeners({ diff --git a/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java index 5f7fc7caa0..d99692cd5a 100644 --- a/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java +++ b/dao/src/test/java/org/thingsboard/server/dao/AbstractJpaDaoTest.java @@ -30,7 +30,7 @@ import org.thingsboard.server.dao.service.DaoSqlTest; * Created by Valerii Sosliuk on 4/22/2017. */ @RunWith(SpringRunner.class) -@ContextConfiguration(classes = {JpaDaoConfig.class, PsqlTsDaoConfig.class, PsqlTsLatestDaoConfig.class, SqlTimeseriesDaoConfig.class}) +@ContextConfiguration(classes = {JpaDaoConfig.class, SqlTsDaoConfig.class, SqlTsLatestDaoConfig.class, SqlTimeseriesDaoConfig.class}) @DaoSqlTest @TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, diff --git a/dao/src/test/java/org/thingsboard/server/dao/util/DaoTestUtil.java b/dao/src/test/java/org/thingsboard/server/dao/util/DaoTestUtil.java deleted file mode 100644 index 34cceb440b..0000000000 --- a/dao/src/test/java/org/thingsboard/server/dao/util/DaoTestUtil.java +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util; - -import org.springframework.jdbc.core.JdbcTemplate; - -import java.sql.DriverManager; - -public class DaoTestUtil { - private static final String POSTGRES_DRIVER_CLASS = "org.postgresql.Driver"; - private static final String H2_DRIVER_CLASS = "org.hsqldb.jdbc.JDBCDriver"; - - - public static SqlDbType getSqlDbType(JdbcTemplate template){ - try { - String driverName = DriverManager.getDriver(template.getDataSource().getConnection().getMetaData().getURL()).getClass().getName(); - if (POSTGRES_DRIVER_CLASS.equals(driverName)) { - return SqlDbType.POSTGRES; - } else if (H2_DRIVER_CLASS.equals(driverName)) { - return SqlDbType.H2; - } - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } -} diff --git a/dao/src/test/java/org/thingsboard/server/dao/util/SqlDbType.java b/dao/src/test/java/org/thingsboard/server/dao/util/SqlDbType.java deleted file mode 100644 index f655955807..0000000000 --- a/dao/src/test/java/org/thingsboard/server/dao/util/SqlDbType.java +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Copyright © 2016-2022 The Thingsboard Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.thingsboard.server.dao.util; - -public enum SqlDbType { - POSTGRES, H2; -} diff --git a/dao/src/test/resources/nosql-test.properties b/dao/src/test/resources/nosql-test.properties index 8f661359a9..1c6d2442cf 100644 --- a/dao/src/test/resources/nosql-test.properties +++ b/dao/src/test/resources/nosql-test.properties @@ -11,7 +11,6 @@ spring.jpa.properties.hibernate.jdbc.log.warnings=false spring.jpa.show-sql=false spring.jpa.hibernate.ddl-auto=none -spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect spring.datasource.username=postgres spring.datasource.password=postgres spring.datasource.url=jdbc:tc:postgresql:12.8:///thingsboard?TC_DAEMON=true&TC_TMPFS=/testtmpfs:rw&?TC_INITFUNCTION=org.thingsboard.server.dao.PostgreSqlInitializer::initDb diff --git a/dao/src/test/resources/sql-test.properties b/dao/src/test/resources/sql-test.properties index d843b1dc09..b2ded716c4 100644 --- a/dao/src/test/resources/sql-test.properties +++ b/dao/src/test/resources/sql-test.properties @@ -12,7 +12,6 @@ spring.jpa.properties.hibernate.jdbc.log.warnings=false spring.jpa.show-sql=false spring.jpa.hibernate.ddl-auto=none -spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect spring.datasource.username=postgres spring.datasource.password=postgres spring.datasource.url=jdbc:tc:postgresql:12.8:///thingsboard?TC_DAEMON=true&TC_TMPFS=/testtmpfs:rw&?TC_INITFUNCTION=org.thingsboard.server.dao.PostgreSqlInitializer::initDb @@ -32,7 +31,6 @@ service.type=monolith #spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true #spring.jpa.show-sql=false #spring.jpa.hibernate.ddl-auto=none -#spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect # #spring.datasource.username=postgres #spring.datasource.password=postgres diff --git a/docker/tb-node.hybrid.env b/docker/tb-node.hybrid.env index 5f72c6e1a1..e03239bd96 100644 --- a/docker/tb-node.hybrid.env +++ b/docker/tb-node.hybrid.env @@ -2,7 +2,6 @@ DATABASE_TS_TYPE=cassandra CASSANDRA_URL=cassandra:9042 -SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQL10Dialect SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/thingsboard SPRING_DATASOURCE_USERNAME=postgres diff --git a/docker/tb-node.postgres.env b/docker/tb-node.postgres.env index f4e11cd70a..633b8b6fe9 100644 --- a/docker/tb-node.postgres.env +++ b/docker/tb-node.postgres.env @@ -1,7 +1,6 @@ # ThingsBoard server configuration for PostgreSQL database DATABASE_TS_TYPE=sql -SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQL10Dialect SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver SPRING_DATASOURCE_URL=jdbc:postgresql://postgres:5432/thingsboard SPRING_DATASOURCE_USERNAME=postgres diff --git a/msa/tb/docker-cassandra/Dockerfile b/msa/tb/docker-cassandra/Dockerfile index 144c359cc0..5b22efd636 100644 --- a/msa/tb/docker-cassandra/Dockerfile +++ b/msa/tb/docker-cassandra/Dockerfile @@ -54,7 +54,6 @@ ENV DATABASE_TS_TYPE=cassandra ENV PGDATA=/data/db ENV CASSANDRA_DATA=/data/cassandra -ENV SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQL10Dialect ENV SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver ENV SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/thingsboard ENV SPRING_DATASOURCE_USERNAME=${pkg.user} diff --git a/msa/tb/docker-postgres/Dockerfile b/msa/tb/docker-postgres/Dockerfile index 6b6dbc0011..720f770007 100644 --- a/msa/tb/docker-postgres/Dockerfile +++ b/msa/tb/docker-postgres/Dockerfile @@ -50,7 +50,6 @@ ENV DATABASE_TS_TYPE=sql ENV PGDATA=/data/db ENV PATH=$PATH:/usr/lib/postgresql/$PG_MAJOR/bin -ENV SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.PostgreSQL10Dialect ENV SPRING_DRIVER_CLASS_NAME=org.postgresql.Driver ENV SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/thingsboard ENV SPRING_DATASOURCE_USERNAME=${pkg.user} diff --git a/msa/tb/docker-tb/Dockerfile b/msa/tb/docker-tb/Dockerfile deleted file mode 100644 index 6deea6d274..0000000000 --- a/msa/tb/docker-tb/Dockerfile +++ /dev/null @@ -1,61 +0,0 @@ -# -# Copyright © 2016-2022 The Thingsboard Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -FROM thingsboard/openjdk11 - -COPY logback.xml ${pkg.name}.conf start-db.sh stop-db.sh start-tb.sh upgrade-tb.sh install-tb.sh ${pkg.name}.deb /tmp/ - -RUN chmod a+x /tmp/*.sh \ - && mv /tmp/start-tb.sh /usr/bin \ - && mv /tmp/upgrade-tb.sh /usr/bin \ - && mv /tmp/install-tb.sh /usr/bin \ - && mv /tmp/start-db.sh /usr/bin \ - && mv /tmp/stop-db.sh /usr/bin - -RUN dpkg -i /tmp/${pkg.name}.deb -RUN rm /tmp/${pkg.name}.deb - -RUN systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || : - -RUN mv /tmp/logback.xml ${pkg.installFolder}/conf \ - && mv /tmp/${pkg.name}.conf ${pkg.installFolder}/conf - -ENV DATA_FOLDER=/data - -ENV HTTP_BIND_PORT=9090 -ENV DATABASE_TS_TYPE=sql - -ENV SPRING_JPA_DATABASE_PLATFORM=org.hibernate.dialect.HSQLDialect -ENV SPRING_DRIVER_CLASS_NAME=org.hsqldb.jdbc.JDBCDriver -ENV SPRING_DATASOURCE_URL=jdbc:hsqldb:file:/data/db/thingsboardDb;sql.enforce_size=false;hsqldb.log_size=5 -ENV SPRING_DATASOURCE_USERNAME=sa -ENV SPRING_DATASOURCE_PASSWORD= - -RUN mkdir -p /data -RUN chown -R ${pkg.user}:${pkg.user} /data - -RUN chmod 555 ${pkg.installFolder}/bin/${pkg.name}.jar - -USER ${pkg.user} - -EXPOSE 9090 -EXPOSE 1883 -EXPOSE 5683/udp -EXPOSE 5685/udp - -VOLUME ["/data"] - -CMD ["start-tb.sh"] diff --git a/msa/tb/docker-tb/start-db.sh b/msa/tb/docker-tb/start-db.sh deleted file mode 100644 index 6dfddf8a7a..0000000000 --- a/msa/tb/docker-tb/start-db.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# Copyright © 2016-2022 The Thingsboard Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Do nothing \ No newline at end of file diff --git a/msa/tb/docker-tb/stop-db.sh b/msa/tb/docker-tb/stop-db.sh deleted file mode 100644 index 6dfddf8a7a..0000000000 --- a/msa/tb/docker-tb/stop-db.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/bash -# -# Copyright © 2016-2022 The Thingsboard Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# - -# Do nothing \ No newline at end of file diff --git a/msa/tb/pom.xml b/msa/tb/pom.xml index a1aa1c0e16..13f6ef3226 100644 --- a/msa/tb/pom.xml +++ b/msa/tb/pom.xml @@ -35,7 +35,6 @@ UTF-8 ${basedir}/../.. thingsboard - tb tb-postgres tb-cassandra /usr/share/${pkg.name} @@ -59,25 +58,6 @@ org.apache.maven.plugins maven-dependency-plugin - - copy-tb-deb - package - - copy - - - - - org.thingsboard - application - deb - deb - ${pkg.name}.deb - ${project.build.directory}/docker-tb - - - - copy-tb-postgres-deb package @@ -122,27 +102,7 @@ org.apache.maven.plugins maven-resources-plugin - - copy-docker-tb-config - process-resources - - copy-resources - - - ${project.build.directory}/docker-tb - - - docker - true - - - docker-tb - true - - - - - + copy-docker-tb-postgres-config process-resources @@ -188,32 +148,6 @@ com.spotify dockerfile-maven-plugin - - build-docker-tb-image - pre-integration-test - - build - - - ${dockerfile.skip} - ${docker.repo}/${tb.docker.name} - true - false - ${project.build.directory}/docker-tb - - - - tag-docker-tb-image - pre-integration-test - - tag - - - ${dockerfile.skip} - ${docker.repo}/${tb.docker.name} - ${project.version} - - build-docker-tb-postgres-image pre-integration-test @@ -284,28 +218,6 @@ com.spotify dockerfile-maven-plugin - - push-latest-docker-tb-image - pre-integration-test - - push - - - latest - ${docker.repo}/${tb.docker.name} - - - - push-version-docker-tb-image - pre-integration-test - - push - - - ${project.version} - ${docker.repo}/${tb.docker.name} - - push-latest-docker-tb-postgres-image pre-integration-test @@ -368,48 +280,6 @@ org.codehaus.mojo exec-maven-plugin - - push-latest-docker-amd-arm-tb-images - pre-integration-test - - exec - - - docker - ${project.build.directory}/docker-tb - - buildx - build - -t - ${docker.repo}/${tb.docker.name}:latest - --platform=linux/amd64,linux/arm64 - -o - type=registry - . - - - - - push-version-docker-amd-arm-tb-images - pre-integration-test - - exec - - - docker - ${project.build.directory}/docker-tb - - buildx - build - -t - ${docker.repo}/${tb.docker.name}:${project.version} - --platform=linux/amd64,linux/arm64 - -o - type=registry - . - - - push-latest-docker-amd-arm-tb-postgres-images pre-integration-test diff --git a/pom.xml b/pom.xml index 78c4ae6fa2..9273e7bebf 100755 --- a/pom.xml +++ b/pom.xml @@ -125,7 +125,6 @@ 4.1.0 4.3.1.0 2.7.2 - 2.6.1 1.5.2 5.7.2 2.6.0 @@ -1659,11 +1658,6 @@ bcpkix-jdk15on ${bouncycastle.version} - - org.hsqldb - hsqldb - ${hsqldb.version} - org.testcontainers postgresql From 76525766622503e3fc6ea6e5c78eaead266e83ee Mon Sep 17 00:00:00 2001 From: Sergey Matvienko Date: Thu, 16 Jun 2022 11:04:12 +0300 Subject: [PATCH 84/86] Postgresql repo from os-release $VERSION_CODENAME for dockerfile. Disable docker cache temporary to avoid cached releases collission --- msa/tb/docker-cassandra/Dockerfile | 2 +- msa/tb/docker-postgres/Dockerfile | 2 +- msa/tb/pom.xml | 2 ++ 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/msa/tb/docker-cassandra/Dockerfile b/msa/tb/docker-cassandra/Dockerfile index 5b22efd636..f61f070486 100644 --- a/msa/tb/docker-cassandra/Dockerfile +++ b/msa/tb/docker-cassandra/Dockerfile @@ -18,7 +18,7 @@ FROM thingsboard/openjdk11 RUN apt-get update RUN apt-get install -y curl nmap procps gnupg2 -RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main' | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null +RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null RUN curl -L https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - RUN echo 'deb http://downloads.apache.org/cassandra/debian 40x main' | tee --append /etc/apt/sources.list.d/cassandra.list > /dev/null RUN curl -L https://downloads.apache.org/cassandra/KEYS | apt-key add - diff --git a/msa/tb/docker-postgres/Dockerfile b/msa/tb/docker-postgres/Dockerfile index 720f770007..d70bc29b91 100644 --- a/msa/tb/docker-postgres/Dockerfile +++ b/msa/tb/docker-postgres/Dockerfile @@ -18,7 +18,7 @@ FROM thingsboard/openjdk11 RUN apt-get update RUN apt-get install -y curl gnupg2 -RUN echo 'deb http://apt.postgresql.org/pub/repos/apt/ buster-pgdg main' | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null +RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null RUN curl -L https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - ENV PG_MAJOR 12 RUN apt-get update diff --git a/msa/tb/pom.xml b/msa/tb/pom.xml index 13f6ef3226..a69b358e64 100644 --- a/msa/tb/pom.xml +++ b/msa/tb/pom.xml @@ -160,6 +160,7 @@ true false ${project.build.directory}/docker-postgres + true @@ -186,6 +187,7 @@ true false ${project.build.directory}/docker-cassandra + true From 4195d48c3bff5814a9bbc52ea081b85cdb161cc7 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 16 Jun 2022 12:39:39 +0300 Subject: [PATCH 85/86] Updated and optimized docker build files. --- msa/js-executor/docker/Dockerfile | 16 +++--- msa/js-executor/pom.xml | 2 +- msa/tb-node/docker/Dockerfile | 7 +-- msa/tb/docker-cassandra/Dockerfile | 80 ++++++++++++--------------- msa/tb/docker-postgres/Dockerfile | 61 +++++++++----------- msa/transport/coap/docker/Dockerfile | 2 +- msa/transport/http/docker/Dockerfile | 2 +- msa/transport/lwm2m/docker/Dockerfile | 2 +- msa/transport/mqtt/docker/Dockerfile | 2 +- msa/transport/snmp/docker/Dockerfile | 2 +- msa/web-ui/docker/Dockerfile | 16 +++--- msa/web-ui/pom.xml | 2 +- ui-ngx/pom.xml | 2 +- 13 files changed, 88 insertions(+), 108 deletions(-) diff --git a/msa/js-executor/docker/Dockerfile b/msa/js-executor/docker/Dockerfile index 0934b4b1a1..620d712ad1 100644 --- a/msa/js-executor/docker/Dockerfile +++ b/msa/js-executor/docker/Dockerfile @@ -14,16 +14,13 @@ # limitations under the License. # -FROM node:16.13.1-bullseye-slim - -COPY start-js-executor.sh /tmp/ - -RUN chmod a+x /tmp/*.sh \ - && mv /tmp/start-js-executor.sh /usr/bin +FROM node:16.15.1-bullseye-slim ENV NODE_ENV production ENV DOCKER_MODE true +COPY start-js-executor.sh /tmp/ + WORKDIR ${pkg.installFolder} COPY ["src/package.json", "src/yarn.lock", "./"] @@ -34,9 +31,10 @@ COPY src/api ./api COPY src/queue ./queue COPY src/server.js ./ -RUN chown -R node:node ${pkg.installFolder} - -RUN yarn install --production && yarn cache clean --all +RUN chmod a+x /tmp/*.sh \ + && mv /tmp/start-js-executor.sh /usr/bin \ + && chown -R node:node ${pkg.installFolder} \ + && yarn install --production && yarn cache clean --all USER node diff --git a/msa/js-executor/pom.xml b/msa/js-executor/pom.xml index a910e4759f..8e376e1e15 100644 --- a/msa/js-executor/pom.xml +++ b/msa/js-executor/pom.xml @@ -71,7 +71,7 @@ install-node-and-yarn - v16.13.1 + v16.15.1 v1.22.17 diff --git a/msa/tb-node/docker/Dockerfile b/msa/tb-node/docker/Dockerfile index 1881351b92..cbfbebf86c 100644 --- a/msa/tb-node/docker/Dockerfile +++ b/msa/tb-node/docker/Dockerfile @@ -14,13 +14,12 @@ # limitations under the License. # -FROM thingsboard/openjdk11 - -RUN echo 'networkaddress.cache.ttl=60' >> /etc/java-11-openjdk/security/java.security +FROM thingsboard/openjdk11:bullseye-slim COPY start-tb-node.sh ${pkg.name}.deb /tmp/ -RUN chmod a+x /tmp/*.sh \ +RUN echo 'networkaddress.cache.ttl=60' >> /etc/java-11-openjdk/security/java.security \ + && chmod a+x /tmp/*.sh \ && mv /tmp/start-tb-node.sh /usr/bin && \ (yes | dpkg -i /tmp/${pkg.name}.deb) && \ rm /tmp/${pkg.name}.deb && \ diff --git a/msa/tb/docker-cassandra/Dockerfile b/msa/tb/docker-cassandra/Dockerfile index f61f070486..f3fa3146c0 100644 --- a/msa/tb/docker-cassandra/Dockerfile +++ b/msa/tb/docker-cassandra/Dockerfile @@ -14,37 +14,9 @@ # limitations under the License. # -FROM thingsboard/openjdk11 +FROM thingsboard/openjdk11:bullseye-slim -RUN apt-get update -RUN apt-get install -y curl nmap procps gnupg2 -RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null -RUN curl -L https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - -RUN echo 'deb http://downloads.apache.org/cassandra/debian 40x main' | tee --append /etc/apt/sources.list.d/cassandra.list > /dev/null -RUN curl -L https://downloads.apache.org/cassandra/KEYS | apt-key add - ENV PG_MAJOR=12 -RUN apt-get update -RUN apt-get install -y cassandra cassandra-tools postgresql-12 -RUN update-rc.d cassandra disable -RUN update-rc.d postgresql disable -RUN sed -i.old '/ulimit/d' /etc/init.d/cassandra - -COPY logback.xml ${pkg.name}.conf start-db.sh stop-db.sh start-tb.sh upgrade-tb.sh install-tb.sh ${pkg.name}.deb /tmp/ - -RUN chmod a+x /tmp/*.sh \ - && mv /tmp/start-tb.sh /usr/bin \ - && mv /tmp/upgrade-tb.sh /usr/bin \ - && mv /tmp/install-tb.sh /usr/bin \ - && mv /tmp/start-db.sh /usr/bin \ - && mv /tmp/stop-db.sh /usr/bin - -RUN dpkg -i /tmp/${pkg.name}.deb -RUN rm /tmp/${pkg.name}.deb - -RUN systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || : - -RUN mv /tmp/logback.xml ${pkg.installFolder}/conf \ - && mv /tmp/${pkg.name}.conf ${pkg.installFolder}/conf ENV DATA_FOLDER=/data @@ -69,23 +41,43 @@ ENV PATH=$PATH:/usr/lib/postgresql/$PG_MAJOR/bin ENV PGLOG=/var/log/postgres ENV CASSANDRA_LOG=/var/log/cassandra -# postgres config -RUN mkdir -p $PGLOG -RUN chown -R ${pkg.user}:${pkg.user} $PGLOG -RUN chown -R ${pkg.user}:${pkg.user} /var/log/postgresql -RUN chown -R ${pkg.user}:${pkg.user} /var/run/postgresql +COPY logback.xml ${pkg.name}.conf start-db.sh stop-db.sh start-tb.sh upgrade-tb.sh install-tb.sh ${pkg.name}.deb /tmp/ +RUN apt-get update \ + && apt-get install -y curl nmap procps gnupg2 \ + && echo "deb http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null \ + && curl -L https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ + && echo 'deb http://downloads.apache.org/cassandra/debian 40x main' | tee --append /etc/apt/sources.list.d/cassandra.list > /dev/null \ + && curl -L https://downloads.apache.org/cassandra/KEYS | apt-key add - \ + && apt-get update \ + && apt-get install -y cassandra cassandra-tools postgresql-12 \ + && update-rc.d cassandra disable \ + && update-rc.d postgresql disable \ + && sed -i.old '/ulimit/d' /etc/init.d/cassandra \ + && chmod a+x /tmp/*.sh \ + && mv /tmp/start-tb.sh /usr/bin \ + && mv /tmp/upgrade-tb.sh /usr/bin \ + && mv /tmp/install-tb.sh /usr/bin \ + && mv /tmp/start-db.sh /usr/bin \ + && mv /tmp/stop-db.sh /usr/bin \ + && dpkg -i /tmp/${pkg.name}.deb \ + && rm /tmp/${pkg.name}.deb \ + && systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || : \ + && mv /tmp/logback.xml ${pkg.installFolder}/conf \ + && mv /tmp/${pkg.name}.conf ${pkg.installFolder}/conf \ +# postgres config + && mkdir -p $PGLOG \ + && chown -R ${pkg.user}:${pkg.user} $PGLOG \ + && chown -R ${pkg.user}:${pkg.user} /var/log/postgresql \ + && chown -R ${pkg.user}:${pkg.user} /var/run/postgresql \ # cassandra config -RUN rm -rf /var/lib/cassandra -RUN chmod a+w /var/lib -RUN chown -R ${pkg.user}:${pkg.user} $CASSANDRA_LOG - - -RUN mkdir -p $DATA_FOLDER -RUN chown -R ${pkg.user}:${pkg.user} $DATA_FOLDER -RUN chown -R ${pkg.user}:${pkg.user} /var/log/${pkg.name} - -RUN chmod 555 ${pkg.installFolder}/bin/${pkg.name}.jar + && rm -rf /var/lib/cassandra \ + && chmod a+w /var/lib \ + && chown -R ${pkg.user}:${pkg.user} $CASSANDRA_LOG \ + && mkdir -p $DATA_FOLDER \ + && chown -R ${pkg.user}:${pkg.user} $DATA_FOLDER \ + && chown -R ${pkg.user}:${pkg.user} /var/log/${pkg.name} \ + && chmod 555 ${pkg.installFolder}/bin/${pkg.name}.jar USER ${pkg.user} diff --git a/msa/tb/docker-postgres/Dockerfile b/msa/tb/docker-postgres/Dockerfile index d70bc29b91..24c9200ea4 100644 --- a/msa/tb/docker-postgres/Dockerfile +++ b/msa/tb/docker-postgres/Dockerfile @@ -14,33 +14,9 @@ # limitations under the License. # -FROM thingsboard/openjdk11 +FROM thingsboard/openjdk11:bullseye-slim -RUN apt-get update -RUN apt-get install -y curl gnupg2 -RUN echo "deb http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null -RUN curl -L https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - ENV PG_MAJOR 12 -RUN apt-get update -RUN apt-get install -y postgresql-12 -RUN update-rc.d postgresql disable - -COPY logback.xml ${pkg.name}.conf start-db.sh stop-db.sh start-tb.sh upgrade-tb.sh install-tb.sh ${pkg.name}.deb /tmp/ - -RUN chmod a+x /tmp/*.sh \ - && mv /tmp/start-tb.sh /usr/bin \ - && mv /tmp/upgrade-tb.sh /usr/bin \ - && mv /tmp/install-tb.sh /usr/bin \ - && mv /tmp/start-db.sh /usr/bin \ - && mv /tmp/stop-db.sh /usr/bin - -RUN dpkg -i /tmp/${pkg.name}.deb -RUN rm /tmp/${pkg.name}.deb - -RUN systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || : - -RUN mv /tmp/logback.xml ${pkg.installFolder}/conf \ - && mv /tmp/${pkg.name}.conf ${pkg.installFolder}/conf ENV DATA_FOLDER=/data @@ -55,18 +31,35 @@ ENV SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/thingsboard ENV SPRING_DATASOURCE_USERNAME=${pkg.user} ENV SPRING_DATASOURCE_PASSWORD=postgres - ENV PGLOG=/var/log/postgres -RUN mkdir -p $PGLOG -RUN chown -R ${pkg.user}:${pkg.user} $PGLOG -RUN chown -R ${pkg.user}:${pkg.user} /var/run/postgresql - -RUN mkdir -p /data -RUN chown -R ${pkg.user}:${pkg.user} /data +COPY logback.xml ${pkg.name}.conf start-db.sh stop-db.sh start-tb.sh upgrade-tb.sh install-tb.sh ${pkg.name}.deb /tmp/ -RUN chown -R ${pkg.user}:${pkg.user} /var/log/${pkg.name} -RUN chmod 555 ${pkg.installFolder}/bin/${pkg.name}.jar +RUN apt-get update \ + && apt-get install -y curl gnupg2 \ + && echo "deb http://apt.postgresql.org/pub/repos/apt/ $(. /etc/os-release && echo -n $VERSION_CODENAME)-pgdg main" | tee --append /etc/apt/sources.list.d/pgdg.list > /dev/null \ + && curl -L https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add - \ + && apt-get update \ + && apt-get install -y postgresql-12 \ + && update-rc.d postgresql disable \ + && chmod a+x /tmp/*.sh \ + && mv /tmp/start-tb.sh /usr/bin \ + && mv /tmp/upgrade-tb.sh /usr/bin \ + && mv /tmp/install-tb.sh /usr/bin \ + && mv /tmp/start-db.sh /usr/bin \ + && mv /tmp/stop-db.sh /usr/bin \ + && dpkg -i /tmp/${pkg.name}.deb \ + && rm /tmp/${pkg.name}.deb \ + && systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || : \ + && mv /tmp/logback.xml ${pkg.installFolder}/conf \ + && mv /tmp/${pkg.name}.conf ${pkg.installFolder}/conf \ + && mkdir -p $PGLOG \ + && chown -R ${pkg.user}:${pkg.user} $PGLOG \ + && chown -R ${pkg.user}:${pkg.user} /var/run/postgresql \ + && mkdir -p /data \ + && chown -R ${pkg.user}:${pkg.user} /data \ + && chown -R ${pkg.user}:${pkg.user} /var/log/${pkg.name} \ + && chmod 555 ${pkg.installFolder}/bin/${pkg.name}.jar USER ${pkg.user} diff --git a/msa/transport/coap/docker/Dockerfile b/msa/transport/coap/docker/Dockerfile index 2d174a4827..8b1d5d7a0e 100644 --- a/msa/transport/coap/docker/Dockerfile +++ b/msa/transport/coap/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11 +FROM thingsboard/openjdk11:bullseye-slim COPY start-tb-coap-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/http/docker/Dockerfile b/msa/transport/http/docker/Dockerfile index 8e0075738e..d17afe7f54 100644 --- a/msa/transport/http/docker/Dockerfile +++ b/msa/transport/http/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11 +FROM thingsboard/openjdk11:bullseye-slim COPY start-tb-http-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/lwm2m/docker/Dockerfile b/msa/transport/lwm2m/docker/Dockerfile index f0c92419d0..d6fa010a1a 100644 --- a/msa/transport/lwm2m/docker/Dockerfile +++ b/msa/transport/lwm2m/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11 +FROM thingsboard/openjdk11:bullseye-slim COPY start-tb-lwm2m-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/mqtt/docker/Dockerfile b/msa/transport/mqtt/docker/Dockerfile index 378cd14dd5..d46af0138c 100644 --- a/msa/transport/mqtt/docker/Dockerfile +++ b/msa/transport/mqtt/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11 +FROM thingsboard/openjdk11:bullseye-slim COPY start-tb-mqtt-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/transport/snmp/docker/Dockerfile b/msa/transport/snmp/docker/Dockerfile index 84d115f0d4..310d1b34e1 100644 --- a/msa/transport/snmp/docker/Dockerfile +++ b/msa/transport/snmp/docker/Dockerfile @@ -14,7 +14,7 @@ # limitations under the License. # -FROM thingsboard/openjdk11 +FROM thingsboard/openjdk11:bullseye-slim COPY start-tb-snmp-transport.sh ${pkg.name}.deb /tmp/ diff --git a/msa/web-ui/docker/Dockerfile b/msa/web-ui/docker/Dockerfile index 96a6861701..f99509893f 100644 --- a/msa/web-ui/docker/Dockerfile +++ b/msa/web-ui/docker/Dockerfile @@ -14,16 +14,13 @@ # limitations under the License. # -FROM node:16.13.1-bullseye-slim - -COPY start-web-ui.sh /tmp/ - -RUN chmod a+x /tmp/*.sh \ - && mv /tmp/start-web-ui.sh /usr/bin +FROM node:16.15.1-bullseye-slim ENV NODE_ENV production ENV DOCKER_MODE true +COPY start-web-ui.sh /tmp/ + WORKDIR ${pkg.installFolder} COPY ["src/package.json", "src/yarn.lock", "./"] @@ -33,9 +30,10 @@ COPY package/linux/conf ./config COPY web ./web COPY src/server.js ./ -RUN chown -R node:node ${pkg.installFolder} - -RUN yarn install --production && yarn cache clean --all +RUN chmod a+x /tmp/*.sh \ + && mv /tmp/start-web-ui.sh /usr/bin \ + && chown -R node:node ${pkg.installFolder} \ + && yarn install --production && yarn cache clean --all USER node diff --git a/msa/web-ui/pom.xml b/msa/web-ui/pom.xml index c949555d46..2319caa092 100644 --- a/msa/web-ui/pom.xml +++ b/msa/web-ui/pom.xml @@ -80,7 +80,7 @@ install-node-and-yarn - v16.13.1 + v16.15.1 v1.22.17 diff --git a/ui-ngx/pom.xml b/ui-ngx/pom.xml index 66bf79951f..fce2719dc9 100644 --- a/ui-ngx/pom.xml +++ b/ui-ngx/pom.xml @@ -56,7 +56,7 @@ install-node-and-yarn - v16.13.0 + v16.15.1 v1.22.17 From aadfd1eb886c619c7a49062a75e5fee5349c2232 Mon Sep 17 00:00:00 2001 From: Igor Kulikov Date: Thu, 16 Jun 2022 13:47:02 +0300 Subject: [PATCH 86/86] Dockerfile improvements --- msa/tb/docker-cassandra/Dockerfile | 2 +- msa/tb/docker-postgres/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msa/tb/docker-cassandra/Dockerfile b/msa/tb/docker-cassandra/Dockerfile index f3fa3146c0..9d16d46ef5 100644 --- a/msa/tb/docker-cassandra/Dockerfile +++ b/msa/tb/docker-cassandra/Dockerfile @@ -62,7 +62,7 @@ RUN apt-get update \ && mv /tmp/stop-db.sh /usr/bin \ && dpkg -i /tmp/${pkg.name}.deb \ && rm /tmp/${pkg.name}.deb \ - && systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || : \ + && (systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || :) \ && mv /tmp/logback.xml ${pkg.installFolder}/conf \ && mv /tmp/${pkg.name}.conf ${pkg.installFolder}/conf \ # postgres config diff --git a/msa/tb/docker-postgres/Dockerfile b/msa/tb/docker-postgres/Dockerfile index 24c9200ea4..5dfdba41bd 100644 --- a/msa/tb/docker-postgres/Dockerfile +++ b/msa/tb/docker-postgres/Dockerfile @@ -50,7 +50,7 @@ RUN apt-get update \ && mv /tmp/stop-db.sh /usr/bin \ && dpkg -i /tmp/${pkg.name}.deb \ && rm /tmp/${pkg.name}.deb \ - && systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || : \ + && (systemctl --no-reload disable --now ${pkg.name}.service > /dev/null 2>&1 || :) \ && mv /tmp/logback.xml ${pkg.installFolder}/conf \ && mv /tmp/${pkg.name}.conf ${pkg.installFolder}/conf \ && mkdir -p $PGLOG \