diff --git a/examples/performance-tuning/solo-gke/Taskfile.yml b/examples/performance-tuning/solo-gke/Taskfile.yml new file mode 100644 index 000000000..6e752b8b1 --- /dev/null +++ b/examples/performance-tuning/solo-gke/Taskfile.yml @@ -0,0 +1,21 @@ +version: 3 +includes: + main: + taskfile: ../Taskfile.examples.yml + flatten: true +vars: + solo_home_override_dir: "/home/gke1" +env: + SOLO_NETWORK_SIZE: 4 + SOLO_NAMESPACE: solo-gke1 + SOLO_CHART_VERSION: 0.42.3 + # CONSENSUS_NODE_VERSION: v0.58.0 + VALUES_FLAG: "--values-file {{.USER_WORKING_DIR}}/init-containers-values.yaml" + SETTINGS_FLAG: "--settings-txt {{.USER_WORKING_DIR}}/settings.txt" + SOLO_HOME: "{{.solo_home_override_dir}}" + LOG4J2_FLAG: "--log4j2-xml {{.USER_WORKING_DIR}}/log4j2.xml" + APPLICATION_PROPERTIES_FLAG: "--application-properties {{.USER_WORKING_DIR}}/application.properties" + HEDERA_SERVICES_ROOT: "/home/gke1/workspaces/10nodes/hedera-services" + LOCAL_BUILD_FLAG: "--local-build-path {{.HEDERA_SERVICES_ROOT}}/hedera-node/data" + GENESIS_THROTTLES_FLAG: "--genesis-throttles-file {{.USER_WORKING_DIR}}/throttles.json" + # SOLO_CHARTS_DIR_FLAG: "-d /Users/user/source/solo-charts/charts" diff --git a/examples/performance-tuning/solo-gke/application.properties b/examples/performance-tuning/solo-gke/application.properties new file mode 100644 index 000000000..19b28eb49 --- /dev/null +++ b/examples/performance-tuning/solo-gke/application.properties @@ -0,0 +1,24 @@ +hedera.config.version=0 +ledger.id=0x01 +netty.mode=TEST +contracts.chainId=298 +hedera.recordStream.logPeriod=1 +balances.exportPeriodSecs=400 +files.maxSizeKb=2048 +hedera.recordStream.compressFilesOnCreation=true +balances.compressOnCreation=true +contracts.maxNumWithHapiSigsAccess=0 +autoRenew.targetTypes= +nodes.gossipFqdnRestricted=false +hedera.profiles.active=TEST +# TODO: this is a workaround until prepareUpgrade freeze will recalculate the weight prior to writing the config.txt +staking.periodMins=1 +nodes.updateAccountIdAllowed=true +blockStream.streamMode=BOTH + +# Override the throttle definitions to be used during genesis. +# This override is required because release <= 0.58.x use a different default path. +bootstrap.throttleDefsJson.resource=data/config/genesis-throttles.json + +#small GKE specific: +cache.warmThreads=6 diff --git a/examples/performance-tuning/solo-gke/init-containers-values.yaml b/examples/performance-tuning/solo-gke/init-containers-values.yaml new file mode 100644 index 000000000..31abb52c4 --- /dev/null +++ b/examples/performance-tuning/solo-gke/init-containers-values.yaml @@ -0,0 +1,174 @@ +# hedera node configuration +hedera: + initContainers: + - name: init-hedera-node + image: busybox:stable-musl + command: ["sh", "-c", "cp -r /etc /data-saved"] + volumeMounts: + - name: hgcapp-data-saved + mountPath: /data-saved + nodes: + - name: node1 + nodeId: 0 + accountId: 0.0.3 + root: + resources: + requests: + cpu: 2 + memory: 16Gi + limits: + cpu: 4 + memory: 31Gi + - name: node2 + nodeId: 1 + accountId: 0.0.4 + root: + resources: + requests: + cpu: 2 + memory: 16Gi + limits: + cpu: 4 + memory: 31Gi + - name: node3 + nodeId: 2 + accountId: 0.0.5 + root: + resources: + requests: + cpu: 2 + memory: 16Gi + limits: + cpu: 4 + memory: 31Gi + - name: node4 + nodeId: 3 + accountId: 0.0.6 + root: + resources: + requests: + cpu: 2 + memory: 16Gi + limits: + cpu: 4 + memory: 31Gi +defaults: + haproxy: + serviceType: NodePort + envoyProxy: + loadBalancerEnabled: true + sidecars: + recordStreamUploader: + resources: + requests: + cpu: 100m + memory: 100Mi + limits: + cpu: 150m + memory: 200Mi + eventStreamUploader: + resources: + requests: + cpu: 100m + memory: 100Mi + limits: + cpu: 150m + memory: 200Mi + recordStreamSidecarUploader: + resources: + requests: + cpu: 100m + memory: 100Mi + limits: + cpu: 150m + memory: 200Mi + blockstreamUploader: + resources: + requests: + cpu: 100m + memory: 200Mi + limits: + cpu: 150m + memory: 400Mi + root: + resources: + requests: + cpu: 2 + memory: 16Gi + limits: + cpu: 4 + memory: 31Gi + extraEnv: + - name: JAVA_OPTS + value: "-XX:+UnlockExperimentalVMOptions -XX:+UseZGC -XX:ZAllocationSpikeTolerance=2 -XX:ConcGCThreads=4 -XX:MaxDirectMemorySize=4g -XX:MetaspaceSize=100M -XX:+ZGenerational -Xlog:gc*:gc.log --add-opens java.base/jdk.internal.misc=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED -Dio.netty.tryReflectionSetAccessible=true" + - name: JAVA_HEAP_MIN + value: "16g" + - name: JAVA_HEAP_MAX + value: "19g" + - name: MALLOC_ARENA_MAX + value: "1" +deployment: + podAnnotations: {} + podLabels: {} + nodeSelector: + solo.hashgraph.io/role: "consensus-node" + tolerations: + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "consensus-node" + effect: "NoSchedule" +minio-server: + secrets: + # This secret has [accessKey, secretKey] and will be randomly generated by helm + existingSecret: minio-secrets + tenant: + buckets: + - name: solo-streams + - name: solo-backups + name: minio + pools: + - servers: 1 + name: pool-1 + volumesPerServer: 1 + size: 512Gi + storageClassName: standard-rwo + nodeSelector: {} + configuration: + name: minio-secrets + certificate: + requestAutoCert: false + environment: + MINIO_BROWSER_LOGIN_ANIMATION: off # https://github.com/minio/console/issues/2539#issuecomment-1619211962 +haproxyDeployment: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: solo.hedera.com/type + operator: In + values: + - network-node + topologyKey: kubernetes.io/hostname +envoyDeployment: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: solo.hedera.com/type + operator: In + values: + - network-node + topologyKey: kubernetes.io/hostname +minioDeployment: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: solo.hedera.com/type + operator: In + values: + - network-node + topologyKey: kubernetes.io/hostname diff --git a/examples/performance-tuning/solo-gke/log4j2.xml b/examples/performance-tuning/solo-gke/log4j2.xml new file mode 100644 index 000000000..47fb2f712 --- /dev/null +++ b/examples/performance-tuning/solo-gke/log4j2.xml @@ -0,0 +1,378 @@ + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %-4L %c{1} - %m{nolookups}%n + + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %-4L %c{1} - %m{nolookups}%n + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-8sn %-5p %-16marker <%t> %c{1}: %msg{nolookups}%n + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-8sn %-5p %-16marker <%t> %c{1}: %msg{nolookups}%n + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} %-8sn %-5p %-16marker <%t> %c{1}: %msg{nolookups}%n + + + + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} - %m{nolookups}%n + + + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} - %m{nolookups}%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/performance-tuning/solo-gke/mirror-and-explorer-values.yaml b/examples/performance-tuning/solo-gke/mirror-and-explorer-values.yaml new file mode 100644 index 000000000..5ac9dc88d --- /dev/null +++ b/examples/performance-tuning/solo-gke/mirror-and-explorer-values.yaml @@ -0,0 +1,277 @@ +# hedera mirror node explorer +ingress: + enabled: true + hosts: + - host: "explorer.solo.local" + paths: + - path: / + pathType: Prefix + tls: + - secretName: ca-secret-hedera-explorer + hosts: + - '{{ index .Values.ingress.hosts 0 "host" }}' +labels: + solo.hedera.com/testSuiteName: "" + solo.hedera.com/testName: "" + solo.hedera.com/testRunUID: "" + solo.hedera.com/testCreationTimestamp: "" + solo.hedera.com/testExpirationTimestamp: "" + solo.hedera.com/testRequester: "" + +stackgres: + coordinator: + persistentVolume: + storageClass: "standard-rwo" + worker: + persistentVolume: + storageClass: "standard-rwo" + +tolerations: + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "consensus-node" + effect: "NoSchedule" + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "test-clients" + effect: "NoSchedule" + - key: "solo-scheduling.io/os" + operator: "Equal" + value: "linux" + effect: "NoSchedule" + - key: "solo-scheduling.io/role" + operator: "Equal" + value: "network" + effect: "NoSchedule" +#global: +# namespaceOverride: "{{ .Values.global.namespaceOverride }}" +# The hedera explorer UI /api url will proxy all request to mirror node +# +# Without this we would need to expose the mirror node rest API publicly and specify its public url in the network config below +proxyPass: + /api: "http://{{ .Release.Name }}-rest" + +# In the json config below we are using the url as "/", instead of a regular http://mainnet.url +# This makes the explorer UI make a relative request to its own url +# This in combination with proxyPass above saves us the need to expose mirror node URL publicly +config: | + [ + { + "name": "localnet", + "displayName": "LOCALNET", + "url": "/", + "ledgerID": "03" + } + ] + +# mirror node +graphql: # not needed for default use case + enabled: false +rosetta: # not needed for default use case + enabled: false +redis: + enabled: true +#global: +# namespaceOverride: "{{ tpl (.Values.global.namespaceOverride | toString) }}" + +# importer is a component of the hedera mirror node +# config for subchart hedera-mirror/importer +importer: + tolerations: + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "consensus-node" + effect: "NoSchedule" + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "test-clients" + effect: "NoSchedule" + - key: "solo-scheduling.io/os" + operator: "Equal" + value: "linux" + effect: "NoSchedule" + - key: "solo-scheduling.io/role" + operator: "Equal" + value: "network" + effect: "NoSchedule" + envFrom: + - secretRef: + name: mirror-passwords + - secretRef: + name: "{{ .Release.Name }}-redis" + - secretRef: + name: uploader-mirror-secrets + # The addressbook.bin file updates will be handled by infrastructure code or solo + addressBook: "" + config: + # importer is a springboot app, its application.yaml configuration starts here + # This config is mounted at [/usr/etc/hedera/application.yaml] in the importer pod + hedera: + mirror: + importer: + network: other + downloader: + allowAnonymousAccess: false + bucketName: "solo-streams" + # for s3 configuration of mirror node look at uploader-mirror-secrets.yaml + parser: + record: + entity: + notify: + enabled: true + redis: + enabled: false + sidecar: + enabled: true + management: + endpoint: + health: + group: + readiness: + exclude: redis +grpc: + tolerations: + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "consensus-node" + effect: "NoSchedule" + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "test-clients" + effect: "NoSchedule" + - key: "solo-scheduling.io/os" + operator: "Equal" + value: "linux" + effect: "NoSchedule" + - key: "solo-scheduling.io/role" + operator: "Equal" + value: "network" + effect: "NoSchedule" + config: + hedera: + mirror: + grpc: + listener: + type: NOTIFY + management: + endpoint: + health: + group: + readiness: + exclude: redis +postgresql: + postgresql: + tolerations: + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "consensus-node" + effect: "NoSchedule" + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "test-clients" + effect: "NoSchedule" + - key: "solo-scheduling.io/os" + operator: "Equal" + value: "linux" + effect: "NoSchedule" + - key: "solo-scheduling.io/role" + operator: "Equal" + value: "network" + effect: "NoSchedule" + pgpool: + replicaCount: 0 +rest: + tolerations: + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "consensus-node" + effect: "NoSchedule" + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "test-clients" + effect: "NoSchedule" + - key: "solo-scheduling.io/os" + operator: "Equal" + value: "linux" + effect: "NoSchedule" + - key: "solo-scheduling.io/role" + operator: "Equal" + value: "network" + effect: "NoSchedule" + monitor: + enabled: false + redis: + enabled: true +web3: + tolerations: + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "consensus-node" + effect: "NoSchedule" + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "test-clients" + effect: "NoSchedule" + - key: "solo-scheduling.io/os" + operator: "Equal" + value: "linux" + effect: "NoSchedule" + - key: "solo-scheduling.io/role" + operator: "Equal" + value: "network" + effect: "NoSchedule" + +# config for subchart hedera-mirror/monitor +# Sets up a Pinger service that periodically submits CRYPTO_TRANSFER transactions +# Additional configuration for node addresses, operator id and key should be handled by infrastructure code or solo +monitor: + tolerations: + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "consensus-node" + effect: "NoSchedule" + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "test-clients" + effect: "NoSchedule" + - key: "solo-scheduling.io/os" + operator: "Equal" + value: "linux" + effect: "NoSchedule" + - key: "solo-scheduling.io/role" + operator: "Equal" + value: "network" + effect: "NoSchedule" + envFrom: + - secretRef: + name: mirror-passwords + - secretRef: + name: "{{ .Release.Name }}-redis" + - secretRef: + name: uploader-mirror-secrets + config: + hedera: + mirror: + monitor: + publish: + scenarios: + pinger: + properties: + amount: 1 + maxTransactionFee: 10000 + senderAccountId: 0.0.2 + recipientAccountId: 0.0.55 + transferTypes: + - CRYPTO + receiptPercent: 1 + tps: 10 + type: CRYPTO_TRANSFER + subscribe: + grpc: + hcs: + enabled: false + rest: + transactionId: + enabled: true + samplePercent: 1 + network: OTHER diff --git a/examples/performance-tuning/solo-gke/nlg-values.yaml b/examples/performance-tuning/solo-gke/nlg-values.yaml new file mode 100644 index 000000000..06efb13e3 --- /dev/null +++ b/examples/performance-tuning/solo-gke/nlg-values.yaml @@ -0,0 +1,44 @@ +replicas: 1 + +resources: + limits: + memory: 32Gi + cpu: '32' + requests: + memory: 16Gi + cpu: '16' + +nodeSelector: + solo.hashgraph.io/role: "test-clients" +tolerations: + - key: "solo.hashgraph.io/role" + operator: "Equal" + value: "test-clients" + effect: "NoSchedule" +affinity: {} + +loadGenerator: + java: + maxMemory: '48g' + test: + className: com.hedera.benchmark.NftTransferLoadTest + args: + - -c + - "7" + - -a + - "1000" + - -T + - "10" + - -n + - "10" + - -S + - "hot" + - -p + - "50" + - -t + - "1m" + properties: + - '34.118.234.151\:50211=0.0.3' + - '34.118.236.218\:50211=0.0.4' + - '34.118.228.172\:50211=0.0.5' + - '34.118.228.97\:50211=0.0.6' diff --git a/examples/performance-tuning/solo-gke/relay-values.yaml b/examples/performance-tuning/solo-gke/relay-values.yaml new file mode 100644 index 000000000..0364431f7 --- /dev/null +++ b/examples/performance-tuning/solo-gke/relay-values.yaml @@ -0,0 +1,25 @@ +# https://github.com/hashgraph/hedera-json-rpc-relay/blob/main/charts/hedera-json-rpc-relay/values.yaml#L125 + +ingress: + enabled: true + hosts: + - host: relay.explorer.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + +replicaCount: 1 + +resources: + requests: + cpu: 0 + memory: 0 + limits: + cpu: 500m + memory: 1000Mi + +service: + type: ClusterIP + port: 7546 + annotations: {} diff --git a/examples/performance-tuning/solo-gke/settings.txt b/examples/performance-tuning/solo-gke/settings.txt new file mode 100644 index 000000000..5694c6be5 --- /dev/null +++ b/examples/performance-tuning/solo-gke/settings.txt @@ -0,0 +1,18 @@ +checkSignedStateFromDisk, 1 +csvFileName, MainNetStats +doUpnp, false +loadKeysFromPfxFiles, 0 +maxOutgoingSyncs, 1 +reconnect.active, 1 +reconnect.reconnectWindowSeconds, -1 +showInternalStats, 1 +state.saveStatePeriod, 900 +useLoopbackIp, false +waitAtStartup, false +state.mainClassNameOverride, com.hedera.services.ServicesMain +maxEventQueueForCons, 1000 +merkleDb.hashesRamToDiskThreshold, 8388608 +event.creation.maxCreationRate, 20 +virtualMap.familyThrottleThreshold, 6000000000 +merkleDb.maxFileChannelsPerFileReader, 1 + diff --git a/examples/performance-tuning/solo-gke/throttles.json b/examples/performance-tuning/solo-gke/throttles.json new file mode 100644 index 000000000..6ffc1c201 --- /dev/null +++ b/examples/performance-tuning/solo-gke/throttles.json @@ -0,0 +1,204 @@ +{ + "buckets": [ + { + "burstPeriod": 0, + "burstPeriodMs": 15000, + "name": "ThroughputLimits", + "throttleGroups": [ + { + "opsPerSec": 0, + "milliOpsPerSec": 150000, + "operations": [ + "ScheduleCreate", + "CryptoCreate", + "CryptoTransfer", + "CryptoUpdate", + "CryptoDelete", + "CryptoGetInfo", + "CryptoGetAccountRecords", + "ConsensusCreateTopic", + "ConsensusSubmitMessage", + "ConsensusUpdateTopic", + "ConsensusDeleteTopic", + "ConsensusGetTopicInfo", + "TokenGetNftInfo", + "TokenGetInfo", + "ScheduleDelete", + "ScheduleGetInfo", + "FileGetContents", + "FileGetInfo", + "ContractUpdate", + "ContractDelete", + "ContractGetInfo", + "ContractGetBytecode", + "ContractGetRecords", + "ContractCallLocal", + "TransactionGetRecord", + "GetVersionInfo", + "TokenGetAccountNftInfos", + "TokenGetNftInfos", + "CryptoApproveAllowance", + "CryptoDeleteAllowance", + "UtilPrng", + "NodeCreate", + "NodeUpdate", + "NodeDelete" + ] + }, + { + "opsPerSec": 0, + "milliOpsPerSec": 40000, + "operations": [ + "FileCreate", + "FileUpdate", + "FileAppend", + "FileDelete" + ] + }, + { + "opsPerSec": 0, + "milliOpsPerSec": 100000, + "operations": [ + "ScheduleSign" + ] + }, + { + "opsPerSec": 0, + "milliOpsPerSec": 125000, + "operations": [ + "TokenMint" + ] + }, + { + "opsPerSec": 0, + "milliOpsPerSec": 35000, + "operations": [ + "ContractCall", + "ContractCreate", + "EthereumTransaction" + ] + }, + { + "opsPerSec": 0, + "milliOpsPerSec": 100000, + "operations": [ + "TokenCreate", + "TokenDelete", + "TokenBurn", + "TokenUpdate", + "TokenFeeScheduleUpdate", + "TokenAssociateToAccount", + "TokenAccountWipe", + "TokenDissociateFromAccount", + "TokenFreezeAccount", + "TokenUnfreezeAccount", + "TokenGrantKycToAccount", + "TokenRevokeKycFromAccount", + "TokenPause", + "TokenUnpause", + "TokenUpdateNfts", + "TokenReject", + "TokenAirdrop", + "TokenClaimAirdrop", + "TokenCancelAirdrop" + ] + } + ] + }, + { + "burstPeriod": 0, + "burstPeriodMs": 1000, + "name": "OffHeapQueryLimits", + "throttleGroups": [ + { + "opsPerSec": 0, + "milliOpsPerSec": 100000, + "operations": [ + "FileGetContents", + "FileGetInfo", + "ContractGetInfo", + "ContractGetBytecode", + "ContractCallLocal" + ] + } + ] + }, + { + "burstPeriod": 0, + "burstPeriodMs": 3000, + "name": "PriorityReservations", + "throttleGroups": [ + { + "opsPerSec": 0, + "milliOpsPerSec": 40000, + "operations": [ + "FileCreate", + "FileUpdate", + "FileAppend", + "FileDelete" + ] + } + ] + }, + { + "burstPeriod": 0, + "burstPeriodMs": 15000, + "name": "CreationLimits", + "throttleGroups": [ + { + "opsPerSec": 0, + "milliOpsPerSec": 40000, + "operations": [ + "CryptoCreate", + "NodeCreate" + ] + }, + { + "opsPerSec": 0, + "milliOpsPerSec": 5000, + "operations": [ + "ConsensusCreateTopic" + ] + }, + { + "opsPerSec": 0, + "milliOpsPerSec": 100000, + "operations": [ + "TokenCreate", + "TokenAssociateToAccount", + "ScheduleCreate", + "TokenAirdrop" + ] + } + ] + }, + { + "burstPeriod": 0, + "burstPeriodMs": 1000, + "name": "FreeQueryLimits", + "throttleGroups": [ + { + "opsPerSec": 0, + "milliOpsPerSec": 1000000000, + "operations": [ + "TransactionGetReceipt" + ] + } + ] + }, + { + "burstPeriod": 0, + "burstPeriodMs": 1000, + "name": "BalanceQueryLimits", + "throttleGroups": [ + { + "opsPerSec": 0, + "milliOpsPerSec": 1000000, + "operations": [ + "CryptoGetAccountBalance" + ] + } + ] + } + ] +} diff --git a/package-lock.json b/package-lock.json index 61d2f1900..35b2b7e9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,7 +29,7 @@ "figlet": "^1.8.0", "got": "^14.4.5", "http-status-codes": "^2.3.0", - "inquirer": "^12.3.1", + "inquirer": "^12.3.2", "ip": "^2.0.1", "js-base64": "^3.7.7", "listr2": "^8.2.5", @@ -62,7 +62,7 @@ "@types/ip": "^1.1.3", "@types/mocha": "^10.0.10", "@types/mocha-each": "^2.0.4", - "@types/node": "^22.10.5", + "@types/node": "^22.10.6", "@types/semver": "^7.5.8", "@types/sinon": "^17.0.3", "@types/sinon-chai": "^4.0.0", @@ -71,13 +71,13 @@ "@types/uuid": "^10.0.0", "@types/ws": "^8.5.13", "@types/yargs": "^17.0.33", - "@typescript-eslint/utils": "^8.19.1", + "@typescript-eslint/utils": "^8.20.0", "c8": "^10.1.3", "chai": "^5.1.2", "chai-as-promised": "^8.0.1", "cross-env": "^7.0.3", "eslint": "^9.18.0", - "eslint-config-prettier": "^9.1.0", + "eslint-config-prettier": "^10.0.1", "eslint-plugin-headers": "^1.2.1", "eslint-plugin-import": "^2.30.0", "eslint-plugin-mocha": "^10.5.0", @@ -1390,11 +1390,11 @@ } }, "node_modules/@inquirer/checkbox": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.5.tgz", - "integrity": "sha512-H//QP3E8Vy0oYX5lw6WSFnOTiRUNm4+LYRby1/1r6y3doRurnqekAj4pJoUbdL5ESEgLqJFJ5HhNDWTp5Qyz5A==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.0.6.tgz", + "integrity": "sha512-PgP35JfmGjHU0LSXOyRew0zHuA9N6OJwOlos1fZ20b7j8ISeAdib3L+n0jIxBtX958UeEpte6xhG/gxJ5iUqMw==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/figures": "^1.0.9", "@inquirer/type": "^3.0.2", "ansi-escapes": "^4.3.2", @@ -1408,11 +1408,11 @@ } }, "node_modules/@inquirer/confirm": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.2.tgz", - "integrity": "sha512-VKgaKxw2I3cu2smedeMFyxuYyI+HABlFY1Px4j8NueA7xDskKAo9hxEQemTpp1Fu4OiTtOCgU4eK91BVuBKH3g==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.3.tgz", + "integrity": "sha512-fuF9laMmHoOgWapF9h9hv6opA5WvmGFHsTYGCmuFxcghIhEhb3dN0CdQR4BUMqa2H506NCj8cGX4jwMsE4t6dA==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/type": "^3.0.2" }, "engines": { @@ -1423,9 +1423,9 @@ } }, "node_modules/@inquirer/core": { - "version": "10.1.3", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.3.tgz", - "integrity": "sha512-+7/dCYwDku2xfcWJWX6Urxb8aRz6d0K+4lRgIBM08ktE84dm++RPROgnVfWq4hLK5FVu/O4rbO9HnJtaz3pt2w==", + "version": "10.1.4", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.4.tgz", + "integrity": "sha512-5y4/PUJVnRb4bwWY67KLdebWOhOc7xj5IP2J80oWXa64mVag24rwQ1VAdnj7/eDY/odhguW0zQ1Mp1pj6fO/2w==", "dependencies": { "@inquirer/figures": "^1.0.9", "@inquirer/type": "^3.0.2", @@ -1453,11 +1453,11 @@ } }, "node_modules/@inquirer/editor": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.2.tgz", - "integrity": "sha512-BPLJsWxLO6r47wU2qtGG+akQuoSCotDlOu8GTIkJVxJpNNVYnA60xKHkSGbEAALO+D3DFeRXE0JFvFJ53sVbjA==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.3.tgz", + "integrity": "sha512-S9KnIOJuTZpb9upeRSBBhoDZv7aSV3pG9TECrBj0f+ZsFwccz886hzKBrChGrXMJwd4NKY+pOA9Vy72uqnd6Eg==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/type": "^3.0.2", "external-editor": "^3.1.0" }, @@ -1469,11 +1469,11 @@ } }, "node_modules/@inquirer/expand": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.5.tgz", - "integrity": "sha512-Ff3CqHmc8MuUu9A0LKgftzIdp+D5k/kTYHGmjY7iouO37OuP6Np4UqL0clkjQ2UHph7ORwvi0RMfSNnH3PF0PQ==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.6.tgz", + "integrity": "sha512-TRTfi1mv1GeIZGyi9PQmvAaH65ZlG4/FACq6wSzs7Vvf1z5dnNWsAAXBjWMHt76l+1hUY8teIqJFrWBk5N6gsg==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/type": "^3.0.2", "yoctocolors-cjs": "^2.1.2" }, @@ -1493,11 +1493,11 @@ } }, "node_modules/@inquirer/input": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.2.tgz", - "integrity": "sha512-YnnskI/AX92KVU6gjNxdeLNqdJPBEOkL3I6EzZjfByKskjZtJuAX1CBev8AAHJsLaB3X9JCQoB/ag2dyzRPdSg==", + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.3.tgz", + "integrity": "sha512-zeo++6f7hxaEe7OjtMzdGZPHiawsfmCZxWB9X1NpmYgbeoyerIbWemvlBxxl+sQIlHC0WuSAG19ibMq3gbhaqQ==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/type": "^3.0.2" }, "engines": { @@ -1508,11 +1508,11 @@ } }, "node_modules/@inquirer/number": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.5.tgz", - "integrity": "sha512-O/gcUwhS0TzBdBszYues3B4PTwyOLo51RctvXPRGtDfwIftuTTdPnm3K7oiK2OC2CDc7eG4UNa+QtdLlaJxIOA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.6.tgz", + "integrity": "sha512-xO07lftUHk1rs1gR0KbqB+LJPhkUNkyzV/KhH+937hdkMazmAYHLm1OIrNKpPelppeV1FgWrgFDjdUD8mM+XUg==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/type": "^3.0.2" }, "engines": { @@ -1523,11 +1523,11 @@ } }, "node_modules/@inquirer/password": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.5.tgz", - "integrity": "sha512-/Undb8fTDSo6LX79OtAsdaaW08x6Xx9zr4z9Xd1VV/N4kDnJ9fWyUHJ287V0XTqMYgH/5SnZBU2e8VzgpGWO8g==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.6.tgz", + "integrity": "sha512-QLF0HmMpHZPPMp10WGXh6F+ZPvzWE7LX6rNoccdktv/Rov0B+0f+eyXkAcgqy5cH9V+WSpbLxu2lo3ysEVK91w==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/type": "^3.0.2", "ansi-escapes": "^4.3.2" }, @@ -1539,20 +1539,20 @@ } }, "node_modules/@inquirer/prompts": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.2.2.tgz", - "integrity": "sha512-kUd4L1S8huk+2FbIl0UbBqZ6g8mYFtag9Pb8IqzeefIYgRXyS4Oc29ikuSlhfSkEYjG+gBAA5Ip0JvuvSqtfWA==", - "dependencies": { - "@inquirer/checkbox": "^4.0.5", - "@inquirer/confirm": "^5.1.2", - "@inquirer/editor": "^4.2.2", - "@inquirer/expand": "^4.0.5", - "@inquirer/input": "^4.1.2", - "@inquirer/number": "^3.0.5", - "@inquirer/password": "^4.0.5", - "@inquirer/rawlist": "^4.0.5", - "@inquirer/search": "^3.0.5", - "@inquirer/select": "^4.0.5" + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.2.3.tgz", + "integrity": "sha512-hzfnm3uOoDySDXfDNOm9usOuYIaQvTgKp/13l1uJoe6UNY+Zpcn2RYt0jXz3yA+yemGHvDOxVzqWl3S5sQq53Q==", + "dependencies": { + "@inquirer/checkbox": "^4.0.6", + "@inquirer/confirm": "^5.1.3", + "@inquirer/editor": "^4.2.3", + "@inquirer/expand": "^4.0.6", + "@inquirer/input": "^4.1.3", + "@inquirer/number": "^3.0.6", + "@inquirer/password": "^4.0.6", + "@inquirer/rawlist": "^4.0.6", + "@inquirer/search": "^3.0.6", + "@inquirer/select": "^4.0.6" }, "engines": { "node": ">=18" @@ -1562,11 +1562,11 @@ } }, "node_modules/@inquirer/rawlist": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.5.tgz", - "integrity": "sha512-38g3v5/cX3NUv+jcr4sU6phKAthQKv36NYRgahsZIGNIVy8ewtSnolCJ1N64nGwi/sTUz5AE6PV1ZF+NaIThxg==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.0.6.tgz", + "integrity": "sha512-QoE4s1SsIPx27FO4L1b1mUjVcoHm1pWE/oCmm4z/Hl+V1Aw5IXl8FYYzGmfXaBT0l/sWr49XmNSiq7kg3Kd/Lg==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/type": "^3.0.2", "yoctocolors-cjs": "^2.1.2" }, @@ -1578,11 +1578,11 @@ } }, "node_modules/@inquirer/search": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.5.tgz", - "integrity": "sha512-INqlGeK85gOmlVY8aosAdOMWgOmpcA7+eDlq5WBdbh8aZbAXX0HItf1GIdDj8zQnh+8Pv0DXU7OvdaLVcV4bWA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.6.tgz", + "integrity": "sha512-eFZ2hiAq0bZcFPuFFBmZEtXU1EarHLigE+ENCtpO+37NHCl4+Yokq1P/d09kUblObaikwfo97w+0FtG/EXl5Ng==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/figures": "^1.0.9", "@inquirer/type": "^3.0.2", "yoctocolors-cjs": "^2.1.2" @@ -1595,11 +1595,11 @@ } }, "node_modules/@inquirer/select": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.5.tgz", - "integrity": "sha512-5UAnpWqs0G316MwJdSdgaRcWPIuUPllHa8pdHVi/w9KE/Ff/GzWhPwUn9ETtq/n8GEiWDUrP/LdJN8FJxf7JbA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.0.6.tgz", + "integrity": "sha512-yANzIiNZ8fhMm4NORm+a74+KFYHmf7BZphSOBovIzYPVLquseTGEkU5l2UTnBOf5k0VLmTgPighNDLE9QtbViQ==", "dependencies": { - "@inquirer/core": "^10.1.3", + "@inquirer/core": "^10.1.4", "@inquirer/figures": "^1.0.9", "@inquirer/type": "^3.0.2", "ansi-escapes": "^4.3.2", @@ -2707,9 +2707,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "22.10.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.5.tgz", - "integrity": "sha512-F8Q+SeGimwOo86fiovQh8qiXfFEh2/ocYv7tU5pJ3EXMSSxk1Joj5wefpFK2fHTf/N6HKGSxIDBT9f3gCxXPkQ==", + "version": "22.10.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.6.tgz", + "integrity": "sha512-qNiuwC4ZDAUNcY47xgaSuS92cjf8JbSUoaKS77bmLG1rU7MlATVSiw/IlrjtIyyskXBZ8KkNfjK/P5na7rgXbQ==", "dependencies": { "undici-types": "~6.20.0" } @@ -2893,6 +2893,29 @@ "typescript": ">=4.8.4 <5.8.0" } }, + "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.1.tgz", + "integrity": "sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.19.1", + "@typescript-eslint/types": "8.19.1", + "@typescript-eslint/typescript-estree": "8.19.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ts-api-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", @@ -2969,6 +2992,29 @@ "typescript": ">=4.8.4 <5.8.0" } }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/utils": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.1.tgz", + "integrity": "sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.19.1", + "@typescript-eslint/types": "8.19.1", + "@typescript-eslint/typescript-estree": "8.19.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, "node_modules/@typescript-eslint/type-utils/node_modules/ts-api-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", @@ -3057,15 +3103,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.19.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.1.tgz", - "integrity": "sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==", + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.20.0.tgz", + "integrity": "sha512-dq70RUw6UK9ei7vxc4KQtBRk7qkHZv447OUZ6RPQMQl71I3NZxQJX/f32Smr+iqWrB02pHKn2yAdHBb0KNrRMA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.19.1", - "@typescript-eslint/types": "8.19.1", - "@typescript-eslint/typescript-estree": "8.19.1" + "@typescript-eslint/scope-manager": "8.20.0", + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/typescript-estree": "8.20.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3079,6 +3125,127 @@ "typescript": ">=4.8.4 <5.8.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.20.0.tgz", + "integrity": "sha512-J7+VkpeGzhOt3FeG1+SzhiMj9NzGD/M6KoGn9f4dbz3YzK9hvbhVTmLj/HiTp9DazIzJ8B4XcM80LrR9Dm1rJw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.20.0.tgz", + "integrity": "sha512-cqaMiY72CkP+2xZRrFt3ExRBu0WmVitN/rYPZErA80mHjHx/Svgp8yfbzkJmDoQ/whcytOPO9/IZXnOc+wigRA==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.20.0.tgz", + "integrity": "sha512-Y7ncuy78bJqHI35NwzWol8E0X7XkRVS4K4P4TCyzWkOJih5NDvtoRDW4Ba9YJJoB2igm9yXDdYI/+fkiiAxPzA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.20.0", + "@typescript-eslint/visitor-keys": "8.20.0", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "is-glob": "^4.0.3", + "minimatch": "^9.0.4", + "semver": "^7.6.0", + "ts-api-utils": "^2.0.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "typescript": ">=4.8.4 <5.8.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.20.0.tgz", + "integrity": "sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "8.20.0", + "eslint-visitor-keys": "^4.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/eslint-visitor-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz", + "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==", + "dev": true, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/ts-api-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.0.tgz", + "integrity": "sha512-xCt/TOAc+EOHS1XPnijD3/yzpH6qg2xppZO1YDqGoVsNXfQfzHpOdNuXwrwOU8u4ITXJyDCTyt8w5g1sZv9ynQ==", + "dev": true, + "engines": { + "node": ">=18.12" + }, + "peerDependencies": { + "typescript": ">=4.8.4" + } + }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.19.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.19.1.tgz", @@ -5283,13 +5450,12 @@ } }, "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz", + "integrity": "sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==", "dev": true, - "license": "MIT", "bin": { - "eslint-config-prettier": "bin/cli.js" + "eslint-config-prettier": "build/bin/cli.js" }, "peerDependencies": { "eslint": ">=7.0.0" @@ -6842,12 +7008,12 @@ } }, "node_modules/inquirer": { - "version": "12.3.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.3.1.tgz", - "integrity": "sha512-EEJuhXDogMeu3opiLncf4fvkf25vGxl0cBYv1WIdqV3bvdZraDn0B31zoNqFHe7WndBMctZuYkZ/H/IO1yw8yw==", + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-12.3.2.tgz", + "integrity": "sha512-YjQCIcDd3yyDuQrbII0FBtm/ZqNoWtvaC71yeCnd5Vbg4EgzsAGaemzfpzmqfvIZEp2roSwuZZKdM0C65hA43g==", "dependencies": { - "@inquirer/core": "^10.1.3", - "@inquirer/prompts": "^7.2.2", + "@inquirer/core": "^10.1.4", + "@inquirer/prompts": "^7.2.3", "@inquirer/type": "^3.0.2", "ansi-escapes": "^4.3.2", "mute-stream": "^2.0.0", @@ -12415,6 +12581,29 @@ "typescript": ">=4.8.4 <5.8.0" } }, + "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { + "version": "8.19.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.19.1.tgz", + "integrity": "sha512-IxG5gLO0Ne+KaUc8iW1A+XuKLd63o4wlbI1Zp692n1xojCl/THvgIKXJXBZixTh5dd5+yTJ/VXH7GJaaw21qXA==", + "dev": true, + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@typescript-eslint/scope-manager": "8.19.1", + "@typescript-eslint/types": "8.19.1", + "@typescript-eslint/typescript-estree": "8.19.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.57.0 || ^9.0.0", + "typescript": ">=4.8.4 <5.8.0" + } + }, "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", diff --git a/package.json b/package.json index 2ed51fa76..3999a1872 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "figlet": "^1.8.0", "got": "^14.4.5", "http-status-codes": "^2.3.0", - "inquirer": "^12.3.1", + "inquirer": "^12.3.2", "ip": "^2.0.1", "js-base64": "^3.7.7", "listr2": "^8.2.5", @@ -92,7 +92,7 @@ "@types/ip": "^1.1.3", "@types/mocha": "^10.0.10", "@types/mocha-each": "^2.0.4", - "@types/node": "^22.10.5", + "@types/node": "^22.10.6", "@types/semver": "^7.5.8", "@types/sinon": "^17.0.3", "@types/sinon-chai": "^4.0.0", @@ -101,13 +101,13 @@ "@types/uuid": "^10.0.0", "@types/ws": "^8.5.13", "@types/yargs": "^17.0.33", - "@typescript-eslint/utils": "^8.19.1", + "@typescript-eslint/utils": "^8.20.0", "c8": "^10.1.3", "chai": "^5.1.2", "chai-as-promised": "^8.0.1", "cross-env": "^7.0.3", "eslint": "^9.18.0", - "eslint-config-prettier": "^9.1.0", + "eslint-config-prettier": "^10.0.1", "eslint-plugin-headers": "^1.2.1", "eslint-plugin-import": "^2.30.0", "eslint-plugin-mocha": "^10.5.0", diff --git a/src/commands/network.ts b/src/commands/network.ts index 7a9b53d31..5dea8d64e 100644 --- a/src/commands/network.ts +++ b/src/commands/network.ts @@ -16,7 +16,7 @@ */ import {ListrEnquirerPromptAdapter} from '@listr2/prompt-adapter-enquirer'; import chalk from 'chalk'; -import {Listr, type ListrTask} from 'listr2'; +import {Listr} from 'listr2'; import {IllegalArgumentError, MissingArgumentError, SoloError} from '../core/errors.js'; import {BaseCommand} from './base.js'; import {Flags as flags} from './flags.js'; @@ -40,6 +40,8 @@ import {EnvoyProxyComponent} from '../core/config/remote/components/envoy_proxy_ import {HaProxyComponent} from '../core/config/remote/components/ha_proxy_component.js'; import {v4 as uuidv4} from 'uuid'; import * as Base64 from 'js-base64'; +import type {SoloListrTask} from '../types/index.js'; +import type {Namespace} from '../core/config/remote/types.js'; export interface NetworkDeployConfigClass { applicationEnv: string; @@ -772,10 +774,15 @@ export class NetworkCommand extends BaseCommand { self.logger.error(message); self.logger.showUser(chalk.red(message)); networkDestroySuccess = false; + if (ctx.config.deletePvcs && ctx.config.deleteSecrets && ctx.config.force) { self.k8.deleteNamespace(ctx.config.namespace); + } else { + // If the namespace is not being deleted, + // remove all components data from the remote configuration + self.remoteConfigManager.deleteComponents(); } - }, constants.NETWORK_DESTROY_WAIT_TIMEOUT * 1000); + }, constants.NETWORK_DESTROY_WAIT_TIMEOUT * 1_000); await self.destroyTask(ctx, task); @@ -794,7 +801,7 @@ export class NetworkCommand extends BaseCommand { try { await tasks.run(); - } catch (e: Error | any) { + } catch (e: Error | unknown) { throw new SoloError('Error destroying network', e); } finally { await lease.release(); @@ -947,7 +954,7 @@ export class NetworkCommand extends BaseCommand { } /** Adds the consensus node, envoy and haproxy components to remote config. */ - public addNodesAndProxies(): ListrTask { + public addNodesAndProxies(): SoloListrTask<{config: {namespace: Namespace; nodeAliases: NodeAliases}}> { return { title: 'Add node and proxies to remote config', skip: (): boolean => !this.remoteConfigManager.isLoaded(), diff --git a/src/core/config/local_config.ts b/src/core/config/local_config.ts index 9dbfb910d..679c1921d 100644 --- a/src/core/config/local_config.ts +++ b/src/core/config/local_config.ts @@ -169,7 +169,7 @@ export class LocalConfig implements LocalConfigData { title: 'Prompt local configuration', skip: this.skipPromptTask, task: async (_: any, task: SoloListrTaskWrapper): Promise => { - if (self.configFileExists) { + if (self.configFileExists()) { self.configManager.setFlag(flags.userEmailAddress, self.userEmailAddress); } diff --git a/src/core/config/remote/remote_config_manager.ts b/src/core/config/remote/remote_config_manager.ts index d611d357a..4efbb2661 100644 --- a/src/core/config/remote/remote_config_manager.ts +++ b/src/core/config/remote/remote_config_manager.ts @@ -221,6 +221,13 @@ export class RemoteConfigManager { /* ---------- Utilities ---------- */ + /** Empties the component data inside the remote config */ + public async deleteComponents() { + await this.modify(async remoteConfig => { + remoteConfig.components = ComponentsDataWrapper.initializeEmpty(); + }); + } + public isLoaded(): boolean { return !!this.remoteConfig; }