diff --git a/.gitignore b/.gitignore index f62411788..2b6bc78b6 100644 --- a/.gitignore +++ b/.gitignore @@ -51,3 +51,4 @@ node_modules/ .gradle @rerun.txt test-results +frontend/test-report.xml diff --git a/api/src/main/java/io/kafbat/ui/mapper/ClusterMapper.java b/api/src/main/java/io/kafbat/ui/mapper/ClusterMapper.java index 28793be33..df3051af3 100644 --- a/api/src/main/java/io/kafbat/ui/mapper/ClusterMapper.java +++ b/api/src/main/java/io/kafbat/ui/mapper/ClusterMapper.java @@ -118,6 +118,13 @@ default ConfigSynonymDTO toConfigSynonym(ConfigEntry.ConfigSynonym config) { ReplicaDTO toReplica(InternalReplica replica); + @Mapping(target = "connectorsCount", ignore = true) + @Mapping(target = "failedConnectorsCount", ignore = true) + @Mapping(target = "tasksCount", ignore = true) + @Mapping(target = "failedTasksCount", ignore = true) + @Mapping(target = "version", ignore = true) + @Mapping(target = "commit", ignore = true) + @Mapping(target = "clusterId", ignore = true) ConnectDTO toKafkaConnect(ClustersProperties.ConnectCluster connect); List toFeaturesEnum(List features); diff --git a/api/src/main/java/io/kafbat/ui/mapper/DynamicConfigMapper.java b/api/src/main/java/io/kafbat/ui/mapper/DynamicConfigMapper.java index ebe465660..e913f206e 100644 --- a/api/src/main/java/io/kafbat/ui/mapper/DynamicConfigMapper.java +++ b/api/src/main/java/io/kafbat/ui/mapper/DynamicConfigMapper.java @@ -7,7 +7,7 @@ import io.kafbat.ui.model.ApplicationConfigPropertiesAuthOauth2ResourceServerOpaquetokenDTO; import io.kafbat.ui.model.ApplicationConfigPropertiesDTO; import io.kafbat.ui.model.ApplicationConfigPropertiesKafkaClustersInnerDTO; -import io.kafbat.ui.model.ApplicationConfigPropertiesRbacRolesInnerPermissionsInnerDTO; +import io.kafbat.ui.model.RbacPermissionDTO; import io.kafbat.ui.model.rbac.Permission; import io.kafbat.ui.util.DynamicConfigOperations; import java.util.Optional; @@ -32,7 +32,7 @@ default String map(Resource resource) { @Mapping(source = "metrics.store", target = "metrics.store", ignore = true) ApplicationConfigPropertiesKafkaClustersInnerDTO map(ClustersProperties.Cluster cluster); - default Permission map(ApplicationConfigPropertiesRbacRolesInnerPermissionsInnerDTO perm) { + default Permission map(RbacPermissionDTO perm) { Permission permission = new Permission(); permission.setResource(perm.getResource().getValue()); permission.setActions(perm.getActions().stream().map(ActionDTO::getValue).toList()); diff --git a/api/src/test/java/io/kafbat/ui/service/mcp/McpSpecificationGeneratorTest.java b/api/src/test/java/io/kafbat/ui/service/mcp/McpSpecificationGeneratorTest.java index 6156a0bfa..6cbcf96c5 100644 --- a/api/src/test/java/io/kafbat/ui/service/mcp/McpSpecificationGeneratorTest.java +++ b/api/src/test/java/io/kafbat/ui/service/mcp/McpSpecificationGeneratorTest.java @@ -87,7 +87,7 @@ void testConvertController() { "clusterName", Map.of("type", "string"), "topicName", Map.of("type", "string"), "topicUpdate", SCHEMA_GENERATOR.generateSchema(TopicUpdateDTO.class) - ), List.of("clusterName", "topicName"), false, null, null) + ), List.of("clusterName", "topicName", "topicUpdate"), false, null, null) ) ); assertThat(tools).allMatch(tool -> diff --git a/build.gradle b/build.gradle index f999f4baa..deb45bcf0 100644 --- a/build.gradle +++ b/build.gradle @@ -35,6 +35,7 @@ ext { release = resolveBooleanProperty("release") includeFrontend = resolveBooleanProperty("include-frontend", release) buildDockerImages = resolveBooleanProperty("build-docker-images", release) + useTypeSpec = resolveBooleanProperty("typespec", true) runE2e = resolveBooleanProperty("run-e2e") } diff --git a/contract-typespec/api/acls.tsp b/contract-typespec/api/acls.tsp new file mode 100644 index 000000000..a56ddea5c --- /dev/null +++ b/contract-typespec/api/acls.tsp @@ -0,0 +1,143 @@ +import "@typespec/openapi"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/acls") +@tag("Acls") +interface AclApi { + @summary("listKafkaAcls") + @get + @operationId("listAcls") + listAcls( + @path clusterName: string, + @query resourceType?: KafkaAclResourceType, + @query resourceName?: string, + @query namePatternType?: KafkaAclNamePatternType, + @query search?: string + ): KafkaAcl[]; + + @route("/csv") + @summary("getAclAsCsv") + @get + @operationId("getAclAsCsv") + getAclAsCsv(@path clusterName: string): string; + + @route("/csv") + @summary("syncAclsCsv") + @post + @operationId("syncAclsCsv") + syncAclsCsv(@path clusterName: string, @body content: string): void | ApiBadRequestResponse; + + @post + @operationId("createAcl") + @summary("createAcl") + createAcl(@path clusterName: string, @body acl: KafkaAcl): void | ApiBadRequestResponse; + + @summary("deleteAcl") + @delete + @operationId("deleteAcl") + @summary("deleteAcl") + deleteAcl( + @path clusterName: string, + @body acl: KafkaAcl, + ): void | ApiNotFoundResponse; + + @route("/consumer") + @post + @operationId("createConsumerAcl") + @summary("createConsumerAcl") + createConsumerAcl( + @path clusterName: string, + @body payload: CreateConsumerAcl, + ): void | ApiBadRequestResponse; + + @route("/producer") + @summary("createProducerAcl") + @operationId("createProducerAcl") + @post + createProducerAcl( + @path clusterName: string, + @body payload: CreateProducerAcl, + ): void | ApiBadRequestResponse; + + @route("/streamapp") + @summary("createStreamAppAcl") + @post + @operationId("createStreamAppAcl") + createStreamAppAcl( + @path clusterName: string, + @body payload: CreateStreamAppAcl, + ): void | ApiBadRequestResponse; +} + +model KafkaAcl { + resourceType: KafkaAclResourceType; + resourceName: string; // "*" if acl can be applied to any resource of given type + namePatternType: KafkaAclNamePatternType; + principal: string; + host: string; + operation: KafkaAclOpeations; + permission: "ALLOW" | "DENY"; +} + +alias KafkaAclOpeations = + "UNKNOWN" + | "ALL" + | "READ" + | "WRITE" + | "CREATE" + | "DELETE" + | "ALTER" + | "DESCRIBE" + | "CLUSTER_ACTION" + | "DESCRIBE_CONFIGS" + | "ALTER_CONFIGS" + | "IDEMPOTENT_WRITE" + | "CREATE_TOKENS" + | "DESCRIBE_TOKENS"; + +enum KafkaAclResourceType { + UNKNOWN, + TOPIC, + GROUP, + CLUSTER, + TRANSACTIONAL_ID, + DELEGATION_TOKEN, + USER, +} + +enum KafkaAclNamePatternType { + MATCH, + LITERAL, + PREFIXED, +} + +model CreateConsumerAcl { + principal?: string; + host?: string; + topics?: string[]; + topicsPrefix?: string; + consumerGroups?: string[]; + consumerGroupsPrefix?: string; +} + +model CreateProducerAcl { + principal?: string; + host?: string; + topics?: string[]; + topicsPrefix?: string; + transactionalId?: string; + transactionsIdPrefix?: string; + idempotent?: boolean = false; +} + +model CreateStreamAppAcl { + principal?: string; + host?: string; + inputTopics?: string[]; + outputTopics?: string[]; + applicationId?: string; +} diff --git a/contract-typespec/api/auth.tsp b/contract-typespec/api/auth.tsp new file mode 100644 index 000000000..e8240faea --- /dev/null +++ b/contract-typespec/api/auth.tsp @@ -0,0 +1,47 @@ +import "@typespec/openapi"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@tag("Authorization") +interface AuthorizationApi { + @route("/api/authorization") + @summary("Get user authorization related info") + @operationId("getUserAuthInfo") + @get + getUserAuthInfo(): AuthenticationInfo; +} + +@route("/login") +@summary("Authenticate") +@operationId("authenticate") +@post +@tag("Unmapped") +op authenticate(@header contentType: "application/x-www-form-urlencoded", @body form: LoginForm): void | Http.Response<401>; + + +model LoginForm { + username?: string; + password?: string; +} + +model AuthenticationInfo { + @doc("true if role based access control is enabled and granular permission access is required") + rbacEnabled: boolean; + userInfo?: UserInfo; +} + +model UserInfo { + username: string; + permissions: UserPermission[]; +} + + +model UserPermission { + clusters: string[]; + resource: ResourceType; + value?: string; + actions: Action[]; +} diff --git a/contract-typespec/api/brokers.tsp b/contract-typespec/api/brokers.tsp new file mode 100644 index 000000000..29a2ceca5 --- /dev/null +++ b/contract-typespec/api/brokers.tsp @@ -0,0 +1,128 @@ +import "@typespec/openapi"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/brokers") +@tag("Brokers") +interface BrokersApi { + @get + @operationId("getBrokers") + @summary("getBrokers") + getBrokers(@path clusterName: string): Broker[]; + + @get + @route("/{id}/configs") + @operationId("getBrokerConfig") + @summary("getBrokerConfig") + getBrokerConfig(@path clusterName: string, @path id: int32): BrokerConfig[]; + + @put + @route("/{id}/configs/{name}") + @operationId("updateBrokerConfigByName") + @summary("updateBrokerConfigByName") + updateBrokerConfigByName( + @path clusterName: string, + @path id: int32, + @path name: string, + @body config: BrokerConfigItem, + ): void | ApiBadRequestResponse; + + @get + @route("/{id}/metrics") + @operationId("getBrokersMetrics") + @summary("getBrokersMetrics") + getBrokersMetrics(@path clusterName: string, @path id: int32): BrokerMetrics; + + @get + @route("/logdirs") + @operationId("getAllBrokersLogdirs") + @summary("getAllBrokersLogdirs") + getAllBrokersLogdirs( + @path clusterName: string, + @query broker?: int32[], + ): BrokersLogdirs[]; + + @patch(#{implicitOptionality: true}) + @route("/{id}/logdirs") + @operationId("updateBrokerTopicPartitionLogDir") + @summary("updateBrokerTopicPartitionLogDir") + updateBrokerTopicPartitionLogDir( + @path clusterName: string, + @path id: int32, + @body update: BrokerLogdirUpdate, + ): void | ApiBadRequestResponse; +} + +model Broker { + id: int32; + host?: string; + port?: int32; + bytesInPerSec?: float64; + bytesOutPerSec?: float64; + partitionsLeader?: int32; + partitions?: int32; + inSyncPartitions?: int32; + partitionsSkew?: float64; + leadersSkew?: float64; +} + +model BrokerLogdirUpdate { + topic?: string; + partition?: int32; + logDir?: string; +} + +model BrokerConfig { + name: string; + value: string; + source: ConfigSource; + isSensitive: boolean; + isReadOnly: boolean; + synonyms?: ConfigSynonym[]; +} + +model BrokerConfigItem { + value?: string; +} + +model BrokerLogdirs { + name?: string; + error?: string; + topics?: TopicLogdirs[]; +} + +model TopicLogdirs { + name?: string; + partitions?: TopicPartitionLogdir[]; +} + +model BrokerMetrics { + segmentSize?: int64; + segmentCount?: int32; + metrics?: Metric[]; +} + +model BrokersLogdirs { + name?: string; + error?: string; + topics?: BrokerTopicLogdirs[]; +} + +model BrokerTopicLogdirs { + name?: string; + partitions?: BrokerTopicPartitionLogdir[]; +} + +model BrokerTopicPartitionLogdir { + ...TopicPartitionLogdir; + broker?: int32; +} + +model TopicPartitionLogdir { + partition?: int32; + size?: int64; + offsetLag?: int64; +} diff --git a/contract-typespec/api/clusters.tsp b/contract-typespec/api/clusters.tsp new file mode 100644 index 000000000..388aeae8c --- /dev/null +++ b/contract-typespec/api/clusters.tsp @@ -0,0 +1,98 @@ +import "@typespec/openapi"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters") +@tag("Clusters") +interface ClustersApi { + @get + @operationId("getClusters") + @summary("getClusters") + getClusters(): Cluster[]; + + @post + @route("/{clusterName}/cache") + @operationId("updateClusterInfo") + @summary("updateClusterInfo") + updateClusterInfo(@path clusterName: string): Cluster; + + @get + @route("/{clusterName}/metrics") + @operationId("getClusterMetrics") + @summary("getClusterMetrics") + getClusterMetrics(@path clusterName: string): ClusterMetrics; + + @get + @route("/{clusterName}/stats") + @operationId("getClusterStats") + @summary("getClusterStats") + getClusterStats(@path clusterName: string): ClusterStats; +} + +model Cluster { + name: string; + defaultCluster?: boolean; + status: ServerStatus; + lastError?: MetricsCollectionError; + brokerCount?: int32; + onlinePartitionCount?: int32; + topicCount?: int32; + bytesInPerSec?: float64; + bytesOutPerSec?: float64; + readOnly?: boolean; + version?: string; + features?: ClusterFeature[]; +} + +alias ClusterFeature = + "SCHEMA_REGISTRY" + | "KAFKA_CONNECT" + | "KSQL_DB" + | "TOPIC_DELETION" + | "KAFKA_ACL_VIEW" + | "KAFKA_ACL_EDIT" + | "CLIENT_QUOTA_MANAGEMENT" + | "GRAPHS_ENABLED"; + +enum ServerStatus { + ONLINE, + OFFLINE, + INITIALIZING, +} + +model ClusterMetrics { + items: Metric[]; +} + +model ClusterStats { + brokerCount?: int32; + #deprecated "Unused" + zooKeeperStatus?: int32; + + @doc("Id of broker which is cluster's controller. null, if controller not known yet.") + activeControllers?: int32; + + onlinePartitionCount?: int32; + offlinePartitionCount?: int32; + inSyncReplicasCount?: int32; + outOfSyncReplicasCount?: int32; + underReplicatedPartitionCount?: int32; + diskUsage?: BrokerDiskUsage[]; + version?: string; +} + +model MetricsCollectionError { + message?: string; + stackTrace?: string; +} + + +model BrokerDiskUsage { + brokerId: int32; + segmentSize?: int64; + segmentCount?: int32; +} diff --git a/contract-typespec/api/config.tsp b/contract-typespec/api/config.tsp new file mode 100644 index 000000000..eea72c412 --- /dev/null +++ b/contract-typespec/api/config.tsp @@ -0,0 +1,322 @@ +import "@typespec/openapi"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/info") +@summary("Gets application info") +@get +@tag("ApplicationConfig") +op getApplicationInfo(): ApplicationInfo; + +@route("/api/config") +@tag("ApplicationConfig") +interface ApplicationConfigApi { + @summary("Gets current application configuration") + @get + @operationId("getCurrentConfig") + getCurrentConfig(): ApplicationConfig; + + @put + @summary("Restarts application with specified configuration") + @operationId("restartWithConfig") + restartWithConfig(@body config: RestartRequest): void | ApiBadRequestResponse; + + @put + @route("/validated") + @summary("Restarts application with specified configuration") + @operationId("validateConfig") + validateConfig(@body config: ApplicationConfig): ApplicationConfigValidation | ApiBadRequestResponse; + + @post + @route("/relatedfiles") + @summary("Upload config related file") + @operationId("uploadConfigRelatedFile") + uploadConfigRelatedFile( + @multipartBody body: { + file: HttpPart; + } + ): UploadedFileInfo; + + @get + @route("/authentication") + @summary("Get authentication methods enabled for the app and other related settings") + @operationId("getAuthenticationSettings") + getAuthenticationSettings(): AppAuthenticationSettings; +} + + +model ApplicationInfo { + enabledFeatures?: ApplicationFeature[]; + build?: { + commitId?: string; + version?: string; + buildTime?: string; + isLatestRelease?: boolean; + }; + latestRelease?: { + versionTag?: string; + publishedAt?: string; + htmlUrl?: string; + }; +} + +model ApplicationConfig { + properties: { + auth?: { + type: string; + oauth2: { + client?: Record<{ + provider: string; + clientId: string; + clientSecret?: string; + clientName?: string; + redirectUri?: string; + authorizationGrantType?: string; + issuerUri?: string; + authorizationUri?: string; + tokenUri?: string; + userInfoUri?: string; + jwkSetUri?: string; + userNameAttribute?: string; + scope?: string[]; + customParams?: Record; + }>; + resourceServer?: { + jwt?: { + jwkSetUri?: string; + jwsAlgorithms?: string[]; + issuerUri?: string; + publicKeyLocation?: string; + audiences?: string[]; + authorityPrefix?: string; + authoritiesClaimDelimiter?: string; + authoritiesClaimName?: string; + principalClaimName?: string; + }; + opaquetoken?: { + clientId?: string; + clientSecret?: string; + introspectionUri?: string; + }; + }; + }; + }; + rbac?: { + roles?: { + name?: string; + clusters?: string[]; + subjects?: { + provider?: string; + type?: string; + value?: string; + regex?: boolean = false; + }[]; + permissions?: RbacPermission[]; + }[]; + defaultRole?: { + permissions?: RbacPermission[]; + } + }; + webclient?: { + maxInMemoryBufferSize?: string; + responseTimeoutMs?: int32; + }; + kafka?: { + polling?: { + pollTimeoutMs?: int32; + maxPageSize?: int32; + defaultPageSize?: int32; + responseTimeoutMs?: int32; + }; + adminClientTimeout?: int32; + internalTopicPrefix?: string; + defaultMetricsStorage?: ClusterMetricsStoreConfig; + cache?: { + enabled?: boolean; + @format("duration") + connectCacheExpiry?: string; + @format("duration") + connectClusterCacheExpiry?: string; + }; + clusters?: { + name?: string; + bootstrapServers?: string; + ssl?: { + truststoreLocation?: string; + truststorePassword?: string; + verifySsl?: boolean = true; + }; + schemaRegistry?: string; + schemaRegistryAuth?: { + username?: string; + password?: string; + }; + schemaRegistrySsl?: { + keystoreLocation?: string; + keystorePassword?: string; + }; + ksqldbServer?: string; + ksqldbServerSsl?: { + keystoreLocation?: string; + keystorePassword?: string; + }; + ksqldbServerAuth?: { + username?: string; + password?: string; + }; + kafkaConnect?: { + name?: string; + address?: string; + username?: string; + password?: string; + keystoreLocation?: string; + keystorePassword?: string; + }[]; + metrics?: { + type?: string; + port?: int32; + ssl?: boolean; + username?: string; + password?: string; + keystoreLocation?: string; + keystorePassword?: string; + prometheusExpose?: boolean; + store?: ClusterMetricsStoreConfig; + }; + properties?: Record; + consumerProperties?: Record; + producerProperties?: Record; + readOnly?: boolean; + serde?: { + name?: string; + className?: string; + filePath?: string; + properties?: Record; + topicKeysPattern?: string; + topicValuesPattern?: string; + }[]; + defaultKeySerde?: string; + defaultValueSerde?: string; + masking?: { + type?: "REMOVE" | "MASK" | "REPLACE"; + fields?: string[]; + fieldsNamePattern?: string; + maskingCharsReplacement?: string[]; + replacement?: string; + topicKeysPattern?: string; + topicValuesPattern?: string; + }[]; + pollingThrottleRate?: int64; + audit?: { + level?: "ALL" | "ALTER_ONLY"; + topic?: string; + auditTopicsPartitions?: int32; + topicAuditEnabled?: boolean; + consoleAuditEnabled?: boolean; + auditTopicProperties?: Record; + }; + }[]; + }; + }; +} + +model ApplicationConfigValidation { + clusters?: Record; +} + +model ApplicationPropertyValidation { + error: boolean; + + @doc("Contains error message if error = true") + errorMessage?: string; +} + +model ClusterConfigValidation { + kafka: ApplicationPropertyValidation; + schemaRegistry?: ApplicationPropertyValidation; + kafkaConnects?: Record; + ksqldb?: ApplicationPropertyValidation; + prometheusStorage?: ApplicationPropertyValidation; +} + +alias ApplicationFeature = + "DYNAMIC_CONFIG"; + +enum AuthType { + DISABLED, + OAUTH2, + LOGIN_FORM, + LDAP +} + +model AppAuthenticationSettings { + authType?: Api.AuthType; + oAuthProviders?: OAuthProvider[]; +} + +model OAuthProvider { + clientName: string; + authorizationUri: string; +} + +model RestartRequest { + config?: ApplicationConfig; +} + +model UploadedFileInfo { + location: string; +} + +enum Action { + ALL, + VIEW, + EDIT, + CREATE, + DELETE, + RESET_OFFSETS, + EXECUTE, + MODIFY_GLOBAL_COMPATIBILITY, + ANALYSIS_VIEW, + ANALYSIS_RUN, + MESSAGES_READ, + MESSAGES_PRODUCE, + MESSAGES_DELETE, + OPERATE, + RESTART, +} + +enum ResourceType { + APPLICATIONCONFIG, + CLUSTERCONFIG, + TOPIC, + CONSUMER, + SCHEMA, + CONNECT, + KSQL, + ACL, + AUDIT, + CLIENT_QUOTAS, +} + +model ClusterMetricsStoreConfig { + prometheus?: PrometheusStorage; +} + +model PrometheusStorage { + url?: string; + remoteWrite?: boolean; + pushGatewayUrl?: string; + pushGatewayUsername?: string; + pushGatewayPassword?: string; + pushGatewayJobName?: string; +} + +model RbacPermission { + resource?: ResourceType; + value?: string; + actions?: Action[]; +} diff --git a/contract-typespec/api/consumer-groups.tsp b/contract-typespec/api/consumer-groups.tsp new file mode 100644 index 000000000..d901fc001 --- /dev/null +++ b/contract-typespec/api/consumer-groups.tsp @@ -0,0 +1,147 @@ +import "@typespec/openapi"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/consumer-groups") +@tag("Consumer Groups") +interface ConsumerGroupsApi { + @get + @route("/paged") + @operationId("getConsumerGroupsPage") + @summary("getConsumerGroupsPage") + getConsumerGroupsPage( + @path clusterName: string, + @query page?: int32, + @query perPage?: int32, + @query search?: string, + @query orderBy?: ConsumerGroupOrdering, + @query sortOrder?: SortOrder, + ): ConsumerGroupsPageResponse; + + @get + @route("/{id}") + @operationId("getConsumerGroup") + @summary("getConsumerGroup") + getConsumerGroup( + @path clusterName: string, + @path id: string, + ): ConsumerGroupDetails; + + @delete + @route("/{id}") + @operationId("deleteConsumerGroup") + @summary("deleteConsumerGroup") + deleteConsumerGroup(@path clusterName: string, @path id: string): void; + + @post + @route("/{id}/offsets") + @operationId("resetConsumerGroupOffsets") + @summary("resetConsumerGroupOffsets") + resetConsumerGroupOffsets( + @path clusterName: string, + @path id: string, + @body reset: ConsumerGroupOffsetsReset, + ): void; + + @delete + @route("/{id}/topics/{topicName}") + @operationId("deleteConsumerGroupOffsets") + @summary("deleteConsumerGroupOffsets") + deleteConsumerGroupOffsets( + @path clusterName: string, + @path id: string, + @path topicName: string, + ): void; +} + +@route("/api/clusters/{clusterName}/topics/{topicName}/consumer-groups") +@tag("Consumer Groups") +interface TopicConsumerGroupsApi { + @get + @operationId("getTopicConsumerGroups") + @summary("getTopicConsumerGroups") + getTopicConsumerGroups( + @path clusterName: string, + @path topicName: string, + ): ConsumerGroup[]; +} + +enum ConsumerGroupState { + UNKNOWN, + PREPARING_REBALANCE, + COMPLETING_REBALANCE, + STABLE, + DEAD, + EMPTY, +} + +@discriminator("inherit") +model ConsumerGroup { + @invisible(Lifecycle) + inherit: string; + groupId: string; + members?: int32; + topics?: int32; + simple?: boolean; + partitionAssignor?: string; + state?: ConsumerGroupState; + coordinator?: Broker; + + @doc("null if consumer group has no offsets committed") + consumerLag?: int64; +} + + +model ConsumerGroupDetails extends ConsumerGroup { + @invisible(Lifecycle) + inherit: "details"; + partitions?: ConsumerGroupTopicPartition[]; +} + +enum ConsumerGroupOrdering { + NAME, + MEMBERS, + STATE, + MESSAGES_BEHIND, + TOPIC_NUM, +} + +model ConsumerGroupsPageResponse { + pageCount?: int32; + consumerGroups?: ConsumerGroup[]; +} + +model ConsumerGroupOffsetsReset { + topic: string; + resetType: ConsumerGroupOffsetsResetType; + partitions?: int32[]; + resetToTimestamp?: int64; + partitionsOffsets?: PartitionOffset[]; +} + +enum ConsumerGroupOffsetsResetType { + EARLIEST, + LATEST, + TIMESTAMP, + OFFSET, +} + +model ConsumerGroupTopicPartition { + topic: string; + partition: int32; + currentOffset?: int64; + endOffset?: int64; + consumerLag?: int64; // null if consumer group has no offsets committed + consumerId?: string; + host?: string; +} + +model PartitionOffset { + partition: int32; + offset?: int64; +} + diff --git a/contract-typespec/api/graphs.tsp b/contract-typespec/api/graphs.tsp new file mode 100644 index 000000000..a50ca14e8 --- /dev/null +++ b/contract-typespec/api/graphs.tsp @@ -0,0 +1,91 @@ +import "@typespec/openapi"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/graphs") +@tag("Graphs") +interface GraphsApi { + @get + @operationId("getGraphsList") + @summary("getGraphsList") + getGraphsList( + @path clusterName: string + ): GraphDescriptions; + + @post + @operationId("getGraphData") + @summary("getGraphData") + getGraphData( + @path clusterName: string, + @body request: GraphDataRequest + ) : PrometheusApiQueryResponse +} + +model GraphDescriptions { + graphs?: Array; +} + +model GraphDescription { + @doc("Id that should be used to query data on API level") + id: string; + type?: "range" | "instant"; + @doc(""" + ISO_8601 duration string (for "range" graphs only) + """) + defaultPeriod?: string; + parameters?: Array; +} + +model GraphParameter { + name: string; +} + +model GraphDataRequest { + id?: string; + parameters?: Record; + from?: offsetDateTime; + to?: offsetDateTime; +} + +model PrometheusApiBaseResponse { + status: "success" | "error"; + error?: string; + errorType?: string; + warnings?: Array; +} + +model PrometheusApiQueryResponse extends PrometheusApiBaseResponse { + data?: PrometheusApiQueryResponseData; +} + +model PrometheusApiQueryResponseData { + resultType: "matrix" | "vector" | "scalar" | "string"; + @doc(""" + Depending on resultType format can vary: + "vector": + [ + { + "metric": { "": "", ... }, + "value": [ , "" ], + "histogram": [ , ] + }, ... + ] + "matrix": + [ + { + "metric": { "": "", ... }, + "values": [ [ , "" ], ... ], + "histograms": [ [ , ], ... ] + }, ... + ] + "scalar": + [ , "" ] + "string": + [ , "" ] + """) + result?: Array; +} diff --git a/contract-typespec/api/kafka-connect.tsp b/contract-typespec/api/kafka-connect.tsp new file mode 100644 index 000000000..585e0ac79 --- /dev/null +++ b/contract-typespec/api/kafka-connect.tsp @@ -0,0 +1,305 @@ +import "@typespec/openapi"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/connects") +@tag("Kafka Connect") +interface ConnectInstancesApi { + @get + @operationId("getConnects") + @summary("getConnects") + getConnects(@path clusterName: string, @query withStats?: boolean): Connect[]; + + @get + @route("/{connectName}/plugins") + @summary("get connector plugins") + @operationId("getConnectorPlugins") + getConnectorPlugins( + @path clusterName: string, + @path connectName: string, + ): ConnectorPlugin[]; + + @put + @route("/{connectName}/plugins/{pluginName}/config/validate") + @summary("validate connector plugin configuration") + @operationId("validateConnectorPluginConfig") + validateConnectorPluginConfig( + @path clusterName: string, + @path connectName: string, + @path pluginName: string, + @body config: ConnectorConfig, + ): ConnectorPluginConfigValidationResponse; +} + +// /api/clusters/{clusterName}/connectors +@route("/api/clusters/{clusterName}/connectors") +@tag("Kafka Connect") +interface ConnectorsApi { + @get + @operationId("getAllConnectors") + @summary("getAllConnectors") + getAllConnectors( + @path clusterName: string, + @query search?: string, + @query orderBy?: ConnectorColumnsToSort, + @query sortOrder?: SortOrder, + ): FullConnectorInfo[]; +} + +// /api/clusters/{clusterName}/connects/{connectName}/connectors +@route("/api/clusters/{clusterName}/connects/{connectName}/connectors") +@tag("Kafka Connect") +interface KafkaConnectConnectorsApi { + @get + @operationId("getConnectors") + @summary("getConnectors") + getConnectors(@path clusterName: string, @path connectName: string): string[]; + + @post + @operationId("createConnector") + @summary("createConnector") + createConnector( + @path clusterName: string, + @path connectName: string, + @body connector: NewConnector, + ): Connector | ApiRebalanceInProgressResponse; + + @get + @route("/{connectorName}") + @operationId("getConnector") + @summary("getConnector") + getConnector( + @path clusterName: string, + @path connectName: string, + @path connectorName: string, + ): Connector; + + @delete + @route("/{connectorName}") + @operationId("deleteConnector") + @summary("deleteConnector") + deleteConnector( + @path clusterName: string, + @path connectName: string, + @path connectorName: string, + ): void | ApiRebalanceInProgressResponse; + + @post + @route("/{connectorName}/action/{action}") + @operationId("updateConnectorState") + @summary("updateConnectorState") + updateConnectorState( + @path clusterName: string, + @path connectName: string, + @path connectorName: string, + @path action: ConnectorAction, + ): void | ApiRebalanceInProgressResponse | ApiBadRequestResponse; + + @get + @route("/{connectorName}/config") + @operationId("getConnectorConfig") + @summary("getConnectorConfig") + getConnectorConfig( + @path clusterName: string, + @path connectName: string, + @path connectorName: string, + ): ConnectorConfig; + + @put + @route("/{connectorName}/config") + @operationId("setConnectorConfig") + @summary("setConnectorConfig") + setConnectorConfig( + @path clusterName: string, + @path connectName: string, + @path connectorName: string, + @body config: ConnectorConfig, + ): Connector | ApiRebalanceInProgressResponse | ApiBadRequestResponse; + + @get + @route("/{connectorName}/tasks") + @operationId("getConnectorTasks") + @summary("getConnectorTasks") + getConnectorTasks( + @path clusterName: string, + @path connectName: string, + @path connectorName: string, + ): Task[]; + + @post + @route("/{connectorName}/tasks/{taskId}/action/restart") + @operationId("restartConnectorTask") + @summary("restartConnectorTask") + restartConnectorTask( + @path clusterName: string, + @path connectName: string, + @path connectorName: string, + @path taskId: int32, + ): void | ApiBadRequestResponse; + + @delete + @route("/{connectorName}/offsets") + @operationId("resetConnectorOffsets") + @summary("resetConnectorOffsets") + resetConnectorOffsets( + @path clusterName: string, + @path connectName: string, + @path connectorName: string, + ): void | ApiBadRequestResponse; +} + + +model Connect { + name: string; + address?: string; + connectorsCount?: int32 | null; + failedConnectorsCount?: int32 | null; + tasksCount?: int32 | null; + failedTasksCount?: int32 | null; + version?: string | null; + commit?: string | null; + clusterId?: string | null; +} + +model ConnectorConfig is Record; + +model TaskId { + connector?: string; + task?: int32; +} + +model TaskStatus { + id: int32; + state: ConnectorTaskStatus; + workerId: string; + trace?: string; +} + +model Task { + id?: TaskId; + status: TaskStatus; + config?: ConnectorConfig; +} + +model NewConnector { + name: string; + config: ConnectorConfig; +} + +enum ConnectorType { + SOURCE, + SINK, +} + +enum ConnectorTaskStatus { + RUNNING, + FAILED, + PAUSED, + RESTARTING, + UNASSIGNED, +} + +enum ConnectorState { + RUNNING, + FAILED, + PAUSED, + UNASSIGNED, + TASK_FAILED, + RESTARTING, + STOPPED, +} + +model ConnectorStatus { + state: ConnectorState; + workerId?: string; +} + +model Connector { + ...NewConnector; + tasks?: TaskId[]; + type: ConnectorType; + status: ConnectorStatus; + connect: string; +} + +enum ConnectorAction { + RESTART, + RESTART_ALL_TASKS, + RESTART_FAILED_TASKS, + PAUSE, + RESUME, + STOP +} + +enum TaskAction { + restart, +} + +model ConnectorPlugin { + class?: string; +} + +model ConnectorPluginConfigDefinition { + name?: string; + type?: + | "BOOLEAN" + | "CLASS" + | "DOUBLE" + | "INT" + | "LIST" + | "LONG" + | "PASSWORD" + | "SHORT" + | "STRING"; + required?: boolean; + defaultValue?: string; + importance?: "LOW" | "MEDIUM" | "HIGH"; + documentation?: string; + group?: string; + width?: "SHORT" | "MEDIUM" | "LONG" | "NONE"; + displayName?: string; + dependents?: string[]; + order?: int32; +} + +model ConnectorPluginConfigValue { + name?: string; + value?: string; + recommendedValues?: string[]; + errors?: string[]; + visible?: boolean; +} + +model ConnectorPluginConfig { + definition?: ConnectorPluginConfigDefinition; + value?: ConnectorPluginConfigValue; +} + +model ConnectorPluginConfigValidationResponse { + name?: string; + errorCount?: int32; + groups?: string[]; + configs?: ConnectorPluginConfig[]; +} + +model FullConnectorInfo { + connect: string; + name: string; + connectorClass?: string; + type?: ConnectorType; + topics?: string[]; + status: ConnectorStatus; + tasksCount?: integer; + failedTasksCount?: integer; +} + +enum ConnectorColumnsToSort { + NAME, + CONNECT, + TYPE, + STATUS, +} diff --git a/contract-typespec/api/ksql.tsp b/contract-typespec/api/ksql.tsp new file mode 100644 index 000000000..b6a84836d --- /dev/null +++ b/contract-typespec/api/ksql.tsp @@ -0,0 +1,76 @@ +import "@typespec/openapi"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/ksql") +@tag("Ksql") +interface KsqlApi { + @post + @route("/v2") + @operationId("executeKsql") + @summary("executeKsql") + executeKsql( + @path clusterName: string, + @body command: KsqlCommandV2, + ): KsqlCommandV2Response | ApiBadRequestResponse; + + @get + @route("/tables") + @operationId("listTables") + @summary("listTables") + listTables(@path clusterName: string): KsqlTableDescription[]; + + @get + @route("/streams") + @operationId("listStreams") + @summary("listStreams") + listStreams(@path clusterName: string): KsqlStreamDescription[]; + + @get + @route("/response") + @operationId("openKsqlResponsePipe") + @summary("openKsqlResponsePipe") + openKsqlResponsePipe( + @path clusterName: string, + @query pipeId: string, + ): SseResponse; +} + + +model KsqlCommandV2 { + ksql: string; + streamsProperties?: Record; +} + +model KsqlCommandV2Response { + pipeId: string; +} + +model KsqlTableDescription { + name?: string; + topic?: string; + keyFormat?: string; + valueFormat?: string; + isWindowed?: boolean; +} + +model KsqlStreamDescription { + name?: string; + topic?: string; + keyFormat?: string; + valueFormat?: string; +} + +model KsqlTableResponse { + header?: string; + columnNames?: string[]; + values?: unknown[][]; +} + +model KsqlResponse { + table?: KsqlTableResponse; +} diff --git a/contract-typespec/api/main.tsp b/contract-typespec/api/main.tsp new file mode 100644 index 000000000..a810a5b93 --- /dev/null +++ b/contract-typespec/api/main.tsp @@ -0,0 +1,33 @@ +// APIs +import "./clusters.tsp"; +import "./brokers.tsp"; +import "./topics.tsp"; +import "./messages.tsp"; +import "./consumer-groups.tsp"; +import "./schemas.tsp"; +import "./kafka-connect.tsp"; +import "./ksql.tsp"; +import "./acls.tsp"; +import "./quotas.tsp"; +import "./auth.tsp"; +import "./config.tsp"; +import "./graphs.tsp"; +import "./prometheus.tsp"; + +import "@typespec/http"; +import "@typespec/rest"; +import "@typespec/openapi"; + +using TypeSpec.OpenAPI; +using Http; +using Rest; + +@service(#{ title: "Kafbat UI Api Service" }) +@info(#{ + contact: #{ name: "API Support", email: "support@kafbat.io" }, + license: #{ name: "Apache 2.0", url: "https://www.apache.org/licenses/LICENSE-2.0.html" }, + version: "0.2.0" +}) +@server("http://localhost:8080", "Default endpoint for Kafbat UI API") +namespace Api; + diff --git a/contract-typespec/api/messages.tsp b/contract-typespec/api/messages.tsp new file mode 100644 index 000000000..75f728f86 --- /dev/null +++ b/contract-typespec/api/messages.tsp @@ -0,0 +1,241 @@ +import "@typespec/openapi"; +import "./models.tsp"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/topics/{topicName}") +@tag("Messages") +interface MessagesApi { + @get + @route("/serdes") + @operationId("getSerdes") + @summary("getSerdes") + getSerdes( + @path clusterName: string, + @path topicName: string, + @query use: SerdeUsage, + ): TopicSerdeSuggestion; + + @get + @route("/messages") + @operationId("getTopicMessages") + @summary("getTopicMessages") + getTopicMessages( + @path clusterName: string, + @path topicName: string, + @query seekType?: SeekType, + @query seekTo?: string[], + @query limit?: int32, + @query q?: string, + @query filterQueryType?: MessageFilterType, + @query seekDirection?: SeekDirection, + @query keySerde?: string, + @query valueSerde?: string, + ): SseResponse; + + @delete + @route("/messages") + @operationId("deleteTopicMessages") + @summary("deleteTopicMessages") + deleteTopicMessages( + @path clusterName: string, + @path topicName: string, + @query partitions?: int32[], + ): void | ApiNotFoundResponse | ApiBadRequestResponse; + + @post + @route("/messages") + @operationId("sendTopicMessages") + @summary("sendTopicMessages") + sendTopicMessages( + @path clusterName: string, + @path topicName: string, + @body message: CreateTopicMessage, + ): void | ApiNotFoundResponse | ApiBadRequestResponse; + + @post + @route("/smartfilters") + @operationId("registerFilter") + @summary("registerFilter") + registerFilter( + @path clusterName: string, + @path topicName: string, + @body registration: MessageFilterRegistration, + ): MessageFilterId | ApiBadRequestResponse; + + @get + @route("/messages/v2") + @operationId("getTopicMessagesV2") + @summary("getTopicMessagesV2") + getTopicMessagesV2( + @path clusterName: string, + @path topicName: string, + @query mode?: PollingMode, + @query partitions?: int32[], + @query limit?: int32, + @query stringFilter?: string, + @query smartFilterId?: string, + @query offset?: int64, + @query timestamp?: int64, + @query keySerde?: string, + @query valueSerde?: string, + @query cursor?: string, + ): SseResponse | ApiBadRequestResponse; +} + +@route("/api/smartfilters/testexecutions") +@tag("Messages") +interface SmartFiltersTestExecutionsApi { + @put + @operationId("executeSmartFilterTest") + @summary("executeSmartFilterTest") + executeSmartFilterTest( + @body input: SmartFilterTestExecution, + ): SmartFilterTestExecutionResult | ApiBadRequestResponse; +} + +model TopicSerdeSuggestion { + key?: SerdeDescription[]; + value?: SerdeDescription[]; +} + +enum SerdeUsage { + SERIALIZE, + DESERIALIZE, +} + +model TopicMessageEvent { + type?: "PHASE" | "MESSAGE" | "CONSUMING" | "DONE"; + message?: TopicMessage; + phase?: TopicMessagePhase; + consuming?: TopicMessageConsuming; + cursor?: TopicMessageNextPageCursor; +} + +model TopicMessagePhase { + name?: string; +} + +model TimeStampFormat { + timeStampFormat?: string; +} + +model TopicMessageConsuming { + bytesConsumed?: int64; + elapsedMs?: int64; + isCancelled?: boolean; + messagesConsumed?: int32; + filterApplyErrors?: int32; +} + +model TopicMessageNextPageCursor { + id?: string; +} + +model TopicMessage { + partition: int32; + offset: int64; + timestamp: offsetDateTime; + timestampType?: "NO_TIMESTAMP_TYPE" | "CREATE_TIME" | "LOG_APPEND_TIME"; + key?: string; + headers?: Record; + value?: string; + #deprecated "use 'keySerde' field instead" + keyFormat?: MessageFormat; + #deprecated "use 'valueSerde' field instead" + valueFormat?: MessageFormat; + keySize?: int64; + valueSize?: int64; + #deprecated "use 'keyDeserializeProperties' field instead" + keySchemaId?: string; + #deprecated "use 'valueDeserializeProperties' field instead" + valueSchemaId?: string; + headersSize?: int64; + keySerde?: string; + valueSerde?: string; + keyDeserializeProperties?: Record; + valueDeserializeProperties?: Record; +} + +enum SeekType { + BEGINNING, + OFFSET, + TIMESTAMP, + LATEST, +} + +model MessageFilterRegistration { + filterCode?: string; +} + +model MessageFilterId { + id?: string; +} + +enum PollingMode { + FROM_OFFSET, + TO_OFFSET, + FROM_TIMESTAMP, + TO_TIMESTAMP, + LATEST, + EARLIEST, + TAILING, +} + +enum MessageFilterType { + STRING_CONTAINS, + CEL_SCRIPT, +} + +enum SeekDirection { + FORWARD, + BACKWARD, + TAILING, +} + +model SmartFilterTestExecution { + filterCode: string; + key?: string; + value?: string; + headers?: Record; + partition?: int32; + offset?: int64; + timestampMs?: int64; +} + +model SmartFilterTestExecutionResult { + result?: boolean; + error?: string; +} + +model CreateTopicMessage { + partition: int32; + key?: string | null; + headers?: Record; + value?: string | null; + keySerde?: string | null; + valueSerde?: string | null; +} + +enum MessageFormat { + AVRO, + JSON, + PROTOBUF, + UNKNOWN, +} + + +model SerdeDescription { + name?: string; + description?: string; + + @doc("This serde was automatically chosen by cluster config. This should be enabled in UI by default. Also it will be used for deserialization if no serdes passed.") + preferred?: boolean; + + schema?: string; + additionalProperties?: Record; +} diff --git a/contract-typespec/api/models.tsp b/contract-typespec/api/models.tsp new file mode 100644 index 000000000..ab4b590e7 --- /dev/null +++ b/contract-typespec/api/models.tsp @@ -0,0 +1,25 @@ +namespace Api; + +model Metric { + name?: string; + labels?: Record; + value?: decimal; +} + +enum ConfigSource { + DYNAMIC_TOPIC_CONFIG, + DYNAMIC_BROKER_LOGGER_CONFIG, + DYNAMIC_BROKER_CONFIG, + DYNAMIC_DEFAULT_BROKER_CONFIG, + DYNAMIC_CLIENT_METRICS_CONFIG, + STATIC_BROKER_CONFIG, + DEFAULT_CONFIG, + UNKNOWN, +} + +enum SortOrder { + ASC, + DESC, +} + + diff --git a/contract-typespec/api/package-lock.json b/contract-typespec/api/package-lock.json new file mode 100644 index 000000000..edd3d6ef4 --- /dev/null +++ b/contract-typespec/api/package-lock.json @@ -0,0 +1,2039 @@ +{ + "name": "tsp", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tsp", + "version": "0.1.0", + "dependencies": { + "@typespec/compiler": "1.3.0", + "@typespec/http": "1.3.0", + "@typespec/openapi": "1.3.0", + "@typespec/openapi3": "1.3.0", + "@typespec/rest": "0.73.0", + "@typespec/sse": "0.73.0", + "@typespec/streams": "0.73.0", + "build": "^0.1.4" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-14.0.1.tgz", + "integrity": "sha512-Oc96zvmxx1fqoSEdUmfmvvb59/KDOnUoJ7s2t7bISyAn0XEz57LCCw8k2Y4Pf3mwKaZLMciESALORLgfe2frCw==", + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.15", + "js-yaml": "^4.1.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/philsturgeon" + } + }, + "node_modules/@apidevtools/openapi-schemas": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@apidevtools/openapi-schemas/-/openapi-schemas-2.1.0.tgz", + "integrity": "sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/@apidevtools/swagger-methods": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-methods/-/swagger-methods-3.0.2.tgz", + "integrity": "sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==", + "license": "MIT" + }, + "node_modules/@apidevtools/swagger-parser": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/@apidevtools/swagger-parser/-/swagger-parser-12.0.0.tgz", + "integrity": "sha512-WLJIWcfOXrSKlZEM+yhA2Xzatgl488qr1FoOxixYmtWapBzwSC0gVGq4WObr4hHClMIiFFdOBdixNkvWqkWIWA==", + "license": "MIT", + "dependencies": { + "@apidevtools/json-schema-ref-parser": "14.0.1", + "@apidevtools/openapi-schemas": "^2.1.0", + "@apidevtools/swagger-methods": "^3.0.2", + "ajv": "^8.17.1", + "ajv-draft-04": "^1.0.0", + "call-me-maybe": "^1.0.2" + }, + "peerDependencies": { + "openapi-types": ">=7" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.6.0.tgz", + "integrity": "sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==", + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@dabh/diagnostics": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@dabh/diagnostics/-/diagnostics-2.0.3.tgz", + "integrity": "sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==", + "license": "MIT", + "dependencies": { + "colorspace": "1.1.x", + "enabled": "2.0.x", + "kuler": "^2.0.0" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.8.tgz", + "integrity": "sha512-d/QAsnwuHX2OPolxvYcgSj7A9DO9H6gVOy2DvBTx+P2LH2iRTo/RSGV3iwCzW024nP9hw98KIuDmdyhZQj1UQg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.12", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.12.tgz", + "integrity": "sha512-dpq+ielV9/bqgXRUbNH//KsY6WEw9DrGPmipkpmgC1Y46cwuBTNx7PXFWTjc3MQ+urcc0QxoVHcMI0FW4Ok0hg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.13", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.13.tgz", + "integrity": "sha512-1viSxebkYN2nJULlzCxES6G9/stgHSepZ9LqqfdIGPHj5OHhiBUXVS0a6R0bEC2A+VL4D9w6QB66ebCr6HGllA==", + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.13", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.13.tgz", + "integrity": "sha512-WbicD9SUQt/K8O5Vyk9iC2ojq5RHoCLK6itpp2fHsWe44VxxcA9z3GTWlvjSTGmMQpZr+lbVmrxdHcumJoLbMA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.15.tgz", + "integrity": "sha512-4Y+pbr/U9Qcvf+N/goHzPEXiHH8680lM3Dr3Y9h9FFw4gHS+zVpbj8LfbKWIb/jayIB4aSO4pWiBTrBYWkvi5A==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.12.tgz", + "integrity": "sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.12.tgz", + "integrity": "sha512-xJ6PFZpDjC+tC1P8ImGprgcsrzQRsUh9aH3IZixm1lAZFK49UGHxM3ltFfuInN2kPYNfyoPRh+tU4ftsjPLKqQ==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.15.tgz", + "integrity": "sha512-xWg+iYfqdhRiM55MvqiTCleHzszpoigUpN5+t1OMcRkJrUrw7va3AzXaxvS+Ak7Gny0j2mFSTv2JJj8sMtbV2g==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.15.tgz", + "integrity": "sha512-75CT2p43DGEnfGTaqFpbDC2p2EEMrq0S+IRrf9iJvYreMy5mAWj087+mdKyLHapUEPLjN10mNvABpGbk8Wdraw==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.5.3.tgz", + "integrity": "sha512-8YL0WiV7J86hVAxrh3fE5mDCzcTDe1670unmJRz6ArDgN+DBK1a0+rbnNWp4DUB5rPMwqD5ZP6YHl9KK1mbZRg==", + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.1.8", + "@inquirer/confirm": "^5.1.12", + "@inquirer/editor": "^4.2.13", + "@inquirer/expand": "^4.0.15", + "@inquirer/input": "^4.1.12", + "@inquirer/number": "^3.0.15", + "@inquirer/password": "^4.0.15", + "@inquirer/rawlist": "^4.1.3", + "@inquirer/search": "^3.0.15", + "@inquirer/select": "^4.2.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.3.tgz", + "integrity": "sha512-7XrV//6kwYumNDSsvJIPeAqa8+p7GJh7H5kRuxirct2cgOcSWwwNGoXDRgpNFbY/MG2vQ4ccIWCi8+IXXyFMZA==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.15.tgz", + "integrity": "sha512-YBMwPxYBrADqyvP4nNItpwkBnGGglAvCLVW8u4pRmmvOsHUtCAUIMbUrLX5B3tFL1/WsLGdQ2HNzkqswMs5Uaw==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.2.3.tgz", + "integrity": "sha512-OAGhXU0Cvh0PhLz9xTF/kx6g6x+sP+PcyTiLvCrewI99P3BBeexD+VbuwkNDvqGkk3y2h5ZiWLeRP7BFlhkUDg==", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.13", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.7.tgz", + "integrity": "sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "license": "MIT" + }, + "node_modules/@types/triple-beam": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/triple-beam/-/triple-beam-1.3.5.tgz", + "integrity": "sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==", + "license": "MIT" + }, + "node_modules/@typespec/asset-emitter": { + "version": "0.73.0", + "resolved": "https://registry.npmjs.org/@typespec/asset-emitter/-/asset-emitter-0.73.0.tgz", + "integrity": "sha512-SigCa9k8gS+AiHE7Ky/kcwyqFM5kuJ0wXT+Dy89Jbd+wwrYu+mKXyXbScrTdc+MBzut+rFltFENgEYXsSvA/mA==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.3.0" + } + }, + "node_modules/@typespec/compiler": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@typespec/compiler/-/compiler-1.3.0.tgz", + "integrity": "sha512-OqpoNP3C2y8riA6C5RofPMvmj9jNiGyyhde0tM2ZE7IBOv7BBaTDqw4CJD22YnC8JEilRfPmvdVCViNrPHEjrA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "~7.27.1", + "@inquirer/prompts": "^7.4.0", + "ajv": "~8.17.1", + "change-case": "~5.4.4", + "env-paths": "^3.0.0", + "globby": "~14.1.0", + "is-unicode-supported": "^2.1.0", + "mustache": "~4.2.0", + "picocolors": "~1.1.1", + "prettier": "~3.6.2", + "semver": "^7.7.1", + "tar": "^7.4.3", + "temporal-polyfill": "^0.3.0", + "vscode-languageserver": "~9.0.1", + "vscode-languageserver-textdocument": "~1.0.12", + "yaml": "~2.8.0", + "yargs": "~18.0.0" + }, + "bin": { + "tsp": "cmd/tsp.js", + "tsp-server": "cmd/tsp-server.js" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@typespec/events": { + "version": "0.73.0", + "resolved": "https://registry.npmjs.org/@typespec/events/-/events-0.73.0.tgz", + "integrity": "sha512-etlhp86amDaElD/UX27u9I4O58zREov73HkkV3xbdTWpv2RqOKyD3mkyGAWsW3hKaGVIxwHOvKcOZ2j+b07Gpw==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.3.0" + } + }, + "node_modules/@typespec/http": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@typespec/http/-/http-1.3.0.tgz", + "integrity": "sha512-4W3KsmBHZGgECVbvyh7S7KQG06948XyVVzae+UbVDDxoUj/x4Ry0AXw3q4HmzB2BVhxw6JBrwBuVa5mxjVMzdw==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.3.0", + "@typespec/streams": "^0.73.0" + }, + "peerDependenciesMeta": { + "@typespec/streams": { + "optional": true + } + } + }, + "node_modules/@typespec/openapi": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@typespec/openapi/-/openapi-1.3.0.tgz", + "integrity": "sha512-BSeshjCZQodVGyVHn7ytcUeIcUGjqbG2Ac0NLOQaaKnISVrhTWNcgo5aFTqxAa24ZL/EuhqlSauLyYce2EV9fw==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.3.0", + "@typespec/http": "^1.3.0" + } + }, + "node_modules/@typespec/openapi3": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@typespec/openapi3/-/openapi3-1.3.0.tgz", + "integrity": "sha512-ZG+swQYtdBgyTUbwPI03YQJpPUYhORtbcx6mIFNsKhsTRRC2UDq63jUNCIFCTYI6DJPzkVpra56YPNCXmQLZMg==", + "license": "MIT", + "dependencies": { + "@apidevtools/swagger-parser": "~12.0.0", + "@typespec/asset-emitter": "^0.73.0", + "openapi-types": "~12.1.3", + "yaml": "~2.8.0" + }, + "bin": { + "tsp-openapi3": "cmd/tsp-openapi3.js" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.3.0", + "@typespec/http": "^1.3.0", + "@typespec/json-schema": "^1.3.0", + "@typespec/openapi": "^1.3.0", + "@typespec/versioning": "^0.73.0" + }, + "peerDependenciesMeta": { + "@typespec/json-schema": { + "optional": true + }, + "@typespec/versioning": { + "optional": true + }, + "@typespec/xml": { + "optional": true + } + } + }, + "node_modules/@typespec/rest": { + "version": "0.73.0", + "resolved": "https://registry.npmjs.org/@typespec/rest/-/rest-0.73.0.tgz", + "integrity": "sha512-28hgFGvreBg34Xuguw+E++pQC/kbRxy1Bpx/9nU7x87Ly6ykns3lpx74gjY9ByE8VYKVbXtC7lzdnp19DRSjIQ==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.3.0", + "@typespec/http": "^1.3.0" + } + }, + "node_modules/@typespec/sse": { + "version": "0.73.0", + "resolved": "https://registry.npmjs.org/@typespec/sse/-/sse-0.73.0.tgz", + "integrity": "sha512-WTnRJ1b1M3RPzlHxhnK9sh6+AGKPKWpuA0TSAqzyxb/uRHFYLNeoDKPOnlQ749SJ8lJz71Oh0nUsP3vB0EzO6Q==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.3.0", + "@typespec/events": "^0.73.0", + "@typespec/http": "^1.3.0", + "@typespec/streams": "^0.73.0" + } + }, + "node_modules/@typespec/streams": { + "version": "0.73.0", + "resolved": "https://registry.npmjs.org/@typespec/streams/-/streams-0.73.0.tgz", + "integrity": "sha512-pL4xffHXEIhBQKPlB9L4AKuM0bn44WsGKjnz91wa6wBtP/CbsPrGQicof0Z7GPGdddtDi4G8PWGmJtVFw53V9g==", + "license": "MIT", + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@typespec/compiler": "^1.3.0" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ansi-styles/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ansi-styles/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, + "node_modules/async": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", + "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", + "license": "MIT" + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/build": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/build/-/build-0.1.4.tgz", + "integrity": "sha512-KwbDJ/zrsU8KZRRMfoURG14cKIAStUlS8D5jBDvtrZbwO5FEkYqc3oB8HIhRiyD64A48w1lc+sOmQ+mmBw5U/Q==", + "dependencies": { + "cssmin": "0.3.x", + "jsmin": "1.x", + "jxLoader": "*", + "moo-server": "*", + "promised-io": "*", + "timespan": "2.x", + "uglify-js": "1.x", + "walker": "1.x", + "winston": "*", + "wrench": "1.3.x" + }, + "engines": { + "node": ">v0.4.12" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "license": "MIT" + }, + "node_modules/change-case": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/change-case/-/change-case-5.4.4.tgz", + "integrity": "sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==", + "license": "MIT" + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "license": "MIT" + }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "license": "ISC", + "dependencies": { + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" + }, + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/color": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/color/-/color-3.2.1.tgz", + "integrity": "sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==", + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.3", + "color-string": "^1.6.0" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "license": "MIT" + }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "node_modules/colorspace": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", + "integrity": "sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==", + "license": "MIT", + "dependencies": { + "color": "^3.1.3", + "text-hex": "1.0.x" + } + }, + "node_modules/cssmin": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssmin/-/cssmin-0.3.2.tgz", + "integrity": "sha512-bynxGIAJ8ybrnFobjsQotIjA8HFDDgPwbeUWNXXXfR+B4f9kkxdcUyagJoQCSUOfMV+ZZ6bMn8bvbozlCzUGwQ==", + "bin": { + "cssmin": "bin/cssmin" + } + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "license": "MIT" + }, + "node_modules/enabled": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/enabled/-/enabled-2.0.0.tgz", + "integrity": "sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==", + "license": "MIT" + }, + "node_modules/env-paths": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", + "integrity": "sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/fecha": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/fecha/-/fecha-4.2.3.tgz", + "integrity": "sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==", + "license": "MIT" + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/fn.name": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fn.name/-/fn.name-1.1.0.tgz", + "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==", + "license": "MIT" + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsmin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/jsmin/-/jsmin-1.0.1.tgz", + "integrity": "sha512-OPuL5X/bFKgVdMvEIX3hnpx3jbVpFCrEM8pKPXjFkZUqg521r41ijdyTz7vACOhW6o1neVlcLyd+wkbK5fNHRg==", + "license": "Doug Crockford's license that allows this module to be used for Good but not for Evil", + "bin": { + "jsmin": "bin/jsmin" + }, + "engines": { + "node": ">=0.1.93" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/jxLoader": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jxLoader/-/jxLoader-0.1.1.tgz", + "integrity": "sha512-ClEvAj3K68y8uKhub3RgTmcRPo5DfIWvtxqrKQdDPyZ1UVHIIKvVvjrAsJFSVL5wjv0rt5iH9SMCZ0XRKNzeUA==", + "dependencies": { + "js-yaml": "0.3.x", + "moo-server": "1.3.x", + "promised-io": "*", + "walker": "1.x" + }, + "engines": { + "node": ">v0.4.10" + } + }, + "node_modules/jxLoader/node_modules/js-yaml": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-0.3.7.tgz", + "integrity": "sha512-/7PsVDNP2tVe2Z1cF9kTEkjamIwz4aooDpRKmN1+g/9eePCgcxsv4QDvEbxO0EH+gdDD7MLyDoR6BASo3hH51g==", + "license": "MIT", + "engines": { + "node": "> 0.4.11" + } + }, + "node_modules/kuler": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/kuler/-/kuler-2.0.0.tgz", + "integrity": "sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==", + "license": "MIT" + }, + "node_modules/logform": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/logform/-/logform-2.7.0.tgz", + "integrity": "sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==", + "license": "MIT", + "dependencies": { + "@colors/colors": "1.6.0", + "@types/triple-beam": "^1.3.2", + "fecha": "^4.2.0", + "ms": "^2.1.1", + "safe-stable-stringify": "^2.3.1", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "license": "BSD-3-Clause", + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/moo-server": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/moo-server/-/moo-server-1.3.0.tgz", + "integrity": "sha512-9A8/eor2DXwpv1+a4pZAAydqLFVrWoKoO1fzdzqLUhYVXAO1Kgd1FR2gFZi7YdHzF0s4W8cDNwCfKJQrvLqxDw==", + "engines": { + "node": ">v0.4.10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/mustache": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz", + "integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==", + "license": "MIT", + "bin": { + "mustache": "bin/mustache" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/one-time": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/one-time/-/one-time-1.0.0.tgz", + "integrity": "sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==", + "license": "MIT", + "dependencies": { + "fn.name": "1.x.x" + } + }, + "node_modules/openapi-types": { + "version": "12.1.3", + "resolved": "https://registry.npmjs.org/openapi-types/-/openapi-types-12.1.3.tgz", + "integrity": "sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==", + "license": "MIT" + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/prettier": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz", + "integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==", + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "node_modules/promised-io": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/promised-io/-/promised-io-0.3.6.tgz", + "integrity": "sha512-bNwZusuNIW4m0SPR8jooSyndD35ggirHlxVl/UhIaZD/F0OBv9ebfc6tNmbpZts3QXHggkjIBH8lvtnzhtcz0A==" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-stable-stringify": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", + "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/stack-trace": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", + "integrity": "sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==", + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/temporal-polyfill": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/temporal-polyfill/-/temporal-polyfill-0.3.0.tgz", + "integrity": "sha512-qNsTkX9K8hi+FHDfHmf22e/OGuXmfBm9RqNismxBrnSmZVJKegQ+HYYXT+R7Ha8F/YSm2Y34vmzD4cxMu2u95g==", + "license": "MIT", + "dependencies": { + "temporal-spec": "0.3.0" + } + }, + "node_modules/temporal-spec": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/temporal-spec/-/temporal-spec-0.3.0.tgz", + "integrity": "sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ==", + "license": "ISC" + }, + "node_modules/text-hex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/text-hex/-/text-hex-1.0.0.tgz", + "integrity": "sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==", + "license": "MIT" + }, + "node_modules/timespan": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", + "integrity": "sha512-0Jq9+58T2wbOyLth0EU+AUb6JMGCLaTWIykJFa7hyAybjVH9gpVMTfUAwo5fWAvtFt2Tjh/Elg8JtgNpnMnM8g==", + "engines": { + "node": ">= 0.2.0" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "license": "BSD-3-Clause" + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/triple-beam": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/triple-beam/-/triple-beam-1.4.1.tgz", + "integrity": "sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==", + "license": "MIT", + "engines": { + "node": ">= 14.0.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/uglify-js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz", + "integrity": "sha512-YPX1DjKtom8l9XslmPFQnqWzTBkvI4N0pbkzLuPZZ4QTyig0uQqvZz9NgUdfEV+qccJzi7fVcGWdESvRIjWptQ==", + "bin": { + "uglifyjs": "bin/uglifyjs" + } + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/vscode-jsonrpc": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz", + "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==", + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vscode-languageserver": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-9.0.1.tgz", + "integrity": "sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==", + "license": "MIT", + "dependencies": { + "vscode-languageserver-protocol": "3.17.5" + }, + "bin": { + "installServerIntoExtension": "bin/installServerIntoExtension" + } + }, + "node_modules/vscode-languageserver-protocol": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz", + "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==", + "license": "MIT", + "dependencies": { + "vscode-jsonrpc": "8.2.0", + "vscode-languageserver-types": "3.17.5" + } + }, + "node_modules/vscode-languageserver-textdocument": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz", + "integrity": "sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==", + "license": "MIT" + }, + "node_modules/vscode-languageserver-types": { + "version": "3.17.5", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz", + "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==", + "license": "MIT" + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "license": "Apache-2.0", + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/winston": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/winston/-/winston-3.17.0.tgz", + "integrity": "sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==", + "license": "MIT", + "dependencies": { + "@colors/colors": "^1.6.0", + "@dabh/diagnostics": "^2.0.2", + "async": "^3.2.3", + "is-stream": "^2.0.0", + "logform": "^2.7.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.9.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/winston-transport": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/winston-transport/-/winston-transport-4.9.0.tgz", + "integrity": "sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==", + "license": "MIT", + "dependencies": { + "logform": "^2.7.0", + "readable-stream": "^3.6.2", + "triple-beam": "^1.3.0" + }, + "engines": { + "node": ">= 12.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrench": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/wrench/-/wrench-1.3.9.tgz", + "integrity": "sha512-srTJQmLTP5YtW+F5zDuqjMEZqLLr/eJOZfDI5ibfPfRMeDh3oBUefAscuH0q5wBKE339ptH/S/0D18ZkfOfmKQ==", + "deprecated": "wrench.js is deprecated! You should check out fs-extra (https://github.com/jprichardson/node-fs-extra) for any operations you were using wrench for. Thanks for all the usage over the years.", + "engines": { + "node": ">=0.1.97" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/yaml": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.1.tgz", + "integrity": "sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + } + }, + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "license": "MIT" + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/contract-typespec/api/package.json b/contract-typespec/api/package.json new file mode 100644 index 000000000..ba38d898e --- /dev/null +++ b/contract-typespec/api/package.json @@ -0,0 +1,20 @@ +{ + "name": "tsp", + "version": "0.1.0", + "type": "module", + "dependencies": { + "@typespec/compiler": "1.3.0", + "@typespec/http": "1.3.0", + "@typespec/openapi": "1.3.0", + "@typespec/openapi3": "1.3.0", + "@typespec/rest": "0.73.0", + "@typespec/sse": "0.73.0", + "@typespec/streams": "0.73.0", + "build": "^0.1.4" + }, + "scripts": { + "build": "tsp compile ." + }, + "private": true, + "packageManager": "pnpm@9.15.9+sha512.68046141893c66fad01c079231128e9afb89ef87e2691d69e4d40eee228988295fd4682181bae55b58418c3a253bde65a505ec7c5f9403ece5cc3cd37dcf2531" +} diff --git a/contract-typespec/api/pnpm-lock.yaml b/contract-typespec/api/pnpm-lock.yaml new file mode 100644 index 000000000..5386cf161 --- /dev/null +++ b/contract-typespec/api/pnpm-lock.yaml @@ -0,0 +1,1388 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@typespec/compiler': + specifier: 1.3.0 + version: 1.3.0 + '@typespec/http': + specifier: 1.3.0 + version: 1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)) + '@typespec/openapi': + specifier: 1.3.0 + version: 1.3.0(@typespec/compiler@1.3.0)(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0))) + '@typespec/openapi3': + specifier: 1.3.0 + version: 1.3.0(@typespec/compiler@1.3.0)(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)))(@typespec/openapi@1.3.0(@typespec/compiler@1.3.0)(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)))) + '@typespec/rest': + specifier: 0.73.0 + version: 0.73.0(@typespec/compiler@1.3.0)(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0))) + '@typespec/sse': + specifier: 0.73.0 + version: 0.73.0(@typespec/compiler@1.3.0)(@typespec/events@0.70.0(@typespec/compiler@1.3.0))(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)))(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)) + '@typespec/streams': + specifier: 0.73.0 + version: 0.73.0(@typespec/compiler@1.3.0) + build: + specifier: ^0.1.4 + version: 0.1.4 + +packages: + + '@apidevtools/json-schema-ref-parser@14.0.1': + resolution: {integrity: sha512-Oc96zvmxx1fqoSEdUmfmvvb59/KDOnUoJ7s2t7bISyAn0XEz57LCCw8k2Y4Pf3mwKaZLMciESALORLgfe2frCw==} + engines: {node: '>= 16'} + + '@apidevtools/openapi-schemas@2.1.0': + resolution: {integrity: sha512-Zc1AlqrJlX3SlpupFGpiLi2EbteyP7fXmUOGup6/DnkRgjP9bgMM/ag+n91rsv0U1Gpz0H3VILA/o3bW7Ua6BQ==} + engines: {node: '>=10'} + + '@apidevtools/swagger-methods@3.0.2': + resolution: {integrity: sha512-QAkD5kK2b1WfjDS/UQn/qQkbwF31uqRjPTrsCs5ZG9BQGAkjwvqGFjjPqAuzac/IYzpPtRzjCP1WrTuAIjMrXg==} + + '@apidevtools/swagger-parser@12.0.0': + resolution: {integrity: sha512-WLJIWcfOXrSKlZEM+yhA2Xzatgl488qr1FoOxixYmtWapBzwSC0gVGq4WObr4hHClMIiFFdOBdixNkvWqkWIWA==} + peerDependencies: + openapi-types: '>=7' + + '@babel/code-frame@7.27.1': + resolution: {integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.27.1': + resolution: {integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==} + engines: {node: '>=6.9.0'} + + '@colors/colors@1.6.0': + resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} + engines: {node: '>=0.1.90'} + + '@dabh/diagnostics@2.0.3': + resolution: {integrity: sha512-hrlQOIi7hAfzsMqlGSFyVucrx38O+j6wiGOf//H2ecvIEqYN4ADBSS2iLMh5UFyDunCNniUIPk/q3riFv45xRA==} + + '@inquirer/checkbox@4.1.8': + resolution: {integrity: sha512-d/QAsnwuHX2OPolxvYcgSj7A9DO9H6gVOy2DvBTx+P2LH2iRTo/RSGV3iwCzW024nP9hw98KIuDmdyhZQj1UQg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/confirm@5.1.12': + resolution: {integrity: sha512-dpq+ielV9/bqgXRUbNH//KsY6WEw9DrGPmipkpmgC1Y46cwuBTNx7PXFWTjc3MQ+urcc0QxoVHcMI0FW4Ok0hg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@10.1.13': + resolution: {integrity: sha512-1viSxebkYN2nJULlzCxES6G9/stgHSepZ9LqqfdIGPHj5OHhiBUXVS0a6R0bEC2A+VL4D9w6QB66ebCr6HGllA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/editor@4.2.13': + resolution: {integrity: sha512-WbicD9SUQt/K8O5Vyk9iC2ojq5RHoCLK6itpp2fHsWe44VxxcA9z3GTWlvjSTGmMQpZr+lbVmrxdHcumJoLbMA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/expand@4.0.15': + resolution: {integrity: sha512-4Y+pbr/U9Qcvf+N/goHzPEXiHH8680lM3Dr3Y9h9FFw4gHS+zVpbj8LfbKWIb/jayIB4aSO4pWiBTrBYWkvi5A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@1.0.12': + resolution: {integrity: sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==} + engines: {node: '>=18'} + + '@inquirer/input@4.1.12': + resolution: {integrity: sha512-xJ6PFZpDjC+tC1P8ImGprgcsrzQRsUh9aH3IZixm1lAZFK49UGHxM3ltFfuInN2kPYNfyoPRh+tU4ftsjPLKqQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/number@3.0.15': + resolution: {integrity: sha512-xWg+iYfqdhRiM55MvqiTCleHzszpoigUpN5+t1OMcRkJrUrw7va3AzXaxvS+Ak7Gny0j2mFSTv2JJj8sMtbV2g==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/password@4.0.15': + resolution: {integrity: sha512-75CT2p43DGEnfGTaqFpbDC2p2EEMrq0S+IRrf9iJvYreMy5mAWj087+mdKyLHapUEPLjN10mNvABpGbk8Wdraw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/prompts@7.5.3': + resolution: {integrity: sha512-8YL0WiV7J86hVAxrh3fE5mDCzcTDe1670unmJRz6ArDgN+DBK1a0+rbnNWp4DUB5rPMwqD5ZP6YHl9KK1mbZRg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/rawlist@4.1.3': + resolution: {integrity: sha512-7XrV//6kwYumNDSsvJIPeAqa8+p7GJh7H5kRuxirct2cgOcSWwwNGoXDRgpNFbY/MG2vQ4ccIWCi8+IXXyFMZA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/search@3.0.15': + resolution: {integrity: sha512-YBMwPxYBrADqyvP4nNItpwkBnGGglAvCLVW8u4pRmmvOsHUtCAUIMbUrLX5B3tFL1/WsLGdQ2HNzkqswMs5Uaw==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/select@4.2.3': + resolution: {integrity: sha512-OAGhXU0Cvh0PhLz9xTF/kx6g6x+sP+PcyTiLvCrewI99P3BBeexD+VbuwkNDvqGkk3y2h5ZiWLeRP7BFlhkUDg==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/type@3.0.7': + resolution: {integrity: sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@sindresorhus/merge-streams@2.3.0': + resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==} + engines: {node: '>=18'} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/triple-beam@1.3.5': + resolution: {integrity: sha512-6WaYesThRMCl19iryMYP7/x2OVgCtbIVflDGFpWnb9irXI3UjYE4AzmYuiUKY1AJstGijoY+MgUszMgRxIYTYw==} + + '@typespec/asset-emitter@0.73.0': + resolution: {integrity: sha512-SigCa9k8gS+AiHE7Ky/kcwyqFM5kuJ0wXT+Dy89Jbd+wwrYu+mKXyXbScrTdc+MBzut+rFltFENgEYXsSvA/mA==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@typespec/compiler': ^1.3.0 + + '@typespec/compiler@1.3.0': + resolution: {integrity: sha512-OqpoNP3C2y8riA6C5RofPMvmj9jNiGyyhde0tM2ZE7IBOv7BBaTDqw4CJD22YnC8JEilRfPmvdVCViNrPHEjrA==} + engines: {node: '>=20.0.0'} + hasBin: true + + '@typespec/events@0.70.0': + resolution: {integrity: sha512-qHW1N05n8PkNf2YQGNMdl/sAYqrJv+zQ1kny+3vg/20nzVj7sZpNFIKqUIc11z0GkT7k3Q9SPTymvq+K00sAUg==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@typespec/compiler': ^1.0.0 + + '@typespec/http@1.3.0': + resolution: {integrity: sha512-4W3KsmBHZGgECVbvyh7S7KQG06948XyVVzae+UbVDDxoUj/x4Ry0AXw3q4HmzB2BVhxw6JBrwBuVa5mxjVMzdw==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@typespec/compiler': ^1.3.0 + '@typespec/streams': ^0.73.0 + peerDependenciesMeta: + '@typespec/streams': + optional: true + + '@typespec/openapi3@1.3.0': + resolution: {integrity: sha512-ZG+swQYtdBgyTUbwPI03YQJpPUYhORtbcx6mIFNsKhsTRRC2UDq63jUNCIFCTYI6DJPzkVpra56YPNCXmQLZMg==} + engines: {node: '>=20.0.0'} + hasBin: true + peerDependencies: + '@typespec/compiler': ^1.3.0 + '@typespec/http': ^1.3.0 + '@typespec/json-schema': ^1.3.0 + '@typespec/openapi': ^1.3.0 + '@typespec/versioning': ^0.73.0 + '@typespec/xml': '*' + peerDependenciesMeta: + '@typespec/json-schema': + optional: true + '@typespec/versioning': + optional: true + '@typespec/xml': + optional: true + + '@typespec/openapi@1.3.0': + resolution: {integrity: sha512-BSeshjCZQodVGyVHn7ytcUeIcUGjqbG2Ac0NLOQaaKnISVrhTWNcgo5aFTqxAa24ZL/EuhqlSauLyYce2EV9fw==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@typespec/compiler': ^1.3.0 + '@typespec/http': ^1.3.0 + + '@typespec/rest@0.73.0': + resolution: {integrity: sha512-28hgFGvreBg34Xuguw+E++pQC/kbRxy1Bpx/9nU7x87Ly6ykns3lpx74gjY9ByE8VYKVbXtC7lzdnp19DRSjIQ==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@typespec/compiler': ^1.3.0 + '@typespec/http': ^1.3.0 + + '@typespec/sse@0.73.0': + resolution: {integrity: sha512-WTnRJ1b1M3RPzlHxhnK9sh6+AGKPKWpuA0TSAqzyxb/uRHFYLNeoDKPOnlQ749SJ8lJz71Oh0nUsP3vB0EzO6Q==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@typespec/compiler': ^1.3.0 + '@typespec/events': ^0.73.0 + '@typespec/http': ^1.3.0 + '@typespec/streams': ^0.73.0 + + '@typespec/streams@0.73.0': + resolution: {integrity: sha512-pL4xffHXEIhBQKPlB9L4AKuM0bn44WsGKjnz91wa6wBtP/CbsPrGQicof0Z7GPGdddtDi4G8PWGmJtVFw53V9g==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@typespec/compiler': ^1.3.0 + + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + build@0.1.4: + resolution: {integrity: sha512-KwbDJ/zrsU8KZRRMfoURG14cKIAStUlS8D5jBDvtrZbwO5FEkYqc3oB8HIhRiyD64A48w1lc+sOmQ+mmBw5U/Q==} + engines: {node: '>v0.4.12'} + + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + + change-case@5.4.4: + resolution: {integrity: sha512-HRQyTk2/YPEkt9TnUPbOpr64Uw3KOicFWPVBb+xiHvd6eBx/qPr9xqfBFDT8P2vWsvvz4jbEkfDe71W3VyNu2w==} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color@3.2.1: + resolution: {integrity: sha512-aBl7dZI9ENN6fUGC7mWpMTPNHmWUSNan9tuWN6ahh5ZLNk9baLJOnSMlrQkHcrfFgz2/RigjUVAjdx36VcemKA==} + + colorspace@1.1.4: + resolution: {integrity: sha512-BgvKJiuVu1igBUF2kEjRCZXol6wiiGbY5ipL/oVPwm0BL9sIpMIzM8IK7vwuxIIzOXMV3Ey5w+vxhm0rR/TN8w==} + + cssmin@0.3.2: + resolution: {integrity: sha512-bynxGIAJ8ybrnFobjsQotIjA8HFDDgPwbeUWNXXXfR+B4f9kkxdcUyagJoQCSUOfMV+ZZ6bMn8bvbozlCzUGwQ==} + hasBin: true + + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + enabled@2.0.0: + resolution: {integrity: sha512-AKrN98kuwOzMIdAizXGI86UFBoo26CL21UM763y1h/GMSJ4/OHU9k2YlsmBpyScFo/wbLzWQJBMCW4+IO3/+OQ==} + + env-paths@3.0.0: + resolution: {integrity: sha512-dtJUTepzMW3Lm/NPxRf3wP4642UWhjL2sQxc+ym2YMj1m/H2zDNQOlezafzkHwn6sMstjHTwG6iQQsctDW/b1A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-uri@3.0.6: + resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} + + fastq@1.19.1: + resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} + + fecha@4.2.3: + resolution: {integrity: sha512-OP2IUU6HeYKJi3i0z4A19kHMQoLVs4Hc+DPqqxI2h/DPZHTm/vjsfC6P0b4jCMy14XizLBqvndQ+UilD7707Jw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + fn.name@1.1.0: + resolution: {integrity: sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.3.0: + resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} + engines: {node: '>=18'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + globby@14.1.0: + resolution: {integrity: sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==} + engines: {node: '>=18'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + is-arrayish@0.3.2: + resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@0.3.7: + resolution: {integrity: sha512-/7PsVDNP2tVe2Z1cF9kTEkjamIwz4aooDpRKmN1+g/9eePCgcxsv4QDvEbxO0EH+gdDD7MLyDoR6BASo3hH51g==} + engines: {node: '> 0.4.11'} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsmin@1.0.1: + resolution: {integrity: sha512-OPuL5X/bFKgVdMvEIX3hnpx3jbVpFCrEM8pKPXjFkZUqg521r41ijdyTz7vACOhW6o1neVlcLyd+wkbK5fNHRg==} + engines: {node: '>=0.1.93'} + hasBin: true + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + jxLoader@0.1.1: + resolution: {integrity: sha512-ClEvAj3K68y8uKhub3RgTmcRPo5DfIWvtxqrKQdDPyZ1UVHIIKvVvjrAsJFSVL5wjv0rt5iH9SMCZ0XRKNzeUA==} + engines: {node: '>v0.4.10'} + + kuler@2.0.0: + resolution: {integrity: sha512-Xq9nH7KlWZmXAtodXDDRE7vs6DU1gTU8zYDHDiWLSip45Egwq3plLHzPn27NgvzL2r1LMPC1vdqh98sQxtqj4A==} + + logform@2.7.0: + resolution: {integrity: sha512-TFYA4jnP7PVbmlBIfhlSe+WKxs9dklXMTEGcBCIvLhE/Tn3H6Gk1norupVW7m5Cnd4bLcr08AytbyV/xj7f/kQ==} + engines: {node: '>= 12.0.0'} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.2: + resolution: {integrity: sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==} + engines: {node: '>= 18'} + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + moo-server@1.3.0: + resolution: {integrity: sha512-9A8/eor2DXwpv1+a4pZAAydqLFVrWoKoO1fzdzqLUhYVXAO1Kgd1FR2gFZi7YdHzF0s4W8cDNwCfKJQrvLqxDw==} + engines: {node: '>v0.4.10'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + mustache@4.2.0: + resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} + hasBin: true + + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + + one-time@1.0.0: + resolution: {integrity: sha512-5DXOiRKwuSEcQ/l0kGCF6Q3jcADFv5tSmRaJck/OqkVFcOzutB134KRSfF0xDrL39MNnqxbHBbUUcjZIhTgb2g==} + + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + path-type@6.0.0: + resolution: {integrity: sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==} + engines: {node: '>=18'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + prettier@3.6.2: + resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==} + engines: {node: '>=14'} + hasBin: true + + promised-io@0.3.6: + resolution: {integrity: sha512-bNwZusuNIW4m0SPR8jooSyndD35ggirHlxVl/UhIaZD/F0OBv9ebfc6tNmbpZts3QXHggkjIBH8lvtnzhtcz0A==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + semver@7.7.2: + resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} + engines: {node: '>=10'} + hasBin: true + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + simple-swizzle@0.2.2: + resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} + + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + stack-trace@0.0.10: + resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + temporal-polyfill@0.3.0: + resolution: {integrity: sha512-qNsTkX9K8hi+FHDfHmf22e/OGuXmfBm9RqNismxBrnSmZVJKegQ+HYYXT+R7Ha8F/YSm2Y34vmzD4cxMu2u95g==} + + temporal-spec@0.3.0: + resolution: {integrity: sha512-n+noVpIqz4hYgFSMOSiINNOUOMFtV5cZQNCmmszA6GiVFVRt3G7AqVyhXjhCSmowvQn+NsGn+jMDMKJYHd3bSQ==} + + text-hex@1.0.0: + resolution: {integrity: sha512-uuVGNWzgJ4yhRaNSiubPY7OjISw4sw4E5Uv0wbjp+OzcbmVU/rsT8ujgcXJhn9ypzsgr5vlzpPqP+MBBKcGvbg==} + + timespan@2.3.0: + resolution: {integrity: sha512-0Jq9+58T2wbOyLth0EU+AUb6JMGCLaTWIykJFa7hyAybjVH9gpVMTfUAwo5fWAvtFt2Tjh/Elg8JtgNpnMnM8g==} + engines: {node: '>= 0.2.0'} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + triple-beam@1.4.1: + resolution: {integrity: sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg==} + engines: {node: '>= 14.0.0'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + uglify-js@1.3.5: + resolution: {integrity: sha512-YPX1DjKtom8l9XslmPFQnqWzTBkvI4N0pbkzLuPZZ4QTyig0uQqvZz9NgUdfEV+qccJzi7fVcGWdESvRIjWptQ==} + hasBin: true + + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-textdocument@1.0.12: + resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + winston-transport@4.9.0: + resolution: {integrity: sha512-8drMJ4rkgaPo1Me4zD/3WLfI/zPdA9o2IipKODunnGDcuqbHwjsbB79ylv04LCGGzU0xQ6vTznOMpQGaLhhm6A==} + engines: {node: '>= 12.0.0'} + + winston@3.17.0: + resolution: {integrity: sha512-DLiFIXYC5fMPxaRg832S6F5mJYvePtmO5G9v9IgUFPhXm9/GkXarH/TUrBAVzhTCzAj9anE/+GjrgXp/54nOgw==} + engines: {node: '>= 12.0.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@9.0.0: + resolution: {integrity: sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==} + engines: {node: '>=18'} + + wrench@1.3.9: + resolution: {integrity: sha512-srTJQmLTP5YtW+F5zDuqjMEZqLLr/eJOZfDI5ibfPfRMeDh3oBUefAscuH0q5wBKE339ptH/S/0D18ZkfOfmKQ==} + engines: {node: '>=0.1.97'} + deprecated: wrench.js is deprecated! You should check out fs-extra (https://github.com/jprichardson/node-fs-extra) for any operations you were using wrench for. Thanks for all the usage over the years. + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + engines: {node: '>= 14.6'} + hasBin: true + + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.0.0: + resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yoctocolors-cjs@2.1.2: + resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} + engines: {node: '>=18'} + +snapshots: + + '@apidevtools/json-schema-ref-parser@14.0.1': + dependencies: + '@types/json-schema': 7.0.15 + js-yaml: 4.1.0 + + '@apidevtools/openapi-schemas@2.1.0': {} + + '@apidevtools/swagger-methods@3.0.2': {} + + '@apidevtools/swagger-parser@12.0.0(openapi-types@12.1.3)': + dependencies: + '@apidevtools/json-schema-ref-parser': 14.0.1 + '@apidevtools/openapi-schemas': 2.1.0 + '@apidevtools/swagger-methods': 3.0.2 + ajv: 8.17.1 + ajv-draft-04: 1.0.0(ajv@8.17.1) + call-me-maybe: 1.0.2 + openapi-types: 12.1.3 + + '@babel/code-frame@7.27.1': + dependencies: + '@babel/helper-validator-identifier': 7.27.1 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/helper-validator-identifier@7.27.1': {} + + '@colors/colors@1.6.0': {} + + '@dabh/diagnostics@2.0.3': + dependencies: + colorspace: 1.1.4 + enabled: 2.0.0 + kuler: 2.0.0 + + '@inquirer/checkbox@4.1.8': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/figures': 1.0.12 + '@inquirer/type': 3.0.7 + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.2 + + '@inquirer/confirm@5.1.12': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/type': 3.0.7 + + '@inquirer/core@10.1.13': + dependencies: + '@inquirer/figures': 1.0.12 + '@inquirer/type': 3.0.7 + ansi-escapes: 4.3.2 + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.2 + + '@inquirer/editor@4.2.13': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/type': 3.0.7 + external-editor: 3.1.0 + + '@inquirer/expand@4.0.15': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/type': 3.0.7 + yoctocolors-cjs: 2.1.2 + + '@inquirer/figures@1.0.12': {} + + '@inquirer/input@4.1.12': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/type': 3.0.7 + + '@inquirer/number@3.0.15': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/type': 3.0.7 + + '@inquirer/password@4.0.15': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/type': 3.0.7 + ansi-escapes: 4.3.2 + + '@inquirer/prompts@7.5.3': + dependencies: + '@inquirer/checkbox': 4.1.8 + '@inquirer/confirm': 5.1.12 + '@inquirer/editor': 4.2.13 + '@inquirer/expand': 4.0.15 + '@inquirer/input': 4.1.12 + '@inquirer/number': 3.0.15 + '@inquirer/password': 4.0.15 + '@inquirer/rawlist': 4.1.3 + '@inquirer/search': 3.0.15 + '@inquirer/select': 4.2.3 + + '@inquirer/rawlist@4.1.3': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/type': 3.0.7 + yoctocolors-cjs: 2.1.2 + + '@inquirer/search@3.0.15': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/figures': 1.0.12 + '@inquirer/type': 3.0.7 + yoctocolors-cjs: 2.1.2 + + '@inquirer/select@4.2.3': + dependencies: + '@inquirer/core': 10.1.13 + '@inquirer/figures': 1.0.12 + '@inquirer/type': 3.0.7 + ansi-escapes: 4.3.2 + yoctocolors-cjs: 2.1.2 + + '@inquirer/type@3.0.7': {} + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.19.1 + + '@sindresorhus/merge-streams@2.3.0': {} + + '@types/json-schema@7.0.15': {} + + '@types/triple-beam@1.3.5': {} + + '@typespec/asset-emitter@0.73.0(@typespec/compiler@1.3.0)': + dependencies: + '@typespec/compiler': 1.3.0 + + '@typespec/compiler@1.3.0': + dependencies: + '@babel/code-frame': 7.27.1 + '@inquirer/prompts': 7.5.3 + ajv: 8.17.1 + change-case: 5.4.4 + env-paths: 3.0.0 + globby: 14.1.0 + is-unicode-supported: 2.1.0 + mustache: 4.2.0 + picocolors: 1.1.1 + prettier: 3.6.2 + semver: 7.7.2 + tar: 7.4.3 + temporal-polyfill: 0.3.0 + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.12 + yaml: 2.8.1 + yargs: 18.0.0 + transitivePeerDependencies: + - '@types/node' + + '@typespec/events@0.70.0(@typespec/compiler@1.3.0)': + dependencies: + '@typespec/compiler': 1.3.0 + + '@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0))': + dependencies: + '@typespec/compiler': 1.3.0 + optionalDependencies: + '@typespec/streams': 0.73.0(@typespec/compiler@1.3.0) + + '@typespec/openapi3@1.3.0(@typespec/compiler@1.3.0)(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)))(@typespec/openapi@1.3.0(@typespec/compiler@1.3.0)(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0))))': + dependencies: + '@apidevtools/swagger-parser': 12.0.0(openapi-types@12.1.3) + '@typespec/asset-emitter': 0.73.0(@typespec/compiler@1.3.0) + '@typespec/compiler': 1.3.0 + '@typespec/http': 1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)) + '@typespec/openapi': 1.3.0(@typespec/compiler@1.3.0)(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0))) + openapi-types: 12.1.3 + yaml: 2.8.1 + + '@typespec/openapi@1.3.0(@typespec/compiler@1.3.0)(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)))': + dependencies: + '@typespec/compiler': 1.3.0 + '@typespec/http': 1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)) + + '@typespec/rest@0.73.0(@typespec/compiler@1.3.0)(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)))': + dependencies: + '@typespec/compiler': 1.3.0 + '@typespec/http': 1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)) + + '@typespec/sse@0.73.0(@typespec/compiler@1.3.0)(@typespec/events@0.70.0(@typespec/compiler@1.3.0))(@typespec/http@1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)))(@typespec/streams@0.73.0(@typespec/compiler@1.3.0))': + dependencies: + '@typespec/compiler': 1.3.0 + '@typespec/events': 0.70.0(@typespec/compiler@1.3.0) + '@typespec/http': 1.3.0(@typespec/compiler@1.3.0)(@typespec/streams@0.73.0(@typespec/compiler@1.3.0)) + '@typespec/streams': 0.73.0(@typespec/compiler@1.3.0) + + '@typespec/streams@0.73.0(@typespec/compiler@1.3.0)': + dependencies: + '@typespec/compiler': 1.3.0 + + ajv-draft-04@1.0.0(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.6 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + argparse@2.0.1: {} + + async@3.2.6: {} + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + build@0.1.4: + dependencies: + cssmin: 0.3.2 + jsmin: 1.0.1 + jxLoader: 0.1.1 + moo-server: 1.3.0 + promised-io: 0.3.6 + timespan: 2.3.0 + uglify-js: 1.3.5 + walker: 1.0.8 + winston: 3.17.0 + wrench: 1.3.9 + + call-me-maybe@1.0.2: {} + + change-case@5.4.4: {} + + chardet@0.7.0: {} + + chownr@3.0.0: {} + + cli-width@4.1.0: {} + + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.1.0 + wrap-ansi: 9.0.0 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.2 + + color@3.2.1: + dependencies: + color-convert: 1.9.3 + color-string: 1.9.1 + + colorspace@1.1.4: + dependencies: + color: 3.2.1 + text-hex: 1.0.0 + + cssmin@0.3.2: {} + + emoji-regex@10.4.0: {} + + emoji-regex@8.0.0: {} + + enabled@2.0.0: {} + + env-paths@3.0.0: {} + + escalade@3.2.0: {} + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-uri@3.0.6: {} + + fastq@1.19.1: + dependencies: + reusify: 1.1.0 + + fecha@4.2.3: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + fn.name@1.1.0: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.3.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + globby@14.1.0: + dependencies: + '@sindresorhus/merge-streams': 2.3.0 + fast-glob: 3.3.3 + ignore: 7.0.5 + path-type: 6.0.0 + slash: 5.1.0 + unicorn-magic: 0.3.0 + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@7.0.5: {} + + inherits@2.0.4: {} + + is-arrayish@0.3.2: {} + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-number@7.0.0: {} + + is-stream@2.0.1: {} + + is-unicode-supported@2.1.0: {} + + js-tokens@4.0.0: {} + + js-yaml@0.3.7: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsmin@1.0.1: {} + + json-schema-traverse@1.0.0: {} + + jxLoader@0.1.1: + dependencies: + js-yaml: 0.3.7 + moo-server: 1.3.0 + promised-io: 0.3.6 + walker: 1.0.8 + + kuler@2.0.0: {} + + logform@2.7.0: + dependencies: + '@colors/colors': 1.6.0 + '@types/triple-beam': 1.3.5 + fecha: 4.2.3 + ms: 2.1.3 + safe-stable-stringify: 2.5.0 + triple-beam: 1.4.1 + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + minipass@7.1.2: {} + + minizlib@3.0.2: + dependencies: + minipass: 7.1.2 + + mkdirp@3.0.1: {} + + moo-server@1.3.0: {} + + ms@2.1.3: {} + + mustache@4.2.0: {} + + mute-stream@2.0.0: {} + + one-time@1.0.0: + dependencies: + fn.name: 1.1.0 + + openapi-types@12.1.3: {} + + os-tmpdir@1.0.2: {} + + path-type@6.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + prettier@3.6.2: {} + + promised-io@0.3.6: {} + + queue-microtask@1.2.3: {} + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + require-from-string@2.0.2: {} + + reusify@1.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.2.1: {} + + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + semver@7.7.2: {} + + signal-exit@4.1.0: {} + + simple-swizzle@0.2.2: + dependencies: + is-arrayish: 0.3.2 + + slash@5.1.0: {} + + stack-trace@0.0.10: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@7.2.0: + dependencies: + emoji-regex: 10.4.0 + get-east-asian-width: 1.3.0 + strip-ansi: 7.1.0 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.2 + mkdirp: 3.0.1 + yallist: 5.0.0 + + temporal-polyfill@0.3.0: + dependencies: + temporal-spec: 0.3.0 + + temporal-spec@0.3.0: {} + + text-hex@1.0.0: {} + + timespan@2.3.0: {} + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + tmpl@1.0.5: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + triple-beam@1.4.1: {} + + type-fest@0.21.3: {} + + uglify-js@1.3.5: {} + + unicorn-magic@0.3.0: {} + + util-deprecate@1.0.2: {} + + vscode-jsonrpc@8.2.0: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-textdocument@1.0.12: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + winston-transport@4.9.0: + dependencies: + logform: 2.7.0 + readable-stream: 3.6.2 + triple-beam: 1.4.1 + + winston@3.17.0: + dependencies: + '@colors/colors': 1.6.0 + '@dabh/diagnostics': 2.0.3 + async: 3.2.6 + is-stream: 2.0.1 + logform: 2.7.0 + one-time: 1.0.0 + readable-stream: 3.6.2 + safe-stable-stringify: 2.5.0 + stack-trace: 0.0.10 + triple-beam: 1.4.1 + winston-transport: 4.9.0 + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@9.0.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 7.2.0 + strip-ansi: 7.1.0 + + wrench@1.3.9: {} + + y18n@5.0.8: {} + + yallist@5.0.0: {} + + yaml@2.8.1: {} + + yargs-parser@22.0.0: {} + + yargs@18.0.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 7.2.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + + yoctocolors-cjs@2.1.2: {} diff --git a/contract-typespec/api/prometheus.tsp b/contract-typespec/api/prometheus.tsp new file mode 100644 index 000000000..3a0c349d0 --- /dev/null +++ b/contract-typespec/api/prometheus.tsp @@ -0,0 +1,23 @@ +import "@typespec/openapi"; +import "./models.tsp"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/metrics") +@tag("PrometheusExpose") +interface PrometheusExposeApi { + @get + @summary("exposeAllMetrics") + @operationId("exposeAllMetrics") + exposeAllMetrics(): string; + + @get + @route("/{clusterName}") + @summary("exposeClusterMetrics") + @operationId("exposeClusterMetrics") + exposeClusterMetrics(@path clusterName: string): string; +} diff --git a/contract-typespec/api/quotas.tsp b/contract-typespec/api/quotas.tsp new file mode 100644 index 000000000..b0b0a0998 --- /dev/null +++ b/contract-typespec/api/quotas.tsp @@ -0,0 +1,32 @@ +import "@typespec/openapi"; +import "./models.tsp"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/clientquotas") +@tag("ClientQuotas") +interface QuoatsApi { + @get + @summary("listQuotas") + @operationId("listQuotas") + listQuotas(@path clusterName: string): ClientQuotas[]; + + @post + @summary("upsertClientQuotas") + @operationId("upsertClientQuotas") + upsertClientQuotas( + @path clusterName: string, + @body quota: ClientQuotas, + ): void | ApiBadRequestResponse; +} + +model ClientQuotas { + user?: string; + clientId?: string; + ip?: string; + quotas?: Record; +} diff --git a/contract-typespec/api/responses.tsp b/contract-typespec/api/responses.tsp new file mode 100644 index 000000000..c784aff70 --- /dev/null +++ b/contract-typespec/api/responses.tsp @@ -0,0 +1,72 @@ +import "@typespec/http"; +import "@typespec/http/streams"; + +namespace Api; + +using TypeSpec.Http; +using TypeSpec.Streams; + +model ApiCreatedResponse is Response<201> { + @body + body: Model; +} + +model SseResponse is Stream { + @header contentType: "text/event-stream"; + @body body: Model[]; +} + +// ----- Error Responses ----- +model ApiNotFoundResponse is Response<404> { + message: string; +} + +model ApiTimeoutResponse is Response<408> { + message: string; +} + +model ApiDuplicateResponse is Response<409> { + message: string; +} + +model ApiRebalanceInProgressResponse is Response<409> { + message: string; +} + +model ApiInvalidParametersResponse is Response<422> { + message: string; +} + +model ApiBadRequestResponse is Response<400> { + @body + message: ErrorResponse; +} + +model ApiUnauthorized is Response<401> { + message: string; +} + +model ErrorResponse { + @doc("Internal error code (can be used for message formatting & localization on UI)") + code: int32; + + @doc("Error message") + message: string; + + @doc("Response unix timestamp in ms") + timestamp: decimal; + + @doc("Unique server-defined request id for convenient debugging") + requestId: string; + + fieldsErrors?: FieldError[]; + stackTrace?: string; +} + +model FieldError { + @doc("Name of field that violated format") + fieldName: string; + + @doc("Field format violations description (ex. [\"size must be between 0 and 20\", \"must be a well-formed email address\"])") + restrictions?: string[]; +} diff --git a/contract-typespec/api/schemas.tsp b/contract-typespec/api/schemas.tsp new file mode 100644 index 000000000..2d4d7e997 --- /dev/null +++ b/contract-typespec/api/schemas.tsp @@ -0,0 +1,174 @@ +import "@typespec/openapi"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/schemas") +@tag("Schemas") +interface SchemasApi { + @post + @operationId("createNewSchema") + @summary("createNewSchema") + createNewSchema(@path clusterName: string, @body input: NewSchemaSubject): + | SchemaSubject + | ApiBadRequestResponse + | ApiDuplicateResponse + | ApiInvalidParametersResponse; + + @get + @operationId("getSchemas") + @summary("getSchemas") + getSchemas( + @path clusterName: string, + @query page?: int32, + @query perPage?: int32, + @query search?: string, + ): SchemaSubjectsResponse; + + @delete + @route("/{subject}") + @operationId("deleteSchema") + @summary("deleteSchema") + deleteSchema( + @path clusterName: string, + @path subject: string, + ): void | ApiNotFoundResponse; + + @get + @route("/{subject}/versions") + @operationId("getAllVersionsBySubject") + @summary("getAllVersionsBySubject") + getAllVersionsBySubject( + @path clusterName: string, + @path subject: string, + ): SchemaSubject[]; + + @get + @route("/{subject}/latest") + @operationId("getLatestSchema") + @summary("getLatestSchema") + getLatestSchema( + @path clusterName: string, + @path subject: string, + ): SchemaSubject; + + @delete + @route("/{subject}/latest") + @operationId("deleteLatestSchema") + @summary("deleteLatestSchema") + deleteLatestSchema( + @path clusterName: string, + @path subject: string, + ): void | ApiNotFoundResponse; + + @get + @route("/{subject}/versions/{version}") + @operationId("getSchemaByVersion") + @summary("getSchemaByVersion") + getSchemaByVersion( + @path clusterName: string, + @path subject: string, + @path version: int32, + ): SchemaSubject; + + @delete + @route("/{subject}/versions/{version}") + @operationId("deleteSchemaByVersion") + @summary("deleteSchemaByVersion") + deleteSchemaByVersion( + @path clusterName: string, + @path subject: string, + @path version: int32, + ): void | ApiNotFoundResponse; + + @get + @route("/compatibility") + @operationId("getGlobalSchemaCompatibilityLevel") + @summary("getGlobalSchemaCompatibilityLevel") + getGlobalSchemaCompatibilityLevel( + @path clusterName: string, + ): CompatibilityLevel; + + @put + @route("/compatibility") + @operationId("updateGlobalSchemaCompatibilityLevel") + @summary("updateGlobalSchemaCompatibilityLevel") + updateGlobalSchemaCompatibilityLevel( + @path clusterName: string, + @body level: CompatibilityLevel, + ): void | ApiNotFoundResponse | ApiBadRequestResponse; + + @put + @route("/{subject}/compatibility") + @operationId("updateSchemaCompatibilityLevel") + @summary("updateSchemaCompatibilityLevel") + updateSchemaCompatibilityLevel( + @path clusterName: string, + @path subject: string, + @body level: CompatibilityLevel, + ): void | ApiNotFoundResponse | ApiBadRequestResponse; + + @post + @route("/{subject}/check") + @operationId("checkSchemaCompatibility") + @summary("checkSchemaCompatibility") + checkSchemaCompatibility( + @path clusterName: string, + @path subject: string, + @body input: NewSchemaSubject, + ): CompatibilityCheckResponse | ApiNotFoundResponse; +} + +model SchemaReference { + name: string; + subject: string; + version: int32; +} + +enum SchemaType { + AVRO, + JSON, + PROTOBUF, +} + +model SchemaSubject { + id: int32; + subject: string; + version: string; + schema: string; + compatibilityLevel: string; + schemaType: SchemaType; + references?: SchemaReference[]; +} + +model NewSchemaSubject { + @doc("should be set for creating/updating schema subject") + subject: string; + + schema: string; + schemaType: SchemaType; + references?: SchemaReference[]; +} + +model CompatibilityLevel { + compatibility: + | "BACKWARD" + | "BACKWARD_TRANSITIVE" + | "FORWARD" + | "FORWARD_TRANSITIVE" + | "FULL" + | "FULL_TRANSITIVE" + | "NONE"; +} + +model CompatibilityCheckResponse { + isCompatible: boolean; +} + +model SchemaSubjectsResponse { + pageCount?: int32; + schemas?: SchemaSubject[]; +} diff --git a/contract-typespec/api/topics.tsp b/contract-typespec/api/topics.tsp new file mode 100644 index 000000000..c41696764 --- /dev/null +++ b/contract-typespec/api/topics.tsp @@ -0,0 +1,324 @@ +import "@typespec/openapi"; +import "./responses.tsp"; + +namespace Api; + +using TypeSpec.Http; +using OpenAPI; + +@route("/api/clusters/{clusterName}/topics") +@tag("Topics") +interface TopicsApi { + @get + @operationId("getTopics") + @summary("getTopics") + getTopics( + @path clusterName: string, + @query page?: int32, + @query perPage?: int32, + @query showInternal?: boolean, + @query search?: string, + @query orderBy?: TopicColumnsToSort, + @query sortOrder?: SortOrder, + ): TopicsResponse; + + @post + @operationId("createTopic") + @summary("createTopic") + createTopic( + @path clusterName: string, + @body topic: TopicCreation, + ): ApiCreatedResponse; + + @post + @route("/{topicName}/clone") + @operationId("cloneTopic") + @summary("cloneTopic") + cloneTopic( + @path clusterName: string, + @path topicName: string, + @query newTopicName: string, + ): ApiCreatedResponse | ApiNotFoundResponse; + + @get + @route("/{topicName}/analysis") + @operationId("getTopicAnalysis") + @summary("getTopicAnalysis") + getTopicAnalysis( + @path clusterName: string, + @path topicName: string, + ): TopicAnalysis | ApiNotFoundResponse; + + @post + @route("/{topicName}/analysis") + @operationId("analyzeTopic") + @summary("analyzeTopic") + analyzeTopic( + @path clusterName: string, + @path topicName: string, + ): void | ApiNotFoundResponse; + + @delete + @route("/{topicName}/analysis") + @operationId("cancelTopicAnalysis") + @summary("cancelTopicAnalysis") + cancelTopicAnalysis( + @path clusterName: string, + @path topicName: string, + ): void | ApiNotFoundResponse; + + @get + @route("/{topicName}") + @operationId("getTopicDetails") + @summary("getTopicDetails") + getTopicDetails( + @path clusterName: string, + @path topicName: string, + ): TopicDetails; + + @post + @route("/{topicName}") + @operationId("recreateTopic") + @summary("recreateTopic") + recreateTopic(@path clusterName: string, @path topicName: string): + | ApiCreatedResponse + | ApiTimeoutResponse + | ApiNotFoundResponse + | ApiBadRequestResponse; + + @patch(#{implicitOptionality: true}) + @route("/{topicName}") + @operationId("updateTopic") + @summary("updateTopic") + updateTopic( + @path clusterName: string, + @path topicName: string, + @body update: TopicUpdate, + ): Topic; + + @delete + @route("/{topicName}") + @operationId("deleteTopic") + @summary("deleteTopic") + deleteTopic( + @path clusterName: string, + @path topicName: string, + ): void | NotFoundResponse; + + @get + @route("/{topicName}/config") + @operationId("getTopicConfigs") + @summary("getTopicConfigs") + getTopicConfigs( + @path clusterName: string, + @path topicName: string, + ): TopicConfig[]; + + @patch(#{ implicitOptionality: true }) + @route("/{topicName}/replications") + @operationId("changeReplicationFactor") + @summary("changeReplicationFactor") + changeReplicationFactor( + @path clusterName: string, + @path topicName: string, + @body change: ReplicationFactorChange, + ): ReplicationFactorChangeResponse | ApiNotFoundResponse | ApiBadRequestResponse; + + @get + @route("/{topicName}/activeproducers") + @operationId("getActiveProducerStates") + @summary("getActiveProducerStates") + getActiveProducerStates( + @path clusterName: string, + @path topicName: string, + ): TopicProducerState[]; + + @patch(#{ implicitOptionality: true }) + @route("/{topicName}/partitions") + @summary("increaseTopicPartitions") + @operationId("increaseTopicPartitions") + increaseTopicPartitions( + @path clusterName: string, + @path topicName: string, + @body partitionsIncrease: PartitionsIncrease, + ): PartitionsIncreaseResponse | ApiNotFoundResponse; +} + +model TopicsResponse { + pageCount?: int32; + topics?: Topic[]; +} + +enum TopicColumnsToSort { + NAME, + OUT_OF_SYNC_REPLICAS, + TOTAL_PARTITIONS, + REPLICATION_FACTOR, + SIZE, +} + +model Topic { + name: string; + internal?: boolean; + partitionCount?: int32; + replicationFactor?: int32; + replicas?: int32; + inSyncReplicas?: int32; + segmentSize?: int64; + segmentCount?: int32; + bytesInPerSec?: float64; + bytesOutPerSec?: float64; + underReplicatedPartitions?: int32; + cleanUpPolicy?: CleanUpPolicy; + partitions?: Partition[]; +} + +model TopicUpdate { + configs: Record; +} + +model TopicAnalysis { + progress?: TopicAnalysisProgress; + result?: TopicAnalysisResult; +} + +model TopicAnalysisProgress { + startedAt?: int64; + completenessPercent?: decimal; + msgsScanned?: int64; + bytesScanned?: int64; +} + +model TopicAnalysisResult { + startedAt?: int64; + finishedAt?: int64; + error?: string; + totalStats?: TopicAnalysisStats; + partitionStats?: TopicAnalysisStats[]; +} + +model TopicAnalysisStats { + @doc("null if this is total stats") + partition?: int32; + + totalMsgs?: int64; + minOffset?: int64; + maxOffset?: int64; + minTimestamp?: int64; + maxTimestamp?: int64; + nullKeys?: int64; + nullValues?: int64; + approxUniqKeys?: int64; + approxUniqValues?: int64; + keySize?: TopicAnalysisSizeStats; + valueSize?: TopicAnalysisSizeStats; + hourlyMsgCounts?: { + hourStart?: int64; + count?: int64; + }[]; +} + +model TopicAnalysisSizeStats { + sum?: int64; + min?: int64; + max?: int64; + avg?: int64; + prctl50?: int64; + prctl75?: int64; + prctl95?: int64; + prctl99?: int64; + prctl999?: int64; +} + +model TopicProducerState { + partition?: int32; + producerId?: int64; + producerEpoch?: int32; + lastSequence?: int32; + lastTimestampMs?: int64; + coordinatorEpoch?: int32; + currentTransactionStartOffset?: int64; +} + +model TopicDetails { + name: string; + internal?: boolean; + partitions?: Partition[]; + partitionCount?: int32; + replicationFactor?: int32; + replicas?: int32; + inSyncReplicas?: int32; + bytesInPerSec?: float64; + bytesOutPerSec?: float64; + segmentSize?: int64; + segmentCount?: int32; + underReplicatedPartitions?: int32; + cleanUpPolicy?: CleanUpPolicy; + keySerde?: string; + valueSerde?: string; +} + +model TopicConfig { + name: string; + value?: string; + defaultValue?: string; + source?: ConfigSource; + isSensitive?: boolean; + isReadOnly?: boolean; + synonyms?: ConfigSynonym[]; + doc?: string; +} + +model TopicCreation { + name: string; + partitions: int32; + replicationFactor?: int32; + configs?: Record; +} + +enum CleanUpPolicy { + DELETE, + COMPACT, + COMPACT_DELETE, + UNKNOWN, +} + +model ConfigSynonym { + name?: string; + value?: string; + source?: ConfigSource; +} + +model Partition { + partition: int32; + leader?: int32; + replicas?: Replica[]; + offsetMax: int64; + offsetMin: int64; +} + +model PartitionsIncrease { + @minValue(1) + totalPartitionsCount: integer; +} + +model PartitionsIncreaseResponse { + totalPartitionsCount: integer; + topicName: string; +} + + +model ReplicationFactorChange { + totalReplicationFactor: integer; +} + +model ReplicationFactorChangeResponse { + totalReplicationFactor: integer; + topicName: string; +} + +model Replica { + broker?: int32; + leader?: boolean; + inSync?: boolean; +} diff --git a/contract-typespec/api/tspconfig.yaml b/contract-typespec/api/tspconfig.yaml new file mode 100644 index 000000000..f0b1f2718 --- /dev/null +++ b/contract-typespec/api/tspconfig.yaml @@ -0,0 +1,8 @@ +output-dir: "{project-root}/../build/tsp/api" + +emit: + - "@typespec/openapi3" +options: + "@typespec/openapi3": + emitter-output-dir: "{output-dir}" + output-file: openapi.yaml diff --git a/contract-typespec/build.gradle b/contract-typespec/build.gradle new file mode 100644 index 000000000..6b5f018d4 --- /dev/null +++ b/contract-typespec/build.gradle @@ -0,0 +1,58 @@ +plugins { + id "java" + alias(libs.plugins.node.gradle) +} + + +java { + sourceCompatibility = JavaVersion.VERSION_21 + targetCompatibility = JavaVersion.VERSION_21 +} + + +node { + download = "true" != project.property("local_node") + version = project.property("node_version").toString() + pnpmVersion = project.property("pnpm_version").toString() +} + +def typeSpecVersion = "1.0.0" + +sourceSets { + main { + resources { + srcDirs += ['build/tsp'] + } + } +} + + + +def typeSpecs = ["api"] + +typeSpecs.each { spec -> + + def tspPath = "\\tsp --output-dir=${project.layout.buildDirectory.get()}/tsp/${spec} compile .\\" + + tasks.register("installDependencies_${spec}", NpmTask) { + group = 'build' + npmCommand = ['install'] + workingDir = project.layout.projectDirectory.dir(spec).asFile + } + + tasks.register("generateOpenApi_${spec}", NpmTask) { + group = 'build' + dependsOn "installDependencies_${spec}" + npmCommand = ['exec'] + workingDir = project.layout.projectDirectory.dir(spec).asFile + args = ["--package=@typespec/compiler@${typeSpecVersion}", '-c', tspPath] + } + + tasks.register("cleanDependencies_${spec}", Delete) { + delete layout.projectDirectory.dir(spec).dir("node_modules") + } + + clean.dependsOn("cleanDependencies_${spec}") + processResources.dependsOn("generateOpenApi_${spec}") + build.dependsOn("generateOpenApi_${spec}") +} diff --git a/contract/build.gradle b/contract/build.gradle index 5bb53ac9d..95b917adb 100644 --- a/contract/build.gradle +++ b/contract/build.gradle @@ -21,7 +21,12 @@ dependencies { tasks.register('generateUiClient', GenerateTask) { generatorName = "java" - inputSpec = specDir.file("kafbat-ui-api.yaml").asFile.absolutePath + if (useTypeSpec) { + dependsOn ":contract-typespec:build" + inputSpec = project(":contract-typespec").layout.buildDirectory.dir("tsp/api/openapi.yaml").get().asFile.absolutePath + } else { + inputSpec = specDir.file("kafbat-ui-api.yaml").asFile.absolutePath + } outputDir = targetDir.dir("kafbat-ui-client").asFile.absolutePath apiPackage = "io.kafbat.ui.api.api" invokerPackage = "io.kafbat.ui.api" @@ -36,7 +41,12 @@ tasks.register('generateUiClient', GenerateTask) { tasks.register('generateBackendApi', GenerateTask) { generatorName = "spring" - inputSpec = specDir.file("kafbat-ui-api.yaml").asFile.absolutePath + if (useTypeSpec) { + dependsOn ":contract-typespec:build" + inputSpec = project(":contract-typespec").layout.buildDirectory.dir("tsp/api/openapi.yaml").get().asFile.absolutePath + } else { + inputSpec = specDir.file("kafbat-ui-api.yaml").asFile.absolutePath + } outputDir = targetDir.dir("api").asFile.absolutePath apiPackage = "io.kafbat.ui.api" invokerPackage = "io.kafbat.ui.api" @@ -61,7 +71,11 @@ tasks.register('generateBackendApi', GenerateTask) { } openAPIStyleValidator { - inputFile = "${project.projectDir}/src/main/resources/swagger/kafbat-ui-api.yaml" + if (useTypeSpec) { + inputFile = project(":contract-typespec").layout.buildDirectory.dir("tsp/api/openapi.yaml").get().asFile.absolutePath + } else { + inputFile = specDir.file("kafbat-ui-api.yaml").asFile.absolutePath + } validateModelPropertiesDescription = false validateModelPropertiesExample = false parameterNamingConvention = "UnderscoreCase" diff --git a/contract/src/main/resources/swagger/kafbat-ui-api.yaml b/contract/src/main/resources/swagger/kafbat-ui-api.yaml index d35e320cf..7eea7bd21 100644 --- a/contract/src/main/resources/swagger/kafbat-ui-api.yaml +++ b/contract/src/main/resources/swagger/kafbat-ui-api.yaml @@ -578,6 +578,7 @@ paths: schema: type: string requestBody: + required: true content: application/json: schema: diff --git a/frontend/build.gradle b/frontend/build.gradle index dc982ad73..17e0d74c1 100644 --- a/frontend/build.gradle +++ b/frontend/build.gradle @@ -23,6 +23,12 @@ tasks.named("pnpmInstall") { tasks.register('generateContract', PnpmTask) { dependsOn pnpmInstall + if (useTypeSpec) { + dependsOn ":contract-typespec:build" + inputs.files(project(":contract-typespec").layout.buildDirectory.dir("tsp/api/openapi.yaml")) + } else { + inputs.files(fileTree("../contract/src/main/resources")) + } inputs.files(fileTree("../contract/src/main/resources")) outputs.dir(project.layout.projectDirectory.dir("src/generated-sources")) args = ['gen:sources'] diff --git a/frontend/openapitools.json b/frontend/openapitools.json index 4762ba082..4f82eb54d 100644 --- a/frontend/openapitools.json +++ b/frontend/openapitools.json @@ -7,7 +7,7 @@ "fetch": { "generatorName": "typescript-fetch", "output": "src/generated-sources", - "glob": "../contract/src/main/resources/swagger/kafbat-ui-api.yaml", + "glob": "../contract-typespec/build/tsp/api/openapi.yaml", "additionalProperties": { "enumPropertyNaming": "UPPERCASE", "typescriptThreePlus": true, diff --git a/frontend/package.json b/frontend/package.json index b150467db..41d33a722 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -40,8 +40,8 @@ "start": "vite", "dev": "vite", "compile": "pnpm gen:sources && tsc --noEmit", - "gen:sources": "rimraf ./src/generated-sources && openapi-generator-cli generate", - "build": "rimraf ./src/generated-sources && openapi-generator-cli generate && tsc --noEmit && vite build", + "gen:sources": "rimraf ./src/generated-sources && cd ../contract-typespec/api && pnpm install && pnpm build && cd ../../frontend && openapi-generator-cli generate", + "build": "pnpm gen:sources && tsc --noEmit && vite build", "preview": "vite preview", "lint": "eslint --ext .tsx,.ts src/", "lint:fix": "eslint --ext .tsx,.ts src/ --fix", @@ -121,5 +121,6 @@ "axios@>=1.3.2 <=1.7.3": ">=1.7.4", "braces": "3.0.3" } - } + }, + "packageManager": "pnpm@9.15.9+sha512.68046141893c66fad01c079231128e9afb89ef87e2691d69e4d40eee228988295fd4682181bae55b58418c3a253bde65a505ec7c5f9403ece5cc3cd37dcf2531" } diff --git a/frontend/src/lib/fixtures/topics.ts b/frontend/src/lib/fixtures/topics.ts index cff119077..ec8803c4b 100644 --- a/frontend/src/lib/fixtures/topics.ts +++ b/frontend/src/lib/fixtures/topics.ts @@ -64,6 +64,7 @@ export const topicConsumerGroups: ConsumerGroup[] = [ state: ConsumerGroupState.UNKNOWN, coordinator: { id: 1 }, consumerLag: 9, + inherit: '', }, { groupId: 'amazon.msk.canary.group.broker-4', @@ -74,6 +75,7 @@ export const topicConsumerGroups: ConsumerGroup[] = [ state: ConsumerGroupState.COMPLETING_REBALANCE, coordinator: { id: 1 }, consumerLag: 9, + inherit: '', }, ]; diff --git a/frontend/src/lib/hooks/__tests__/dateTimeHelpers.spec.ts b/frontend/src/lib/hooks/__tests__/dateTimeHelpers.spec.ts index 61e188f29..d3558c94d 100644 --- a/frontend/src/lib/hooks/__tests__/dateTimeHelpers.spec.ts +++ b/frontend/src/lib/hooks/__tests__/dateTimeHelpers.spec.ts @@ -11,12 +11,13 @@ describe('dateTimeHelpers', () => { }); it('should output the correct date', () => { + const language = navigator.language || navigator.languages[0]; const date = new Date(); expect(formatTimestamp({ timestamp: date })).toBe( - date.toLocaleString([], { hourCycle: 'h23' }) + date.toLocaleString(language || [], { hourCycle: 'h23' }) ); expect(formatTimestamp({ timestamp: date.getTime() })).toBe( - date.toLocaleString([], { hourCycle: 'h23' }) + date.toLocaleString(language || [], { hourCycle: 'h23' }) ); }); }); diff --git a/frontend/src/lib/hooks/api/__tests__/topicMessages.spec.ts b/frontend/src/lib/hooks/api/__tests__/topicMessages.spec.ts index 49a143f22..134ff9e8e 100644 --- a/frontend/src/lib/hooks/api/__tests__/topicMessages.spec.ts +++ b/frontend/src/lib/hooks/api/__tests__/topicMessages.spec.ts @@ -25,7 +25,7 @@ jest.mock('lib/errorHandling', () => ({ describe('Topic Messages hooks', () => { beforeEach(() => fetchMock.restore()); it('handles useSerdes', async () => { - const path = `/api/clusters/${clusterName}/topic/${topicName}/serdes?use=SERIALIZE`; + const path = `/api/clusters/${clusterName}/topics/${topicName}/serdes?use=SERIALIZE`; const mock = fetchMock.getOnce(path, {}); const { result } = renderQueryHook(() => diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 94e022899..b2636b05a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -47,8 +47,8 @@ prometheus = '1.3.6' spring-boot = { id = 'org.springframework.boot', version.ref = 'spring-boot' } spring-dependency-management = { id = 'io.spring.dependency-management', version = '1.1.3' } git-properties = { id = 'com.gorylenko.gradle-git-properties', version = '2.4.2' } -openapi-generator = { id = 'org.openapi.generator', version = '7.9.0' } openapi-validator = {id = "org.openapitools.openapistylevalidator", version = "1.10" } +openapi-generator = { id = 'org.openapi.generator', version = '7.13.0' } allure = { id = 'io.qameta.allure', version = '2.10.0' } nexus-publish-plugin = { id = 'io.github.gradle-nexus.publish-plugin', version = '1.1.0' } node-gradle = { id = 'com.github.node-gradle.node', version = '7.1.0' } @@ -57,7 +57,6 @@ docker-remote-api = { id = 'com.bmuschko.docker-remote-api', version = '9.4.0' } sonarqube = { id = "org.sonarqube", version = "6.0.1.5171" } - [libraries] spring-starter-actuator = { module = 'org.springframework.boot:spring-boot-starter-actuator', version.ref = 'spring-boot' } spring-starter-test = { module = 'org.springframework.boot:spring-boot-starter-test', version.ref = 'spring-boot' } diff --git a/settings.gradle b/settings.gradle index a9be51116..fa0dcb978 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,6 +7,7 @@ pluginManagement { rootProject.name = "kafbat-ui" include "contract" +include "contract-typespec" include "serde-api" include "api" include "frontend"