From 1cbe71e407b459b3f624ea46e420962d024d61be Mon Sep 17 00:00:00 2001 From: markitosha Date: Thu, 12 Feb 2026 11:34:39 +0100 Subject: [PATCH 01/44] feat: removed .ferignore to generate clean version of sdk --- .fernignore | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 .fernignore diff --git a/.fernignore b/.fernignore deleted file mode 100644 index 47e21c2f..00000000 --- a/.fernignore +++ /dev/null @@ -1,26 +0,0 @@ -# All custom code -src/custom - -# Custom imports from custom code that replaces generated one -src/index.ts -src/api/index.ts - -# Patch: fetcher respects CortiClient withCredentials via global config -src/core/fetcher/Fetcher.ts - -# Documentation -README.md -AUTHENTICATION.md -reference.md -PROXYING.md - -# Integration tests -tests/custom -jest.integration.config.mjs -.github/workflows/integration-tests.yml - -# Issue templates -.github/ISSUE_TEMPLATE - -# Updated release workflow -.github/workflows/ci.yml From 2655e5d820d879350c7365abeaa450d159df5066 Mon Sep 17 00:00:00 2001 From: "fern-api[bot]" <115122769+fern-api[bot]@users.noreply.github.com> Date: Thu, 12 Feb 2026 10:41:20 +0000 Subject: [PATCH 02/44] SDK regeneration --- .fern/metadata.json | 16 + .fernignore | 1 + .github/ISSUE_TEMPLATE/bug_report.md | 49 - .github/ISSUE_TEMPLATE/feature_request.md | 48 - .github/workflows/ci.yml | 154 +- .github/workflows/integration-tests.yml | 29 - .npmignore | 9 - .prettierrc.yml | 2 - AUTHENTICATION.md | 495 --- CONTRIBUTING.md | 133 + PROXYING.md | 343 -- README.md | 688 +++- biome.json | 74 + jest.config.mjs | 42 - jest.integration.config.mjs | 16 - package.json | 33 +- pnpm-lock.yaml | 2201 +++++++++++ pnpm-workspace.yaml | 1 + reference.md | 2572 +++++++++++++ src/BaseClient.ts | 90 + src/Client.ts | 189 +- src/api/errors/BadGatewayError.ts | 15 +- src/api/errors/BadRequestError.ts | 13 +- src/api/errors/ForbiddenError.ts | 15 +- src/api/errors/GatewayTimeoutError.ts | 15 +- src/api/errors/InternalServerError.ts | 15 +- src/api/errors/NotFoundError.ts | 13 +- src/api/errors/UnauthorizedError.ts | 13 +- src/api/errors/index.ts | 4 +- src/api/index.ts | 6 +- src/api/resources/agents/client/Client.ts | 718 ++-- src/api/resources/agents/client/index.ts | 1 - .../client/requests/AgentsCreateAgent.ts | 12 +- .../client/requests/AgentsDeleteRequest.ts | 12 + .../client/requests/AgentsGetCardRequest.ts | 12 + .../requests/AgentsGetContextRequest.ts | 25 +- .../AgentsGetRegistryExpertsRequest.ts | 16 +- .../client/requests/AgentsGetRequest.ts | 12 + .../client/requests/AgentsGetTaskRequest.ts | 19 +- .../client/requests/AgentsListRequest.ts | 22 +- .../requests/AgentsMessageSendParams.ts | 9 +- .../client/requests/AgentsUpdateRequest.ts | 21 + .../resources/agents/client/requests/index.ts | 16 +- src/api/resources/agents/index.ts | 2 +- .../types/AgentsCreateAgentAgentType.ts | 10 +- .../types/AgentsCreateAgentExpertsItem.ts | 6 +- .../agents/types/AgentsMessageSendResponse.ts | 6 +- src/api/resources/auth/client/Client.ts | 117 +- src/api/resources/auth/client/index.ts | 1 - ...TokenRequest.ts => GetTokenAuthRequest.ts} | 6 +- .../resources/auth/client/requests/index.ts | 2 +- src/api/resources/auth/index.ts | 2 +- .../resources/auth/types/GetTokenResponse.ts | 4 +- src/api/resources/codes/client/Client.ts | 102 +- src/api/resources/codes/client/index.ts | 1 - .../requests/CodesGeneralPredictRequest.ts | 6 +- .../resources/codes/client/requests/index.ts | 2 +- src/api/resources/documents/client/Client.ts | 416 +-- src/api/resources/documents/client/index.ts | 1 - .../client/requests/DocumentsCreateRequest.ts | 26 + .../client/requests/DocumentsDeleteRequest.ts | 17 + .../client/requests/DocumentsGetRequest.ts | 17 + .../client/requests/DocumentsListRequest.ts | 14 + .../client/requests/DocumentsUpdateRequest.ts | 15 +- .../documents/client/requests/index.ts | 6 +- src/api/resources/facts/client/Client.ts | 397 +- src/api/resources/facts/client/index.ts | 1 - .../requests/FactsBatchUpdateRequest.ts | 9 +- .../client/requests/FactsCreateRequest.ts | 9 +- .../client/requests/FactsExtractRequest.ts | 6 +- .../facts/client/requests/FactsListRequest.ts | 14 + .../client/requests/FactsUpdateRequest.ts | 15 +- .../resources/facts/client/requests/index.ts | 9 +- src/api/resources/index.ts | 35 +- .../resources/interactions/client/Client.ts | 400 +- .../resources/interactions/client/index.ts | 1 - .../requests/InteractionsCreateRequest.ts | 6 +- .../requests/InteractionsDeleteRequest.ts | 14 + .../client/requests/InteractionsGetRequest.ts | 14 + .../requests/InteractionsListRequest.ts | 40 +- .../requests/InteractionsUpdateRequest.ts | 12 +- .../interactions/client/requests/index.ts | 8 +- src/api/resources/interactions/index.ts | 2 +- .../types/InteractionsListRequestSort.ts | 11 +- src/api/resources/recordings/client/Client.ts | 310 +- src/api/resources/recordings/client/index.ts | 2 +- .../requests/RecordingsDeleteRequest.ts | 17 + .../client/requests/RecordingsGetRequest.ts | 17 + .../client/requests/RecordingsListRequest.ts | 14 + .../recordings/client/requests/index.ts | 3 + src/api/resources/stream/client/Client.ts | 60 +- src/api/resources/stream/client/Socket.ts | 27 +- src/api/resources/templates/client/Client.ts | 261 +- src/api/resources/templates/client/index.ts | 1 - .../client/requests/TemplatesGetRequest.ts | 12 + .../client/requests/TemplatesListRequest.ts | 16 +- .../requests/TemplatesSectionListRequest.ts | 12 +- .../templates/client/requests/index.ts | 5 +- src/api/resources/transcribe/client/Client.ts | 58 +- src/api/resources/transcribe/client/Socket.ts | 30 +- .../resources/transcripts/client/Client.ts | 413 +-- src/api/resources/transcripts/client/index.ts | 1 - .../requests/TranscriptsCreateRequest.ts | 9 +- .../requests/TranscriptsDeleteRequest.ts | 17 + .../client/requests/TranscriptsGetRequest.ts | 17 + .../requests/TranscriptsGetStatusRequest.ts | 17 + .../client/requests/TranscriptsListRequest.ts | 18 +- .../transcripts/client/requests/index.ts | 7 +- src/api/types/AgentsAgent.ts | 6 +- src/api/types/AgentsAgentCapabilities.ts | 6 +- src/api/types/AgentsAgentCard.ts | 6 +- src/api/types/AgentsAgentCardSignature.ts | 4 +- src/api/types/AgentsAgentExpertsItem.ts | 6 +- src/api/types/AgentsAgentExtension.ts | 4 +- src/api/types/AgentsAgentInterface.ts | 4 +- src/api/types/AgentsAgentProvider.ts | 4 +- src/api/types/AgentsAgentReference.ts | 8 +- src/api/types/AgentsAgentReferenceType.ts | 6 + src/api/types/AgentsAgentResponse.ts | 6 +- src/api/types/AgentsAgentSkill.ts | 6 +- src/api/types/AgentsArtifact.ts | 6 +- src/api/types/AgentsContext.ts | 6 +- src/api/types/AgentsContextItemsItem.ts | 6 +- src/api/types/AgentsCreateExpert.ts | 8 +- src/api/types/AgentsCreateExpertReference.ts | 8 +- .../types/AgentsCreateExpertReferenceType.ts | 7 + src/api/types/AgentsCreateExpertType.ts | 6 + src/api/types/AgentsCreateMcpServer.ts | 6 +- .../AgentsCreateMcpServerAuthorizationType.ts | 11 +- .../AgentsCreateMcpServerTransportType.ts | 11 +- src/api/types/AgentsDataPart.ts | 8 +- src/api/types/AgentsDataPartKind.ts | 7 + src/api/types/AgentsExpert.ts | 8 +- src/api/types/AgentsExpertReference.ts | 8 +- src/api/types/AgentsExpertReferenceType.ts | 6 + src/api/types/AgentsExpertType.ts | 6 + src/api/types/AgentsFilePart.ts | 8 +- src/api/types/AgentsFilePartFile.ts | 6 +- src/api/types/AgentsFilePartKind.ts | 7 + src/api/types/AgentsFileWithBytes.ts | 4 +- src/api/types/AgentsFileWithUri.ts | 4 +- src/api/types/AgentsMcpServer.ts | 6 +- .../types/AgentsMcpServerAuthorizationType.ts | 11 +- src/api/types/AgentsMcpServerTransportType.ts | 11 +- src/api/types/AgentsMessage.ts | 8 +- src/api/types/AgentsMessageKind.ts | 7 + src/api/types/AgentsMessageRole.ts | 10 +- .../types/AgentsMessageSendConfiguration.ts | 6 +- src/api/types/AgentsPart.ts | 6 +- ...gentsPushNotificationAuthenticationInfo.ts | 4 +- src/api/types/AgentsPushNotificationConfig.ts | 6 +- src/api/types/AgentsRegistryExpert.ts | 6 +- .../types/AgentsRegistryExpertsResponse.ts | 6 +- src/api/types/AgentsRegistryMcpServer.ts | 6 +- ...gentsRegistryMcpServerAuthorizationType.ts | 11 +- src/api/types/AgentsTask.ts | 8 +- src/api/types/AgentsTaskKind.ts | 7 + src/api/types/AgentsTaskStatus.ts | 6 +- src/api/types/AgentsTaskStatusState.ts | 19 +- src/api/types/AgentsTextPart.ts | 8 +- src/api/types/AgentsTextPartKind.ts | 7 + src/api/types/CodesGeneralReadResponse.ts | 6 +- .../CodesGeneralReadResponseEvidencesItem.ts | 4 +- src/api/types/CodesGeneralResponse.ts | 6 +- src/api/types/CommonAiContext.ts | 6 +- src/api/types/CommonCodingSystemEnum.ts | 6 +- src/api/types/CommonDocumentIdContext.ts | 8 +- src/api/types/CommonDocumentIdContextType.ts | 8 + src/api/types/CommonSortingDirectionEnum.ts | 6 +- src/api/types/CommonSourceEnum.ts | 6 +- src/api/types/CommonTextContext.ts | 8 +- src/api/types/CommonTextContextType.ts | 7 + src/api/types/CommonTranscriptRequest.ts | 4 +- src/api/types/CommonTranscriptResponse.ts | 4 +- src/api/types/CommonUsageInfo.ts | 4 +- src/api/types/DocumentsContext.ts | 6 +- src/api/types/DocumentsContextWithFacts.ts | 8 +- .../types/DocumentsContextWithFactsType.ts | 8 + src/api/types/DocumentsContextWithString.ts | 8 +- .../types/DocumentsContextWithStringType.ts | 8 + .../types/DocumentsContextWithTranscript.ts | 8 +- .../DocumentsContextWithTranscriptType.ts | 8 + ...quest.ts => DocumentsCreateRequestBody.ts} | 8 +- .../DocumentsCreateRequestWithTemplate.ts | 6 +- .../DocumentsCreateRequestWithTemplateKey.ts | 6 +- src/api/types/DocumentsGetResponse.ts | 6 +- src/api/types/DocumentsListResponse.ts | 6 +- src/api/types/DocumentsSection.ts | 4 +- src/api/types/DocumentsSectionInput.ts | 4 +- src/api/types/DocumentsSectionOverride.ts | 4 +- src/api/types/DocumentsTemplate.ts | 6 +- .../types/DocumentsTemplateWithSectionKeys.ts | 4 +- .../types/DocumentsTemplateWithSections.ts | 6 +- src/api/types/ErrorResponse.ts | 4 +- src/api/types/FactsBatchUpdateInput.ts | 4 +- src/api/types/FactsBatchUpdateItem.ts | 6 +- src/api/types/FactsBatchUpdateResponse.ts | 6 +- src/api/types/FactsContext.ts | 6 +- src/api/types/FactsCreateInput.ts | 6 +- src/api/types/FactsCreateItem.ts | 6 +- src/api/types/FactsCreateResponse.ts | 6 +- src/api/types/FactsEvidence.ts | 4 +- src/api/types/FactsExtractResponse.ts | 6 +- .../types/FactsExtractResponseFactsItem.ts | 4 +- src/api/types/FactsFactGroupsItem.ts | 6 +- .../FactsFactGroupsItemTranslationsItem.ts | 4 +- src/api/types/FactsFactGroupsListResponse.ts | 6 +- src/api/types/FactsListItem.ts | 6 +- src/api/types/FactsListResponse.ts | 6 +- src/api/types/FactsUpdateResponse.ts | 6 +- src/api/types/InteractionsCreateResponse.ts | 6 +- .../InteractionsEncounterCreateRequest.ts | 6 +- src/api/types/InteractionsEncounterPeriod.ts | 4 +- .../types/InteractionsEncounterResponse.ts | 6 +- .../types/InteractionsEncounterStatusEnum.ts | 13 +- .../types/InteractionsEncounterTypeEnum.ts | 12 +- .../InteractionsEncounterUpdateRequest.ts | 6 +- src/api/types/InteractionsGenderEnum.ts | 6 +- src/api/types/InteractionsGetResponse.ts | 6 +- src/api/types/InteractionsListResponse.ts | 6 +- src/api/types/InteractionsPatient.ts | 6 +- src/api/types/RecordingsCreateResponse.ts | 6 +- src/api/types/RecordingsListResponse.ts | 6 +- src/api/types/StreamConfig.ts | 6 +- src/api/types/StreamConfigMessage.ts | 8 +- src/api/types/StreamConfigMessageType.ts | 6 + src/api/types/StreamConfigMode.ts | 6 +- src/api/types/StreamConfigModeType.ts | 10 +- src/api/types/StreamConfigParticipant.ts | 6 +- src/api/types/StreamConfigParticipantRole.ts | 11 +- src/api/types/StreamConfigStatusMessage.ts | 6 +- .../types/StreamConfigStatusMessageType.ts | 17 +- src/api/types/StreamConfigTranscription.ts | 6 +- src/api/types/StreamEndMessage.ts | 8 +- src/api/types/StreamEndMessageType.ts | 6 + src/api/types/StreamEndedMessage.ts | 8 +- src/api/types/StreamEndedMessageType.ts | 6 + src/api/types/StreamErrorDetail.ts | 4 +- src/api/types/StreamErrorMessage.ts | 8 +- src/api/types/StreamErrorMessageType.ts | 6 + src/api/types/StreamFact.ts | 4 +- src/api/types/StreamFactsMessage.ts | 8 +- src/api/types/StreamFactsMessageType.ts | 6 + src/api/types/StreamFlushMessage.ts | 8 +- src/api/types/StreamFlushMessageType.ts | 6 + src/api/types/StreamFlushedMessage.ts | 8 +- src/api/types/StreamFlushedMessageType.ts | 6 + src/api/types/StreamParticipant.ts | 4 +- src/api/types/StreamSupportedLanguage.ts | 4 +- src/api/types/StreamTranscript.ts | 6 +- src/api/types/StreamTranscriptMessage.ts | 8 +- src/api/types/StreamTranscriptMessageType.ts | 7 + src/api/types/StreamTranscriptTime.ts | 4 +- src/api/types/StreamUsageMessage.ts | 8 +- src/api/types/StreamUsageMessageType.ts | 6 + .../types/TemplatesDocumentationModeEnum.ts | 11 +- src/api/types/TemplatesFormatRule.ts | 6 +- src/api/types/TemplatesItem.ts | 6 +- src/api/types/TemplatesListResponse.ts | 6 +- src/api/types/TemplatesSection.ts | 6 +- src/api/types/TemplatesSectionListResponse.ts | 6 +- src/api/types/TemplatesSectionSorted.ts | 6 +- src/api/types/TemplatesSectionTranslation.ts | 4 +- src/api/types/TemplatesTranslation.ts | 4 +- src/api/types/TemplatesWritingStyle.ts | 4 +- src/api/types/TranscribeCommand.ts | 6 +- src/api/types/TranscribeCommandData.ts | 6 +- src/api/types/TranscribeCommandMessage.ts | 8 +- src/api/types/TranscribeCommandMessageType.ts | 7 + src/api/types/TranscribeCommandVariable.ts | 8 +- .../types/TranscribeCommandVariableType.ts | 8 + src/api/types/TranscribeConfig.ts | 6 +- src/api/types/TranscribeConfigMessage.ts | 8 +- src/api/types/TranscribeConfigMessageType.ts | 7 + .../types/TranscribeConfigStatusMessage.ts | 6 +- .../TranscribeConfigStatusMessageType.ts | 11 +- src/api/types/TranscribeEndMessage.ts | 8 +- src/api/types/TranscribeEndMessageType.ts | 6 + src/api/types/TranscribeEndedMessage.ts | 8 +- src/api/types/TranscribeEndedMessageType.ts | 6 + src/api/types/TranscribeErrorMessage.ts | 8 +- src/api/types/TranscribeErrorMessageError.ts | 4 +- src/api/types/TranscribeErrorMessageType.ts | 6 + src/api/types/TranscribeFlushMessage.ts | 8 +- src/api/types/TranscribeFlushMessageType.ts | 6 + src/api/types/TranscribeFlushedMessage.ts | 8 +- src/api/types/TranscribeFlushedMessageType.ts | 7 + src/api/types/TranscribeFormatting.ts | 6 +- src/api/types/TranscribeFormattingDates.ts | 10 +- .../types/TranscribeFormattingMeasurements.ts | 11 +- src/api/types/TranscribeFormattingNumbers.ts | 11 +- .../TranscribeFormattingNumericRanges.ts | 11 +- src/api/types/TranscribeFormattingOrdinals.ts | 11 +- src/api/types/TranscribeFormattingTimes.ts | 10 +- src/api/types/TranscribeSupportedLanguage.ts | 4 +- src/api/types/TranscribeTranscriptData.ts | 4 +- src/api/types/TranscribeTranscriptMessage.ts | 8 +- .../types/TranscribeTranscriptMessageType.ts | 7 + src/api/types/TranscribeUsageMessage.ts | 8 +- src/api/types/TranscribeUsageMessageType.ts | 6 + src/api/types/TranscriptsData.ts | 6 +- src/api/types/TranscriptsListItem.ts | 6 +- src/api/types/TranscriptsListResponse.ts | 8 +- src/api/types/TranscriptsMetadata.ts | 6 +- src/api/types/TranscriptsParticipant.ts | 6 +- .../types/TranscriptsParticipantRoleEnum.ts | 7 +- src/api/types/TranscriptsResponse.ts | 8 +- src/api/types/TranscriptsStatusEnum.ts | 10 +- src/api/types/TranscriptsStatusResponse.ts | 6 +- src/api/types/Uuid.ts | 4 +- src/api/types/index.ts | 296 +- src/auth/OAuthAuthProvider.ts | 168 + src/auth/index.ts | 1 + src/core/auth/AuthProvider.ts | 6 + src/core/auth/AuthRequest.ts | 9 + src/core/auth/BasicAuth.ts | 3 +- src/core/auth/BearerToken.ts | 19 +- src/core/auth/NoOpAuthProvider.ts | 8 + src/core/auth/OAuthTokenProvider.ts | 57 - src/core/auth/index.ts | 4 +- src/core/exports.ts | 3 + src/core/fetcher/APIResponse.ts | 2 +- src/core/fetcher/BinaryResponse.ts | 14 +- src/core/fetcher/EndpointMetadata.ts | 13 + src/core/fetcher/EndpointSupplier.ts | 14 + src/core/fetcher/Fetcher.ts | 277 +- src/core/fetcher/HttpResponsePromise.ts | 2 +- src/core/fetcher/ResponseWithBody.ts | 7 - src/core/fetcher/getErrorResponseBody.ts | 3 +- src/core/fetcher/getRequestBody.ts | 6 +- src/core/fetcher/getResponseBody.ts | 29 +- src/core/fetcher/index.ts | 12 +- src/core/fetcher/makeRequest.ts | 8 +- src/core/fetcher/requestWithRetries.ts | 49 +- src/core/fetcher/signals.ts | 14 +- src/core/file/exports.ts | 2 +- src/core/file/file.ts | 49 +- src/core/headers.ts | 24 +- src/core/index.ts | 11 +- src/core/logging/exports.ts | 19 + src/core/logging/index.ts | 1 + src/core/logging/logger.ts | 203 ++ src/core/pagination/CustomPager.ts | 194 + src/core/pagination/Page.ts | 21 +- src/core/pagination/Pageable.ts | 18 - src/core/pagination/exports.ts | 1 + src/core/pagination/index.ts | 2 +- src/core/runtime/runtime.ts | 23 +- src/core/schemas/Schema.ts | 4 +- src/core/schemas/builders/bigint/bigint.ts | 2 +- src/core/schemas/builders/date/date.ts | 2 +- src/core/schemas/builders/enum/enum.ts | 2 +- src/core/schemas/builders/lazy/index.ts | 2 +- src/core/schemas/builders/lazy/lazy.ts | 2 +- src/core/schemas/builders/lazy/lazyObject.ts | 4 +- src/core/schemas/builders/list/list.ts | 2 +- .../builders/literals/booleanLiteral.ts | 2 +- src/core/schemas/builders/literals/index.ts | 2 +- .../builders/literals/stringLiteral.ts | 2 +- .../object-like/getObjectLikeUtils.ts | 4 +- .../schemas/builders/object-like/types.ts | 10 +- src/core/schemas/builders/object/index.ts | 4 +- src/core/schemas/builders/object/object.ts | 54 +- .../object/objectWithoutOptionalProperties.ts | 6 +- src/core/schemas/builders/object/property.ts | 2 +- src/core/schemas/builders/object/types.ts | 10 +- src/core/schemas/builders/primitives/any.ts | 7 +- .../schemas/builders/primitives/boolean.ts | 4 +- src/core/schemas/builders/primitives/index.ts | 1 + src/core/schemas/builders/primitives/never.ts | 15 + .../schemas/builders/primitives/number.ts | 4 +- .../schemas/builders/primitives/string.ts | 4 +- .../schemas/builders/primitives/unknown.ts | 7 +- src/core/schemas/builders/record/record.ts | 6 +- src/core/schemas/builders/record/types.ts | 4 +- .../builders/schema-utils/JsonError.ts | 2 +- .../builders/schema-utils/ParseError.ts | 2 +- .../builders/schema-utils/getSchemaUtils.ts | 2 +- .../schemas/builders/schema-utils/index.ts | 2 +- .../schema-utils/stringifyValidationErrors.ts | 2 +- src/core/schemas/builders/set/set.ts | 2 +- .../builders/undiscriminated-union/types.ts | 2 +- .../undiscriminatedUnion.ts | 11 +- src/core/schemas/builders/union/index.ts | 2 +- src/core/schemas/builders/union/types.ts | 4 +- src/core/schemas/builders/union/union.ts | 12 +- .../utils/createIdentitySchemaCreator.ts | 2 +- src/core/schemas/utils/maybeSkipValidation.ts | 2 +- src/core/url/encodePathParam.ts | 18 + src/core/url/index.ts | 1 + src/core/url/join.ts | 7 +- src/core/websocket/exports.ts | 9 + src/core/websocket/ws.ts | 46 +- src/custom/CortiAuth.ts | 385 -- src/custom/CortiClient.ts | 315 -- src/custom/CortiSDKError.ts | 26 - src/custom/CortiWebSocketProxyClient.ts | 22 - src/custom/CustomStream.ts | 155 - src/custom/CustomStreamSocket.ts | 46 - src/custom/CustomTranscribe.ts | 152 - src/custom/CustomTranscribeSocket.ts | 49 - src/custom/RefreshBearerProvider.ts | 129 - src/custom/index.ts | 1 - src/custom/proxy/CustomProxyStream.ts | 40 - src/custom/proxy/CustomProxyTranscribe.ts | 39 - src/custom/utils/decodeToken.ts | 83 - .../utils/encodeHeadersAsWsProtocols.ts | 74 - src/custom/utils/getEnvironmentFromString.ts | 16 - src/custom/utils/localStorage.ts | 39 - src/custom/utils/pkce.ts | 17 - src/custom/utils/resolveClientOptions.ts | 105 - src/custom/utils/tokenRequest.ts | 64 - src/custom/utils/withCredentialsConfig.ts | 13 - src/environments.ts | 4 +- src/errors/CortiError.ts | 15 +- src/errors/CortiTimeoutError.ts | 11 +- src/errors/handleNonStatusCodeError.ts | 37 + src/index.ts | 31 +- .../resources/agents/client/list.ts | 8 +- .../client/requests/AgentsCreateAgent.ts | 8 +- .../requests/AgentsMessageSendParams.ts | 10 +- src/serialization/resources/agents/index.ts | 2 +- .../types/AgentsCreateAgentAgentType.ts | 8 +- .../types/AgentsCreateAgentExpertsItem.ts | 8 +- .../agents/types/AgentsMessageSendResponse.ts | 8 +- ...TokenRequest.ts => GetTokenAuthRequest.ts} | 16 +- .../resources/auth/client/requests/index.ts | 2 +- src/serialization/resources/auth/index.ts | 2 +- .../resources/auth/types/GetTokenResponse.ts | 8 +- .../requests/CodesGeneralPredictRequest.ts | 10 +- .../client/requests/DocumentsUpdateRequest.ts | 10 +- .../requests/FactsBatchUpdateRequest.ts | 10 +- .../client/requests/FactsCreateRequest.ts | 10 +- .../client/requests/FactsExtractRequest.ts | 8 +- .../client/requests/FactsUpdateRequest.ts | 10 +- .../resources/facts/client/requests/index.ts | 4 +- src/serialization/resources/index.ts | 34 +- .../requests/InteractionsCreateRequest.ts | 10 +- .../requests/InteractionsUpdateRequest.ts | 12 +- .../resources/interactions/index.ts | 2 +- .../types/InteractionsListRequestSort.ts | 8 +- .../client/socket/StreamSocketResponse.ts | 14 +- .../client/socket/TranscribeSocketResponse.ts | 14 +- .../requests/TranscriptsCreateRequest.ts | 12 +- src/serialization/types/AgentsAgent.ts | 8 +- .../types/AgentsAgentCapabilities.ts | 10 +- src/serialization/types/AgentsAgentCard.ts | 28 +- .../types/AgentsAgentCardSignature.ts | 8 +- .../types/AgentsAgentExpertsItem.ts | 8 +- .../types/AgentsAgentExtension.ts | 8 +- .../types/AgentsAgentInterface.ts | 8 +- .../types/AgentsAgentProvider.ts | 8 +- .../types/AgentsAgentReference.ts | 13 +- .../types/AgentsAgentReferenceType.ts | 14 + .../types/AgentsAgentResponse.ts | 8 +- src/serialization/types/AgentsAgentSkill.ts | 16 +- src/serialization/types/AgentsArtifact.ts | 8 +- src/serialization/types/AgentsContext.ts | 8 +- .../types/AgentsContextItemsItem.ts | 10 +- src/serialization/types/AgentsCreateExpert.ts | 13 +- .../types/AgentsCreateExpertReference.ts | 13 +- .../types/AgentsCreateExpertReferenceType.ts | 14 + .../types/AgentsCreateExpertType.ts | 14 + .../types/AgentsCreateMcpServer.ts | 10 +- .../AgentsCreateMcpServerAuthorizationType.ts | 8 +- .../AgentsCreateMcpServerTransportType.ts | 8 +- src/serialization/types/AgentsDataPart.ts | 13 +- src/serialization/types/AgentsDataPartKind.ts | 14 + src/serialization/types/AgentsExpert.ts | 13 +- .../types/AgentsExpertReference.ts | 13 +- .../types/AgentsExpertReferenceType.ts | 14 + src/serialization/types/AgentsExpertType.ts | 12 + src/serialization/types/AgentsFilePart.ts | 13 +- src/serialization/types/AgentsFilePartFile.ts | 10 +- src/serialization/types/AgentsFilePartKind.ts | 14 + .../types/AgentsFileWithBytes.ts | 8 +- src/serialization/types/AgentsFileWithUri.ts | 8 +- src/serialization/types/AgentsMcpServer.ts | 12 +- .../types/AgentsMcpServerAuthorizationType.ts | 8 +- .../types/AgentsMcpServerTransportType.ts | 8 +- src/serialization/types/AgentsMessage.ts | 13 +- src/serialization/types/AgentsMessageKind.ts | 12 + src/serialization/types/AgentsMessageRole.ts | 8 +- .../types/AgentsMessageSendConfiguration.ts | 8 +- src/serialization/types/AgentsPart.ts | 12 +- ...gentsPushNotificationAuthenticationInfo.ts | 8 +- .../types/AgentsPushNotificationConfig.ts | 8 +- .../types/AgentsRegistryExpert.ts | 8 +- .../types/AgentsRegistryExpertsResponse.ts | 8 +- .../types/AgentsRegistryMcpServer.ts | 8 +- ...gentsRegistryMcpServerAuthorizationType.ts | 8 +- src/serialization/types/AgentsTask.ts | 17 +- src/serialization/types/AgentsTaskKind.ts | 12 + src/serialization/types/AgentsTaskStatus.ts | 10 +- .../types/AgentsTaskStatusState.ts | 8 +- src/serialization/types/AgentsTextPart.ts | 13 +- src/serialization/types/AgentsTextPartKind.ts | 14 + .../types/CodesGeneralReadResponse.ts | 10 +- .../CodesGeneralReadResponseEvidencesItem.ts | 8 +- .../types/CodesGeneralResponse.ts | 8 +- src/serialization/types/CommonAiContext.ts | 10 +- .../types/CommonCodingSystemEnum.ts | 8 +- .../types/CommonDocumentIdContext.ts | 13 +- .../types/CommonDocumentIdContextType.ts | 14 + .../types/CommonSortingDirectionEnum.ts | 8 +- src/serialization/types/CommonSourceEnum.ts | 8 +- src/serialization/types/CommonTextContext.ts | 13 +- .../types/CommonTextContextType.ts | 14 + .../types/CommonTranscriptRequest.ts | 8 +- .../types/CommonTranscriptResponse.ts | 8 +- src/serialization/types/CommonUsageInfo.ts | 8 +- src/serialization/types/DocumentsContext.ts | 10 +- .../types/DocumentsContextWithFacts.ts | 13 +- .../types/DocumentsContextWithFactsType.ts | 14 + .../types/DocumentsContextWithString.ts | 13 +- .../types/DocumentsContextWithStringType.ts | 14 + .../types/DocumentsContextWithTranscript.ts | 13 +- .../DocumentsContextWithTranscriptType.ts | 14 + ...quest.ts => DocumentsCreateRequestBody.ts} | 18 +- .../DocumentsCreateRequestWithTemplate.ts | 8 +- .../DocumentsCreateRequestWithTemplateKey.ts | 8 +- .../types/DocumentsGetResponse.ts | 12 +- .../types/DocumentsListResponse.ts | 8 +- src/serialization/types/DocumentsSection.ts | 8 +- .../types/DocumentsSectionInput.ts | 8 +- .../types/DocumentsSectionOverride.ts | 8 +- src/serialization/types/DocumentsTemplate.ts | 10 +- .../types/DocumentsTemplateWithSectionKeys.ts | 8 +- .../types/DocumentsTemplateWithSections.ts | 8 +- src/serialization/types/ErrorResponse.ts | 8 +- .../types/FactsBatchUpdateInput.ts | 8 +- .../types/FactsBatchUpdateItem.ts | 10 +- .../types/FactsBatchUpdateResponse.ts | 8 +- src/serialization/types/FactsContext.ts | 8 +- src/serialization/types/FactsCreateInput.ts | 8 +- src/serialization/types/FactsCreateItem.ts | 10 +- .../types/FactsCreateResponse.ts | 8 +- src/serialization/types/FactsEvidence.ts | 8 +- .../types/FactsExtractResponse.ts | 10 +- .../types/FactsExtractResponseFactsItem.ts | 8 +- .../types/FactsFactGroupsItem.ts | 10 +- .../FactsFactGroupsItemTranslationsItem.ts | 8 +- .../types/FactsFactGroupsListResponse.ts | 8 +- src/serialization/types/FactsListItem.ts | 10 +- src/serialization/types/FactsListResponse.ts | 8 +- .../types/FactsUpdateResponse.ts | 10 +- .../types/InteractionsCreateResponse.ts | 8 +- .../InteractionsEncounterCreateRequest.ts | 12 +- .../types/InteractionsEncounterPeriod.ts | 10 +- .../types/InteractionsEncounterResponse.ts | 12 +- .../types/InteractionsEncounterStatusEnum.ts | 8 +- .../types/InteractionsEncounterTypeEnum.ts | 8 +- .../InteractionsEncounterUpdateRequest.ts | 12 +- .../types/InteractionsGenderEnum.ts | 8 +- .../types/InteractionsGetResponse.ts | 12 +- .../types/InteractionsListResponse.ts | 8 +- .../types/InteractionsPatient.ts | 14 +- .../types/RecordingsCreateResponse.ts | 8 +- .../types/RecordingsListResponse.ts | 8 +- src/serialization/types/StreamConfig.ts | 10 +- .../types/StreamConfigMessage.ts | 13 +- .../types/StreamConfigMessageType.ts | 14 + src/serialization/types/StreamConfigMode.ts | 8 +- .../types/StreamConfigModeType.ts | 8 +- .../types/StreamConfigParticipant.ts | 8 +- .../types/StreamConfigParticipantRole.ts | 8 +- .../types/StreamConfigStatusMessage.ts | 8 +- .../types/StreamConfigStatusMessageType.ts | 8 +- .../types/StreamConfigTranscription.ts | 10 +- src/serialization/types/StreamEndMessage.ts | 13 +- .../types/StreamEndMessageType.ts | 14 + src/serialization/types/StreamEndedMessage.ts | 13 +- .../types/StreamEndedMessageType.ts | 14 + src/serialization/types/StreamErrorDetail.ts | 8 +- src/serialization/types/StreamErrorMessage.ts | 13 +- .../types/StreamErrorMessageType.ts | 14 + src/serialization/types/StreamFact.ts | 8 +- src/serialization/types/StreamFactsMessage.ts | 13 +- .../types/StreamFactsMessageType.ts | 14 + src/serialization/types/StreamFlushMessage.ts | 13 +- .../types/StreamFlushMessageType.ts | 14 + .../types/StreamFlushedMessage.ts | 13 +- .../types/StreamFlushedMessageType.ts | 14 + src/serialization/types/StreamParticipant.ts | 8 +- .../types/StreamSupportedLanguage.ts | 8 +- src/serialization/types/StreamTranscript.ts | 8 +- .../types/StreamTranscriptMessage.ts | 13 +- .../types/StreamTranscriptMessageType.ts | 14 + .../types/StreamTranscriptTime.ts | 8 +- src/serialization/types/StreamUsageMessage.ts | 13 +- .../types/StreamUsageMessageType.ts | 14 + .../types/TemplatesDocumentationModeEnum.ts | 8 +- .../types/TemplatesFormatRule.ts | 12 +- src/serialization/types/TemplatesItem.ts | 12 +- .../types/TemplatesListResponse.ts | 8 +- src/serialization/types/TemplatesSection.ts | 14 +- .../types/TemplatesSectionListResponse.ts | 8 +- .../types/TemplatesSectionSorted.ts | 8 +- .../types/TemplatesSectionTranslation.ts | 12 +- .../types/TemplatesTranslation.ts | 8 +- .../types/TemplatesWritingStyle.ts | 8 +- src/serialization/types/TranscribeCommand.ts | 8 +- .../types/TranscribeCommandData.ts | 12 +- .../types/TranscribeCommandMessage.ts | 13 +- .../types/TranscribeCommandMessageType.ts | 14 + .../types/TranscribeCommandVariable.ts | 13 +- .../types/TranscribeCommandVariableType.ts | 14 + src/serialization/types/TranscribeConfig.ts | 10 +- .../types/TranscribeConfigMessage.ts | 13 +- .../types/TranscribeConfigMessageType.ts | 14 + .../types/TranscribeConfigStatusMessage.ts | 8 +- .../TranscribeConfigStatusMessageType.ts | 8 +- .../types/TranscribeEndMessage.ts | 13 +- .../types/TranscribeEndMessageType.ts | 14 + .../types/TranscribeEndedMessage.ts | 13 +- .../types/TranscribeEndedMessageType.ts | 14 + .../types/TranscribeErrorMessage.ts | 13 +- .../types/TranscribeErrorMessageError.ts | 8 +- .../types/TranscribeErrorMessageType.ts | 14 + .../types/TranscribeFlushMessage.ts | 13 +- .../types/TranscribeFlushMessageType.ts | 14 + .../types/TranscribeFlushedMessage.ts | 13 +- .../types/TranscribeFlushedMessageType.ts | 14 + .../types/TranscribeFormatting.ts | 12 +- .../types/TranscribeFormattingDates.ts | 8 +- .../types/TranscribeFormattingMeasurements.ts | 8 +- .../types/TranscribeFormattingNumbers.ts | 8 +- .../TranscribeFormattingNumericRanges.ts | 8 +- .../types/TranscribeFormattingOrdinals.ts | 8 +- .../types/TranscribeFormattingTimes.ts | 8 +- .../types/TranscribeSupportedLanguage.ts | 8 +- .../types/TranscribeTranscriptData.ts | 8 +- .../types/TranscribeTranscriptMessage.ts | 13 +- .../types/TranscribeTranscriptMessageType.ts | 14 + .../types/TranscribeUsageMessage.ts | 13 +- .../types/TranscribeUsageMessageType.ts | 14 + src/serialization/types/TranscriptsData.ts | 10 +- .../types/TranscriptsListItem.ts | 10 +- .../types/TranscriptsListResponse.ts | 12 +- .../types/TranscriptsMetadata.ts | 10 +- .../types/TranscriptsParticipant.ts | 8 +- .../types/TranscriptsParticipantRoleEnum.ts | 8 +- .../types/TranscriptsResponse.ts | 16 +- .../types/TranscriptsStatusEnum.ts | 8 +- .../types/TranscriptsStatusResponse.ts | 8 +- src/serialization/types/Uuid.ts | 8 +- src/serialization/types/index.ts | 296 +- tests/BrowserTestEnvironment.ts | 17 - tests/custom/agents.create.integration.ts | 110 - tests/custom/agents.delete.integration.ts | 59 - tests/custom/agents.get.integration.ts | 59 - tests/custom/agents.getCard.integration.ts | 50 - tests/custom/agents.getContext.integration.ts | 157 - .../agents.getRegistryExperts.integration.ts | 63 - tests/custom/agents.getTask.integration.ts | 115 - tests/custom/agents.list.integration.ts | 109 - .../custom/agents.messageSend.integration.ts | 399 -- tests/custom/agents.update.integration.ts | 198 - tests/custom/codes.predict.integration.ts | 230 -- tests/custom/documents.create.integration.ts | 1342 ------- tests/custom/documents.delete.integration.ts | 61 - tests/custom/documents.get.integration.ts | 69 - tests/custom/documents.list.integration.ts | 59 - tests/custom/documents.update.integration.ts | 255 -- tests/custom/facts.batchUpdate.integration.ts | 372 -- tests/custom/facts.create.integration.ts | 249 -- tests/custom/facts.extract.integration.ts | 304 -- .../facts.factGroupsList.integration.ts | 28 - tests/custom/facts.list.integration.ts | 60 - tests/custom/facts.update.integration.ts | 248 -- .../custom/interactions.create.integration.ts | 440 --- .../custom/interactions.delete.integration.ts | 46 - tests/custom/interactions.get.integration.ts | 46 - tests/custom/interactions.list.integration.ts | 684 ---- .../custom/interactions.update.integration.ts | 370 -- tests/custom/recordings.delete.integration.ts | 113 - tests/custom/recordings.get.integration.ts | 174 - tests/custom/recordings.list.integration.ts | 96 - tests/custom/recordings.upload.integration.ts | 110 - tests/custom/stream.connect.integration.ts | 569 --- tests/custom/templates.get.integration.ts | 80 - tests/custom/templates.list.integration.ts | 164 - .../templates.sectionList.integration.ts | 116 - tests/custom/testUtils.ts | 352 -- .../custom/transcribe.connect.integration.ts | 444 --- .../custom/transcripts.create.integration.ts | 337 -- .../custom/transcripts.delete.integration.ts | 117 - tests/custom/transcripts.get.integration.ts | 119 - tests/custom/transcripts.list.integration.ts | 147 - tests/custom/trouble-breathing.mp3 | Bin 2008239 -> 0 bytes tests/mock-server/MockServer.ts | 4 +- tests/mock-server/MockServerPool.ts | 10 +- tests/mock-server/mockEndpointBuilder.ts | 35 +- tests/mock-server/setup.ts | 2 +- tests/mock-server/withFormUrlEncoded.ts | 89 + tests/mock-server/withHeaders.ts | 2 +- tests/mock-server/withJson.ts | 35 +- tests/setup.ts | 80 + tests/tsconfig.json | 3 +- tests/unit/auth/BasicAuth.test.ts | 92 +- tests/unit/fetcher/Fetcher.test.ts | 48 +- .../unit/fetcher/HttpResponsePromise.test.ts | 10 +- tests/unit/fetcher/RawResponse.test.ts | 2 +- tests/unit/fetcher/createRequestUrl.test.ts | 305 +- tests/unit/fetcher/getRequestBody.test.ts | 154 +- tests/unit/fetcher/getResponseBody.test.ts | 90 +- tests/unit/fetcher/logging.test.ts | 517 +++ tests/unit/fetcher/makeRequest.test.ts | 5 +- tests/unit/fetcher/redacting.test.ts | 1115 ++++++ tests/unit/fetcher/requestWithRetries.test.ts | 138 +- tests/unit/fetcher/signals.test.ts | 8 +- tests/unit/file/file.test.ts | 48 +- tests/unit/logging/logger.test.ts | 454 +++ tests/unit/schemas/lazy/lazy.test.ts | 6 +- .../object-like/withParsedProperties.test.ts | 2 +- tests/unit/schemas/object/extend.test.ts | 2 +- tests/unit/schemas/primitives/never.test.ts | 54 + .../schema-utils/getSchemaUtils.test.ts | 6 +- .../undiscriminatedUnion.test.ts | 2 +- tests/unit/schemas/utils/itSchema.ts | 14 +- tests/unit/schemas/utils/itValidate.ts | 10 +- tests/unit/{file => }/test-file.txt | 0 tests/unit/url/join.test.ts | 324 +- tests/unit/url/qs.test.ts | 375 +- tests/wire/agents.test.ts | 1653 +++++++++ tests/wire/auth.test.ts | 53 + tests/wire/codes.test.ts | 320 ++ tests/wire/documents.test.ts | 1117 ++++++ tests/wire/facts.test.ts | 509 +++ tests/wire/interactions.test.ts | 641 ++++ tests/wire/mockAuth.ts | 26 + tests/wire/recordings.test.ts | 293 ++ tests/wire/templates.test.ts | 349 ++ tests/wire/transcripts.test.ts | 862 +++++ tsconfig.base.json | 4 +- tsconfig.esm.json | 3 +- vitest.config.mts | 28 + yarn.lock | 3237 ----------------- 738 files changed, 20478 insertions(+), 20912 deletions(-) create mode 100644 .fern/metadata.json create mode 100644 .fernignore delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 .github/workflows/integration-tests.yml delete mode 100644 .npmignore delete mode 100644 .prettierrc.yml delete mode 100644 AUTHENTICATION.md create mode 100644 CONTRIBUTING.md delete mode 100644 PROXYING.md create mode 100644 biome.json delete mode 100644 jest.config.mjs delete mode 100644 jest.integration.config.mjs create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml create mode 100644 reference.md create mode 100644 src/BaseClient.ts create mode 100644 src/api/resources/agents/client/requests/AgentsDeleteRequest.ts create mode 100644 src/api/resources/agents/client/requests/AgentsGetCardRequest.ts create mode 100644 src/api/resources/agents/client/requests/AgentsGetRequest.ts create mode 100644 src/api/resources/agents/client/requests/AgentsUpdateRequest.ts rename src/api/resources/auth/client/requests/{AuthGetTokenRequest.ts => GetTokenAuthRequest.ts} (69%) create mode 100644 src/api/resources/documents/client/requests/DocumentsCreateRequest.ts create mode 100644 src/api/resources/documents/client/requests/DocumentsDeleteRequest.ts create mode 100644 src/api/resources/documents/client/requests/DocumentsGetRequest.ts create mode 100644 src/api/resources/documents/client/requests/DocumentsListRequest.ts create mode 100644 src/api/resources/facts/client/requests/FactsListRequest.ts create mode 100644 src/api/resources/interactions/client/requests/InteractionsDeleteRequest.ts create mode 100644 src/api/resources/interactions/client/requests/InteractionsGetRequest.ts create mode 100644 src/api/resources/recordings/client/requests/RecordingsDeleteRequest.ts create mode 100644 src/api/resources/recordings/client/requests/RecordingsGetRequest.ts create mode 100644 src/api/resources/recordings/client/requests/RecordingsListRequest.ts create mode 100644 src/api/resources/recordings/client/requests/index.ts create mode 100644 src/api/resources/templates/client/requests/TemplatesGetRequest.ts create mode 100644 src/api/resources/transcripts/client/requests/TranscriptsDeleteRequest.ts create mode 100644 src/api/resources/transcripts/client/requests/TranscriptsGetRequest.ts create mode 100644 src/api/resources/transcripts/client/requests/TranscriptsGetStatusRequest.ts create mode 100644 src/api/types/AgentsAgentReferenceType.ts create mode 100644 src/api/types/AgentsCreateExpertReferenceType.ts create mode 100644 src/api/types/AgentsCreateExpertType.ts create mode 100644 src/api/types/AgentsDataPartKind.ts create mode 100644 src/api/types/AgentsExpertReferenceType.ts create mode 100644 src/api/types/AgentsExpertType.ts create mode 100644 src/api/types/AgentsFilePartKind.ts create mode 100644 src/api/types/AgentsMessageKind.ts create mode 100644 src/api/types/AgentsTaskKind.ts create mode 100644 src/api/types/AgentsTextPartKind.ts create mode 100644 src/api/types/CommonDocumentIdContextType.ts create mode 100644 src/api/types/CommonTextContextType.ts create mode 100644 src/api/types/DocumentsContextWithFactsType.ts create mode 100644 src/api/types/DocumentsContextWithStringType.ts create mode 100644 src/api/types/DocumentsContextWithTranscriptType.ts rename src/api/types/{DocumentsCreateRequest.ts => DocumentsCreateRequestBody.ts} (75%) create mode 100644 src/api/types/StreamConfigMessageType.ts create mode 100644 src/api/types/StreamEndMessageType.ts create mode 100644 src/api/types/StreamEndedMessageType.ts create mode 100644 src/api/types/StreamErrorMessageType.ts create mode 100644 src/api/types/StreamFactsMessageType.ts create mode 100644 src/api/types/StreamFlushMessageType.ts create mode 100644 src/api/types/StreamFlushedMessageType.ts create mode 100644 src/api/types/StreamTranscriptMessageType.ts create mode 100644 src/api/types/StreamUsageMessageType.ts create mode 100644 src/api/types/TranscribeCommandMessageType.ts create mode 100644 src/api/types/TranscribeCommandVariableType.ts create mode 100644 src/api/types/TranscribeConfigMessageType.ts create mode 100644 src/api/types/TranscribeEndMessageType.ts create mode 100644 src/api/types/TranscribeEndedMessageType.ts create mode 100644 src/api/types/TranscribeErrorMessageType.ts create mode 100644 src/api/types/TranscribeFlushMessageType.ts create mode 100644 src/api/types/TranscribeFlushedMessageType.ts create mode 100644 src/api/types/TranscribeTranscriptMessageType.ts create mode 100644 src/api/types/TranscribeUsageMessageType.ts create mode 100644 src/auth/OAuthAuthProvider.ts create mode 100644 src/auth/index.ts create mode 100644 src/core/auth/AuthProvider.ts create mode 100644 src/core/auth/AuthRequest.ts create mode 100644 src/core/auth/NoOpAuthProvider.ts delete mode 100644 src/core/auth/OAuthTokenProvider.ts create mode 100644 src/core/fetcher/EndpointMetadata.ts create mode 100644 src/core/fetcher/EndpointSupplier.ts delete mode 100644 src/core/fetcher/ResponseWithBody.ts create mode 100644 src/core/logging/exports.ts create mode 100644 src/core/logging/index.ts create mode 100644 src/core/logging/logger.ts create mode 100644 src/core/pagination/CustomPager.ts delete mode 100644 src/core/pagination/Pageable.ts create mode 100644 src/core/pagination/exports.ts create mode 100644 src/core/schemas/builders/primitives/never.ts create mode 100644 src/core/url/encodePathParam.ts create mode 100644 src/core/websocket/exports.ts delete mode 100644 src/custom/CortiAuth.ts delete mode 100644 src/custom/CortiClient.ts delete mode 100644 src/custom/CortiSDKError.ts delete mode 100644 src/custom/CortiWebSocketProxyClient.ts delete mode 100644 src/custom/CustomStream.ts delete mode 100644 src/custom/CustomStreamSocket.ts delete mode 100644 src/custom/CustomTranscribe.ts delete mode 100644 src/custom/CustomTranscribeSocket.ts delete mode 100644 src/custom/RefreshBearerProvider.ts delete mode 100644 src/custom/index.ts delete mode 100644 src/custom/proxy/CustomProxyStream.ts delete mode 100644 src/custom/proxy/CustomProxyTranscribe.ts delete mode 100644 src/custom/utils/decodeToken.ts delete mode 100644 src/custom/utils/encodeHeadersAsWsProtocols.ts delete mode 100644 src/custom/utils/getEnvironmentFromString.ts delete mode 100644 src/custom/utils/localStorage.ts delete mode 100644 src/custom/utils/pkce.ts delete mode 100644 src/custom/utils/resolveClientOptions.ts delete mode 100644 src/custom/utils/tokenRequest.ts delete mode 100644 src/custom/utils/withCredentialsConfig.ts create mode 100644 src/errors/handleNonStatusCodeError.ts rename src/serialization/resources/auth/client/requests/{AuthGetTokenRequest.ts => GetTokenAuthRequest.ts} (51%) create mode 100644 src/serialization/types/AgentsAgentReferenceType.ts create mode 100644 src/serialization/types/AgentsCreateExpertReferenceType.ts create mode 100644 src/serialization/types/AgentsCreateExpertType.ts create mode 100644 src/serialization/types/AgentsDataPartKind.ts create mode 100644 src/serialization/types/AgentsExpertReferenceType.ts create mode 100644 src/serialization/types/AgentsExpertType.ts create mode 100644 src/serialization/types/AgentsFilePartKind.ts create mode 100644 src/serialization/types/AgentsMessageKind.ts create mode 100644 src/serialization/types/AgentsTaskKind.ts create mode 100644 src/serialization/types/AgentsTextPartKind.ts create mode 100644 src/serialization/types/CommonDocumentIdContextType.ts create mode 100644 src/serialization/types/CommonTextContextType.ts create mode 100644 src/serialization/types/DocumentsContextWithFactsType.ts create mode 100644 src/serialization/types/DocumentsContextWithStringType.ts create mode 100644 src/serialization/types/DocumentsContextWithTranscriptType.ts rename src/serialization/types/{DocumentsCreateRequest.ts => DocumentsCreateRequestBody.ts} (56%) create mode 100644 src/serialization/types/StreamConfigMessageType.ts create mode 100644 src/serialization/types/StreamEndMessageType.ts create mode 100644 src/serialization/types/StreamEndedMessageType.ts create mode 100644 src/serialization/types/StreamErrorMessageType.ts create mode 100644 src/serialization/types/StreamFactsMessageType.ts create mode 100644 src/serialization/types/StreamFlushMessageType.ts create mode 100644 src/serialization/types/StreamFlushedMessageType.ts create mode 100644 src/serialization/types/StreamTranscriptMessageType.ts create mode 100644 src/serialization/types/StreamUsageMessageType.ts create mode 100644 src/serialization/types/TranscribeCommandMessageType.ts create mode 100644 src/serialization/types/TranscribeCommandVariableType.ts create mode 100644 src/serialization/types/TranscribeConfigMessageType.ts create mode 100644 src/serialization/types/TranscribeEndMessageType.ts create mode 100644 src/serialization/types/TranscribeEndedMessageType.ts create mode 100644 src/serialization/types/TranscribeErrorMessageType.ts create mode 100644 src/serialization/types/TranscribeFlushMessageType.ts create mode 100644 src/serialization/types/TranscribeFlushedMessageType.ts create mode 100644 src/serialization/types/TranscribeTranscriptMessageType.ts create mode 100644 src/serialization/types/TranscribeUsageMessageType.ts delete mode 100644 tests/BrowserTestEnvironment.ts delete mode 100644 tests/custom/agents.create.integration.ts delete mode 100644 tests/custom/agents.delete.integration.ts delete mode 100644 tests/custom/agents.get.integration.ts delete mode 100644 tests/custom/agents.getCard.integration.ts delete mode 100644 tests/custom/agents.getContext.integration.ts delete mode 100644 tests/custom/agents.getRegistryExperts.integration.ts delete mode 100644 tests/custom/agents.getTask.integration.ts delete mode 100644 tests/custom/agents.list.integration.ts delete mode 100644 tests/custom/agents.messageSend.integration.ts delete mode 100644 tests/custom/agents.update.integration.ts delete mode 100644 tests/custom/codes.predict.integration.ts delete mode 100644 tests/custom/documents.create.integration.ts delete mode 100644 tests/custom/documents.delete.integration.ts delete mode 100644 tests/custom/documents.get.integration.ts delete mode 100644 tests/custom/documents.list.integration.ts delete mode 100644 tests/custom/documents.update.integration.ts delete mode 100644 tests/custom/facts.batchUpdate.integration.ts delete mode 100644 tests/custom/facts.create.integration.ts delete mode 100644 tests/custom/facts.extract.integration.ts delete mode 100644 tests/custom/facts.factGroupsList.integration.ts delete mode 100644 tests/custom/facts.list.integration.ts delete mode 100644 tests/custom/facts.update.integration.ts delete mode 100644 tests/custom/interactions.create.integration.ts delete mode 100644 tests/custom/interactions.delete.integration.ts delete mode 100644 tests/custom/interactions.get.integration.ts delete mode 100644 tests/custom/interactions.list.integration.ts delete mode 100644 tests/custom/interactions.update.integration.ts delete mode 100644 tests/custom/recordings.delete.integration.ts delete mode 100644 tests/custom/recordings.get.integration.ts delete mode 100644 tests/custom/recordings.list.integration.ts delete mode 100644 tests/custom/recordings.upload.integration.ts delete mode 100644 tests/custom/stream.connect.integration.ts delete mode 100644 tests/custom/templates.get.integration.ts delete mode 100644 tests/custom/templates.list.integration.ts delete mode 100644 tests/custom/templates.sectionList.integration.ts delete mode 100644 tests/custom/testUtils.ts delete mode 100644 tests/custom/transcribe.connect.integration.ts delete mode 100644 tests/custom/transcripts.create.integration.ts delete mode 100644 tests/custom/transcripts.delete.integration.ts delete mode 100644 tests/custom/transcripts.get.integration.ts delete mode 100644 tests/custom/transcripts.list.integration.ts delete mode 100644 tests/custom/trouble-breathing.mp3 create mode 100644 tests/mock-server/withFormUrlEncoded.ts create mode 100644 tests/setup.ts create mode 100644 tests/unit/fetcher/logging.test.ts create mode 100644 tests/unit/fetcher/redacting.test.ts create mode 100644 tests/unit/logging/logger.test.ts create mode 100644 tests/unit/schemas/primitives/never.test.ts rename tests/unit/{file => }/test-file.txt (100%) create mode 100644 tests/wire/agents.test.ts create mode 100644 tests/wire/auth.test.ts create mode 100644 tests/wire/codes.test.ts create mode 100644 tests/wire/documents.test.ts create mode 100644 tests/wire/facts.test.ts create mode 100644 tests/wire/interactions.test.ts create mode 100644 tests/wire/mockAuth.ts create mode 100644 tests/wire/recordings.test.ts create mode 100644 tests/wire/templates.test.ts create mode 100644 tests/wire/transcripts.test.ts create mode 100644 vitest.config.mts delete mode 100644 yarn.lock diff --git a/.fern/metadata.json b/.fern/metadata.json new file mode 100644 index 00000000..68e76761 --- /dev/null +++ b/.fern/metadata.json @@ -0,0 +1,16 @@ +{ + "cliVersion": "3.74.1", + "generatorName": "fernapi/fern-typescript-node-sdk", + "generatorVersion": "3.48.0", + "generatorConfig": { + "namespaceExport": "Corti", + "noSerdeLayer": false, + "enableInlineTypes": false, + "streamType": "web", + "shouldGenerateWebsocketClients": true, + "extraDevDependencies": { + "@faker-js/faker": "^9.9.0" + } + }, + "sdkVersion": "0.10.1" +} diff --git a/.fernignore b/.fernignore new file mode 100644 index 00000000..084a8ebb --- /dev/null +++ b/.fernignore @@ -0,0 +1 @@ +# Specify files that shouldn't be modified by Fern diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index c3abcfb3..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,49 +0,0 @@ ---- -name: Bug Report -about: Create a report to help us improve -title: "[BUG] " -labels: ["bug"] -assignees: "" ---- - -## 1. Summary - -Provide a clear and concise description of the issue. - -## 2. Steps to Reproduce - -List the steps to reproduce the issue: - -1. Go to '...' -2. Click on '...' -3. Scroll down to '...' -4. See error - -## 3. Expected Behavior - -What should have happened? - -## 4. Actual Behavior - -What actually happened? - -## 5. Screenshots or Logs (if applicable) - -Attach screenshots, recordings, or logs that help clarify the problem. - -## 6. Environment - -- **Platform** (Web, iOS, Android, etc.): -- **Browser/Device version**: -- **User role** (if applicable): - -## 7. Priority Level - -- [ ] 🔴 Blocker (prevents work/usage entirely) -- [ ] 🟠 High (critical path disrupted) -- [ ] 🟡 Medium (can work around it) -- [ ] 🟢 Low (cosmetic/minor inconvenience) - -## 8. Additional Context - -Anything else that might be useful for diagnosing or fixing the issue. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index 3f4b005e..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: Feature Request -about: Suggest an idea for this project -title: "[FEATURE] " -labels: ["enhancement"] -assignees: "" ---- - -## 1. What is the problem you're trying to solve? - -Describe the user pain point or limitation clearly. - -## 2. Describe the proposed solution - -How would you like the system to behave? - -## 3. Who would benefit from this feature? - -List the user roles or personas affected (e.g., end users, support, QA). - -## 4. Why is this feature important? - -Explain the business or user value of implementing this feature. - -## 5. Priority Level - -- [ ] 🔴 Must-have -- [ ] 🟠 Should-have -- [ ] 🟡 Nice-to-have -- [ ] 🟢 Exploratory/Idea-stage - -## 6. Acceptance Criteria - -Define success criteria or how we'll know the feature is working correctly. Use Gherkin-style if helpful: - -``` -Given [context] -When [action] -Then [expected outcome] -``` - -## 7. Alternatives Considered - -Have you tried any workarounds or alternative solutions? - -## 8. Additional Context / Mockups - -Attach diagrams, mockups, references, or similar feature links if available. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 01a81611..83610699 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,84 +3,76 @@ name: ci on: [push] jobs: - compile: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Set up node - uses: actions/setup-node@v4 - # with: - # node-version: "18.18.0" - - - name: Setup yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - - - name: Compile - run: yarn build - - test: - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Set up node - uses: actions/setup-node@v4 - # with: - # node-version: "18.18.0" - - - name: Setup yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - -# - name: Check for formatting issues -# run: yarn prettier . --check --ignore-unknown - - - name: Run tests - run: yarn test - - publish: - needs: [compile, test] - if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') - runs-on: ubuntu-latest - permissions: - id-token: write - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Set up node - uses: actions/setup-node@v4 - # with: - # node-version: "18.18.0" - - - name: Setup yarn - run: npm install -g yarn - - - name: Install dependencies - run: yarn install - - - name: Build - run: yarn build - - - name: Publish to npm - run: | - publish() { - npx -y npm@latest publish "$@" - } - if [[ ${GITHUB_REF} == *alpha* ]]; then - publish --access public --tag alpha - elif [[ ${GITHUB_REF} == *beta* ]]; then - publish --access public --tag beta - elif [[ ${GITHUB_REF} == *rc* ]]; then - publish --tag rc - else - publish --access public - fi + compile: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Set up node + uses: actions/setup-node@v6 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Compile + run: pnpm build + + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Set up node + uses: actions/setup-node@v6 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Test + run: pnpm test + + publish: + needs: [ compile, test ] + if: github.event_name == 'push' && contains(github.ref, 'refs/tags/') + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Set up node + uses: actions/setup-node@v6 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build + run: pnpm build + + - name: Publish to npm + run: | + npm config set //registry.npmjs.org/:_authToken ${NPM_TOKEN} + publish() { # use latest npm to ensure OIDC support + npx -y npm@latest publish "$@" + } + if [[ ${GITHUB_REF} == *alpha* ]]; then + publish --access public --tag alpha + elif [[ ${GITHUB_REF} == *beta* ]]; then + publish --access public --tag beta + else + publish --access public + fi + env: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml deleted file mode 100644 index b1d2110a..00000000 --- a/.github/workflows/integration-tests.yml +++ /dev/null @@ -1,29 +0,0 @@ -name: integration-tests - -on: [pull_request] - -concurrency: - group: integration-tests - cancel-in-progress: true - -jobs: - integration-tests: - runs-on: ubuntu-latest - - steps: - - name: Checkout repo - uses: actions/checkout@v4 - - - name: Set up node - uses: actions/setup-node@v3 - - - name: Install dependencies - run: yarn - - - name: Run integration tests - run: yarn jest --config jest.integration.config.mjs - env: - CORTI_ENVIRONMENT: ${{ vars.CORTI_ENVIRONMENT }} - CORTI_TENANT_NAME: ${{ vars.CORTI_TENANT_NAME }} - CORTI_CLIENT_ID: ${{ vars.CORTI_CLIENT_ID }} - CORTI_CLIENT_SECRET: ${{ secrets.CORTI_CLIENT_SECRET }} diff --git a/.npmignore b/.npmignore deleted file mode 100644 index 6db0876c..00000000 --- a/.npmignore +++ /dev/null @@ -1,9 +0,0 @@ -node_modules -src -tests -.gitignore -.github -.fernignore -.prettierrc.yml -tsconfig.json -yarn.lock \ No newline at end of file diff --git a/.prettierrc.yml b/.prettierrc.yml deleted file mode 100644 index 0c06786b..00000000 --- a/.prettierrc.yml +++ /dev/null @@ -1,2 +0,0 @@ -tabWidth: 4 -printWidth: 120 diff --git a/AUTHENTICATION.md b/AUTHENTICATION.md deleted file mode 100644 index 3a22915c..00000000 --- a/AUTHENTICATION.md +++ /dev/null @@ -1,495 +0,0 @@ -# Authentication Guide - -The Corti TypeScript SDK supports multiple authentication methods to provide flexibility for different use cases. This guide covers all available authentication options and their usage. - -## Overview - -The SDK supports five main authentication methods: - -1. **Client Credentials (OAuth2)** - Traditional OAuth2 client credentials flow (Backend only) -2. **Bearer Token** - Direct token usage with optional refresh capability (Frontend & Backend) -3. **Authorization Code Flow without PKCE (OAuth2)** - Full OAuth2 authorization code flow for user authentication (Frontend & Backend) -4. **Authorization Code Flow with PKCE (OAuth2)** - OAuth2 authorization code flow with PKCE for enhanced security (Frontend & Backend) -5. **Resource Owner Password Credentials (ROPC)** - OAuth2 ROPC flow for username/password authentication (Frontend & Backend, requires server endpoint) - -## Client Credentials Authentication - -**⚠️ Backend Only** - This method should only be used in server-side applications where client secrets can be securely stored. - -This is the most common authentication method for server-to-server applications. The SDK handles the OAuth2 token exchange and refresh automatically, ensuring your application always has valid credentials. - -For detailed information about Client Credentials flow, see the [official Corti documentation](https://docs.corti.ai/about/oauth#4-client-credentials-grant-used-for-api-integrations). - -> **⚠️ Security Note**: Client Credentials tokens are multi-user tokens that provide access to all data within the same API Client. If you need to use the SDK from the frontend, consider implementing a proxy or using scoped tokens. See the [Proxying Guide](./PROXYING.md) for detailed information about securing frontend implementations. - -### Basic Usage - -> Note: The `codeChallenge` must be generated by applying SHA-256 to the verifier and encoding with URL-safe Base64. - -```typescript -import { CortiEnvironment, CortiClient } from "@corti/sdk"; - -const client = new CortiClient({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", - auth: { - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", - }, -}); -``` - -## Bearer Token Authentication - -**✅ Frontend & Backend** - This method can be used in both client-side and server-side applications. - -Use this method when you already have an access token from another source or want to manage tokens externally. - -### Generating Bearer Tokens (Backend) - -You can generate bearer tokens on your **backend server** using `CortiAuth`: - -```typescript -import { CortiAuth, CortiEnvironment } from "@corti/sdk"; - -const auth = new CortiAuth({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", -}); - -// Generate tokens using client credentials -const tokenResponse = await auth.getToken({ - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", -}); - -/** -interface GetTokenResponse { - accessToken: string; - tokenType?: string; // Optional: Token type (defaults to "Bearer") - expiresIn: number; - refreshToken?: string; - refreshExpiresIn?: number; -} -*/ -``` - -### Basic Bearer Token - -Use the token data received from your backend server (from the `getToken` call above) to initialize the client: - -```typescript -const client = new CortiClient({ - auth: { - accessToken: "YOUR_ACCESS_TOKEN", - // Optional: expiration can be extracted from token. Provide only when straight from server - expiresIn: 3600, - }, -}); -``` - -You can spread the token response directly from your backend: - -```typescript -const client = new CortiClient({ - auth: { - ...tokenResponse, // Spread the token object received from your backend - }, -}); -``` - -### Bearer Token With Refresh Token Support - -You can use a refresh function to automatically refresh tokens when they expire. You can provide an initial access token or start with just the refresh function: - -**With initial access and refresh tokens:** - -```typescript -const client = new CortiClient({ - auth: { - accessToken: "YOUR_ACCESS_TOKEN", - refreshToken: "YOUR_REFRESH_TOKEN", - refreshAccessToken: async (refreshToken?: string) => { - // Your custom logic to get a new access token - const response = await fetch("https://your-auth-server/refresh", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ refreshToken }), - }); - - // Response must return a valid token object: - // { - // accessToken: string; // Required: The new access token - // expiresIn?: number; // Optional: Seconds until token expires - // refreshToken?: string; // Optional: New refresh token if rotated - // refreshExpiresIn?: number; // Optional: Seconds until refresh token expires - // tokenType?: string; // Optional: Token type (defaults to "Bearer") - // } - return response.json(); - }, - }, -}); -``` - -**Without initial access token (refreshToken will be undefined for the first call):** - -```typescript -const client = new CortiClient({ - auth: { - // refreshToken will be undefined for the first call, then it will be the refreshToken returned from the previous token request - refreshAccessToken: async (refreshToken?: string) => { - // Your custom logic to get a new access token - const response = await fetch("https://your-auth-server/token", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ refreshToken }), - }); - - // Response must return a valid token object: - // { - // accessToken: string; // Required: The new access token - // expiresIn?: number; // Optional: Seconds until token expires - // refreshToken?: string; // Optional: New refresh token if rotated - // refreshExpiresIn?: number; // Optional: Seconds until refresh token expires - // tokenType?: string; // Optional: Token type (defaults to "Bearer") - // } - return response.json(); - }, - }, -}); -``` - -## Authorization Code Flow - -**✅ Client-Side or Backend** - This method can be fully handled on the client side, or tokens can be exchanged on the backend. The SDK handles all authentication steps. - -**Note**: CORS is enabled for this flow. Requests must come from the same origin as specified in your redirect URIs configuration. - -The Authorization Code Flow is the standard OAuth2 flow for user authentication. This flow is implemented through the `CortiAuth` class and is available when enabled for your client. - -For detailed information about Authorization Code Flow, see the [official Corti documentation](https://docs.corti.ai/about/oauth#2-authorization-code-flow-without-pkce). - -### Basic Flow Overview - -1. **Redirect user to authorization URL** - User is redirected to Corti's login page -2. **User authenticates** - User logs in and authorizes your application -3. **Receive authorization code** - User is redirected back with an authorization code -4. **Exchange code for tokens** - Exchange the authorization code for access and refresh tokens using SDK (client-side) -5. **Use tokens** - Pass the tokens to a new `CortiClient` instance to make authenticated API calls, refresh when needed - -### Step 1: Create Authorization URL - -```typescript -import { CortiAuth, CortiEnvironment } from "@corti/sdk"; - -const auth = new CortiAuth({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", -}); - -// Generate authorization URL -const authUrl = await auth.authorizeURL({ - clientId: "YOUR_CLIENT_ID", - redirectUri: "https://your-app.com/callback", -}); // Automatically redirects to authorization URL - -// To prevent automatic redirect and get URL only: -const authUrlNoRedirect = await auth.authorizeURL( - { - clientId: "YOUR_CLIENT_ID", - redirectUri: "https://your-app.com/callback", - }, - { skipRedirect: true }, -); -``` - -### Step 2: Handle the Callback and Exchange Code for Tokens - -When the user is redirected back to your application, you'll receive an authorization code in the URL parameters. Exchange it for tokens directly on the client using the SDK: - -```typescript -// Extract the authorization code from URL parameters -const urlParams = new URLSearchParams(window.location.search); -const code = urlParams.get("code"); -const error = urlParams.get("error"); - -if (error) { - console.error("Authorization failed:", error); - return; -} - -if (code) { - // Exchange the authorization code for tokens using SDK (client-side) - const tokenResponse = await auth.getCodeFlowToken({ - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", - redirectUri: "https://your-app.com/callback", - code: code, - }); - - const { accessToken, refreshToken } = tokenResponse; -} -``` - -### Step 3: Use the Tokens - -Once you have the tokens, you can create a `CortiClient` instance: - -```typescript -// Create CortiClient with tokens -const client = new CortiClient({ - auth: { - accessToken: accessToken, - refreshToken: refreshToken, - refreshAccessToken: async (refreshToken: string) => { - // Custom refresh logic -- get new access_token from server - const response = await fetch("https://your-auth-server/refresh", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ refreshToken: refreshToken }), - }); - - // Response must return a valid token object: - // { - // accessToken: string; // Required: The new access token - // expiresIn?: number; // Optional: Seconds until token expires - // refreshToken?: string; // Optional: New refresh token if rotated - // refreshExpiresIn?: number; // Optional: Seconds until refresh token expires - // tokenType?: string; // Optional: Token type (defaults to "Bearer") - // } - return response.json(); - }, - }, -}); - -// Now you can use the client for API calls -try { - const interactions = await client.interactions.list(); - console.log("Interactions:", interactions); -} catch (error) { - console.error("API call failed:", error); -} -``` - -## Authorization Code Flow with PKCE - -**✅ Client-Side or Backend** - This method can be fully handled on the client side, or tokens can be exchanged on the backend. This flow is secure, interactive, and doesn't require a client secret (ideal for public clients). Proof Key for Code Exchange (PKCE) protects against code interception attacks. - -**Note**: CORS is enabled for this flow. Requests must come from the same origin as specified in your redirect URIs configuration. - -The Authorization Code Flow with PKCE is ideal for: - -- Native apps -- Single Page Applications (SPAs) -- Browser-based integration where a user is present - -For detailed information about PKCE flow, see the [official Corti documentation](https://docs.corti.ai/about/oauth#1-authorization-code-flow-with-pkce-recommended-for-corti-assistant). - -### Basic Flow Overview - -1. **Generate code verifier and challenge** - Create a code verifier and compute its challenge -2. **Redirect user to authorization URL** - User is redirected to Corti's login page with code challenge -3. **User authenticates** - User logs in and authorizes your application -4. **Receive authorization code** - User is redirected back with an authorization code -5. **Exchange code for tokens with code verifier** - Exchange the authorization code for access and refresh tokens using the code verifier -6. **Use tokens** - Pass the tokens to a new `CortiClient` instance to make authenticated API calls - -### Step 1: Generate Authorization URL (Frontend) - -**Recommended: Use `authorizePkceUrl()`** - The SDK handles code verifier generation and storage automatically: - -```typescript -import { CortiAuth, CortiEnvironment } from "@corti/sdk"; - -const auth = new CortiAuth({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", -}); - -// SDK automatically generates code verifier and stores it in localStorage -const authUrl = await auth.authorizePkceUrl({ - clientId: "YOUR_CLIENT_ID", - redirectUri: "https://your-app.com/callback", -}); - -// To prevent automatic redirect and get URL only: -const authUrlNoRedirect = await auth.authorizePkceUrl( - { - clientId: "YOUR_CLIENT_ID", - redirectUri: "https://your-app.com/callback", - }, - { skipRedirect: true }, -); -``` - -**Alternative: Manual Generation** - If you need more control over the process: - -```typescript -const auth = new CortiAuth({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", -}); - -const codeVerifier = "your-precomputed-verifier"; // Use high-entropy value -const codeChallenge = "your-precomputed-challenge"; // base64url(SHA-256(codeVerifier)) - -const authUrl = await auth.authorizeURL( - { - clientId: "YOUR_CLIENT_ID", - redirectUri: "https://your-app.com/callback", - codeChallenge, - }, - { skipRedirect: true }, -); -``` - -### Step 2: Handle the Callback and Exchange Code for Tokens - -```typescript -// Extract the authorization code from URL parameters -const urlParams = new URLSearchParams(window.location.search); -const code = urlParams.get("code"); -const error = urlParams.get("error"); - -if (error) { - console.error("Authorization failed:", error); - return; -} - -if (code) { - // Retrieve codeVerifier from SDK if you used authorizePkceUrl (automatically stored) - // Otherwise, you need to pass it manually if you generated it yourself - const codeVerifier = auth.getCodeVerifier(); - - if (!codeVerifier) { - console.error("Code verifier not found"); - return; - } - - // Exchange the authorization code for tokens using SDK (client-side) - const tokenResponse = await auth.getPkceFlowToken({ - clientId: "YOUR_CLIENT_ID", - redirectUri: "https://your-app.com/callback", - code: code, - codeVerifier: codeVerifier, - }); - - const { accessToken, refreshToken } = tokenResponse; -} -``` - -### Step 3: Use the Tokens - -Once you have the tokens, you can create a `CortiClient` instance: - -```typescript -// Create CortiClient with tokens -const client = new CortiClient({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", - auth: { - accessToken: accessToken, - refreshToken: refreshToken, - refreshAccessToken: async (refreshToken: string) => { - // Custom refresh logic -- get new access_token from server - const response = await fetch("https://your-auth-server/refresh", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ refreshToken: refreshToken }), - }); - - // Response must return a valid token object: - // { - // accessToken: string; // Required: The new access token - // expiresIn?: number; // Optional: Seconds until token expires - // refreshToken?: string; // Optional: New refresh token if rotated - // refreshExpiresIn?: number; // Optional: Seconds until refresh token expires - // tokenType?: string; // Optional: Token type (defaults to "Bearer") - // } - return response.json(); - }, - }, -}); - -// Now you can use the client for API calls -try { - const interactions = await client.interactions.list(); - console.log("Interactions:", interactions); -} catch (error) { - console.error("API call failed:", error); -} -``` - -## Resource Owner Password Credentials (ROPC) Flow - -**⚠️ Backend Only** - This method should only be used in server-side applications. The ROPC flow allows users to authenticate directly with their username and password using the SDK. - -**⚠️ Security Note**: ROPC flow requires sending credentials directly. This should only be used for: - -- Trusted applications (e.g., first-party mobile apps, backend services) -- Testing and development -- Internal tools - -**For production web applications, use PKCE flow instead.** - -For detailed information about ROPC flow, see the [official Corti documentation](https://docs.corti.ai/about/oauth#3-resource-owner-password-credentials-ropc-grant-use-with-caution). - -### Basic Usage - -```typescript -import { CortiAuth, CortiClient, CortiEnvironment } from "@corti/sdk"; - -const CLIENT_ID = "YOUR_CLIENT_ID"; -const USERNAME = "user@example.com"; -const PASSWORD = "your-password"; - -// Step 1: Exchange credentials for tokens using ROPC flow -const auth = new CortiAuth({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", -}); - -const tokenResponse = await auth.getRopcFlowToken({ - clientId: CLIENT_ID, - username: USERNAME, - password: PASSWORD, -}); - -const { accessToken, refreshToken } = tokenResponse; - -// Step 2: Create CortiClient with tokens -const client = new CortiClient({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", - auth: { - accessToken: accessToken, - refreshToken: refreshToken, - refreshAccessToken: async (refreshToken: string) => { - // Custom refresh logic -- get new access_token from server - const response = await fetch("https://your-auth-server/refresh", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ refreshToken: refreshToken }), - }); - - // Response must return a valid token object: - // { - // accessToken: string; // Required: The new access token - // expiresIn?: number; // Optional: Seconds until token expires - // refreshToken?: string; // Optional: New refresh token if rotated - // refreshExpiresIn?: number; // Optional: Seconds until refresh token expires - // tokenType?: string; // Optional: Token type (defaults to "Bearer") - // } - return response.json(); - }, - }, -}); - -// Step 3: Make API calls -try { - const interactions = await client.interactions.list(); - console.log("Interactions:", interactions); -} catch (error) { - console.error("API call failed:", error); -} -``` diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..fe5bc2f7 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,133 @@ +# Contributing + +Thanks for your interest in contributing to this SDK! This document provides guidelines for contributing to the project. + +## Getting Started + +### Prerequisites + +- Node.js 20 or higher +- pnpm package manager + +### Installation + +Install the project dependencies: + +```bash +pnpm install +``` + +### Building + +Build the project: + +```bash +pnpm build +``` + +### Testing + +Run the test suite: + +```bash +pnpm test +``` + +Run specific test types: +- `pnpm test:unit` - Run unit tests +- `pnpm test:wire` - Run wire/integration tests + +### Linting and Formatting + +Check code style: + +```bash +pnpm run lint +pnpm run format:check +``` + +Fix code style issues: + +```bash +pnpm run lint:fix +pnpm run format:fix +``` + +Or use the combined check command: + +```bash +pnpm run check:fix +``` + +## About Generated Code + +**Important**: Most files in this SDK are automatically generated by [Fern](https://buildwithfern.com) from the API definition. Direct modifications to generated files will be overwritten the next time the SDK is generated. + +### Generated Files + +The following directories contain generated code: +- `src/api/` - API client classes and types +- `src/serialization/` - Serialization/deserialization logic +- Most TypeScript files in `src/` + +### How to Customize + +If you need to customize the SDK, you have two options: + +#### Option 1: Use `.fernignore` + +For custom code that should persist across SDK regenerations: + +1. Create a `.fernignore` file in the project root +2. Add file patterns for files you want to preserve (similar to `.gitignore` syntax) +3. Add your custom code to those files + +Files listed in `.fernignore` will not be overwritten when the SDK is regenerated. + +For more information, see the [Fern documentation on custom code](https://buildwithfern.com/learn/sdks/overview/custom-code). + +#### Option 2: Contribute to the Generator + +If you want to change how code is generated for all users of this SDK: + +1. The TypeScript SDK generator lives in the [Fern repository](https://github.com/fern-api/fern) +2. Generator code is located at `generators/typescript/sdk/` +3. Follow the [Fern contributing guidelines](https://github.com/fern-api/fern/blob/main/CONTRIBUTING.md) +4. Submit a pull request with your changes to the generator + +This approach is best for: +- Bug fixes in generated code +- New features that would benefit all users +- Improvements to code generation patterns + +## Making Changes + +### Workflow + +1. Create a new branch for your changes +2. Make your modifications +3. Run tests to ensure nothing breaks: `pnpm test` +4. Run linting and formatting: `pnpm run check:fix` +5. Build the project: `pnpm build` +6. Commit your changes with a clear commit message +7. Push your branch and create a pull request + +### Commit Messages + +Write clear, descriptive commit messages that explain what changed and why. + +### Code Style + +This project uses automated code formatting and linting. Run `pnpm run check:fix` before committing to ensure your code meets the project's style guidelines. + +## Questions or Issues? + +If you have questions or run into issues: + +1. Check the [Fern documentation](https://buildwithfern.com) +2. Search existing [GitHub issues](https://github.com/fern-api/fern/issues) +3. Open a new issue if your question hasn't been addressed + +## License + +By contributing to this project, you agree that your contributions will be licensed under the same license as the project. diff --git a/PROXYING.md b/PROXYING.md deleted file mode 100644 index a956a37e..00000000 --- a/PROXYING.md +++ /dev/null @@ -1,343 +0,0 @@ -# Proxying Guide - -This guide explains how to use proxying with the Corti JavaScript SDK to securely handle authentication in frontend applications and protect sensitive credentials. - -## Why Proxying? - -When using **Client Credentials** authentication, the token you receive is a **service account user token** that provides access to all data created within the same API Client. This means: - -- **Data isolation is your responsibility** - You must implement access control logic to ensure users can only access their own data -- **Frontend exposure risk** - If you expose a Client Credentials token in your frontend application, it could be used to access all data associated with that API Client, not just the current user's data - -### Security Best Practice - -**Our general recommendation when Client Credentials is used is to use the SDK (or other calls to Corti API) only on the backend** where you can: - -- Securely store client credentials -- Implement proper access control checks -- Validate user permissions before making API calls -- Call from the frontend only your own backend methods - -However, if you need to use the SDK directly from the frontend while maintaining security, proxying provides a solution. - -For more information about Client Credentials authentication, see the [Authentication Guide - Client Credentials](./AUTHENTICATION.md#client-credentials-authentication). - -## Using Proxying with baseUrl and environments - -If you're implementing a proxy instead of your own backend methods, you can leverage the SDK's types and endpoint structures by using the `baseUrl` and `environments` options for both `CortiClient` and `CortiAuth`. - -### Using baseUrl - -The `baseUrl` option allows you to point the SDK to your own proxy server instead of directly to Corti's API. All requests will be routed through your proxy. - -#### Example: CortiClient with baseUrl - -```typescript -import { CortiClient } from "@corti/sdk"; - -// Point the client to your proxy server -const client = new CortiClient({ - baseUrl: "https://your-proxy-server.com/api/corti_proxy", - // Optional: You can omit the `auth` option if your proxy handles authentication. - // If provided, it will add the header: `Authorization: Bearer {accessToken}` - auth: { - accessToken: "YOUR_TOKEN", - }, - // Optional: You can add custom headers here. These headers will be included in every request sent by the client. - headers: { - 'X-Custom-Header': "CUSTOM_HEADER_VALUE", - } -}); - -// All API calls will go to your proxy -const interactions = await client.interactions.list(); -// Under the hood: GET https://your-proxy-server.com/api/corti_proxy/interactions -``` - -#### Example: CortiAuth with baseUrl - -```typescript -import { CortiAuth } from "@corti/sdk"; - -const auth = new CortiAuth({ - baseUrl: "https://your-proxy-server.com/auth/corti_proxy", -}); - -// Token requests will go to your proxy -const tokenResponse = await auth.getToken({ - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", -}); -// Under the hood: POST https://your-proxy-server.com/auth/corti_proxy/{tenantName}/protocol/openid-connect/token -// Under the hood if tenantName is empty: POST https://your-proxy-server.com/auth/corti_proxy/protocol/openid-connect/token -``` - -### Using Custom Environments - -Instead of using `baseUrl`, you can provide a custom environment object that defines all the endpoints your proxy uses. This gives you fine-grained control over where different types of requests are routed. - -#### Environment Object Structure - -The environment object has the following structure: - -```typescript -interface CortiEnvironmentUrls { - base: string; // Base URL for REST API calls (e.g., "https://your-proxy.com/api/v2/corti_proxy") - wss: string; // WebSocket URL for stream/transcribe connections (e.g., "wss://your-proxy.com/corti_proxy") - login: string; // Authentication endpoint base URL (e.g., "https://your-proxy.com/auth/realms/corti_proxy") - agents: string; // Agents API base URL (e.g., "https://your-proxy.com/api/corti_proxy") -} -``` - -#### Example: CortiClient with Custom Environment - -```typescript -import { CortiClient } from "@corti/sdk"; - -const customEnvironment = { - base: "https://your-proxy-server.com/api/corti_proxy", - wss: "wss://your-proxy-server.com/corti_proxy", - login: "https://your-proxy-server.com/auth/corti_proxy", - agents: "https://your-proxy-server.com/agents/corti_proxy", -}; - -const client = new CortiClient({ - environment: customEnvironment, - // Optional: You can omit the `auth` option if your proxy handles authentication. - // If provided, it will add the header: `Authorization: Bearer {accessToken}` - auth: { - accessToken: "YOUR_TOKEN", - }, - // Optional: You can add custom headers here. These headers will be included in every request sent by the client. - headers: { - 'X-Custom-Header': "CUSTOM_HEADER_VALUE", - } -}); - -// REST API calls use environment.base -const interactions = await client.interactions.list(); -// Under the hood: GET https://your-proxy-server.com/api/corti_proxy/interactions - -// WebSocket connections use environment.wss -const socket = await client.stream.connect({ id: "interaction-id" }); -// Under the hood: Connects to wss://your-proxy-server.com/corti_proxy/interactions/{interaction-id}/stream -``` - -#### Example: CortiAuth with Custom Environment - -```typescript -import { CortiAuth } from "@corti/sdk"; - -const customEnvironment = { - base: "https://your-proxy-server.com/api/corti_proxy", - wss: "wss://your-proxy-server.com/corti_proxy", - login: "https://your-proxy-server.com/auth/corti_proxy", - agents: "https://your-proxy-server.com/agents/corti_proxy", -}; - -const auth = new CortiAuth({ - environment: customEnvironment, -}); - -// Token requests use environment.login -const tokenResponse = await auth.getToken({ - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", -}); -// Under the hood: POST https://your-proxy-server.com/auth/corti_proxy/{tenantName}/protocol/openid-connect/token -// Under the hood when tenantName is empty: POST https://your-proxy-server.com/auth/corti_proxy/protocol/openid-connect/token -``` - -### What Gets Called Under the Hood - -When you use `baseUrl` or a custom environment: - -1. **REST API calls** - All HTTP requests (GET, POST, PUT, DELETE, etc.) are sent to your proxy's base URL -2. **Authentication requests** - Token requests are sent to your proxy's login endpoint -3. **WebSocket connections** - WebSocket connections are established to your proxy's WebSocket URL - -Your proxy server should: - -- Forward requests to the appropriate Corti API endpoints -- Handle authentication and add the necessary tokens -- Implement access control and data filtering -- Return responses in the same format as Corti's API - -## WebSocket Proxying with CortiWebSocketProxyClient - -For WebSocket connections (stream and transcribe), the SDK provides `CortiWebSocketProxyClient` to make proxying even easier. This client handles all the logic around managing sockets, parsing messages, and sending configuration automatically, while allowing you to connect to your own WebSocket proxy endpoint. - -### Basic Usage - -```typescript -import { CortiWebSocketProxyClient } from "@corti/sdk"; - -// Connect to stream through your proxy -const streamSocket = await CortiWebSocketProxyClient.stream.connect({ - proxy: { - url: "wss://your-proxy-server.com/corti_proxy/steam", - // Optional: specify WebSocket subprotocols - protocols: ["stream-protocol"], - // Optional: add query parameters - queryParameters: { - interactionId: "interaction-id", - }, - }, - // Optional: stream configuration - configuration: { - // ... your stream configuration - }, -}); - -// Listen for messages -streamSocket.on("message", (data) => { - console.log("Received:", data); -}); - -// Send messages -streamSocket.send({ type: "message", content: "Hello" }); - -// Connect to transcribe through your proxy -const transcribeSocket = await CortiWebSocketProxyClient.transcribe.connect({ - proxy: { - url: "wss://your-proxy-server.com/corti_proxy/transcribe", - queryParameters: { - interactionId: "interaction-id", - }, - }, - // Optional: transcribe configuration - configuration: { - // ... your transcribe configuration - }, -}); -``` - -### Proxy Options - -The `proxy` parameter accepts the following options: - -- **`url`** (required): The WebSocket URL of your proxy server -- **`protocols`** (optional): WebSocket subprotocols. Pass an **array** to use it as-is on the WebSocket handshake. Pass an **object** (e.g. `{ "Custom-Header": value }`) to have it encoded the same way as headers (name, `encodeURIComponent(value)`, ...); values can be strings or suppliers (e.g. functions). -- **`queryParameters`** (optional): Query parameters to append to the WebSocket URL - -### Encoding custom headers as WebSocket protocols - -You can use **`encodeHeadersAsWsProtocols`** whenever you pass `headers` on **`CortiClient`**; it only makes sense when you use the same client with a proxy for **both** REST API and WebSocket (stream/transcribe). In that case, the client encodes those headers as **WebSocket subprotocols** (each header as two strings: name, then `encodeURIComponent(value)`), since browsers do not allow arbitrary HTTP headers on the WebSocket handshake. Your proxy can read them from `Sec-WebSocket-Protocol` and use or forward them. - -If you only use WebSocket through a proxy (e.g. with `CortiWebSocketProxyClient`) or you don't need the same headers on the WS handshake, pass protocols as usual via **`proxy.protocols`** when calling `stream.connect` or `transcribe.connect`. - -#### Example: CortiClient with encodeHeadersAsWsProtocols - -```typescript -import { CortiClient } from "@corti/sdk"; - -const client = new CortiClient({ - baseUrl: "https://your-proxy-server.com/api/corti_proxy", - encodeHeadersAsWsProtocols: true, - headers: { - "Custom-Header": customValue, - "Custom-Protocol": () => getLatestProtocolValue(), // suppliers (e.g. functions) are resolved when connecting - }, -}); - -// When connecting, Sec-WebSocket-Protocol will include the encoded headers -const socket = await client.stream.connect({ - id: "interaction-id", -}); -// Under the hood: protocols sent as e.g. ["Custom-Header", "", "Custom-Protocol", ""] -``` - -Your proxy should parse the `Sec-WebSocket-Protocol` header to extract these name/value pairs (split by comma, then decode and pair them) and use or forward them as required. - -### Benefits - -Using `CortiWebSocketProxyClient` provides: - -- **Configuration handling** - Configuration messages are automatically sent when connecting -- **Reconnection logic** - Built-in reconnection handling with configurable attempts -- **Type safety** - Full TypeScript support for all message types and configurations -- **Event handling** - Standard WebSocket event interface (message, error, close, open) - -## Scoped Tokens (Alternative to Proxying) - -If exposing an `accessToken` for WebSockets is absolutely necessary and a proxy cannot be implemented, you can use **scoped tokens** to limit the token's access. By passing additional scopes to authentication methods, you can issue a token that only grants access to specific endpoints, preventing the token from being used to access other data. - -### Available Scopes - -Currently available scopes: - -- **`"transcribe"`** - Grants access only to the transcribe WebSocket endpoint -- **`"stream"`** - Grants access only to the stream WebSocket endpoint - -### Using Scopes with Client Credentials - -```typescript -import { CortiAuth, CortiEnvironment } from "@corti/sdk"; - -const auth = new CortiAuth({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", -}); - -// Request a token with only stream scope -const streamToken = await auth.getToken({ - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", - scopes: ["stream"], -}); - -// Request a token with only transcribe scope -const transcribeToken = await auth.getToken({ - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", - scopes: ["transcribe"], -}); - -// Request a token with both scopes -const bothScopesToken = await auth.getToken({ - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", - scopes: ["stream", "transcribe"], -}); -``` - -### Important Notes on Scoped Tokens - -- **Limited access** - Scoped tokens can only be used for the specified endpoints (stream or transcribe WebSocket connections) -- **Cannot access REST API** - Scoped tokens cannot be used to make REST API calls to access data -- **Security consideration** - While scoped tokens limit access, they still provide access to WebSocket endpoints. Proxying remains the recommended approach for maximum security -- **Token validation** - The Corti API will reject requests made with scoped tokens to endpoints outside their scope - -### Using Scoped Tokens with WebSocket Clients - -```typescript -import { CortiClient, CortiEnvironment } from "@corti/sdk"; - -// Create client with scoped token (stream scope only) -const client = new CortiClient({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", - auth: { - accessToken: streamToken.accessToken, // Token with "stream" scope - }, -}); - -// This will work - stream is within the token's scope -const streamSocket = await client.stream.connect({ id: "interaction-id" }); - -// This will fail - transcribe is not within the token's scope -// await client.transcribe.connect({ id: "interaction-id" }); // ❌ Error - -// This will fail - REST API calls are not within the token's scope -// await client.interactions.list(); // ❌ Error -``` - -## Summary - -- **Proxying is recommended** when using Client Credentials in frontend applications to protect sensitive tokens and implement proper access control -- **Use `baseUrl` or custom environments** to route SDK requests through your proxy server while maintaining type safety -- **Use `CortiWebSocketProxyClient`** for simplified WebSocket proxying with automatic message handling -- **Use `encodeHeadersAsWsProtocols`** on `CortiClient` only when using the same client with a proxy for both API and WebSocket and you need the same headers on the WS handshake; otherwise pass **`proxy.protocols`** as usual -- **Scoped tokens** provide an alternative when proxying isn't possible, but limit access to specific WebSocket endpoints only - -For more information about authentication methods, see the [Authentication Guide](./AUTHENTICATION.md). diff --git a/README.md b/README.md index 8f0dc3f2..4210d7df 100644 --- a/README.md +++ b/README.md @@ -1,13 +1,31 @@ -# Corti JavaScript SDK +# Corti TypeScript Library [![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Fcorticph%2Fcorti-sdk-javascript) [![npm shield](https://img.shields.io/npm/v/@corti/sdk)](https://www.npmjs.com/package/@corti/sdk) -> This is a **Beta version** of the Corti JavaScript SDK. We are treating it as stable for production use, but -> there may still be breaking changes before we reach version 1.0. We're actively working to improve the SDK and would greatly -> appreciate any feedback if you encounter any inconsistencies or issues 💚 - -The Corti JavaScript SDK provides convenient access to the Corti API from JavaScript. +The Corti TypeScript library provides convenient access to the Corti APIs from TypeScript. + +## Table of Contents + +- [Installation](#installation) +- [Reference](#reference) +- [Usage](#usage) +- [Authentication](#authentication) +- [Request and Response Types](#request-and-response-types) +- [Exception Handling](#exception-handling) +- [File Uploads](#file-uploads) +- [Binary Response](#binary-response) +- [Pagination](#pagination) +- [Advanced](#advanced) + - [Additional Headers](#additional-headers) + - [Additional Query String Parameters](#additional-query-string-parameters) + - [Retries](#retries) + - [Timeouts](#timeouts) + - [Aborting Requests](#aborting-requests) + - [Access Raw Response Data](#access-raw-response-data) + - [Logging](#logging) + - [Runtime Compatibility](#runtime-compatibility) +- [Contributing](#contributing) ## Installation @@ -17,67 +35,57 @@ npm i -s @corti/sdk ## Reference -For detailed authentication instructions, see the [Authentication Guide](./AUTHENTICATION.md). - -For information about proxying and securing frontend implementations, see the [Proxying Guide](./PROXYING.md). +A full reference for this library is available [here](https://github.com/corticph/corti-sdk-javascript/blob/HEAD/./reference.md). ## Usage Instantiate and use the client with the following: ```typescript -import { CortiEnvironment, CortiClient } from "@corti/sdk"; +import { CortiClient, CortiEnvironment } from "@corti/sdk"; -// Using client credentials (OAuth2) -const client = new CortiClient({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", - auth: { - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", - }, +const client = new CortiClient({ environment: CortiEnvironment.Eu, clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", tenantName: "YOUR_TENANT_NAME" }); +await client.interactions.create({ + encounter: { + identifier: "identifier", + status: "planned", + type: "first_consultation" + } }); +``` -// Or using a bearer token -const client = new CortiClient({ - auth: { - accessToken: "YOUR_ACCESS_TOKEN", - }, -}); +## Authentication + +The SDK supports OAuth authentication with two options: + +**Option 1: OAuth Client Credentials Flow** + +Use this when you want the SDK to automatically handle OAuth token retrieval and refreshing: + +```typescript +import { CortiClient } from "@corti/sdk"; -// Or using just a refresh function (no initial access token needed) const client = new CortiClient({ - auth: { - // refreshToken will be undefined for the first call, then it will be the refreshToken returned from the previous token request - refreshAccessToken: async (refreshToken?: string) => { - // Your custom logic to get a new access token - const response = await fetch("https://your-auth-server/token", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ refreshToken }), - }); - - return response.json(); - }, - }, + clientId: "YOUR_CLIENT_ID", + clientSecret: "YOUR_CLIENT_SECRET", + ... }); +``` -// For user authentication, you can use: -// - Authorization Code Flow -// - Authorization Code Flow with PKCE -// - Resource Owner Password Credentials (ROPC) flow -// See the Authentication Guide for detailed instructions +**Option 2: Token Override** -await client.interactions.create({ - encounter: { - identifier: "identifier", - status: "planned", - type: "first_consultation", - }, +Use this when you already have a valid bearer token and want to skip the OAuth flow: + +```typescript +import { CortiClient } from "@corti/sdk"; + +const client = new CortiClient({ + token: "my-pre-generated-bearer-token", + ... }); ``` -## Request And Response Types +## Request and Response Types The SDK exports all request and response types as TypeScript interfaces. Simply import them with the following namespace: @@ -92,72 +100,479 @@ const request: Corti.InteractionsListRequest = { ## Exception Handling -Depending on the type of error, the SDK will throw one of the following: - -- **CortiError**: Thrown when the API returns a non-success status code (4xx or 5xx response). This is the base error for API-related issues. -- **ParseError**: Thrown when parsing input data fails schema validation. This typically occurs when the data you provide does not match the expected schema. -- **JsonError**: Thrown when serializing data to JSON fails schema validation. This typically occurs when converting parsed data to JSON for transmission or storage fails validation. -- **CortiSDKError**: Base class for SDK-specific runtime issues (e.g., internal helpers, environment detection). Provides an optional `code` and `cause` for debugging. - -Example usage: +When the API returns a non-success status code (4xx or 5xx response), a subclass of the following error +will be thrown. ```typescript -import { CortiError, ParseError, JsonError, CortiSDKError } from "@corti/sdk"; +import { CortiError } from "@corti/sdk"; try { await client.interactions.create(...); } catch (err) { if (err instanceof CortiError) { - // Handle API errors console.log(err.statusCode); console.log(err.message); console.log(err.body); console.log(err.rawResponse); } - if (err instanceof ParseError) { - // Handle schema validation errors during parsing - console.error("Parse validation error details:", err.errors); - } - if (err instanceof JsonError) { - // Handle schema validation errors during serialization - console.error("JSON validation error details:", err.errors); - } - if (err instanceof CortiSDKError) { - // Handle other SDK-level errors that expose extra context - console.error("SDK error code:", err.code); - console.error("SDK error cause:", err.cause); - if (err.code === "local_storage_error") { - console.error("LocalStorage operation failed:", err.message); - } - } } ``` +## File Uploads + +You can upload files using the client: + +```typescript +import { createReadStream } from "fs"; + +await client.recordings.upload(createReadStream("path/to/file"), ...); +await client.recordings.upload(new ReadableStream(), ...); +await client.recordings.upload(Buffer.from('binary data'), ...); +await client.recordings.upload(new Blob(['binary data'], { type: 'audio/mpeg' }), ...); +await client.recordings.upload(new File(['binary data'], 'file.mp3'), ...); +await client.recordings.upload(new ArrayBuffer(8), ...); +await client.recordings.upload(new Uint8Array([0, 1, 2]), ...); +``` +The client accepts a variety of types for file upload parameters: +* Stream types: `fs.ReadStream`, `stream.Readable`, and `ReadableStream` +* Buffered types: `Buffer`, `Blob`, `File`, `ArrayBuffer`, `ArrayBufferView`, and `Uint8Array` + +### Metadata + +You can configure metadata when uploading a file: +```typescript +const file: Uploadable.WithMetadata = { + data: createReadStream("path/to/file"), + filename: "my-file", // optional + contentType: "audio/mpeg", // optional + contentLength: 1949, // optional +}; +``` + +Alternatively, you can upload a file directly from a file path: +```typescript +const file : Uploadable.FromPath = { + path: "path/to/file", + filename: "my-file", // optional + contentType: "audio/mpeg", // optional + contentLength: 1949, // optional +}; +``` + +The metadata is used to set the `Content-Length`, `Content-Type`, and `Content-Disposition` headers. If not provided, the client will attempt to determine them automatically. +For example, `fs.ReadStream` has a `path` property which the SDK uses to retrieve the file size from the filesystem without loading it into memory. + + +## Binary Response + +You can consume binary data from endpoints using the `BinaryResponse` type which lets you choose how to consume the data: + +```typescript +const response = await client.recordings.get(...); +const stream: ReadableStream = response.stream(); +// const arrayBuffer: ArrayBuffer = await response.arrayBuffer(); +// const blob: Blob = response.blob(); +// const bytes: Uint8Array = response.bytes(); +// You can only use the response body once, so you must choose one of the above methods. +// If you want to check if the response body has been used, you can use the following property. +const bodyUsed = response.bodyUsed; +``` +
+Save binary response to a file + +
+
+Node.js + +
+
+ReadableStream (most-efficient) + +```ts +import { createWriteStream } from 'fs'; +import { Readable } from 'stream'; +import { pipeline } from 'stream/promises'; + +const response = await client.recordings.get(...); + +const stream = response.stream(); +const nodeStream = Readable.fromWeb(stream); +const writeStream = createWriteStream('path/to/file'); + +await pipeline(nodeStream, writeStream); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +import { writeFile } from 'fs/promises'; + +const response = await client.recordings.get(...); + +const arrayBuffer = await response.arrayBuffer(); +await writeFile('path/to/file', Buffer.from(arrayBuffer)); +``` + +
+
+ +
+
+Blob + +```ts +import { writeFile } from 'fs/promises'; + +const response = await client.recordings.get(...); + +const blob = await response.blob(); +const arrayBuffer = await blob.arrayBuffer(); +await writeFile('output.bin', Buffer.from(arrayBuffer)); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +import { writeFile } from 'fs/promises'; + +const response = await client.recordings.get(...); + +const bytes = await response.bytes(); +await writeFile('path/to/file', bytes); +``` + +
+
+ +
+
+ +
+
+Bun + +
+
+ReadableStream (most-efficient) + +```ts +const response = await client.recordings.get(...); + +const stream = response.stream(); +await Bun.write('path/to/file', stream); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.recordings.get(...); + +const arrayBuffer = await response.arrayBuffer(); +await Bun.write('path/to/file', arrayBuffer); +``` + +
+
+ +
+
+Blob + +```ts +const response = await client.recordings.get(...); + +const blob = await response.blob(); +await Bun.write('path/to/file', blob); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.recordings.get(...); + +const bytes = await response.bytes(); +await Bun.write('path/to/file', bytes); +``` + +
+
+ +
+
+ +
+
+Deno + +
+
+ReadableStream (most-efficient) + +```ts +const response = await client.recordings.get(...); + +const stream = response.stream(); +const file = await Deno.open('path/to/file', { write: true, create: true }); +await stream.pipeTo(file.writable); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.recordings.get(...); + +const arrayBuffer = await response.arrayBuffer(); +await Deno.writeFile('path/to/file', new Uint8Array(arrayBuffer)); +``` + +
+
+ +
+
+Blob + +```ts +const response = await client.recordings.get(...); + +const blob = await response.blob(); +const arrayBuffer = await blob.arrayBuffer(); +await Deno.writeFile('path/to/file', new Uint8Array(arrayBuffer)); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.recordings.get(...); + +const bytes = await response.bytes(); +await Deno.writeFile('path/to/file', bytes); +``` + +
+
+ +
+
+ +
+
+Browser + +
+
+Blob (most-efficient) + +```ts +const response = await client.recordings.get(...); + +const blob = await response.blob(); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+ReadableStream + +```ts +const response = await client.recordings.get(...); + +const stream = response.stream(); +const reader = stream.getReader(); +const chunks = []; + +while (true) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); +} + +const blob = new Blob(chunks); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.recordings.get(...); + +const arrayBuffer = await response.arrayBuffer(); +const blob = new Blob([arrayBuffer]); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.recordings.get(...); + +const bytes = await response.bytes(); +const blob = new Blob([bytes]); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+ +
+ + +
+Convert binary response to text + +
+
+ReadableStream + +```ts +const response = await client.recordings.get(...); + +const stream = response.stream(); +const text = await new Response(stream).text(); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.recordings.get(...); + +const arrayBuffer = await response.arrayBuffer(); +const text = new TextDecoder().decode(arrayBuffer); +``` + +
+
+ +
+
+Blob + +```ts +const response = await client.recordings.get(...); + +const blob = await response.blob(); +const text = await blob.text(); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.recordings.get(...); + +const bytes = await response.bytes(); +const text = new TextDecoder().decode(bytes); +``` + +
+
+ +
+ ## Pagination List endpoints are paginated. The SDK provides an iterator so that you can simply loop over the items: ```typescript -import { CortiEnvironment, CortiClient } from "@corti/sdk"; +import { CortiClient, CortiEnvironment } from "@corti/sdk"; -const client = new CortiClient({ - environment: CortiEnvironment.Eu, - tenantName: "YOUR_TENANT_NAME", - auth: { - clientId: "YOUR_CLIENT_ID", - clientSecret: "YOUR_CLIENT_SECRET", - }, -}); -const response = await client.interactions.list(); -for await (const item of response) { +const client = new CortiClient({ environment: CortiEnvironment.Eu, clientId: "YOUR_CLIENT_ID", clientSecret: "YOUR_CLIENT_SECRET", tenantName: "YOUR_TENANT_NAME" }); +const pageableResponse = await client.interactions.list(); +for await (const item of pageableResponse) { console.log(item); } // Or you can manually iterate page-by-page -const page = await client.interactions.list(); +let page = await client.interactions.list(); while (page.hasNextPage()) { page = page.getNextPage(); } + +// You can also access the underlying response +const response = page.response; ``` ## Advanced @@ -167,6 +582,15 @@ while (page.hasNextPage()) { If you would like to send additional headers as part of the request, use the `headers` request option. ```typescript +import { CortiClient } from "@corti/sdk"; + +const client = new CortiClient({ + ... + headers: { + 'X-Custom-Header': 'custom value' + } +}); + const response = await client.interactions.create(..., { headers: { 'X-Custom-Header': 'custom value' @@ -174,6 +598,18 @@ const response = await client.interactions.create(..., { }); ``` +### Additional Query String Parameters + +If you would like to send additional query string parameters as part of the request, use the `queryParams` request option. + +```typescript +const response = await client.interactions.create(..., { + queryParams: { + 'customQueryParamKey': 'custom query param value' + } +}); +``` + ### Retries The SDK is instrumented with automatic retries with exponential backoff. A request will be retried as long @@ -228,13 +664,77 @@ console.log(data); console.log(rawResponse.headers['X-My-Header']); ``` +### Logging + +The SDK supports logging. You can configure the logger by passing in a `logging` object to the client options. + +```typescript +import { CortiClient, logging } from "@corti/sdk"; + +const client = new CortiClient({ + ... + logging: { + level: logging.LogLevel.Debug, // defaults to logging.LogLevel.Info + logger: new logging.ConsoleLogger(), // defaults to ConsoleLogger + silent: false, // defaults to true, set to false to enable logging + } +}); +``` +The `logging` object can have the following properties: +- `level`: The log level to use. Defaults to `logging.LogLevel.Info`. +- `logger`: The logger to use. Defaults to a `logging.ConsoleLogger`. +- `silent`: Whether to silence the logger. Defaults to `true`. + +The `level` property can be one of the following values: +- `logging.LogLevel.Debug` +- `logging.LogLevel.Info` +- `logging.LogLevel.Warn` +- `logging.LogLevel.Error` + +To provide a custom logger, you can pass in an object that implements the `logging.ILogger` interface. + +
+Custom logger examples + +Here's an example using the popular `winston` logging library. +```ts +import winston from 'winston'; + +const winstonLogger = winston.createLogger({...}); + +const logger: logging.ILogger = { + debug: (msg, ...args) => winstonLogger.debug(msg, ...args), + info: (msg, ...args) => winstonLogger.info(msg, ...args), + warn: (msg, ...args) => winstonLogger.warn(msg, ...args), + error: (msg, ...args) => winstonLogger.error(msg, ...args), +}; +``` + +Here's an example using the popular `pino` logging library. + +```ts +import pino from 'pino'; + +const pinoLogger = pino({...}); + +const logger: logging.ILogger = { + debug: (msg, ...args) => pinoLogger.debug(args, msg), + info: (msg, ...args) => pinoLogger.info(args, msg), + warn: (msg, ...args) => pinoLogger.warn(args, msg), + error: (msg, ...args) => pinoLogger.error(args, msg), +}; +``` +
+ + ### Runtime Compatibility -The SDK defaults to `node-fetch` but will use the global fetch client if present. The SDK works in the following -runtimes: + +The SDK works in the following runtimes: + + - Node.js 18+ -- Modern browsers - Vercel - Cloudflare Workers - Deno v1.25+ @@ -257,10 +757,10 @@ const client = new CortiClient({ ## Contributing -While we value open-source contributions to this SDK, this repo is (mostly) generated programmatically. -Additions made directly to this code would have to be moved over to our generation code, +While we value open-source contributions to this SDK, this library is generated programmatically. +Additions made directly to this library would have to be moved over to our generation code, otherwise they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept, but know that we will not be able to merge it as-is. We suggest opening an issue first to discuss with us! -On the other hand, contributions to the README are always very welcome! +On the other hand, contributions to the README are always very welcome! \ No newline at end of file diff --git a/biome.json b/biome.json new file mode 100644 index 00000000..371d3650 --- /dev/null +++ b/biome.json @@ -0,0 +1,74 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.3.11/schema.json", + "root": true, + "vcs": { + "enabled": false + }, + "files": { + "ignoreUnknown": true, + "includes": [ + "**", + "!!dist", + "!!**/dist", + "!!lib", + "!!**/lib", + "!!_tmp_*", + "!!**/_tmp_*", + "!!*.tmp", + "!!**/*.tmp", + "!!.tmp/", + "!!**/.tmp/", + "!!*.log", + "!!**/*.log", + "!!**/.DS_Store", + "!!**/Thumbs.db" + ] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4, + "lineWidth": 120 + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } + } + }, + "linter": { + "rules": { + "style": { + "useNodejsImportProtocol": "off" + }, + "suspicious": { + "noAssignInExpressions": "warn", + "noUselessEscapeInString": { + "level": "warn", + "fix": "none", + "options": {} + }, + "noThenProperty": "warn", + "useIterableCallbackReturn": "warn", + "noShadowRestrictedNames": "warn", + "noTsIgnore": { + "level": "warn", + "fix": "none", + "options": {} + }, + "noConfusingVoidType": { + "level": "warn", + "fix": "none", + "options": {} + } + } + } + } +} diff --git a/jest.config.mjs b/jest.config.mjs deleted file mode 100644 index b6927007..00000000 --- a/jest.config.mjs +++ /dev/null @@ -1,42 +0,0 @@ -/** @type {import('jest').Config} */ -export default { - preset: "ts-jest", - testEnvironment: "node", - projects: [ - { - displayName: "unit", - preset: "ts-jest", - testEnvironment: "node", - moduleNameMapper: { - "^(\.{1,2}/.*)\.js$": "$1", - }, - roots: ["/tests"], - testPathIgnorePatterns: ["\.browser\.(spec|test)\.[jt]sx?$", "/tests/wire/"], - setupFilesAfterEnv: [], - }, - { - displayName: "browser", - preset: "ts-jest", - testEnvironment: "/tests/BrowserTestEnvironment.ts", - moduleNameMapper: { - "^(\.{1,2}/.*)\.js$": "$1", - }, - roots: ["/tests"], - testMatch: ["/tests/unit/**/?(*.)+(browser).(spec|test).[jt]s?(x)"], - setupFilesAfterEnv: [], - }, - , - { - displayName: "wire", - preset: "ts-jest", - testEnvironment: "node", - moduleNameMapper: { - "^(\.{1,2}/.*)\.js$": "$1", - }, - roots: ["/tests/wire"], - setupFilesAfterEnv: ["/tests/mock-server/setup.ts"], - }, - ], - workerThreads: false, - passWithNoTests: true, -}; diff --git a/jest.integration.config.mjs b/jest.integration.config.mjs deleted file mode 100644 index 1b5c68b7..00000000 --- a/jest.integration.config.mjs +++ /dev/null @@ -1,16 +0,0 @@ -/** @type {import('jest').Config} */ -export default { - preset: "ts-jest", - testEnvironment: "node", - displayName: "integration", - moduleNameMapper: { - "^(\\.{1,2}/.*)\\.js$": "$1", - }, - roots: ["/tests/custom", "/src"], - testMatch: ["**/*.integration.ts"], - setupFilesAfterEnv: [], - testTimeout: 120000, // 2 minute TTL - maxWorkers: 1, // Run tests one by one (no concurrent execution) - workerThreads: false, - passWithNoTests: true, -}; diff --git a/package.json b/package.json index 60fa5c9a..ebb7340d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,10 @@ "name": "@corti/sdk", "version": "0.10.1", "private": false, - "repository": "github:corticph/corti-sdk-javascript", + "repository": { + "type": "git", + "url": "git+https://github.com/corticph/corti-sdk-javascript.git" + }, "license": "MIT", "type": "commonjs", "main": "./dist/cjs/index.js", @@ -42,14 +45,18 @@ "LICENSE" ], "scripts": { - "format": "prettier . --write --ignore-unknown", - "build": "yarn build:cjs && yarn build:esm", + "format": "biome format --write --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "format:check": "biome format --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "lint": "biome lint --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "lint:fix": "biome lint --fix --unsafe --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "check": "biome check --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "check:fix": "biome check --fix --unsafe --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "build": "pnpm build:cjs && pnpm build:esm", "build:cjs": "tsc --project ./tsconfig.cjs.json", "build:esm": "tsc --project ./tsconfig.esm.json && node scripts/rename-to-esm-files.js dist/esm", - "test": "jest --config jest.config.mjs", - "test:unit": "jest --selectProjects unit", - "test:browser": "jest --selectProjects browser", - "test:wire": "jest --selectProjects wire" + "test": "vitest", + "test:unit": "vitest --project unit", + "test:wire": "vitest --project wire" }, "dependencies": { "ws": "^8.16.0" @@ -58,15 +65,11 @@ "webpack": "^5.97.1", "ts-loader": "^9.5.1", "@types/ws": "^8.5.10", - "jest": "^29.7.0", - "@jest/globals": "^29.7.0", - "@types/jest": "^29.5.14", - "ts-jest": "^29.3.4", - "jest-environment-jsdom": "^29.7.0", - "msw": "^2.8.4", + "vitest": "^3.2.4", + "msw": "2.11.2", "@types/node": "^18.19.70", - "prettier": "^3.4.2", "typescript": "~5.7.2", + "@biomejs/biome": "2.3.11", "@faker-js/faker": "^9.9.0" }, "browser": { @@ -75,7 +78,7 @@ "path": false, "stream": false }, - "packageManager": "yarn@1.22.22", + "packageManager": "pnpm@10.20.0", "engines": { "node": ">=18.0.0" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 00000000..c684053d --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,2201 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + ws: + specifier: ^8.16.0 + version: 8.19.0 + devDependencies: + '@biomejs/biome': + specifier: 2.3.11 + version: 2.3.11 + '@faker-js/faker': + specifier: ^9.9.0 + version: 9.9.0 + '@types/node': + specifier: ^18.19.70 + version: 18.19.130 + '@types/ws': + specifier: ^8.5.10 + version: 8.18.1 + msw: + specifier: 2.11.2 + version: 2.11.2(@types/node@18.19.130)(typescript@5.7.3) + ts-loader: + specifier: ^9.5.1 + version: 9.5.4(typescript@5.7.3)(webpack@5.105.1) + typescript: + specifier: ~5.7.2 + version: 5.7.3 + vitest: + specifier: ^3.2.4 + version: 3.2.4(@types/node@18.19.130)(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(terser@5.46.0) + webpack: + specifier: ^5.97.1 + version: 5.105.1 + +packages: + + '@biomejs/biome@2.3.11': + resolution: {integrity: sha512-/zt+6qazBWguPG6+eWmiELqO+9jRsMZ/DBU3lfuU2ngtIQYzymocHhKiZRyrbra4aCOoyTg/BmY+6WH5mv9xmQ==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@2.3.11': + resolution: {integrity: sha512-/uXXkBcPKVQY7rc9Ys2CrlirBJYbpESEDme7RKiBD6MmqR2w3j0+ZZXRIL2xiaNPsIMMNhP1YnA+jRRxoOAFrA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@2.3.11': + resolution: {integrity: sha512-fh7nnvbweDPm2xEmFjfmq7zSUiox88plgdHF9OIW4i99WnXrAC3o2P3ag9judoUMv8FCSUnlwJCM1B64nO5Fbg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@2.3.11': + resolution: {integrity: sha512-XPSQ+XIPZMLaZ6zveQdwNjbX+QdROEd1zPgMwD47zvHV+tCGB88VH+aynyGxAHdzL+Tm/+DtKST5SECs4iwCLg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-arm64@2.3.11': + resolution: {integrity: sha512-l4xkGa9E7Uc0/05qU2lMYfN1H+fzzkHgaJoy98wO+b/7Gl78srbCRRgwYSW+BTLixTBrM6Ede5NSBwt7rd/i6g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + + '@biomejs/cli-linux-x64-musl@2.3.11': + resolution: {integrity: sha512-vU7a8wLs5C9yJ4CB8a44r12aXYb8yYgBn+WeyzbMjaCMklzCv1oXr8x+VEyWodgJt9bDmhiaW/I0RHbn7rsNmw==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-linux-x64@2.3.11': + resolution: {integrity: sha512-/1s9V/H3cSe0r0Mv/Z8JryF5x9ywRxywomqZVLHAoa/uN0eY7F8gEngWKNS5vbbN/BsfpCG5yeBT5ENh50Frxg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + + '@biomejs/cli-win32-arm64@2.3.11': + resolution: {integrity: sha512-PZQ6ElCOnkYapSsysiTy0+fYX+agXPlWugh6+eQ6uPKI3vKAqNp6TnMhoM3oY2NltSB89hz59o8xIfOdyhi9Iw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@2.3.11': + resolution: {integrity: sha512-43VrG813EW+b5+YbDbz31uUsheX+qFKCpXeY9kfdAx+ww3naKxeVkTD9zLIWxUPfJquANMHrmW3wbe/037G0Qg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@bundled-es-modules/cookie@2.0.1': + resolution: {integrity: sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw==} + + '@bundled-es-modules/statuses@1.0.1': + resolution: {integrity: sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg==} + + '@esbuild/aix-ppc64@0.27.3': + resolution: {integrity: sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.27.3': + resolution: {integrity: sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.27.3': + resolution: {integrity: sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.27.3': + resolution: {integrity: sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.27.3': + resolution: {integrity: sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.27.3': + resolution: {integrity: sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.27.3': + resolution: {integrity: sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.27.3': + resolution: {integrity: sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.27.3': + resolution: {integrity: sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.27.3': + resolution: {integrity: sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.27.3': + resolution: {integrity: sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.27.3': + resolution: {integrity: sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.27.3': + resolution: {integrity: sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.27.3': + resolution: {integrity: sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.27.3': + resolution: {integrity: sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.27.3': + resolution: {integrity: sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.27.3': + resolution: {integrity: sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.27.3': + resolution: {integrity: sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.27.3': + resolution: {integrity: sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.27.3': + resolution: {integrity: sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.27.3': + resolution: {integrity: sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.3': + resolution: {integrity: sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.27.3': + resolution: {integrity: sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.27.3': + resolution: {integrity: sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.27.3': + resolution: {integrity: sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.27.3': + resolution: {integrity: sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@faker-js/faker@9.9.0': + resolution: {integrity: sha512-OEl393iCOoo/z8bMezRlJu+GlRGlsKbUAN7jKB6LhnKoqKve5DXRpalbItIIcwnCjs1k/FOPjFzcA6Qn+H+YbA==} + engines: {node: '>=18.0.0', npm: '>=9.0.0'} + + '@inquirer/ansi@1.0.2': + resolution: {integrity: sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==} + engines: {node: '>=18'} + + '@inquirer/confirm@5.1.21': + resolution: {integrity: sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/core@10.3.2': + resolution: {integrity: sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@inquirer/figures@1.0.15': + resolution: {integrity: sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==} + engines: {node: '>=18'} + + '@inquirer/type@3.0.10': + resolution: {integrity: sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@mswjs/interceptors@0.39.8': + resolution: {integrity: sha512-2+BzZbjRO7Ct61k8fMNHEtoKjeWI9pIlHFTqBwZ5icHpqszIgEZbjb1MW5Z0+bITTCTl3gk4PDBxs9tA/csXvA==} + engines: {node: '>=18'} + + '@open-draft/deferred-promise@2.2.0': + resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} + + '@open-draft/logger@0.3.0': + resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} + + '@open-draft/until@2.1.0': + resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} + + '@rollup/rollup-android-arm-eabi@4.57.1': + resolution: {integrity: sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.57.1': + resolution: {integrity: sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.57.1': + resolution: {integrity: sha512-crNPrwJOrRxagUYeMn/DZwqN88SDmwaJ8Cvi/TN1HnWBU7GwknckyosC2gd0IqYRsHDEnXf328o9/HC6OkPgOg==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.57.1': + resolution: {integrity: sha512-Ji8g8ChVbKrhFtig5QBV7iMaJrGtpHelkB3lsaKzadFBe58gmjfGXAOfI5FV0lYMH8wiqsxKQ1C9B0YTRXVy4w==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.57.1': + resolution: {integrity: sha512-R+/WwhsjmwodAcz65guCGFRkMb4gKWTcIeLy60JJQbXrJ97BOXHxnkPFrP+YwFlaS0m+uWJTstrUA9o+UchFug==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.57.1': + resolution: {integrity: sha512-IEQTCHeiTOnAUC3IDQdzRAGj3jOAYNr9kBguI7MQAAZK3caezRrg0GxAb6Hchg4lxdZEI5Oq3iov/w/hnFWY9Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': + resolution: {integrity: sha512-F8sWbhZ7tyuEfsmOxwc2giKDQzN3+kuBLPwwZGyVkLlKGdV1nvnNwYD0fKQ8+XS6hp9nY7B+ZeK01EBUE7aHaw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.57.1': + resolution: {integrity: sha512-rGfNUfn0GIeXtBP1wL5MnzSj98+PZe/AXaGBCRmT0ts80lU5CATYGxXukeTX39XBKsxzFpEeK+Mrp9faXOlmrw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.57.1': + resolution: {integrity: sha512-MMtej3YHWeg/0klK2Qodf3yrNzz6CGjo2UntLvk2RSPlhzgLvYEB3frRvbEF2wRKh1Z2fDIg9KRPe1fawv7C+g==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.57.1': + resolution: {integrity: sha512-1a/qhaaOXhqXGpMFMET9VqwZakkljWHLmZOX48R0I/YLbhdxr1m4gtG1Hq7++VhVUmf+L3sTAf9op4JlhQ5u1Q==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.57.1': + resolution: {integrity: sha512-QWO6RQTZ/cqYtJMtxhkRkidoNGXc7ERPbZN7dVW5SdURuLeVU7lwKMpo18XdcmpWYd0qsP1bwKPf7DNSUinhvA==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.57.1': + resolution: {integrity: sha512-xpObYIf+8gprgWaPP32xiN5RVTi/s5FCR+XMXSKmhfoJjrpRAjCuuqQXyxUa/eJTdAE6eJ+KDKaoEqjZQxh3Gw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-ppc64-gnu@4.57.1': + resolution: {integrity: sha512-4BrCgrpZo4hvzMDKRqEaW1zeecScDCR+2nZ86ATLhAoJ5FQ+lbHVD3ttKe74/c7tNT9c6F2viwB3ufwp01Oh2w==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.57.1': + resolution: {integrity: sha512-NOlUuzesGauESAyEYFSe3QTUguL+lvrN1HtwEEsU2rOwdUDeTMJdO5dUYl/2hKf9jWydJrO9OL/XSSf65R5+Xw==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.57.1': + resolution: {integrity: sha512-ptA88htVp0AwUUqhVghwDIKlvJMD/fmL/wrQj99PRHFRAG6Z5nbWoWG4o81Nt9FT+IuqUQi+L31ZKAFeJ5Is+A==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.57.1': + resolution: {integrity: sha512-S51t7aMMTNdmAMPpBg7OOsTdn4tySRQvklmL3RpDRyknk87+Sp3xaumlatU+ppQ+5raY7sSTcC2beGgvhENfuw==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.57.1': + resolution: {integrity: sha512-Bl00OFnVFkL82FHbEqy3k5CUCKH6OEJL54KCyx2oqsmZnFTR8IoNqBF+mjQVcRCT5sB6yOvK8A37LNm/kPJiZg==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.57.1': + resolution: {integrity: sha512-ABca4ceT4N+Tv/GtotnWAeXZUZuM/9AQyCyKYyKnpk4yoA7QIAuBt6Hkgpw8kActYlew2mvckXkvx0FfoInnLg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.57.1': + resolution: {integrity: sha512-HFps0JeGtuOR2convgRRkHCekD7j+gdAuXM+/i6kGzQtFhlCtQkpwtNzkNj6QhCDp7DRJ7+qC/1Vg2jt5iSOFw==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.57.1': + resolution: {integrity: sha512-H+hXEv9gdVQuDTgnqD+SQffoWoc0Of59AStSzTEj/feWTBAnSfSD3+Dql1ZruJQxmykT/JVY0dE8Ka7z0DH1hw==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.57.1': + resolution: {integrity: sha512-4wYoDpNg6o/oPximyc/NG+mYUejZrCU2q+2w6YZqrAs2UcNUChIZXjtafAiiZSUc7On8v5NyNj34Kzj/Ltk6dQ==} + cpu: [arm64] + os: [openharmony] + + '@rollup/rollup-win32-arm64-msvc@4.57.1': + resolution: {integrity: sha512-O54mtsV/6LW3P8qdTcamQmuC990HDfR71lo44oZMZlXU4tzLrbvTii87Ni9opq60ds0YzuAlEr/GNwuNluZyMQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.57.1': + resolution: {integrity: sha512-P3dLS+IerxCT/7D2q2FYcRdWRl22dNbrbBEtxdWhXrfIMPP9lQhb5h4Du04mdl5Woq05jVCDPCMF7Ub0NAjIew==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.57.1': + resolution: {integrity: sha512-VMBH2eOOaKGtIJYleXsi2B8CPVADrh+TyNxJ4mWPnKfLB/DBUmzW+5m1xUrcwWoMfSLagIRpjUFeW5CO5hyciQ==} + cpu: [x64] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.57.1': + resolution: {integrity: sha512-mxRFDdHIWRxg3UfIIAwCm6NzvxG0jDX/wBN6KsQFTvKFqqg9vTrWUE68qEjHt19A5wwx5X5aUi2zuZT7YR0jrA==} + cpu: [x64] + os: [win32] + + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + + '@types/cookie@0.6.0': + resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==} + + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree@1.0.8': + resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@18.19.130': + resolution: {integrity: sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==} + + '@types/statuses@2.0.6': + resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@vitest/expect@3.2.4': + resolution: {integrity: sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==} + + '@vitest/mocker@3.2.4': + resolution: {integrity: sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==} + peerDependencies: + msw: ^2.4.9 + vite: ^5.0.0 || ^6.0.0 || ^7.0.0-0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@3.2.4': + resolution: {integrity: sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==} + + '@vitest/runner@3.2.4': + resolution: {integrity: sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==} + + '@vitest/snapshot@3.2.4': + resolution: {integrity: sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==} + + '@vitest/spy@3.2.4': + resolution: {integrity: sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==} + + '@vitest/utils@3.2.4': + resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + + acorn@8.15.0: + resolution: {integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + baseline-browser-mapping@2.9.19: + resolution: {integrity: sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg==} + hasBin: true + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.1: + resolution: {integrity: sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + + caniuse-lite@1.0.30001769: + resolution: {integrity: sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg==} + + chai@5.3.3: + resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} + engines: {node: '>=18'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + check-error@2.1.3: + resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} + engines: {node: '>= 16'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + cli-width@4.1.0: + resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} + engines: {node: '>= 12'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + + electron-to-chromium@1.5.286: + resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + enhanced-resolve@5.19.0: + resolution: {integrity: sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg==} + engines: {node: '>=10.13.0'} + + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + + es-module-lexer@2.0.0: + resolution: {integrity: sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==} + + esbuild@0.27.3: + resolution: {integrity: sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + expect-type@1.3.0: + resolution: {integrity: sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==} + engines: {node: '>=12.0.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-uri@3.1.0: + resolution: {integrity: sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphql@16.12.0: + resolution: {integrity: sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==} + engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + headers-polyfill@4.0.3: + resolution: {integrity: sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ==} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-node-process@1.2.0: + resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + js-tokens@9.0.1: + resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + loader-runner@4.3.1: + resolution: {integrity: sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==} + engines: {node: '>=6.11.5'} + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + msw@2.11.2: + resolution: {integrity: sha512-MI54hLCsrMwiflkcqlgYYNJJddY5/+S0SnONvhv1owOplvqohKSQyGejpNdUGyCwgs4IH7PqaNbPw/sKOEze9Q==} + engines: {node: '>=18'} + hasBin: true + peerDependencies: + typescript: '>= 4.8.x' + peerDependenciesMeta: + typescript: + optional: true + + mute-stream@2.0.0: + resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} + engines: {node: ^18.17.0 || >=20.5.0} + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-releases@2.0.27: + resolution: {integrity: sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==} + + outvariant@1.4.3: + resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + + pathval@2.0.1: + resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} + engines: {node: '>= 14.16'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.3: + resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} + engines: {node: '>=12'} + + postcss@8.5.6: + resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==} + engines: {node: ^10 || ^12 || >=14} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + rettime@0.7.0: + resolution: {integrity: sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw==} + + rollup@4.57.1: + resolution: {integrity: sha512-oQL6lgK3e2QZeQ7gcgIkS2YZPg5slw37hYufJ3edKlfQSGGm8ICoxswK15ntSzF/a8+h7ekRy7k7oWc3BQ7y8A==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + semver@7.7.4: + resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + engines: {node: '>=10'} + hasBin: true + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + std-env@3.10.0: + resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} + + strict-event-emitter@0.5.1: + resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-literal@3.1.0: + resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + tapable@2.3.0: + resolution: {integrity: sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==} + engines: {node: '>=6'} + + terser-webpack-plugin@5.3.16: + resolution: {integrity: sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@swc/core': '*' + esbuild: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@swc/core': + optional: true + esbuild: + optional: true + uglify-js: + optional: true + + terser@5.46.0: + resolution: {integrity: sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==} + engines: {node: '>=10'} + hasBin: true + + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@0.3.2: + resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} + + tinyglobby@0.2.15: + resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==} + engines: {node: '>=12.0.0'} + + tinypool@1.1.1: + resolution: {integrity: sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@2.0.0: + resolution: {integrity: sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==} + engines: {node: '>=14.0.0'} + + tinyspy@4.0.4: + resolution: {integrity: sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==} + engines: {node: '>=14.0.0'} + + tldts-core@7.0.23: + resolution: {integrity: sha512-0g9vrtDQLrNIiCj22HSe9d4mLVG3g5ph5DZ8zCKBr4OtrspmNB6ss7hVyzArAeE88ceZocIEGkyW1Ime7fxPtQ==} + + tldts@7.0.23: + resolution: {integrity: sha512-ASdhgQIBSay0R/eXggAkQ53G4nTJqTXqC2kbaBbdDwM7SkjyZyO0OaaN1/FH7U/yCeqOHDwFO5j8+Os/IS1dXw==} + hasBin: true + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tough-cookie@6.0.0: + resolution: {integrity: sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==} + engines: {node: '>=16'} + + ts-loader@9.5.4: + resolution: {integrity: sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + typescript: '*' + webpack: ^5.0.0 + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + typescript@5.7.3: + resolution: {integrity: sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==} + engines: {node: '>=14.17'} + hasBin: true + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + vite-node@3.2.4: + resolution: {integrity: sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + + vite@7.3.1: + resolution: {integrity: sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + jiti: '>=1.21.0' + less: ^4.0.0 + lightningcss: ^1.21.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@3.2.4: + resolution: {integrity: sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/debug': ^4.1.12 + '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 + '@vitest/browser': 3.2.4 + '@vitest/ui': 3.2.4 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/debug': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + engines: {node: '>=10.13.0'} + + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + engines: {node: '>=10.13.0'} + + webpack@5.105.1: + resolution: {integrity: sha512-Gdj3X74CLJJ8zy4URmK42W7wTZUJrqL+z8nyGEr4dTN0kb3nVs+ZvjbTOqRYPD7qX4tUmwyHL9Q9K6T1seW6Yw==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yoctocolors-cjs@2.1.3: + resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} + engines: {node: '>=18'} + +snapshots: + + '@biomejs/biome@2.3.11': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.3.11 + '@biomejs/cli-darwin-x64': 2.3.11 + '@biomejs/cli-linux-arm64': 2.3.11 + '@biomejs/cli-linux-arm64-musl': 2.3.11 + '@biomejs/cli-linux-x64': 2.3.11 + '@biomejs/cli-linux-x64-musl': 2.3.11 + '@biomejs/cli-win32-arm64': 2.3.11 + '@biomejs/cli-win32-x64': 2.3.11 + + '@biomejs/cli-darwin-arm64@2.3.11': + optional: true + + '@biomejs/cli-darwin-x64@2.3.11': + optional: true + + '@biomejs/cli-linux-arm64-musl@2.3.11': + optional: true + + '@biomejs/cli-linux-arm64@2.3.11': + optional: true + + '@biomejs/cli-linux-x64-musl@2.3.11': + optional: true + + '@biomejs/cli-linux-x64@2.3.11': + optional: true + + '@biomejs/cli-win32-arm64@2.3.11': + optional: true + + '@biomejs/cli-win32-x64@2.3.11': + optional: true + + '@bundled-es-modules/cookie@2.0.1': + dependencies: + cookie: 0.7.2 + + '@bundled-es-modules/statuses@1.0.1': + dependencies: + statuses: 2.0.2 + + '@esbuild/aix-ppc64@0.27.3': + optional: true + + '@esbuild/android-arm64@0.27.3': + optional: true + + '@esbuild/android-arm@0.27.3': + optional: true + + '@esbuild/android-x64@0.27.3': + optional: true + + '@esbuild/darwin-arm64@0.27.3': + optional: true + + '@esbuild/darwin-x64@0.27.3': + optional: true + + '@esbuild/freebsd-arm64@0.27.3': + optional: true + + '@esbuild/freebsd-x64@0.27.3': + optional: true + + '@esbuild/linux-arm64@0.27.3': + optional: true + + '@esbuild/linux-arm@0.27.3': + optional: true + + '@esbuild/linux-ia32@0.27.3': + optional: true + + '@esbuild/linux-loong64@0.27.3': + optional: true + + '@esbuild/linux-mips64el@0.27.3': + optional: true + + '@esbuild/linux-ppc64@0.27.3': + optional: true + + '@esbuild/linux-riscv64@0.27.3': + optional: true + + '@esbuild/linux-s390x@0.27.3': + optional: true + + '@esbuild/linux-x64@0.27.3': + optional: true + + '@esbuild/netbsd-arm64@0.27.3': + optional: true + + '@esbuild/netbsd-x64@0.27.3': + optional: true + + '@esbuild/openbsd-arm64@0.27.3': + optional: true + + '@esbuild/openbsd-x64@0.27.3': + optional: true + + '@esbuild/openharmony-arm64@0.27.3': + optional: true + + '@esbuild/sunos-x64@0.27.3': + optional: true + + '@esbuild/win32-arm64@0.27.3': + optional: true + + '@esbuild/win32-ia32@0.27.3': + optional: true + + '@esbuild/win32-x64@0.27.3': + optional: true + + '@faker-js/faker@9.9.0': {} + + '@inquirer/ansi@1.0.2': {} + + '@inquirer/confirm@5.1.21(@types/node@18.19.130)': + dependencies: + '@inquirer/core': 10.3.2(@types/node@18.19.130) + '@inquirer/type': 3.0.10(@types/node@18.19.130) + optionalDependencies: + '@types/node': 18.19.130 + + '@inquirer/core@10.3.2(@types/node@18.19.130)': + dependencies: + '@inquirer/ansi': 1.0.2 + '@inquirer/figures': 1.0.15 + '@inquirer/type': 3.0.10(@types/node@18.19.130) + cli-width: 4.1.0 + mute-stream: 2.0.0 + signal-exit: 4.1.0 + wrap-ansi: 6.2.0 + yoctocolors-cjs: 2.1.3 + optionalDependencies: + '@types/node': 18.19.130 + + '@inquirer/figures@1.0.15': {} + + '@inquirer/type@3.0.10(@types/node@18.19.130)': + optionalDependencies: + '@types/node': 18.19.130 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@mswjs/interceptors@0.39.8': + dependencies: + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/logger': 0.3.0 + '@open-draft/until': 2.1.0 + is-node-process: 1.2.0 + outvariant: 1.4.3 + strict-event-emitter: 0.5.1 + + '@open-draft/deferred-promise@2.2.0': {} + + '@open-draft/logger@0.3.0': + dependencies: + is-node-process: 1.2.0 + outvariant: 1.4.3 + + '@open-draft/until@2.1.0': {} + + '@rollup/rollup-android-arm-eabi@4.57.1': + optional: true + + '@rollup/rollup-android-arm64@4.57.1': + optional: true + + '@rollup/rollup-darwin-arm64@4.57.1': + optional: true + + '@rollup/rollup-darwin-x64@4.57.1': + optional: true + + '@rollup/rollup-freebsd-arm64@4.57.1': + optional: true + + '@rollup/rollup-freebsd-x64@4.57.1': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.57.1': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.57.1': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-ppc64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.57.1': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.57.1': + optional: true + + '@rollup/rollup-linux-x64-musl@4.57.1': + optional: true + + '@rollup/rollup-openbsd-x64@4.57.1': + optional: true + + '@rollup/rollup-openharmony-arm64@4.57.1': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.57.1': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.57.1': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.57.1': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.57.1': + optional: true + + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + + '@types/cookie@0.6.0': {} + + '@types/deep-eql@4.0.2': {} + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.8 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + + '@types/estree@1.0.8': {} + + '@types/json-schema@7.0.15': {} + + '@types/node@18.19.130': + dependencies: + undici-types: 5.26.5 + + '@types/statuses@2.0.6': {} + + '@types/ws@8.18.1': + dependencies: + '@types/node': 18.19.130 + + '@vitest/expect@3.2.4': + dependencies: + '@types/chai': 5.2.3 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + tinyrainbow: 2.0.0 + + '@vitest/mocker@3.2.4(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(vite@7.3.1(@types/node@18.19.130)(terser@5.46.0))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + msw: 2.11.2(@types/node@18.19.130)(typescript@5.7.3) + vite: 7.3.1(@types/node@18.19.130)(terser@5.46.0) + + '@vitest/pretty-format@3.2.4': + dependencies: + tinyrainbow: 2.0.0 + + '@vitest/runner@3.2.4': + dependencies: + '@vitest/utils': 3.2.4 + pathe: 2.0.3 + strip-literal: 3.1.0 + + '@vitest/snapshot@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@3.2.4': + dependencies: + tinyspy: 4.0.4 + + '@vitest/utils@3.2.4': + dependencies: + '@vitest/pretty-format': 3.2.4 + loupe: 3.2.1 + tinyrainbow: 2.0.0 + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + acorn-import-phases@1.0.4(acorn@8.15.0): + dependencies: + acorn: 8.15.0 + + acorn@8.15.0: {} + + ajv-formats@2.1.1(ajv@8.17.1): + optionalDependencies: + ajv: 8.17.1 + + ajv-keywords@5.1.0(ajv@8.17.1): + dependencies: + ajv: 8.17.1 + fast-deep-equal: 3.1.3 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.0 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-regex@5.0.1: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + assertion-error@2.0.1: {} + + baseline-browser-mapping@2.9.19: {} + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.1: + dependencies: + baseline-browser-mapping: 2.9.19 + caniuse-lite: 1.0.30001769 + electron-to-chromium: 1.5.286 + node-releases: 2.0.27 + update-browserslist-db: 1.2.3(browserslist@4.28.1) + + buffer-from@1.1.2: {} + + cac@6.7.14: {} + + caniuse-lite@1.0.30001769: {} + + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.3 + deep-eql: 5.0.2 + loupe: 3.2.1 + pathval: 2.0.1 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + check-error@2.1.3: {} + + chrome-trace-event@1.0.4: {} + + cli-width@4.1.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + commander@2.20.3: {} + + cookie@0.7.2: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + deep-eql@5.0.2: {} + + electron-to-chromium@1.5.286: {} + + emoji-regex@8.0.0: {} + + enhanced-resolve@5.19.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + + es-module-lexer@1.7.0: {} + + es-module-lexer@2.0.0: {} + + esbuild@0.27.3: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.3 + '@esbuild/android-arm': 0.27.3 + '@esbuild/android-arm64': 0.27.3 + '@esbuild/android-x64': 0.27.3 + '@esbuild/darwin-arm64': 0.27.3 + '@esbuild/darwin-x64': 0.27.3 + '@esbuild/freebsd-arm64': 0.27.3 + '@esbuild/freebsd-x64': 0.27.3 + '@esbuild/linux-arm': 0.27.3 + '@esbuild/linux-arm64': 0.27.3 + '@esbuild/linux-ia32': 0.27.3 + '@esbuild/linux-loong64': 0.27.3 + '@esbuild/linux-mips64el': 0.27.3 + '@esbuild/linux-ppc64': 0.27.3 + '@esbuild/linux-riscv64': 0.27.3 + '@esbuild/linux-s390x': 0.27.3 + '@esbuild/linux-x64': 0.27.3 + '@esbuild/netbsd-arm64': 0.27.3 + '@esbuild/netbsd-x64': 0.27.3 + '@esbuild/openbsd-arm64': 0.27.3 + '@esbuild/openbsd-x64': 0.27.3 + '@esbuild/openharmony-arm64': 0.27.3 + '@esbuild/sunos-x64': 0.27.3 + '@esbuild/win32-arm64': 0.27.3 + '@esbuild/win32-ia32': 0.27.3 + '@esbuild/win32-x64': 0.27.3 + + escalade@3.2.0: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.8 + + events@3.3.0: {} + + expect-type@1.3.0: {} + + fast-deep-equal@3.1.3: {} + + fast-uri@3.1.0: {} + + fdir@6.5.0(picomatch@4.0.3): + optionalDependencies: + picomatch: 4.0.3 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + fsevents@2.3.3: + optional: true + + get-caller-file@2.0.5: {} + + glob-to-regexp@0.4.1: {} + + graceful-fs@4.2.11: {} + + graphql@16.12.0: {} + + has-flag@4.0.0: {} + + headers-polyfill@4.0.3: {} + + is-fullwidth-code-point@3.0.0: {} + + is-node-process@1.2.0: {} + + is-number@7.0.0: {} + + jest-worker@27.5.1: + dependencies: + '@types/node': 18.19.130 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + js-tokens@9.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@1.0.0: {} + + loader-runner@4.3.1: {} + + loupe@3.2.1: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + merge-stream@2.0.0: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + ms@2.1.3: {} + + msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3): + dependencies: + '@bundled-es-modules/cookie': 2.0.1 + '@bundled-es-modules/statuses': 1.0.1 + '@inquirer/confirm': 5.1.21(@types/node@18.19.130) + '@mswjs/interceptors': 0.39.8 + '@open-draft/deferred-promise': 2.2.0 + '@open-draft/until': 2.1.0 + '@types/cookie': 0.6.0 + '@types/statuses': 2.0.6 + graphql: 16.12.0 + headers-polyfill: 4.0.3 + is-node-process: 1.2.0 + outvariant: 1.4.3 + path-to-regexp: 6.3.0 + picocolors: 1.1.1 + rettime: 0.7.0 + strict-event-emitter: 0.5.1 + tough-cookie: 6.0.0 + type-fest: 4.41.0 + yargs: 17.7.2 + optionalDependencies: + typescript: 5.7.3 + transitivePeerDependencies: + - '@types/node' + + mute-stream@2.0.0: {} + + nanoid@3.3.11: {} + + neo-async@2.6.2: {} + + node-releases@2.0.27: {} + + outvariant@1.4.3: {} + + path-to-regexp@6.3.0: {} + + pathe@2.0.3: {} + + pathval@2.0.1: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.3: {} + + postcss@8.5.6: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + rettime@0.7.0: {} + + rollup@4.57.1: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.57.1 + '@rollup/rollup-android-arm64': 4.57.1 + '@rollup/rollup-darwin-arm64': 4.57.1 + '@rollup/rollup-darwin-x64': 4.57.1 + '@rollup/rollup-freebsd-arm64': 4.57.1 + '@rollup/rollup-freebsd-x64': 4.57.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.57.1 + '@rollup/rollup-linux-arm-musleabihf': 4.57.1 + '@rollup/rollup-linux-arm64-gnu': 4.57.1 + '@rollup/rollup-linux-arm64-musl': 4.57.1 + '@rollup/rollup-linux-loong64-gnu': 4.57.1 + '@rollup/rollup-linux-loong64-musl': 4.57.1 + '@rollup/rollup-linux-ppc64-gnu': 4.57.1 + '@rollup/rollup-linux-ppc64-musl': 4.57.1 + '@rollup/rollup-linux-riscv64-gnu': 4.57.1 + '@rollup/rollup-linux-riscv64-musl': 4.57.1 + '@rollup/rollup-linux-s390x-gnu': 4.57.1 + '@rollup/rollup-linux-x64-gnu': 4.57.1 + '@rollup/rollup-linux-x64-musl': 4.57.1 + '@rollup/rollup-openbsd-x64': 4.57.1 + '@rollup/rollup-openharmony-arm64': 4.57.1 + '@rollup/rollup-win32-arm64-msvc': 4.57.1 + '@rollup/rollup-win32-ia32-msvc': 4.57.1 + '@rollup/rollup-win32-x64-gnu': 4.57.1 + '@rollup/rollup-win32-x64-msvc': 4.57.1 + fsevents: 2.3.3 + + safe-buffer@5.2.1: {} + + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.17.1 + ajv-formats: 2.1.1(ajv@8.17.1) + ajv-keywords: 5.1.0(ajv@8.17.1) + + semver@7.7.4: {} + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + siginfo@2.0.0: {} + + signal-exit@4.1.0: {} + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + stackback@0.0.2: {} + + statuses@2.0.2: {} + + std-env@3.10.0: {} + + strict-event-emitter@0.5.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-literal@3.1.0: + dependencies: + js-tokens: 9.0.1 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + tapable@2.3.0: {} + + terser-webpack-plugin@5.3.16(webpack@5.105.1): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + terser: 5.46.0 + webpack: 5.105.1 + + terser@5.46.0: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.15.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + tinybench@2.9.0: {} + + tinyexec@0.3.2: {} + + tinyglobby@0.2.15: + dependencies: + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + + tinypool@1.1.1: {} + + tinyrainbow@2.0.0: {} + + tinyspy@4.0.4: {} + + tldts-core@7.0.23: {} + + tldts@7.0.23: + dependencies: + tldts-core: 7.0.23 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tough-cookie@6.0.0: + dependencies: + tldts: 7.0.23 + + ts-loader@9.5.4(typescript@5.7.3)(webpack@5.105.1): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.19.0 + micromatch: 4.0.8 + semver: 7.7.4 + source-map: 0.7.6 + typescript: 5.7.3 + webpack: 5.105.1 + + type-fest@4.41.0: {} + + typescript@5.7.3: {} + + undici-types@5.26.5: {} + + update-browserslist-db@1.2.3(browserslist@4.28.1): + dependencies: + browserslist: 4.28.1 + escalade: 3.2.0 + picocolors: 1.1.1 + + vite-node@3.2.4(@types/node@18.19.130)(terser@5.46.0): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.3.1(@types/node@18.19.130)(terser@5.46.0) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + vite@7.3.1(@types/node@18.19.130)(terser@5.46.0): + dependencies: + esbuild: 0.27.3 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.57.1 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 18.19.130 + fsevents: 2.3.3 + terser: 5.46.0 + + vitest@3.2.4(@types/node@18.19.130)(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(terser@5.46.0): + dependencies: + '@types/chai': 5.2.3 + '@vitest/expect': 3.2.4 + '@vitest/mocker': 3.2.4(msw@2.11.2(@types/node@18.19.130)(typescript@5.7.3))(vite@7.3.1(@types/node@18.19.130)(terser@5.46.0)) + '@vitest/pretty-format': 3.2.4 + '@vitest/runner': 3.2.4 + '@vitest/snapshot': 3.2.4 + '@vitest/spy': 3.2.4 + '@vitest/utils': 3.2.4 + chai: 5.3.3 + debug: 4.4.3 + expect-type: 1.3.0 + magic-string: 0.30.21 + pathe: 2.0.3 + picomatch: 4.0.3 + std-env: 3.10.0 + tinybench: 2.9.0 + tinyexec: 0.3.2 + tinyglobby: 0.2.15 + tinypool: 1.1.1 + tinyrainbow: 2.0.0 + vite: 7.3.1(@types/node@18.19.130)(terser@5.46.0) + vite-node: 3.2.4(@types/node@18.19.130)(terser@5.46.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 18.19.130 + transitivePeerDependencies: + - jiti + - less + - lightningcss + - msw + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + + watchpack@2.5.1: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + webpack-sources@3.3.3: {} + + webpack@5.105.1: + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.8 + '@types/json-schema': 7.0.15 + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/wasm-edit': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + acorn: 8.15.0 + acorn-import-phases: 1.0.4(acorn@8.15.0) + browserslist: 4.28.1 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.19.0 + es-module-lexer: 2.0.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + json-parse-even-better-errors: 2.3.1 + loader-runner: 4.3.1 + mime-types: 2.1.35 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.0 + terser-webpack-plugin: 5.3.16(webpack@5.105.1) + watchpack: 2.5.1 + webpack-sources: 3.3.3 + transitivePeerDependencies: + - '@swc/core' + - esbuild + - uglify-js + + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + ws@8.19.0: {} + + y18n@5.0.8: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yoctocolors-cjs@2.1.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 00000000..6e4c3951 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1 @@ +packages: ['.'] \ No newline at end of file diff --git a/reference.md b/reference.md new file mode 100644 index 00000000..2a8ed212 --- /dev/null +++ b/reference.md @@ -0,0 +1,2572 @@ +# Reference +## Interactions +
client.interactions.list({ ...params }) -> core.Page<Corti.InteractionsGetResponse, Corti.InteractionsListResponse> +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Lists all existing interactions. Results can be filtered by encounter status and patient identifier. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +const pageableResponse = await client.interactions.list(); +for await (const item of pageableResponse) { + console.log(item); +} + +// Or you can manually iterate page-by-page +let page = await client.interactions.list(); +while (page.hasNextPage()) { + page = page.getNextPage(); +} + +// You can also access the underlying response +const response = page.response; + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.InteractionsListRequest` + +
+
+ +
+
+ +**requestOptions:** `InteractionsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.interactions.create({ ...params }) -> Corti.InteractionsCreateResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Creates a new interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.interactions.create({ + encounter: { + identifier: "identifier", + status: "planned", + type: "first_consultation" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.InteractionsCreateRequest` + +
+
+ +
+
+ +**requestOptions:** `InteractionsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.interactions.get({ ...params }) -> Corti.InteractionsGetResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a previously recorded interaction by its unique identifier (interaction ID). +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.interactions.get({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.InteractionsGetRequest` + +
+
+ +
+
+ +**requestOptions:** `InteractionsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.interactions.delete({ ...params }) -> void +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Deletes an existing interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.interactions.delete({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.InteractionsDeleteRequest` + +
+
+ +
+
+ +**requestOptions:** `InteractionsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.interactions.update({ ...params }) -> Corti.InteractionsGetResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Modifies an existing interaction by updating specific fields without overwriting the entire record. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.interactions.update({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.InteractionsUpdateRequest` + +
+
+ +
+
+ +**requestOptions:** `InteractionsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Recordings +
client.recordings.list({ ...params }) -> Corti.RecordingsListResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieve a list of recordings for a given interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.recordings.list({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.RecordingsListRequest` + +
+
+ +
+
+ +**requestOptions:** `RecordingsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.recordings.get({ ...params }) -> core.BinaryResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieve a specific recording for a given interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.recordings.get({ + id: "id", + recordingId: "recordingId" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.RecordingsGetRequest` + +
+
+ +
+
+ +**requestOptions:** `RecordingsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.recordings.delete({ ...params }) -> void +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Delete a specific recording for a given interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.recordings.delete({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + recordingId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.RecordingsDeleteRequest` + +
+
+ +
+
+ +**requestOptions:** `RecordingsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Transcripts +
client.transcripts.list({ ...params }) -> Corti.TranscriptsListResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a list of transcripts for a given interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.transcripts.list({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.TranscriptsListRequest` + +
+
+ +
+
+ +**requestOptions:** `TranscriptsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.transcripts.create({ ...params }) -> Corti.TranscriptsResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Create a transcript from an audio file attached, via `/recordings` endpoint, to the interaction.
Each interaction may have more than one audio file and transcript associated with it. While audio files up to 60min in total duration, or 150MB in total size, may be attached to an interaction, synchronous processing is only supported for audio files less than ~2min in duration.

If an audio file takes longer to transcribe than the 25sec synchronous processing timeout, then it will continue to process asynchronously. In this scenario, an incomplete or empty transcript with `status=processing` will be returned with a location header that can be used to retrieve the final transcript.

The client can poll the Get Transcript endpoint (`GET /interactions/{id}/transcripts/{transcriptId}/status`) for transcript status changes:
- `200 OK` with status `processing`, `completed`, or `failed`
- `404 Not Found` if the `interactionId` or `transcriptId` are invalid

The completed transcript can be retrieved via the Get Transcript endpoint (`GET /interactions/{id}/transcripts/{transcriptId}/`).
+
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.transcripts.create({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + recordingId: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + primaryLanguage: "en" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.TranscriptsCreateRequest` + +
+
+ +
+
+ +**requestOptions:** `TranscriptsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.transcripts.get({ ...params }) -> Corti.TranscriptsResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieve a transcript from a specific interaction.
Each interaction may have more than one transcript associated with it. Use the List Transcript request (`GET /interactions/{id}/transcripts/`) to see all transcriptIds available for the interaction.

The client can poll this Get Transcript endpoint (`GET /interactions/{id}/transcripts/{transcriptId}/status`) for transcript status changes:
- `200 OK` with status `processing`, `completed`, or `failed`
- `404 Not Found` if the `interactionId` or `transcriptId` are invalid

Status of `completed` indicates the transcript is finalized. If the transcript is retrieved while status is `processing`, then it will be incomplete.
+
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.transcripts.get({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + transcriptId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.TranscriptsGetRequest` + +
+
+ +
+
+ +**requestOptions:** `TranscriptsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.transcripts.delete({ ...params }) -> void +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Deletes a specific transcript associated with an interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.transcripts.delete({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + transcriptId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.TranscriptsDeleteRequest` + +
+
+ +
+
+ +**requestOptions:** `TranscriptsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.transcripts.getStatus({ ...params }) -> Corti.TranscriptsStatusResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Poll for transcript creation status.
Status of `completed` indicates the transcript is finalized.
If the transcript is retrieved while status is `processing`, then it will be incomplete.
Status of `failed` indicate the transcript was not created successfully; please retry.
+
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.transcripts.getStatus({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + transcriptId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.TranscriptsGetStatusRequest` + +
+
+ +
+
+ +**requestOptions:** `TranscriptsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Facts +
client.facts.factGroupsList() -> Corti.FactsFactGroupsListResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Returns a list of available fact groups, used to categorize facts associated with an interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.facts.factGroupsList(); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**requestOptions:** `FactsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.facts.list({ ...params }) -> Corti.FactsListResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a list of facts for a given interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.facts.list({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.FactsListRequest` + +
+
+ +
+
+ +**requestOptions:** `FactsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.facts.create({ ...params }) -> Corti.FactsCreateResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Adds new facts to an interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.facts.create({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + facts: [{ + text: "text", + group: "other" + }] +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.FactsCreateRequest` + +
+
+ +
+
+ +**requestOptions:** `FactsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.facts.batchUpdate({ ...params }) -> Corti.FactsBatchUpdateResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Updates multiple facts associated with an interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.facts.batchUpdate({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + facts: [{ + factId: "3c9d8a12-7f44-4b3e-9e6f-9271c2bbfa08" + }] +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.FactsBatchUpdateRequest` + +
+
+ +
+
+ +**requestOptions:** `FactsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.facts.update({ ...params }) -> Corti.FactsUpdateResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Updates an existing fact associated with a specific interaction. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.facts.update({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + factId: "3c9d8a12-7f44-4b3e-9e6f-9271c2bbfa08" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.FactsUpdateRequest` + +
+
+ +
+
+ +**requestOptions:** `FactsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.facts.extract({ ...params }) -> Corti.FactsExtractResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Extract facts from provided text, without storing them. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.facts.extract({ + context: [{ + type: "text", + text: "text" + }], + outputLanguage: "outputLanguage" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.FactsExtractRequest` + +
+
+ +
+
+ +**requestOptions:** `FactsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Documents +
client.documents.list({ ...params }) -> Corti.DocumentsListResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +List Documents +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.list({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.DocumentsListRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.create({ ...params }) -> Corti.DocumentsGetResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint offers different ways to generate a document. Find guides to document generation [here](/textgen/documents-standard). +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.create({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + body: { + context: [{ + type: "facts", + data: [{ + text: "text", + source: "core" + }] + }], + templateKey: "templateKey", + outputLanguage: "outputLanguage" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.DocumentsCreateRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.get({ ...params }) -> Corti.DocumentsGetResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Get Document. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.get({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + documentId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.DocumentsGetRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.delete({ ...params }) -> void +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.delete({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + documentId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.DocumentsDeleteRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.update({ ...params }) -> Corti.DocumentsGetResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.update({ + id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + documentId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.DocumentsUpdateRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Templates +
client.templates.sectionList({ ...params }) -> Corti.TemplatesSectionListResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a list of template sections with optional filters for organization and language. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.templates.sectionList(); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.TemplatesSectionListRequest` + +
+
+ +
+
+ +**requestOptions:** `TemplatesClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.templates.list({ ...params }) -> Corti.TemplatesListResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a list of templates with optional filters for organization, language, and status. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.templates.list(); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.TemplatesListRequest` + +
+
+ +
+
+ +**requestOptions:** `TemplatesClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.templates.get({ ...params }) -> Corti.TemplatesItem +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves template by key. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.templates.get({ + key: "key" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.TemplatesGetRequest` + +
+
+ +
+
+ +**requestOptions:** `TemplatesClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Codes +
client.codes.predict({ ...params }) -> Corti.CodesGeneralResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Predict medical codes from provided context.
This is a stateless endpoint, designed to predict ICD-10-CM, ICD-10-PCS, and CPT codes based on input text string or documentId.

More than one code system may be defined in a single request, and the maximum number of codes to return per system can also be defined.

Code prediction requests have two possible values for context:
- `text`: One set of code prediction results will be returned based on all input text defined.
- `documentId`: Code prediction will be based on that defined document only.

The response includes two sets of results:
- `Codes`: Highest confidence bundle of codes, as selected by the code prediction model
- `Candidates`: Full list of candidate codes as predicted by the model, rank sorted by model confidence with maximum possible value of 50.

All predicted code results are based on input context defined in the request only (not other external data or assets associated with an interaction).
+
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.codes.predict({ + system: ["icd10cm", "cpt"], + context: [{ + type: "text", + text: "Short arm splint applied in ED for pain control." + }], + maxCandidates: 5 +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.CodesGeneralPredictRequest` + +
+
+ +
+
+ +**requestOptions:** `CodesClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Auth +
client.auth.getToken({ ...params }) -> Corti.GetTokenResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Obtain an OAuth2 access token using client credentials +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.auth.getToken({ + clientId: "client_id_123", + clientSecret: "my_secret_value" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.GetTokenAuthRequest` + +
+
+ +
+
+ +**requestOptions:** `AuthClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Agents +
client.agents.list({ ...params }) -> Corti.AgentsAgentResponse[] +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint retrieves a list of all agents that can be called by the Corti Agent Framework. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.list(); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsListRequest` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.agents.create({ ...params }) -> Corti.AgentsAgent +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint allows the creation of a new agent that can be utilized in the `POST /agents/{id}/v1/message:send` endpoint. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.create({ + name: "name", + description: "description" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsCreateAgent` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.agents.get({ ...params }) -> Corti.AgentsAgentResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint retrieves an agent by its identifier. The agent contains information about its capabilities and the experts it can call. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.get({ + id: "12345678-90ab-cdef-gh12-34567890abc" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsGetRequest` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.agents.delete({ ...params }) -> void +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint deletes an agent by its identifier. Once deleted, the agent can no longer be used in threads. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.delete({ + id: "12345678-90ab-cdef-gh12-34567890abc" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsDeleteRequest` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.agents.update({ ...params }) -> Corti.AgentsAgent +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint updates an existing agent. Only the fields provided in the request body will be updated; other fields will remain unchanged. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.update({ + id: "12345678-90ab-cdef-gh12-34567890abc", + body: { + id: "id", + name: "name", + description: "description", + systemPrompt: "systemPrompt" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsUpdateRequest` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.agents.getCard({ ...params }) -> Corti.AgentsAgentCard +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint retrieves the agent card in JSON format, which provides metadata about the agent, including its name, description, and the experts it can call. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.getCard({ + id: "12345678-90ab-cdef-gh12-34567890abc" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsGetCardRequest` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.agents.messageSend({ ...params }) -> Corti.AgentsMessageSendResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint sends a message to the specified agent to start or continue a task. The agent processes the message and returns a response. If the message contains a task ID that matches an ongoing task, the agent will continue that task; otherwise, it will start a new task. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.messageSend({ + id: "12345678-90ab-cdef-gh12-34567890abc", + message: { + role: "user", + parts: [{ + kind: "text", + text: "text" + }], + messageId: "messageId", + kind: "message" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsMessageSendParams` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.agents.getTask({ ...params }) -> Corti.AgentsTask +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint retrieves the status and details of a specific task associated with the given agent. It provides information about the task's current state, history, and any artifacts produced during its execution. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.getTask({ + id: "12345678-90ab-cdef-gh12-34567890abc", + taskId: "taskId" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsGetTaskRequest` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.agents.getContext({ ...params }) -> Corti.AgentsContext +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint retrieves all tasks and top-level messages associated with a specific context for the given agent. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.getContext({ + id: "12345678-90ab-cdef-gh12-34567890abc", + contextId: "contextId" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsGetContextRequest` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.agents.getRegistryExperts({ ...params }) -> Corti.AgentsRegistryExpertsResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +This endpoint retrieves the experts registry, which contains information about all available experts that can be referenced when creating agents through the AgentsCreateExpertReference schema. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agents.getRegistryExperts({ + limit: 100, + offset: 0 +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Corti.AgentsGetRegistryExpertsRequest` + +
+
+ +
+
+ +**requestOptions:** `AgentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
diff --git a/src/BaseClient.ts b/src/BaseClient.ts new file mode 100644 index 00000000..a33e840f --- /dev/null +++ b/src/BaseClient.ts @@ -0,0 +1,90 @@ +// This file was auto-generated by Fern from our API Definition. + +import { OAuthAuthProvider } from "./auth/OAuthAuthProvider.js"; +import { mergeHeaders } from "./core/headers.js"; +import * as core from "./core/index.js"; +import type * as environments from "./environments.js"; + +export type BaseClientOptions = { + environment: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + /** Override the Tenant-Name header */ + tenantName: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + /** The default maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The default number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** Provide a custom fetch implementation. Useful for platforms that don't have a built-in fetch or need a custom implementation. */ + fetch?: typeof fetch; + /** Configure logging for the client. */ + logging?: core.logging.LogConfig | core.logging.Logger; +} & OAuthAuthProvider.AuthOptions; + +export interface BaseRequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Override the Tenant-Name header */ + tenantName?: string; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; +} + +export type NormalizedClientOptions = T & { + logging: core.logging.Logger; + authProvider?: core.AuthProvider; +}; + +export type NormalizedClientOptionsWithAuth = + NormalizedClientOptions & { + authProvider: core.AuthProvider; + }; + +export function normalizeClientOptions( + options: T, +): NormalizedClientOptions { + const headers = mergeHeaders( + { + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@corti/sdk", + "X-Fern-SDK-Version": "0.10.1", + "User-Agent": "@corti/sdk/0.10.1", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + "Tenant-Name": options?.tenantName, + }, + options?.headers, + ); + + return { + ...options, + logging: core.logging.createLogger(options?.logging), + headers, + } as NormalizedClientOptions; +} + +export function normalizeClientOptionsWithAuth( + options: T, +): NormalizedClientOptionsWithAuth { + const normalized = normalizeClientOptions(options) as NormalizedClientOptionsWithAuth; + const normalizedWithNoOpAuthProvider = withNoOpAuthProvider(normalized); + normalized.authProvider ??= OAuthAuthProvider.createInstance(normalizedWithNoOpAuthProvider); + return normalized; +} + +function withNoOpAuthProvider( + options: NormalizedClientOptions, +): NormalizedClientOptionsWithAuth { + return { + ...options, + authProvider: new core.NoOpAuthProvider(), + }; +} diff --git a/src/Client.ts b/src/Client.ts index 68a57f06..558a5dea 100644 --- a/src/Client.ts +++ b/src/Client.ts @@ -1,165 +1,84 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ - -import * as environments from "./environments.js"; -import * as core from "./core/index.js"; -import { Auth } from "./api/resources/auth/client/Client.js"; -import { mergeHeaders } from "./core/headers.js"; -import { Interactions } from "./api/resources/interactions/client/Client.js"; -import { Recordings } from "./api/resources/recordings/client/Client.js"; -import { Transcripts } from "./api/resources/transcripts/client/Client.js"; -import { Facts } from "./api/resources/facts/client/Client.js"; -import { Documents } from "./api/resources/documents/client/Client.js"; -import { Templates } from "./api/resources/templates/client/Client.js"; -import { Codes } from "./api/resources/codes/client/Client.js"; -import { Agents } from "./api/resources/agents/client/Client.js"; -import { Stream } from "./api/resources/stream/client/Client.js"; -import { Transcribe } from "./api/resources/transcribe/client/Client.js"; +// This file was auto-generated by Fern from our API Definition. + +import { AgentsClient } from "./api/resources/agents/client/Client.js"; +import { AuthClient } from "./api/resources/auth/client/Client.js"; +import { CodesClient } from "./api/resources/codes/client/Client.js"; +import { DocumentsClient } from "./api/resources/documents/client/Client.js"; +import { FactsClient } from "./api/resources/facts/client/Client.js"; +import { InteractionsClient } from "./api/resources/interactions/client/Client.js"; +import { RecordingsClient } from "./api/resources/recordings/client/Client.js"; +import { StreamClient } from "./api/resources/stream/client/Client.js"; +import { TemplatesClient } from "./api/resources/templates/client/Client.js"; +import { TranscribeClient } from "./api/resources/transcribe/client/Client.js"; +import { TranscriptsClient } from "./api/resources/transcripts/client/Client.js"; +import type { BaseClientOptions, BaseRequestOptions } from "./BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "./BaseClient.js"; export declare namespace CortiClient { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - clientId: core.Supplier; - clientSecret: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } export class CortiClient { - protected readonly _options: CortiClient.Options; - private readonly _oauthTokenProvider: core.OAuthTokenProvider; - protected _interactions: Interactions | undefined; - protected _recordings: Recordings | undefined; - protected _transcripts: Transcripts | undefined; - protected _facts: Facts | undefined; - protected _documents: Documents | undefined; - protected _templates: Templates | undefined; - protected _codes: Codes | undefined; - protected _auth: Auth | undefined; - protected _agents: Agents | undefined; - protected _stream: Stream | undefined; - protected _transcribe: Transcribe | undefined; - - constructor(_options: CortiClient.Options) { - this._options = { - ..._options, - headers: mergeHeaders( - { - "Tenant-Name": _options?.tenantName, - "X-Fern-Language": "JavaScript", - "X-Fern-SDK-Name": "@corti/sdk", - "X-Fern-SDK-Version": "0.10.1", - "User-Agent": "@corti/sdk/0.10.1", - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - }, - _options?.headers, - ), - }; - - this._oauthTokenProvider = new core.OAuthTokenProvider({ - clientId: this._options.clientId, - clientSecret: this._options.clientSecret, - authClient: new Auth({ - ...this._options, - environment: this._options.environment, - }), - }); + protected readonly _options: NormalizedClientOptionsWithAuth; + protected _interactions: InteractionsClient | undefined; + protected _recordings: RecordingsClient | undefined; + protected _transcripts: TranscriptsClient | undefined; + protected _facts: FactsClient | undefined; + protected _documents: DocumentsClient | undefined; + protected _templates: TemplatesClient | undefined; + protected _codes: CodesClient | undefined; + protected _auth: AuthClient | undefined; + protected _agents: AgentsClient | undefined; + protected _stream: StreamClient | undefined; + protected _transcribe: TranscribeClient | undefined; + + constructor(options: CortiClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } - public get interactions(): Interactions { - return (this._interactions ??= new Interactions({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get interactions(): InteractionsClient { + return (this._interactions ??= new InteractionsClient(this._options)); } - public get recordings(): Recordings { - return (this._recordings ??= new Recordings({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get recordings(): RecordingsClient { + return (this._recordings ??= new RecordingsClient(this._options)); } - public get transcripts(): Transcripts { - return (this._transcripts ??= new Transcripts({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get transcripts(): TranscriptsClient { + return (this._transcripts ??= new TranscriptsClient(this._options)); } - public get facts(): Facts { - return (this._facts ??= new Facts({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get facts(): FactsClient { + return (this._facts ??= new FactsClient(this._options)); } - public get documents(): Documents { - return (this._documents ??= new Documents({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get documents(): DocumentsClient { + return (this._documents ??= new DocumentsClient(this._options)); } - public get templates(): Templates { - return (this._templates ??= new Templates({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get templates(): TemplatesClient { + return (this._templates ??= new TemplatesClient(this._options)); } - public get codes(): Codes { - return (this._codes ??= new Codes({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get codes(): CodesClient { + return (this._codes ??= new CodesClient(this._options)); } - public get auth(): Auth { - return (this._auth ??= new Auth({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get auth(): AuthClient { + return (this._auth ??= new AuthClient(this._options)); } - public get agents(): Agents { - return (this._agents ??= new Agents({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get agents(): AgentsClient { + return (this._agents ??= new AgentsClient(this._options)); } - public get stream(): Stream { - return (this._stream ??= new Stream({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get stream(): StreamClient { + return (this._stream ??= new StreamClient(this._options)); } - public get transcribe(): Transcribe { - return (this._transcribe ??= new Transcribe({ - ...this._options, - token: async () => await this._oauthTokenProvider.getToken(), - })); + public get transcribe(): TranscribeClient { + return (this._transcribe ??= new TranscribeClient(this._options)); } } diff --git a/src/api/errors/BadGatewayError.ts b/src/api/errors/BadGatewayError.ts index 93c6cd52..e8b6b269 100644 --- a/src/api/errors/BadGatewayError.ts +++ b/src/api/errors/BadGatewayError.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. +import type * as core from "../../core/index.js"; import * as errors from "../../errors/index.js"; -import * as Corti from "../index.js"; -import * as core from "../../core/index.js"; +import type * as Corti from "../index.js"; export class BadGatewayError extends errors.CortiError { constructor(body: Corti.ErrorResponse, rawResponse?: core.RawResponse) { @@ -14,6 +12,11 @@ export class BadGatewayError extends errors.CortiError { body: body, rawResponse: rawResponse, }); - Object.setPrototypeOf(this, BadGatewayError.prototype); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = this.constructor.name; } } diff --git a/src/api/errors/BadRequestError.ts b/src/api/errors/BadRequestError.ts index 7dccc76b..f3993f98 100644 --- a/src/api/errors/BadRequestError.ts +++ b/src/api/errors/BadRequestError.ts @@ -1,9 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. +import type * as core from "../../core/index.js"; import * as errors from "../../errors/index.js"; -import * as core from "../../core/index.js"; export class BadRequestError extends errors.CortiError { constructor(body?: unknown, rawResponse?: core.RawResponse) { @@ -13,6 +11,11 @@ export class BadRequestError extends errors.CortiError { body: body, rawResponse: rawResponse, }); - Object.setPrototypeOf(this, BadRequestError.prototype); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = this.constructor.name; } } diff --git a/src/api/errors/ForbiddenError.ts b/src/api/errors/ForbiddenError.ts index 3a058174..948b7672 100644 --- a/src/api/errors/ForbiddenError.ts +++ b/src/api/errors/ForbiddenError.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. +import type * as core from "../../core/index.js"; import * as errors from "../../errors/index.js"; -import * as Corti from "../index.js"; -import * as core from "../../core/index.js"; +import type * as Corti from "../index.js"; export class ForbiddenError extends errors.CortiError { constructor(body: Corti.ErrorResponse, rawResponse?: core.RawResponse) { @@ -14,6 +12,11 @@ export class ForbiddenError extends errors.CortiError { body: body, rawResponse: rawResponse, }); - Object.setPrototypeOf(this, ForbiddenError.prototype); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = this.constructor.name; } } diff --git a/src/api/errors/GatewayTimeoutError.ts b/src/api/errors/GatewayTimeoutError.ts index c57fe019..c211296b 100644 --- a/src/api/errors/GatewayTimeoutError.ts +++ b/src/api/errors/GatewayTimeoutError.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. +import type * as core from "../../core/index.js"; import * as errors from "../../errors/index.js"; -import * as Corti from "../index.js"; -import * as core from "../../core/index.js"; +import type * as Corti from "../index.js"; export class GatewayTimeoutError extends errors.CortiError { constructor(body: Corti.ErrorResponse, rawResponse?: core.RawResponse) { @@ -14,6 +12,11 @@ export class GatewayTimeoutError extends errors.CortiError { body: body, rawResponse: rawResponse, }); - Object.setPrototypeOf(this, GatewayTimeoutError.prototype); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = this.constructor.name; } } diff --git a/src/api/errors/InternalServerError.ts b/src/api/errors/InternalServerError.ts index cc81905b..a5705c14 100644 --- a/src/api/errors/InternalServerError.ts +++ b/src/api/errors/InternalServerError.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. +import type * as core from "../../core/index.js"; import * as errors from "../../errors/index.js"; -import * as Corti from "../index.js"; -import * as core from "../../core/index.js"; +import type * as Corti from "../index.js"; export class InternalServerError extends errors.CortiError { constructor(body: Corti.ErrorResponse, rawResponse?: core.RawResponse) { @@ -14,6 +12,11 @@ export class InternalServerError extends errors.CortiError { body: body, rawResponse: rawResponse, }); - Object.setPrototypeOf(this, InternalServerError.prototype); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = this.constructor.name; } } diff --git a/src/api/errors/NotFoundError.ts b/src/api/errors/NotFoundError.ts index 1e9bf21c..e8f9c5be 100644 --- a/src/api/errors/NotFoundError.ts +++ b/src/api/errors/NotFoundError.ts @@ -1,9 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. +import type * as core from "../../core/index.js"; import * as errors from "../../errors/index.js"; -import * as core from "../../core/index.js"; export class NotFoundError extends errors.CortiError { constructor(body?: unknown, rawResponse?: core.RawResponse) { @@ -13,6 +11,11 @@ export class NotFoundError extends errors.CortiError { body: body, rawResponse: rawResponse, }); - Object.setPrototypeOf(this, NotFoundError.prototype); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = this.constructor.name; } } diff --git a/src/api/errors/UnauthorizedError.ts b/src/api/errors/UnauthorizedError.ts index be3cea18..eecf170a 100644 --- a/src/api/errors/UnauthorizedError.ts +++ b/src/api/errors/UnauthorizedError.ts @@ -1,9 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. +import type * as core from "../../core/index.js"; import * as errors from "../../errors/index.js"; -import * as core from "../../core/index.js"; export class UnauthorizedError extends errors.CortiError { constructor(body?: unknown, rawResponse?: core.RawResponse) { @@ -13,6 +11,11 @@ export class UnauthorizedError extends errors.CortiError { body: body, rawResponse: rawResponse, }); - Object.setPrototypeOf(this, UnauthorizedError.prototype); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = this.constructor.name; } } diff --git a/src/api/errors/index.ts b/src/api/errors/index.ts index cfb88dde..20780f20 100644 --- a/src/api/errors/index.ts +++ b/src/api/errors/index.ts @@ -1,7 +1,7 @@ +export * from "./BadGatewayError.js"; +export * from "./BadRequestError.js"; export * from "./ForbiddenError.js"; export * from "./GatewayTimeoutError.js"; -export * from "./BadRequestError.js"; export * from "./InternalServerError.js"; export * from "./NotFoundError.js"; export * from "./UnauthorizedError.js"; -export * from "./BadGatewayError.js"; diff --git a/src/api/index.ts b/src/api/index.ts index 390dbe0e..6ed44b0b 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -1,7 +1,3 @@ +export * from "./errors/index.js"; export * from "./resources/index.js"; export * from "./types/index.js"; -export * from "./errors/index.js"; -/** - * Patch: including custom types to main export of types - */ -export * from "../custom/index.js"; diff --git a/src/api/resources/agents/client/Client.ts b/src/api/resources/agents/client/Client.ts index a2cc934a..f6cc6f81 100644 --- a/src/api/resources/agents/client/Client.ts +++ b/src/api/resources/agents/client/Client.ts @@ -1,52 +1,32 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; -import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; -import * as serializers from "../../../../serialization/index.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; import * as errors from "../../../../errors/index.js"; +import * as serializers from "../../../../serialization/index.js"; +import * as Corti from "../../../index.js"; -export declare namespace Agents { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace AgentsClient { + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } -export class Agents { - protected readonly _options: Agents.Options; +export class AgentsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; - constructor(_options: Agents.Options) { - this._options = _options; + constructor(options: AgentsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } /** * This endpoint retrieves a list of all agents that can be called by the Corti Agent Framework. * * @param {Corti.AgentsListRequest} request - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} @@ -56,29 +36,28 @@ export class Agents { */ public list( request: Corti.AgentsListRequest = {}, - requestOptions?: Agents.RequestOptions, + requestOptions?: AgentsClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); } private async __list( request: Corti.AgentsListRequest = {}, - requestOptions?: Agents.RequestOptions, + requestOptions?: AgentsClient.RequestOptions, ): Promise> { const { limit, offset, ephemeral } = request; - const _queryParams: Record = {}; - if (limit !== undefined) { - _queryParams["limit"] = limit?.toString() ?? null; - } - - if (offset !== undefined) { - _queryParams["offset"] = offset?.toString() ?? null; - } - - if (ephemeral !== undefined) { - _queryParams["ephemeral"] = ephemeral?.toString() ?? null; - } - + const _queryParams: Record = { + limit, + offset, + ephemeral, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -86,18 +65,13 @@ export class Agents { "agents", ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - queryParameters: _queryParams, - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -127,28 +101,14 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /agents."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/agents"); } /** * This endpoint allows the creation of a new agent that can be utilized in the `POST /agents/{id}/v1/message:send` endpoint. * * @param {Corti.AgentsCreateAgent} request - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} @@ -161,21 +121,26 @@ export class Agents { */ public create( request: Corti.AgentsCreateAgent, - requestOptions?: Agents.RequestOptions, + requestOptions?: AgentsClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__create(request, requestOptions)); } private async __create( request: Corti.AgentsCreateAgent, - requestOptions?: Agents.RequestOptions, + requestOptions?: AgentsClient.RequestOptions, ): Promise> { const { ephemeral, ..._body } = request; - const _queryParams: Record = {}; - if (ephemeral !== undefined) { - _queryParams["ephemeral"] = ephemeral?.toString() ?? null; - } - + const _queryParams: Record = { + ephemeral, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -183,24 +148,19 @@ export class Agents { "agents", ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", - queryParameters: _queryParams, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, requestType: "json", body: serializers.AgentsCreateAgent.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -230,65 +190,57 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling POST /agents."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/agents"); } /** * This endpoint retrieves an agent by its identifier. The agent contains information about its capabilities and the experts it can call. * - * @param {string} id - The identifier of the agent associated with the context. - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.AgentsGetRequest} request + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.NotFoundError} * * @example - * await client.agents.get("12345678-90ab-cdef-gh12-34567890abc") + * await client.agents.get({ + * id: "12345678-90ab-cdef-gh12-34567890abc" + * }) */ public get( - id: string, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsGetRequest, + requestOptions?: AgentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__get(id, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); } private async __get( - id: string, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsGetRequest, + requestOptions?: AgentsClient.RequestOptions, ): Promise> { + const { id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).agents, - `agents/${encodeURIComponent(id)}`, + `agents/${core.url.encodePathParam(id)}`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -320,59 +272,57 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /agents/{id}."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/agents/{id}"); } /** * This endpoint deletes an agent by its identifier. Once deleted, the agent can no longer be used in threads. * - * @param {string} id - The identifier of the agent associated with the context. - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.AgentsDeleteRequest} request + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.NotFoundError} * * @example - * await client.agents.delete("12345678-90ab-cdef-gh12-34567890abc") + * await client.agents.delete({ + * id: "12345678-90ab-cdef-gh12-34567890abc" + * }) */ - public delete(id: string, requestOptions?: Agents.RequestOptions): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__delete(id, requestOptions)); + public delete( + request: Corti.AgentsDeleteRequest, + requestOptions?: AgentsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(request, requestOptions)); } - private async __delete(id: string, requestOptions?: Agents.RequestOptions): Promise> { + private async __delete( + request: Corti.AgentsDeleteRequest, + requestOptions?: AgentsClient.RequestOptions, + ): Promise> { + const { id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).agents, - `agents/${encodeURIComponent(id)}`, + `agents/${core.url.encodePathParam(id)}`, ), method: "DELETE", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { data: undefined, rawResponse: _response.rawResponse }; @@ -395,79 +345,66 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling DELETE /agents/{id}."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/agents/{id}"); } /** * This endpoint updates an existing agent. Only the fields provided in the request body will be updated; other fields will remain unchanged. * - * @param {string} id - The identifier of the agent associated with the context. - * @param {Corti.AgentsAgent} request - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.AgentsUpdateRequest} request + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.NotFoundError} * * @example - * await client.agents.update("12345678-90ab-cdef-gh12-34567890abc", { - * id: "id", - * name: "name", - * description: "description", - * systemPrompt: "systemPrompt" + * await client.agents.update({ + * id: "12345678-90ab-cdef-gh12-34567890abc", + * body: { + * id: "id", + * name: "name", + * description: "description", + * systemPrompt: "systemPrompt" + * } * }) */ public update( - id: string, - request: Corti.AgentsAgent, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsUpdateRequest, + requestOptions?: AgentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__update(id, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__update(request, requestOptions)); } private async __update( - id: string, - request: Corti.AgentsAgent, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsUpdateRequest, + requestOptions?: AgentsClient.RequestOptions, ): Promise> { + const { id, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).agents, - `agents/${encodeURIComponent(id)}`, + `agents/${core.url.encodePathParam(id)}`, ), method: "PATCH", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", - body: serializers.AgentsAgent.jsonOrThrow(request, { - unrecognizedObjectKeys: "strip", - omitUndefined: true, - }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + body: serializers.AgentsAgent.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true }), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -499,65 +436,57 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling PATCH /agents/{id}."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/agents/{id}"); } /** * This endpoint retrieves the agent card in JSON format, which provides metadata about the agent, including its name, description, and the experts it can call. * - * @param {string} id - The identifier of the agent associated with the context. - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.AgentsGetCardRequest} request + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.NotFoundError} * * @example - * await client.agents.getCard("12345678-90ab-cdef-gh12-34567890abc") + * await client.agents.getCard({ + * id: "12345678-90ab-cdef-gh12-34567890abc" + * }) */ public getCard( - id: string, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsGetCardRequest, + requestOptions?: AgentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__getCard(id, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__getCard(request, requestOptions)); } private async __getCard( - id: string, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsGetCardRequest, + requestOptions?: AgentsClient.RequestOptions, ): Promise> { + const { id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).agents, - `agents/${encodeURIComponent(id)}/agent-card.json`, + `agents/${core.url.encodePathParam(id)}/agent-card.json`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -589,36 +518,22 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /agents/{id}/agent-card.json."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/agents/{id}/agent-card.json"); } /** * This endpoint sends a message to the specified agent to start or continue a task. The agent processes the message and returns a response. If the message contains a task ID that matches an ongoing task, the agent will continue that task; otherwise, it will start a new task. * - * @param {string} id - The identifier of the agent associated with the context. * @param {Corti.AgentsMessageSendParams} request - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.NotFoundError} * * @example - * await client.agents.messageSend("12345678-90ab-cdef-gh12-34567890abc", { + * await client.agents.messageSend({ + * id: "12345678-90ab-cdef-gh12-34567890abc", * message: { * role: "user", * parts: [{ @@ -631,42 +546,44 @@ export class Agents { * }) */ public messageSend( - id: string, request: Corti.AgentsMessageSendParams, - requestOptions?: Agents.RequestOptions, + requestOptions?: AgentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__messageSend(id, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__messageSend(request, requestOptions)); } private async __messageSend( - id: string, request: Corti.AgentsMessageSendParams, - requestOptions?: Agents.RequestOptions, + requestOptions?: AgentsClient.RequestOptions, ): Promise> { + const { id, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).agents, - `agents/${encodeURIComponent(id)}/v1/message:send`, + `agents/${core.url.encodePathParam(id)}/v1/message:send`, ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", - body: serializers.AgentsMessageSendParams.jsonOrThrow(request, { + body: serializers.AgentsMessageSendParams.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -698,78 +615,61 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling POST /agents/{id}/v1/message:send."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/agents/{id}/v1/message:send"); } /** * This endpoint retrieves the status and details of a specific task associated with the given agent. It provides information about the task's current state, history, and any artifacts produced during its execution. * - * @param {string} id - The identifier of the agent associated with the context. - * @param {string} taskId - The identifier of the task to retrieve. * @param {Corti.AgentsGetTaskRequest} request - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.NotFoundError} * * @example - * await client.agents.getTask("12345678-90ab-cdef-gh12-34567890abc", "taskId") + * await client.agents.getTask({ + * id: "12345678-90ab-cdef-gh12-34567890abc", + * taskId: "taskId" + * }) */ public getTask( - id: string, - taskId: string, - request: Corti.AgentsGetTaskRequest = {}, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsGetTaskRequest, + requestOptions?: AgentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__getTask(id, taskId, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__getTask(request, requestOptions)); } private async __getTask( - id: string, - taskId: string, - request: Corti.AgentsGetTaskRequest = {}, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsGetTaskRequest, + requestOptions?: AgentsClient.RequestOptions, ): Promise> { - const { historyLength } = request; - const _queryParams: Record = {}; - if (historyLength !== undefined) { - _queryParams["historyLength"] = historyLength?.toString() ?? null; - } - + const { id, taskId, historyLength } = request; + const _queryParams: Record = { + historyLength, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).agents, - `agents/${encodeURIComponent(id)}/v1/tasks/${encodeURIComponent(taskId)}`, + `agents/${core.url.encodePathParam(id)}/v1/tasks/${core.url.encodePathParam(taskId)}`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - queryParameters: _queryParams, - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -801,82 +701,67 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /agents/{id}/v1/tasks/{taskId}."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/agents/{id}/v1/tasks/{taskId}", + ); } /** * This endpoint retrieves all tasks and top-level messages associated with a specific context for the given agent. * - * @param {string} id - The identifier of the agent associated with the context. - * @param {string} contextId - The identifier of the context (thread) to retrieve tasks for. * @param {Corti.AgentsGetContextRequest} request - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.NotFoundError} * * @example - * await client.agents.getContext("12345678-90ab-cdef-gh12-34567890abc", "contextId") + * await client.agents.getContext({ + * id: "12345678-90ab-cdef-gh12-34567890abc", + * contextId: "contextId" + * }) */ public getContext( - id: string, - contextId: string, - request: Corti.AgentsGetContextRequest = {}, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsGetContextRequest, + requestOptions?: AgentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__getContext(id, contextId, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__getContext(request, requestOptions)); } private async __getContext( - id: string, - contextId: string, - request: Corti.AgentsGetContextRequest = {}, - requestOptions?: Agents.RequestOptions, + request: Corti.AgentsGetContextRequest, + requestOptions?: AgentsClient.RequestOptions, ): Promise> { - const { limit, offset } = request; - const _queryParams: Record = {}; - if (limit !== undefined) { - _queryParams["limit"] = limit?.toString() ?? null; - } - - if (offset !== undefined) { - _queryParams["offset"] = offset?.toString() ?? null; - } - + const { id, contextId, limit, offset } = request; + const _queryParams: Record = { + limit, + offset, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).agents, - `agents/${encodeURIComponent(id)}/v1/contexts/${encodeURIComponent(contextId)}`, + `agents/${core.url.encodePathParam(id)}/v1/contexts/${core.url.encodePathParam(contextId)}`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - queryParameters: _queryParams, - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -908,30 +793,19 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling GET /agents/{id}/v1/contexts/{contextId}.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/agents/{id}/v1/contexts/{contextId}", + ); } /** * This endpoint retrieves the experts registry, which contains information about all available experts that can be referenced when creating agents through the AgentsCreateExpertReference schema. * * @param {Corti.AgentsGetRegistryExpertsRequest} request - * @param {Agents.RequestOptions} requestOptions - Request-specific configuration. + * @param {AgentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} @@ -944,25 +818,27 @@ export class Agents { */ public getRegistryExperts( request: Corti.AgentsGetRegistryExpertsRequest = {}, - requestOptions?: Agents.RequestOptions, + requestOptions?: AgentsClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__getRegistryExperts(request, requestOptions)); } private async __getRegistryExperts( request: Corti.AgentsGetRegistryExpertsRequest = {}, - requestOptions?: Agents.RequestOptions, + requestOptions?: AgentsClient.RequestOptions, ): Promise> { const { limit, offset } = request; - const _queryParams: Record = {}; - if (limit !== undefined) { - _queryParams["limit"] = limit?.toString() ?? null; - } - - if (offset !== undefined) { - _queryParams["offset"] = offset?.toString() ?? null; - } - + const _queryParams: Record = { + limit, + offset, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -970,18 +846,13 @@ export class Agents { "agents/registry/experts", ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - queryParameters: _queryParams, - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -1011,29 +882,6 @@ export class Agents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /agents/registry/experts."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/agents/registry/experts"); } } diff --git a/src/api/resources/agents/client/index.ts b/src/api/resources/agents/client/index.ts index 82648c6f..195f9aa8 100644 --- a/src/api/resources/agents/client/index.ts +++ b/src/api/resources/agents/client/index.ts @@ -1,2 +1 @@ -export {}; export * from "./requests/index.js"; diff --git a/src/api/resources/agents/client/requests/AgentsCreateAgent.ts b/src/api/resources/agents/client/requests/AgentsCreateAgent.ts index f723f65e..42c96a76 100644 --- a/src/api/resources/agents/client/requests/AgentsCreateAgent.ts +++ b/src/api/resources/agents/client/requests/AgentsCreateAgent.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example @@ -12,10 +10,8 @@ import * as Corti from "../../../../index.js"; * } */ export interface AgentsCreateAgent { - /** - * If set to true, the agent will be created as ephemeral, it won't be listed in the agents_list but can still be fetched by ID. Ephemeral agents will be deleted periodically. - */ - ephemeral?: boolean | null; + /** If set to true, the agent will be created as ephemeral, it won't be listed in the agents_list but can still be fetched by ID. Ephemeral agents will be deleted periodically. */ + ephemeral?: boolean; /** The name of the agent. */ name: string; /** Optional type of agent. */ diff --git a/src/api/resources/agents/client/requests/AgentsDeleteRequest.ts b/src/api/resources/agents/client/requests/AgentsDeleteRequest.ts new file mode 100644 index 00000000..4438d8ad --- /dev/null +++ b/src/api/resources/agents/client/requests/AgentsDeleteRequest.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * id: "12345678-90ab-cdef-gh12-34567890abc" + * } + */ +export interface AgentsDeleteRequest { + /** The identifier of the agent associated with the context. */ + id: string; +} diff --git a/src/api/resources/agents/client/requests/AgentsGetCardRequest.ts b/src/api/resources/agents/client/requests/AgentsGetCardRequest.ts new file mode 100644 index 00000000..46ab31be --- /dev/null +++ b/src/api/resources/agents/client/requests/AgentsGetCardRequest.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * id: "12345678-90ab-cdef-gh12-34567890abc" + * } + */ +export interface AgentsGetCardRequest { + /** The identifier of the agent associated with the context. */ + id: string; +} diff --git a/src/api/resources/agents/client/requests/AgentsGetContextRequest.ts b/src/api/resources/agents/client/requests/AgentsGetContextRequest.ts index 8eac4f90..bc834a61 100644 --- a/src/api/resources/agents/client/requests/AgentsGetContextRequest.ts +++ b/src/api/resources/agents/client/requests/AgentsGetContextRequest.ts @@ -1,18 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * @example - * {} + * { + * id: "12345678-90ab-cdef-gh12-34567890abc", + * contextId: "contextId" + * } */ export interface AgentsGetContextRequest { - /** - * The maximum number of tasks and messages to return. If not specified all history is returned. - */ - limit?: number | null; - /** - * The number of tasks and messages to skip before starting to collect the result set. Default is 0. - */ - offset?: number | null; + /** The identifier of the agent associated with the context. */ + id: string; + /** The identifier of the context (thread) to retrieve tasks for. */ + contextId: string; + /** The maximum number of tasks and messages to return. If not specified all history is returned. */ + limit?: number; + /** The number of tasks and messages to skip before starting to collect the result set. Default is 0. */ + offset?: number; } diff --git a/src/api/resources/agents/client/requests/AgentsGetRegistryExpertsRequest.ts b/src/api/resources/agents/client/requests/AgentsGetRegistryExpertsRequest.ts index 299644db..8fcaf74f 100644 --- a/src/api/resources/agents/client/requests/AgentsGetRegistryExpertsRequest.ts +++ b/src/api/resources/agents/client/requests/AgentsGetRegistryExpertsRequest.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * @example @@ -10,12 +8,8 @@ * } */ export interface AgentsGetRegistryExpertsRequest { - /** - * The maximum number of items to return. If not specified, a default number of items will be returned. - */ - limit?: number | null; - /** - * The number of items to skip before starting to collect the result set. Default is 0. - */ - offset?: number | null; + /** The maximum number of items to return. If not specified, a default number of items will be returned. */ + limit?: number; + /** The number of items to skip before starting to collect the result set. Default is 0. */ + offset?: number; } diff --git a/src/api/resources/agents/client/requests/AgentsGetRequest.ts b/src/api/resources/agents/client/requests/AgentsGetRequest.ts new file mode 100644 index 00000000..61e9657d --- /dev/null +++ b/src/api/resources/agents/client/requests/AgentsGetRequest.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * id: "12345678-90ab-cdef-gh12-34567890abc" + * } + */ +export interface AgentsGetRequest { + /** The identifier of the agent associated with the context. */ + id: string; +} diff --git a/src/api/resources/agents/client/requests/AgentsGetTaskRequest.ts b/src/api/resources/agents/client/requests/AgentsGetTaskRequest.ts index ff6ecc75..602a563d 100644 --- a/src/api/resources/agents/client/requests/AgentsGetTaskRequest.ts +++ b/src/api/resources/agents/client/requests/AgentsGetTaskRequest.ts @@ -1,14 +1,17 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * @example - * {} + * { + * id: "12345678-90ab-cdef-gh12-34567890abc", + * taskId: "taskId" + * } */ export interface AgentsGetTaskRequest { - /** - * The number of previous messages to include in the context for the agent when retrieving this task. Default is all messages. - */ - historyLength?: number | null; + /** The identifier of the agent associated with the context. */ + id: string; + /** The identifier of the task to retrieve. */ + taskId: string; + /** The number of previous messages to include in the context for the agent when retrieving this task. Default is all messages. */ + historyLength?: number; } diff --git a/src/api/resources/agents/client/requests/AgentsListRequest.ts b/src/api/resources/agents/client/requests/AgentsListRequest.ts index 0d7ea137..efafb427 100644 --- a/src/api/resources/agents/client/requests/AgentsListRequest.ts +++ b/src/api/resources/agents/client/requests/AgentsListRequest.ts @@ -1,22 +1,14 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * @example * {} */ export interface AgentsListRequest { - /** - * The maximum number of agents to return. If not specified, all agents will be returned. - */ - limit?: number | null; - /** - * The number of agents to skip before starting to collect the result set. Default is 0. - */ - offset?: number | null; - /** - * If set to true, ephemeral agents will be included in the response. Default is false. - */ - ephemeral?: boolean | null; + /** The maximum number of agents to return. If not specified, all agents will be returned. */ + limit?: number; + /** The number of agents to skip before starting to collect the result set. Default is 0. */ + offset?: number; + /** If set to true, ephemeral agents will be included in the response. Default is false. */ + ephemeral?: boolean; } diff --git a/src/api/resources/agents/client/requests/AgentsMessageSendParams.ts b/src/api/resources/agents/client/requests/AgentsMessageSendParams.ts index 49b6ca9c..4d12b968 100644 --- a/src/api/resources/agents/client/requests/AgentsMessageSendParams.ts +++ b/src/api/resources/agents/client/requests/AgentsMessageSendParams.ts @@ -1,12 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example * { + * id: "12345678-90ab-cdef-gh12-34567890abc", * message: { * role: "user", * parts: [{ @@ -19,6 +18,8 @@ import * as Corti from "../../../../index.js"; * } */ export interface AgentsMessageSendParams { + /** The identifier of the agent associated with the context. */ + id: string; message: Corti.AgentsMessage; configuration?: Corti.AgentsMessageSendConfiguration; /** Optional metadata that will be associated with the message. */ diff --git a/src/api/resources/agents/client/requests/AgentsUpdateRequest.ts b/src/api/resources/agents/client/requests/AgentsUpdateRequest.ts new file mode 100644 index 00000000..049303c2 --- /dev/null +++ b/src/api/resources/agents/client/requests/AgentsUpdateRequest.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "12345678-90ab-cdef-gh12-34567890abc", + * body: { + * id: "id", + * name: "name", + * description: "description", + * systemPrompt: "systemPrompt" + * } + * } + */ +export interface AgentsUpdateRequest { + /** The identifier of the agent associated with the context. */ + id: string; + body: Corti.AgentsAgent; +} diff --git a/src/api/resources/agents/client/requests/index.ts b/src/api/resources/agents/client/requests/index.ts index c153c97f..31d1a6bf 100644 --- a/src/api/resources/agents/client/requests/index.ts +++ b/src/api/resources/agents/client/requests/index.ts @@ -1,6 +1,10 @@ -export { type AgentsListRequest } from "./AgentsListRequest.js"; -export { type AgentsCreateAgent } from "./AgentsCreateAgent.js"; -export { type AgentsMessageSendParams } from "./AgentsMessageSendParams.js"; -export { type AgentsGetTaskRequest } from "./AgentsGetTaskRequest.js"; -export { type AgentsGetContextRequest } from "./AgentsGetContextRequest.js"; -export { type AgentsGetRegistryExpertsRequest } from "./AgentsGetRegistryExpertsRequest.js"; +export type { AgentsCreateAgent } from "./AgentsCreateAgent.js"; +export type { AgentsDeleteRequest } from "./AgentsDeleteRequest.js"; +export type { AgentsGetCardRequest } from "./AgentsGetCardRequest.js"; +export type { AgentsGetContextRequest } from "./AgentsGetContextRequest.js"; +export type { AgentsGetRegistryExpertsRequest } from "./AgentsGetRegistryExpertsRequest.js"; +export type { AgentsGetRequest } from "./AgentsGetRequest.js"; +export type { AgentsGetTaskRequest } from "./AgentsGetTaskRequest.js"; +export type { AgentsListRequest } from "./AgentsListRequest.js"; +export type { AgentsMessageSendParams } from "./AgentsMessageSendParams.js"; +export type { AgentsUpdateRequest } from "./AgentsUpdateRequest.js"; diff --git a/src/api/resources/agents/index.ts b/src/api/resources/agents/index.ts index f095e147..d9adb1af 100644 --- a/src/api/resources/agents/index.ts +++ b/src/api/resources/agents/index.ts @@ -1,2 +1,2 @@ -export * from "./types/index.js"; export * from "./client/index.js"; +export * from "./types/index.js"; diff --git a/src/api/resources/agents/types/AgentsCreateAgentAgentType.ts b/src/api/resources/agents/types/AgentsCreateAgentAgentType.ts index 33a0c81a..745a52e8 100644 --- a/src/api/resources/agents/types/AgentsCreateAgentAgentType.ts +++ b/src/api/resources/agents/types/AgentsCreateAgentAgentType.ts @@ -1,13 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Optional type of agent. - */ -export type AgentsCreateAgentAgentType = "expert" | "orchestrator" | "interviewing-expert"; +/** Optional type of agent. */ export const AgentsCreateAgentAgentType = { Expert: "expert", Orchestrator: "orchestrator", InterviewingExpert: "interviewing-expert", } as const; +export type AgentsCreateAgentAgentType = (typeof AgentsCreateAgentAgentType)[keyof typeof AgentsCreateAgentAgentType]; diff --git a/src/api/resources/agents/types/AgentsCreateAgentExpertsItem.ts b/src/api/resources/agents/types/AgentsCreateAgentExpertsItem.ts index 5e2d015a..9a1278ed 100644 --- a/src/api/resources/agents/types/AgentsCreateAgentExpertsItem.ts +++ b/src/api/resources/agents/types/AgentsCreateAgentExpertsItem.ts @@ -1,7 +1,5 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../index.js"; +import type * as Corti from "../../../index.js"; export type AgentsCreateAgentExpertsItem = Corti.AgentsCreateExpert | Corti.AgentsCreateExpertReference; diff --git a/src/api/resources/agents/types/AgentsMessageSendResponse.ts b/src/api/resources/agents/types/AgentsMessageSendResponse.ts index 791d7a91..daa55406 100644 --- a/src/api/resources/agents/types/AgentsMessageSendResponse.ts +++ b/src/api/resources/agents/types/AgentsMessageSendResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../index.js"; +import type * as Corti from "../../../index.js"; export interface AgentsMessageSendResponse { message?: Corti.AgentsMessage; diff --git a/src/api/resources/auth/client/Client.ts b/src/api/resources/auth/client/Client.ts index 852b864d..9a8208d4 100644 --- a/src/api/resources/auth/client/Client.ts +++ b/src/api/resources/auth/client/Client.ts @@ -1,52 +1,32 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; -import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; -import * as serializers from "../../../../serialization/index.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; import * as errors from "../../../../errors/index.js"; +import * as serializers from "../../../../serialization/index.js"; +import type * as Corti from "../../../index.js"; -export declare namespace Auth { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace AuthClient { + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } -export class Auth { - protected readonly _options: Auth.Options; +export class AuthClient { + protected readonly _options: NormalizedClientOptionsWithAuth; - constructor(_options: Auth.Options) { - this._options = _options; + constructor(options: AuthClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } /** * Obtain an OAuth2 access token using client credentials * - * @param {Corti.AuthGetTokenRequest} request - * @param {Auth.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.GetTokenAuthRequest} request + * @param {AuthClient.RequestOptions} requestOptions - Request-specific configuration. * * @example * await client.auth.getToken({ @@ -55,16 +35,21 @@ export class Auth { * }) */ public getToken( - request: Corti.AuthGetTokenRequest, - requestOptions?: Auth.RequestOptions, + request: Corti.GetTokenAuthRequest, + requestOptions?: AuthClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__getToken(request, requestOptions)); } private async __getToken( - request: Corti.AuthGetTokenRequest, - requestOptions?: Auth.RequestOptions, + request: Corti.GetTokenAuthRequest, + requestOptions?: AuthClient.RequestOptions, ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -72,27 +57,23 @@ export class Auth { "protocol/openid-connect/token", ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/x-www-form-urlencoded", - requestType: "json", + queryParameters: requestOptions?.queryParams, + requestType: "form", body: { - ...serializers.AuthGetTokenRequest.jsonOrThrow(request, { + ...serializers.GetTokenAuthRequest.jsonOrThrow(request, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), scope: "openid", grant_type: "client_credentials", }, - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -115,31 +96,11 @@ export class Auth { }); } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling POST /protocol/openid-connect/token.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/protocol/openid-connect/token", + ); } } diff --git a/src/api/resources/auth/client/index.ts b/src/api/resources/auth/client/index.ts index 82648c6f..195f9aa8 100644 --- a/src/api/resources/auth/client/index.ts +++ b/src/api/resources/auth/client/index.ts @@ -1,2 +1 @@ -export {}; export * from "./requests/index.js"; diff --git a/src/api/resources/auth/client/requests/AuthGetTokenRequest.ts b/src/api/resources/auth/client/requests/GetTokenAuthRequest.ts similarity index 69% rename from src/api/resources/auth/client/requests/AuthGetTokenRequest.ts rename to src/api/resources/auth/client/requests/GetTokenAuthRequest.ts index fb7b849d..203b6882 100644 --- a/src/api/resources/auth/client/requests/AuthGetTokenRequest.ts +++ b/src/api/resources/auth/client/requests/GetTokenAuthRequest.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * @example @@ -9,7 +7,7 @@ * clientSecret: "my_secret_value" * } */ -export interface AuthGetTokenRequest { +export interface GetTokenAuthRequest { clientId: string; /** Optional secret for confidential clients and Authorization code flow */ clientSecret?: string; diff --git a/src/api/resources/auth/client/requests/index.ts b/src/api/resources/auth/client/requests/index.ts index db82948f..d78eb061 100644 --- a/src/api/resources/auth/client/requests/index.ts +++ b/src/api/resources/auth/client/requests/index.ts @@ -1 +1 @@ -export { type AuthGetTokenRequest } from "./AuthGetTokenRequest.js"; +export type { GetTokenAuthRequest } from "./GetTokenAuthRequest.js"; diff --git a/src/api/resources/auth/index.ts b/src/api/resources/auth/index.ts index f095e147..d9adb1af 100644 --- a/src/api/resources/auth/index.ts +++ b/src/api/resources/auth/index.ts @@ -1,2 +1,2 @@ -export * from "./types/index.js"; export * from "./client/index.js"; +export * from "./types/index.js"; diff --git a/src/api/resources/auth/types/GetTokenResponse.ts b/src/api/resources/auth/types/GetTokenResponse.ts index 63db812e..b22cd566 100644 --- a/src/api/resources/auth/types/GetTokenResponse.ts +++ b/src/api/resources/auth/types/GetTokenResponse.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface GetTokenResponse { accessToken: string; diff --git a/src/api/resources/codes/client/Client.ts b/src/api/resources/codes/client/Client.ts index 3a1df8d1..e0bc1660 100644 --- a/src/api/resources/codes/client/Client.ts +++ b/src/api/resources/codes/client/Client.ts @@ -1,52 +1,32 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; -import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; -import * as serializers from "../../../../serialization/index.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; import * as errors from "../../../../errors/index.js"; +import * as serializers from "../../../../serialization/index.js"; +import * as Corti from "../../../index.js"; -export declare namespace Codes { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace CodesClient { + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } -export class Codes { - protected readonly _options: Codes.Options; +export class CodesClient { + protected readonly _options: NormalizedClientOptionsWithAuth; - constructor(_options: Codes.Options) { - this._options = _options; + constructor(options: CodesClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } /** * Predict medical codes from provided context.
This is a stateless endpoint, designed to predict ICD-10-CM, ICD-10-PCS, and CPT codes based on input text string or documentId.

More than one code system may be defined in a single request, and the maximum number of codes to return per system can also be defined.

Code prediction requests have two possible values for context:
- `text`: One set of code prediction results will be returned based on all input text defined.
- `documentId`: Code prediction will be based on that defined document only.

The response includes two sets of results:
- `Codes`: Highest confidence bundle of codes, as selected by the code prediction model
- `Candidates`: Full list of candidate codes as predicted by the model, rank sorted by model confidence with maximum possible value of 50.

All predicted code results are based on input context defined in the request only (not other external data or assets associated with an interaction).
* * @param {Corti.CodesGeneralPredictRequest} request - * @param {Codes.RequestOptions} requestOptions - Request-specific configuration. + * @param {CodesClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.ForbiddenError} @@ -66,15 +46,22 @@ export class Codes { */ public predict( request: Corti.CodesGeneralPredictRequest, - requestOptions?: Codes.RequestOptions, + requestOptions?: CodesClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__predict(request, requestOptions)); } private async __predict( request: Corti.CodesGeneralPredictRequest, - requestOptions?: Codes.RequestOptions, + requestOptions?: CodesClient.RequestOptions, ): Promise> { + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -82,23 +69,19 @@ export class Codes { "tools/coding/", ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", body: serializers.CodesGeneralPredictRequest.jsonOrThrow(request, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -170,29 +153,6 @@ export class Codes { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling POST /tools/coding/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; + return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/tools/coding/"); } } diff --git a/src/api/resources/codes/client/index.ts b/src/api/resources/codes/client/index.ts index 82648c6f..195f9aa8 100644 --- a/src/api/resources/codes/client/index.ts +++ b/src/api/resources/codes/client/index.ts @@ -1,2 +1 @@ -export {}; export * from "./requests/index.js"; diff --git a/src/api/resources/codes/client/requests/CodesGeneralPredictRequest.ts b/src/api/resources/codes/client/requests/CodesGeneralPredictRequest.ts index dc4faed3..53682522 100644 --- a/src/api/resources/codes/client/requests/CodesGeneralPredictRequest.ts +++ b/src/api/resources/codes/client/requests/CodesGeneralPredictRequest.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example diff --git a/src/api/resources/codes/client/requests/index.ts b/src/api/resources/codes/client/requests/index.ts index 94f0625c..e326f9e4 100644 --- a/src/api/resources/codes/client/requests/index.ts +++ b/src/api/resources/codes/client/requests/index.ts @@ -1 +1 @@ -export { type CodesGeneralPredictRequest } from "./CodesGeneralPredictRequest.js"; +export type { CodesGeneralPredictRequest } from "./CodesGeneralPredictRequest.js"; diff --git a/src/api/resources/documents/client/Client.ts b/src/api/resources/documents/client/Client.ts index 56f35de7..a4830c1f 100644 --- a/src/api/resources/documents/client/Client.ts +++ b/src/api/resources/documents/client/Client.ts @@ -1,52 +1,32 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; -import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; -import * as serializers from "../../../../serialization/index.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; import * as errors from "../../../../errors/index.js"; +import * as serializers from "../../../../serialization/index.js"; +import * as Corti from "../../../index.js"; -export declare namespace Documents { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace DocumentsClient { + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } -export class Documents { - protected readonly _options: Documents.Options; +export class DocumentsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; - constructor(_options: Documents.Options) { - this._options = _options; + constructor(options: DocumentsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } /** * List Documents * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Documents.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.DocumentsListRequest} request + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.ForbiddenError} @@ -54,37 +34,43 @@ export class Documents { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.documents.list("f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.documents.list({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public list( - id: Corti.Uuid, - requestOptions?: Documents.RequestOptions, + request: Corti.DocumentsListRequest, + requestOptions?: DocumentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__list(id, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); } private async __list( - id: Corti.Uuid, - requestOptions?: Documents.RequestOptions, + request: Corti.DocumentsListRequest, + requestOptions?: DocumentsClient.RequestOptions, ): Promise> { + const { id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -145,29 +131,14 @@ export class Documents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /interactions/{id}/documents/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/interactions/{id}/documents/"); } /** * This endpoint offers different ways to generate a document. Find guides to document generation [here](/textgen/documents-standard). * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. * @param {Corti.DocumentsCreateRequest} request - * @param {Documents.RequestOptions} requestOptions - Request-specific configuration. + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.ForbiddenError} @@ -175,55 +146,60 @@ export class Documents { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.documents.create("f47ac10b-58cc-4372-a567-0e02b2c3d479", { - * context: [{ - * type: "facts", - * data: [{ - * text: "text", - * source: "core" - * }] - * }], - * templateKey: "templateKey", - * outputLanguage: "outputLanguage" + * await client.documents.create({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * body: { + * context: [{ + * type: "facts", + * data: [{ + * text: "text", + * source: "core" + * }] + * }], + * templateKey: "templateKey", + * outputLanguage: "outputLanguage" + * } * }) */ public create( - id: Corti.Uuid, request: Corti.DocumentsCreateRequest, - requestOptions?: Documents.RequestOptions, + requestOptions?: DocumentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__create(id, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__create(request, requestOptions)); } private async __create( - id: Corti.Uuid, request: Corti.DocumentsCreateRequest, - requestOptions?: Documents.RequestOptions, + requestOptions?: DocumentsClient.RequestOptions, ): Promise> { + const { id, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/`, ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", - body: serializers.DocumentsCreateRequest.jsonOrThrow(request, { + body: serializers.DocumentsCreateRequestBody.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -284,29 +260,19 @@ export class Documents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling POST /interactions/{id}/documents/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/interactions/{id}/documents/", + ); } /** * Get Document. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Corti.Uuid} documentId - The document ID representing the context for the request. Must be a valid UUID. - * @param {Documents.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.DocumentsGetRequest} request + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.ForbiddenError} @@ -314,39 +280,44 @@ export class Documents { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.documents.get("f47ac10b-58cc-4372-a567-0e02b2c3d479", "f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.documents.get({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * documentId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public get( - id: Corti.Uuid, - documentId: Corti.Uuid, - requestOptions?: Documents.RequestOptions, + request: Corti.DocumentsGetRequest, + requestOptions?: DocumentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__get(id, documentId, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); } private async __get( - id: Corti.Uuid, - documentId: Corti.Uuid, - requestOptions?: Documents.RequestOptions, + request: Corti.DocumentsGetRequest, + requestOptions?: DocumentsClient.RequestOptions, ): Promise> { + const { id, documentId } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/${encodeURIComponent(serializers.Uuid.jsonOrThrow(documentId, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(documentId, { omitUndefined: true }))}`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -407,29 +378,17 @@ export class Documents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling GET /interactions/{id}/documents/{documentId}.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/interactions/{id}/documents/{documentId}", + ); } /** - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Corti.Uuid} documentId - The document ID representing the context for the request. Must be a valid UUID. - * @param {Documents.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.DocumentsDeleteRequest} request + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.ForbiddenError} * @throws {@link Corti.NotFoundError} @@ -437,39 +396,44 @@ export class Documents { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.documents.delete("f47ac10b-58cc-4372-a567-0e02b2c3d479", "f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.documents.delete({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * documentId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public delete( - id: Corti.Uuid, - documentId: Corti.Uuid, - requestOptions?: Documents.RequestOptions, + request: Corti.DocumentsDeleteRequest, + requestOptions?: DocumentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__delete(id, documentId, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__delete(request, requestOptions)); } private async __delete( - id: Corti.Uuid, - documentId: Corti.Uuid, - requestOptions?: Documents.RequestOptions, + request: Corti.DocumentsDeleteRequest, + requestOptions?: DocumentsClient.RequestOptions, ): Promise> { + const { id, documentId } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/${encodeURIComponent(serializers.Uuid.jsonOrThrow(documentId, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(documentId, { omitUndefined: true }))}`, ), method: "DELETE", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { data: undefined, rawResponse: _response.rawResponse }; @@ -521,30 +485,17 @@ export class Documents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling DELETE /interactions/{id}/documents/{documentId}.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "DELETE", + "/interactions/{id}/documents/{documentId}", + ); } /** - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Corti.Uuid} documentId - The document ID representing the context for the request. Must be a valid UUID. * @param {Corti.DocumentsUpdateRequest} request - * @param {Documents.RequestOptions} requestOptions - Request-specific configuration. + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.ForbiddenError} @@ -552,47 +503,50 @@ export class Documents { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.documents.update("f47ac10b-58cc-4372-a567-0e02b2c3d479", "f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.documents.update({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * documentId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public update( - id: Corti.Uuid, - documentId: Corti.Uuid, - request: Corti.DocumentsUpdateRequest = {}, - requestOptions?: Documents.RequestOptions, + request: Corti.DocumentsUpdateRequest, + requestOptions?: DocumentsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__update(id, documentId, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__update(request, requestOptions)); } private async __update( - id: Corti.Uuid, - documentId: Corti.Uuid, - request: Corti.DocumentsUpdateRequest = {}, - requestOptions?: Documents.RequestOptions, + request: Corti.DocumentsUpdateRequest, + requestOptions?: DocumentsClient.RequestOptions, ): Promise> { + const { id, documentId, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/${encodeURIComponent(serializers.Uuid.jsonOrThrow(documentId, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/documents/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(documentId, { omitUndefined: true }))}`, ), method: "PATCH", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", - body: serializers.DocumentsUpdateRequest.jsonOrThrow(request, { + body: serializers.DocumentsUpdateRequest.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -653,31 +607,11 @@ export class Documents { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling PATCH /interactions/{id}/documents/{documentId}.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "PATCH", + "/interactions/{id}/documents/{documentId}", + ); } } diff --git a/src/api/resources/documents/client/index.ts b/src/api/resources/documents/client/index.ts index 82648c6f..195f9aa8 100644 --- a/src/api/resources/documents/client/index.ts +++ b/src/api/resources/documents/client/index.ts @@ -1,2 +1 @@ -export {}; export * from "./requests/index.js"; diff --git a/src/api/resources/documents/client/requests/DocumentsCreateRequest.ts b/src/api/resources/documents/client/requests/DocumentsCreateRequest.ts new file mode 100644 index 00000000..464b98ed --- /dev/null +++ b/src/api/resources/documents/client/requests/DocumentsCreateRequest.ts @@ -0,0 +1,26 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * body: { + * context: [{ + * type: "facts", + * data: [{ + * text: "text", + * source: "core" + * }] + * }], + * templateKey: "templateKey", + * outputLanguage: "outputLanguage" + * } + * } + */ +export interface DocumentsCreateRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + body: Corti.DocumentsCreateRequestBody; +} diff --git a/src/api/resources/documents/client/requests/DocumentsDeleteRequest.ts b/src/api/resources/documents/client/requests/DocumentsDeleteRequest.ts new file mode 100644 index 00000000..709667db --- /dev/null +++ b/src/api/resources/documents/client/requests/DocumentsDeleteRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * documentId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface DocumentsDeleteRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** The document ID representing the context for the request. Must be a valid UUID. */ + documentId: Corti.Uuid; +} diff --git a/src/api/resources/documents/client/requests/DocumentsGetRequest.ts b/src/api/resources/documents/client/requests/DocumentsGetRequest.ts new file mode 100644 index 00000000..b90892f4 --- /dev/null +++ b/src/api/resources/documents/client/requests/DocumentsGetRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * documentId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface DocumentsGetRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** The document ID representing the context for the request. Must be a valid UUID. */ + documentId: Corti.Uuid; +} diff --git a/src/api/resources/documents/client/requests/DocumentsListRequest.ts b/src/api/resources/documents/client/requests/DocumentsListRequest.ts new file mode 100644 index 00000000..ea2f4212 --- /dev/null +++ b/src/api/resources/documents/client/requests/DocumentsListRequest.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface DocumentsListRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; +} diff --git a/src/api/resources/documents/client/requests/DocumentsUpdateRequest.ts b/src/api/resources/documents/client/requests/DocumentsUpdateRequest.ts index c3836133..8345b9bb 100644 --- a/src/api/resources/documents/client/requests/DocumentsUpdateRequest.ts +++ b/src/api/resources/documents/client/requests/DocumentsUpdateRequest.ts @@ -1,14 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example - * {} + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * documentId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } */ export interface DocumentsUpdateRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** The document ID representing the context for the request. Must be a valid UUID. */ + documentId: Corti.Uuid; /** An optional name for the document. */ name?: string; sections?: Corti.DocumentsSectionInput[]; diff --git a/src/api/resources/documents/client/requests/index.ts b/src/api/resources/documents/client/requests/index.ts index 3a81e0fb..1f9f05f3 100644 --- a/src/api/resources/documents/client/requests/index.ts +++ b/src/api/resources/documents/client/requests/index.ts @@ -1 +1,5 @@ -export { type DocumentsUpdateRequest } from "./DocumentsUpdateRequest.js"; +export type { DocumentsCreateRequest } from "./DocumentsCreateRequest.js"; +export type { DocumentsDeleteRequest } from "./DocumentsDeleteRequest.js"; +export type { DocumentsGetRequest } from "./DocumentsGetRequest.js"; +export type { DocumentsListRequest } from "./DocumentsListRequest.js"; +export type { DocumentsUpdateRequest } from "./DocumentsUpdateRequest.js"; diff --git a/src/api/resources/facts/client/Client.ts b/src/api/resources/facts/client/Client.ts index d023b2ad..f2b39f5d 100644 --- a/src/api/resources/facts/client/Client.ts +++ b/src/api/resources/facts/client/Client.ts @@ -1,51 +1,31 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; -import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; -import * as serializers from "../../../../serialization/index.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; import * as errors from "../../../../errors/index.js"; +import * as serializers from "../../../../serialization/index.js"; +import * as Corti from "../../../index.js"; -export declare namespace Facts { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace FactsClient { + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } -export class Facts { - protected readonly _options: Facts.Options; +export class FactsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; - constructor(_options: Facts.Options) { - this._options = _options; + constructor(options: FactsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } /** * Returns a list of available fact groups, used to categorize facts associated with an interaction. * - * @param {Facts.RequestOptions} requestOptions - Request-specific configuration. + * @param {FactsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.InternalServerError} * @@ -53,14 +33,21 @@ export class Facts { * await client.facts.factGroupsList() */ public factGroupsList( - requestOptions?: Facts.RequestOptions, + requestOptions?: FactsClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__factGroupsList(requestOptions)); } private async __factGroupsList( - requestOptions?: Facts.RequestOptions, + requestOptions?: FactsClient.RequestOptions, ): Promise> { + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -68,17 +55,13 @@ export class Facts { "factgroups/", ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -115,63 +98,55 @@ export class Facts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /factgroups/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/factgroups/"); } /** * Retrieves a list of facts for a given interaction. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Facts.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.FactsListRequest} request + * @param {FactsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.facts.list("f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.facts.list({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public list( - id: Corti.Uuid, - requestOptions?: Facts.RequestOptions, + request: Corti.FactsListRequest, + requestOptions?: FactsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__list(id, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); } private async __list( - id: Corti.Uuid, - requestOptions?: Facts.RequestOptions, + request: Corti.FactsListRequest, + requestOptions?: FactsClient.RequestOptions, ): Promise> { + const { id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -208,34 +183,20 @@ export class Facts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /interactions/{id}/facts/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/interactions/{id}/facts/"); } /** * Adds new facts to an interaction. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. * @param {Corti.FactsCreateRequest} request - * @param {Facts.RequestOptions} requestOptions - Request-specific configuration. + * @param {FactsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.facts.create("f47ac10b-58cc-4372-a567-0e02b2c3d479", { + * await client.facts.create({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", * facts: [{ * text: "text", * group: "other" @@ -243,42 +204,44 @@ export class Facts { * }) */ public create( - id: Corti.Uuid, request: Corti.FactsCreateRequest, - requestOptions?: Facts.RequestOptions, + requestOptions?: FactsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__create(id, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__create(request, requestOptions)); } private async __create( - id: Corti.Uuid, request: Corti.FactsCreateRequest, - requestOptions?: Facts.RequestOptions, + requestOptions?: FactsClient.RequestOptions, ): Promise> { + const { id, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/`, ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", - body: serializers.FactsCreateRequest.jsonOrThrow(request, { + body: serializers.FactsCreateRequest.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -315,76 +278,64 @@ export class Facts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling POST /interactions/{id}/facts/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/interactions/{id}/facts/"); } /** * Updates multiple facts associated with an interaction. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. * @param {Corti.FactsBatchUpdateRequest} request - * @param {Facts.RequestOptions} requestOptions - Request-specific configuration. + * @param {FactsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.facts.batchUpdate("f47ac10b-58cc-4372-a567-0e02b2c3d479", { + * await client.facts.batchUpdate({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", * facts: [{ * factId: "3c9d8a12-7f44-4b3e-9e6f-9271c2bbfa08" * }] * }) */ public batchUpdate( - id: Corti.Uuid, request: Corti.FactsBatchUpdateRequest, - requestOptions?: Facts.RequestOptions, + requestOptions?: FactsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__batchUpdate(id, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__batchUpdate(request, requestOptions)); } private async __batchUpdate( - id: Corti.Uuid, request: Corti.FactsBatchUpdateRequest, - requestOptions?: Facts.RequestOptions, + requestOptions?: FactsClient.RequestOptions, ): Promise> { + const { id, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/`, ), method: "PATCH", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", - body: serializers.FactsBatchUpdateRequest.jsonOrThrow(request, { + body: serializers.FactsBatchUpdateRequest.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -421,75 +372,62 @@ export class Facts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling PATCH /interactions/{id}/facts/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/interactions/{id}/facts/"); } /** * Updates an existing fact associated with a specific interaction. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {string} factId - The unique identifier of the fact to update. Must be a valid UUID. * @param {Corti.FactsUpdateRequest} request - * @param {Facts.RequestOptions} requestOptions - Request-specific configuration. + * @param {FactsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.facts.update("f47ac10b-58cc-4372-a567-0e02b2c3d479", "3c9d8a12-7f44-4b3e-9e6f-9271c2bbfa08") + * await client.facts.update({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * factId: "3c9d8a12-7f44-4b3e-9e6f-9271c2bbfa08" + * }) */ public update( - id: Corti.Uuid, - factId: string, - request: Corti.FactsUpdateRequest = {}, - requestOptions?: Facts.RequestOptions, + request: Corti.FactsUpdateRequest, + requestOptions?: FactsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__update(id, factId, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__update(request, requestOptions)); } private async __update( - id: Corti.Uuid, - factId: string, - request: Corti.FactsUpdateRequest = {}, - requestOptions?: Facts.RequestOptions, + request: Corti.FactsUpdateRequest, + requestOptions?: FactsClient.RequestOptions, ): Promise> { + const { id, factId, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/${encodeURIComponent(factId)}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/facts/${core.url.encodePathParam(factId)}`, ), method: "PATCH", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", - body: serializers.FactsUpdateRequest.jsonOrThrow(request, { + body: serializers.FactsUpdateRequest.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -526,30 +464,19 @@ export class Facts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling PATCH /interactions/{id}/facts/{factId}.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "PATCH", + "/interactions/{id}/facts/{factId}", + ); } /** * Extract facts from provided text, without storing them. * * @param {Corti.FactsExtractRequest} request - * @param {Facts.RequestOptions} requestOptions - Request-specific configuration. + * @param {FactsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.GatewayTimeoutError} * @@ -564,15 +491,22 @@ export class Facts { */ public extract( request: Corti.FactsExtractRequest, - requestOptions?: Facts.RequestOptions, + requestOptions?: FactsClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__extract(request, requestOptions)); } private async __extract( request: Corti.FactsExtractRequest, - requestOptions?: Facts.RequestOptions, + requestOptions?: FactsClient.RequestOptions, ): Promise> { + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -580,23 +514,19 @@ export class Facts { "tools/extract-facts", ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", body: serializers.FactsExtractRequest.jsonOrThrow(request, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -633,29 +563,6 @@ export class Facts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling POST /tools/extract-facts."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; + return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/tools/extract-facts"); } } diff --git a/src/api/resources/facts/client/index.ts b/src/api/resources/facts/client/index.ts index 82648c6f..195f9aa8 100644 --- a/src/api/resources/facts/client/index.ts +++ b/src/api/resources/facts/client/index.ts @@ -1,2 +1 @@ -export {}; export * from "./requests/index.js"; diff --git a/src/api/resources/facts/client/requests/FactsBatchUpdateRequest.ts b/src/api/resources/facts/client/requests/FactsBatchUpdateRequest.ts index 4e1d1097..3b140ea4 100644 --- a/src/api/resources/facts/client/requests/FactsBatchUpdateRequest.ts +++ b/src/api/resources/facts/client/requests/FactsBatchUpdateRequest.ts @@ -1,18 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", * facts: [{ * factId: "3c9d8a12-7f44-4b3e-9e6f-9271c2bbfa08" * }] * } */ export interface FactsBatchUpdateRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; /** A list of facts to be updated. */ facts: Corti.FactsBatchUpdateInput[]; } diff --git a/src/api/resources/facts/client/requests/FactsCreateRequest.ts b/src/api/resources/facts/client/requests/FactsCreateRequest.ts index 0d77d7fa..6ce13b93 100644 --- a/src/api/resources/facts/client/requests/FactsCreateRequest.ts +++ b/src/api/resources/facts/client/requests/FactsCreateRequest.ts @@ -1,12 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", * facts: [{ * text: "text", * group: "other" @@ -14,6 +13,8 @@ import * as Corti from "../../../../index.js"; * } */ export interface FactsCreateRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; /** A list of facts to be created. */ facts: Corti.FactsCreateInput[]; } diff --git a/src/api/resources/facts/client/requests/FactsExtractRequest.ts b/src/api/resources/facts/client/requests/FactsExtractRequest.ts index 29bc6cb4..f20eeec9 100644 --- a/src/api/resources/facts/client/requests/FactsExtractRequest.ts +++ b/src/api/resources/facts/client/requests/FactsExtractRequest.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example diff --git a/src/api/resources/facts/client/requests/FactsListRequest.ts b/src/api/resources/facts/client/requests/FactsListRequest.ts new file mode 100644 index 00000000..4b67a8c0 --- /dev/null +++ b/src/api/resources/facts/client/requests/FactsListRequest.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface FactsListRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; +} diff --git a/src/api/resources/facts/client/requests/FactsUpdateRequest.ts b/src/api/resources/facts/client/requests/FactsUpdateRequest.ts index 63196a68..16d7d076 100644 --- a/src/api/resources/facts/client/requests/FactsUpdateRequest.ts +++ b/src/api/resources/facts/client/requests/FactsUpdateRequest.ts @@ -1,14 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example - * {} + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * factId: "3c9d8a12-7f44-4b3e-9e6f-9271c2bbfa08" + * } */ export interface FactsUpdateRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** The unique identifier of the fact to update. Must be a valid UUID. */ + factId: string; /** The updated text of the fact. */ text?: string; /** The updated group key for the fact. */ diff --git a/src/api/resources/facts/client/requests/index.ts b/src/api/resources/facts/client/requests/index.ts index f6557284..04579c97 100644 --- a/src/api/resources/facts/client/requests/index.ts +++ b/src/api/resources/facts/client/requests/index.ts @@ -1,4 +1,5 @@ -export { type FactsCreateRequest } from "./FactsCreateRequest.js"; -export { type FactsBatchUpdateRequest } from "./FactsBatchUpdateRequest.js"; -export { type FactsUpdateRequest } from "./FactsUpdateRequest.js"; -export { type FactsExtractRequest } from "./FactsExtractRequest.js"; +export type { FactsBatchUpdateRequest } from "./FactsBatchUpdateRequest.js"; +export type { FactsCreateRequest } from "./FactsCreateRequest.js"; +export type { FactsExtractRequest } from "./FactsExtractRequest.js"; +export type { FactsListRequest } from "./FactsListRequest.js"; +export type { FactsUpdateRequest } from "./FactsUpdateRequest.js"; diff --git a/src/api/resources/index.ts b/src/api/resources/index.ts index 12628de3..cc75b8f5 100644 --- a/src/api/resources/index.ts +++ b/src/api/resources/index.ts @@ -1,22 +1,23 @@ -export * as interactions from "./interactions/index.js"; -export * from "./interactions/types/index.js"; -export * as auth from "./auth/index.js"; -export * from "./auth/types/index.js"; +export * from "./agents/client/requests/index.js"; export * as agents from "./agents/index.js"; export * from "./agents/types/index.js"; -export * as stream from "./stream/index.js"; -export * as transcribe from "./transcribe/index.js"; -export * as recordings from "./recordings/index.js"; -export * as transcripts from "./transcripts/index.js"; -export * as facts from "./facts/index.js"; -export * as documents from "./documents/index.js"; -export * as templates from "./templates/index.js"; +export * from "./auth/client/requests/index.js"; +export * as auth from "./auth/index.js"; +export * from "./auth/types/index.js"; +export * from "./codes/client/requests/index.js"; export * as codes from "./codes/index.js"; -export * from "./interactions/client/requests/index.js"; -export * from "./transcripts/client/requests/index.js"; -export * from "./facts/client/requests/index.js"; export * from "./documents/client/requests/index.js"; +export * as documents from "./documents/index.js"; +export * from "./facts/client/requests/index.js"; +export * as facts from "./facts/index.js"; +export * from "./interactions/client/requests/index.js"; +export * as interactions from "./interactions/index.js"; +export * from "./interactions/types/index.js"; +export * from "./recordings/client/requests/index.js"; +export * as recordings from "./recordings/index.js"; +export * as stream from "./stream/index.js"; export * from "./templates/client/requests/index.js"; -export * from "./codes/client/requests/index.js"; -export * from "./auth/client/requests/index.js"; -export * from "./agents/client/requests/index.js"; +export * as templates from "./templates/index.js"; +export * as transcribe from "./transcribe/index.js"; +export * from "./transcripts/client/requests/index.js"; +export * as transcripts from "./transcripts/index.js"; diff --git a/src/api/resources/interactions/client/Client.ts b/src/api/resources/interactions/client/Client.ts index 8cb2d2d7..2bd95b2d 100644 --- a/src/api/resources/interactions/client/Client.ts +++ b/src/api/resources/interactions/client/Client.ts @@ -1,52 +1,32 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; -import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; -import * as serializers from "../../../../serialization/index.js"; +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; import * as errors from "../../../../errors/index.js"; +import * as serializers from "../../../../serialization/index.js"; +import * as Corti from "../../../index.js"; -export declare namespace Interactions { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace InteractionsClient { + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } -export class Interactions { - protected readonly _options: Interactions.Options; +export class InteractionsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; - constructor(_options: Interactions.Options) { - this._options = _options; + constructor(options: InteractionsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } /** * Lists all existing interactions. Results can be filtered by encounter status and patient identifier. * * @param {Corti.InteractionsListRequest} request - * @param {Interactions.RequestOptions} requestOptions - Request-specific configuration. + * @param {InteractionsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.ForbiddenError} * @throws {@link Corti.GatewayTimeoutError} @@ -56,50 +36,52 @@ export class Interactions { */ public async list( request: Corti.InteractionsListRequest = {}, - requestOptions?: Interactions.RequestOptions, - ): Promise> { + requestOptions?: InteractionsClient.RequestOptions, + ): Promise> { const list = core.HttpResponsePromise.interceptFunction( async ( request: Corti.InteractionsListRequest, ): Promise> => { const { sort, direction, pageSize, index, encounterStatus, patient } = request; - const _queryParams: Record = {}; - if (sort !== undefined) { - _queryParams["sort"] = serializers.InteractionsListRequestSort.jsonOrThrow(sort, { - unrecognizedObjectKeys: "strip", - omitUndefined: true, - }); - } - if (direction !== undefined) { - _queryParams["direction"] = serializers.CommonSortingDirectionEnum.jsonOrThrow(direction, { - unrecognizedObjectKeys: "strip", - omitUndefined: true, - }); - } - if (pageSize !== undefined) { - _queryParams["pageSize"] = pageSize?.toString() ?? null; - } - if (index !== undefined) { - _queryParams["index"] = index?.toString() ?? null; - } - if (encounterStatus != null) { - if (Array.isArray(encounterStatus)) { - _queryParams["encounterStatus"] = encounterStatus.map((item) => - serializers.InteractionsEncounterStatusEnum.jsonOrThrow(item, { + const _queryParams: Record = { + sort: + sort != null + ? serializers.InteractionsListRequestSort.jsonOrThrow(sort, { + unrecognizedObjectKeys: "strip", + omitUndefined: true, + }) + : undefined, + direction: + direction != null + ? serializers.CommonSortingDirectionEnum.jsonOrThrow(direction, { + unrecognizedObjectKeys: "strip", + omitUndefined: true, + }) + : undefined, + pageSize, + index, + encounterStatus: Array.isArray(encounterStatus) + ? encounterStatus.map((item) => + serializers.InteractionsEncounterStatusEnum.jsonOrThrow(item, { + unrecognizedObjectKeys: "strip", + omitUndefined: true, + }), + ) + : encounterStatus != null + ? serializers.InteractionsEncounterStatusEnum.jsonOrThrow(encounterStatus, { unrecognizedObjectKeys: "strip", omitUndefined: true, - }), - ); - } else { - _queryParams["encounterStatus"] = serializers.InteractionsEncounterStatusEnum.jsonOrThrow( - encounterStatus, - { unrecognizedObjectKeys: "strip", omitUndefined: true }, - ); - } - } - if (patient !== undefined) { - _queryParams["patient"] = patient; - } + }) + : undefined, + patient, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -107,19 +89,13 @@ export class Interactions { "interactions/", ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - queryParameters: _queryParams, - timeoutMs: - requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -165,26 +141,12 @@ export class Interactions { }); } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /interactions/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/interactions/"); }, ); let _offset = request?.index != null ? request?.index : 1; const dataWithRawResponse = await list(request).withRawResponse(); - return new core.Pageable({ + return new core.Page({ response: dataWithRawResponse.data, rawResponse: dataWithRawResponse.rawResponse, hasNextPage: (response) => (response?.interactions ?? []).length > 0, @@ -200,7 +162,7 @@ export class Interactions { * Creates a new interaction. * * @param {Corti.InteractionsCreateRequest} request - * @param {Interactions.RequestOptions} requestOptions - Request-specific configuration. + * @param {InteractionsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.ForbiddenError} @@ -218,15 +180,22 @@ export class Interactions { */ public create( request: Corti.InteractionsCreateRequest, - requestOptions?: Interactions.RequestOptions, + requestOptions?: InteractionsClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__create(request, requestOptions)); } private async __create( request: Corti.InteractionsCreateRequest, - requestOptions?: Interactions.RequestOptions, + requestOptions?: InteractionsClient.RequestOptions, ): Promise> { + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -234,23 +203,19 @@ export class Interactions { "interactions/", ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", body: serializers.InteractionsCreateRequest.jsonOrThrow(request, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -311,64 +276,56 @@ export class Interactions { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling POST /interactions/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/interactions/"); } /** * Retrieves a previously recorded interaction by its unique identifier (interaction ID). * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Interactions.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.InteractionsGetRequest} request + * @param {InteractionsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.ForbiddenError} * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.interactions.get("f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.interactions.get({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public get( - id: Corti.Uuid, - requestOptions?: Interactions.RequestOptions, + request: Corti.InteractionsGetRequest, + requestOptions?: InteractionsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__get(id, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); } private async __get( - id: Corti.Uuid, - requestOptions?: Interactions.RequestOptions, + request: Corti.InteractionsGetRequest, + requestOptions?: InteractionsClient.RequestOptions, ): Promise> { + const { id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -416,61 +373,56 @@ export class Interactions { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /interactions/{id}."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/interactions/{id}"); } /** * Deletes an existing interaction. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Interactions.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.InteractionsDeleteRequest} request + * @param {InteractionsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.ForbiddenError} * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.interactions.delete("f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.interactions.delete({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ - public delete(id: Corti.Uuid, requestOptions?: Interactions.RequestOptions): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__delete(id, requestOptions)); + public delete( + request: Corti.InteractionsDeleteRequest, + requestOptions?: InteractionsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(request, requestOptions)); } private async __delete( - id: Corti.Uuid, - requestOptions?: Interactions.RequestOptions, + request: Corti.InteractionsDeleteRequest, + requestOptions?: InteractionsClient.RequestOptions, ): Promise> { + const { id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}`, ), method: "DELETE", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { data: undefined, rawResponse: _response.rawResponse }; @@ -509,73 +461,62 @@ export class Interactions { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling DELETE /interactions/{id}."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/interactions/{id}"); } /** * Modifies an existing interaction by updating specific fields without overwriting the entire record. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. * @param {Corti.InteractionsUpdateRequest} request - * @param {Interactions.RequestOptions} requestOptions - Request-specific configuration. + * @param {InteractionsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.ForbiddenError} * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.interactions.update("f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.interactions.update({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public update( - id: Corti.Uuid, - request: Corti.InteractionsUpdateRequest = {}, - requestOptions?: Interactions.RequestOptions, + request: Corti.InteractionsUpdateRequest, + requestOptions?: InteractionsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__update(id, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__update(request, requestOptions)); } private async __update( - id: Corti.Uuid, - request: Corti.InteractionsUpdateRequest = {}, - requestOptions?: Interactions.RequestOptions, + request: Corti.InteractionsUpdateRequest, + requestOptions?: InteractionsClient.RequestOptions, ): Promise> { + const { id, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}`, ), method: "PATCH", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", - body: serializers.InteractionsUpdateRequest.jsonOrThrow(request, { + body: serializers.InteractionsUpdateRequest.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -623,29 +564,6 @@ export class Interactions { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling PATCH /interactions/{id}."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; + return handleNonStatusCodeError(_response.error, _response.rawResponse, "PATCH", "/interactions/{id}"); } } diff --git a/src/api/resources/interactions/client/index.ts b/src/api/resources/interactions/client/index.ts index 82648c6f..195f9aa8 100644 --- a/src/api/resources/interactions/client/index.ts +++ b/src/api/resources/interactions/client/index.ts @@ -1,2 +1 @@ -export {}; export * from "./requests/index.js"; diff --git a/src/api/resources/interactions/client/requests/InteractionsCreateRequest.ts b/src/api/resources/interactions/client/requests/InteractionsCreateRequest.ts index deea4b43..4840bd7f 100644 --- a/src/api/resources/interactions/client/requests/InteractionsCreateRequest.ts +++ b/src/api/resources/interactions/client/requests/InteractionsCreateRequest.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example diff --git a/src/api/resources/interactions/client/requests/InteractionsDeleteRequest.ts b/src/api/resources/interactions/client/requests/InteractionsDeleteRequest.ts new file mode 100644 index 00000000..95492f1b --- /dev/null +++ b/src/api/resources/interactions/client/requests/InteractionsDeleteRequest.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface InteractionsDeleteRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; +} diff --git a/src/api/resources/interactions/client/requests/InteractionsGetRequest.ts b/src/api/resources/interactions/client/requests/InteractionsGetRequest.ts new file mode 100644 index 00000000..8ac2350f --- /dev/null +++ b/src/api/resources/interactions/client/requests/InteractionsGetRequest.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface InteractionsGetRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; +} diff --git a/src/api/resources/interactions/client/requests/InteractionsListRequest.ts b/src/api/resources/interactions/client/requests/InteractionsListRequest.ts index c06164fc..d91d520e 100644 --- a/src/api/resources/interactions/client/requests/InteractionsListRequest.ts +++ b/src/api/resources/interactions/client/requests/InteractionsListRequest.ts @@ -1,36 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example * {} */ export interface InteractionsListRequest { - /** - * Field used to sort interactions. Default is createdAt. - */ - sort?: Corti.InteractionsListRequestSort | null; - /** - * Sorting order. Allowed values: [asc, desc]. Default is desc. - */ - direction?: Corti.CommonSortingDirectionEnum | null; - /** - * Number of interactions to return per page. Must be greater than 0. Default is 10. - */ - pageSize?: number | null; - /** - * Page number to retrieve. Starts at 1. For example, index=2 with pageSize=10 will return interactions 11–20. Must be greater than 0. Default is 1. - */ - index?: number | null; - /** - * The status of the encounter. To filter on multiple statuses, pass the same parameter again. - */ + /** Field used to sort interactions. Default is createdAt. */ + sort?: Corti.InteractionsListRequestSort; + /** Sorting order. Allowed values: [asc, desc]. Default is desc. */ + direction?: Corti.CommonSortingDirectionEnum; + /** Number of interactions to return per page. Must be greater than 0. Default is 10. */ + pageSize?: number; + /** Page number to retrieve. Starts at 1. For example, index=2 with pageSize=10 will return interactions 11–20. Must be greater than 0. Default is 1. */ + index?: number; + /** The status of the encounter. To filter on multiple statuses, pass the same parameter again. */ encounterStatus?: Corti.InteractionsEncounterStatusEnum | Corti.InteractionsEncounterStatusEnum[]; - /** - * A unique identifier for the patient. - */ - patient?: string | null; + /** A unique identifier for the patient. */ + patient?: string; } diff --git a/src/api/resources/interactions/client/requests/InteractionsUpdateRequest.ts b/src/api/resources/interactions/client/requests/InteractionsUpdateRequest.ts index cff15102..6f0f7371 100644 --- a/src/api/resources/interactions/client/requests/InteractionsUpdateRequest.ts +++ b/src/api/resources/interactions/client/requests/InteractionsUpdateRequest.ts @@ -1,14 +1,16 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example - * {} + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } */ export interface InteractionsUpdateRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; /** The unique identifier of the medical professional responsible for this interaction. If nulled, automatically set to a uuid. */ assignedUserId?: Corti.Uuid; /** Details of the encounter being updated. */ diff --git a/src/api/resources/interactions/client/requests/index.ts b/src/api/resources/interactions/client/requests/index.ts index 1a6b0840..6b6ba9fe 100644 --- a/src/api/resources/interactions/client/requests/index.ts +++ b/src/api/resources/interactions/client/requests/index.ts @@ -1,3 +1,5 @@ -export { type InteractionsListRequest } from "./InteractionsListRequest.js"; -export { type InteractionsCreateRequest } from "./InteractionsCreateRequest.js"; -export { type InteractionsUpdateRequest } from "./InteractionsUpdateRequest.js"; +export type { InteractionsCreateRequest } from "./InteractionsCreateRequest.js"; +export type { InteractionsDeleteRequest } from "./InteractionsDeleteRequest.js"; +export type { InteractionsGetRequest } from "./InteractionsGetRequest.js"; +export type { InteractionsListRequest } from "./InteractionsListRequest.js"; +export type { InteractionsUpdateRequest } from "./InteractionsUpdateRequest.js"; diff --git a/src/api/resources/interactions/index.ts b/src/api/resources/interactions/index.ts index f095e147..d9adb1af 100644 --- a/src/api/resources/interactions/index.ts +++ b/src/api/resources/interactions/index.ts @@ -1,2 +1,2 @@ -export * from "./types/index.js"; export * from "./client/index.js"; +export * from "./types/index.js"; diff --git a/src/api/resources/interactions/types/InteractionsListRequestSort.ts b/src/api/resources/interactions/types/InteractionsListRequestSort.ts index 563c04f4..9a7f4db1 100644 --- a/src/api/resources/interactions/types/InteractionsListRequestSort.ts +++ b/src/api/resources/interactions/types/InteractionsListRequestSort.ts @@ -1,11 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Field used to sort interactions. Default is createdAt. - */ -export type InteractionsListRequestSort = "id" | "assignedUserId" | "patient" | "createdAt" | "endedAt" | "updatedAt"; +/** Field used to sort interactions. Default is createdAt. */ export const InteractionsListRequestSort = { Id: "id", AssignedUserId: "assignedUserId", @@ -14,3 +9,5 @@ export const InteractionsListRequestSort = { EndedAt: "endedAt", UpdatedAt: "updatedAt", } as const; +export type InteractionsListRequestSort = + (typeof InteractionsListRequestSort)[keyof typeof InteractionsListRequestSort]; diff --git a/src/api/resources/recordings/client/Client.ts b/src/api/resources/recordings/client/Client.ts index 72570e63..27a80a14 100644 --- a/src/api/resources/recordings/client/Client.ts +++ b/src/api/resources/recordings/client/Client.ts @@ -1,52 +1,32 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; -import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; -import * as serializers from "../../../../serialization/index.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; import * as errors from "../../../../errors/index.js"; +import * as serializers from "../../../../serialization/index.js"; +import * as Corti from "../../../index.js"; -export declare namespace Recordings { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace RecordingsClient { + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } -export class Recordings { - protected readonly _options: Recordings.Options; +export class RecordingsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; - constructor(_options: Recordings.Options) { - this._options = _options; + constructor(options: RecordingsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } /** * Retrieve a list of recordings for a given interaction. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Recordings.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.RecordingsListRequest} request + * @param {RecordingsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.ForbiddenError} @@ -54,37 +34,43 @@ export class Recordings { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.recordings.list("f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.recordings.list({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public list( - id: Corti.Uuid, - requestOptions?: Recordings.RequestOptions, + request: Corti.RecordingsListRequest, + requestOptions?: RecordingsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__list(id, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); } private async __list( - id: Corti.Uuid, - requestOptions?: Recordings.RequestOptions, + request: Corti.RecordingsListRequest, + requestOptions?: RecordingsClient.RequestOptions, ): Promise> { + const { id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -145,21 +131,12 @@ export class Recordings { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /interactions/{id}/recordings/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/interactions/{id}/recordings/", + ); } /** @@ -167,7 +144,7 @@ export class Recordings { * * @param {core.file.Uploadable} uploadable * @param {Corti.Uuid} id - * @param {Recordings.RequestOptions} requestOptions - Request-specific configuration. + * @param {RecordingsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.ForbiddenError} @@ -177,7 +154,7 @@ export class Recordings { public upload( uploadable: core.file.Uploadable, id: Corti.Uuid, - requestOptions?: Recordings.RequestOptions, + requestOptions?: RecordingsClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__upload(uploadable, id, requestOptions)); } @@ -185,32 +162,35 @@ export class Recordings { private async __upload( uploadable: core.file.Uploadable, id: Corti.Uuid, - requestOptions?: Recordings.RequestOptions, + requestOptions?: RecordingsClient.RequestOptions, ): Promise> { const _binaryUploadRequest = await core.file.toBinaryUploadRequest(uploadable); + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + _binaryUploadRequest.headers, + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/`, ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - _binaryUploadRequest.headers, - requestOptions?.headers, - ), + headers: _headers, contentType: "application/octet-stream", + queryParameters: requestOptions?.queryParams, requestType: "bytes", duplex: "half", body: _binaryUploadRequest.body, - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -271,23 +251,12 @@ export class Recordings { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling POST /interactions/{id}/recordings/.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/interactions/{id}/recordings/", + ); } /** @@ -299,37 +268,39 @@ export class Recordings { * @throws {@link Corti.GatewayTimeoutError} */ public get( - id: Corti.Uuid, - recordingId: Corti.Uuid, - requestOptions?: Recordings.RequestOptions, + request: Corti.RecordingsGetRequest, + requestOptions?: RecordingsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__get(id, recordingId, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); } private async __get( - id: Corti.Uuid, - recordingId: Corti.Uuid, - requestOptions?: Recordings.RequestOptions, + request: Corti.RecordingsGetRequest, + requestOptions?: RecordingsClient.RequestOptions, ): Promise> { + const { id, recordingId } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/${encodeURIComponent(serializers.Uuid.jsonOrThrow(recordingId, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(recordingId, { omitUndefined: true }))}`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, + queryParameters: requestOptions?.queryParams, responseType: "binary-response", - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { data: _response.body, rawResponse: _response.rawResponse }; @@ -383,31 +354,19 @@ export class Recordings { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling GET /interactions/{id}/recordings/{recordingId}.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/interactions/{id}/recordings/{recordingId}", + ); } /** * Delete a specific recording for a given interaction. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Corti.Uuid} recordingId - The unique identifier of the recording. Must be a valid UUID. - * @param {Recordings.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.RecordingsDeleteRequest} request + * @param {RecordingsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.ForbiddenError} * @throws {@link Corti.NotFoundError} @@ -415,39 +374,44 @@ export class Recordings { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.recordings.delete("f47ac10b-58cc-4372-a567-0e02b2c3d479", "f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.recordings.delete({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * recordingId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public delete( - id: Corti.Uuid, - recordingId: Corti.Uuid, - requestOptions?: Recordings.RequestOptions, + request: Corti.RecordingsDeleteRequest, + requestOptions?: RecordingsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__delete(id, recordingId, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__delete(request, requestOptions)); } private async __delete( - id: Corti.Uuid, - recordingId: Corti.Uuid, - requestOptions?: Recordings.RequestOptions, + request: Corti.RecordingsDeleteRequest, + requestOptions?: RecordingsClient.RequestOptions, ): Promise> { + const { id, recordingId } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/${encodeURIComponent(serializers.Uuid.jsonOrThrow(recordingId, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/recordings/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(recordingId, { omitUndefined: true }))}`, ), method: "DELETE", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { data: undefined, rawResponse: _response.rawResponse }; @@ -499,31 +463,11 @@ export class Recordings { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling DELETE /interactions/{id}/recordings/{recordingId}.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "DELETE", + "/interactions/{id}/recordings/{recordingId}", + ); } } diff --git a/src/api/resources/recordings/client/index.ts b/src/api/resources/recordings/client/index.ts index cb0ff5c3..195f9aa8 100644 --- a/src/api/resources/recordings/client/index.ts +++ b/src/api/resources/recordings/client/index.ts @@ -1 +1 @@ -export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/recordings/client/requests/RecordingsDeleteRequest.ts b/src/api/resources/recordings/client/requests/RecordingsDeleteRequest.ts new file mode 100644 index 00000000..664bac9c --- /dev/null +++ b/src/api/resources/recordings/client/requests/RecordingsDeleteRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * recordingId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface RecordingsDeleteRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** The unique identifier of the recording. Must be a valid UUID. */ + recordingId: Corti.Uuid; +} diff --git a/src/api/resources/recordings/client/requests/RecordingsGetRequest.ts b/src/api/resources/recordings/client/requests/RecordingsGetRequest.ts new file mode 100644 index 00000000..84afc75a --- /dev/null +++ b/src/api/resources/recordings/client/requests/RecordingsGetRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "id", + * recordingId: "recordingId" + * } + */ +export interface RecordingsGetRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** The unique identifier of the recording. Must be a valid UUID. */ + recordingId: Corti.Uuid; +} diff --git a/src/api/resources/recordings/client/requests/RecordingsListRequest.ts b/src/api/resources/recordings/client/requests/RecordingsListRequest.ts new file mode 100644 index 00000000..d1718d3e --- /dev/null +++ b/src/api/resources/recordings/client/requests/RecordingsListRequest.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface RecordingsListRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; +} diff --git a/src/api/resources/recordings/client/requests/index.ts b/src/api/resources/recordings/client/requests/index.ts new file mode 100644 index 00000000..4252facd --- /dev/null +++ b/src/api/resources/recordings/client/requests/index.ts @@ -0,0 +1,3 @@ +export type { RecordingsDeleteRequest } from "./RecordingsDeleteRequest.js"; +export type { RecordingsGetRequest } from "./RecordingsGetRequest.js"; +export type { RecordingsListRequest } from "./RecordingsListRequest.js"; diff --git a/src/api/resources/stream/client/Client.ts b/src/api/resources/stream/client/Client.ts index ab27d87b..97ff899c 100644 --- a/src/api/resources/stream/client/Client.ts +++ b/src/api/resources/stream/client/Client.ts @@ -1,27 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; +import type { BaseClientOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptions, normalizeClientOptions } from "../../../../BaseClient.js"; import * as core from "../../../../core/index.js"; import { StreamSocket } from "./Socket.js"; -export declare namespace Stream { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace StreamClient { + export type Options = BaseClientOptions; export interface ConnectArgs { id: string; tenantName: string; token: string; + /** Additional query parameters to send with the websocket connect request. */ + queryParams?: Record; /** Arbitrary headers to send with the websocket connect request. */ headers?: Record; /** Enable debug mode on the websocket. Defaults to false. */ @@ -31,41 +23,31 @@ export declare namespace Stream { } } -export class Stream { - protected readonly _options: Stream.Options; +export class StreamClient { + protected readonly _options: NormalizedClientOptions; - constructor(_options: Stream.Options) { - this._options = _options; + constructor(options: StreamClient.Options) { + this._options = normalizeClientOptions(options); } - public async connect(args: Stream.ConnectArgs): Promise { - const { id, tenantName, token, headers, debug, reconnectAttempts } = args; - const _queryParams: Record = {}; - _queryParams["tenant-name"] = tenantName; - _queryParams["token"] = token; - let _headers: Record = { - ...headers, + public async connect(args: StreamClient.ConnectArgs): Promise { + const { id, tenantName, token, queryParams, headers, debug, reconnectAttempts } = args; + const _queryParams: Record = { + "tenant-name": tenantName, + token, }; + const _headers: Record = { ...headers }; const socket = new core.ReconnectingWebSocket({ url: core.url.join( - (await core.Supplier.get(this._options["baseUrl"])) ?? - (await core.Supplier.get(this._options["environment"])).wss, - `/interactions/${encodeURIComponent(id)}/streams`, + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)).wss, + `/interactions/${core.url.encodePathParam(id)}/streams`, ), protocols: [], - queryParameters: _queryParams, + queryParameters: { ..._queryParams, ...queryParams }, headers: _headers, options: { debug: debug ?? false, maxRetries: reconnectAttempts ?? 30 }, }); return new StreamSocket({ socket }); } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; - } } diff --git a/src/api/resources/stream/client/Socket.ts b/src/api/resources/stream/client/Socket.ts index 312e73fd..cb2d5711 100644 --- a/src/api/resources/stream/client/Socket.ts +++ b/src/api/resources/stream/client/Socket.ts @@ -1,14 +1,12 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; -import { StreamConfigMessage } from "../../../../serialization/types/StreamConfigMessage.js"; -import { StreamFlushMessage } from "../../../../serialization/types/StreamFlushMessage.js"; -import { StreamEndMessage } from "../../../../serialization/types/StreamEndMessage.js"; import { fromJson } from "../../../../core/json.js"; import * as serializers from "../../../../serialization/index.js"; +import { StreamConfigMessage } from "../../../../serialization/types/StreamConfigMessage.js"; +import { StreamEndMessage } from "../../../../serialization/types/StreamEndMessage.js"; +import { StreamFlushMessage } from "../../../../serialization/types/StreamFlushMessage.js"; +import type * as Corti from "../../../index.js"; export declare namespace StreamSocket { export interface Args { @@ -84,7 +82,7 @@ export class StreamSocket { * }); * ``` */ - public on(event: T, callback: StreamSocket.EventHandlers[T]) { + public on(event: T, callback: StreamSocket.EventHandlers[T]): void { this.eventHandlers[event] = callback; } @@ -100,18 +98,9 @@ export class StreamSocket { this.socket.send(JSON.stringify(jsonPayload)); } - public sendAudio(message: string): void { + public sendAudio(message: ArrayBufferLike | Blob | ArrayBufferView): void { this.assertSocketIsOpen(); - const jsonPayload = core.serialization - .string() - .jsonOrThrow(message, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - omitUndefined: true, - }); - this.socket.send(JSON.stringify(jsonPayload)); + this.sendBinary(message); } public sendFlush(message: Corti.StreamFlushMessage): void { diff --git a/src/api/resources/templates/client/Client.ts b/src/api/resources/templates/client/Client.ts index f3fbbfd8..5da18dd9 100644 --- a/src/api/resources/templates/client/Client.ts +++ b/src/api/resources/templates/client/Client.ts @@ -1,52 +1,32 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; -import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; -import * as serializers from "../../../../serialization/index.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; import * as errors from "../../../../errors/index.js"; +import * as serializers from "../../../../serialization/index.js"; +import * as Corti from "../../../index.js"; -export declare namespace Templates { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace TemplatesClient { + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } -export class Templates { - protected readonly _options: Templates.Options; +export class TemplatesClient { + protected readonly _options: NormalizedClientOptionsWithAuth; - constructor(_options: Templates.Options) { - this._options = _options; + constructor(options: TemplatesClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } /** * Retrieves a list of template sections with optional filters for organization and language. * * @param {Corti.TemplatesSectionListRequest} request - * @param {Templates.RequestOptions} requestOptions - Request-specific configuration. + * @param {TemplatesClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.InternalServerError} @@ -56,33 +36,27 @@ export class Templates { */ public sectionList( request: Corti.TemplatesSectionListRequest = {}, - requestOptions?: Templates.RequestOptions, + requestOptions?: TemplatesClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__sectionList(request, requestOptions)); } private async __sectionList( request: Corti.TemplatesSectionListRequest = {}, - requestOptions?: Templates.RequestOptions, + requestOptions?: TemplatesClient.RequestOptions, ): Promise> { const { org, lang } = request; - const _queryParams: Record = {}; - if (org != null) { - if (Array.isArray(org)) { - _queryParams["org"] = org.map((item) => item); - } else { - _queryParams["org"] = org; - } - } - - if (lang != null) { - if (Array.isArray(lang)) { - _queryParams["lang"] = lang.map((item) => item); - } else { - _queryParams["lang"] = lang; - } - } - + const _queryParams: Record = { + org, + lang, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -90,18 +64,13 @@ export class Templates { "templateSections/", ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - queryParameters: _queryParams, - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -140,28 +109,14 @@ export class Templates { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /templateSections/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/templateSections/"); } /** * Retrieves a list of templates with optional filters for organization, language, and status. * * @param {Corti.TemplatesListRequest} request - * @param {Templates.RequestOptions} requestOptions - Request-specific configuration. + * @param {TemplatesClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.InternalServerError} @@ -171,41 +126,28 @@ export class Templates { */ public list( request: Corti.TemplatesListRequest = {}, - requestOptions?: Templates.RequestOptions, + requestOptions?: TemplatesClient.RequestOptions, ): core.HttpResponsePromise { return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); } private async __list( request: Corti.TemplatesListRequest = {}, - requestOptions?: Templates.RequestOptions, + requestOptions?: TemplatesClient.RequestOptions, ): Promise> { const { org, lang, status } = request; - const _queryParams: Record = {}; - if (org != null) { - if (Array.isArray(org)) { - _queryParams["org"] = org.map((item) => item); - } else { - _queryParams["org"] = org; - } - } - - if (lang != null) { - if (Array.isArray(lang)) { - _queryParams["lang"] = lang.map((item) => item); - } else { - _queryParams["lang"] = lang; - } - } - - if (status != null) { - if (Array.isArray(status)) { - _queryParams["status"] = status.map((item) => item); - } else { - _queryParams["status"] = status; - } - } - + const _queryParams: Record = { + org, + lang, + status, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? @@ -213,18 +155,13 @@ export class Templates { "templates/", ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - queryParameters: _queryParams, - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -263,61 +200,56 @@ export class Templates { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /templates/."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/templates/"); } /** * Retrieves template by key. * - * @param {string} key - The key of the template - * @param {Templates.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.TemplatesGetRequest} request + * @param {TemplatesClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.UnauthorizedError} * @throws {@link Corti.InternalServerError} * * @example - * await client.templates.get("key") + * await client.templates.get({ + * key: "key" + * }) */ - public get(key: string, requestOptions?: Templates.RequestOptions): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__get(key, requestOptions)); + public get( + request: Corti.TemplatesGetRequest, + requestOptions?: TemplatesClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); } private async __get( - key: string, - requestOptions?: Templates.RequestOptions, + request: Corti.TemplatesGetRequest, + requestOptions?: TemplatesClient.RequestOptions, ): Promise> { + const { key } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `templates/${encodeURIComponent(key)}`, + `templates/${core.url.encodePathParam(key)}`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -356,29 +288,6 @@ export class Templates { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError("Timeout exceeded when calling GET /templates/{key}."); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/templates/{key}"); } } diff --git a/src/api/resources/templates/client/index.ts b/src/api/resources/templates/client/index.ts index 82648c6f..195f9aa8 100644 --- a/src/api/resources/templates/client/index.ts +++ b/src/api/resources/templates/client/index.ts @@ -1,2 +1 @@ -export {}; export * from "./requests/index.js"; diff --git a/src/api/resources/templates/client/requests/TemplatesGetRequest.ts b/src/api/resources/templates/client/requests/TemplatesGetRequest.ts new file mode 100644 index 00000000..ebe512a8 --- /dev/null +++ b/src/api/resources/templates/client/requests/TemplatesGetRequest.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * key: "key" + * } + */ +export interface TemplatesGetRequest { + /** The key of the template */ + key: string; +} diff --git a/src/api/resources/templates/client/requests/TemplatesListRequest.ts b/src/api/resources/templates/client/requests/TemplatesListRequest.ts index f2b8d6d1..abc1c28c 100644 --- a/src/api/resources/templates/client/requests/TemplatesListRequest.ts +++ b/src/api/resources/templates/client/requests/TemplatesListRequest.ts @@ -1,22 +1,14 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * @example * {} */ export interface TemplatesListRequest { - /** - * Filter templates by organization. - */ + /** Filter templates by organization. */ org?: string | string[]; - /** - * Filter templates by language. - */ + /** Filter templates by language. */ lang?: string | string[]; - /** - * Filter templates by their status. - */ + /** Filter templates by their status. */ status?: string | string[]; } diff --git a/src/api/resources/templates/client/requests/TemplatesSectionListRequest.ts b/src/api/resources/templates/client/requests/TemplatesSectionListRequest.ts index 891a3c2b..d0768d63 100644 --- a/src/api/resources/templates/client/requests/TemplatesSectionListRequest.ts +++ b/src/api/resources/templates/client/requests/TemplatesSectionListRequest.ts @@ -1,18 +1,12 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * @example * {} */ export interface TemplatesSectionListRequest { - /** - * Filter template sections by organization. - */ + /** Filter template sections by organization. */ org?: string | string[]; - /** - * Filter template sections by language. - */ + /** Filter template sections by language. */ lang?: string | string[]; } diff --git a/src/api/resources/templates/client/requests/index.ts b/src/api/resources/templates/client/requests/index.ts index 9a86ad52..df067ef1 100644 --- a/src/api/resources/templates/client/requests/index.ts +++ b/src/api/resources/templates/client/requests/index.ts @@ -1,2 +1,3 @@ -export { type TemplatesSectionListRequest } from "./TemplatesSectionListRequest.js"; -export { type TemplatesListRequest } from "./TemplatesListRequest.js"; +export type { TemplatesGetRequest } from "./TemplatesGetRequest.js"; +export type { TemplatesListRequest } from "./TemplatesListRequest.js"; +export type { TemplatesSectionListRequest } from "./TemplatesSectionListRequest.js"; diff --git a/src/api/resources/transcribe/client/Client.ts b/src/api/resources/transcribe/client/Client.ts index 52ef7f80..38f15974 100644 --- a/src/api/resources/transcribe/client/Client.ts +++ b/src/api/resources/transcribe/client/Client.ts @@ -1,26 +1,18 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; +import type { BaseClientOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptions, normalizeClientOptions } from "../../../../BaseClient.js"; import * as core from "../../../../core/index.js"; import { TranscribeSocket } from "./Socket.js"; -export declare namespace Transcribe { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace TranscribeClient { + export type Options = BaseClientOptions; export interface ConnectArgs { tenantName: string; token: string; + /** Additional query parameters to send with the websocket connect request. */ + queryParams?: Record; /** Arbitrary headers to send with the websocket connect request. */ headers?: Record; /** Enable debug mode on the websocket. Defaults to false. */ @@ -30,41 +22,31 @@ export declare namespace Transcribe { } } -export class Transcribe { - protected readonly _options: Transcribe.Options; +export class TranscribeClient { + protected readonly _options: NormalizedClientOptions; - constructor(_options: Transcribe.Options) { - this._options = _options; + constructor(options: TranscribeClient.Options) { + this._options = normalizeClientOptions(options); } - public async connect(args: Transcribe.ConnectArgs): Promise { - const { tenantName, token, headers, debug, reconnectAttempts } = args; - const _queryParams: Record = {}; - _queryParams["tenant-name"] = tenantName; - _queryParams["token"] = token; - let _headers: Record = { - ...headers, + public async connect(args: TranscribeClient.ConnectArgs): Promise { + const { tenantName, token, queryParams, headers, debug, reconnectAttempts } = args; + const _queryParams: Record = { + "tenant-name": tenantName, + token, }; + const _headers: Record = { ...headers }; const socket = new core.ReconnectingWebSocket({ url: core.url.join( - (await core.Supplier.get(this._options["baseUrl"])) ?? - (await core.Supplier.get(this._options["environment"])).wss, + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)).wss, "/transcribe", ), protocols: [], - queryParameters: _queryParams, + queryParameters: { ..._queryParams, ...queryParams }, headers: _headers, options: { debug: debug ?? false, maxRetries: reconnectAttempts ?? 30 }, }); return new TranscribeSocket({ socket }); } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; - } } diff --git a/src/api/resources/transcribe/client/Socket.ts b/src/api/resources/transcribe/client/Socket.ts index d69b8184..ee1555f8 100644 --- a/src/api/resources/transcribe/client/Socket.ts +++ b/src/api/resources/transcribe/client/Socket.ts @@ -1,14 +1,12 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; -import { TranscribeConfigMessage } from "../../../../serialization/types/TranscribeConfigMessage.js"; -import { TranscribeFlushMessage } from "../../../../serialization/types/TranscribeFlushMessage.js"; -import { TranscribeEndMessage } from "../../../../serialization/types/TranscribeEndMessage.js"; import { fromJson } from "../../../../core/json.js"; import * as serializers from "../../../../serialization/index.js"; +import { TranscribeConfigMessage } from "../../../../serialization/types/TranscribeConfigMessage.js"; +import { TranscribeEndMessage } from "../../../../serialization/types/TranscribeEndMessage.js"; +import { TranscribeFlushMessage } from "../../../../serialization/types/TranscribeFlushMessage.js"; +import type * as Corti from "../../../index.js"; export declare namespace TranscribeSocket { export interface Args { @@ -84,7 +82,10 @@ export class TranscribeSocket { * }); * ``` */ - public on(event: T, callback: TranscribeSocket.EventHandlers[T]) { + public on( + event: T, + callback: TranscribeSocket.EventHandlers[T], + ): void { this.eventHandlers[event] = callback; } @@ -100,18 +101,9 @@ export class TranscribeSocket { this.socket.send(JSON.stringify(jsonPayload)); } - public sendAudio(message: string): void { + public sendAudio(message: ArrayBufferLike | Blob | ArrayBufferView): void { this.assertSocketIsOpen(); - const jsonPayload = core.serialization - .string() - .jsonOrThrow(message, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - omitUndefined: true, - }); - this.socket.send(JSON.stringify(jsonPayload)); + this.sendBinary(message); } public sendFlush(message: Corti.TranscribeFlushMessage): void { diff --git a/src/api/resources/transcripts/client/Client.ts b/src/api/resources/transcripts/client/Client.ts index 3ba8772c..1230158a 100644 --- a/src/api/resources/transcripts/client/Client.ts +++ b/src/api/resources/transcripts/client/Client.ts @@ -1,53 +1,32 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as environments from "../../../../environments.js"; -import * as core from "../../../../core/index.js"; -import * as Corti from "../../../index.js"; +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; -import * as serializers from "../../../../serialization/index.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; import * as errors from "../../../../errors/index.js"; +import * as serializers from "../../../../serialization/index.js"; +import * as Corti from "../../../index.js"; -export declare namespace Transcripts { - export interface Options { - environment: core.Supplier; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: Record | undefined>; - } +export declare namespace TranscriptsClient { + export type Options = BaseClientOptions; - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: Record | undefined>; - } + export interface RequestOptions extends BaseRequestOptions {} } -export class Transcripts { - protected readonly _options: Transcripts.Options; +export class TranscriptsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; - constructor(_options: Transcripts.Options) { - this._options = _options; + constructor(options: TranscriptsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); } /** * Retrieves a list of transcripts for a given interaction. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. * @param {Corti.TranscriptsListRequest} request - * @param {Transcripts.RequestOptions} requestOptions - Request-specific configuration. + * @param {TranscriptsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} @@ -56,46 +35,46 @@ export class Transcripts { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.transcripts.list("f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.transcripts.list({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public list( - id: Corti.Uuid, - request: Corti.TranscriptsListRequest = {}, - requestOptions?: Transcripts.RequestOptions, + request: Corti.TranscriptsListRequest, + requestOptions?: TranscriptsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__list(id, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); } private async __list( - id: Corti.Uuid, - request: Corti.TranscriptsListRequest = {}, - requestOptions?: Transcripts.RequestOptions, + request: Corti.TranscriptsListRequest, + requestOptions?: TranscriptsClient.RequestOptions, ): Promise> { - const { full } = request; - const _queryParams: Record = {}; - if (full !== undefined) { - _queryParams["full"] = full?.toString() ?? null; - } - + const { id, full } = request; + const _queryParams: Record = { + full, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - queryParameters: _queryParams, - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -158,31 +137,19 @@ export class Transcripts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling GET /interactions/{id}/transcripts/.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/interactions/{id}/transcripts/", + ); } /** * Create a transcript from an audio file attached, via `/recordings` endpoint, to the interaction.
Each interaction may have more than one audio file and transcript associated with it. While audio files up to 60min in total duration, or 150MB in total size, may be attached to an interaction, synchronous processing is only supported for audio files less than ~2min in duration.

If an audio file takes longer to transcribe than the 25sec synchronous processing timeout, then it will continue to process asynchronously. In this scenario, an incomplete or empty transcript with `status=processing` will be returned with a location header that can be used to retrieve the final transcript.

The client can poll the Get Transcript endpoint (`GET /interactions/{id}/transcripts/{transcriptId}/status`) for transcript status changes:
- `200 OK` with status `processing`, `completed`, or `failed`
- `404 Not Found` if the `interactionId` or `transcriptId` are invalid

The completed transcript can be retrieved via the Get Transcript endpoint (`GET /interactions/{id}/transcripts/{transcriptId}/`).
* - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. * @param {Corti.TranscriptsCreateRequest} request - * @param {Transcripts.RequestOptions} requestOptions - Request-specific configuration. + * @param {TranscriptsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} @@ -191,48 +158,51 @@ export class Transcripts { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.transcripts.create("f47ac10b-58cc-4372-a567-0e02b2c3d479", { + * await client.transcripts.create({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", * recordingId: "f47ac10b-58cc-4372-a567-0e02b2c3d479", * primaryLanguage: "en" * }) */ public create( - id: Corti.Uuid, request: Corti.TranscriptsCreateRequest, - requestOptions?: Transcripts.RequestOptions, + requestOptions?: TranscriptsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__create(id, request, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__create(request, requestOptions)); } private async __create( - id: Corti.Uuid, request: Corti.TranscriptsCreateRequest, - requestOptions?: Transcripts.RequestOptions, + requestOptions?: TranscriptsClient.RequestOptions, ): Promise> { + const { id, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/`, ), method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), + headers: _headers, contentType: "application/json", + queryParameters: requestOptions?.queryParams, requestType: "json", - body: serializers.TranscriptsCreateRequest.jsonOrThrow(request, { + body: serializers.TranscriptsCreateRequest.jsonOrThrow(_body, { unrecognizedObjectKeys: "strip", omitUndefined: true, }), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -295,31 +265,19 @@ export class Transcripts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling POST /interactions/{id}/transcripts/.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/interactions/{id}/transcripts/", + ); } /** * Retrieve a transcript from a specific interaction.
Each interaction may have more than one transcript associated with it. Use the List Transcript request (`GET /interactions/{id}/transcripts/`) to see all transcriptIds available for the interaction.

The client can poll this Get Transcript endpoint (`GET /interactions/{id}/transcripts/{transcriptId}/status`) for transcript status changes:
- `200 OK` with status `processing`, `completed`, or `failed`
- `404 Not Found` if the `interactionId` or `transcriptId` are invalid

Status of `completed` indicates the transcript is finalized. If the transcript is retrieved while status is `processing`, then it will be incomplete.
* - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Corti.Uuid} transcriptId - The unique identifier of the transcript. Must be a valid UUID. - * @param {Transcripts.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.TranscriptsGetRequest} request + * @param {TranscriptsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} @@ -328,39 +286,44 @@ export class Transcripts { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.transcripts.get("f47ac10b-58cc-4372-a567-0e02b2c3d479", "f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.transcripts.get({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * transcriptId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public get( - id: Corti.Uuid, - transcriptId: Corti.Uuid, - requestOptions?: Transcripts.RequestOptions, + request: Corti.TranscriptsGetRequest, + requestOptions?: TranscriptsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__get(id, transcriptId, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); } private async __get( - id: Corti.Uuid, - transcriptId: Corti.Uuid, - requestOptions?: Transcripts.RequestOptions, + request: Corti.TranscriptsGetRequest, + requestOptions?: TranscriptsClient.RequestOptions, ): Promise> { + const { id, transcriptId } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/${encodeURIComponent(serializers.Uuid.jsonOrThrow(transcriptId, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(transcriptId, { omitUndefined: true }))}`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -423,31 +386,19 @@ export class Transcripts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling GET /interactions/{id}/transcripts/{transcriptId}.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/interactions/{id}/transcripts/{transcriptId}", + ); } /** * Deletes a specific transcript associated with an interaction. * - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Corti.Uuid} transcriptId - The unique identifier of the transcript. Must be a valid UUID. - * @param {Transcripts.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.TranscriptsDeleteRequest} request + * @param {TranscriptsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.BadRequestError} * @throws {@link Corti.UnauthorizedError} @@ -456,39 +407,44 @@ export class Transcripts { * @throws {@link Corti.GatewayTimeoutError} * * @example - * await client.transcripts.delete("f47ac10b-58cc-4372-a567-0e02b2c3d479", "f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.transcripts.delete({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * transcriptId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public delete( - id: Corti.Uuid, - transcriptId: Corti.Uuid, - requestOptions?: Transcripts.RequestOptions, + request: Corti.TranscriptsDeleteRequest, + requestOptions?: TranscriptsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__delete(id, transcriptId, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__delete(request, requestOptions)); } private async __delete( - id: Corti.Uuid, - transcriptId: Corti.Uuid, - requestOptions?: Transcripts.RequestOptions, + request: Corti.TranscriptsDeleteRequest, + requestOptions?: TranscriptsClient.RequestOptions, ): Promise> { + const { id, transcriptId } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/${encodeURIComponent(serializers.Uuid.jsonOrThrow(transcriptId, { omitUndefined: true }))}`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(transcriptId, { omitUndefined: true }))}`, ), method: "DELETE", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { data: undefined, rawResponse: _response.rawResponse }; @@ -542,68 +498,61 @@ export class Transcripts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling DELETE /interactions/{id}/transcripts/{transcriptId}.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "DELETE", + "/interactions/{id}/transcripts/{transcriptId}", + ); } /** * Poll for transcript creation status.
Status of `completed` indicates the transcript is finalized.
If the transcript is retrieved while status is `processing`, then it will be incomplete.
Status of `failed` indicate the transcript was not created successfully; please retry.
* - * @param {Corti.Uuid} id - The unique identifier of the interaction. Must be a valid UUID. - * @param {Corti.Uuid} transcriptId - The unique identifier of the transcript. Must be a valid UUID. - * @param {Transcripts.RequestOptions} requestOptions - Request-specific configuration. + * @param {Corti.TranscriptsGetStatusRequest} request + * @param {TranscriptsClient.RequestOptions} requestOptions - Request-specific configuration. * * @throws {@link Corti.NotFoundError} * * @example - * await client.transcripts.getStatus("f47ac10b-58cc-4372-a567-0e02b2c3d479", "f47ac10b-58cc-4372-a567-0e02b2c3d479") + * await client.transcripts.getStatus({ + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * transcriptId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * }) */ public getStatus( - id: Corti.Uuid, - transcriptId: Corti.Uuid, - requestOptions?: Transcripts.RequestOptions, + request: Corti.TranscriptsGetStatusRequest, + requestOptions?: TranscriptsClient.RequestOptions, ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__getStatus(id, transcriptId, requestOptions)); + return core.HttpResponsePromise.fromPromise(this.__getStatus(request, requestOptions)); } private async __getStatus( - id: Corti.Uuid, - transcriptId: Corti.Uuid, - requestOptions?: Transcripts.RequestOptions, + request: Corti.TranscriptsGetStatusRequest, + requestOptions?: TranscriptsClient.RequestOptions, ): Promise> { + const { id, transcriptId } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "Tenant-Name": requestOptions?.tenantName ?? this._options?.tenantName }), + requestOptions?.headers, + ); const _response = await core.fetcher({ url: core.url.join( (await core.Supplier.get(this._options.baseUrl)) ?? (await core.Supplier.get(this._options.environment)).base, - `interactions/${encodeURIComponent(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/${encodeURIComponent(serializers.Uuid.jsonOrThrow(transcriptId, { omitUndefined: true }))}/status`, + `interactions/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(id, { omitUndefined: true }))}/transcripts/${core.url.encodePathParam(serializers.Uuid.jsonOrThrow(transcriptId, { omitUndefined: true }))}/status`, ), method: "GET", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - Authorization: await this._getAuthorizationHeader(), - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, }); if (_response.ok) { return { @@ -631,31 +580,11 @@ export class Transcripts { } } - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling GET /interactions/{id}/transcripts/{transcriptId}/status.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - protected async _getAuthorizationHeader(): Promise { - const bearer = await core.Supplier.get(this._options.token); - if (bearer != null) { - return `Bearer ${bearer}`; - } - - return undefined; + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/interactions/{id}/transcripts/{transcriptId}/status", + ); } } diff --git a/src/api/resources/transcripts/client/index.ts b/src/api/resources/transcripts/client/index.ts index 82648c6f..195f9aa8 100644 --- a/src/api/resources/transcripts/client/index.ts +++ b/src/api/resources/transcripts/client/index.ts @@ -1,2 +1 @@ -export {}; export * from "./requests/index.js"; diff --git a/src/api/resources/transcripts/client/requests/TranscriptsCreateRequest.ts b/src/api/resources/transcripts/client/requests/TranscriptsCreateRequest.ts index c6eb58b9..b9fd67e9 100644 --- a/src/api/resources/transcripts/client/requests/TranscriptsCreateRequest.ts +++ b/src/api/resources/transcripts/client/requests/TranscriptsCreateRequest.ts @@ -1,17 +1,18 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../../../../index.js"; +import type * as Corti from "../../../../index.js"; /** * @example * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", * recordingId: "f47ac10b-58cc-4372-a567-0e02b2c3d479", * primaryLanguage: "en" * } */ export interface TranscriptsCreateRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; /** The unique identifier for the recording. */ recordingId: Corti.Uuid; /** The primary spoken language of the recording. Check https://docs.corti.ai/about/languages for more. */ diff --git a/src/api/resources/transcripts/client/requests/TranscriptsDeleteRequest.ts b/src/api/resources/transcripts/client/requests/TranscriptsDeleteRequest.ts new file mode 100644 index 00000000..22a92769 --- /dev/null +++ b/src/api/resources/transcripts/client/requests/TranscriptsDeleteRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * transcriptId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface TranscriptsDeleteRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** The unique identifier of the transcript. Must be a valid UUID. */ + transcriptId: Corti.Uuid; +} diff --git a/src/api/resources/transcripts/client/requests/TranscriptsGetRequest.ts b/src/api/resources/transcripts/client/requests/TranscriptsGetRequest.ts new file mode 100644 index 00000000..ce3abb59 --- /dev/null +++ b/src/api/resources/transcripts/client/requests/TranscriptsGetRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * transcriptId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface TranscriptsGetRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** The unique identifier of the transcript. Must be a valid UUID. */ + transcriptId: Corti.Uuid; +} diff --git a/src/api/resources/transcripts/client/requests/TranscriptsGetStatusRequest.ts b/src/api/resources/transcripts/client/requests/TranscriptsGetStatusRequest.ts new file mode 100644 index 00000000..7fadfc2e --- /dev/null +++ b/src/api/resources/transcripts/client/requests/TranscriptsGetStatusRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; + +/** + * @example + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479", + * transcriptId: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } + */ +export interface TranscriptsGetStatusRequest { + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** The unique identifier of the transcript. Must be a valid UUID. */ + transcriptId: Corti.Uuid; +} diff --git a/src/api/resources/transcripts/client/requests/TranscriptsListRequest.ts b/src/api/resources/transcripts/client/requests/TranscriptsListRequest.ts index 318c748e..b1557f43 100644 --- a/src/api/resources/transcripts/client/requests/TranscriptsListRequest.ts +++ b/src/api/resources/transcripts/client/requests/TranscriptsListRequest.ts @@ -1,14 +1,16 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../../../index.js"; /** * @example - * {} + * { + * id: "f47ac10b-58cc-4372-a567-0e02b2c3d479" + * } */ export interface TranscriptsListRequest { - /** - * Display full transcripts in listing - */ - full?: boolean | null; + /** The unique identifier of the interaction. Must be a valid UUID. */ + id: Corti.Uuid; + /** Display full transcripts in listing */ + full?: boolean; } diff --git a/src/api/resources/transcripts/client/requests/index.ts b/src/api/resources/transcripts/client/requests/index.ts index 4895649b..a337b7ac 100644 --- a/src/api/resources/transcripts/client/requests/index.ts +++ b/src/api/resources/transcripts/client/requests/index.ts @@ -1,2 +1,5 @@ -export { type TranscriptsListRequest } from "./TranscriptsListRequest.js"; -export { type TranscriptsCreateRequest } from "./TranscriptsCreateRequest.js"; +export type { TranscriptsCreateRequest } from "./TranscriptsCreateRequest.js"; +export type { TranscriptsDeleteRequest } from "./TranscriptsDeleteRequest.js"; +export type { TranscriptsGetRequest } from "./TranscriptsGetRequest.js"; +export type { TranscriptsGetStatusRequest } from "./TranscriptsGetStatusRequest.js"; +export type { TranscriptsListRequest } from "./TranscriptsListRequest.js"; diff --git a/src/api/types/AgentsAgent.ts b/src/api/types/AgentsAgent.ts index 94b4532b..3de35752 100644 --- a/src/api/types/AgentsAgent.ts +++ b/src/api/types/AgentsAgent.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsAgent { /** The unique identifier of the agent. */ diff --git a/src/api/types/AgentsAgentCapabilities.ts b/src/api/types/AgentsAgentCapabilities.ts index b3adb3a4..1421c537 100644 --- a/src/api/types/AgentsAgentCapabilities.ts +++ b/src/api/types/AgentsAgentCapabilities.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsAgentCapabilities { /** Indicates whether the agent supports streaming responses. */ diff --git a/src/api/types/AgentsAgentCard.ts b/src/api/types/AgentsAgentCard.ts index 98957701..1ab605f7 100644 --- a/src/api/types/AgentsAgentCard.ts +++ b/src/api/types/AgentsAgentCard.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsAgentCard { /** The version of the A2A protocol this agents supports. */ diff --git a/src/api/types/AgentsAgentCardSignature.ts b/src/api/types/AgentsAgentCardSignature.ts index 22d1f282..d80738a0 100644 --- a/src/api/types/AgentsAgentCardSignature.ts +++ b/src/api/types/AgentsAgentCardSignature.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface AgentsAgentCardSignature { /** The protected header of the JWS, base64url-encoded. */ diff --git a/src/api/types/AgentsAgentExpertsItem.ts b/src/api/types/AgentsAgentExpertsItem.ts index 7a219b8c..f8a9a698 100644 --- a/src/api/types/AgentsAgentExpertsItem.ts +++ b/src/api/types/AgentsAgentExpertsItem.ts @@ -1,7 +1,5 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export type AgentsAgentExpertsItem = Corti.AgentsExpert | Corti.AgentsExpertReference; diff --git a/src/api/types/AgentsAgentExtension.ts b/src/api/types/AgentsAgentExtension.ts index fe7c384c..05d29ff3 100644 --- a/src/api/types/AgentsAgentExtension.ts +++ b/src/api/types/AgentsAgentExtension.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface AgentsAgentExtension { /** The URI that identifies the extension. */ diff --git a/src/api/types/AgentsAgentInterface.ts b/src/api/types/AgentsAgentInterface.ts index 52e32b3c..0dcf9151 100644 --- a/src/api/types/AgentsAgentInterface.ts +++ b/src/api/types/AgentsAgentInterface.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface AgentsAgentInterface { /** The URL where the agent can be reached using the specified protocol. */ diff --git a/src/api/types/AgentsAgentProvider.ts b/src/api/types/AgentsAgentProvider.ts index 66f4d6af..2359af07 100644 --- a/src/api/types/AgentsAgentProvider.ts +++ b/src/api/types/AgentsAgentProvider.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface AgentsAgentProvider { /** The name of the organization providing the agent. */ diff --git a/src/api/types/AgentsAgentReference.ts b/src/api/types/AgentsAgentReference.ts index c5dd3c0c..d00c8c29 100644 --- a/src/api/types/AgentsAgentReference.ts +++ b/src/api/types/AgentsAgentReference.ts @@ -1,12 +1,12 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; /** * A reference to an agent, either id or name must be provided. If both are passed, the id will be used. */ export interface AgentsAgentReference { - type: "reference"; + type: Corti.AgentsAgentReferenceType; /** The unique identifier of the agent. */ id?: string; /** The name of the agent. */ diff --git a/src/api/types/AgentsAgentReferenceType.ts b/src/api/types/AgentsAgentReferenceType.ts new file mode 100644 index 00000000..0f7dc386 --- /dev/null +++ b/src/api/types/AgentsAgentReferenceType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const AgentsAgentReferenceType = { + Reference: "reference", +} as const; +export type AgentsAgentReferenceType = (typeof AgentsAgentReferenceType)[keyof typeof AgentsAgentReferenceType]; diff --git a/src/api/types/AgentsAgentResponse.ts b/src/api/types/AgentsAgentResponse.ts index 20bca0ed..6cdfbabc 100644 --- a/src/api/types/AgentsAgentResponse.ts +++ b/src/api/types/AgentsAgentResponse.ts @@ -1,7 +1,5 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export type AgentsAgentResponse = Corti.AgentsAgent | Corti.AgentsAgentReference; diff --git a/src/api/types/AgentsAgentSkill.ts b/src/api/types/AgentsAgentSkill.ts index f4a2fb09..f7cc0579 100644 --- a/src/api/types/AgentsAgentSkill.ts +++ b/src/api/types/AgentsAgentSkill.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsAgentSkill { /** Unique identifier for the skill. */ diff --git a/src/api/types/AgentsArtifact.ts b/src/api/types/AgentsArtifact.ts index a901127f..f04e2c8f 100644 --- a/src/api/types/AgentsArtifact.ts +++ b/src/api/types/AgentsArtifact.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsArtifact { /** Unique identifier for the artifact. */ diff --git a/src/api/types/AgentsContext.ts b/src/api/types/AgentsContext.ts index 6080e2a7..f3daeff2 100644 --- a/src/api/types/AgentsContext.ts +++ b/src/api/types/AgentsContext.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsContext { /** The context ID. */ diff --git a/src/api/types/AgentsContextItemsItem.ts b/src/api/types/AgentsContextItemsItem.ts index 6252d781..2a2affbe 100644 --- a/src/api/types/AgentsContextItemsItem.ts +++ b/src/api/types/AgentsContextItemsItem.ts @@ -1,7 +1,5 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export type AgentsContextItemsItem = Corti.AgentsTask | Corti.AgentsMessage; diff --git a/src/api/types/AgentsCreateExpert.ts b/src/api/types/AgentsCreateExpert.ts index 329899de..0ee8760a 100644 --- a/src/api/types/AgentsCreateExpert.ts +++ b/src/api/types/AgentsCreateExpert.ts @@ -1,11 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsCreateExpert { - type: "new"; + type: Corti.AgentsCreateExpertType; /** The name of the expert. Must be unique. */ name: string; /** A brief description of the expert's capabilities. */ diff --git a/src/api/types/AgentsCreateExpertReference.ts b/src/api/types/AgentsCreateExpertReference.ts index 8501545d..733a6184 100644 --- a/src/api/types/AgentsCreateExpertReference.ts +++ b/src/api/types/AgentsCreateExpertReference.ts @@ -1,12 +1,12 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; /** * A reference to a registry expert when creating an agent, either id or name must be provided. If both are passed, the id will be used. */ export interface AgentsCreateExpertReference { - type: "reference"; + type: Corti.AgentsCreateExpertReferenceType; /** The unique identifier of the expert. */ id?: string; /** The name of the expert. */ diff --git a/src/api/types/AgentsCreateExpertReferenceType.ts b/src/api/types/AgentsCreateExpertReferenceType.ts new file mode 100644 index 00000000..5b760a87 --- /dev/null +++ b/src/api/types/AgentsCreateExpertReferenceType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const AgentsCreateExpertReferenceType = { + Reference: "reference", +} as const; +export type AgentsCreateExpertReferenceType = + (typeof AgentsCreateExpertReferenceType)[keyof typeof AgentsCreateExpertReferenceType]; diff --git a/src/api/types/AgentsCreateExpertType.ts b/src/api/types/AgentsCreateExpertType.ts new file mode 100644 index 00000000..0e984eb3 --- /dev/null +++ b/src/api/types/AgentsCreateExpertType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const AgentsCreateExpertType = { + New: "new", +} as const; +export type AgentsCreateExpertType = (typeof AgentsCreateExpertType)[keyof typeof AgentsCreateExpertType]; diff --git a/src/api/types/AgentsCreateMcpServer.ts b/src/api/types/AgentsCreateMcpServer.ts index ccd17b1f..1ec5d267 100644 --- a/src/api/types/AgentsCreateMcpServer.ts +++ b/src/api/types/AgentsCreateMcpServer.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsCreateMcpServer { /** Name of the MCP server. */ diff --git a/src/api/types/AgentsCreateMcpServerAuthorizationType.ts b/src/api/types/AgentsCreateMcpServerAuthorizationType.ts index 10ca9a7b..ca4518e9 100644 --- a/src/api/types/AgentsCreateMcpServerAuthorizationType.ts +++ b/src/api/types/AgentsCreateMcpServerAuthorizationType.ts @@ -1,14 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Type of authorization used by the MCP server. - */ -export type AgentsCreateMcpServerAuthorizationType = "none" | "bearer" | "inherit" | "oauth2.0"; +/** Type of authorization used by the MCP server. */ export const AgentsCreateMcpServerAuthorizationType = { None: "none", Bearer: "bearer", Inherit: "inherit", Oauth20: "oauth2.0", } as const; +export type AgentsCreateMcpServerAuthorizationType = + (typeof AgentsCreateMcpServerAuthorizationType)[keyof typeof AgentsCreateMcpServerAuthorizationType]; diff --git a/src/api/types/AgentsCreateMcpServerTransportType.ts b/src/api/types/AgentsCreateMcpServerTransportType.ts index 3ad5e658..37aef0b9 100644 --- a/src/api/types/AgentsCreateMcpServerTransportType.ts +++ b/src/api/types/AgentsCreateMcpServerTransportType.ts @@ -1,13 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Type of transport used by the MCP server. - */ -export type AgentsCreateMcpServerTransportType = "stdio" | "streamable_http" | "sse"; +/** Type of transport used by the MCP server. */ export const AgentsCreateMcpServerTransportType = { Stdio: "stdio", StreamableHttp: "streamable_http", Sse: "sse", } as const; +export type AgentsCreateMcpServerTransportType = + (typeof AgentsCreateMcpServerTransportType)[keyof typeof AgentsCreateMcpServerTransportType]; diff --git a/src/api/types/AgentsDataPart.ts b/src/api/types/AgentsDataPart.ts index b7b47bcf..1223b959 100644 --- a/src/api/types/AgentsDataPart.ts +++ b/src/api/types/AgentsDataPart.ts @@ -1,10 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface AgentsDataPart { /** The kind of the part, always "data". */ - kind: "data"; + kind: Corti.AgentsDataPartKind; /** JSON data payload. */ data: Record; /** Additional metadata for the data part. */ diff --git a/src/api/types/AgentsDataPartKind.ts b/src/api/types/AgentsDataPartKind.ts new file mode 100644 index 00000000..7713b079 --- /dev/null +++ b/src/api/types/AgentsDataPartKind.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The kind of the part, always "data". */ +export const AgentsDataPartKind = { + Data: "data", +} as const; +export type AgentsDataPartKind = (typeof AgentsDataPartKind)[keyof typeof AgentsDataPartKind]; diff --git a/src/api/types/AgentsExpert.ts b/src/api/types/AgentsExpert.ts index 81c05f83..7117e0c9 100644 --- a/src/api/types/AgentsExpert.ts +++ b/src/api/types/AgentsExpert.ts @@ -1,11 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsExpert { - type: "expert"; + type: Corti.AgentsExpertType; /** The unique identifier of the expert. */ id: string; /** The name of the expert. Must be unique. */ diff --git a/src/api/types/AgentsExpertReference.ts b/src/api/types/AgentsExpertReference.ts index 42ea2eb9..c5d5dd72 100644 --- a/src/api/types/AgentsExpertReference.ts +++ b/src/api/types/AgentsExpertReference.ts @@ -1,12 +1,12 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; /** * A reference to an expert returned by the API. The expert's id and name are always provided. systemPrompt is included only when a registry expert was created with a custom system prompt. */ export interface AgentsExpertReference { - type: "reference"; + type: Corti.AgentsExpertReferenceType; /** The unique identifier of the expert. */ id: string; /** The name of the expert. */ diff --git a/src/api/types/AgentsExpertReferenceType.ts b/src/api/types/AgentsExpertReferenceType.ts new file mode 100644 index 00000000..f9677db7 --- /dev/null +++ b/src/api/types/AgentsExpertReferenceType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const AgentsExpertReferenceType = { + Reference: "reference", +} as const; +export type AgentsExpertReferenceType = (typeof AgentsExpertReferenceType)[keyof typeof AgentsExpertReferenceType]; diff --git a/src/api/types/AgentsExpertType.ts b/src/api/types/AgentsExpertType.ts new file mode 100644 index 00000000..cef31a43 --- /dev/null +++ b/src/api/types/AgentsExpertType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const AgentsExpertType = { + Expert: "expert", +} as const; +export type AgentsExpertType = (typeof AgentsExpertType)[keyof typeof AgentsExpertType]; diff --git a/src/api/types/AgentsFilePart.ts b/src/api/types/AgentsFilePart.ts index c8930175..64794dfc 100644 --- a/src/api/types/AgentsFilePart.ts +++ b/src/api/types/AgentsFilePart.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsFilePart { /** The kind of the part, always "file". */ - kind: "file"; + kind: Corti.AgentsFilePartKind; file?: Corti.AgentsFilePartFile; /** Additional metadata for the file part. */ metadata?: Record; diff --git a/src/api/types/AgentsFilePartFile.ts b/src/api/types/AgentsFilePartFile.ts index 184bdb5b..8ab63935 100644 --- a/src/api/types/AgentsFilePartFile.ts +++ b/src/api/types/AgentsFilePartFile.ts @@ -1,7 +1,5 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export type AgentsFilePartFile = Corti.AgentsFileWithUri | Corti.AgentsFileWithBytes; diff --git a/src/api/types/AgentsFilePartKind.ts b/src/api/types/AgentsFilePartKind.ts new file mode 100644 index 00000000..0bb2ac0e --- /dev/null +++ b/src/api/types/AgentsFilePartKind.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The kind of the part, always "file". */ +export const AgentsFilePartKind = { + File: "file", +} as const; +export type AgentsFilePartKind = (typeof AgentsFilePartKind)[keyof typeof AgentsFilePartKind]; diff --git a/src/api/types/AgentsFileWithBytes.ts b/src/api/types/AgentsFileWithBytes.ts index 5c69dfae..b58af3f6 100644 --- a/src/api/types/AgentsFileWithBytes.ts +++ b/src/api/types/AgentsFileWithBytes.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface AgentsFileWithBytes { /** The byte content of the file. */ diff --git a/src/api/types/AgentsFileWithUri.ts b/src/api/types/AgentsFileWithUri.ts index f1ff4bed..9919157a 100644 --- a/src/api/types/AgentsFileWithUri.ts +++ b/src/api/types/AgentsFileWithUri.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface AgentsFileWithUri { /** The URI of the file. */ diff --git a/src/api/types/AgentsMcpServer.ts b/src/api/types/AgentsMcpServer.ts index a0c5f7b4..57fabed5 100644 --- a/src/api/types/AgentsMcpServer.ts +++ b/src/api/types/AgentsMcpServer.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsMcpServer { /** Unique identifier for the MCP server. */ diff --git a/src/api/types/AgentsMcpServerAuthorizationType.ts b/src/api/types/AgentsMcpServerAuthorizationType.ts index 46157090..36d6daef 100644 --- a/src/api/types/AgentsMcpServerAuthorizationType.ts +++ b/src/api/types/AgentsMcpServerAuthorizationType.ts @@ -1,14 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Type of authorization used by the MCP server. - */ -export type AgentsMcpServerAuthorizationType = "none" | "bearer" | "inherit" | "oauth2.0"; +/** Type of authorization used by the MCP server. */ export const AgentsMcpServerAuthorizationType = { None: "none", Bearer: "bearer", Inherit: "inherit", Oauth20: "oauth2.0", } as const; +export type AgentsMcpServerAuthorizationType = + (typeof AgentsMcpServerAuthorizationType)[keyof typeof AgentsMcpServerAuthorizationType]; diff --git a/src/api/types/AgentsMcpServerTransportType.ts b/src/api/types/AgentsMcpServerTransportType.ts index 10c1f4e4..198e8c44 100644 --- a/src/api/types/AgentsMcpServerTransportType.ts +++ b/src/api/types/AgentsMcpServerTransportType.ts @@ -1,12 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Type of transport used by the MCP server. - */ -export type AgentsMcpServerTransportType = "stdio" | "streamable_http"; +/** Type of transport used by the MCP server. */ export const AgentsMcpServerTransportType = { Stdio: "stdio", StreamableHttp: "streamable_http", } as const; +export type AgentsMcpServerTransportType = + (typeof AgentsMcpServerTransportType)[keyof typeof AgentsMcpServerTransportType]; diff --git a/src/api/types/AgentsMessage.ts b/src/api/types/AgentsMessage.ts index 35e3f514..08b1d045 100644 --- a/src/api/types/AgentsMessage.ts +++ b/src/api/types/AgentsMessage.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsMessage { /** The role of the message sender. */ @@ -22,5 +20,5 @@ export interface AgentsMessage { /** Identifier for the context (thread) in which the message is sent. */ contextId?: string; /** The kind of the object, always "message". */ - kind: "message"; + kind: Corti.AgentsMessageKind; } diff --git a/src/api/types/AgentsMessageKind.ts b/src/api/types/AgentsMessageKind.ts new file mode 100644 index 00000000..33024a17 --- /dev/null +++ b/src/api/types/AgentsMessageKind.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The kind of the object, always "message". */ +export const AgentsMessageKind = { + Message: "message", +} as const; +export type AgentsMessageKind = (typeof AgentsMessageKind)[keyof typeof AgentsMessageKind]; diff --git a/src/api/types/AgentsMessageRole.ts b/src/api/types/AgentsMessageRole.ts index c3e12702..c2e2164f 100644 --- a/src/api/types/AgentsMessageRole.ts +++ b/src/api/types/AgentsMessageRole.ts @@ -1,12 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * The role of the message sender. - */ -export type AgentsMessageRole = "user" | "agent"; +/** The role of the message sender. */ export const AgentsMessageRole = { User: "user", Agent: "agent", } as const; +export type AgentsMessageRole = (typeof AgentsMessageRole)[keyof typeof AgentsMessageRole]; diff --git a/src/api/types/AgentsMessageSendConfiguration.ts b/src/api/types/AgentsMessageSendConfiguration.ts index 6b007844..f85cc4fd 100644 --- a/src/api/types/AgentsMessageSendConfiguration.ts +++ b/src/api/types/AgentsMessageSendConfiguration.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsMessageSendConfiguration { /** A list of output MIME types the client is prepared to accept in the response. */ diff --git a/src/api/types/AgentsPart.ts b/src/api/types/AgentsPart.ts index c3a6f69b..dbde9135 100644 --- a/src/api/types/AgentsPart.ts +++ b/src/api/types/AgentsPart.ts @@ -1,7 +1,5 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export type AgentsPart = Corti.AgentsTextPart | Corti.AgentsFilePart | Corti.AgentsDataPart; diff --git a/src/api/types/AgentsPushNotificationAuthenticationInfo.ts b/src/api/types/AgentsPushNotificationAuthenticationInfo.ts index 44d4f945..5769026a 100644 --- a/src/api/types/AgentsPushNotificationAuthenticationInfo.ts +++ b/src/api/types/AgentsPushNotificationAuthenticationInfo.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface AgentsPushNotificationAuthenticationInfo { /** A list of supported authentication schemes (e.g. 'Basic', 'Bearer'). */ diff --git a/src/api/types/AgentsPushNotificationConfig.ts b/src/api/types/AgentsPushNotificationConfig.ts index 40574731..9c5f9cc4 100644 --- a/src/api/types/AgentsPushNotificationConfig.ts +++ b/src/api/types/AgentsPushNotificationConfig.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsPushNotificationConfig { /** Unique identifier for the push notification configuration. */ diff --git a/src/api/types/AgentsRegistryExpert.ts b/src/api/types/AgentsRegistryExpert.ts index dac8ca31..5486ddc1 100644 --- a/src/api/types/AgentsRegistryExpert.ts +++ b/src/api/types/AgentsRegistryExpert.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsRegistryExpert { /** The name of the expert. */ diff --git a/src/api/types/AgentsRegistryExpertsResponse.ts b/src/api/types/AgentsRegistryExpertsResponse.ts index 6c1cd705..f923bb1d 100644 --- a/src/api/types/AgentsRegistryExpertsResponse.ts +++ b/src/api/types/AgentsRegistryExpertsResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsRegistryExpertsResponse { /** A list of all available experts in the experts registry. */ diff --git a/src/api/types/AgentsRegistryMcpServer.ts b/src/api/types/AgentsRegistryMcpServer.ts index 3166cfae..0236f42b 100644 --- a/src/api/types/AgentsRegistryMcpServer.ts +++ b/src/api/types/AgentsRegistryMcpServer.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsRegistryMcpServer { /** Name of the MCP server. */ diff --git a/src/api/types/AgentsRegistryMcpServerAuthorizationType.ts b/src/api/types/AgentsRegistryMcpServerAuthorizationType.ts index 0344e7a8..e2764042 100644 --- a/src/api/types/AgentsRegistryMcpServerAuthorizationType.ts +++ b/src/api/types/AgentsRegistryMcpServerAuthorizationType.ts @@ -1,14 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Type of authorization used by the MCP server. - */ -export type AgentsRegistryMcpServerAuthorizationType = "none" | "bearer" | "inherit" | "oauth2.0"; +/** Type of authorization used by the MCP server. */ export const AgentsRegistryMcpServerAuthorizationType = { None: "none", Bearer: "bearer", Inherit: "inherit", Oauth20: "oauth2.0", } as const; +export type AgentsRegistryMcpServerAuthorizationType = + (typeof AgentsRegistryMcpServerAuthorizationType)[keyof typeof AgentsRegistryMcpServerAuthorizationType]; diff --git a/src/api/types/AgentsTask.ts b/src/api/types/AgentsTask.ts index 2510a1b6..2bd6389f 100644 --- a/src/api/types/AgentsTask.ts +++ b/src/api/types/AgentsTask.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsTask { /** Unique identifier for the task. */ @@ -17,5 +15,5 @@ export interface AgentsTask { /** Additional metadata for the task. */ metadata?: Record; /** The kind of the object, always "task". */ - kind: "task"; + kind: Corti.AgentsTaskKind; } diff --git a/src/api/types/AgentsTaskKind.ts b/src/api/types/AgentsTaskKind.ts new file mode 100644 index 00000000..51fc3dda --- /dev/null +++ b/src/api/types/AgentsTaskKind.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The kind of the object, always "task". */ +export const AgentsTaskKind = { + Task: "task", +} as const; +export type AgentsTaskKind = (typeof AgentsTaskKind)[keyof typeof AgentsTaskKind]; diff --git a/src/api/types/AgentsTaskStatus.ts b/src/api/types/AgentsTaskStatus.ts index df5ea44c..c9f055ed 100644 --- a/src/api/types/AgentsTaskStatus.ts +++ b/src/api/types/AgentsTaskStatus.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface AgentsTaskStatus { /** The current state of the task. */ diff --git a/src/api/types/AgentsTaskStatusState.ts b/src/api/types/AgentsTaskStatusState.ts index d6098a16..7e186848 100644 --- a/src/api/types/AgentsTaskStatusState.ts +++ b/src/api/types/AgentsTaskStatusState.ts @@ -1,20 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * The current state of the task. - */ -export type AgentsTaskStatusState = - | "submitted" - | "working" - | "input-required" - | "completed" - | "canceled" - | "failed" - | "rejected" - | "auth-required" - | "unknown"; +/** The current state of the task. */ export const AgentsTaskStatusState = { Submitted: "submitted", Working: "working", @@ -26,3 +12,4 @@ export const AgentsTaskStatusState = { AuthRequired: "auth-required", Unknown: "unknown", } as const; +export type AgentsTaskStatusState = (typeof AgentsTaskStatusState)[keyof typeof AgentsTaskStatusState]; diff --git a/src/api/types/AgentsTextPart.ts b/src/api/types/AgentsTextPart.ts index 6a4bcab9..b0fda0cf 100644 --- a/src/api/types/AgentsTextPart.ts +++ b/src/api/types/AgentsTextPart.ts @@ -1,10 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface AgentsTextPart { /** The kind of the part, always "text". */ - kind: "text"; + kind: Corti.AgentsTextPartKind; /** The text content of the part. */ text: string; /** Additional metadata for the text part. */ diff --git a/src/api/types/AgentsTextPartKind.ts b/src/api/types/AgentsTextPartKind.ts new file mode 100644 index 00000000..3366f180 --- /dev/null +++ b/src/api/types/AgentsTextPartKind.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The kind of the part, always "text". */ +export const AgentsTextPartKind = { + Text: "text", +} as const; +export type AgentsTextPartKind = (typeof AgentsTextPartKind)[keyof typeof AgentsTextPartKind]; diff --git a/src/api/types/CodesGeneralReadResponse.ts b/src/api/types/CodesGeneralReadResponse.ts index e4234348..ecf9381d 100644 --- a/src/api/types/CodesGeneralReadResponse.ts +++ b/src/api/types/CodesGeneralReadResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; /** * Predicted or candidate code record. diff --git a/src/api/types/CodesGeneralReadResponseEvidencesItem.ts b/src/api/types/CodesGeneralReadResponseEvidencesItem.ts index 5d4b0707..44b0034a 100644 --- a/src/api/types/CodesGeneralReadResponseEvidencesItem.ts +++ b/src/api/types/CodesGeneralReadResponseEvidencesItem.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface CodesGeneralReadResponseEvidencesItem { /** Index from the context input array */ diff --git a/src/api/types/CodesGeneralResponse.ts b/src/api/types/CodesGeneralResponse.ts index 8890a642..27c1c08d 100644 --- a/src/api/types/CodesGeneralResponse.ts +++ b/src/api/types/CodesGeneralResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface CodesGeneralResponse { /** Highest confidence bundle of codes, preselected by the code prediction model */ diff --git a/src/api/types/CommonAiContext.ts b/src/api/types/CommonAiContext.ts index fa69191e..7d597c08 100644 --- a/src/api/types/CommonAiContext.ts +++ b/src/api/types/CommonAiContext.ts @@ -1,7 +1,5 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export type CommonAiContext = Corti.CommonTextContext | Corti.CommonDocumentIdContext; diff --git a/src/api/types/CommonCodingSystemEnum.ts b/src/api/types/CommonCodingSystemEnum.ts index dd34a283..64d4d789 100644 --- a/src/api/types/CommonCodingSystemEnum.ts +++ b/src/api/types/CommonCodingSystemEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -export type CommonCodingSystemEnum = "icd10cm" | "icd10pcs" | "cpt"; export const CommonCodingSystemEnum = { Icd10Cm: "icd10cm", Icd10Pcs: "icd10pcs", Cpt: "cpt", } as const; +export type CommonCodingSystemEnum = (typeof CommonCodingSystemEnum)[keyof typeof CommonCodingSystemEnum]; diff --git a/src/api/types/CommonDocumentIdContext.ts b/src/api/types/CommonDocumentIdContext.ts index f5ceb79c..bcb354c4 100644 --- a/src/api/types/CommonDocumentIdContext.ts +++ b/src/api/types/CommonDocumentIdContext.ts @@ -1,10 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface CommonDocumentIdContext { /** The type of context, always "documentId" in this context. */ - type: "documentId"; + type: Corti.CommonDocumentIdContextType; /** A referenced document ID to be used as input to the model. */ documentId: string; } diff --git a/src/api/types/CommonDocumentIdContextType.ts b/src/api/types/CommonDocumentIdContextType.ts new file mode 100644 index 00000000..46adc0b0 --- /dev/null +++ b/src/api/types/CommonDocumentIdContextType.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The type of context, always "documentId" in this context. */ +export const CommonDocumentIdContextType = { + DocumentId: "documentId", +} as const; +export type CommonDocumentIdContextType = + (typeof CommonDocumentIdContextType)[keyof typeof CommonDocumentIdContextType]; diff --git a/src/api/types/CommonSortingDirectionEnum.ts b/src/api/types/CommonSortingDirectionEnum.ts index 0d8efe0c..b81a9b6b 100644 --- a/src/api/types/CommonSortingDirectionEnum.ts +++ b/src/api/types/CommonSortingDirectionEnum.ts @@ -1,9 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -export type CommonSortingDirectionEnum = "asc" | "desc"; export const CommonSortingDirectionEnum = { Asc: "asc", Desc: "desc", } as const; +export type CommonSortingDirectionEnum = (typeof CommonSortingDirectionEnum)[keyof typeof CommonSortingDirectionEnum]; diff --git a/src/api/types/CommonSourceEnum.ts b/src/api/types/CommonSourceEnum.ts index bd679e7d..e38194f1 100644 --- a/src/api/types/CommonSourceEnum.ts +++ b/src/api/types/CommonSourceEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -export type CommonSourceEnum = "core" | "system" | "user"; export const CommonSourceEnum = { Core: "core", System: "system", User: "user", } as const; +export type CommonSourceEnum = (typeof CommonSourceEnum)[keyof typeof CommonSourceEnum]; diff --git a/src/api/types/CommonTextContext.ts b/src/api/types/CommonTextContext.ts index fc34c227..f6109d2b 100644 --- a/src/api/types/CommonTextContext.ts +++ b/src/api/types/CommonTextContext.ts @@ -1,10 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface CommonTextContext { /** The type of context, always "text" in this context. */ - type: "text"; + type: Corti.CommonTextContextType; /** A text string to be used as input to the model. */ text: string; } diff --git a/src/api/types/CommonTextContextType.ts b/src/api/types/CommonTextContextType.ts new file mode 100644 index 00000000..3ab87830 --- /dev/null +++ b/src/api/types/CommonTextContextType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The type of context, always "text" in this context. */ +export const CommonTextContextType = { + Text: "text", +} as const; +export type CommonTextContextType = (typeof CommonTextContextType)[keyof typeof CommonTextContextType]; diff --git a/src/api/types/CommonTranscriptRequest.ts b/src/api/types/CommonTranscriptRequest.ts index 1de3c43f..7a816c84 100644 --- a/src/api/types/CommonTranscriptRequest.ts +++ b/src/api/types/CommonTranscriptRequest.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface CommonTranscriptRequest { /** The channel associated with this phrase/utterance. */ diff --git a/src/api/types/CommonTranscriptResponse.ts b/src/api/types/CommonTranscriptResponse.ts index 4aecce1c..9a18874f 100644 --- a/src/api/types/CommonTranscriptResponse.ts +++ b/src/api/types/CommonTranscriptResponse.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface CommonTranscriptResponse { /** The channel associated with this phrase/utterance. */ diff --git a/src/api/types/CommonUsageInfo.ts b/src/api/types/CommonUsageInfo.ts index fe707329..ee1f0492 100644 --- a/src/api/types/CommonUsageInfo.ts +++ b/src/api/types/CommonUsageInfo.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * Credits consumed for this request. diff --git a/src/api/types/DocumentsContext.ts b/src/api/types/DocumentsContext.ts index de98fad4..fe3496ad 100644 --- a/src/api/types/DocumentsContext.ts +++ b/src/api/types/DocumentsContext.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export type DocumentsContext = | Corti.DocumentsContextWithFacts diff --git a/src/api/types/DocumentsContextWithFacts.ts b/src/api/types/DocumentsContextWithFacts.ts index 9b9a0f7e..642853f0 100644 --- a/src/api/types/DocumentsContextWithFacts.ts +++ b/src/api/types/DocumentsContextWithFacts.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface DocumentsContextWithFacts { /** The type of context data that will be used in the request: `Facts`, `Transcript`, or `String`. */ - type: "facts"; + type: Corti.DocumentsContextWithFactsType; /** An array of facts. See [guide](/textgen/documents-standard##generate-document-from-facts-as-input). */ data: Corti.FactsContext[]; } diff --git a/src/api/types/DocumentsContextWithFactsType.ts b/src/api/types/DocumentsContextWithFactsType.ts new file mode 100644 index 00000000..fb531db9 --- /dev/null +++ b/src/api/types/DocumentsContextWithFactsType.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The type of context data that will be used in the request: `Facts`, `Transcript`, or `String`. */ +export const DocumentsContextWithFactsType = { + Facts: "facts", +} as const; +export type DocumentsContextWithFactsType = + (typeof DocumentsContextWithFactsType)[keyof typeof DocumentsContextWithFactsType]; diff --git a/src/api/types/DocumentsContextWithString.ts b/src/api/types/DocumentsContextWithString.ts index 83a2db5e..566a5b0e 100644 --- a/src/api/types/DocumentsContextWithString.ts +++ b/src/api/types/DocumentsContextWithString.ts @@ -1,10 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface DocumentsContextWithString { /** The type of context data that will be used in the request: `Facts`, `Transcript`, or `String`. */ - type: "string"; + type: Corti.DocumentsContextWithStringType; /** String data can include any text to be reasoned over for document generation: Transcript text, facts, or other narrative information. */ data: string; } diff --git a/src/api/types/DocumentsContextWithStringType.ts b/src/api/types/DocumentsContextWithStringType.ts new file mode 100644 index 00000000..a3620d52 --- /dev/null +++ b/src/api/types/DocumentsContextWithStringType.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The type of context data that will be used in the request: `Facts`, `Transcript`, or `String`. */ +export const DocumentsContextWithStringType = { + String: "string", +} as const; +export type DocumentsContextWithStringType = + (typeof DocumentsContextWithStringType)[keyof typeof DocumentsContextWithStringType]; diff --git a/src/api/types/DocumentsContextWithTranscript.ts b/src/api/types/DocumentsContextWithTranscript.ts index 4ad559db..eb1ad2b4 100644 --- a/src/api/types/DocumentsContextWithTranscript.ts +++ b/src/api/types/DocumentsContextWithTranscript.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface DocumentsContextWithTranscript { /** The type of context data that will be used in the request: `Facts`, `Transcript`, or `String`. */ - type: "transcript"; + type: Corti.DocumentsContextWithTranscriptType; /** The transcript `data.text` object can accept the full transcript in one string, alternatively pass each transcript segment into a `context` object - [see guide](/textgen/documents-standard#generate-document-from-transcript-as-input). */ data: Corti.CommonTranscriptRequest; } diff --git a/src/api/types/DocumentsContextWithTranscriptType.ts b/src/api/types/DocumentsContextWithTranscriptType.ts new file mode 100644 index 00000000..91ca07d4 --- /dev/null +++ b/src/api/types/DocumentsContextWithTranscriptType.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +/** The type of context data that will be used in the request: `Facts`, `Transcript`, or `String`. */ +export const DocumentsContextWithTranscriptType = { + Transcript: "transcript", +} as const; +export type DocumentsContextWithTranscriptType = + (typeof DocumentsContextWithTranscriptType)[keyof typeof DocumentsContextWithTranscriptType]; diff --git a/src/api/types/DocumentsCreateRequest.ts b/src/api/types/DocumentsCreateRequestBody.ts similarity index 75% rename from src/api/types/DocumentsCreateRequest.ts rename to src/api/types/DocumentsCreateRequestBody.ts index e61c566b..c207e617 100644 --- a/src/api/types/DocumentsCreateRequest.ts +++ b/src/api/types/DocumentsCreateRequestBody.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; -export type DocumentsCreateRequest = +export type DocumentsCreateRequestBody = /** * Standard method for document generation: Use template key to generate document based on pre-defined template. */ | Corti.DocumentsCreateRequestWithTemplateKey diff --git a/src/api/types/DocumentsCreateRequestWithTemplate.ts b/src/api/types/DocumentsCreateRequestWithTemplate.ts index 943aaa0a..69357041 100644 --- a/src/api/types/DocumentsCreateRequestWithTemplate.ts +++ b/src/api/types/DocumentsCreateRequestWithTemplate.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface DocumentsCreateRequestWithTemplate { /** An array of context objects. Currently only accepts multiple objects when of type `transcript`. See [guide](/textgen/documents-standard#generate-document-from-transcript-as-input). */ diff --git a/src/api/types/DocumentsCreateRequestWithTemplateKey.ts b/src/api/types/DocumentsCreateRequestWithTemplateKey.ts index d7a3a94a..f8133d1e 100644 --- a/src/api/types/DocumentsCreateRequestWithTemplateKey.ts +++ b/src/api/types/DocumentsCreateRequestWithTemplateKey.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface DocumentsCreateRequestWithTemplateKey { /** An array of context objects. Currently only accepts multiple objects when of type `transcript`. See [guide](/textgen/documents-standard#generate-document-from-transcript-as-input). */ diff --git a/src/api/types/DocumentsGetResponse.ts b/src/api/types/DocumentsGetResponse.ts index d786f3d6..1d79cd9f 100644 --- a/src/api/types/DocumentsGetResponse.ts +++ b/src/api/types/DocumentsGetResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface DocumentsGetResponse { /** Unique ID of the generated document */ diff --git a/src/api/types/DocumentsListResponse.ts b/src/api/types/DocumentsListResponse.ts index dc8bb1d0..3720187f 100644 --- a/src/api/types/DocumentsListResponse.ts +++ b/src/api/types/DocumentsListResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface DocumentsListResponse { data: Corti.DocumentsGetResponse[]; diff --git a/src/api/types/DocumentsSection.ts b/src/api/types/DocumentsSection.ts index a7364114..21e4fca4 100644 --- a/src/api/types/DocumentsSection.ts +++ b/src/api/types/DocumentsSection.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface DocumentsSection { /** Document section key */ diff --git a/src/api/types/DocumentsSectionInput.ts b/src/api/types/DocumentsSectionInput.ts index b8975a9d..91c2ea5c 100644 --- a/src/api/types/DocumentsSectionInput.ts +++ b/src/api/types/DocumentsSectionInput.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface DocumentsSectionInput { key: string; diff --git a/src/api/types/DocumentsSectionOverride.ts b/src/api/types/DocumentsSectionOverride.ts index 259097fc..9b6ef591 100644 --- a/src/api/types/DocumentsSectionOverride.ts +++ b/src/api/types/DocumentsSectionOverride.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface DocumentsSectionOverride { /** The key that references the section to use for document generation. */ diff --git a/src/api/types/DocumentsTemplate.ts b/src/api/types/DocumentsTemplate.ts index af732607..78857ecd 100644 --- a/src/api/types/DocumentsTemplate.ts +++ b/src/api/types/DocumentsTemplate.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export type DocumentsTemplate = /** diff --git a/src/api/types/DocumentsTemplateWithSectionKeys.ts b/src/api/types/DocumentsTemplateWithSectionKeys.ts index 3cca13c8..68947606 100644 --- a/src/api/types/DocumentsTemplateWithSectionKeys.ts +++ b/src/api/types/DocumentsTemplateWithSectionKeys.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface DocumentsTemplateWithSectionKeys { /** An array of section keys. */ diff --git a/src/api/types/DocumentsTemplateWithSections.ts b/src/api/types/DocumentsTemplateWithSections.ts index 2718aad0..5e730f25 100644 --- a/src/api/types/DocumentsTemplateWithSections.ts +++ b/src/api/types/DocumentsTemplateWithSections.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface DocumentsTemplateWithSections { sections: Corti.DocumentsSectionOverride[]; diff --git a/src/api/types/ErrorResponse.ts b/src/api/types/ErrorResponse.ts index 7733d0a5..0a123e93 100644 --- a/src/api/types/ErrorResponse.ts +++ b/src/api/types/ErrorResponse.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface ErrorResponse { requestid: string; diff --git a/src/api/types/FactsBatchUpdateInput.ts b/src/api/types/FactsBatchUpdateInput.ts index 53340cdf..289dbda1 100644 --- a/src/api/types/FactsBatchUpdateInput.ts +++ b/src/api/types/FactsBatchUpdateInput.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface FactsBatchUpdateInput { /** The unique identifier of the fact to be updated. */ diff --git a/src/api/types/FactsBatchUpdateItem.ts b/src/api/types/FactsBatchUpdateItem.ts index dd1beaca..13fabbec 100644 --- a/src/api/types/FactsBatchUpdateItem.ts +++ b/src/api/types/FactsBatchUpdateItem.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsBatchUpdateItem { /** The unique identifier of the updated fact. */ diff --git a/src/api/types/FactsBatchUpdateResponse.ts b/src/api/types/FactsBatchUpdateResponse.ts index a1d42040..0e065668 100644 --- a/src/api/types/FactsBatchUpdateResponse.ts +++ b/src/api/types/FactsBatchUpdateResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsBatchUpdateResponse { /** A list of updated facts. */ diff --git a/src/api/types/FactsContext.ts b/src/api/types/FactsContext.ts index dc3d11bc..c55a0dea 100644 --- a/src/api/types/FactsContext.ts +++ b/src/api/types/FactsContext.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsContext { /** The text of the fact. */ diff --git a/src/api/types/FactsCreateInput.ts b/src/api/types/FactsCreateInput.ts index 7ab1ebb2..54e38b1b 100644 --- a/src/api/types/FactsCreateInput.ts +++ b/src/api/types/FactsCreateInput.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsCreateInput { /** The text content of the fact. */ diff --git a/src/api/types/FactsCreateItem.ts b/src/api/types/FactsCreateItem.ts index aeb96891..4f839430 100644 --- a/src/api/types/FactsCreateItem.ts +++ b/src/api/types/FactsCreateItem.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsCreateItem { /** The unique identifier of the newly created fact. */ diff --git a/src/api/types/FactsCreateResponse.ts b/src/api/types/FactsCreateResponse.ts index cf433b5b..b94e4b28 100644 --- a/src/api/types/FactsCreateResponse.ts +++ b/src/api/types/FactsCreateResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsCreateResponse { /** A list of successfully created facts. */ diff --git a/src/api/types/FactsEvidence.ts b/src/api/types/FactsEvidence.ts index 5275982d..989784de 100644 --- a/src/api/types/FactsEvidence.ts +++ b/src/api/types/FactsEvidence.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface FactsEvidence { /** The category of evidence. */ diff --git a/src/api/types/FactsExtractResponse.ts b/src/api/types/FactsExtractResponse.ts index 17ab97f8..4ac3c494 100644 --- a/src/api/types/FactsExtractResponse.ts +++ b/src/api/types/FactsExtractResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsExtractResponse { /** List of extracted facts based on the provided input context. */ diff --git a/src/api/types/FactsExtractResponseFactsItem.ts b/src/api/types/FactsExtractResponseFactsItem.ts index 6ee1a56f..db2b3b0c 100644 --- a/src/api/types/FactsExtractResponseFactsItem.ts +++ b/src/api/types/FactsExtractResponseFactsItem.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface FactsExtractResponseFactsItem { /** The fact group key the fact belongs to. */ diff --git a/src/api/types/FactsFactGroupsItem.ts b/src/api/types/FactsFactGroupsItem.ts index 43dce1db..f71fb28c 100644 --- a/src/api/types/FactsFactGroupsItem.ts +++ b/src/api/types/FactsFactGroupsItem.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsFactGroupsItem { id?: Corti.Uuid; diff --git a/src/api/types/FactsFactGroupsItemTranslationsItem.ts b/src/api/types/FactsFactGroupsItemTranslationsItem.ts index 3289875e..9889285a 100644 --- a/src/api/types/FactsFactGroupsItemTranslationsItem.ts +++ b/src/api/types/FactsFactGroupsItemTranslationsItem.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface FactsFactGroupsItemTranslationsItem { id?: number; diff --git a/src/api/types/FactsFactGroupsListResponse.ts b/src/api/types/FactsFactGroupsListResponse.ts index 350a8da5..32f68282 100644 --- a/src/api/types/FactsFactGroupsListResponse.ts +++ b/src/api/types/FactsFactGroupsListResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsFactGroupsListResponse { data: Corti.FactsFactGroupsItem[]; diff --git a/src/api/types/FactsListItem.ts b/src/api/types/FactsListItem.ts index c5f87db8..d7a301e9 100644 --- a/src/api/types/FactsListItem.ts +++ b/src/api/types/FactsListItem.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsListItem { /** The unique identifier of the fact. */ diff --git a/src/api/types/FactsListResponse.ts b/src/api/types/FactsListResponse.ts index 64126b07..895c0c1f 100644 --- a/src/api/types/FactsListResponse.ts +++ b/src/api/types/FactsListResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsListResponse { /** A list of facts associated with the interaction. */ diff --git a/src/api/types/FactsUpdateResponse.ts b/src/api/types/FactsUpdateResponse.ts index a0920962..a4e1f939 100644 --- a/src/api/types/FactsUpdateResponse.ts +++ b/src/api/types/FactsUpdateResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface FactsUpdateResponse { /** The unique identifier of the fact. */ diff --git a/src/api/types/InteractionsCreateResponse.ts b/src/api/types/InteractionsCreateResponse.ts index 7a49f6ec..829582d8 100644 --- a/src/api/types/InteractionsCreateResponse.ts +++ b/src/api/types/InteractionsCreateResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface InteractionsCreateResponse { /** Unique identifier for the interaction. */ diff --git a/src/api/types/InteractionsEncounterCreateRequest.ts b/src/api/types/InteractionsEncounterCreateRequest.ts index 4f942dbf..b69be463 100644 --- a/src/api/types/InteractionsEncounterCreateRequest.ts +++ b/src/api/types/InteractionsEncounterCreateRequest.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface InteractionsEncounterCreateRequest { /** A unique identifier for the encounter, essential for tracking and referencing specific patient interactions. */ diff --git a/src/api/types/InteractionsEncounterPeriod.ts b/src/api/types/InteractionsEncounterPeriod.ts index 73b1ac5c..5525b5cc 100644 --- a/src/api/types/InteractionsEncounterPeriod.ts +++ b/src/api/types/InteractionsEncounterPeriod.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface InteractionsEncounterPeriod { /** The start date/time of the encounter. (UTC) */ diff --git a/src/api/types/InteractionsEncounterResponse.ts b/src/api/types/InteractionsEncounterResponse.ts index f3585783..a3ef3f5d 100644 --- a/src/api/types/InteractionsEncounterResponse.ts +++ b/src/api/types/InteractionsEncounterResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface InteractionsEncounterResponse { /** A unique identifier for the encounter, essential for tracking and referencing specific patient interactions. */ diff --git a/src/api/types/InteractionsEncounterStatusEnum.ts b/src/api/types/InteractionsEncounterStatusEnum.ts index 2b9ffe90..97ea40c5 100644 --- a/src/api/types/InteractionsEncounterStatusEnum.ts +++ b/src/api/types/InteractionsEncounterStatusEnum.ts @@ -1,14 +1,5 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -export type InteractionsEncounterStatusEnum = - | "planned" - | "in-progress" - | "on-hold" - | "completed" - | "cancelled" - | "deleted"; export const InteractionsEncounterStatusEnum = { Planned: "planned", InProgress: "in-progress", @@ -17,3 +8,5 @@ export const InteractionsEncounterStatusEnum = { Cancelled: "cancelled", Deleted: "deleted", } as const; +export type InteractionsEncounterStatusEnum = + (typeof InteractionsEncounterStatusEnum)[keyof typeof InteractionsEncounterStatusEnum]; diff --git a/src/api/types/InteractionsEncounterTypeEnum.ts b/src/api/types/InteractionsEncounterTypeEnum.ts index 53377c76..67ef5c74 100644 --- a/src/api/types/InteractionsEncounterTypeEnum.ts +++ b/src/api/types/InteractionsEncounterTypeEnum.ts @@ -1,13 +1,5 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -export type InteractionsEncounterTypeEnum = - | "first_consultation" - | "consultation" - | "emergency" - | "inpatient" - | "outpatient"; export const InteractionsEncounterTypeEnum = { FirstConsultation: "first_consultation", Consultation: "consultation", @@ -15,3 +7,5 @@ export const InteractionsEncounterTypeEnum = { Inpatient: "inpatient", Outpatient: "outpatient", } as const; +export type InteractionsEncounterTypeEnum = + (typeof InteractionsEncounterTypeEnum)[keyof typeof InteractionsEncounterTypeEnum]; diff --git a/src/api/types/InteractionsEncounterUpdateRequest.ts b/src/api/types/InteractionsEncounterUpdateRequest.ts index 8781a199..e46049d5 100644 --- a/src/api/types/InteractionsEncounterUpdateRequest.ts +++ b/src/api/types/InteractionsEncounterUpdateRequest.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface InteractionsEncounterUpdateRequest { /** A unique identifier for the encounter, essential for tracking and referencing specific patient interactions. */ diff --git a/src/api/types/InteractionsGenderEnum.ts b/src/api/types/InteractionsGenderEnum.ts index 989d4bdd..ae0344bd 100644 --- a/src/api/types/InteractionsGenderEnum.ts +++ b/src/api/types/InteractionsGenderEnum.ts @@ -1,11 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -export type InteractionsGenderEnum = "male" | "female" | "unknown" | "other"; export const InteractionsGenderEnum = { Male: "male", Female: "female", Unknown: "unknown", Other: "other", } as const; +export type InteractionsGenderEnum = (typeof InteractionsGenderEnum)[keyof typeof InteractionsGenderEnum]; diff --git a/src/api/types/InteractionsGetResponse.ts b/src/api/types/InteractionsGetResponse.ts index f48f22b1..74e26f09 100644 --- a/src/api/types/InteractionsGetResponse.ts +++ b/src/api/types/InteractionsGetResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface InteractionsGetResponse { /** Unique identifier for the interaction. */ diff --git a/src/api/types/InteractionsListResponse.ts b/src/api/types/InteractionsListResponse.ts index 24df42d6..8a5de3da 100644 --- a/src/api/types/InteractionsListResponse.ts +++ b/src/api/types/InteractionsListResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface InteractionsListResponse { interactions: Corti.InteractionsGetResponse[]; diff --git a/src/api/types/InteractionsPatient.ts b/src/api/types/InteractionsPatient.ts index e933a81d..14c48fa6 100644 --- a/src/api/types/InteractionsPatient.ts +++ b/src/api/types/InteractionsPatient.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface InteractionsPatient { /** FHIR reference to patient identifier. */ diff --git a/src/api/types/RecordingsCreateResponse.ts b/src/api/types/RecordingsCreateResponse.ts index 3922c107..2b62ee09 100644 --- a/src/api/types/RecordingsCreateResponse.ts +++ b/src/api/types/RecordingsCreateResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface RecordingsCreateResponse { /** The unique identifier for the created recording. */ diff --git a/src/api/types/RecordingsListResponse.ts b/src/api/types/RecordingsListResponse.ts index 17f9667b..e9affced 100644 --- a/src/api/types/RecordingsListResponse.ts +++ b/src/api/types/RecordingsListResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface RecordingsListResponse { /** A list of recordings for the interaction. */ diff --git a/src/api/types/StreamConfig.ts b/src/api/types/StreamConfig.ts index d60c199a..2d041e77 100644 --- a/src/api/types/StreamConfig.ts +++ b/src/api/types/StreamConfig.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamConfig { transcription: Corti.StreamConfigTranscription; diff --git a/src/api/types/StreamConfigMessage.ts b/src/api/types/StreamConfigMessage.ts index 46a1ac0f..4a05d18d 100644 --- a/src/api/types/StreamConfigMessage.ts +++ b/src/api/types/StreamConfigMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamConfigMessage { - type: "config"; + type: Corti.StreamConfigMessageType; configuration: Corti.StreamConfig; } diff --git a/src/api/types/StreamConfigMessageType.ts b/src/api/types/StreamConfigMessageType.ts new file mode 100644 index 00000000..9ed7e32f --- /dev/null +++ b/src/api/types/StreamConfigMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const StreamConfigMessageType = { + Config: "config", +} as const; +export type StreamConfigMessageType = (typeof StreamConfigMessageType)[keyof typeof StreamConfigMessageType]; diff --git a/src/api/types/StreamConfigMode.ts b/src/api/types/StreamConfigMode.ts index 78976b06..5ec39b72 100644 --- a/src/api/types/StreamConfigMode.ts +++ b/src/api/types/StreamConfigMode.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamConfigMode { /** Processing mode */ diff --git a/src/api/types/StreamConfigModeType.ts b/src/api/types/StreamConfigModeType.ts index 2c2dd409..2ec3ceb8 100644 --- a/src/api/types/StreamConfigModeType.ts +++ b/src/api/types/StreamConfigModeType.ts @@ -1,12 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Processing mode - */ -export type StreamConfigModeType = "facts" | "transcription"; +/** Processing mode */ export const StreamConfigModeType = { Facts: "facts", Transcription: "transcription", } as const; +export type StreamConfigModeType = (typeof StreamConfigModeType)[keyof typeof StreamConfigModeType]; diff --git a/src/api/types/StreamConfigParticipant.ts b/src/api/types/StreamConfigParticipant.ts index ca45df9b..6df615c9 100644 --- a/src/api/types/StreamConfigParticipant.ts +++ b/src/api/types/StreamConfigParticipant.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamConfigParticipant { /** Audio channel number (e.g. 0 or 1) */ diff --git a/src/api/types/StreamConfigParticipantRole.ts b/src/api/types/StreamConfigParticipantRole.ts index 0586c14e..0491b35a 100644 --- a/src/api/types/StreamConfigParticipantRole.ts +++ b/src/api/types/StreamConfigParticipantRole.ts @@ -1,13 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Role of the participant (e.g., doctor, patient, or multiple) - */ -export type StreamConfigParticipantRole = "doctor" | "patient" | "multiple"; +/** Role of the participant (e.g., doctor, patient, or multiple) */ export const StreamConfigParticipantRole = { Doctor: "doctor", Patient: "patient", Multiple: "multiple", } as const; +export type StreamConfigParticipantRole = + (typeof StreamConfigParticipantRole)[keyof typeof StreamConfigParticipantRole]; diff --git a/src/api/types/StreamConfigStatusMessage.ts b/src/api/types/StreamConfigStatusMessage.ts index 2a1d66cc..32a32c1a 100644 --- a/src/api/types/StreamConfigStatusMessage.ts +++ b/src/api/types/StreamConfigStatusMessage.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamConfigStatusMessage { /** Configuration status result */ diff --git a/src/api/types/StreamConfigStatusMessageType.ts b/src/api/types/StreamConfigStatusMessageType.ts index 32c1ec7f..4c9db82e 100644 --- a/src/api/types/StreamConfigStatusMessageType.ts +++ b/src/api/types/StreamConfigStatusMessageType.ts @@ -1,17 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Configuration status result - */ -export type StreamConfigStatusMessageType = - | "CONFIG_ACCEPTED" - | "CONFIG_DENIED" - | "CONFIG_MISSING" - | "CONFIG_NOT_PROVIDED" - | "CONFIG_ALREADY_RECEIVED" - | "CONFIG_TIMEOUT"; +/** Configuration status result */ export const StreamConfigStatusMessageType = { ConfigAccepted: "CONFIG_ACCEPTED", ConfigDenied: "CONFIG_DENIED", @@ -20,3 +9,5 @@ export const StreamConfigStatusMessageType = { ConfigAlreadyReceived: "CONFIG_ALREADY_RECEIVED", ConfigTimeout: "CONFIG_TIMEOUT", } as const; +export type StreamConfigStatusMessageType = + (typeof StreamConfigStatusMessageType)[keyof typeof StreamConfigStatusMessageType]; diff --git a/src/api/types/StreamConfigTranscription.ts b/src/api/types/StreamConfigTranscription.ts index 0f543513..8a61d252 100644 --- a/src/api/types/StreamConfigTranscription.ts +++ b/src/api/types/StreamConfigTranscription.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamConfigTranscription { /** Primary spoken language for transcription */ diff --git a/src/api/types/StreamEndMessage.ts b/src/api/types/StreamEndMessage.ts index cb816658..f948f485 100644 --- a/src/api/types/StreamEndMessage.ts +++ b/src/api/types/StreamEndMessage.ts @@ -1,7 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface StreamEndMessage { - type: "end"; + type: Corti.StreamEndMessageType; } diff --git a/src/api/types/StreamEndMessageType.ts b/src/api/types/StreamEndMessageType.ts new file mode 100644 index 00000000..a004874a --- /dev/null +++ b/src/api/types/StreamEndMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const StreamEndMessageType = { + End: "end", +} as const; +export type StreamEndMessageType = (typeof StreamEndMessageType)[keyof typeof StreamEndMessageType]; diff --git a/src/api/types/StreamEndedMessage.ts b/src/api/types/StreamEndedMessage.ts index 83a22eb7..d55dc3eb 100644 --- a/src/api/types/StreamEndedMessage.ts +++ b/src/api/types/StreamEndedMessage.ts @@ -1,7 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface StreamEndedMessage { - type: "ENDED"; + type: Corti.StreamEndedMessageType; } diff --git a/src/api/types/StreamEndedMessageType.ts b/src/api/types/StreamEndedMessageType.ts new file mode 100644 index 00000000..335ed883 --- /dev/null +++ b/src/api/types/StreamEndedMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const StreamEndedMessageType = { + Ended: "ENDED", +} as const; +export type StreamEndedMessageType = (typeof StreamEndedMessageType)[keyof typeof StreamEndedMessageType]; diff --git a/src/api/types/StreamErrorDetail.ts b/src/api/types/StreamErrorDetail.ts index f7d9f9f3..988c5aed 100644 --- a/src/api/types/StreamErrorDetail.ts +++ b/src/api/types/StreamErrorDetail.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface StreamErrorDetail { /** Error identifier */ diff --git a/src/api/types/StreamErrorMessage.ts b/src/api/types/StreamErrorMessage.ts index 5a55a719..a399930e 100644 --- a/src/api/types/StreamErrorMessage.ts +++ b/src/api/types/StreamErrorMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamErrorMessage { - type: "error"; + type: Corti.StreamErrorMessageType; error: Corti.StreamErrorDetail; } diff --git a/src/api/types/StreamErrorMessageType.ts b/src/api/types/StreamErrorMessageType.ts new file mode 100644 index 00000000..878f65d3 --- /dev/null +++ b/src/api/types/StreamErrorMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const StreamErrorMessageType = { + Error: "error", +} as const; +export type StreamErrorMessageType = (typeof StreamErrorMessageType)[keyof typeof StreamErrorMessageType]; diff --git a/src/api/types/StreamFact.ts b/src/api/types/StreamFact.ts index 64cb1cb9..473ac6e3 100644 --- a/src/api/types/StreamFact.ts +++ b/src/api/types/StreamFact.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface StreamFact { /** Unique identifier for the fact */ diff --git a/src/api/types/StreamFactsMessage.ts b/src/api/types/StreamFactsMessage.ts index 8dcbe032..f163683f 100644 --- a/src/api/types/StreamFactsMessage.ts +++ b/src/api/types/StreamFactsMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamFactsMessage { - type: "facts"; + type: Corti.StreamFactsMessageType; fact: Corti.StreamFact[]; } diff --git a/src/api/types/StreamFactsMessageType.ts b/src/api/types/StreamFactsMessageType.ts new file mode 100644 index 00000000..80a3ac66 --- /dev/null +++ b/src/api/types/StreamFactsMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const StreamFactsMessageType = { + Facts: "facts", +} as const; +export type StreamFactsMessageType = (typeof StreamFactsMessageType)[keyof typeof StreamFactsMessageType]; diff --git a/src/api/types/StreamFlushMessage.ts b/src/api/types/StreamFlushMessage.ts index a74f60b8..527646c4 100644 --- a/src/api/types/StreamFlushMessage.ts +++ b/src/api/types/StreamFlushMessage.ts @@ -1,7 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface StreamFlushMessage { - type: "flush"; + type: Corti.StreamFlushMessageType; } diff --git a/src/api/types/StreamFlushMessageType.ts b/src/api/types/StreamFlushMessageType.ts new file mode 100644 index 00000000..80cf0d27 --- /dev/null +++ b/src/api/types/StreamFlushMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const StreamFlushMessageType = { + Flush: "flush", +} as const; +export type StreamFlushMessageType = (typeof StreamFlushMessageType)[keyof typeof StreamFlushMessageType]; diff --git a/src/api/types/StreamFlushedMessage.ts b/src/api/types/StreamFlushedMessage.ts index c0e04f41..c8bccca5 100644 --- a/src/api/types/StreamFlushedMessage.ts +++ b/src/api/types/StreamFlushedMessage.ts @@ -1,7 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface StreamFlushedMessage { - type: "flushed"; + type: Corti.StreamFlushedMessageType; } diff --git a/src/api/types/StreamFlushedMessageType.ts b/src/api/types/StreamFlushedMessageType.ts new file mode 100644 index 00000000..37200df0 --- /dev/null +++ b/src/api/types/StreamFlushedMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const StreamFlushedMessageType = { + Flushed: "flushed", +} as const; +export type StreamFlushedMessageType = (typeof StreamFlushedMessageType)[keyof typeof StreamFlushedMessageType]; diff --git a/src/api/types/StreamParticipant.ts b/src/api/types/StreamParticipant.ts index 618e6099..1771e496 100644 --- a/src/api/types/StreamParticipant.ts +++ b/src/api/types/StreamParticipant.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface StreamParticipant { /** Audio channel number (e.g. 0 or 1) */ diff --git a/src/api/types/StreamSupportedLanguage.ts b/src/api/types/StreamSupportedLanguage.ts index 13ee8746..c98e879d 100644 --- a/src/api/types/StreamSupportedLanguage.ts +++ b/src/api/types/StreamSupportedLanguage.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * Supported language codes diff --git a/src/api/types/StreamTranscript.ts b/src/api/types/StreamTranscript.ts index 0f4ac686..e55e700c 100644 --- a/src/api/types/StreamTranscript.ts +++ b/src/api/types/StreamTranscript.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamTranscript { /** Interaction ID that the transcript segments are associated with */ diff --git a/src/api/types/StreamTranscriptMessage.ts b/src/api/types/StreamTranscriptMessage.ts index da98ab78..0069e9bf 100644 --- a/src/api/types/StreamTranscriptMessage.ts +++ b/src/api/types/StreamTranscriptMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface StreamTranscriptMessage { - type: "transcript"; + type: Corti.StreamTranscriptMessageType; data: Corti.StreamTranscript[]; } diff --git a/src/api/types/StreamTranscriptMessageType.ts b/src/api/types/StreamTranscriptMessageType.ts new file mode 100644 index 00000000..f78d7abc --- /dev/null +++ b/src/api/types/StreamTranscriptMessageType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const StreamTranscriptMessageType = { + Transcript: "transcript", +} as const; +export type StreamTranscriptMessageType = + (typeof StreamTranscriptMessageType)[keyof typeof StreamTranscriptMessageType]; diff --git a/src/api/types/StreamTranscriptTime.ts b/src/api/types/StreamTranscriptTime.ts index e11722e1..2bee128d 100644 --- a/src/api/types/StreamTranscriptTime.ts +++ b/src/api/types/StreamTranscriptTime.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface StreamTranscriptTime { /** Start time of the transcript segment */ diff --git a/src/api/types/StreamUsageMessage.ts b/src/api/types/StreamUsageMessage.ts index 07a52ff4..4dcc4c4c 100644 --- a/src/api/types/StreamUsageMessage.ts +++ b/src/api/types/StreamUsageMessage.ts @@ -1,9 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface StreamUsageMessage { - type: "usage"; + type: Corti.StreamUsageMessageType; /** The amount of credits used for this stream. */ credits: number; } diff --git a/src/api/types/StreamUsageMessageType.ts b/src/api/types/StreamUsageMessageType.ts new file mode 100644 index 00000000..2ab61edc --- /dev/null +++ b/src/api/types/StreamUsageMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const StreamUsageMessageType = { + Usage: "usage", +} as const; +export type StreamUsageMessageType = (typeof StreamUsageMessageType)[keyof typeof StreamUsageMessageType]; diff --git a/src/api/types/TemplatesDocumentationModeEnum.ts b/src/api/types/TemplatesDocumentationModeEnum.ts index b62e6407..78b67203 100644 --- a/src/api/types/TemplatesDocumentationModeEnum.ts +++ b/src/api/types/TemplatesDocumentationModeEnum.ts @@ -1,12 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Configures the approach and underlying system prompt that govern how the LLM generates documentation. - */ -export type TemplatesDocumentationModeEnum = "global_sequential" | "routed_parallel"; +/** Configures the approach and underlying system prompt that govern how the LLM generates documentation. */ export const TemplatesDocumentationModeEnum = { GlobalSequential: "global_sequential", RoutedParallel: "routed_parallel", } as const; +export type TemplatesDocumentationModeEnum = + (typeof TemplatesDocumentationModeEnum)[keyof typeof TemplatesDocumentationModeEnum]; diff --git a/src/api/types/TemplatesFormatRule.ts b/src/api/types/TemplatesFormatRule.ts index cb8a07f9..d39df0dc 100644 --- a/src/api/types/TemplatesFormatRule.ts +++ b/src/api/types/TemplatesFormatRule.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface TemplatesFormatRule { /** Name of the format rule. */ - name?: string | null; + name: string | null; } diff --git a/src/api/types/TemplatesItem.ts b/src/api/types/TemplatesItem.ts index 8b3b8680..0a056f6a 100644 --- a/src/api/types/TemplatesItem.ts +++ b/src/api/types/TemplatesItem.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TemplatesItem { /** The timestamp when the template was updated. */ diff --git a/src/api/types/TemplatesListResponse.ts b/src/api/types/TemplatesListResponse.ts index 5b3cf670..8c723d3b 100644 --- a/src/api/types/TemplatesListResponse.ts +++ b/src/api/types/TemplatesListResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TemplatesListResponse { /** List of filtered templates */ diff --git a/src/api/types/TemplatesSection.ts b/src/api/types/TemplatesSection.ts index 2c65e619..55b8d960 100644 --- a/src/api/types/TemplatesSection.ts +++ b/src/api/types/TemplatesSection.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TemplatesSection { /** The timestamp when the section was updated. */ diff --git a/src/api/types/TemplatesSectionListResponse.ts b/src/api/types/TemplatesSectionListResponse.ts index 6f77eb9f..5b652126 100644 --- a/src/api/types/TemplatesSectionListResponse.ts +++ b/src/api/types/TemplatesSectionListResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TemplatesSectionListResponse { /** List of filtered template sections */ diff --git a/src/api/types/TemplatesSectionSorted.ts b/src/api/types/TemplatesSectionSorted.ts index e99b4771..102c6622 100644 --- a/src/api/types/TemplatesSectionSorted.ts +++ b/src/api/types/TemplatesSectionSorted.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TemplatesSectionSorted { /** Sort order of the section within the template. */ diff --git a/src/api/types/TemplatesSectionTranslation.ts b/src/api/types/TemplatesSectionTranslation.ts index 6a364605..7c0549ca 100644 --- a/src/api/types/TemplatesSectionTranslation.ts +++ b/src/api/types/TemplatesSectionTranslation.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface TemplatesSectionTranslation { /** Language code. */ diff --git a/src/api/types/TemplatesTranslation.ts b/src/api/types/TemplatesTranslation.ts index d50ea0c5..74034914 100644 --- a/src/api/types/TemplatesTranslation.ts +++ b/src/api/types/TemplatesTranslation.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface TemplatesTranslation { /** Language code. */ diff --git a/src/api/types/TemplatesWritingStyle.ts b/src/api/types/TemplatesWritingStyle.ts index b962ad5d..ca08d733 100644 --- a/src/api/types/TemplatesWritingStyle.ts +++ b/src/api/types/TemplatesWritingStyle.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface TemplatesWritingStyle { /** Name of the writing style. */ diff --git a/src/api/types/TranscribeCommand.ts b/src/api/types/TranscribeCommand.ts index 71d0160b..7a418c27 100644 --- a/src/api/types/TranscribeCommand.ts +++ b/src/api/types/TranscribeCommand.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscribeCommand { /** To identify the command when it gets detected and returned over the WebSocket */ diff --git a/src/api/types/TranscribeCommandData.ts b/src/api/types/TranscribeCommandData.ts index 66a17899..af5a9a11 100644 --- a/src/api/types/TranscribeCommandData.ts +++ b/src/api/types/TranscribeCommandData.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface TranscribeCommandData { /** To identify the command when it gets detected and returned over the WebSocket */ id: string; /** The variables identified */ - variables?: Record | null; + variables?: Record | null; /** The raw transcript without spoken punctuation applied and without command phrases removed */ rawTranscriptText: string; /** Start time of the transcript segment in seconds */ diff --git a/src/api/types/TranscribeCommandMessage.ts b/src/api/types/TranscribeCommandMessage.ts index f1d0ce5a..8cede78f 100644 --- a/src/api/types/TranscribeCommandMessage.ts +++ b/src/api/types/TranscribeCommandMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscribeCommandMessage { - type: "command"; + type: Corti.TranscribeCommandMessageType; data: Corti.TranscribeCommandData; } diff --git a/src/api/types/TranscribeCommandMessageType.ts b/src/api/types/TranscribeCommandMessageType.ts new file mode 100644 index 00000000..99829f02 --- /dev/null +++ b/src/api/types/TranscribeCommandMessageType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const TranscribeCommandMessageType = { + Command: "command", +} as const; +export type TranscribeCommandMessageType = + (typeof TranscribeCommandMessageType)[keyof typeof TranscribeCommandMessageType]; diff --git a/src/api/types/TranscribeCommandVariable.ts b/src/api/types/TranscribeCommandVariable.ts index 003a0d84..511fbb26 100644 --- a/src/api/types/TranscribeCommandVariable.ts +++ b/src/api/types/TranscribeCommandVariable.ts @@ -1,12 +1,12 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface TranscribeCommandVariable { /** Variable key identifier */ key: string; /** Variable type */ - type: "enum"; + type: Corti.TranscribeCommandVariableType; /** Enum values for the variable */ enum: string[]; } diff --git a/src/api/types/TranscribeCommandVariableType.ts b/src/api/types/TranscribeCommandVariableType.ts new file mode 100644 index 00000000..ff26f363 --- /dev/null +++ b/src/api/types/TranscribeCommandVariableType.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +/** Variable type */ +export const TranscribeCommandVariableType = { + Enum: "enum", +} as const; +export type TranscribeCommandVariableType = + (typeof TranscribeCommandVariableType)[keyof typeof TranscribeCommandVariableType]; diff --git a/src/api/types/TranscribeConfig.ts b/src/api/types/TranscribeConfig.ts index 9a8b17e2..bf8dbd61 100644 --- a/src/api/types/TranscribeConfig.ts +++ b/src/api/types/TranscribeConfig.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscribeConfig { /** The locale of the primary spoken language. */ diff --git a/src/api/types/TranscribeConfigMessage.ts b/src/api/types/TranscribeConfigMessage.ts index d15d0285..1a0f95c7 100644 --- a/src/api/types/TranscribeConfigMessage.ts +++ b/src/api/types/TranscribeConfigMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscribeConfigMessage { - type: "config"; + type: Corti.TranscribeConfigMessageType; configuration: Corti.TranscribeConfig; } diff --git a/src/api/types/TranscribeConfigMessageType.ts b/src/api/types/TranscribeConfigMessageType.ts new file mode 100644 index 00000000..2e563b8e --- /dev/null +++ b/src/api/types/TranscribeConfigMessageType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const TranscribeConfigMessageType = { + Config: "config", +} as const; +export type TranscribeConfigMessageType = + (typeof TranscribeConfigMessageType)[keyof typeof TranscribeConfigMessageType]; diff --git a/src/api/types/TranscribeConfigStatusMessage.ts b/src/api/types/TranscribeConfigStatusMessage.ts index 69801cc0..765dcd6f 100644 --- a/src/api/types/TranscribeConfigStatusMessage.ts +++ b/src/api/types/TranscribeConfigStatusMessage.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscribeConfigStatusMessage { /** Configuration status result */ diff --git a/src/api/types/TranscribeConfigStatusMessageType.ts b/src/api/types/TranscribeConfigStatusMessageType.ts index 817ac87b..bded7c6c 100644 --- a/src/api/types/TranscribeConfigStatusMessageType.ts +++ b/src/api/types/TranscribeConfigStatusMessageType.ts @@ -1,13 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Configuration status result - */ -export type TranscribeConfigStatusMessageType = "CONFIG_ACCEPTED" | "CONFIG_DENIED" | "CONFIG_TIMEOUT"; +/** Configuration status result */ export const TranscribeConfigStatusMessageType = { ConfigAccepted: "CONFIG_ACCEPTED", ConfigDenied: "CONFIG_DENIED", ConfigTimeout: "CONFIG_TIMEOUT", } as const; +export type TranscribeConfigStatusMessageType = + (typeof TranscribeConfigStatusMessageType)[keyof typeof TranscribeConfigStatusMessageType]; diff --git a/src/api/types/TranscribeEndMessage.ts b/src/api/types/TranscribeEndMessage.ts index b008d92d..6a9a4bf7 100644 --- a/src/api/types/TranscribeEndMessage.ts +++ b/src/api/types/TranscribeEndMessage.ts @@ -1,7 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface TranscribeEndMessage { - type: "end"; + type: Corti.TranscribeEndMessageType; } diff --git a/src/api/types/TranscribeEndMessageType.ts b/src/api/types/TranscribeEndMessageType.ts new file mode 100644 index 00000000..240401fa --- /dev/null +++ b/src/api/types/TranscribeEndMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const TranscribeEndMessageType = { + End: "end", +} as const; +export type TranscribeEndMessageType = (typeof TranscribeEndMessageType)[keyof typeof TranscribeEndMessageType]; diff --git a/src/api/types/TranscribeEndedMessage.ts b/src/api/types/TranscribeEndedMessage.ts index a33a4675..8f8a1fee 100644 --- a/src/api/types/TranscribeEndedMessage.ts +++ b/src/api/types/TranscribeEndedMessage.ts @@ -1,7 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface TranscribeEndedMessage { - type: "ended"; + type: Corti.TranscribeEndedMessageType; } diff --git a/src/api/types/TranscribeEndedMessageType.ts b/src/api/types/TranscribeEndedMessageType.ts new file mode 100644 index 00000000..c4db7637 --- /dev/null +++ b/src/api/types/TranscribeEndedMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const TranscribeEndedMessageType = { + Ended: "ended", +} as const; +export type TranscribeEndedMessageType = (typeof TranscribeEndedMessageType)[keyof typeof TranscribeEndedMessageType]; diff --git a/src/api/types/TranscribeErrorMessage.ts b/src/api/types/TranscribeErrorMessage.ts index c2ea333e..ac5fe934 100644 --- a/src/api/types/TranscribeErrorMessage.ts +++ b/src/api/types/TranscribeErrorMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscribeErrorMessage { - type: "error"; + type: Corti.TranscribeErrorMessageType; error: Corti.TranscribeErrorMessageError; } diff --git a/src/api/types/TranscribeErrorMessageError.ts b/src/api/types/TranscribeErrorMessageError.ts index c1948b1b..067e054b 100644 --- a/src/api/types/TranscribeErrorMessageError.ts +++ b/src/api/types/TranscribeErrorMessageError.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface TranscribeErrorMessageError { /** Unique error identifier */ diff --git a/src/api/types/TranscribeErrorMessageType.ts b/src/api/types/TranscribeErrorMessageType.ts new file mode 100644 index 00000000..1e8198bd --- /dev/null +++ b/src/api/types/TranscribeErrorMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const TranscribeErrorMessageType = { + Error: "error", +} as const; +export type TranscribeErrorMessageType = (typeof TranscribeErrorMessageType)[keyof typeof TranscribeErrorMessageType]; diff --git a/src/api/types/TranscribeFlushMessage.ts b/src/api/types/TranscribeFlushMessage.ts index d347f9dd..f01121ae 100644 --- a/src/api/types/TranscribeFlushMessage.ts +++ b/src/api/types/TranscribeFlushMessage.ts @@ -1,7 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface TranscribeFlushMessage { - type: "flush"; + type: Corti.TranscribeFlushMessageType; } diff --git a/src/api/types/TranscribeFlushMessageType.ts b/src/api/types/TranscribeFlushMessageType.ts new file mode 100644 index 00000000..f7154265 --- /dev/null +++ b/src/api/types/TranscribeFlushMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const TranscribeFlushMessageType = { + Flush: "flush", +} as const; +export type TranscribeFlushMessageType = (typeof TranscribeFlushMessageType)[keyof typeof TranscribeFlushMessageType]; diff --git a/src/api/types/TranscribeFlushedMessage.ts b/src/api/types/TranscribeFlushedMessage.ts index bd8d916e..86894143 100644 --- a/src/api/types/TranscribeFlushedMessage.ts +++ b/src/api/types/TranscribeFlushedMessage.ts @@ -1,7 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface TranscribeFlushedMessage { - type: "flushed"; + type: Corti.TranscribeFlushedMessageType; } diff --git a/src/api/types/TranscribeFlushedMessageType.ts b/src/api/types/TranscribeFlushedMessageType.ts new file mode 100644 index 00000000..6111d76f --- /dev/null +++ b/src/api/types/TranscribeFlushedMessageType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const TranscribeFlushedMessageType = { + Flushed: "flushed", +} as const; +export type TranscribeFlushedMessageType = + (typeof TranscribeFlushedMessageType)[keyof typeof TranscribeFlushedMessageType]; diff --git a/src/api/types/TranscribeFormatting.ts b/src/api/types/TranscribeFormatting.ts index 1dea11e8..d34efe52 100644 --- a/src/api/types/TranscribeFormatting.ts +++ b/src/api/types/TranscribeFormatting.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscribeFormatting { /** Formatting for dates. */ diff --git a/src/api/types/TranscribeFormattingDates.ts b/src/api/types/TranscribeFormattingDates.ts index 73af2aaa..fc6601aa 100644 --- a/src/api/types/TranscribeFormattingDates.ts +++ b/src/api/types/TranscribeFormattingDates.ts @@ -1,11 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Formatting for dates. - */ -export type TranscribeFormattingDates = "as_dictated" | "eu_slash" | "iso_compact" | "long_text" | "us_slash"; +/** Formatting for dates. */ export const TranscribeFormattingDates = { AsDictated: "as_dictated", EuSlash: "eu_slash", @@ -13,3 +8,4 @@ export const TranscribeFormattingDates = { LongText: "long_text", UsSlash: "us_slash", } as const; +export type TranscribeFormattingDates = (typeof TranscribeFormattingDates)[keyof typeof TranscribeFormattingDates]; diff --git a/src/api/types/TranscribeFormattingMeasurements.ts b/src/api/types/TranscribeFormattingMeasurements.ts index 351f5de8..cff51a5a 100644 --- a/src/api/types/TranscribeFormattingMeasurements.ts +++ b/src/api/types/TranscribeFormattingMeasurements.ts @@ -1,12 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Formatting for measurements. - */ -export type TranscribeFormattingMeasurements = "abbreviated" | "as_dictated"; +/** Formatting for measurements. */ export const TranscribeFormattingMeasurements = { Abbreviated: "abbreviated", AsDictated: "as_dictated", } as const; +export type TranscribeFormattingMeasurements = + (typeof TranscribeFormattingMeasurements)[keyof typeof TranscribeFormattingMeasurements]; diff --git a/src/api/types/TranscribeFormattingNumbers.ts b/src/api/types/TranscribeFormattingNumbers.ts index 110b0934..f56341aa 100644 --- a/src/api/types/TranscribeFormattingNumbers.ts +++ b/src/api/types/TranscribeFormattingNumbers.ts @@ -1,13 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Formatting for numbers. - */ -export type TranscribeFormattingNumbers = "as_dictated" | "numerals" | "numerals_above_nine"; +/** Formatting for numbers. */ export const TranscribeFormattingNumbers = { AsDictated: "as_dictated", Numerals: "numerals", NumeralsAboveNine: "numerals_above_nine", } as const; +export type TranscribeFormattingNumbers = + (typeof TranscribeFormattingNumbers)[keyof typeof TranscribeFormattingNumbers]; diff --git a/src/api/types/TranscribeFormattingNumericRanges.ts b/src/api/types/TranscribeFormattingNumericRanges.ts index 917fe792..016f9775 100644 --- a/src/api/types/TranscribeFormattingNumericRanges.ts +++ b/src/api/types/TranscribeFormattingNumericRanges.ts @@ -1,12 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Formatting for numeric ranges. - */ -export type TranscribeFormattingNumericRanges = "as_dictated" | "numerals"; +/** Formatting for numeric ranges. */ export const TranscribeFormattingNumericRanges = { AsDictated: "as_dictated", Numerals: "numerals", } as const; +export type TranscribeFormattingNumericRanges = + (typeof TranscribeFormattingNumericRanges)[keyof typeof TranscribeFormattingNumericRanges]; diff --git a/src/api/types/TranscribeFormattingOrdinals.ts b/src/api/types/TranscribeFormattingOrdinals.ts index be5557e4..6db15561 100644 --- a/src/api/types/TranscribeFormattingOrdinals.ts +++ b/src/api/types/TranscribeFormattingOrdinals.ts @@ -1,12 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Formatting for ordinals. - */ -export type TranscribeFormattingOrdinals = "as_dictated" | "numerals"; +/** Formatting for ordinals. */ export const TranscribeFormattingOrdinals = { AsDictated: "as_dictated", Numerals: "numerals", } as const; +export type TranscribeFormattingOrdinals = + (typeof TranscribeFormattingOrdinals)[keyof typeof TranscribeFormattingOrdinals]; diff --git a/src/api/types/TranscribeFormattingTimes.ts b/src/api/types/TranscribeFormattingTimes.ts index 0a8aaa78..cdc30da7 100644 --- a/src/api/types/TranscribeFormattingTimes.ts +++ b/src/api/types/TranscribeFormattingTimes.ts @@ -1,13 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Formatting for times. - */ -export type TranscribeFormattingTimes = "as_dictated" | "h12" | "h24"; +/** Formatting for times. */ export const TranscribeFormattingTimes = { AsDictated: "as_dictated", H12: "h12", H24: "h24", } as const; +export type TranscribeFormattingTimes = (typeof TranscribeFormattingTimes)[keyof typeof TranscribeFormattingTimes]; diff --git a/src/api/types/TranscribeSupportedLanguage.ts b/src/api/types/TranscribeSupportedLanguage.ts index 839d6448..8f7d582e 100644 --- a/src/api/types/TranscribeSupportedLanguage.ts +++ b/src/api/types/TranscribeSupportedLanguage.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. /** * Supported language codes for transcription diff --git a/src/api/types/TranscribeTranscriptData.ts b/src/api/types/TranscribeTranscriptData.ts index 45bfbb5a..be3aa39a 100644 --- a/src/api/types/TranscribeTranscriptData.ts +++ b/src/api/types/TranscribeTranscriptData.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface TranscribeTranscriptData { /** Transcript segment with punctuations applied and command phrases removed */ diff --git a/src/api/types/TranscribeTranscriptMessage.ts b/src/api/types/TranscribeTranscriptMessage.ts index 62bec432..eecc7bb6 100644 --- a/src/api/types/TranscribeTranscriptMessage.ts +++ b/src/api/types/TranscribeTranscriptMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscribeTranscriptMessage { - type: "transcript"; + type: Corti.TranscribeTranscriptMessageType; data: Corti.TranscribeTranscriptData; } diff --git a/src/api/types/TranscribeTranscriptMessageType.ts b/src/api/types/TranscribeTranscriptMessageType.ts new file mode 100644 index 00000000..aa02c2b4 --- /dev/null +++ b/src/api/types/TranscribeTranscriptMessageType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const TranscribeTranscriptMessageType = { + Transcript: "transcript", +} as const; +export type TranscribeTranscriptMessageType = + (typeof TranscribeTranscriptMessageType)[keyof typeof TranscribeTranscriptMessageType]; diff --git a/src/api/types/TranscribeUsageMessage.ts b/src/api/types/TranscribeUsageMessage.ts index a3649c3d..300e7623 100644 --- a/src/api/types/TranscribeUsageMessage.ts +++ b/src/api/types/TranscribeUsageMessage.ts @@ -1,9 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../index.js"; export interface TranscribeUsageMessage { - type: "usage"; + type: Corti.TranscribeUsageMessageType; /** The amount of credits used for this stream. */ credits: number; } diff --git a/src/api/types/TranscribeUsageMessageType.ts b/src/api/types/TranscribeUsageMessageType.ts new file mode 100644 index 00000000..cc765cc1 --- /dev/null +++ b/src/api/types/TranscribeUsageMessageType.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export const TranscribeUsageMessageType = { + Usage: "usage", +} as const; +export type TranscribeUsageMessageType = (typeof TranscribeUsageMessageType)[keyof typeof TranscribeUsageMessageType]; diff --git a/src/api/types/TranscriptsData.ts b/src/api/types/TranscriptsData.ts index 679c9ced..1d4dafe9 100644 --- a/src/api/types/TranscriptsData.ts +++ b/src/api/types/TranscriptsData.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscriptsData { /** Additional information about the participants involved in the transcript. */ diff --git a/src/api/types/TranscriptsListItem.ts b/src/api/types/TranscriptsListItem.ts index eaaf84b9..f45d67b7 100644 --- a/src/api/types/TranscriptsListItem.ts +++ b/src/api/types/TranscriptsListItem.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscriptsListItem { /** The unique identifier of the transcript. */ diff --git a/src/api/types/TranscriptsListResponse.ts b/src/api/types/TranscriptsListResponse.ts index fc99e04a..1e7b8412 100644 --- a/src/api/types/TranscriptsListResponse.ts +++ b/src/api/types/TranscriptsListResponse.ts @@ -1,9 +1,7 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscriptsListResponse { - transcripts?: Corti.TranscriptsListItem[] | null; + transcripts: Corti.TranscriptsListItem[] | null; } diff --git a/src/api/types/TranscriptsMetadata.ts b/src/api/types/TranscriptsMetadata.ts index 85f705bf..750e2153 100644 --- a/src/api/types/TranscriptsMetadata.ts +++ b/src/api/types/TranscriptsMetadata.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscriptsMetadata { participantsRoles?: Corti.TranscriptsParticipant[] | null; diff --git a/src/api/types/TranscriptsParticipant.ts b/src/api/types/TranscriptsParticipant.ts index e93d6f8b..6cfa4654 100644 --- a/src/api/types/TranscriptsParticipant.ts +++ b/src/api/types/TranscriptsParticipant.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscriptsParticipant { /** The audio channel to associate with a participant role. */ diff --git a/src/api/types/TranscriptsParticipantRoleEnum.ts b/src/api/types/TranscriptsParticipantRoleEnum.ts index f64ffa23..677b2305 100644 --- a/src/api/types/TranscriptsParticipantRoleEnum.ts +++ b/src/api/types/TranscriptsParticipantRoleEnum.ts @@ -1,10 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -export type TranscriptsParticipantRoleEnum = "doctor" | "patient" | "multiple"; export const TranscriptsParticipantRoleEnum = { Doctor: "doctor", Patient: "patient", Multiple: "multiple", } as const; +export type TranscriptsParticipantRoleEnum = + (typeof TranscriptsParticipantRoleEnum)[keyof typeof TranscriptsParticipantRoleEnum]; diff --git a/src/api/types/TranscriptsResponse.ts b/src/api/types/TranscriptsResponse.ts index 968063d3..122cf417 100644 --- a/src/api/types/TranscriptsResponse.ts +++ b/src/api/types/TranscriptsResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscriptsResponse { /** The unique identifier of the transcript. */ @@ -10,7 +8,7 @@ export interface TranscriptsResponse { /** Additional information about the participants involved in the transcript. */ metadata: Corti.TranscriptsMetadata; /** An array of transcripts. */ - transcripts?: Corti.CommonTranscriptResponse[] | null; + transcripts: Corti.CommonTranscriptResponse[] | null; usageInfo: Corti.CommonUsageInfo; /** The unique identifier for the associated recording. */ recordingId: Corti.Uuid; diff --git a/src/api/types/TranscriptsStatusEnum.ts b/src/api/types/TranscriptsStatusEnum.ts index b6249578..f43dff9f 100644 --- a/src/api/types/TranscriptsStatusEnum.ts +++ b/src/api/types/TranscriptsStatusEnum.ts @@ -1,13 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -/** - * Possible values for transcript processing status. - */ -export type TranscriptsStatusEnum = "completed" | "processing" | "failed"; +/** Possible values for transcript processing status. */ export const TranscriptsStatusEnum = { Completed: "completed", Processing: "processing", Failed: "failed", } as const; +export type TranscriptsStatusEnum = (typeof TranscriptsStatusEnum)[keyof typeof TranscriptsStatusEnum]; diff --git a/src/api/types/TranscriptsStatusResponse.ts b/src/api/types/TranscriptsStatusResponse.ts index 84c982a3..ca349972 100644 --- a/src/api/types/TranscriptsStatusResponse.ts +++ b/src/api/types/TranscriptsStatusResponse.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as Corti from "../index.js"; +import type * as Corti from "../index.js"; export interface TranscriptsStatusResponse { /** The current status of the transcript processing. */ diff --git a/src/api/types/Uuid.ts b/src/api/types/Uuid.ts index 5412d87a..e33bd68e 100644 --- a/src/api/types/Uuid.ts +++ b/src/api/types/Uuid.ts @@ -1,5 +1,3 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export type Uuid = string; diff --git a/src/api/types/index.ts b/src/api/types/index.ts index f52afcf8..3eb03315 100644 --- a/src/api/types/index.ts +++ b/src/api/types/index.ts @@ -1,168 +1,202 @@ +export * from "./AgentsAgent.js"; +export * from "./AgentsAgentCapabilities.js"; +export * from "./AgentsAgentCard.js"; +export * from "./AgentsAgentCardSignature.js"; +export * from "./AgentsAgentExpertsItem.js"; +export * from "./AgentsAgentExtension.js"; +export * from "./AgentsAgentInterface.js"; +export * from "./AgentsAgentProvider.js"; +export * from "./AgentsAgentReference.js"; +export * from "./AgentsAgentReferenceType.js"; +export * from "./AgentsAgentResponse.js"; +export * from "./AgentsAgentSkill.js"; +export * from "./AgentsArtifact.js"; +export * from "./AgentsContext.js"; +export * from "./AgentsContextItemsItem.js"; +export * from "./AgentsCreateExpert.js"; +export * from "./AgentsCreateExpertReference.js"; +export * from "./AgentsCreateExpertReferenceType.js"; +export * from "./AgentsCreateExpertType.js"; +export * from "./AgentsCreateMcpServer.js"; +export * from "./AgentsCreateMcpServerAuthorizationType.js"; +export * from "./AgentsCreateMcpServerTransportType.js"; +export * from "./AgentsDataPart.js"; +export * from "./AgentsDataPartKind.js"; +export * from "./AgentsExpert.js"; +export * from "./AgentsExpertReference.js"; +export * from "./AgentsExpertReferenceType.js"; +export * from "./AgentsExpertType.js"; +export * from "./AgentsFilePart.js"; +export * from "./AgentsFilePartFile.js"; +export * from "./AgentsFilePartKind.js"; +export * from "./AgentsFileWithBytes.js"; +export * from "./AgentsFileWithUri.js"; +export * from "./AgentsMcpServer.js"; +export * from "./AgentsMcpServerAuthorizationType.js"; +export * from "./AgentsMcpServerTransportType.js"; +export * from "./AgentsMessage.js"; +export * from "./AgentsMessageKind.js"; +export * from "./AgentsMessageRole.js"; +export * from "./AgentsMessageSendConfiguration.js"; +export * from "./AgentsPart.js"; +export * from "./AgentsPushNotificationAuthenticationInfo.js"; +export * from "./AgentsPushNotificationConfig.js"; +export * from "./AgentsRegistryExpert.js"; +export * from "./AgentsRegistryExpertsResponse.js"; +export * from "./AgentsRegistryMcpServer.js"; +export * from "./AgentsRegistryMcpServerAuthorizationType.js"; +export * from "./AgentsTask.js"; +export * from "./AgentsTaskKind.js"; +export * from "./AgentsTaskStatus.js"; +export * from "./AgentsTaskStatusState.js"; +export * from "./AgentsTextPart.js"; +export * from "./AgentsTextPartKind.js"; +export * from "./CodesGeneralReadResponse.js"; +export * from "./CodesGeneralReadResponseEvidencesItem.js"; +export * from "./CodesGeneralResponse.js"; +export * from "./CommonAiContext.js"; export * from "./CommonCodingSystemEnum.js"; +export * from "./CommonDocumentIdContext.js"; +export * from "./CommonDocumentIdContextType.js"; +export * from "./CommonSortingDirectionEnum.js"; +export * from "./CommonSourceEnum.js"; +export * from "./CommonTextContext.js"; +export * from "./CommonTextContextType.js"; +export * from "./CommonTranscriptRequest.js"; +export * from "./CommonTranscriptResponse.js"; +export * from "./CommonUsageInfo.js"; export * from "./DocumentsContext.js"; export * from "./DocumentsContextWithFacts.js"; -export * from "./DocumentsContextWithTranscript.js"; +export * from "./DocumentsContextWithFactsType.js"; export * from "./DocumentsContextWithString.js"; +export * from "./DocumentsContextWithStringType.js"; +export * from "./DocumentsContextWithTranscript.js"; +export * from "./DocumentsContextWithTranscriptType.js"; +export * from "./DocumentsCreateRequestBody.js"; +export * from "./DocumentsCreateRequestWithTemplate.js"; +export * from "./DocumentsCreateRequestWithTemplateKey.js"; +export * from "./DocumentsGetResponse.js"; +export * from "./DocumentsListResponse.js"; export * from "./DocumentsSection.js"; +export * from "./DocumentsSectionInput.js"; export * from "./DocumentsSectionOverride.js"; export * from "./DocumentsTemplate.js"; export * from "./DocumentsTemplateWithSectionKeys.js"; export * from "./DocumentsTemplateWithSections.js"; -export * from "./InteractionsEncounterCreateRequest.js"; -export * from "./InteractionsEncounterUpdateRequest.js"; -export * from "./InteractionsEncounterResponse.js"; -export * from "./InteractionsEncounterPeriod.js"; export * from "./ErrorResponse.js"; +export * from "./FactsBatchUpdateInput.js"; +export * from "./FactsBatchUpdateItem.js"; +export * from "./FactsBatchUpdateResponse.js"; export * from "./FactsContext.js"; -export * from "./FactsFactGroupsItemTranslationsItem.js"; -export * from "./FactsFactGroupsItem.js"; -export * from "./InteractionsPatient.js"; -export * from "./DocumentsCreateRequest.js"; -export * from "./DocumentsCreateRequestWithTemplateKey.js"; -export * from "./DocumentsCreateRequestWithTemplate.js"; -export * from "./DocumentsSectionInput.js"; -export * from "./CommonDocumentIdContext.js"; -export * from "./CommonTextContext.js"; -export * from "./CommonAiContext.js"; export * from "./FactsCreateInput.js"; -export * from "./FactsBatchUpdateInput.js"; -export * from "./TranscriptsParticipant.js"; -export * from "./TemplatesSectionListResponse.js"; -export * from "./TemplatesListResponse.js"; -export * from "./DocumentsListResponse.js"; -export * from "./DocumentsGetResponse.js"; -export * from "./FactsListItem.js"; export * from "./FactsCreateItem.js"; +export * from "./FactsCreateResponse.js"; export * from "./FactsEvidence.js"; +export * from "./FactsExtractResponse.js"; +export * from "./FactsExtractResponseFactsItem.js"; +export * from "./FactsFactGroupsItem.js"; +export * from "./FactsFactGroupsItemTranslationsItem.js"; export * from "./FactsFactGroupsListResponse.js"; -export * from "./FactsUpdateResponse.js"; -export * from "./FactsCreateResponse.js"; +export * from "./FactsListItem.js"; export * from "./FactsListResponse.js"; -export * from "./FactsBatchUpdateResponse.js"; -export * from "./FactsBatchUpdateItem.js"; -export * from "./CodesGeneralResponse.js"; -export * from "./CodesGeneralReadResponseEvidencesItem.js"; -export * from "./CodesGeneralReadResponse.js"; -export * from "./FactsExtractResponseFactsItem.js"; -export * from "./FactsExtractResponse.js"; -export * from "./InteractionsGetResponse.js"; +export * from "./FactsUpdateResponse.js"; export * from "./InteractionsCreateResponse.js"; -export * from "./InteractionsListResponse.js"; -export * from "./TranscriptsMetadata.js"; -export * from "./RecordingsCreateResponse.js"; -export * from "./RecordingsListResponse.js"; -export * from "./TranscriptsResponse.js"; -export * from "./TranscriptsListResponse.js"; -export * from "./TranscriptsListItem.js"; -export * from "./TranscriptsData.js"; -export * from "./TranscriptsStatusResponse.js"; -export * from "./TranscriptsStatusEnum.js"; -export * from "./TemplatesSection.js"; -export * from "./CommonSortingDirectionEnum.js"; -export * from "./TemplatesDocumentationModeEnum.js"; -export * from "./TemplatesItem.js"; -export * from "./TemplatesSectionSorted.js"; -export * from "./CommonTranscriptRequest.js"; -export * from "./CommonTranscriptResponse.js"; -export * from "./Uuid.js"; -export * from "./CommonUsageInfo.js"; +export * from "./InteractionsEncounterCreateRequest.js"; +export * from "./InteractionsEncounterPeriod.js"; +export * from "./InteractionsEncounterResponse.js"; export * from "./InteractionsEncounterStatusEnum.js"; export * from "./InteractionsEncounterTypeEnum.js"; +export * from "./InteractionsEncounterUpdateRequest.js"; export * from "./InteractionsGenderEnum.js"; -export * from "./CommonSourceEnum.js"; -export * from "./TranscriptsParticipantRoleEnum.js"; -export * from "./TemplatesWritingStyle.js"; -export * from "./TemplatesFormatRule.js"; -export * from "./TemplatesSectionTranslation.js"; -export * from "./TemplatesTranslation.js"; -export * from "./StreamConfigMessage.js"; +export * from "./InteractionsGetResponse.js"; +export * from "./InteractionsListResponse.js"; +export * from "./InteractionsPatient.js"; +export * from "./RecordingsCreateResponse.js"; +export * from "./RecordingsListResponse.js"; export * from "./StreamConfig.js"; -export * from "./StreamConfigTranscription.js"; -export * from "./StreamConfigModeType.js"; +export * from "./StreamConfigMessage.js"; +export * from "./StreamConfigMessageType.js"; export * from "./StreamConfigMode.js"; -export * from "./StreamConfigStatusMessageType.js"; +export * from "./StreamConfigModeType.js"; +export * from "./StreamConfigParticipant.js"; +export * from "./StreamConfigParticipantRole.js"; export * from "./StreamConfigStatusMessage.js"; +export * from "./StreamConfigStatusMessageType.js"; +export * from "./StreamConfigTranscription.js"; export * from "./StreamEndedMessage.js"; -export * from "./StreamFlushedMessage.js"; -export * from "./StreamUsageMessage.js"; -export * from "./StreamErrorMessage.js"; +export * from "./StreamEndedMessageType.js"; +export * from "./StreamEndMessage.js"; +export * from "./StreamEndMessageType.js"; export * from "./StreamErrorDetail.js"; -export * from "./StreamTranscriptMessage.js"; -export * from "./StreamTranscript.js"; -export * from "./StreamParticipant.js"; -export * from "./StreamConfigParticipantRole.js"; -export * from "./StreamConfigParticipant.js"; -export * from "./StreamTranscriptTime.js"; -export * from "./StreamFactsMessage.js"; +export * from "./StreamErrorMessage.js"; +export * from "./StreamErrorMessageType.js"; export * from "./StreamFact.js"; -export * from "./StreamEndMessage.js"; +export * from "./StreamFactsMessage.js"; +export * from "./StreamFactsMessageType.js"; +export * from "./StreamFlushedMessage.js"; +export * from "./StreamFlushedMessageType.js"; export * from "./StreamFlushMessage.js"; +export * from "./StreamFlushMessageType.js"; +export * from "./StreamParticipant.js"; export * from "./StreamSupportedLanguage.js"; -export * from "./TranscribeSupportedLanguage.js"; -export * from "./TranscribeConfig.js"; -export * from "./TranscribeConfigMessage.js"; +export * from "./StreamTranscript.js"; +export * from "./StreamTranscriptMessage.js"; +export * from "./StreamTranscriptMessageType.js"; +export * from "./StreamTranscriptTime.js"; +export * from "./StreamUsageMessage.js"; +export * from "./StreamUsageMessageType.js"; +export * from "./TemplatesDocumentationModeEnum.js"; +export * from "./TemplatesFormatRule.js"; +export * from "./TemplatesItem.js"; +export * from "./TemplatesListResponse.js"; +export * from "./TemplatesSection.js"; +export * from "./TemplatesSectionListResponse.js"; +export * from "./TemplatesSectionSorted.js"; +export * from "./TemplatesSectionTranslation.js"; +export * from "./TemplatesTranslation.js"; +export * from "./TemplatesWritingStyle.js"; export * from "./TranscribeCommand.js"; +export * from "./TranscribeCommandData.js"; +export * from "./TranscribeCommandMessage.js"; +export * from "./TranscribeCommandMessageType.js"; export * from "./TranscribeCommandVariable.js"; -export * from "./TranscribeConfigStatusMessageType.js"; +export * from "./TranscribeCommandVariableType.js"; +export * from "./TranscribeConfig.js"; +export * from "./TranscribeConfigMessage.js"; +export * from "./TranscribeConfigMessageType.js"; export * from "./TranscribeConfigStatusMessage.js"; -export * from "./TranscribeEndMessage.js"; -export * from "./TranscribeFlushMessage.js"; -export * from "./TranscribeUsageMessage.js"; +export * from "./TranscribeConfigStatusMessageType.js"; export * from "./TranscribeEndedMessage.js"; -export * from "./TranscribeFlushedMessage.js"; -export * from "./TranscribeErrorMessageError.js"; +export * from "./TranscribeEndedMessageType.js"; +export * from "./TranscribeEndMessage.js"; +export * from "./TranscribeEndMessageType.js"; export * from "./TranscribeErrorMessage.js"; -export * from "./TranscribeTranscriptData.js"; -export * from "./TranscribeCommandData.js"; -export * from "./TranscribeTranscriptMessage.js"; -export * from "./TranscribeCommandMessage.js"; +export * from "./TranscribeErrorMessageError.js"; +export * from "./TranscribeErrorMessageType.js"; +export * from "./TranscribeFlushedMessage.js"; +export * from "./TranscribeFlushedMessageType.js"; +export * from "./TranscribeFlushMessage.js"; +export * from "./TranscribeFlushMessageType.js"; +export * from "./TranscribeFormatting.js"; export * from "./TranscribeFormattingDates.js"; -export * from "./TranscribeFormattingTimes.js"; -export * from "./TranscribeFormattingNumbers.js"; export * from "./TranscribeFormattingMeasurements.js"; +export * from "./TranscribeFormattingNumbers.js"; export * from "./TranscribeFormattingNumericRanges.js"; export * from "./TranscribeFormattingOrdinals.js"; -export * from "./TranscribeFormatting.js"; -export * from "./AgentsTaskStatusState.js"; -export * from "./AgentsTaskStatus.js"; -export * from "./AgentsTextPart.js"; -export * from "./AgentsFileWithUri.js"; -export * from "./AgentsFileWithBytes.js"; -export * from "./AgentsFilePartFile.js"; -export * from "./AgentsFilePart.js"; -export * from "./AgentsDataPart.js"; -export * from "./AgentsPart.js"; -export * from "./AgentsMessageRole.js"; -export * from "./AgentsMessage.js"; -export * from "./AgentsArtifact.js"; -export * from "./AgentsTask.js"; -export * from "./AgentsPushNotificationAuthenticationInfo.js"; -export * from "./AgentsPushNotificationConfig.js"; -export * from "./AgentsMessageSendConfiguration.js"; -export * from "./AgentsCreateMcpServerTransportType.js"; -export * from "./AgentsCreateMcpServerAuthorizationType.js"; -export * from "./AgentsCreateMcpServer.js"; -export * from "./AgentsMcpServerTransportType.js"; -export * from "./AgentsMcpServerAuthorizationType.js"; -export * from "./AgentsMcpServer.js"; -export * from "./AgentsRegistryMcpServerAuthorizationType.js"; -export * from "./AgentsRegistryMcpServer.js"; -export * from "./AgentsAgentExpertsItem.js"; -export * from "./AgentsAgent.js"; -export * from "./AgentsAgentReference.js"; -export * from "./AgentsCreateExpert.js"; -export * from "./AgentsCreateExpertReference.js"; -export * from "./AgentsExpert.js"; -export * from "./AgentsExpertReference.js"; -export * from "./AgentsAgentResponse.js"; -export * from "./AgentsAgentInterface.js"; -export * from "./AgentsAgentProvider.js"; -export * from "./AgentsAgentCapabilities.js"; -export * from "./AgentsAgentExtension.js"; -export * from "./AgentsAgentSkill.js"; -export * from "./AgentsAgentCardSignature.js"; -export * from "./AgentsAgentCard.js"; -export * from "./AgentsContextItemsItem.js"; -export * from "./AgentsContext.js"; -export * from "./AgentsRegistryExpert.js"; -export * from "./AgentsRegistryExpertsResponse.js"; +export * from "./TranscribeFormattingTimes.js"; +export * from "./TranscribeSupportedLanguage.js"; +export * from "./TranscribeTranscriptData.js"; +export * from "./TranscribeTranscriptMessage.js"; +export * from "./TranscribeTranscriptMessageType.js"; +export * from "./TranscribeUsageMessage.js"; +export * from "./TranscribeUsageMessageType.js"; +export * from "./TranscriptsData.js"; +export * from "./TranscriptsListItem.js"; +export * from "./TranscriptsListResponse.js"; +export * from "./TranscriptsMetadata.js"; +export * from "./TranscriptsParticipant.js"; +export * from "./TranscriptsParticipantRoleEnum.js"; +export * from "./TranscriptsResponse.js"; +export * from "./TranscriptsStatusEnum.js"; +export * from "./TranscriptsStatusResponse.js"; +export * from "./Uuid.js"; diff --git a/src/auth/OAuthAuthProvider.ts b/src/auth/OAuthAuthProvider.ts new file mode 100644 index 00000000..715ebe78 --- /dev/null +++ b/src/auth/OAuthAuthProvider.ts @@ -0,0 +1,168 @@ +// This file was auto-generated by Fern from our API Definition. + +import { AuthClient } from "../api/resources/auth/client/Client.js"; +import type { BaseClientOptions } from "../BaseClient.js"; +import * as core from "../core/index.js"; +import * as errors from "../errors/index.js"; + +const CLIENT_ID_PARAM = "clientId" as const; +const CLIENT_SECRET_PARAM = "clientSecret" as const; +const TOKEN_PARAM = "token" as const; +const CLIENT_ID_REQUIRED_ERROR_MESSAGE = `${CLIENT_ID_PARAM} is required` as const; +const CLIENT_SECRET_REQUIRED_ERROR_MESSAGE = `${CLIENT_SECRET_PARAM} is required` as const; +const TOKEN_PARAM_REQUIRED_ERROR_MESSAGE = `${TOKEN_PARAM} is required. Please provide it in options.` as const; +const BUFFER_IN_MINUTES = 2 as const; + +export class OAuthAuthProvider implements core.AuthProvider { + private readonly options: BaseClientOptions & OAuthAuthProvider.ClientCredentials; + private readonly authClient: AuthClient; + private accessToken: string | undefined; + private expiresAt: Date; + private refreshPromise: Promise | undefined; + + constructor(options: OAuthAuthProvider.Options & OAuthAuthProvider.ClientCredentials) { + this.options = options; + this.authClient = new AuthClient(options); + this.expiresAt = new Date(); + } + + public static canCreate(options?: Partial): boolean { + return options?.[CLIENT_ID_PARAM] != null && options?.[CLIENT_SECRET_PARAM] != null; + } + + private async clientIdSupplier({ + endpointMetadata, + }: { + endpointMetadata?: core.EndpointMetadata; + } = {}): Promise { + const supplier = this.options[CLIENT_ID_PARAM]; + if (supplier == null) { + throw new errors.CortiError({ + message: CLIENT_ID_REQUIRED_ERROR_MESSAGE, + }); + } + return core.EndpointSupplier.get(supplier, { endpointMetadata }); + } + + private async clientSecretSupplier({ + endpointMetadata, + }: { + endpointMetadata?: core.EndpointMetadata; + } = {}): Promise { + const supplier = this.options[CLIENT_SECRET_PARAM]; + if (supplier == null) { + throw new errors.CortiError({ + message: CLIENT_SECRET_REQUIRED_ERROR_MESSAGE, + }); + } + return core.EndpointSupplier.get(supplier, { endpointMetadata }); + } + + public async getAuthRequest({ + endpointMetadata, + }: { + endpointMetadata?: core.EndpointMetadata; + } = {}): Promise { + const token = await this.getToken({ endpointMetadata }); + + return { + headers: { + Authorization: `Bearer ${token}`, + }, + }; + } + + private async getToken({ endpointMetadata }: { endpointMetadata?: core.EndpointMetadata } = {}): Promise { + if (this.accessToken && this.expiresAt > new Date()) { + return this.accessToken; + } + // If a refresh is already in progress, return the existing promise + if (this.refreshPromise != null) { + return this.refreshPromise; + } + return this.refresh({ endpointMetadata }); + } + + private async refresh({ endpointMetadata }: { endpointMetadata?: core.EndpointMetadata } = {}): Promise { + this.refreshPromise = (async () => { + try { + const clientId = await this.clientIdSupplier({ endpointMetadata }); + const clientSecret = await this.clientSecretSupplier({ endpointMetadata }); + const tokenResponse = await this.authClient.getToken({ + clientId: clientId, + clientSecret: clientSecret, + }); + + this.accessToken = tokenResponse.accessToken; + this.expiresAt = this.getExpiresAt(tokenResponse.expiresIn, BUFFER_IN_MINUTES); + return this.accessToken; + } finally { + this.refreshPromise = undefined; + } + })(); + return this.refreshPromise; + } + + private getExpiresAt(expiresInSeconds: number, bufferInMinutes: number): Date { + const now = new Date(); + return new Date(now.getTime() + expiresInSeconds * 1000 - bufferInMinutes * 60 * 1000); + } +} + +export class OAuthTokenOverrideAuthProvider implements core.AuthProvider { + private readonly options: OAuthAuthProvider.TokenOverride; + + constructor(options: OAuthAuthProvider.TokenOverride) { + this.options = options; + } + + public static canCreate( + options?: Partial, + ): options is OAuthAuthProvider.TokenOverride { + return options?.[TOKEN_PARAM] != null; + } + + public async getAuthRequest({ + endpointMetadata, + }: { + endpointMetadata?: core.EndpointMetadata; + } = {}): Promise { + const token = this.options[TOKEN_PARAM]; + if (token == null) { + throw new errors.CortiError({ + message: TOKEN_PARAM_REQUIRED_ERROR_MESSAGE, + }); + } + return { + headers: { + Authorization: `Bearer ${await core.EndpointSupplier.get(token, { endpointMetadata })}`, + }, + }; + } +} + +export namespace OAuthAuthProvider { + export const AUTH_SCHEME = "OAuth" as const; + export const AUTH_CONFIG_ERROR_MESSAGE: string = + `Insufficient options to create OAuthAuthProvider. Please provide '${CLIENT_ID_PARAM}' and '${CLIENT_SECRET_PARAM}', or ${TOKEN_PARAM}.` as const; + export type ClientCredentials = { + [CLIENT_ID_PARAM]: core.Supplier; + [CLIENT_SECRET_PARAM]: core.Supplier; + }; + export type TokenOverride = { + [TOKEN_PARAM]: core.Supplier; + }; + export type AuthOptions = ClientCredentials | TokenOverride; + export type Options = BaseClientOptions & AuthOptions; + + export function createInstance(options: Options): core.AuthProvider { + if (OAuthTokenOverrideAuthProvider.canCreate(options)) { + return new OAuthTokenOverrideAuthProvider(options); + } else if (OAuthAuthProvider.canCreate(options)) { + return new OAuthAuthProvider(options); + } + throw new errors.CortiError({ + message: AUTH_CONFIG_ERROR_MESSAGE, + }); + } +} diff --git a/src/auth/index.ts b/src/auth/index.ts new file mode 100644 index 00000000..83e326d1 --- /dev/null +++ b/src/auth/index.ts @@ -0,0 +1 @@ +export { OAuthAuthProvider } from "./OAuthAuthProvider.js"; diff --git a/src/core/auth/AuthProvider.ts b/src/core/auth/AuthProvider.ts new file mode 100644 index 00000000..895a50ff --- /dev/null +++ b/src/core/auth/AuthProvider.ts @@ -0,0 +1,6 @@ +import type { EndpointMetadata } from "../fetcher/EndpointMetadata.js"; +import type { AuthRequest } from "./AuthRequest.js"; + +export interface AuthProvider { + getAuthRequest(arg?: { endpointMetadata?: EndpointMetadata }): Promise; +} diff --git a/src/core/auth/AuthRequest.ts b/src/core/auth/AuthRequest.ts new file mode 100644 index 00000000..f6218b42 --- /dev/null +++ b/src/core/auth/AuthRequest.ts @@ -0,0 +1,9 @@ +/** + * Request parameters for authentication requests. + */ +export interface AuthRequest { + /** + * The headers to be included in the request. + */ + headers: Record; +} diff --git a/src/core/auth/BasicAuth.ts b/src/core/auth/BasicAuth.ts index 1c0d8835..a6423591 100644 --- a/src/core/auth/BasicAuth.ts +++ b/src/core/auth/BasicAuth.ts @@ -18,7 +18,8 @@ export const BasicAuth = { fromAuthorizationHeader: (header: string): BasicAuth => { const credentials = header.replace(BASIC_AUTH_HEADER_PREFIX, ""); const decoded = base64Decode(credentials); - const [username, password] = decoded.split(":", 2); + const [username, ...passwordParts] = decoded.split(":"); + const password = passwordParts.length > 0 ? passwordParts.join(":") : undefined; if (username == null || password == null) { throw new Error("Invalid basic auth"); diff --git a/src/core/auth/BearerToken.ts b/src/core/auth/BearerToken.ts index fe987fc9..c44a06c3 100644 --- a/src/core/auth/BearerToken.ts +++ b/src/core/auth/BearerToken.ts @@ -2,13 +2,18 @@ export type BearerToken = string; const BEARER_AUTH_HEADER_PREFIX = /^Bearer /i; -export const BearerToken = { - toAuthorizationHeader: (token: BearerToken | undefined): string | undefined => { - if (token == null) { - return undefined; - } - return `Bearer ${token}`; - }, +function toAuthorizationHeader(token: string | undefined): string | undefined { + if (token == null) { + return undefined; + } + return `Bearer ${token}`; +} + +export const BearerToken: { + toAuthorizationHeader: typeof toAuthorizationHeader; + fromAuthorizationHeader: (header: string) => BearerToken; +} = { + toAuthorizationHeader: toAuthorizationHeader, fromAuthorizationHeader: (header: string): BearerToken => { return header.replace(BEARER_AUTH_HEADER_PREFIX, "").trim() as BearerToken; }, diff --git a/src/core/auth/NoOpAuthProvider.ts b/src/core/auth/NoOpAuthProvider.ts new file mode 100644 index 00000000..5b7acfd2 --- /dev/null +++ b/src/core/auth/NoOpAuthProvider.ts @@ -0,0 +1,8 @@ +import type { AuthProvider } from "./AuthProvider.js"; +import type { AuthRequest } from "./AuthRequest.js"; + +export class NoOpAuthProvider implements AuthProvider { + public getAuthRequest(): Promise { + return Promise.resolve({ headers: {} }); + } +} diff --git a/src/core/auth/OAuthTokenProvider.ts b/src/core/auth/OAuthTokenProvider.ts deleted file mode 100644 index 88cae0be..00000000 --- a/src/core/auth/OAuthTokenProvider.ts +++ /dev/null @@ -1,57 +0,0 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ - -import * as core from "../../core/index.js"; -import { Auth } from "../../api/resources/auth/client/Client.js"; - -/** - * The OAuthTokenProvider retrieves an OAuth access token, refreshing it as needed. - * The access token is then used as the bearer token in every authenticated request. - */ -export class OAuthTokenProvider { - private readonly BUFFER_IN_MINUTES = 2; - private readonly _clientId: core.Supplier; - private readonly _clientSecret: core.Supplier; - private readonly _authClient: Auth; - private _accessToken: string | undefined; - private _expiresAt: Date; - - constructor({ - clientId, - clientSecret, - authClient, - }: { - clientId: core.Supplier; - clientSecret: core.Supplier; - authClient: Auth; - }) { - this._clientId = clientId; - this._clientSecret = clientSecret; - this._authClient = authClient; - this._expiresAt = new Date(); - } - - public async getToken(): Promise { - if (this._accessToken && this._expiresAt > new Date()) { - return this._accessToken; - } - return this.refresh(); - } - - private async refresh(): Promise { - const tokenResponse = await this._authClient.getToken({ - clientId: await core.Supplier.get(this._clientId), - clientSecret: await core.Supplier.get(this._clientSecret), - }); - - this._accessToken = tokenResponse.accessToken; - this._expiresAt = this.getExpiresAt(tokenResponse.expiresIn, this.BUFFER_IN_MINUTES); - return this._accessToken; - } - - private getExpiresAt(expiresInSeconds: number, bufferInMinutes: number): Date { - const now = new Date(); - return new Date(now.getTime() + expiresInSeconds * 1000 - bufferInMinutes * 60 * 1000); - } -} diff --git a/src/core/auth/index.ts b/src/core/auth/index.ts index 1ec5eb4b..2215b227 100644 --- a/src/core/auth/index.ts +++ b/src/core/auth/index.ts @@ -1,3 +1,5 @@ +export type { AuthProvider } from "./AuthProvider.js"; +export type { AuthRequest } from "./AuthRequest.js"; export { BasicAuth } from "./BasicAuth.js"; export { BearerToken } from "./BearerToken.js"; -export { OAuthTokenProvider } from "./OAuthTokenProvider.js"; +export { NoOpAuthProvider } from "./NoOpAuthProvider.js"; diff --git a/src/core/exports.ts b/src/core/exports.ts index e415a8f6..3c60fd49 100644 --- a/src/core/exports.ts +++ b/src/core/exports.ts @@ -1 +1,4 @@ export * from "./file/exports.js"; +export * from "./logging/exports.js"; +export * from "./pagination/exports.js"; +export * from "./websocket/exports.js"; diff --git a/src/core/fetcher/APIResponse.ts b/src/core/fetcher/APIResponse.ts index dd4b9466..97ab83c2 100644 --- a/src/core/fetcher/APIResponse.ts +++ b/src/core/fetcher/APIResponse.ts @@ -1,4 +1,4 @@ -import { RawResponse } from "./RawResponse.js"; +import type { RawResponse } from "./RawResponse.js"; /** * The response of an API call. diff --git a/src/core/fetcher/BinaryResponse.ts b/src/core/fetcher/BinaryResponse.ts index 614cb59b..bca7f4c7 100644 --- a/src/core/fetcher/BinaryResponse.ts +++ b/src/core/fetcher/BinaryResponse.ts @@ -1,25 +1,23 @@ -import { ResponseWithBody } from "./ResponseWithBody.js"; - export type BinaryResponse = { /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bodyUsed) */ - bodyUsed: boolean; + bodyUsed: Response["bodyUsed"]; /** * Returns a ReadableStream of the response body. * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/body) */ - stream: () => ReadableStream; + stream: () => Response["body"]; /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/arrayBuffer) */ - arrayBuffer: () => Promise; + arrayBuffer: () => ReturnType; /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/blob) */ - blob: () => Promise; + blob: () => ReturnType; /** * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bytes) * Some versions of the Fetch API may not support this method. */ - bytes?(): Promise; + bytes?(): ReturnType; }; -export function getBinaryResponse(response: ResponseWithBody): BinaryResponse { +export function getBinaryResponse(response: Response): BinaryResponse { const binaryResponse: BinaryResponse = { get bodyUsed() { return response.bodyUsed; diff --git a/src/core/fetcher/EndpointMetadata.ts b/src/core/fetcher/EndpointMetadata.ts new file mode 100644 index 00000000..998d68f5 --- /dev/null +++ b/src/core/fetcher/EndpointMetadata.ts @@ -0,0 +1,13 @@ +export type SecuritySchemeKey = string; +/** + * A collection of security schemes, where the key is the name of the security scheme and the value is the list of scopes required for that scheme. + * All schemes in the collection must be satisfied for authentication to be successful. + */ +export type SecuritySchemeCollection = Record; +export type AuthScope = string; +export type EndpointMetadata = { + /** + * An array of security scheme collections. Each collection represents an alternative way to authenticate. + */ + security?: SecuritySchemeCollection[]; +}; diff --git a/src/core/fetcher/EndpointSupplier.ts b/src/core/fetcher/EndpointSupplier.ts new file mode 100644 index 00000000..aad81f0d --- /dev/null +++ b/src/core/fetcher/EndpointSupplier.ts @@ -0,0 +1,14 @@ +import type { EndpointMetadata } from "./EndpointMetadata.js"; +import type { Supplier } from "./Supplier.js"; + +type EndpointSupplierFn = (arg: { endpointMetadata?: EndpointMetadata }) => T | Promise; +export type EndpointSupplier = Supplier | EndpointSupplierFn; +export const EndpointSupplier = { + get: async (supplier: EndpointSupplier, arg: { endpointMetadata?: EndpointMetadata }): Promise => { + if (typeof supplier === "function") { + return (supplier as EndpointSupplierFn)(arg); + } else { + return supplier; + } + }, +}; diff --git a/src/core/fetcher/Fetcher.ts b/src/core/fetcher/Fetcher.ts index 14c61917..5e5058a9 100644 --- a/src/core/fetcher/Fetcher.ts +++ b/src/core/fetcher/Fetcher.ts @@ -1,19 +1,17 @@ -/** - * Patch: respect CortiClient withCredentials. When args.withCredentials is undefined, - * use the global default set by CortiClient (see src/custom/withCredentialsConfig.ts). - */ import { toJson } from "../json.js"; -import { APIResponse } from "./APIResponse.js"; -import { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; -import { Supplier } from "./Supplier.js"; +import { createLogger, type LogConfig, type Logger } from "../logging/logger.js"; +import type { APIResponse } from "./APIResponse.js"; import { createRequestUrl } from "./createRequestUrl.js"; +import type { EndpointMetadata } from "./EndpointMetadata.js"; +import { EndpointSupplier } from "./EndpointSupplier.js"; import { getErrorResponseBody } from "./getErrorResponseBody.js"; import { getFetchFn } from "./getFetchFn.js"; import { getRequestBody } from "./getRequestBody.js"; import { getResponseBody } from "./getResponseBody.js"; +import { Headers } from "./Headers.js"; import { makeRequest } from "./makeRequest.js"; +import { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; import { requestWithRetries } from "./requestWithRetries.js"; -import { getDefaultWithCredentials } from "../../custom/utils/withCredentialsConfig.js"; export type FetchFunction = (args: Fetcher.Args) => Promise>; @@ -22,19 +20,22 @@ export declare namespace Fetcher { url: string; method: string; contentType?: string; - headers?: Record | undefined>; - queryParameters?: Record; + headers?: Record; + queryParameters?: Record; body?: unknown; timeoutMs?: number; maxRetries?: number; withCredentials?: boolean; abortSignal?: AbortSignal; - requestType?: "json" | "file" | "bytes"; + requestType?: "json" | "file" | "bytes" | "form" | "other"; responseType?: "json" | "blob" | "sse" | "streaming" | "text" | "arrayBuffer" | "binary-response"; duplex?: "half"; + endpointMetadata?: EndpointMetadata; + fetchFn?: typeof fetch; + logging?: LogConfig | Logger; } - export type Error = FailedStatusCodeError | NonJsonError | TimeoutError | UnknownError; + export type Error = FailedStatusCodeError | NonJsonError | BodyIsNullError | TimeoutError | UnknownError; export interface FailedStatusCodeError { reason: "status-code"; @@ -48,6 +49,11 @@ export declare namespace Fetcher { rawBody: string; } + export interface BodyIsNullError { + reason: "body-is-null"; + statusCode: number; + } + export interface TimeoutError { reason: "timeout"; } @@ -58,10 +64,170 @@ export declare namespace Fetcher { } } -async function getHeaders(args: Fetcher.Args): Promise> { - const newHeaders: Record = {}; +const SENSITIVE_HEADERS = new Set([ + "authorization", + "www-authenticate", + "x-api-key", + "api-key", + "apikey", + "x-api-token", + "x-auth-token", + "auth-token", + "cookie", + "set-cookie", + "proxy-authorization", + "proxy-authenticate", + "x-csrf-token", + "x-xsrf-token", + "x-session-token", + "x-access-token", +]); + +function redactHeaders(headers: Headers | Record): Record { + const filtered: Record = {}; + for (const [key, value] of headers instanceof Headers ? headers.entries() : Object.entries(headers)) { + if (SENSITIVE_HEADERS.has(key.toLowerCase())) { + filtered[key] = "[REDACTED]"; + } else { + filtered[key] = value; + } + } + return filtered; +} + +const SENSITIVE_QUERY_PARAMS = new Set([ + "api_key", + "api-key", + "apikey", + "token", + "access_token", + "access-token", + "auth_token", + "auth-token", + "password", + "passwd", + "secret", + "api_secret", + "api-secret", + "apisecret", + "key", + "session", + "session_id", + "session-id", +]); + +function redactQueryParameters(queryParameters?: Record): Record | undefined { + if (queryParameters == null) { + return queryParameters; + } + const redacted: Record = {}; + for (const [key, value] of Object.entries(queryParameters)) { + if (SENSITIVE_QUERY_PARAMS.has(key.toLowerCase())) { + redacted[key] = "[REDACTED]"; + } else { + redacted[key] = value; + } + } + return redacted; +} + +function redactUrl(url: string): string { + const protocolIndex = url.indexOf("://"); + if (protocolIndex === -1) return url; + + const afterProtocol = protocolIndex + 3; + + // Find the first delimiter that marks the end of the authority section + const pathStart = url.indexOf("/", afterProtocol); + let queryStart = url.indexOf("?", afterProtocol); + let fragmentStart = url.indexOf("#", afterProtocol); + + const firstDelimiter = Math.min( + pathStart === -1 ? url.length : pathStart, + queryStart === -1 ? url.length : queryStart, + fragmentStart === -1 ? url.length : fragmentStart, + ); + + // Find the LAST @ before the delimiter (handles multiple @ in credentials) + let atIndex = -1; + for (let i = afterProtocol; i < firstDelimiter; i++) { + if (url[i] === "@") { + atIndex = i; + } + } + + if (atIndex !== -1) { + url = `${url.slice(0, afterProtocol)}[REDACTED]@${url.slice(atIndex + 1)}`; + } + + // Recalculate queryStart since url might have changed + queryStart = url.indexOf("?"); + if (queryStart === -1) return url; + + fragmentStart = url.indexOf("#", queryStart); + const queryEnd = fragmentStart !== -1 ? fragmentStart : url.length; + const queryString = url.slice(queryStart + 1, queryEnd); + + if (queryString.length === 0) return url; + + // FAST PATH: Quick check if any sensitive keywords present + // Using indexOf is faster than regex for simple substring matching + const lower = queryString.toLowerCase(); + const hasSensitive = + lower.includes("token") || + lower.includes("key") || + lower.includes("password") || + lower.includes("passwd") || + lower.includes("secret") || + lower.includes("session") || + lower.includes("auth"); + + if (!hasSensitive) { + return url; + } + + // SLOW PATH: Parse and redact + const redactedParams: string[] = []; + const params = queryString.split("&"); + + for (const param of params) { + const equalIndex = param.indexOf("="); + if (equalIndex === -1) { + redactedParams.push(param); + continue; + } + + const key = param.slice(0, equalIndex); + let shouldRedact = SENSITIVE_QUERY_PARAMS.has(key.toLowerCase()); + + if (!shouldRedact && key.includes("%")) { + try { + const decodedKey = decodeURIComponent(key); + shouldRedact = SENSITIVE_QUERY_PARAMS.has(decodedKey.toLowerCase()); + } catch {} + } + + redactedParams.push(shouldRedact ? `${key}=[REDACTED]` : param); + } + + return url.slice(0, queryStart + 1) + redactedParams.join("&") + url.slice(queryEnd); +} + +async function getHeaders(args: Fetcher.Args): Promise { + const newHeaders: Headers = new Headers(); + + newHeaders.set( + "Accept", + args.responseType === "json" + ? "application/json" + : args.responseType === "text" + ? "text/plain" + : args.responseType === "sse" + ? "text/event-stream" + : "*/*", + ); if (args.body !== undefined && args.contentType != null) { - newHeaders["Content-Type"] = args.contentType; + newHeaders.set("Content-Type", args.contentType); } if (args.headers == null) { @@ -69,15 +235,15 @@ async function getHeaders(args: Fetcher.Args): Promise> { } for (const [key, value] of Object.entries(args.headers)) { - const result = await Supplier.get(value); + const result = await EndpointSupplier.get(value, { endpointMetadata: args.endpointMetadata ?? {} }); if (typeof result === "string") { - newHeaders[key] = result; + newHeaders.set(key, result); continue; } if (result == null) { continue; } - newHeaders[key] = `${result}`; + newHeaders.set(key, `${result}`); } return newHeaders; } @@ -86,9 +252,22 @@ export async function fetcherImpl(args: Fetcher.Args): Promise(args: Fetcher.Args): Promise= 200 && response.status < 400) { + if (logger.isDebug()) { + const metadata = { + method: args.method, + url: redactUrl(url), + statusCode: response.status, + responseHeaders: redactHeaders(response.headers), + }; + logger.debug("HTTP request succeeded", metadata); + } + const body = await getResponseBody(response, args.responseType); return { ok: true, - body: (await getResponseBody(response, args.responseType)) as R, + body: body as R, headers: response.headers, rawResponse: toRawResponse(response), }; } else { + if (logger.isError()) { + const metadata = { + method: args.method, + url: redactUrl(url), + statusCode: response.status, + responseHeaders: redactHeaders(Object.fromEntries(response.headers.entries())), + }; + logger.error("HTTP request failed with error status", metadata); + } return { ok: false, error: { @@ -126,7 +324,14 @@ export async function fetcherImpl(args: Fetcher.Args): Promise(args: Fetcher.Args): Promise(args: Fetcher.Args): Promise(args: Fetcher.Args): Promise; -}; - -export function isResponseWithBody(response: Response): response is ResponseWithBody { - return (response as ResponseWithBody).body != null; -} diff --git a/src/core/fetcher/getErrorResponseBody.ts b/src/core/fetcher/getErrorResponseBody.ts index 450424bd..7cf4e623 100644 --- a/src/core/fetcher/getErrorResponseBody.ts +++ b/src/core/fetcher/getErrorResponseBody.ts @@ -16,9 +16,10 @@ export async function getErrorResponseBody(response: Response): Promise case "application/ld+json": case "application/problem+json": case "application/vnd.api+json": - case "text/json": + case "text/json": { const text = await response.text(); return text.length > 0 ? fromJson(text) : undefined; + } default: if (contentType.startsWith("application/vnd.") && contentType.endsWith("+json")) { const text = await response.text(); diff --git a/src/core/fetcher/getRequestBody.ts b/src/core/fetcher/getRequestBody.ts index e38457c5..91d9d81f 100644 --- a/src/core/fetcher/getRequestBody.ts +++ b/src/core/fetcher/getRequestBody.ts @@ -1,13 +1,17 @@ import { toJson } from "../json.js"; +import { toQueryString } from "../url/qs.js"; export declare namespace GetRequestBody { interface Args { body: unknown; - type: "json" | "file" | "bytes" | "other"; + type: "json" | "file" | "bytes" | "form" | "other"; } } export async function getRequestBody({ body, type }: GetRequestBody.Args): Promise { + if (type === "form") { + return toQueryString(body, { arrayFormat: "repeat", encode: true }); + } if (type.includes("json")) { return toJson(body); } else { diff --git a/src/core/fetcher/getResponseBody.ts b/src/core/fetcher/getResponseBody.ts index 7ca8b3d2..708d5572 100644 --- a/src/core/fetcher/getResponseBody.ts +++ b/src/core/fetcher/getResponseBody.ts @@ -1,11 +1,7 @@ -import { getBinaryResponse } from "./BinaryResponse.js"; -import { isResponseWithBody } from "./ResponseWithBody.js"; import { fromJson } from "../json.js"; +import { getBinaryResponse } from "./BinaryResponse.js"; export async function getResponseBody(response: Response, responseType?: string): Promise { - if (!isResponseWithBody(response)) { - return undefined; - } switch (responseType) { case "binary-response": return getBinaryResponse(response); @@ -14,8 +10,27 @@ export async function getResponseBody(response: Response, responseType?: string) case "arrayBuffer": return await response.arrayBuffer(); case "sse": + if (response.body == null) { + return { + ok: false, + error: { + reason: "body-is-null", + statusCode: response.status, + }, + }; + } return response.body; case "streaming": + if (response.body == null) { + return { + ok: false, + error: { + reason: "body-is-null", + statusCode: response.status, + }, + }; + } + return response.body; case "text": @@ -26,9 +41,9 @@ export async function getResponseBody(response: Response, responseType?: string) const text = await response.text(); if (text.length > 0) { try { - let responseBody = fromJson(text); + const responseBody = fromJson(text); return responseBody; - } catch (err) { + } catch (_err) { return { ok: false, error: { diff --git a/src/core/fetcher/index.ts b/src/core/fetcher/index.ts index 49e13932..c3bc6da2 100644 --- a/src/core/fetcher/index.ts +++ b/src/core/fetcher/index.ts @@ -1,9 +1,11 @@ export type { APIResponse } from "./APIResponse.js"; -export { fetcher } from "./Fetcher.js"; +export type { BinaryResponse } from "./BinaryResponse.js"; +export type { EndpointMetadata } from "./EndpointMetadata.js"; +export { EndpointSupplier } from "./EndpointSupplier.js"; export type { Fetcher, FetchFunction } from "./Fetcher.js"; +export { fetcher } from "./Fetcher.js"; export { getHeader } from "./getHeader.js"; -export { Supplier } from "./Supplier.js"; -export { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; -export type { RawResponse, WithRawResponse } from "./RawResponse.js"; export { HttpResponsePromise } from "./HttpResponsePromise.js"; -export { BinaryResponse } from "./BinaryResponse.js"; +export type { RawResponse, WithRawResponse } from "./RawResponse.js"; +export { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; +export { Supplier } from "./Supplier.js"; diff --git a/src/core/fetcher/makeRequest.ts b/src/core/fetcher/makeRequest.ts index 1a5ffd3c..921565eb 100644 --- a/src/core/fetcher/makeRequest.ts +++ b/src/core/fetcher/makeRequest.ts @@ -4,7 +4,7 @@ export const makeRequest = async ( fetchFn: (url: string, init: RequestInit) => Promise, url: string, method: string, - headers: Record, + headers: Headers | Record, requestBody: BodyInit | undefined, timeoutMs?: number, abortSignal?: AbortSignal, @@ -13,19 +13,17 @@ export const makeRequest = async ( ): Promise => { const signals: AbortSignal[] = []; - // Add timeout signal - let timeoutAbortId: NodeJS.Timeout | undefined = undefined; + let timeoutAbortId: ReturnType | undefined; if (timeoutMs != null) { const { signal, abortId } = getTimeoutSignal(timeoutMs); timeoutAbortId = abortId; signals.push(signal); } - // Add arbitrary signal if (abortSignal != null) { signals.push(abortSignal); } - let newSignals = anySignal(signals); + const newSignals = anySignal(signals); const response = await fetchFn(url, { method: method, headers, diff --git a/src/core/fetcher/requestWithRetries.ts b/src/core/fetcher/requestWithRetries.ts index add3cce0..1f689688 100644 --- a/src/core/fetcher/requestWithRetries.ts +++ b/src/core/fetcher/requestWithRetries.ts @@ -3,12 +3,47 @@ const MAX_RETRY_DELAY = 60000; // in milliseconds const DEFAULT_MAX_RETRIES = 2; const JITTER_FACTOR = 0.2; // 20% random jitter -function addJitter(delay: number): number { - // Generate a random value between -JITTER_FACTOR and +JITTER_FACTOR - const jitterMultiplier = 1 + (Math.random() * 2 - 1) * JITTER_FACTOR; +function addPositiveJitter(delay: number): number { + const jitterMultiplier = 1 + Math.random() * JITTER_FACTOR; return delay * jitterMultiplier; } +function addSymmetricJitter(delay: number): number { + const jitterMultiplier = 1 + (Math.random() - 0.5) * JITTER_FACTOR; + return delay * jitterMultiplier; +} + +function getRetryDelayFromHeaders(response: Response, retryAttempt: number): number { + const retryAfter = response.headers.get("Retry-After"); + if (retryAfter) { + const retryAfterSeconds = parseInt(retryAfter, 10); + if (!Number.isNaN(retryAfterSeconds) && retryAfterSeconds > 0) { + return Math.min(retryAfterSeconds * 1000, MAX_RETRY_DELAY); + } + + const retryAfterDate = new Date(retryAfter); + if (!Number.isNaN(retryAfterDate.getTime())) { + const delay = retryAfterDate.getTime() - Date.now(); + if (delay > 0) { + return Math.min(Math.max(delay, 0), MAX_RETRY_DELAY); + } + } + } + + const rateLimitReset = response.headers.get("X-RateLimit-Reset"); + if (rateLimitReset) { + const resetTime = parseInt(rateLimitReset, 10); + if (!Number.isNaN(resetTime)) { + const delay = resetTime * 1000 - Date.now(); + if (delay > 0) { + return addPositiveJitter(Math.min(delay, MAX_RETRY_DELAY)); + } + } + } + + return addSymmetricJitter(Math.min(INITIAL_RETRY_DELAY * 2 ** retryAttempt, MAX_RETRY_DELAY)); +} + export async function requestWithRetries( requestFn: () => Promise, maxRetries: number = DEFAULT_MAX_RETRIES, @@ -17,13 +52,9 @@ export async function requestWithRetries( for (let i = 0; i < maxRetries; ++i) { if ([408, 429].includes(response.status) || response.status >= 500) { - // Calculate base delay using exponential backoff (in milliseconds) - const baseDelay = Math.min(INITIAL_RETRY_DELAY * Math.pow(2, i), MAX_RETRY_DELAY); - - // Add jitter to the delay - const delayWithJitter = addJitter(baseDelay); + const delay = getRetryDelayFromHeaders(response, i); - await new Promise((resolve) => setTimeout(resolve, delayWithJitter)); + await new Promise((resolve) => setTimeout(resolve, delay)); response = await requestFn(); } else { break; diff --git a/src/core/fetcher/signals.ts b/src/core/fetcher/signals.ts index a8d32a2e..7bd3757e 100644 --- a/src/core/fetcher/signals.ts +++ b/src/core/fetcher/signals.ts @@ -1,34 +1,22 @@ const TIMEOUT = "timeout"; -export function getTimeoutSignal(timeoutMs: number): { signal: AbortSignal; abortId: NodeJS.Timeout } { +export function getTimeoutSignal(timeoutMs: number): { signal: AbortSignal; abortId: ReturnType } { const controller = new AbortController(); const abortId = setTimeout(() => controller.abort(TIMEOUT), timeoutMs); return { signal: controller.signal, abortId }; } -/** - * Returns an abort signal that is getting aborted when - * at least one of the specified abort signals is aborted. - * - * Requires at least node.js 18. - */ export function anySignal(...args: AbortSignal[] | [AbortSignal[]]): AbortSignal { - // Allowing signals to be passed either as array - // of signals or as multiple arguments. const signals = (args.length === 1 && Array.isArray(args[0]) ? args[0] : args) as AbortSignal[]; const controller = new AbortController(); for (const signal of signals) { if (signal.aborted) { - // Exiting early if one of the signals - // is already aborted. controller.abort((signal as any)?.reason); break; } - // Listening for signals and removing the listeners - // when at least one symbol is aborted. signal.addEventListener("abort", () => controller.abort((signal as any)?.reason), { signal: controller.signal, }); diff --git a/src/core/file/exports.ts b/src/core/file/exports.ts index acda0367..3b0b3967 100644 --- a/src/core/file/exports.ts +++ b/src/core/file/exports.ts @@ -1 +1 @@ -export { Uploadable } from "./types.js"; +export type { Uploadable } from "./types.js"; diff --git a/src/core/file/file.ts b/src/core/file/file.ts index bc4b7e50..0bacc484 100644 --- a/src/core/file/file.ts +++ b/src/core/file/file.ts @@ -1,4 +1,4 @@ -import { Uploadable } from "./types.js"; +import type { Uploadable } from "./types.js"; export async function toBinaryUploadRequest( file: Uploadable, @@ -20,19 +20,40 @@ export async function toBinaryUploadRequest( return request; } -async function getFileWithMetadata(file: Uploadable): Promise { +export async function toMultipartDataPart( + file: Uploadable, +): Promise<{ data: Uploadable.FileLike; filename?: string; contentType?: string }> { + const { data, filename, contentType } = await getFileWithMetadata(file, { + noSniffFileSize: true, + }); + return { + data, + filename, + contentType, + }; +} + +async function getFileWithMetadata( + file: Uploadable, + { noSniffFileSize }: { noSniffFileSize?: boolean } = {}, +): Promise { if (isFileLike(file)) { - return getFileWithMetadata({ - data: file, - }); + return getFileWithMetadata( + { + data: file, + }, + { noSniffFileSize }, + ); } + if ("path" in file) { const fs = await import("fs"); if (!fs || !fs.createReadStream) { throw new Error("File path uploads are not supported in this environment."); } const data = fs.createReadStream(file.path); - const contentLength = file.contentLength ?? (await tryGetFileSizeFromPath(file.path)); + const contentLength = + file.contentLength ?? (noSniffFileSize === true ? undefined : await tryGetFileSizeFromPath(file.path)); const filename = file.filename ?? getNameFromPath(file.path); return { data, @@ -43,7 +64,11 @@ async function getFileWithMetadata(file: Uploadable): Promise } const fileStat = await fs.promises.stat(path); return fileStat.size; - } catch (fallbackError) { + } catch (_fallbackError) { return undefined; } } @@ -92,7 +117,10 @@ function tryGetNameFromFileLike(data: Uploadable.FileLike): string | undefined { return undefined; } -async function tryGetContentLengthFromFileLike(data: Uploadable.FileLike): Promise { +async function tryGetContentLengthFromFileLike( + data: Uploadable.FileLike, + { noSniffFileSize }: { noSniffFileSize?: boolean } = {}, +): Promise { if (isBuffer(data)) { return data.length; } @@ -108,6 +136,9 @@ async function tryGetContentLengthFromFileLike(data: Uploadable.FileLike): Promi if (isFile(data)) { return data.size; } + if (noSniffFileSize === true) { + return undefined; + } if (isPathedValue(data)) { return await tryGetFileSizeFromPath(data.path.toString()); } diff --git a/src/core/headers.ts b/src/core/headers.ts index 561314d2..be45c455 100644 --- a/src/core/headers.ts +++ b/src/core/headers.ts @@ -1,17 +1,14 @@ -import * as core from "./index.js"; - -export function mergeHeaders( - ...headersArray: (Record | undefined> | undefined)[] -): Record> { - const result: Record> = {}; +export function mergeHeaders(...headersArray: (Record | null | undefined)[]): Record { + const result: Record = {}; for (const [key, value] of headersArray .filter((headers) => headers != null) .flatMap((headers) => Object.entries(headers))) { + const insensitiveKey = key.toLowerCase(); if (value != null) { - result[key] = value; - } else if (key in result) { - delete result[key]; + result[insensitiveKey] = value; + } else if (insensitiveKey in result) { + delete result[insensitiveKey]; } } @@ -19,15 +16,16 @@ export function mergeHeaders( } export function mergeOnlyDefinedHeaders( - ...headersArray: (Record | undefined> | undefined)[] -): Record> { - const result: Record> = {}; + ...headersArray: (Record | null | undefined)[] +): Record { + const result: Record = {}; for (const [key, value] of headersArray .filter((headers) => headers != null) .flatMap((headers) => Object.entries(headers))) { + const insensitiveKey = key.toLowerCase(); if (value != null) { - result[key] = value; + result[insensitiveKey] = value; } } diff --git a/src/core/index.ts b/src/core/index.ts index 8a48e319..e2aca287 100644 --- a/src/core/index.ts +++ b/src/core/index.ts @@ -1,10 +1,11 @@ export * from "./auth/index.js"; +export * from "./base64.js"; export * from "./fetcher/index.js"; +export * as file from "./file/index.js"; +export * as logging from "./logging/index.js"; +export * from "./pagination/index.js"; export * from "./runtime/index.js"; -export * as url from "./url/index.js"; export * as serialization from "./schemas/index.js"; -export * from "./websocket/index.js"; -export * from "./base64.js"; +export * as url from "./url/index.js"; export * from "./utils/index.js"; -export * from "./pagination/index.js"; -export * as file from "./file/index.js"; +export * from "./websocket/index.js"; diff --git a/src/core/logging/exports.ts b/src/core/logging/exports.ts new file mode 100644 index 00000000..88f6c00d --- /dev/null +++ b/src/core/logging/exports.ts @@ -0,0 +1,19 @@ +import * as logger from "./logger.js"; + +export namespace logging { + /** + * Configuration for logger instances. + */ + export type LogConfig = logger.LogConfig; + export type LogLevel = logger.LogLevel; + export const LogLevel: typeof logger.LogLevel = logger.LogLevel; + export type ILogger = logger.ILogger; + /** + * Console logger implementation that outputs to the console. + */ + export type ConsoleLogger = logger.ConsoleLogger; + /** + * Console logger implementation that outputs to the console. + */ + export const ConsoleLogger: typeof logger.ConsoleLogger = logger.ConsoleLogger; +} diff --git a/src/core/logging/index.ts b/src/core/logging/index.ts new file mode 100644 index 00000000..d81cc32c --- /dev/null +++ b/src/core/logging/index.ts @@ -0,0 +1 @@ +export * from "./logger.js"; diff --git a/src/core/logging/logger.ts b/src/core/logging/logger.ts new file mode 100644 index 00000000..a3f3673c --- /dev/null +++ b/src/core/logging/logger.ts @@ -0,0 +1,203 @@ +export const LogLevel = { + Debug: "debug", + Info: "info", + Warn: "warn", + Error: "error", +} as const; +export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel]; +const logLevelMap: Record = { + [LogLevel.Debug]: 1, + [LogLevel.Info]: 2, + [LogLevel.Warn]: 3, + [LogLevel.Error]: 4, +}; + +export interface ILogger { + /** + * Logs a debug message. + * @param message - The message to log + * @param args - Additional arguments to log + */ + debug(message: string, ...args: unknown[]): void; + /** + * Logs an info message. + * @param message - The message to log + * @param args - Additional arguments to log + */ + info(message: string, ...args: unknown[]): void; + /** + * Logs a warning message. + * @param message - The message to log + * @param args - Additional arguments to log + */ + warn(message: string, ...args: unknown[]): void; + /** + * Logs an error message. + * @param message - The message to log + * @param args - Additional arguments to log + */ + error(message: string, ...args: unknown[]): void; +} + +/** + * Configuration for logger initialization. + */ +export interface LogConfig { + /** + * Minimum log level to output. + * @default LogLevel.Info + */ + level?: LogLevel; + /** + * Logger implementation to use. + * @default new ConsoleLogger() + */ + logger?: ILogger; + /** + * Whether logging should be silenced. + * @default true + */ + silent?: boolean; +} + +/** + * Default console-based logger implementation. + */ +export class ConsoleLogger implements ILogger { + debug(message: string, ...args: unknown[]): void { + console.debug(message, ...args); + } + info(message: string, ...args: unknown[]): void { + console.info(message, ...args); + } + warn(message: string, ...args: unknown[]): void { + console.warn(message, ...args); + } + error(message: string, ...args: unknown[]): void { + console.error(message, ...args); + } +} + +/** + * Logger class that provides level-based logging functionality. + */ +export class Logger { + private readonly level: number; + private readonly logger: ILogger; + private readonly silent: boolean; + + /** + * Creates a new logger instance. + * @param config - Logger configuration + */ + constructor(config: Required) { + this.level = logLevelMap[config.level]; + this.logger = config.logger; + this.silent = config.silent; + } + + /** + * Checks if a log level should be output based on configuration. + * @param level - The log level to check + * @returns True if the level should be logged + */ + public shouldLog(level: LogLevel): boolean { + return !this.silent && this.level <= logLevelMap[level]; + } + + /** + * Checks if debug logging is enabled. + * @returns True if debug logs should be output + */ + public isDebug(): boolean { + return this.shouldLog(LogLevel.Debug); + } + + /** + * Logs a debug message if debug logging is enabled. + * @param message - The message to log + * @param args - Additional arguments to log + */ + public debug(message: string, ...args: unknown[]): void { + if (this.isDebug()) { + this.logger.debug(message, ...args); + } + } + + /** + * Checks if info logging is enabled. + * @returns True if info logs should be output + */ + public isInfo(): boolean { + return this.shouldLog(LogLevel.Info); + } + + /** + * Logs an info message if info logging is enabled. + * @param message - The message to log + * @param args - Additional arguments to log + */ + public info(message: string, ...args: unknown[]): void { + if (this.isInfo()) { + this.logger.info(message, ...args); + } + } + + /** + * Checks if warning logging is enabled. + * @returns True if warning logs should be output + */ + public isWarn(): boolean { + return this.shouldLog(LogLevel.Warn); + } + + /** + * Logs a warning message if warning logging is enabled. + * @param message - The message to log + * @param args - Additional arguments to log + */ + public warn(message: string, ...args: unknown[]): void { + if (this.isWarn()) { + this.logger.warn(message, ...args); + } + } + + /** + * Checks if error logging is enabled. + * @returns True if error logs should be output + */ + public isError(): boolean { + return this.shouldLog(LogLevel.Error); + } + + /** + * Logs an error message if error logging is enabled. + * @param message - The message to log + * @param args - Additional arguments to log + */ + public error(message: string, ...args: unknown[]): void { + if (this.isError()) { + this.logger.error(message, ...args); + } + } +} + +export function createLogger(config?: LogConfig | Logger): Logger { + if (config == null) { + return defaultLogger; + } + if (config instanceof Logger) { + return config; + } + config = config ?? {}; + config.level ??= LogLevel.Info; + config.logger ??= new ConsoleLogger(); + config.silent ??= true; + return new Logger(config as Required); +} + +const defaultLogger: Logger = new Logger({ + level: LogLevel.Info, + logger: new ConsoleLogger(), + silent: true, +}); diff --git a/src/core/pagination/CustomPager.ts b/src/core/pagination/CustomPager.ts new file mode 100644 index 00000000..f9bb9186 --- /dev/null +++ b/src/core/pagination/CustomPager.ts @@ -0,0 +1,194 @@ +import type { BaseRequestOptions, NormalizedClientOptions } from "../../BaseClient.js"; +import type { APIResponse } from "../fetcher/APIResponse.js"; +import type { Fetcher } from "../fetcher/Fetcher.js"; +import type { RawResponse } from "../fetcher/index.js"; + +/** + * + * @template TItem The type of the items in the page. + * @template TResponse The type of the API response. + */ +export class CustomPager implements AsyncIterable { + /** The items from the current page */ + public data: TItem[]; + /** The raw HTTP response */ + public rawResponse: RawResponse; + /** The parsed response object */ + public response: TResponse; + + private sendRequest: (request: Fetcher.Args) => Promise>; + private nextRequest?: Fetcher.Args; + private previousRequest?: Fetcher.Args; + private _hasNextPage: boolean; + private _hasPreviousPage: boolean; + + constructor(args: { + response: TResponse; + rawResponse: RawResponse; + items: TItem[]; + hasNextPage: boolean; + hasPreviousPage: boolean; + nextRequest?: Fetcher.Args; + previousRequest?: Fetcher.Args; + sendRequest: (request: Fetcher.Args) => Promise>; + }) { + this.response = args.response; + this.rawResponse = args.rawResponse; + this.data = args.items; + this._hasNextPage = args.hasNextPage; + this._hasPreviousPage = args.hasPreviousPage; + this.nextRequest = args.nextRequest; + this.previousRequest = args.previousRequest; + this.sendRequest = args.sendRequest; + } + + /** + * @returns whether there is a next page to load + */ + public hasNextPage(): boolean { + return this._hasNextPage; + } + + /** + * @returns whether there is a previous page to load + */ + public hasPreviousPage(): boolean { + return this._hasPreviousPage; + } + + /** + * Returns the current page data. + * This is an alias for the `data` property for consistency with other pagination APIs. + * + * @returns the items from the current page + */ + public getCurrentPage(): TItem[] { + return this.data; + } + + /** + * Retrieves the next page of results. + * @returns this pager with updated data + * @throws Error if there is no next page + */ + public async getNextPage(): Promise { + if (!this._hasNextPage || !this.nextRequest) { + throw new Error("No next page available"); + } + const response = await this.sendRequest(this.nextRequest); + if (!response.ok) { + const reason = + response.error.reason === "status-code" ? `HTTP ${response.error.statusCode}` : response.error.reason; + throw new Error(`Failed to fetch next page: ${reason}`); + } + const data = response.body; + const rawResponse = response.rawResponse; + const parsed = await parse({ request: this.nextRequest, data, rawResponse }); + this.response = data; + this.rawResponse = rawResponse; + this.data = parsed.items; + this._hasNextPage = parsed.hasNextPage; + this._hasPreviousPage = parsed.hasPreviousPage; + this.nextRequest = parsed.nextRequest; + this.previousRequest = parsed.previousRequest; + return this; + } + + /** + * Retrieves the previous page of results. + * @returns this pager with updated data + * @throws Error if there is no previous page + */ + public async getPreviousPage(): Promise { + if (!this._hasPreviousPage || !this.previousRequest) { + throw new Error("No previous page available"); + } + const response = await this.sendRequest(this.previousRequest); + if (!response.ok) { + const reason = + response.error.reason === "status-code" ? `HTTP ${response.error.statusCode}` : response.error.reason; + throw new Error(`Failed to fetch previous page: ${reason}`); + } + const data = response.body; + const rawResponse = response.rawResponse; + const parsed = await parse({ request: this.previousRequest, data, rawResponse }); + this.response = data; + this.rawResponse = rawResponse; + this.data = parsed.items; + this._hasNextPage = parsed.hasNextPage; + this._hasPreviousPage = parsed.hasPreviousPage; + this.nextRequest = parsed.nextRequest; + this.previousRequest = parsed.previousRequest; + return this; + } + + private async *iterMessages(): AsyncGenerator { + for (const item of this.data) { + yield item; + } + + while (this.hasNextPage()) { + await this.getNextPage(); + for (const item of this.data) { + yield item; + } + } + } + + async *[Symbol.asyncIterator](): AsyncIterator { + for await (const message of this.iterMessages()) { + yield message; + } + } +} + +export async function createCustomPager({ + sendRequest, + initialHttpRequest, + clientOptions, +}: { + sendRequest: (request: Fetcher.Args) => Promise>; + initialHttpRequest: Fetcher.Args; + clientOptions: NormalizedClientOptions; + requestOptions?: BaseRequestOptions; +}): Promise> { + const response = await sendRequest(initialHttpRequest); + if (!response.ok) { + const reason = + response.error.reason === "status-code" ? `HTTP ${response.error.statusCode}` : response.error.reason; + throw new Error(`Failed to fetch initial page: ${reason}`); + } + const data = response.body; + const rawResponse = response.rawResponse; + const parsed = await parse({ request: initialHttpRequest, data, rawResponse }); + return new CustomPager({ + response: data, + rawResponse, + items: parsed.items, + hasNextPage: parsed.hasNextPage, + hasPreviousPage: parsed.hasPreviousPage, + nextRequest: parsed.nextRequest, + previousRequest: parsed.previousRequest, + sendRequest: sendRequest, + }); +} + +async function parse(_args: { + request: Fetcher.Args; + data: TResponse; + rawResponse: RawResponse; +}): Promise<{ + nextRequest?: Fetcher.Args; + hasNextPage: boolean; + previousRequest?: Fetcher.Args; + hasPreviousPage: boolean; + items: TItem[]; +}> { + // Placeholder implementation. + // TODO: Replace this with actual parsing logic. + return { + items: [], + hasNextPage: false, + hasPreviousPage: false, + }; +} diff --git a/src/core/pagination/Page.ts b/src/core/pagination/Page.ts index 307989ef..6621a6f1 100644 --- a/src/core/pagination/Page.ts +++ b/src/core/pagination/Page.ts @@ -1,18 +1,19 @@ -import { HttpResponsePromise, RawResponse } from "../fetcher/index.js"; +import type { HttpResponsePromise, RawResponse } from "../fetcher/index.js"; /** * A page of results from a paginated API. * * @template T The type of the items in the page. + * @template R The type of the API response. */ -export class Page implements AsyncIterable { +export class Page implements AsyncIterable { public data: T[]; public rawResponse: RawResponse; + public response: R; - private response: unknown; - private _hasNextPage: (response: unknown) => boolean; - private getItems: (response: unknown) => T[]; - private loadNextPage: (response: unknown) => HttpResponsePromise; + private _hasNextPage: (response: R) => boolean; + private getItems: (response: R) => T[]; + private loadNextPage: (response: R) => HttpResponsePromise; constructor({ response, @@ -21,11 +22,11 @@ export class Page implements AsyncIterable { getItems, loadPage, }: { - response: unknown; + response: R; rawResponse: RawResponse; - hasNextPage: (response: unknown) => boolean; - getItems: (response: unknown) => T[]; - loadPage: (response: unknown) => HttpResponsePromise; + hasNextPage: (response: R) => boolean; + getItems: (response: R) => T[]; + loadPage: (response: R) => HttpResponsePromise; }) { this.response = response; this.rawResponse = rawResponse; diff --git a/src/core/pagination/Pageable.ts b/src/core/pagination/Pageable.ts deleted file mode 100644 index faec8642..00000000 --- a/src/core/pagination/Pageable.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { RawResponse } from "../fetcher/index.js"; -import { Page } from "./Page.js"; - -export declare namespace Pageable { - interface Args { - response: Response; - rawResponse: RawResponse; - hasNextPage: (response: Response) => boolean; - getItems: (response: Response) => Item[]; - loadPage: (response: Response) => Promise; - } -} - -export class Pageable extends Page { - constructor(args: Pageable.Args) { - super(args as any); - } -} diff --git a/src/core/pagination/exports.ts b/src/core/pagination/exports.ts new file mode 100644 index 00000000..d3acc60b --- /dev/null +++ b/src/core/pagination/exports.ts @@ -0,0 +1 @@ +export type { Page } from "./Page.js"; diff --git a/src/core/pagination/index.ts b/src/core/pagination/index.ts index b0cd68fa..fe9dc949 100644 --- a/src/core/pagination/index.ts +++ b/src/core/pagination/index.ts @@ -1,2 +1,2 @@ +export { CustomPager, createCustomPager } from "./CustomPager.js"; export { Page } from "./Page.js"; -export { Pageable } from "./Pageable.js"; diff --git a/src/core/runtime/runtime.ts b/src/core/runtime/runtime.ts index 08fd2563..56ebbb87 100644 --- a/src/core/runtime/runtime.ts +++ b/src/core/runtime/runtime.ts @@ -99,6 +99,18 @@ function evaluateRuntime(): Runtime { }; } + /** + * A constant that indicates whether the environment the code is running is in React-Native. + * This check should come before Node.js detection since React Native may have a process polyfill. + * https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js + */ + const isReactNative = typeof navigator !== "undefined" && navigator?.product === "ReactNative"; + if (isReactNative) { + return { + type: "react-native", + }; + } + /** * A constant that indicates whether the environment the code is running is Node.JS. */ @@ -116,17 +128,6 @@ function evaluateRuntime(): Runtime { }; } - /** - * A constant that indicates whether the environment the code is running is in React-Native. - * https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js - */ - const isReactNative = typeof navigator !== "undefined" && navigator?.product === "ReactNative"; - if (isReactNative) { - return { - type: "react-native", - }; - } - return { type: "unknown", }; diff --git a/src/core/schemas/Schema.ts b/src/core/schemas/Schema.ts index 5216437c..4cd8b1d9 100644 --- a/src/core/schemas/Schema.ts +++ b/src/core/schemas/Schema.ts @@ -1,4 +1,4 @@ -import { SchemaUtils } from "./builders/index.js"; +import type { SchemaUtils } from "./builders/index.js"; export type Schema = BaseSchema & SchemaUtils; @@ -24,6 +24,7 @@ export const SchemaType = { NUMBER: "number", STRING: "string", UNKNOWN: "unknown", + NEVER: "never", RECORD: "record", SET: "set", UNION: "union", @@ -32,6 +33,7 @@ export const SchemaType = { OPTIONAL: "optional", OPTIONAL_NULLABLE: "optionalNullable", } as const; + export type SchemaType = (typeof SchemaType)[keyof typeof SchemaType]; export type MaybeValid = Valid | Invalid; diff --git a/src/core/schemas/builders/bigint/bigint.ts b/src/core/schemas/builders/bigint/bigint.ts index 098b4bf9..2c7c74c5 100644 --- a/src/core/schemas/builders/bigint/bigint.ts +++ b/src/core/schemas/builders/bigint/bigint.ts @@ -1,4 +1,4 @@ -import { BaseSchema, Schema, SchemaType } from "../../Schema.js"; +import { type BaseSchema, type Schema, SchemaType } from "../../Schema.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation.js"; import { getSchemaUtils } from "../schema-utils/index.js"; diff --git a/src/core/schemas/builders/date/date.ts b/src/core/schemas/builders/date/date.ts index 5afaa49b..f02e3367 100644 --- a/src/core/schemas/builders/date/date.ts +++ b/src/core/schemas/builders/date/date.ts @@ -1,4 +1,4 @@ -import { BaseSchema, Schema, SchemaType } from "../../Schema.js"; +import { type BaseSchema, type Schema, SchemaType } from "../../Schema.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation.js"; import { getSchemaUtils } from "../schema-utils/index.js"; diff --git a/src/core/schemas/builders/enum/enum.ts b/src/core/schemas/builders/enum/enum.ts index b8921867..ccae24bc 100644 --- a/src/core/schemas/builders/enum/enum.ts +++ b/src/core/schemas/builders/enum/enum.ts @@ -1,4 +1,4 @@ -import { Schema, SchemaType } from "../../Schema.js"; +import { type Schema, SchemaType } from "../../Schema.js"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; diff --git a/src/core/schemas/builders/lazy/index.ts b/src/core/schemas/builders/lazy/index.ts index e346ac9d..e8ca4099 100644 --- a/src/core/schemas/builders/lazy/index.ts +++ b/src/core/schemas/builders/lazy/index.ts @@ -1,3 +1,3 @@ -export { lazy } from "./lazy.js"; export type { SchemaGetter } from "./lazy.js"; +export { lazy } from "./lazy.js"; export { lazyObject } from "./lazyObject.js"; diff --git a/src/core/schemas/builders/lazy/lazy.ts b/src/core/schemas/builders/lazy/lazy.ts index c3ec78fe..37f28871 100644 --- a/src/core/schemas/builders/lazy/lazy.ts +++ b/src/core/schemas/builders/lazy/lazy.ts @@ -1,4 +1,4 @@ -import { BaseSchema, Schema } from "../../Schema.js"; +import type { BaseSchema, Schema } from "../../Schema.js"; import { getSchemaUtils } from "../schema-utils/index.js"; export type SchemaGetter> = () => SchemaType; diff --git a/src/core/schemas/builders/lazy/lazyObject.ts b/src/core/schemas/builders/lazy/lazyObject.ts index 0971f921..192c90e5 100644 --- a/src/core/schemas/builders/lazy/lazyObject.ts +++ b/src/core/schemas/builders/lazy/lazyObject.ts @@ -1,8 +1,8 @@ import { getObjectUtils } from "../object/index.js"; +import type { BaseObjectSchema, ObjectSchema } from "../object/types.js"; import { getObjectLikeUtils } from "../object-like/index.js"; -import { BaseObjectSchema, ObjectSchema } from "../object/types.js"; import { getSchemaUtils } from "../schema-utils/index.js"; -import { SchemaGetter, constructLazyBaseSchema, getMemoizedSchema } from "./lazy.js"; +import { constructLazyBaseSchema, getMemoizedSchema, type SchemaGetter } from "./lazy.js"; export function lazyObject(getter: SchemaGetter>): ObjectSchema { const baseSchema: BaseObjectSchema = { diff --git a/src/core/schemas/builders/list/list.ts b/src/core/schemas/builders/list/list.ts index 4cee68ee..4f8c10ba 100644 --- a/src/core/schemas/builders/list/list.ts +++ b/src/core/schemas/builders/list/list.ts @@ -1,4 +1,4 @@ -import { BaseSchema, MaybeValid, Schema, SchemaType, ValidationError } from "../../Schema.js"; +import { type BaseSchema, type MaybeValid, type Schema, SchemaType, type ValidationError } from "../../Schema.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation.js"; import { getSchemaUtils } from "../schema-utils/index.js"; diff --git a/src/core/schemas/builders/literals/booleanLiteral.ts b/src/core/schemas/builders/literals/booleanLiteral.ts index 0bebfb5b..db5d2c7a 100644 --- a/src/core/schemas/builders/literals/booleanLiteral.ts +++ b/src/core/schemas/builders/literals/booleanLiteral.ts @@ -1,4 +1,4 @@ -import { Schema, SchemaType } from "../../Schema.js"; +import { type Schema, SchemaType } from "../../Schema.js"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; diff --git a/src/core/schemas/builders/literals/index.ts b/src/core/schemas/builders/literals/index.ts index fb172c47..4a4ab39d 100644 --- a/src/core/schemas/builders/literals/index.ts +++ b/src/core/schemas/builders/literals/index.ts @@ -1,2 +1,2 @@ -export { stringLiteral } from "./stringLiteral.js"; export { booleanLiteral } from "./booleanLiteral.js"; +export { stringLiteral } from "./stringLiteral.js"; diff --git a/src/core/schemas/builders/literals/stringLiteral.ts b/src/core/schemas/builders/literals/stringLiteral.ts index e3efa7bb..ce6e20ca 100644 --- a/src/core/schemas/builders/literals/stringLiteral.ts +++ b/src/core/schemas/builders/literals/stringLiteral.ts @@ -1,4 +1,4 @@ -import { Schema, SchemaType } from "../../Schema.js"; +import { type Schema, SchemaType } from "../../Schema.js"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; diff --git a/src/core/schemas/builders/object-like/getObjectLikeUtils.ts b/src/core/schemas/builders/object-like/getObjectLikeUtils.ts index 124a0828..af69acb0 100644 --- a/src/core/schemas/builders/object-like/getObjectLikeUtils.ts +++ b/src/core/schemas/builders/object-like/getObjectLikeUtils.ts @@ -1,9 +1,9 @@ -import { BaseSchema } from "../../Schema.js"; +import type { BaseSchema } from "../../Schema.js"; import { filterObject } from "../../utils/filterObject.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; import { isPlainObject } from "../../utils/isPlainObject.js"; import { getSchemaUtils } from "../schema-utils/index.js"; -import { ObjectLikeSchema, ObjectLikeUtils } from "./types.js"; +import type { ObjectLikeSchema, ObjectLikeUtils } from "./types.js"; export function getObjectLikeUtils(schema: BaseSchema): ObjectLikeUtils { return { diff --git a/src/core/schemas/builders/object-like/types.ts b/src/core/schemas/builders/object-like/types.ts index 5a49242a..44b96691 100644 --- a/src/core/schemas/builders/object-like/types.ts +++ b/src/core/schemas/builders/object-like/types.ts @@ -1,11 +1,13 @@ -import { BaseSchema, Schema } from "../../Schema.js"; +import type { BaseSchema, Schema } from "../../Schema.js"; export type ObjectLikeSchema = Schema & BaseSchema & ObjectLikeUtils; export interface ObjectLikeUtils { - withParsedProperties: >(properties: { - [K in keyof T]: T[K] | ((parsed: Parsed) => T[K]); - }) => ObjectLikeSchema; + withParsedProperties: >( + properties: { + [K in keyof T]: T[K] | ((parsed: Parsed) => T[K]); + }, + ) => ObjectLikeSchema; } diff --git a/src/core/schemas/builders/object/index.ts b/src/core/schemas/builders/object/index.ts index a6337fac..c6611aaa 100644 --- a/src/core/schemas/builders/object/index.ts +++ b/src/core/schemas/builders/object/index.ts @@ -1,11 +1,11 @@ export { getObjectUtils, object } from "./object.js"; -export { objectWithoutOptionalProperties } from "./objectWithoutOptionalProperties.js"; export type { inferObjectWithoutOptionalPropertiesSchemaFromPropertySchemas, inferParsedObjectWithoutOptionalPropertiesFromPropertySchemas, } from "./objectWithoutOptionalProperties.js"; -export { isProperty, property } from "./property.js"; +export { objectWithoutOptionalProperties } from "./objectWithoutOptionalProperties.js"; export type { Property } from "./property.js"; +export { isProperty, property } from "./property.js"; export type { BaseObjectSchema, inferObjectSchemaFromPropertySchemas, diff --git a/src/core/schemas/builders/object/object.ts b/src/core/schemas/builders/object/object.ts index bdb8c89c..9ec570a1 100644 --- a/src/core/schemas/builders/object/object.ts +++ b/src/core/schemas/builders/object/object.ts @@ -1,4 +1,4 @@ -import { MaybeValid, Schema, SchemaType, ValidationError } from "../../Schema.js"; +import { type MaybeValid, type Schema, SchemaType, type ValidationError } from "../../Schema.js"; import { entries } from "../../utils/entries.js"; import { filterObject } from "../../utils/filterObject.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; @@ -9,14 +9,14 @@ import { partition } from "../../utils/partition.js"; import { getObjectLikeUtils } from "../object-like/index.js"; import { getSchemaUtils } from "../schema-utils/index.js"; import { isProperty } from "./property.js"; -import { +import type { BaseObjectSchema, - ObjectSchema, - ObjectUtils, - PropertySchemas, inferObjectSchemaFromPropertySchemas, inferParsedObjectFromPropertySchemas, inferRawObjectFromPropertySchemas, + ObjectSchema, + ObjectUtils, + PropertySchemas, } from "./types.js"; interface ObjectPropertyWithRawKey { @@ -244,17 +244,19 @@ export function getObjectUtils(schema: BaseObjectSchema { return validateAndTransformExtendedObject({ extensionKeys: extension._getRawProperties(), - value: raw as object, + value: raw, transformBase: (rawBase) => schema.parse(rawBase, opts), transformExtension: (rawExtension) => extension.parse(rawExtension, opts), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, }); }, json: (parsed, opts) => { return validateAndTransformExtendedObject({ extensionKeys: extension._getParsedProperties(), - value: parsed as object, + value: parsed, transformBase: (parsedBase) => schema.json(parsedBase, opts), transformExtension: (parsedExtension) => extension.json(parsedExtension, opts), + breadcrumbsPrefix: opts?.breadcrumbsPrefix, }); }, getType: () => SchemaType.OBJECT, @@ -268,6 +270,8 @@ export function getObjectUtils(schema: BaseObjectSchema { + const knownRawKeys = new Set(schema._getRawProperties() as string[]); + const knownParsedKeys = new Set(schema._getParsedProperties() as string[]); const baseSchema: BaseObjectSchema = { _getParsedProperties: () => schema._getParsedProperties(), @@ -277,10 +281,18 @@ export function getObjectUtils(schema: BaseObjectSchema = {}; + if (typeof raw === "object" && raw != null) { + for (const [key, value] of Object.entries(raw)) { + if (!knownRawKeys.has(key)) { + extraProperties[key] = value; + } + } + } return { ok: true, value: { - ...(raw as any), + ...extraProperties, ...transformed.value, }, }; @@ -290,10 +302,18 @@ export function getObjectUtils(schema: BaseObjectSchema = {}; + if (typeof parsed === "object" && parsed != null) { + for (const [key, value] of Object.entries(parsed)) { + if (!knownParsedKeys.has(key)) { + extraProperties[key] = value; + } + } + } return { ok: true, value: { - ...(parsed as any), + ...extraProperties, ...transformed.value, }, }; @@ -316,12 +336,26 @@ function validateAndTransformExtendedObject MaybeValid; transformExtension: (value: object) => MaybeValid; + breadcrumbsPrefix?: string[]; }): MaybeValid { + if (!isPlainObject(value)) { + return { + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: getErrorMessageForIncorrectType(value, "object"), + }, + ], + }; + } + const extensionPropertiesSet = new Set(extensionKeys); const [extensionProperties, baseProperties] = partition(keys(value), (key) => extensionPropertiesSet.has(key as keyof PreTransformedExtension), diff --git a/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts b/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts index 5c852bef..4d39c862 100644 --- a/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts +++ b/src/core/schemas/builders/object/objectWithoutOptionalProperties.ts @@ -1,9 +1,9 @@ import { object } from "./object.js"; -import { - ObjectSchema, - PropertySchemas, +import type { inferParsedPropertySchema, inferRawObjectFromPropertySchemas, + ObjectSchema, + PropertySchemas, } from "./types.js"; export function objectWithoutOptionalProperties>( diff --git a/src/core/schemas/builders/object/property.ts b/src/core/schemas/builders/object/property.ts index 4c684fdd..d1f9f386 100644 --- a/src/core/schemas/builders/object/property.ts +++ b/src/core/schemas/builders/object/property.ts @@ -1,4 +1,4 @@ -import { Schema } from "../../Schema.js"; +import type { Schema } from "../../Schema.js"; export function property( rawKey: RawKey, diff --git a/src/core/schemas/builders/object/types.ts b/src/core/schemas/builders/object/types.ts index 4c7aa687..384ae873 100644 --- a/src/core/schemas/builders/object/types.ts +++ b/src/core/schemas/builders/object/types.ts @@ -1,8 +1,8 @@ -import { BaseSchema, Schema, inferParsed, inferRaw } from "../../Schema.js"; -import { addQuestionMarksToNullableProperties } from "../../utils/addQuestionMarksToNullableProperties.js"; -import { ObjectLikeUtils } from "../object-like/index.js"; -import { SchemaUtils } from "../schema-utils/index.js"; -import { Property } from "./property.js"; +import type { BaseSchema, inferParsed, inferRaw, Schema } from "../../Schema.js"; +import type { addQuestionMarksToNullableProperties } from "../../utils/addQuestionMarksToNullableProperties.js"; +import type { ObjectLikeUtils } from "../object-like/index.js"; +import type { SchemaUtils } from "../schema-utils/index.js"; +import type { Property } from "./property.js"; export type ObjectSchema = BaseObjectSchema & ObjectLikeUtils & diff --git a/src/core/schemas/builders/primitives/any.ts b/src/core/schemas/builders/primitives/any.ts index bff7c042..bc4d47fa 100644 --- a/src/core/schemas/builders/primitives/any.ts +++ b/src/core/schemas/builders/primitives/any.ts @@ -1,4 +1,7 @@ -import { SchemaType } from "../../Schema.js"; +import { type Schema, SchemaType } from "../../Schema.js"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js"; -export const any = createIdentitySchemaCreator(SchemaType.ANY, (value) => ({ ok: true, value })); +export const any: () => Schema = createIdentitySchemaCreator(SchemaType.ANY, (value) => ({ + ok: true, + value, +})); diff --git a/src/core/schemas/builders/primitives/boolean.ts b/src/core/schemas/builders/primitives/boolean.ts index 6d93becd..78c3c362 100644 --- a/src/core/schemas/builders/primitives/boolean.ts +++ b/src/core/schemas/builders/primitives/boolean.ts @@ -1,8 +1,8 @@ -import { SchemaType } from "../../Schema.js"; +import { type Schema, SchemaType } from "../../Schema.js"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; -export const boolean = createIdentitySchemaCreator( +export const boolean: () => Schema = createIdentitySchemaCreator( SchemaType.BOOLEAN, (value, { breadcrumbsPrefix = [] } = {}) => { if (typeof value === "boolean") { diff --git a/src/core/schemas/builders/primitives/index.ts b/src/core/schemas/builders/primitives/index.ts index 462a6d11..7a3ee015 100644 --- a/src/core/schemas/builders/primitives/index.ts +++ b/src/core/schemas/builders/primitives/index.ts @@ -1,5 +1,6 @@ export { any } from "./any.js"; export { boolean } from "./boolean.js"; +export { never } from "./never.js"; export { number } from "./number.js"; export { string } from "./string.js"; export { unknown } from "./unknown.js"; diff --git a/src/core/schemas/builders/primitives/never.ts b/src/core/schemas/builders/primitives/never.ts new file mode 100644 index 00000000..91f85d74 --- /dev/null +++ b/src/core/schemas/builders/primitives/never.ts @@ -0,0 +1,15 @@ +import { type Schema, SchemaType } from "../../Schema.js"; +import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js"; + +export const never: () => Schema = createIdentitySchemaCreator( + SchemaType.NEVER, + (_value, { breadcrumbsPrefix = [] } = {}) => ({ + ok: false, + errors: [ + { + path: breadcrumbsPrefix, + message: "Expected never", + }, + ], + }), +); diff --git a/src/core/schemas/builders/primitives/number.ts b/src/core/schemas/builders/primitives/number.ts index a927539e..6f16cd46 100644 --- a/src/core/schemas/builders/primitives/number.ts +++ b/src/core/schemas/builders/primitives/number.ts @@ -1,8 +1,8 @@ -import { SchemaType } from "../../Schema.js"; +import { type Schema, SchemaType } from "../../Schema.js"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; -export const number = createIdentitySchemaCreator( +export const number: () => Schema = createIdentitySchemaCreator( SchemaType.NUMBER, (value, { breadcrumbsPrefix = [] } = {}) => { if (typeof value === "number") { diff --git a/src/core/schemas/builders/primitives/string.ts b/src/core/schemas/builders/primitives/string.ts index fac9cd71..b29d72ae 100644 --- a/src/core/schemas/builders/primitives/string.ts +++ b/src/core/schemas/builders/primitives/string.ts @@ -1,8 +1,8 @@ -import { SchemaType } from "../../Schema.js"; +import { type Schema, SchemaType } from "../../Schema.js"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; -export const string = createIdentitySchemaCreator( +export const string: () => Schema = createIdentitySchemaCreator( SchemaType.STRING, (value, { breadcrumbsPrefix = [] } = {}) => { if (typeof value === "string") { diff --git a/src/core/schemas/builders/primitives/unknown.ts b/src/core/schemas/builders/primitives/unknown.ts index 4df0a6ce..04514160 100644 --- a/src/core/schemas/builders/primitives/unknown.ts +++ b/src/core/schemas/builders/primitives/unknown.ts @@ -1,4 +1,7 @@ -import { SchemaType } from "../../Schema.js"; +import { type Schema, SchemaType } from "../../Schema.js"; import { createIdentitySchemaCreator } from "../../utils/createIdentitySchemaCreator.js"; -export const unknown = createIdentitySchemaCreator(SchemaType.UNKNOWN, (value) => ({ ok: true, value })); +export const unknown: () => Schema = createIdentitySchemaCreator( + SchemaType.UNKNOWN, + (value) => ({ ok: true, value }), +); diff --git a/src/core/schemas/builders/record/record.ts b/src/core/schemas/builders/record/record.ts index de1d7e13..a4896603 100644 --- a/src/core/schemas/builders/record/record.ts +++ b/src/core/schemas/builders/record/record.ts @@ -1,10 +1,10 @@ -import { MaybeValid, Schema, SchemaType, ValidationError } from "../../Schema.js"; +import { type MaybeValid, type Schema, SchemaType, type ValidationError } from "../../Schema.js"; import { entries } from "../../utils/entries.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; import { isPlainObject } from "../../utils/isPlainObject.js"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation.js"; import { getSchemaUtils } from "../schema-utils/index.js"; -import { BaseRecordSchema, RecordSchema } from "./types.js"; +import type { BaseRecordSchema, RecordSchema } from "./types.js"; export function record( keySchema: Schema, @@ -90,7 +90,7 @@ function validateAndTransformRecord 0 ? Number(stringKey) : NaN; - if (!isNaN(numberKey)) { + if (!Number.isNaN(numberKey)) { key = numberKey; } } diff --git a/src/core/schemas/builders/record/types.ts b/src/core/schemas/builders/record/types.ts index e629d5be..5950b4cb 100644 --- a/src/core/schemas/builders/record/types.ts +++ b/src/core/schemas/builders/record/types.ts @@ -1,5 +1,5 @@ -import { BaseSchema } from "../../Schema.js"; -import { SchemaUtils } from "../schema-utils/index.js"; +import type { BaseSchema } from "../../Schema.js"; +import type { SchemaUtils } from "../schema-utils/index.js"; export type RecordSchema< RawKey extends string | number, diff --git a/src/core/schemas/builders/schema-utils/JsonError.ts b/src/core/schemas/builders/schema-utils/JsonError.ts index 14adcb70..daee3dc7 100644 --- a/src/core/schemas/builders/schema-utils/JsonError.ts +++ b/src/core/schemas/builders/schema-utils/JsonError.ts @@ -1,4 +1,4 @@ -import { ValidationError } from "../../Schema.js"; +import type { ValidationError } from "../../Schema.js"; import { stringifyValidationError } from "./stringifyValidationErrors.js"; export class JsonError extends Error { diff --git a/src/core/schemas/builders/schema-utils/ParseError.ts b/src/core/schemas/builders/schema-utils/ParseError.ts index 052a1d31..9facf061 100644 --- a/src/core/schemas/builders/schema-utils/ParseError.ts +++ b/src/core/schemas/builders/schema-utils/ParseError.ts @@ -1,4 +1,4 @@ -import { ValidationError } from "../../Schema.js"; +import type { ValidationError } from "../../Schema.js"; import { stringifyValidationError } from "./stringifyValidationErrors.js"; export class ParseError extends Error { diff --git a/src/core/schemas/builders/schema-utils/getSchemaUtils.ts b/src/core/schemas/builders/schema-utils/getSchemaUtils.ts index 0087b66b..3ceaf4e0 100644 --- a/src/core/schemas/builders/schema-utils/getSchemaUtils.ts +++ b/src/core/schemas/builders/schema-utils/getSchemaUtils.ts @@ -1,4 +1,4 @@ -import { BaseSchema, Schema, SchemaOptions, SchemaType } from "../../Schema.js"; +import { type BaseSchema, type Schema, type SchemaOptions, SchemaType } from "../../Schema.js"; import { JsonError } from "./JsonError.js"; import { ParseError } from "./ParseError.js"; diff --git a/src/core/schemas/builders/schema-utils/index.ts b/src/core/schemas/builders/schema-utils/index.ts index 43ea0082..efb3b0c4 100644 --- a/src/core/schemas/builders/schema-utils/index.ts +++ b/src/core/schemas/builders/schema-utils/index.ts @@ -1,4 +1,4 @@ -export { getSchemaUtils, optional, transform } from "./getSchemaUtils.js"; export type { SchemaUtils } from "./getSchemaUtils.js"; +export { getSchemaUtils, optional, transform } from "./getSchemaUtils.js"; export { JsonError } from "./JsonError.js"; export { ParseError } from "./ParseError.js"; diff --git a/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts b/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts index 4252fb22..d36a4900 100644 --- a/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts +++ b/src/core/schemas/builders/schema-utils/stringifyValidationErrors.ts @@ -1,4 +1,4 @@ -import { ValidationError } from "../../Schema.js"; +import type { ValidationError } from "../../Schema.js"; export function stringifyValidationError(error: ValidationError): string { if (error.path.length === 0) { diff --git a/src/core/schemas/builders/set/set.ts b/src/core/schemas/builders/set/set.ts index 8cce5526..2013cdb4 100644 --- a/src/core/schemas/builders/set/set.ts +++ b/src/core/schemas/builders/set/set.ts @@ -1,4 +1,4 @@ -import { BaseSchema, Schema, SchemaType } from "../../Schema.js"; +import { type BaseSchema, type Schema, SchemaType } from "../../Schema.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation.js"; import { list } from "../list/index.js"; diff --git a/src/core/schemas/builders/undiscriminated-union/types.ts b/src/core/schemas/builders/undiscriminated-union/types.ts index ec6ad439..0d5096fa 100644 --- a/src/core/schemas/builders/undiscriminated-union/types.ts +++ b/src/core/schemas/builders/undiscriminated-union/types.ts @@ -1,4 +1,4 @@ -import { Schema, inferParsed, inferRaw } from "../../Schema.js"; +import type { inferParsed, inferRaw, Schema } from "../../Schema.js"; export type UndiscriminatedUnionSchema = Schema< inferRawUnidiscriminatedUnionSchema, diff --git a/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts b/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts index f5fdb157..07591b4d 100644 --- a/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts +++ b/src/core/schemas/builders/undiscriminated-union/undiscriminatedUnion.ts @@ -1,7 +1,14 @@ -import { BaseSchema, MaybeValid, Schema, SchemaOptions, SchemaType, ValidationError } from "../../Schema.js"; +import { + type BaseSchema, + type MaybeValid, + type Schema, + type SchemaOptions, + SchemaType, + type ValidationError, +} from "../../Schema.js"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation.js"; import { getSchemaUtils } from "../schema-utils/index.js"; -import { inferParsedUnidiscriminatedUnionSchema, inferRawUnidiscriminatedUnionSchema } from "./types.js"; +import type { inferParsedUnidiscriminatedUnionSchema, inferRawUnidiscriminatedUnionSchema } from "./types.js"; export function undiscriminatedUnion, ...Schema[]]>( schemas: Schemas, diff --git a/src/core/schemas/builders/union/index.ts b/src/core/schemas/builders/union/index.ts index 7b487752..6bc29ba9 100644 --- a/src/core/schemas/builders/union/index.ts +++ b/src/core/schemas/builders/union/index.ts @@ -1,5 +1,5 @@ -export { discriminant } from "./discriminant.js"; export type { Discriminant } from "./discriminant.js"; +export { discriminant } from "./discriminant.js"; export type { inferParsedDiscriminant, inferParsedUnion, diff --git a/src/core/schemas/builders/union/types.ts b/src/core/schemas/builders/union/types.ts index bf19fa27..7bfdd636 100644 --- a/src/core/schemas/builders/union/types.ts +++ b/src/core/schemas/builders/union/types.ts @@ -1,5 +1,5 @@ -import { ObjectSchema, inferParsedObject, inferRawObject } from "../object/index.js"; -import { Discriminant } from "./discriminant.js"; +import type { inferParsedObject, inferRawObject, ObjectSchema } from "../object/index.js"; +import type { Discriminant } from "./discriminant.js"; export type UnionSubtypes = { [K in DiscriminantValues]: ObjectSchema; diff --git a/src/core/schemas/builders/union/union.ts b/src/core/schemas/builders/union/union.ts index df33568d..509658e0 100644 --- a/src/core/schemas/builders/union/union.ts +++ b/src/core/schemas/builders/union/union.ts @@ -1,19 +1,19 @@ -import { BaseSchema, MaybeValid, SchemaType } from "../../Schema.js"; +import { type BaseSchema, type MaybeValid, SchemaType } from "../../Schema.js"; import { getErrorMessageForIncorrectType } from "../../utils/getErrorMessageForIncorrectType.js"; import { isPlainObject } from "../../utils/isPlainObject.js"; import { keys } from "../../utils/keys.js"; import { maybeSkipValidation } from "../../utils/maybeSkipValidation.js"; import { enum_ } from "../enum/index.js"; -import { ObjectSchema } from "../object/index.js"; -import { ObjectLikeSchema, getObjectLikeUtils } from "../object-like/index.js"; +import type { ObjectSchema } from "../object/index.js"; +import { getObjectLikeUtils, type ObjectLikeSchema } from "../object-like/index.js"; import { getSchemaUtils } from "../schema-utils/index.js"; -import { Discriminant } from "./discriminant.js"; -import { - UnionSubtypes, +import type { Discriminant } from "./discriminant.js"; +import type { inferParsedDiscriminant, inferParsedUnion, inferRawDiscriminant, inferRawUnion, + UnionSubtypes, } from "./types.js"; export function union, U extends UnionSubtypes>( diff --git a/src/core/schemas/utils/createIdentitySchemaCreator.ts b/src/core/schemas/utils/createIdentitySchemaCreator.ts index 729c51c0..9aa4ed50 100644 --- a/src/core/schemas/utils/createIdentitySchemaCreator.ts +++ b/src/core/schemas/utils/createIdentitySchemaCreator.ts @@ -1,5 +1,5 @@ -import { BaseSchema, MaybeValid, Schema, SchemaOptions, SchemaType } from "../Schema.js"; import { getSchemaUtils } from "../builders/schema-utils/index.js"; +import type { BaseSchema, MaybeValid, Schema, SchemaOptions, SchemaType } from "../Schema.js"; import { maybeSkipValidation } from "./maybeSkipValidation.js"; export function createIdentitySchemaCreator( diff --git a/src/core/schemas/utils/maybeSkipValidation.ts b/src/core/schemas/utils/maybeSkipValidation.ts index c7fd6d93..f32d4525 100644 --- a/src/core/schemas/utils/maybeSkipValidation.ts +++ b/src/core/schemas/utils/maybeSkipValidation.ts @@ -1,4 +1,4 @@ -import { BaseSchema, MaybeValid, SchemaOptions } from "../Schema.js"; +import type { BaseSchema, MaybeValid, SchemaOptions } from "../Schema.js"; export function maybeSkipValidation, Raw, Parsed>(schema: S): S { return { diff --git a/src/core/url/encodePathParam.ts b/src/core/url/encodePathParam.ts new file mode 100644 index 00000000..19b90124 --- /dev/null +++ b/src/core/url/encodePathParam.ts @@ -0,0 +1,18 @@ +export function encodePathParam(param: unknown): string { + if (param === null) { + return "null"; + } + const typeofParam = typeof param; + switch (typeofParam) { + case "undefined": + return "undefined"; + case "string": + case "number": + case "boolean": + break; + default: + param = String(param); + break; + } + return encodeURIComponent(param as string | number | boolean); +} diff --git a/src/core/url/index.ts b/src/core/url/index.ts index ed5aa0ff..f2e0fa2d 100644 --- a/src/core/url/index.ts +++ b/src/core/url/index.ts @@ -1,2 +1,3 @@ +export { encodePathParam } from "./encodePathParam.js"; export { join } from "./join.js"; export { toQueryString } from "./qs.js"; diff --git a/src/core/url/join.ts b/src/core/url/join.ts index 200426be..7ca7daef 100644 --- a/src/core/url/join.ts +++ b/src/core/url/join.ts @@ -12,12 +12,11 @@ export function join(base: string, ...segments: string[]): string { try { url = new URL(base); } catch { - // Fallback to path joining if URL is malformed return joinPath(base, ...segments); } const lastSegment = segments[segments.length - 1]; - const shouldPreserveTrailingSlash = lastSegment && lastSegment.endsWith("/"); + const shouldPreserveTrailingSlash = lastSegment?.endsWith("/"); for (const segment of segments) { const cleanSegment = trimSlashes(segment); @@ -44,7 +43,7 @@ function joinPath(base: string, ...segments: string[]): string { let result = base; const lastSegment = segments[segments.length - 1]; - const shouldPreserveTrailingSlash = lastSegment && lastSegment.endsWith("/"); + const shouldPreserveTrailingSlash = lastSegment?.endsWith("/"); for (const segment of segments) { const cleanSegment = trimSlashes(segment); @@ -64,7 +63,7 @@ function joinPathSegments(left: string, right: string): string { if (left.endsWith("/")) { return left + right; } - return left + "/" + right; + return `${left}/${right}`; } function trimSlashes(str: string): string { diff --git a/src/core/websocket/exports.ts b/src/core/websocket/exports.ts new file mode 100644 index 00000000..91271654 --- /dev/null +++ b/src/core/websocket/exports.ts @@ -0,0 +1,9 @@ +import type * as events from "./events.js"; +import type * as ws from "./ws.js"; + +export type ReconnectingWebSocket = typeof ws.ReconnectingWebSocket; +export declare namespace ReconnectingWebSocket { + export type Event = events.Event; + export type CloseEvent = events.CloseEvent; + export type ErrorEvent = events.ErrorEvent; +} diff --git a/src/core/websocket/ws.ts b/src/core/websocket/ws.ts index b068af14..60895584 100644 --- a/src/core/websocket/ws.ts +++ b/src/core/websocket/ws.ts @@ -28,8 +28,8 @@ export declare namespace ReconnectingWebSocket { url: string; protocols?: string | string[]; options?: ReconnectingWebSocket.Options; - headers?: Record; - queryParameters?: Record; + headers?: Record; + queryParameters?: Record; } export type Options = { @@ -104,31 +104,15 @@ export class ReconnectingWebSocket { this._connect(); } - static get CONNECTING() { - return 0; - } - static get OPEN() { - return 1; - } - static get CLOSING() { - return 2; - } - static get CLOSED() { - return 3; - } + public static readonly CONNECTING = 0; + public static readonly OPEN = 1; + public static readonly CLOSING = 2; + public static readonly CLOSED = 3; - get CONNECTING() { - return ReconnectingWebSocket.CONNECTING; - } - get OPEN() { - return ReconnectingWebSocket.OPEN; - } - get CLOSING() { - return ReconnectingWebSocket.CLOSING; - } - get CLOSED() { - return ReconnectingWebSocket.CLOSED; - } + public readonly CONNECTING: typeof ReconnectingWebSocket.CONNECTING = ReconnectingWebSocket.CONNECTING; + public readonly OPEN: typeof ReconnectingWebSocket.OPEN = ReconnectingWebSocket.OPEN; + public readonly CLOSING: typeof ReconnectingWebSocket.CLOSING = ReconnectingWebSocket.CLOSING; + public readonly CLOSED: typeof ReconnectingWebSocket.CLOSED = ReconnectingWebSocket.CLOSED; get binaryType() { return this._ws ? this._ws.binaryType : this._binaryType; @@ -227,7 +211,7 @@ export class ReconnectingWebSocket { * Closes the WebSocket connection or connection attempt, if any. If the connection is already * CLOSED, this method does nothing */ - public close(code = 1000, reason?: string) { + public close(code = 1000, reason?: string): void { this._closeCalled = true; this._shouldReconnect = false; this._clearTimeouts(); @@ -246,7 +230,7 @@ export class ReconnectingWebSocket { * Closes the WebSocket connection or connection attempt and connects again. * Resets retry counter; */ - public reconnect(code?: number, reason?: string) { + public reconnect(code?: number, reason?: string): void { this._shouldReconnect = true; this._closeCalled = false; this._retryCount = -1; @@ -261,7 +245,7 @@ export class ReconnectingWebSocket { /** * Enqueue specified data to be transmitted to the server over the WebSocket connection */ - public send(data: ReconnectingWebSocket.Message) { + public send(data: ReconnectingWebSocket.Message): void { if (this._ws && this._ws.readyState === this.OPEN) { this._debug("send", data); this._ws.send(data); @@ -330,7 +314,7 @@ export class ReconnectingWebSocket { } = this._options; let delay = 0; if (this._retryCount > 0) { - delay = minReconnectionDelay * Math.pow(reconnectionDelayGrowFactor, this._retryCount - 1); + delay = minReconnectionDelay * reconnectionDelayGrowFactor ** (this._retryCount - 1); if (delay > maxReconnectionDelay) { delay = maxReconnectionDelay; } @@ -425,7 +409,7 @@ export class ReconnectingWebSocket { try { this._ws.close(code, reason); this._handleClose(new Events.CloseEvent(code, reason, this)); - } catch (error) { + } catch (_error) { // ignore } } diff --git a/src/custom/CortiAuth.ts b/src/custom/CortiAuth.ts deleted file mode 100644 index 85189587..00000000 --- a/src/custom/CortiAuth.ts +++ /dev/null @@ -1,385 +0,0 @@ -/** - * This file is implementation of the Auth client that can be used in 2 scenarios: - * 1. Under the hood by the package when Client credentials are used - * 2. Directly imported by the user to implement Authorization code flow - * - * Locally based on the auto-generated Auth client (src/api/resources/auth/client/Client.ts), but with some changes: - * 1. Token request sends proper `application/x-www-form-urlencoded` content type instead of `application/json` - * 2. Token request accepts additional parameters to support Authorization code flow - * 3. Additional methods to support Authorization code flow - * - * All methods are re-implemented, but class still extends the auto-generated one to make sure that we keep the same interface - * and to maybe remove some of the re-implementations in the future when `x-www-form-urlencoded` is supported - */ - -import { Auth as FernAuth } from "../api/resources/auth/client/Client.js"; -import * as core from "../core/index.js"; -import * as Corti from "../api/index.js"; -import { mergeHeaders, mergeOnlyDefinedHeaders } from "../core/headers.js"; -import * as serializers from "../serialization/index.js"; -import * as errors from "../errors/index.js"; -import { Environment, CortiInternalEnvironment, getEnvironment } from "./utils/getEnvironmentFromString.js"; -import { ParseError } from "../core/schemas/builders/schema-utils/ParseError.js"; -import { getLocalStorageItem, setLocalStorageItem } from "./utils/localStorage.js"; -import { generateCodeChallenge, generateCodeVerifier } from "./utils/pkce.js"; -import { buildTokenRequestBody } from "./utils/tokenRequest.js"; - -const CODE_VERIFIER_KEY = "corti_js_sdk_code_verifier"; - -/** - * Patch: added codeChallenge to the AuthorizationCodeClient interface to support PKCE flow - */ -interface AuthorizationCodeClient { - clientId: string; - redirectUri: string; - codeChallenge?: string; - scopes?: string[]; -} - -/** - * Patch: renamed AuthorizationCodeClient to AuthorizationCode as it can be used for both(server and client) flows - */ -interface AuthorizationCode { - clientId: string; - clientSecret: string; - redirectUri: string; - code: string; - scopes?: string[]; -} - -/** - * Patch: added type for AuthorizationPkce request - */ -interface AuthorizationPkce { - clientId: string; - redirectUri: string; - code: string; - codeVerifier?: string; - scopes?: string[]; -} - -/** - * Patch: added type for AuthorizationRopc request - */ -interface AuthorizationRopcServer { - clientId: string; - username: string; - password: string; - scopes?: string[]; -} - -interface AuthorizationRefreshServer { - clientId: string; - /** - * Patch: added optional clientSecret for ROPC and PKCE flow - */ - clientSecret?: string; - refreshToken: string; - scopes?: string[]; -} - -interface Options { - skipRedirect?: boolean; -} - -type AuthOptionsBase = Omit; - -// When baseUrl is provided, environment and tenantName are optional -type AuthOptionsWithBaseUrl = AuthOptionsBase & { - baseUrl: core.Supplier; - environment?: Environment; - tenantName?: core.Supplier; -}; - -// When environment is an object, tenantName is optional -type AuthOptionsWithObjectEnvironment = AuthOptionsBase & { - baseUrl?: core.Supplier; - environment: CortiInternalEnvironment; - tenantName?: core.Supplier; -}; - -// When environment is a string, tenantName is required -type AuthOptionsWithStringEnvironment = AuthOptionsBase & { - baseUrl?: core.Supplier; - environment: string; - tenantName: core.Supplier; -}; - -type AuthOptions = AuthOptionsWithBaseUrl | AuthOptionsWithObjectEnvironment | AuthOptionsWithStringEnvironment; - -export class Auth extends FernAuth { - /** - * Patch: use custom AuthOptions type to support string-based environment - * When baseUrl is provided, environment and tenantName become optional - */ - constructor(_options: AuthOptions) { - super({ - ..._options, - tenantName: _options.tenantName || "", - environment: getEnvironment(_options.environment), - }); - } - - /** - * Patch: Generate PKCE authorization URL with automatic code verifier generation - */ - public async authorizePkceUrl( - { clientId, redirectUri, scopes }: AuthorizationCodeClient, - options?: Options, - ): Promise { - const codeVerifier = generateCodeVerifier(); - setLocalStorageItem(CODE_VERIFIER_KEY, codeVerifier); - - const codeChallenge = await generateCodeChallenge(codeVerifier); - - return this.authorizeURL( - { - clientId, - redirectUri, - codeChallenge, - scopes, - }, - options, - ); - } - - /** - * Patch: Get the stored PKCE code verifier - */ - public getCodeVerifier(): string | null { - return getLocalStorageItem(CODE_VERIFIER_KEY); - } - - /** - * Patch: called custom implementation this.__getToken_custom instead of this.__getToken - * Extended to support additional scopes - */ - public getToken( - request: Corti.AuthGetTokenRequest & { scopes?: string[] }, - requestOptions?: FernAuth.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise(this.__getToken_custom(request, requestOptions)); - } - - /** - * Patch: added method to get Authorization URL for Authorization code flow and PKCE flow - */ - public async authorizeURL( - { clientId, redirectUri, codeChallenge, scopes }: AuthorizationCodeClient, - options?: Options, - ): Promise { - const authUrl = new URL( - core.url.join( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)).login, - await core.Supplier.get(this._options.tenantName), - "protocol/openid-connect/auth", - ), - ); - - authUrl.searchParams.set("response_type", "code"); - - // Build scope string: always include "openid profile", add any additional scopes - const allScopes = ["openid", "profile", ...(scopes || [])]; - const scopeString = [...new Set(allScopes)].join(" "); - - authUrl.searchParams.set("scope", scopeString); - - if (clientId !== undefined) { - authUrl.searchParams.set("client_id", clientId); - } - - if (redirectUri !== undefined) { - authUrl.searchParams.set("redirect_uri", redirectUri); - } - - if (codeChallenge !== undefined) { - authUrl.searchParams.set("code_challenge", codeChallenge); - authUrl.searchParams.set("code_challenge_method", "S256"); - } - - const authUrlString = authUrl.toString(); - - if (typeof window !== "undefined" && !options?.skipRedirect) { - window.location.href = authUrlString; - return authUrlString; - } - - return authUrlString; - } - - /** - * Patch: calls __getToken_custom with additional fields to support Authorization code flow - */ - public getCodeFlowToken( - request: AuthorizationCode, - requestOptions?: FernAuth.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise( - this.__getToken_custom( - { - ...request, - grantType: "authorization_code", - }, - requestOptions, - ), - ); - } - - /** - * Patch: PKCE-specific method - */ - public getPkceFlowToken( - request: AuthorizationPkce, - requestOptions?: FernAuth.RequestOptions, - ): core.HttpResponsePromise { - const codeVerifier = request.codeVerifier || this.getCodeVerifier(); - - if (!codeVerifier) { - throw new ParseError([ - { - path: ["codeVerifier"], - message: "Code verifier was not provided and not found in localStorage.", - }, - ]); - } - - return core.HttpResponsePromise.fromPromise( - this.__getToken_custom( - { - ...request, - codeVerifier: codeVerifier, - grantType: "authorization_code", - }, - requestOptions, - ), - ); - } - - /** - * Patch: ROPC-specific method - */ - public getRopcFlowToken( - request: AuthorizationRopcServer, - requestOptions?: FernAuth.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise( - this.__getToken_custom( - { - ...request, - grantType: "password", - }, - requestOptions, - ), - ); - } - - /** - * Patch: copy of this.__getToken with patches - */ - private async __getToken_custom( - /** - * Patch: added additional fields to request to support Authorization PKCE and ROPC flow - */ - request: Corti.AuthGetTokenRequest & - Partial<{ - grantType: "client_credentials" | "authorization_code" | "refresh_token" | "password"; - code: string; - redirectUri: string; - refreshToken: string; - codeVerifier: string; - username: string; - password: string; - scopes: string[]; - }>, - requestOptions?: FernAuth.RequestOptions, - ): Promise> { - const _response = await core.fetcher({ - url: core.url.join( - (await core.Supplier.get(this._options.baseUrl)) ?? - (await core.Supplier.get(this._options.environment)).login, - /** - * Patch: use tenantName as path parameter - * (consider to be generated from the spec in the future) - */ - await core.Supplier.get(this._options.tenantName), - "protocol/openid-connect/token", - ), - method: "POST", - headers: mergeHeaders( - this._options?.headers, - mergeOnlyDefinedHeaders({ - /** - * Patch: Removed `Authorization` header, as it is not needed for getting the token - */ - "Tenant-Name": requestOptions?.tenantName, - }), - requestOptions?.headers, - ), - contentType: "application/x-www-form-urlencoded", - /** - * Patch: removed `requestType: "json"`, made body a URLSearchParams object - */ - body: buildTokenRequestBody(request), - timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, - maxRetries: requestOptions?.maxRetries, - abortSignal: requestOptions?.abortSignal, - }); - if (_response.ok) { - return { - data: serializers.GetTokenResponse.parseOrThrow(_response.body, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - breadcrumbsPrefix: ["response"], - }), - rawResponse: _response.rawResponse, - }; - } - - if (_response.error.reason === "status-code") { - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.body, - rawResponse: _response.rawResponse, - }); - } - - switch (_response.error.reason) { - case "non-json": - throw new errors.CortiError({ - statusCode: _response.error.statusCode, - body: _response.error.rawBody, - rawResponse: _response.rawResponse, - }); - case "timeout": - throw new errors.CortiTimeoutError( - "Timeout exceeded when calling POST /protocol/openid-connect/token.", - ); - case "unknown": - throw new errors.CortiError({ - message: _response.error.errorMessage, - rawResponse: _response.rawResponse, - }); - } - } - - /** - * Patch: calls __getToken_custom with additional fields to support Refresh token flow - */ - public refreshToken( - request: AuthorizationRefreshServer, - requestOptions?: FernAuth.RequestOptions, - ): core.HttpResponsePromise { - return core.HttpResponsePromise.fromPromise( - this.__getToken_custom( - { - ...request, - grantType: "refresh_token", - }, - requestOptions, - ), - ); - } -} diff --git a/src/custom/CortiClient.ts b/src/custom/CortiClient.ts deleted file mode 100644 index 79f3cb92..00000000 --- a/src/custom/CortiClient.ts +++ /dev/null @@ -1,315 +0,0 @@ -/** - * This file is the custom implementation of the main CortiClient class (src/Client.ts) - * - * It's (almost) handwritten, and it replaces the auto-generated version, and here is why: - * - * 1. The auto-generated version uses direct client imports -> we can not always easily replace them without a patch in Main client - * 2. The auto-generated version produces TypeScript error when initializes authClient in `_oauthTokenProvider` - * 3. `_oauthTokenProvider` is a private field in the auto-generated version, - * so we cannot easily rewrite it in the custom implementation. We can use another field for OAuthProvider, - * but then we need to rewrite all the methods anyway => it will be easier to forget, - * since it would exist in the class, but not properly implemented - * - * => Must be manually synced with src/Client.ts (which is auto-generated). - * - * All the patches marked with `// Patch: ...` comments. - */ - -import * as environments from "../environments.js"; -import * as core from "../core/index.js"; -/** - * Patch: changed import to custom Auth implementation - */ -import { Auth } from "./CortiAuth.js"; -import { mergeHeaders } from "../core/headers.js"; -import { Interactions } from "../api/resources/interactions/client/Client.js"; -import { Recordings } from "../api/resources/recordings/client/Client.js"; -import { Transcripts } from "../api/resources/transcripts/client/Client.js"; -import { Facts } from "../api/resources/facts/client/Client.js"; -import { Documents } from "../api/resources/documents/client/Client.js"; -import { Templates } from "../api/resources/templates/client/Client.js"; -import { Agents } from "../api/resources/agents/client/Client.js"; -import { Codes } from "../api/resources/codes/client/Client.js"; - -/** - * Patch: changed import to custom Stream and Transcribe implementations - */ -import { Stream } from "./CustomStream.js"; -import { Transcribe } from "./CustomTranscribe.js"; - -/** - * Patch: added SDK_VERSION import and custom code imports - */ -import { SDK_VERSION } from "../version.js"; -import { getEnvironment, Environment, CortiInternalEnvironment } from "./utils/getEnvironmentFromString.js"; -import { resolveClientOptions } from "./utils/resolveClientOptions.js"; -import { BearerOptions, RefreshBearerProvider } from "./RefreshBearerProvider.js"; -import { setDefaultWithCredentials } from "./utils/withCredentialsConfig.js"; - -export declare namespace CortiClient { - /** - * Patch: added new public type for `Options` + internal interfaces to create it - */ - - /** Patch: exported headers type for options.headers and WS protocol encoding. */ - export type HeadersRecord = Record | undefined>; - - interface ClientCredentials { - clientId: core.Supplier; - clientSecret: core.Supplier; - } - - interface BaseOptions { - /** Additional headers to include in requests. */ - headers?: HeadersRecord; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - /** Patch: added new option to encode headers as WebSocket protocols for streaming resources (for proxy scenarios) */ - encodeHeadersAsWsProtocols?: boolean; - /** Patch: when true, fetcher sends credentials (cookies, auth headers) on cross-origin requests; sets global default used by core fetcher when not passed per-request */ - withCredentials?: boolean; - } - - interface OptionsWithClientCredentials extends BaseOptions { - /** - * Patch: allow to pass a custom string-based environment - * */ - environment: Environment; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - auth: ClientCredentials; - } - - interface OptionsWithBearerToken extends BaseOptions { - /** - * Patch: allow to pass a custom string-based environment - * */ - environment?: Environment; - /** Override the Tenant-Name header */ - tenantName?: core.Supplier; - auth: BearerOptions; - } - - // When baseUrl is provided, auth becomes optional (for proxying scenarios) - interface OptionsWithBaseUrl extends BaseOptions { - baseUrl: core.Supplier; - environment?: Environment; - tenantName?: core.Supplier; - auth?: ClientCredentials | BearerOptions; - } - - // When environment is an object, auth becomes optional (for proxying scenarios) - interface OptionsWithObjectEnvironment extends BaseOptions { - environment: CortiInternalEnvironment; - tenantName?: core.Supplier; - auth?: ClientCredentials | BearerOptions; - } - - export type Options = - | OptionsWithClientCredentials - | OptionsWithBearerToken - | OptionsWithBaseUrl - | OptionsWithObjectEnvironment; - - /** - * Patch: - * - renamed `Options` to `InternalOptions` - * - added `token` field to support BearerProvider - * - made clientId and clientSecret optional - * - updated environment type to CortiInternalEnvironment - * - added `encodeHeadersAsWsProtocols` - * - added `withCredentials` - */ - interface InternalOptions { - environment: CortiInternalEnvironment; - /** Specify a custom URL to connect the client to. */ - baseUrl?: core.Supplier; - clientId?: core.Supplier; - clientSecret?: core.Supplier; - token?: core.Supplier; - /** Override the Tenant-Name header */ - tenantName: core.Supplier; - /** Additional headers to include in requests. */ - headers?: HeadersRecord; - encodeHeadersAsWsProtocols?: boolean; - withCredentials?: boolean; - } - - export interface RequestOptions { - /** The maximum time to wait for a response in seconds. */ - timeoutInSeconds?: number; - /** The number of times to retry the request. Defaults to 2. */ - maxRetries?: number; - /** A hook to abort the request. */ - abortSignal?: AbortSignal; - /** Override the Tenant-Name header */ - tenantName?: string; - /** Additional headers to include in the request. */ - headers?: HeadersRecord; - } -} - -export class CortiClient { - /** - * Patch: this._options is now of type `CortiClient.InternalOptions` (which matches generated implementation) - */ - protected readonly _options: CortiClient.InternalOptions; - /** - * Patch: extended `_oauthTokenProvider` to support both `RefreshBearerProvider` and `OAuthTokenProvider` options - * Optional - not created when auth is not provided (proxying scenarios) - */ - private readonly _oauthTokenProvider?: core.OAuthTokenProvider | RefreshBearerProvider; - protected _interactions: Interactions | undefined; - protected _recordings: Recordings | undefined; - protected _transcripts: Transcripts | undefined; - protected _facts: Facts | undefined; - protected _templates: Templates | undefined; - protected _documents: Documents | undefined; - protected _agents: Agents | undefined; - /** - * Patch: removed `auth` field - * `_oauthTokenProvider` uses Auth module directly to get the token, - * and our client also don't need to use it within the main client. - * For other cases they can use `CortiAuth` module directly. - */ - protected _stream: Stream | undefined; - protected _transcribe: Transcribe | undefined; - protected _codes: Codes | undefined; - - constructor(_options: CortiClient.Options) { - /** - * Patch: resolve tenantName and environment from options or token - */ - const { tenantName, environment, initialTokenResponse } = resolveClientOptions(_options); - - /** - * Patch: redefining options based on new schema - */ - this._options = { - ..._options, - headers: mergeHeaders( - { - "Tenant-Name": tenantName, - "X-Fern-Language": "JavaScript", - "X-Fern-SDK-Name": "@corti/sdk", - /** - * Patch: replaced hardcoded SDK version with imported one - */ - "X-Fern-SDK-Version": SDK_VERSION, - "User-Agent": `@corti/sdk/${SDK_VERSION}`, - "X-Fern-Runtime": core.RUNTIME.type, - "X-Fern-Runtime-Version": core.RUNTIME.version, - }, - _options?.headers, - ), - clientId: _options.auth && "clientId" in _options.auth ? _options.auth.clientId : undefined, - clientSecret: _options.auth && "clientSecret" in _options.auth ? _options.auth.clientSecret : undefined, - token: _options.auth && "accessToken" in _options.auth ? _options.auth.accessToken : undefined, - tenantName, - environment: getEnvironment(environment), - withCredentials: _options.withCredentials, - }; - - /** - * Patch: set global default for fetcher withCredentials when passed on CortiClient - */ - if (_options.withCredentials !== undefined) { - setDefaultWithCredentials(_options.withCredentials); - } - - /** - * Patch: if `clientId` is provided, use OAuthTokenProvider, otherwise use BearerProvider - * Only create token provider when auth is provided - */ - if (_options.auth) { - this._oauthTokenProvider = - "clientId" in _options.auth - ? new core.OAuthTokenProvider({ - clientId: _options.auth.clientId, - clientSecret: _options.auth.clientSecret, - /** - * Patch: provide whole `options` object to the Auth client, since it depends on both tenantName and environment - */ - authClient: new Auth(this._options), - }) - : new RefreshBearerProvider({ - ..._options.auth, - initialTokenResponse, - }); - } - } - - public get interactions(): Interactions { - return (this._interactions ??= new Interactions({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - public get recordings(): Recordings { - return (this._recordings ??= new Recordings({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - public get transcripts(): Transcripts { - return (this._transcripts ??= new Transcripts({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - public get facts(): Facts { - return (this._facts ??= new Facts({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - public get documents(): Documents { - return (this._documents ??= new Documents({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - public get templates(): Templates { - return (this._templates ??= new Templates({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - public get agents(): Agents { - return (this._agents ??= new Agents({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - public get stream(): Stream { - return (this._stream ??= new Stream({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - public get transcribe(): Transcribe { - return (this._transcribe ??= new Transcribe({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - public get codes(): Codes { - return (this._codes ??= new Codes({ - ...this._options, - token: this._oauthTokenProvider ? async () => await this._oauthTokenProvider!.getToken() : undefined, - })); - } - - /** - * Patch: removed `auth` getter - */ -} diff --git a/src/custom/CortiSDKError.ts b/src/custom/CortiSDKError.ts deleted file mode 100644 index d40a811a..00000000 --- a/src/custom/CortiSDKError.ts +++ /dev/null @@ -1,26 +0,0 @@ -export interface CortiSDKErrorOptions { - code: CortiSDKErrorCodes; - cause?: unknown; -} - -export enum CortiSDKErrorCodes { - LOCAL_STORAGE_ERROR = "local_storage_error", -} - -export class CortiSDKError extends Error { - public readonly code: CortiSDKErrorCodes; - public readonly cause?: unknown; - - constructor( - message = "An unexpected error occurred in the Corti SDK.", - options: CortiSDKErrorOptions = { code: CortiSDKErrorCodes.LOCAL_STORAGE_ERROR }, - ) { - super(message); - this.name = "CortiSDKError"; - this.code = options.code; - if ("cause" in options) { - this.cause = options.cause; - } - Object.setPrototypeOf(this, CortiSDKError.prototype); - } -} diff --git a/src/custom/CortiWebSocketProxyClient.ts b/src/custom/CortiWebSocketProxyClient.ts deleted file mode 100644 index f137c094..00000000 --- a/src/custom/CortiWebSocketProxyClient.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Patch: Lightweight proxy client with only WebSocket resources (stream and transcribe). - * Use this when you need direct WebSocket connections through your own proxy backend. - * - * No environment or tenantName required - proxy is required in connect(). - */ - -import { CustomProxyStream } from "./proxy/CustomProxyStream.js"; -import { CustomProxyTranscribe } from "./proxy/CustomProxyTranscribe.js"; - -export class CortiWebSocketProxyClient { - private static _stream: CustomProxyStream | undefined; - private static _transcribe: CustomProxyTranscribe | undefined; - - public static get stream(): CustomProxyStream { - return (this._stream ??= new CustomProxyStream()); - } - - public static get transcribe(): CustomProxyTranscribe { - return (this._transcribe ??= new CustomProxyTranscribe()); - } -} diff --git a/src/custom/CustomStream.ts b/src/custom/CustomStream.ts deleted file mode 100644 index 21448eae..00000000 --- a/src/custom/CustomStream.ts +++ /dev/null @@ -1,155 +0,0 @@ -/** - * Patch: use custom Stream implementation to support passing _options parameters to connection function - */ -import { Stream as FernStream } from "../api/resources/stream/client/Client.js"; - -import * as core from "../core/index.js"; - -/** - * Patch: added import for types and message parsing logic - */ -import * as api from "../api/index.js"; -import { fromJson } from "../core/json.js"; -import * as serializers from "../serialization/index.js"; -import { ErrorEvent } from "../core/websocket/events.js"; - -/** - * Patch: changed import to custom StreamSocket implementation - */ -import { StreamSocket } from "./CustomStreamSocket.js"; -/** - * Patch: import getWsProtocols for building WS protocols from headers when encodeHeadersAsWsProtocols is set. - */ -import { getWsProtocols } from "./utils/encodeHeadersAsWsProtocols.js"; -import type { CortiClient } from "./CortiClient.js"; - -/** Patch: options type extended with encodeHeadersAsWsProtocols (set by CortiClient). */ -type StreamOptionsWithEncode = FernStream["_options"] & { encodeHeadersAsWsProtocols?: boolean }; - -export class Stream extends FernStream { - /** Patch: narrow type so encodeHeadersAsWsProtocols is available when client is CortiClient. */ - protected readonly _options: StreamOptionsWithEncode; - - /** Patch: constructor accepts extended options so _options is correctly typed. */ - constructor(_options: StreamOptionsWithEncode) { - super(_options); - this._options = _options; - } - - /** - * Patch: use custom connect method to support passing _options parameters. - * Patch: optional proxy parameter for direct WebSocket connection (proxy scenarios). - * Patch: use proxy path when proxy is passed or encodeHeadersAsWsProtocols is set. - * Patch: protocols from getWsProtocols; queryParameters from proxy or empty. - */ - public async connect({ - configuration, - proxy, - ...args - }: Omit & { - configuration?: api.StreamConfig; - /** Patch: proxy connection options - bypasses normal URL construction. protocols: array passed as-is, object encoded like headers. */ - proxy?: { - url?: string; - protocols?: string[] | CortiClient.HeadersRecord; - queryParameters?: Record; - }; - }): Promise { - const useProxyPath = proxy || this._options.encodeHeadersAsWsProtocols; - const protocols = await getWsProtocols(this._options, proxy?.protocols); - - const socket = useProxyPath - ? new core.ReconnectingWebSocket({ - url: - proxy?.url || - core.url.join( - (await core.Supplier.get(this._options["baseUrl"])) ?? - (await core.Supplier.get(this._options["environment"])).wss, - `/interactions/${encodeURIComponent(args.id)}/streams` - ), - protocols, - queryParameters: proxy?.queryParameters ?? {}, - headers: args.headers ?? {}, - options: { debug: args.debug ?? false, maxRetries: args.reconnectAttempts ?? 30 }, - }) - : ( - await super.connect({ - ...args, - token: (await this._getAuthorizationHeader()) || "", - tenantName: await core.Supplier.get(this._options.tenantName), - }) - ).socket; - - const ws = new StreamSocket({ socket }); - - if (!configuration) { - return ws; - } - - ws.socket.addEventListener("open", () => { - ws.sendConfiguration({ - type: "config", - configuration, - }); - }); - - ws.socket.addEventListener("message", (event) => { - const data = fromJson(event.data); - - const parsedResponse = serializers.StreamSocketResponse.parse(data, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - omitUndefined: true, - }); - - if (parsedResponse.ok && parsedResponse.value.type === "CONFIG_ACCEPTED") { - return; - } - - if ( - parsedResponse.ok && - (parsedResponse.value.type === "CONFIG_DENIED" || - parsedResponse.value.type === "CONFIG_MISSING" || - parsedResponse.value.type === "CONFIG_TIMEOUT" || - parsedResponse.value.type === "CONFIG_NOT_PROVIDED") - ) { - ws.socket.dispatchEvent( - new ErrorEvent( - { - name: parsedResponse.value.type, - message: JSON.stringify(parsedResponse.value), - }, - "", - ), - ); - - ws.close(); - return; - } - - if (parsedResponse.ok && parsedResponse.value.type === "error") { - ws.socket.dispatchEvent( - new ErrorEvent( - { - name: "error", - message: JSON.stringify(parsedResponse.value), - }, - "", - ), - ); - - ws.close(); - return; - } - - if (parsedResponse.ok && parsedResponse.value.type === "ENDED") { - ws.close(); - return; - } - }); - - return ws; - } -} diff --git a/src/custom/CustomStreamSocket.ts b/src/custom/CustomStreamSocket.ts deleted file mode 100644 index 74f27cb2..00000000 --- a/src/custom/CustomStreamSocket.ts +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Patch: file patches disability of auto-generating binary data methods for sending data to the socket - */ -import { StreamSocket as FernStreamSocket } from "../api/resources/stream/client/Socket.js"; -import * as core from "../core/index.js"; -import { ReconnectingWebSocket } from "../core/index.js"; - -export class StreamSocket extends FernStreamSocket { - public sendAudio(message: ArrayBufferLike | Blob | ArrayBufferView | string): void { - if (typeof message === "string") { - return super.sendAudio(message); - } - - this.__assertSocketIsOpen(); - super.sendBinary(message); - } - - /** - * Patch: have to repeat this method, because it is private in the base class - */ - private __assertSocketIsOpen(): void { - if (!this.socket) { - throw new Error("Socket is not connected."); - } - - if (this.socket.readyState !== core.ReconnectingWebSocket.OPEN) { - throw new Error("Socket is not open."); - } - } - - /** - * Patch: added ability to remove event handlers - */ - public off(event: T, callback?: FernStreamSocket.EventHandlers[T]) { - if (!callback || callback === this.eventHandlers[event]) { - delete this.eventHandlers[event]; - } - } - - /** - * Patch: expose underlying socket send method for direct access - */ - public send(data: ReconnectingWebSocket.Message): void { - this.socket.send(data); - } -} diff --git a/src/custom/CustomTranscribe.ts b/src/custom/CustomTranscribe.ts deleted file mode 100644 index a5a9db0e..00000000 --- a/src/custom/CustomTranscribe.ts +++ /dev/null @@ -1,152 +0,0 @@ -/** - * Patch: use custom Transcribe implementation to support passing _options parameters to connection function - */ -import { Transcribe as FernTranscribe } from "../api/resources/transcribe/client/Client.js"; - -import * as core from "../core/index.js"; - -/** - * Patch: added import for types and message parsing logic - */ -import * as api from "../api/index.js"; -import { fromJson } from "../core/json.js"; -import * as serializers from "../serialization/index.js"; -import { ErrorEvent } from "../core/websocket/events.js"; - -/** - * Patch: changed import to custom TranscribeSocket implementation - */ -import { TranscribeSocket } from "./CustomTranscribeSocket.js"; -/** - * Patch: import getWsProtocols for building WS protocols from headers when encodeHeadersAsWsProtocols is set. - */ -import { getWsProtocols } from "./utils/encodeHeadersAsWsProtocols.js"; -import type { CortiClient } from "./CortiClient.js"; - -/** Patch: options type extended with encodeHeadersAsWsProtocols (set by CortiClient). */ -type TranscribeOptionsWithEncode = FernTranscribe["_options"] & { encodeHeadersAsWsProtocols?: boolean }; - -export class Transcribe extends FernTranscribe { - /** Patch: narrow type so encodeHeadersAsWsProtocols is available when client is CortiClient. */ - protected readonly _options: TranscribeOptionsWithEncode; - - /** Patch: constructor accepts extended options so _options is correctly typed. */ - constructor(_options: TranscribeOptionsWithEncode) { - super(_options); - this._options = _options; - } - - /** - * Patch: use custom connect method to support passing _options parameters. - * Patch: optional proxy parameter for direct WebSocket connection (proxy scenarios). - * Patch: use proxy path when proxy is passed or encodeHeadersAsWsProtocols is set. - * Patch: protocols from getWsProtocols; queryParameters from proxy or empty. - */ - public async connect({ - configuration, - proxy, - ...args - }: Omit & { - configuration?: api.TranscribeConfig; - /** Patch: proxy connection options - bypasses normal URL construction. protocols: array passed as-is, object encoded like headers. */ - proxy?: { - url?: string; - protocols?: string[] | CortiClient.HeadersRecord; - queryParameters?: Record; - }; - } = {}): Promise { - const useProxyPath = proxy || this._options.encodeHeadersAsWsProtocols; - const protocols = await getWsProtocols(this._options, proxy?.protocols); - - const socket = useProxyPath - ? new core.ReconnectingWebSocket({ - url: - proxy?.url || - core.url.join( - (await core.Supplier.get(this._options["baseUrl"])) ?? - (await core.Supplier.get(this._options["environment"])).wss, - "/transcribe" - ), - protocols, - queryParameters: proxy?.queryParameters ?? {}, - headers: args.headers ?? {}, - options: { debug: args.debug ?? false, maxRetries: args.reconnectAttempts ?? 30 }, - }) - : ( - await super.connect({ - ...args, - token: (await this._getAuthorizationHeader()) || "", - tenantName: await core.Supplier.get(this._options.tenantName), - }) - ).socket; - - const ws = new TranscribeSocket({ socket }); - - if (!configuration) { - return ws; - } - - ws.socket.addEventListener("open", () => { - ws.sendConfiguration({ - type: "config", - configuration, - }); - }); - - ws.socket.addEventListener("message", (event) => { - const data = fromJson(event.data); - - const parsedResponse = serializers.TranscribeSocketResponse.parse(data, { - unrecognizedObjectKeys: "passthrough", - allowUnrecognizedUnionMembers: true, - allowUnrecognizedEnumValues: true, - skipValidation: true, - omitUndefined: true, - }); - - if (parsedResponse.ok && parsedResponse.value.type === "CONFIG_ACCEPTED") { - return; - } - - if ( - parsedResponse.ok && - (parsedResponse.value.type === "CONFIG_DENIED" || parsedResponse.value.type === "CONFIG_TIMEOUT") - ) { - ws.socket.dispatchEvent( - new ErrorEvent( - { - name: parsedResponse.value.type, - message: JSON.stringify(parsedResponse.value), - }, - "", - ), - ); - - ws.close(); - return; - } - - if (parsedResponse.ok && parsedResponse.value.type === "error") { - ws.socket.dispatchEvent( - new ErrorEvent( - { - name: "error", - message: JSON.stringify(parsedResponse.value), - }, - "", - ), - ); - - ws.close(); - return; - } - - if (parsedResponse.ok && parsedResponse.value.type === "ended") { - ws.close(); - return; - } - }); - - return ws; - } -} diff --git a/src/custom/CustomTranscribeSocket.ts b/src/custom/CustomTranscribeSocket.ts deleted file mode 100644 index 1cb493e7..00000000 --- a/src/custom/CustomTranscribeSocket.ts +++ /dev/null @@ -1,49 +0,0 @@ -/** - * Patch: file patches disability of auto-generating binary data methods for sending data to the socket - */ -import { TranscribeSocket as FernTranscribeSocket } from "../api/resources/transcribe/client/Socket.js"; -import * as core from "../core/index.js"; -import { ReconnectingWebSocket } from "../core/index.js"; - -export class TranscribeSocket extends FernTranscribeSocket { - public sendAudio(message: ArrayBufferLike | Blob | ArrayBufferView | string): void { - if (typeof message === "string") { - return super.sendAudio(message); - } - - this.__assertSocketIsOpen(); - super.sendBinary(message); - } - - /** - * Patch: have to repeat this method, because it is private in the base class - */ - private __assertSocketIsOpen(): void { - if (!this.socket) { - throw new Error("Socket is not connected."); - } - - if (this.socket.readyState !== core.ReconnectingWebSocket.OPEN) { - throw new Error("Socket is not open."); - } - } - - /** - * Patch: added ability to remove event handlers - */ - public off( - event: T, - callback?: FernTranscribeSocket.EventHandlers[T], - ) { - if (!callback || callback === this.eventHandlers[event]) { - delete this.eventHandlers[event]; - } - } - - /** - * Patch: expose underlying socket send method for direct access - */ - public send(data: ReconnectingWebSocket.Message): void { - this.socket.send(data); - } -} diff --git a/src/custom/RefreshBearerProvider.ts b/src/custom/RefreshBearerProvider.ts deleted file mode 100644 index 15c90e43..00000000 --- a/src/custom/RefreshBearerProvider.ts +++ /dev/null @@ -1,129 +0,0 @@ -/** - * RefreshBearerProvider used as a replacement of OAuthTokenProvider, in case when accessToken from outside of library was used instead of Client credentials. - */ - -import * as core from "../core/index.js"; -import * as api from "../api/index.js"; -import { decodeToken } from "./utils/decodeToken.js"; - -export type ExpectedTokenResponse = Omit & { - tokenType?: string; - expiresIn?: number; -}; -type RefreshAccessTokenFunction = (refreshToken?: string) => Promise | ExpectedTokenResponse; - -export type BearerOptions = Partial> & - ( - | { - refreshAccessToken?: RefreshAccessTokenFunction; - accessToken: string; - } - | { - refreshAccessToken: RefreshAccessTokenFunction; - accessToken?: string; - } - ); - -export class RefreshBearerProvider { - private readonly BUFFER_IN_MINUTES = 2; - - private _accessToken: string; - private _refreshToken: string | undefined; - - private _refreshAccessToken: RefreshAccessTokenFunction | undefined; - - private _expiresAt: Date; - private _refreshExpiresAt: Date; - private _initialTokenResponse: Promise | undefined; - - constructor({ - accessToken, - refreshAccessToken, - refreshToken, - refreshExpiresIn, - expiresIn, - initialTokenResponse, - }: BearerOptions & { - initialTokenResponse?: Promise; - }) { - this._accessToken = accessToken || "no_token"; - this._refreshToken = refreshToken; - this._initialTokenResponse = initialTokenResponse; - - this._expiresAt = this.getExpiresAt(expiresIn, this._accessToken, this.BUFFER_IN_MINUTES); - this._refreshExpiresAt = this.getExpiresAt(refreshExpiresIn, this._refreshToken, 0); - - this._refreshAccessToken = refreshAccessToken; - } - - public async getToken(): Promise { - if (this._accessToken && this._accessToken !== "no_token" && this._expiresAt > new Date()) { - return core.Supplier.get(this._accessToken); - } - - if (this._initialTokenResponse) { - const tokenResponse = await this._initialTokenResponse; - this._initialTokenResponse = undefined; - - this._accessToken = tokenResponse.accessToken; - this._expiresAt = this.getExpiresAt( - tokenResponse.expiresIn, - tokenResponse.accessToken, - this.BUFFER_IN_MINUTES, - ); - - this._refreshToken = tokenResponse.refreshToken; - this._refreshExpiresAt = this.getExpiresAt(tokenResponse.refreshExpiresIn, this._refreshToken, 0); - - return this.getToken(); - } - - return this.refresh(); - } - - private async refresh(): Promise { - if (!this._refreshAccessToken || (this._refreshToken && this._refreshExpiresAt < new Date())) { - return core.Supplier.get(this._accessToken); - } - - const tokenResponse = await this._refreshAccessToken(this._refreshToken); - - this._accessToken = tokenResponse.accessToken; - this._expiresAt = this.getExpiresAt(tokenResponse.expiresIn, tokenResponse.accessToken, this.BUFFER_IN_MINUTES); - - this._refreshToken = tokenResponse.refreshToken; - this._refreshExpiresAt = this.getExpiresAt(tokenResponse.refreshExpiresIn, this._refreshToken, 0); - - return this._accessToken; - } - - private getExpiresAt( - expiresIn: number | undefined, - token: string | undefined, - bufferInMinutes: number = this.BUFFER_IN_MINUTES, - ): Date { - if (typeof expiresIn === "number") { - const now = new Date(); - - return new Date(now.getTime() + expiresIn * 1000 - bufferInMinutes * 60 * 1000); - } - - return this.parseTokenExpiry(token, bufferInMinutes) || this.getExpiresAt(0, token, bufferInMinutes); - } - - private parseTokenExpiry(token: string | undefined, bufferInMinutes: number): Date | undefined { - if (!token || token === "no_token") { - return; - } - - try { - const decoded = decodeToken(token); - - if (decoded && typeof decoded.expiresAt === "number") { - const ms = decoded.expiresAt * 1000 - bufferInMinutes * 60 * 1000; - - return new Date(ms); - } - } catch {} - } -} diff --git a/src/custom/index.ts b/src/custom/index.ts deleted file mode 100644 index 49d89d60..00000000 --- a/src/custom/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "./RefreshBearerProvider.js"; diff --git a/src/custom/proxy/CustomProxyStream.ts b/src/custom/proxy/CustomProxyStream.ts deleted file mode 100644 index bb114a4d..00000000 --- a/src/custom/proxy/CustomProxyStream.ts +++ /dev/null @@ -1,40 +0,0 @@ -/** - * Patch: Proxy-specific Stream wrapper that enforces `proxy` as required. - * - * Reuses the underlying CustomStream class to preserve the logic we added on top - * of generated sockets (e.g., sending configuration messages, handling responses). - */ - -import * as environments from "../../environments.js"; -import * as api from "../../api/index.js"; -import { Stream } from "../CustomStream.js"; -import { StreamSocket } from "../CustomStreamSocket.js"; -import type { CortiClient } from "../CortiClient.js"; - -export type ProxyOptions = { - url: string; - /** Array passed as-is to WS; object encoded like headers (name, encodeURIComponent(value), ...). */ - protocols?: string[] | CortiClient.HeadersRecord; - queryParameters?: Record; -}; - -export class CustomProxyStream { - private _stream: Stream; - - constructor() { - this._stream = new Stream({ - environment: environments.CortiEnvironment.Eu, - tenantName: "", - }); - } - - public connect(args: { - proxy: ProxyOptions; - configuration?: api.StreamConfig; - debug?: boolean; - reconnectAttempts?: number; - }): Promise { - // id is not used in proxy mode, but required by the underlying type - return this._stream.connect({ ...args, id: "" }); - } -} diff --git a/src/custom/proxy/CustomProxyTranscribe.ts b/src/custom/proxy/CustomProxyTranscribe.ts deleted file mode 100644 index a9e14556..00000000 --- a/src/custom/proxy/CustomProxyTranscribe.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Patch: Proxy-specific Transcribe wrapper that enforces `proxy` as required. - * - * Reuses the underlying CustomTranscribe class to preserve the logic we added on top - * of generated sockets (e.g., sending configuration messages, handling responses). - */ - -import * as environments from "../../environments.js"; -import * as api from "../../api/index.js"; -import { Transcribe } from "../CustomTranscribe.js"; -import { TranscribeSocket } from "../CustomTranscribeSocket.js"; -import type { CortiClient } from "../CortiClient.js"; - -export type ProxyOptions = { - url: string; - /** Array passed as-is to WS; object encoded like headers (name, encodeURIComponent(value), ...). */ - protocols?: string[] | CortiClient.HeadersRecord; - queryParameters?: Record; -}; - -export class CustomProxyTranscribe { - private _transcribe: Transcribe; - - constructor() { - this._transcribe = new Transcribe({ - environment: environments.CortiEnvironment.Eu, - tenantName: "", - }); - } - - public connect(args: { - proxy: ProxyOptions; - configuration?: api.TranscribeConfig; - debug?: boolean; - reconnectAttempts?: number; - }): Promise { - return this._transcribe.connect(args); - } -} diff --git a/src/custom/utils/decodeToken.ts b/src/custom/utils/decodeToken.ts deleted file mode 100644 index 770010f5..00000000 --- a/src/custom/utils/decodeToken.ts +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Decodes a JWT token and extracts environment and tenant details from its issuer URL. - * - * This function assumes the JWT token follows the standard header.payload.signature format. - * It decodes the payload from base64 URL format, parses it as JSON, and then uses a regex - * to extract the `environment` and `tenant` from the issuer URL (iss field) if it matches the pattern: - * https://keycloak.{environment}.corti.app/realms/{tenant}. - * - * @param token - A JSON Web Token (JWT) string. - * @returns An object containing: - * - `environment`: The extracted environment from the issuer URL. - * - `tenant`: The extracted tenant from the issuer URL. - * - `accessToken`: The original token string. - * If the issuer URL doesn't match the expected format, the function returns the full decoded token details. - * - * @throws Will throw an error if: - * - The token format is invalid. - * - The base64 decoding or URI decoding fails. - * - The JSON payload is invalid. - * - The token payload does not contain an issuer (iss) field. - */ -export function decodeToken(token: string) { - // Validate the token structure (should contain at least header and payload parts) - const parts = token ? token.split(".") : ""; - - if (parts.length < 2) { - return null; - } - - // Retrieve the payload (second part) of the JWT token - const base64Url = parts[1]; - - // Replace URL-safe characters to match standard base64 encoding - const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/"); - - // Decode the base64 string into a JSON string - let jsonPayload: string; - try { - jsonPayload = decodeURIComponent( - atob(base64) - .split("") - .map((c) => "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2)) - .join(""), - ); - } catch (error) { - return null; - } - - // Parse the JSON string to obtain token details - let tokenDetails: { iss: string; [key: string]: unknown }; - try { - tokenDetails = JSON.parse(jsonPayload); - } catch (error) { - return null; - } - - // Extract the issuer URL from the token details - const issuerUrl: string = tokenDetails.iss; - - if (!issuerUrl) { - return null; - } - - // Regex to extract environment and tenant from issuer URL: - // Expected format: https://keycloak.{environment}.corti.app/realms/{tenant} - // Note: Unnecessary escapes in character classes have been removed. - const regex = /^https:\/\/(keycloak|auth)\.([^.]+)\.corti\.app\/realms\/([^/]+)/; - const match = issuerUrl.match(regex); - - // If the issuer URL matches the expected pattern, return the extracted values along with the token - if (match) { - const expiresAt = tokenDetails.exp && typeof tokenDetails.exp === "number" ? tokenDetails.exp : undefined; - - return { - environment: match[2], - tenantName: match[3], - accessToken: token, - expiresAt, - }; - } - - return null; -} diff --git a/src/custom/utils/encodeHeadersAsWsProtocols.ts b/src/custom/utils/encodeHeadersAsWsProtocols.ts deleted file mode 100644 index 28c930a7..00000000 --- a/src/custom/utils/encodeHeadersAsWsProtocols.ts +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Patch: utilities to encode client headers as WebSocket subprotocols (for proxy scenarios). - * Format: [headerName1, encodeURIComponent(value1), headerName2, encodeURIComponent(value2), ...] - */ - -import * as core from "../../core/index.js"; -import type { CortiClient } from "../CortiClient.js"; - -/** Patch: headers added by the SDK; exclude these when filterSdkHeaders is true (e.g. merged client headers). */ -const SDK_HEADER_NAMES = new Set([ - "Tenant-Name", - "X-Fern-Language", - "X-Fern-SDK-Name", - "X-Fern-SDK-Version", - "User-Agent", - "X-Fern-Runtime", - "X-Fern-Runtime-Version", -]); - -/** - * Patch: resolves header values (including suppliers/functions) and returns a flat array - * of [name, encodeURIComponent(value)] for each header, skipping undefined/empty values. - * When filterSdkHeaders is true, SDK-added headers are excluded (use for merged client headers). - */ -export async function buildProtocolsFromHeaders( - headers: CortiClient.HeadersRecord | undefined, - filterSdkHeaders = false -): Promise { - if (!headers || Object.keys(headers).length === 0) { - return []; - } - const protocols: string[] = []; - for (const [name, valueOrSupplier] of Object.entries(headers)) { - if (filterSdkHeaders && SDK_HEADER_NAMES.has(name)) { - continue; - } - const value = await core.Supplier.get(valueOrSupplier); - if (value != null && value !== "") { - protocols.push(name, encodeURIComponent(value)); - } - } - return protocols; -} - -/** Patch: options shape for getWsProtocols (encodeHeadersAsWsProtocols + headers). */ -export type WsProtocolsOptions = { - encodeHeadersAsWsProtocols?: boolean; - headers?: CortiClient.HeadersRecord; -}; - -/** Patch: proxy protocols as array (pass-through) or object (encoded like headers). */ -export type ProxyProtocolsInput = string[] | CortiClient.HeadersRecord; - -/** - * Patch: returns WebSocket protocols array for connect (header-derived + proxy protocols). - * proxyProtocols: array is passed as-is; object is encoded like headers (name, encodeURIComponent(value), ...). - */ -export async function getWsProtocols( - options: WsProtocolsOptions, - proxyProtocols?: ProxyProtocolsInput -): Promise { - const headerProtocols = - options.encodeHeadersAsWsProtocols && options.headers - ? await buildProtocolsFromHeaders(options.headers, true) - : []; - const resolvedProxy = - proxyProtocols == null - ? [] - : Array.isArray(proxyProtocols) - ? proxyProtocols - : await buildProtocolsFromHeaders(proxyProtocols, false); - const combined = [...headerProtocols, ...resolvedProxy]; - return combined.length > 0 ? combined : []; -} diff --git a/src/custom/utils/getEnvironmentFromString.ts b/src/custom/utils/getEnvironmentFromString.ts deleted file mode 100644 index 1c1b89d8..00000000 --- a/src/custom/utils/getEnvironmentFromString.ts +++ /dev/null @@ -1,16 +0,0 @@ -import * as core from "../../core/index.js"; -import * as environments from "../../environments.js"; - -export type Environment = CortiInternalEnvironment | string; -export type CortiInternalEnvironment = core.Supplier; - -export function getEnvironment(environment: Environment = "eu"): CortiInternalEnvironment { - return typeof environment === "string" - ? { - base: `https://api.${environment}.corti.app/v2`, - wss: `wss://api.${environment}.corti.app/audio-bridge/v2`, - login: `https://auth.${environment}.corti.app/realms`, - agents: `https://api.${environment}.corti.app`, - } - : environment; -} diff --git a/src/custom/utils/localStorage.ts b/src/custom/utils/localStorage.ts deleted file mode 100644 index af93415c..00000000 --- a/src/custom/utils/localStorage.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { CortiSDKError, CortiSDKErrorCodes } from "../CortiSDKError.js"; - -export const LOCAL_STORAGE_ERROR_CODE = "local_storage_error" as const; - -export const requireLocalStorage = (): Storage => { - if (typeof window === "undefined" || !window.localStorage) { - throw new CortiSDKError("LocalStorage operation failed: storage is not available in this environment.", { - code: CortiSDKErrorCodes.LOCAL_STORAGE_ERROR, - }); - } - - return window.localStorage; -}; - -export const setLocalStorageItem = (key: string, value: string): void => { - const storage = requireLocalStorage(); - - try { - storage.setItem(key, value); - } catch (error) { - throw new CortiSDKError("LocalStorage set operation failed.", { - code: CortiSDKErrorCodes.LOCAL_STORAGE_ERROR, - cause: error, - }); - } -}; - -export const getLocalStorageItem = (key: string): string | null => { - const storage = requireLocalStorage(); - - try { - return storage.getItem(key); - } catch (error) { - throw new CortiSDKError("LocalStorage get operation failed.", { - code: CortiSDKErrorCodes.LOCAL_STORAGE_ERROR, - cause: error, - }); - } -}; diff --git a/src/custom/utils/pkce.ts b/src/custom/utils/pkce.ts deleted file mode 100644 index 5f393c28..00000000 --- a/src/custom/utils/pkce.ts +++ /dev/null @@ -1,17 +0,0 @@ -const base64URLEncode = (buffer: Uint8Array): string => { - const base64 = btoa(String.fromCharCode(...buffer)); - return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, ""); -}; - -export const generateCodeVerifier = (): string => { - const array = new Uint8Array(32); - crypto.getRandomValues(array); - return base64URLEncode(array); -}; - -export const generateCodeChallenge = async (verifier: string): Promise => { - const encoder = new TextEncoder(); - const data = encoder.encode(verifier); - const hash = await crypto.subtle.digest("SHA-256", data); - return base64URLEncode(new Uint8Array(hash)); -}; diff --git a/src/custom/utils/resolveClientOptions.ts b/src/custom/utils/resolveClientOptions.ts deleted file mode 100644 index c3e0e5d9..00000000 --- a/src/custom/utils/resolveClientOptions.ts +++ /dev/null @@ -1,105 +0,0 @@ -import * as core from "../../core/index.js"; -import { decodeToken } from "./decodeToken.js"; -import { CortiClient } from "../CortiClient.js"; -import { ParseError } from "../../core/schemas/index.js"; -import { Environment, getEnvironment } from "./getEnvironmentFromString.js"; -import { ExpectedTokenResponse } from "../RefreshBearerProvider.js"; - -type ResolvedClientOptions = { - environment: Environment; - tenantName: core.Supplier; - initialTokenResponse?: Promise; -}; - -function isClientCredentialsOptions(options: CortiClient.Options): options is CortiClient.OptionsWithClientCredentials { - return !!options.auth && "clientId" in options.auth; -} - -export function resolveClientOptions(options: CortiClient.Options): ResolvedClientOptions { - if (isClientCredentialsOptions(options)) { - return { - tenantName: options.tenantName, - environment: options.environment, - }; - } - - // When auth is not provided (baseUrl-only or environment-object scenario), use provided values or defaults - if (!options.auth) { - return { - tenantName: options.tenantName || "", - environment: options.environment || "", - }; - } - - if ("accessToken" in options.auth) { - const decoded = decodeToken(options.auth.accessToken || ""); - - /** - * Do not throw an error when we have some proxying: - * baseUrl is set - * or - * environment is explicitly provided (not string-generated) - */ - if (!decoded && !options.baseUrl && typeof options.environment !== "object") { - throw new ParseError([ - { - path: ["auth", "accessToken"], - message: "Invalid access token format", - }, - ]); - } - - return { - tenantName: options.tenantName || decoded?.tenantName || "", - environment: options.environment || decoded?.environment || "", - }; - } - - /** - * This branch -- is when we have "refreshAccessToken" defined but no accessToken. - * Trying to avoid initial request at all cost - */ - if (options.tenantName && options.environment) { - return { - tenantName: options.tenantName, - environment: options.environment, - }; - } - - // At this point, auth exists and has refreshAccessToken (BearerOptions without accessToken) - const auth = options.auth as { refreshAccessToken: () => Promise }; - - const tokenResponsePromise = (async () => { - const tokenResponse = await core.Supplier.get(auth.refreshAccessToken); - const decoded = decodeToken(tokenResponse.accessToken); - - /** - * Do not throw an error when we have some proxying: - * baseUrl is set - * or - * environment is explicitly provided (not string-generated) - */ - if (!decoded && !options.baseUrl && typeof options.environment !== "object") { - throw new ParseError([ - { - path: ["auth", "refreshAccessToken"], - message: "Returned invalid access token format", - }, - ]); - } - - return { - tokenResponse, - tenantName: decoded?.tenantName || "", - environment: decoded?.environment || "", - }; - })(); - - return { - tenantName: options.tenantName || tokenResponsePromise.then(({ tenantName }) => tenantName), - environment: - options.environment || - tokenResponsePromise.then(({ environment }) => core.Supplier.get(getEnvironment(environment))), - initialTokenResponse: tokenResponsePromise.then((result) => result.tokenResponse), - }; -} diff --git a/src/custom/utils/tokenRequest.ts b/src/custom/utils/tokenRequest.ts deleted file mode 100644 index d1eaa549..00000000 --- a/src/custom/utils/tokenRequest.ts +++ /dev/null @@ -1,64 +0,0 @@ -import * as Corti from "../../api/index.js"; -import * as serializers from "../../serialization/index.js"; - -export type TokenRequest = Corti.AuthGetTokenRequest & - Partial<{ - grantType: "client_credentials" | "authorization_code" | "refresh_token" | "password"; - code: string; - redirectUri: string; - refreshToken: string; - codeVerifier: string; - username: string; - password: string; - scopes: string[]; - }>; - -export const buildTokenRequestBody = (request: TokenRequest): URLSearchParams => { - type TokenRequestBody = Record; - const serializedRequest = serializers.AuthGetTokenRequest.jsonOrThrow(request, { - unrecognizedObjectKeys: "strip", - omitUndefined: true, - }); - - // Build scope string: always include "openid", add any additional scopes - const allScopes = ["openid", ...(request.scopes || [])]; - const scopeString = [...new Set(allScopes)].join(" "); - - const tokenRequestBody: TokenRequestBody = { - scope: scopeString, - grant_type: request.grantType || "client_credentials", - }; - - Object.entries(serializedRequest).forEach(([key, value]) => { - if (value != null) { - tokenRequestBody[key] = String(value); - } - }); - - if (request.grantType === "authorization_code") { - if (request.code != null) { - tokenRequestBody.code = request.code; - } - if (request.redirectUri != null) { - tokenRequestBody.redirect_uri = request.redirectUri; - } - if (request.codeVerifier != null) { - tokenRequestBody.code_verifier = request.codeVerifier; - } - } - - if (request.grantType === "refresh_token" && request.refreshToken != null) { - tokenRequestBody.refresh_token = request.refreshToken; - } - - if (request.grantType === "password") { - if (request.username != null) { - tokenRequestBody.username = request.username; - } - if (request.password != null) { - tokenRequestBody.password = request.password; - } - } - - return new URLSearchParams(tokenRequestBody); -}; diff --git a/src/custom/utils/withCredentialsConfig.ts b/src/custom/utils/withCredentialsConfig.ts deleted file mode 100644 index cdca8f1c..00000000 --- a/src/custom/utils/withCredentialsConfig.ts +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Global default for fetcher withCredentials. Set by CortiClient when withCredentials - * is passed in options; the core fetcher reads this when args.withCredentials is undefined. - */ -let defaultWithCredentials: boolean | undefined = undefined; - -export function getDefaultWithCredentials(): boolean | undefined { - return defaultWithCredentials; -} - -export function setDefaultWithCredentials(value: boolean | undefined): void { - defaultWithCredentials = value; -} diff --git a/src/environments.ts b/src/environments.ts index 50a2c927..9cdf107e 100644 --- a/src/environments.ts +++ b/src/environments.ts @@ -1,6 +1,4 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export interface CortiEnvironmentUrls { base: string; diff --git a/src/errors/CortiError.ts b/src/errors/CortiError.ts index f8a40423..ee06b977 100644 --- a/src/errors/CortiError.ts +++ b/src/errors/CortiError.ts @@ -1,8 +1,6 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as core from "../core/index.js"; +import type * as core from "../core/index.js"; import { toJson } from "../core/json.js"; export class CortiError extends Error { @@ -22,7 +20,12 @@ export class CortiError extends Error { rawResponse?: core.RawResponse; }) { super(buildMessage({ message, statusCode, body })); - Object.setPrototypeOf(this, CortiError.prototype); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = this.constructor.name; this.statusCode = statusCode; this.body = body; this.rawResponse = rawResponse; @@ -38,7 +41,7 @@ function buildMessage({ statusCode: number | undefined; body: unknown | undefined; }): string { - let lines: string[] = []; + const lines: string[] = []; if (message != null) { lines.push(message); } diff --git a/src/errors/CortiTimeoutError.ts b/src/errors/CortiTimeoutError.ts index 81808d54..cc24d075 100644 --- a/src/errors/CortiTimeoutError.ts +++ b/src/errors/CortiTimeoutError.ts @@ -1,10 +1,13 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. export class CortiTimeoutError extends Error { constructor(message: string) { super(message); - Object.setPrototypeOf(this, CortiTimeoutError.prototype); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = this.constructor.name; } } diff --git a/src/errors/handleNonStatusCodeError.ts b/src/errors/handleNonStatusCodeError.ts new file mode 100644 index 00000000..4d734aeb --- /dev/null +++ b/src/errors/handleNonStatusCodeError.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as core from "../core/index.js"; +import * as errors from "./index.js"; + +export function handleNonStatusCodeError( + error: core.Fetcher.Error, + rawResponse: core.RawResponse, + method: string, + path: string, +): never { + switch (error.reason) { + case "non-json": + throw new errors.CortiError({ + statusCode: error.statusCode, + body: error.rawBody, + rawResponse: rawResponse, + }); + case "body-is-null": + throw new errors.CortiError({ + statusCode: error.statusCode, + rawResponse: rawResponse, + }); + case "timeout": + throw new errors.CortiTimeoutError(`Timeout exceeded when calling ${method} ${path}.`); + case "unknown": + throw new errors.CortiError({ + message: error.errorMessage, + rawResponse: rawResponse, + }); + default: + throw new errors.CortiError({ + message: "Unknown error", + rawResponse: rawResponse, + }); + } +} diff --git a/src/index.ts b/src/index.ts index 19219175..248ff159 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,30 +1,7 @@ export * as Corti from "./api/index.js"; +export type { BaseClientOptions, BaseRequestOptions } from "./BaseClient.js"; +export { CortiClient } from "./Client.js"; +export { CortiEnvironment, type CortiEnvironmentUrls } from "./environments.js"; export { CortiError, CortiTimeoutError } from "./errors/index.js"; +export * from "./exports.js"; export * as serialization from "./serialization/index.js"; -/** - * Patch: use custom CortiClient instead of the generated one. - */ -export { CortiClient } from "./custom/CortiClient.js"; -/** - * Patch: lightweight proxy client with only WebSocket resources. - */ -export { CortiWebSocketProxyClient } from "./custom/CortiWebSocketProxyClient.js"; -export { CortiEnvironment, CortiEnvironmentUrls } from "./environments.js"; - -/** - * Patch: added new export to provide Authorization code flow support. - */ -export { Auth as CortiAuth } from "./custom/CortiAuth.js"; -/** - * Patch: added new exports to provide schema validation errors. - */ -export { JsonError } from "./core/schemas/builders/schema-utils/JsonError.js"; -export { ParseError } from "./core/schemas/builders/schema-utils/ParseError.js"; -/** - * Patch: added new export to provide SDK-level error handling. - */ -export { CortiSDKError } from "./custom/CortiSDKError.js"; -/** - * Patch: added new export to expose environment resolution utility. - */ -export { getEnvironment } from "./custom/utils/getEnvironmentFromString.js"; diff --git a/src/serialization/resources/agents/client/list.ts b/src/serialization/resources/agents/client/list.ts index 63f5bbf1..9866ad37 100644 --- a/src/serialization/resources/agents/client/list.ts +++ b/src/serialization/resources/agents/client/list.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../index.js"; -import * as Corti from "../../../../api/index.js"; +import type * as Corti from "../../../../api/index.js"; import * as core from "../../../../core/index.js"; +import type * as serializers from "../../../index.js"; import { AgentsAgentResponse } from "../../../types/AgentsAgentResponse.js"; export const Response: core.serialization.Schema = diff --git a/src/serialization/resources/agents/client/requests/AgentsCreateAgent.ts b/src/serialization/resources/agents/client/requests/AgentsCreateAgent.ts index e3bbcf31..38b6a31b 100644 --- a/src/serialization/resources/agents/client/requests/AgentsCreateAgent.ts +++ b/src/serialization/resources/agents/client/requests/AgentsCreateAgent.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; import { AgentsCreateAgentAgentType } from "../../types/AgentsCreateAgentAgentType.js"; import { AgentsCreateAgentExpertsItem } from "../../types/AgentsCreateAgentExpertsItem.js"; diff --git a/src/serialization/resources/agents/client/requests/AgentsMessageSendParams.ts b/src/serialization/resources/agents/client/requests/AgentsMessageSendParams.ts index 45d60745..fd4dce8e 100644 --- a/src/serialization/resources/agents/client/requests/AgentsMessageSendParams.ts +++ b/src/serialization/resources/agents/client/requests/AgentsMessageSendParams.ts @@ -1,16 +1,14 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; import { AgentsMessage } from "../../../../types/AgentsMessage.js"; import { AgentsMessageSendConfiguration } from "../../../../types/AgentsMessageSendConfiguration.js"; export const AgentsMessageSendParams: core.serialization.Schema< serializers.AgentsMessageSendParams.Raw, - Corti.AgentsMessageSendParams + Omit > = core.serialization.object({ message: AgentsMessage, configuration: AgentsMessageSendConfiguration.optional(), diff --git a/src/serialization/resources/agents/index.ts b/src/serialization/resources/agents/index.ts index f095e147..d9adb1af 100644 --- a/src/serialization/resources/agents/index.ts +++ b/src/serialization/resources/agents/index.ts @@ -1,2 +1,2 @@ -export * from "./types/index.js"; export * from "./client/index.js"; +export * from "./types/index.js"; diff --git a/src/serialization/resources/agents/types/AgentsCreateAgentAgentType.ts b/src/serialization/resources/agents/types/AgentsCreateAgentAgentType.ts index 8417470d..831b82a0 100644 --- a/src/serialization/resources/agents/types/AgentsCreateAgentAgentType.ts +++ b/src/serialization/resources/agents/types/AgentsCreateAgentAgentType.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../index.js"; -import * as Corti from "../../../../api/index.js"; +import type * as Corti from "../../../../api/index.js"; import * as core from "../../../../core/index.js"; +import type * as serializers from "../../../index.js"; export const AgentsCreateAgentAgentType: core.serialization.Schema< serializers.AgentsCreateAgentAgentType.Raw, diff --git a/src/serialization/resources/agents/types/AgentsCreateAgentExpertsItem.ts b/src/serialization/resources/agents/types/AgentsCreateAgentExpertsItem.ts index b425cb04..8e113572 100644 --- a/src/serialization/resources/agents/types/AgentsCreateAgentExpertsItem.ts +++ b/src/serialization/resources/agents/types/AgentsCreateAgentExpertsItem.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../index.js"; -import * as Corti from "../../../../api/index.js"; +import type * as Corti from "../../../../api/index.js"; import * as core from "../../../../core/index.js"; +import type * as serializers from "../../../index.js"; import { AgentsCreateExpert } from "../../../types/AgentsCreateExpert.js"; import { AgentsCreateExpertReference } from "../../../types/AgentsCreateExpertReference.js"; diff --git a/src/serialization/resources/agents/types/AgentsMessageSendResponse.ts b/src/serialization/resources/agents/types/AgentsMessageSendResponse.ts index 13ec08fa..9e7b74db 100644 --- a/src/serialization/resources/agents/types/AgentsMessageSendResponse.ts +++ b/src/serialization/resources/agents/types/AgentsMessageSendResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../index.js"; -import * as Corti from "../../../../api/index.js"; +import type * as Corti from "../../../../api/index.js"; import * as core from "../../../../core/index.js"; +import type * as serializers from "../../../index.js"; import { AgentsMessage } from "../../../types/AgentsMessage.js"; import { AgentsTask } from "../../../types/AgentsTask.js"; diff --git a/src/serialization/resources/auth/client/requests/AuthGetTokenRequest.ts b/src/serialization/resources/auth/client/requests/GetTokenAuthRequest.ts similarity index 51% rename from src/serialization/resources/auth/client/requests/AuthGetTokenRequest.ts rename to src/serialization/resources/auth/client/requests/GetTokenAuthRequest.ts index ac3c8586..78c6ecd3 100644 --- a/src/serialization/resources/auth/client/requests/AuthGetTokenRequest.ts +++ b/src/serialization/resources/auth/client/requests/GetTokenAuthRequest.ts @@ -1,20 +1,18 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; -export const AuthGetTokenRequest: core.serialization.Schema< - serializers.AuthGetTokenRequest.Raw, - Corti.AuthGetTokenRequest +export const GetTokenAuthRequest: core.serialization.Schema< + serializers.GetTokenAuthRequest.Raw, + Corti.GetTokenAuthRequest > = core.serialization.object({ clientId: core.serialization.property("client_id", core.serialization.string()), clientSecret: core.serialization.property("client_secret", core.serialization.string().optional()), }); -export declare namespace AuthGetTokenRequest { +export declare namespace GetTokenAuthRequest { export interface Raw { client_id: string; client_secret?: string | null; diff --git a/src/serialization/resources/auth/client/requests/index.ts b/src/serialization/resources/auth/client/requests/index.ts index 6ccec97d..938c32e9 100644 --- a/src/serialization/resources/auth/client/requests/index.ts +++ b/src/serialization/resources/auth/client/requests/index.ts @@ -1 +1 @@ -export { AuthGetTokenRequest } from "./AuthGetTokenRequest.js"; +export { GetTokenAuthRequest } from "./GetTokenAuthRequest.js"; diff --git a/src/serialization/resources/auth/index.ts b/src/serialization/resources/auth/index.ts index f095e147..d9adb1af 100644 --- a/src/serialization/resources/auth/index.ts +++ b/src/serialization/resources/auth/index.ts @@ -1,2 +1,2 @@ -export * from "./types/index.js"; export * from "./client/index.js"; +export * from "./types/index.js"; diff --git a/src/serialization/resources/auth/types/GetTokenResponse.ts b/src/serialization/resources/auth/types/GetTokenResponse.ts index f09aa775..de799772 100644 --- a/src/serialization/resources/auth/types/GetTokenResponse.ts +++ b/src/serialization/resources/auth/types/GetTokenResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../index.js"; -import * as Corti from "../../../../api/index.js"; +import type * as Corti from "../../../../api/index.js"; import * as core from "../../../../core/index.js"; +import type * as serializers from "../../../index.js"; export const GetTokenResponse: core.serialization.ObjectSchema< serializers.GetTokenResponse.Raw, diff --git a/src/serialization/resources/codes/client/requests/CodesGeneralPredictRequest.ts b/src/serialization/resources/codes/client/requests/CodesGeneralPredictRequest.ts index 21a40a58..5298aab0 100644 --- a/src/serialization/resources/codes/client/requests/CodesGeneralPredictRequest.ts +++ b/src/serialization/resources/codes/client/requests/CodesGeneralPredictRequest.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; -import { CommonCodingSystemEnum } from "../../../../types/CommonCodingSystemEnum.js"; +import type * as serializers from "../../../../index.js"; import { CommonAiContext } from "../../../../types/CommonAiContext.js"; +import { CommonCodingSystemEnum } from "../../../../types/CommonCodingSystemEnum.js"; export const CodesGeneralPredictRequest: core.serialization.Schema< serializers.CodesGeneralPredictRequest.Raw, diff --git a/src/serialization/resources/documents/client/requests/DocumentsUpdateRequest.ts b/src/serialization/resources/documents/client/requests/DocumentsUpdateRequest.ts index b5ab6788..39624bab 100644 --- a/src/serialization/resources/documents/client/requests/DocumentsUpdateRequest.ts +++ b/src/serialization/resources/documents/client/requests/DocumentsUpdateRequest.ts @@ -1,15 +1,13 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; import { DocumentsSectionInput } from "../../../../types/DocumentsSectionInput.js"; export const DocumentsUpdateRequest: core.serialization.Schema< serializers.DocumentsUpdateRequest.Raw, - Corti.DocumentsUpdateRequest + Omit > = core.serialization.object({ name: core.serialization.string().optional(), sections: core.serialization.list(DocumentsSectionInput).optional(), diff --git a/src/serialization/resources/facts/client/requests/FactsBatchUpdateRequest.ts b/src/serialization/resources/facts/client/requests/FactsBatchUpdateRequest.ts index 66a16fee..7b8ef40c 100644 --- a/src/serialization/resources/facts/client/requests/FactsBatchUpdateRequest.ts +++ b/src/serialization/resources/facts/client/requests/FactsBatchUpdateRequest.ts @@ -1,15 +1,13 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; import { FactsBatchUpdateInput } from "../../../../types/FactsBatchUpdateInput.js"; export const FactsBatchUpdateRequest: core.serialization.Schema< serializers.FactsBatchUpdateRequest.Raw, - Corti.FactsBatchUpdateRequest + Omit > = core.serialization.object({ facts: core.serialization.list(FactsBatchUpdateInput), }); diff --git a/src/serialization/resources/facts/client/requests/FactsCreateRequest.ts b/src/serialization/resources/facts/client/requests/FactsCreateRequest.ts index f8590277..eb32e165 100644 --- a/src/serialization/resources/facts/client/requests/FactsCreateRequest.ts +++ b/src/serialization/resources/facts/client/requests/FactsCreateRequest.ts @@ -1,15 +1,13 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; import { FactsCreateInput } from "../../../../types/FactsCreateInput.js"; export const FactsCreateRequest: core.serialization.Schema< serializers.FactsCreateRequest.Raw, - Corti.FactsCreateRequest + Omit > = core.serialization.object({ facts: core.serialization.list(FactsCreateInput), }); diff --git a/src/serialization/resources/facts/client/requests/FactsExtractRequest.ts b/src/serialization/resources/facts/client/requests/FactsExtractRequest.ts index 09699141..ceb6246c 100644 --- a/src/serialization/resources/facts/client/requests/FactsExtractRequest.ts +++ b/src/serialization/resources/facts/client/requests/FactsExtractRequest.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; import { CommonTextContext } from "../../../../types/CommonTextContext.js"; export const FactsExtractRequest: core.serialization.Schema< diff --git a/src/serialization/resources/facts/client/requests/FactsUpdateRequest.ts b/src/serialization/resources/facts/client/requests/FactsUpdateRequest.ts index 2ebf8f60..5905e834 100644 --- a/src/serialization/resources/facts/client/requests/FactsUpdateRequest.ts +++ b/src/serialization/resources/facts/client/requests/FactsUpdateRequest.ts @@ -1,15 +1,13 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; import { CommonSourceEnum } from "../../../../types/CommonSourceEnum.js"; export const FactsUpdateRequest: core.serialization.Schema< serializers.FactsUpdateRequest.Raw, - Corti.FactsUpdateRequest + Omit > = core.serialization.object({ text: core.serialization.string().optional(), group: core.serialization.string().optional(), diff --git a/src/serialization/resources/facts/client/requests/index.ts b/src/serialization/resources/facts/client/requests/index.ts index 0022b155..ee9e5d91 100644 --- a/src/serialization/resources/facts/client/requests/index.ts +++ b/src/serialization/resources/facts/client/requests/index.ts @@ -1,4 +1,4 @@ -export { FactsCreateRequest } from "./FactsCreateRequest.js"; export { FactsBatchUpdateRequest } from "./FactsBatchUpdateRequest.js"; -export { FactsUpdateRequest } from "./FactsUpdateRequest.js"; +export { FactsCreateRequest } from "./FactsCreateRequest.js"; export { FactsExtractRequest } from "./FactsExtractRequest.js"; +export { FactsUpdateRequest } from "./FactsUpdateRequest.js"; diff --git a/src/serialization/resources/index.ts b/src/serialization/resources/index.ts index cc54e02a..6fbb6cbd 100644 --- a/src/serialization/resources/index.ts +++ b/src/serialization/resources/index.ts @@ -1,21 +1,21 @@ -export * as stream from "./stream/index.js"; -export * from "./stream/client/socket/index.js"; -export * as transcribe from "./transcribe/index.js"; -export * from "./transcribe/client/socket/index.js"; -export * as interactions from "./interactions/index.js"; -export * from "./interactions/types/index.js"; -export * as auth from "./auth/index.js"; -export * from "./auth/types/index.js"; +export * from "./agents/client/requests/index.js"; export * as agents from "./agents/index.js"; export * from "./agents/types/index.js"; +export * from "./auth/client/requests/index.js"; +export * as auth from "./auth/index.js"; +export * from "./auth/types/index.js"; +export * from "./codes/client/requests/index.js"; +export * as codes from "./codes/index.js"; +export * from "./documents/client/requests/index.js"; +export * as documents from "./documents/index.js"; +export * from "./facts/client/requests/index.js"; +export * as facts from "./facts/index.js"; export * from "./interactions/client/requests/index.js"; -export * as transcripts from "./transcripts/index.js"; +export * as interactions from "./interactions/index.js"; +export * from "./interactions/types/index.js"; +export * from "./stream/client/socket/index.js"; +export * as stream from "./stream/index.js"; +export * from "./transcribe/client/socket/index.js"; +export * as transcribe from "./transcribe/index.js"; export * from "./transcripts/client/requests/index.js"; -export * as facts from "./facts/index.js"; -export * from "./facts/client/requests/index.js"; -export * as documents from "./documents/index.js"; -export * from "./documents/client/requests/index.js"; -export * as codes from "./codes/index.js"; -export * from "./codes/client/requests/index.js"; -export * from "./auth/client/requests/index.js"; -export * from "./agents/client/requests/index.js"; +export * as transcripts from "./transcripts/index.js"; diff --git a/src/serialization/resources/interactions/client/requests/InteractionsCreateRequest.ts b/src/serialization/resources/interactions/client/requests/InteractionsCreateRequest.ts index d5ad0960..def31f5f 100644 --- a/src/serialization/resources/interactions/client/requests/InteractionsCreateRequest.ts +++ b/src/serialization/resources/interactions/client/requests/InteractionsCreateRequest.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; -import { Uuid } from "../../../../types/Uuid.js"; +import type * as serializers from "../../../../index.js"; import { InteractionsEncounterCreateRequest } from "../../../../types/InteractionsEncounterCreateRequest.js"; import { InteractionsPatient } from "../../../../types/InteractionsPatient.js"; +import { Uuid } from "../../../../types/Uuid.js"; export const InteractionsCreateRequest: core.serialization.Schema< serializers.InteractionsCreateRequest.Raw, diff --git a/src/serialization/resources/interactions/client/requests/InteractionsUpdateRequest.ts b/src/serialization/resources/interactions/client/requests/InteractionsUpdateRequest.ts index 17990d27..4f9f412e 100644 --- a/src/serialization/resources/interactions/client/requests/InteractionsUpdateRequest.ts +++ b/src/serialization/resources/interactions/client/requests/InteractionsUpdateRequest.ts @@ -1,17 +1,15 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; -import { Uuid } from "../../../../types/Uuid.js"; +import type * as serializers from "../../../../index.js"; import { InteractionsEncounterUpdateRequest } from "../../../../types/InteractionsEncounterUpdateRequest.js"; import { InteractionsPatient } from "../../../../types/InteractionsPatient.js"; +import { Uuid } from "../../../../types/Uuid.js"; export const InteractionsUpdateRequest: core.serialization.Schema< serializers.InteractionsUpdateRequest.Raw, - Corti.InteractionsUpdateRequest + Omit > = core.serialization.object({ assignedUserId: Uuid.optional(), encounter: InteractionsEncounterUpdateRequest.optional(), diff --git a/src/serialization/resources/interactions/index.ts b/src/serialization/resources/interactions/index.ts index f095e147..d9adb1af 100644 --- a/src/serialization/resources/interactions/index.ts +++ b/src/serialization/resources/interactions/index.ts @@ -1,2 +1,2 @@ -export * from "./types/index.js"; export * from "./client/index.js"; +export * from "./types/index.js"; diff --git a/src/serialization/resources/interactions/types/InteractionsListRequestSort.ts b/src/serialization/resources/interactions/types/InteractionsListRequestSort.ts index 7fed8b7b..c4ca7aff 100644 --- a/src/serialization/resources/interactions/types/InteractionsListRequestSort.ts +++ b/src/serialization/resources/interactions/types/InteractionsListRequestSort.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../index.js"; -import * as Corti from "../../../../api/index.js"; +import type * as Corti from "../../../../api/index.js"; import * as core from "../../../../core/index.js"; +import type * as serializers from "../../../index.js"; export const InteractionsListRequestSort: core.serialization.Schema< serializers.InteractionsListRequestSort.Raw, diff --git a/src/serialization/resources/stream/client/socket/StreamSocketResponse.ts b/src/serialization/resources/stream/client/socket/StreamSocketResponse.ts index e533dd1a..da48f3cb 100644 --- a/src/serialization/resources/stream/client/socket/StreamSocketResponse.ts +++ b/src/serialization/resources/stream/client/socket/StreamSocketResponse.ts @@ -1,17 +1,15 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; import { StreamConfigStatusMessage } from "../../../../types/StreamConfigStatusMessage.js"; -import { StreamTranscriptMessage } from "../../../../types/StreamTranscriptMessage.js"; +import { StreamEndedMessage } from "../../../../types/StreamEndedMessage.js"; +import { StreamErrorMessage } from "../../../../types/StreamErrorMessage.js"; import { StreamFactsMessage } from "../../../../types/StreamFactsMessage.js"; import { StreamFlushedMessage } from "../../../../types/StreamFlushedMessage.js"; -import { StreamEndedMessage } from "../../../../types/StreamEndedMessage.js"; +import { StreamTranscriptMessage } from "../../../../types/StreamTranscriptMessage.js"; import { StreamUsageMessage } from "../../../../types/StreamUsageMessage.js"; -import { StreamErrorMessage } from "../../../../types/StreamErrorMessage.js"; export const StreamSocketResponse: core.serialization.Schema< serializers.StreamSocketResponse.Raw, diff --git a/src/serialization/resources/transcribe/client/socket/TranscribeSocketResponse.ts b/src/serialization/resources/transcribe/client/socket/TranscribeSocketResponse.ts index 6fd04b71..1bcca04d 100644 --- a/src/serialization/resources/transcribe/client/socket/TranscribeSocketResponse.ts +++ b/src/serialization/resources/transcribe/client/socket/TranscribeSocketResponse.ts @@ -1,17 +1,15 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; +import type * as serializers from "../../../../index.js"; +import { TranscribeCommandMessage } from "../../../../types/TranscribeCommandMessage.js"; import { TranscribeConfigStatusMessage } from "../../../../types/TranscribeConfigStatusMessage.js"; -import { TranscribeUsageMessage } from "../../../../types/TranscribeUsageMessage.js"; -import { TranscribeFlushedMessage } from "../../../../types/TranscribeFlushedMessage.js"; import { TranscribeEndedMessage } from "../../../../types/TranscribeEndedMessage.js"; import { TranscribeErrorMessage } from "../../../../types/TranscribeErrorMessage.js"; +import { TranscribeFlushedMessage } from "../../../../types/TranscribeFlushedMessage.js"; import { TranscribeTranscriptMessage } from "../../../../types/TranscribeTranscriptMessage.js"; -import { TranscribeCommandMessage } from "../../../../types/TranscribeCommandMessage.js"; +import { TranscribeUsageMessage } from "../../../../types/TranscribeUsageMessage.js"; export const TranscribeSocketResponse: core.serialization.Schema< serializers.TranscribeSocketResponse.Raw, diff --git a/src/serialization/resources/transcripts/client/requests/TranscriptsCreateRequest.ts b/src/serialization/resources/transcripts/client/requests/TranscriptsCreateRequest.ts index 06372a22..75339f6d 100644 --- a/src/serialization/resources/transcripts/client/requests/TranscriptsCreateRequest.ts +++ b/src/serialization/resources/transcripts/client/requests/TranscriptsCreateRequest.ts @@ -1,16 +1,14 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../../../../index.js"; -import * as Corti from "../../../../../api/index.js"; +import type * as Corti from "../../../../../api/index.js"; import * as core from "../../../../../core/index.js"; -import { Uuid } from "../../../../types/Uuid.js"; +import type * as serializers from "../../../../index.js"; import { TranscriptsParticipant } from "../../../../types/TranscriptsParticipant.js"; +import { Uuid } from "../../../../types/Uuid.js"; export const TranscriptsCreateRequest: core.serialization.Schema< serializers.TranscriptsCreateRequest.Raw, - Corti.TranscriptsCreateRequest + Omit > = core.serialization.object({ recordingId: Uuid, primaryLanguage: core.serialization.string(), diff --git a/src/serialization/types/AgentsAgent.ts b/src/serialization/types/AgentsAgent.ts index c80ecc79..9289d227 100644 --- a/src/serialization/types/AgentsAgent.ts +++ b/src/serialization/types/AgentsAgent.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsAgentExpertsItem } from "./AgentsAgentExpertsItem.js"; export const AgentsAgent: core.serialization.ObjectSchema = diff --git a/src/serialization/types/AgentsAgentCapabilities.ts b/src/serialization/types/AgentsAgentCapabilities.ts index e8f5f589..93e62f14 100644 --- a/src/serialization/types/AgentsAgentCapabilities.ts +++ b/src/serialization/types/AgentsAgentCapabilities.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsAgentExtension } from "./AgentsAgentExtension.js"; export const AgentsAgentCapabilities: core.serialization.ObjectSchema< @@ -22,6 +20,6 @@ export declare namespace AgentsAgentCapabilities { streaming?: boolean | null; pushNotifications?: boolean | null; stateTransitionHistory?: boolean | null; - extensions?: (AgentsAgentExtension.Raw[] | null) | null; + extensions?: (AgentsAgentExtension.Raw[] | null | undefined) | null; } } diff --git a/src/serialization/types/AgentsAgentCard.ts b/src/serialization/types/AgentsAgentCard.ts index d2b31171..b07ecc9c 100644 --- a/src/serialization/types/AgentsAgentCard.ts +++ b/src/serialization/types/AgentsAgentCard.ts @@ -1,15 +1,13 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { AgentsAgentCapabilities } from "./AgentsAgentCapabilities.js"; +import { AgentsAgentCardSignature } from "./AgentsAgentCardSignature.js"; import { AgentsAgentInterface } from "./AgentsAgentInterface.js"; import { AgentsAgentProvider } from "./AgentsAgentProvider.js"; -import { AgentsAgentCapabilities } from "./AgentsAgentCapabilities.js"; import { AgentsAgentSkill } from "./AgentsAgentSkill.js"; -import { AgentsAgentCardSignature } from "./AgentsAgentCardSignature.js"; export const AgentsAgentCard: core.serialization.ObjectSchema = core.serialization.object({ @@ -43,19 +41,19 @@ export declare namespace AgentsAgentCard { name: string; description: string; url: string; - preferredTransport?: (string | null) | null; - additionalInterfaces?: (AgentsAgentInterface.Raw[] | null) | null; - iconUrl?: (string | null) | null; - documentationUrl?: (string | null) | null; + preferredTransport?: (string | null | undefined) | null; + additionalInterfaces?: (AgentsAgentInterface.Raw[] | null | undefined) | null; + iconUrl?: (string | null | undefined) | null; + documentationUrl?: (string | null | undefined) | null; provider?: AgentsAgentProvider.Raw | null; version: string; capabilities: AgentsAgentCapabilities.Raw; - securitySchemes?: (Record | null) | null; - security?: (Record | null) | null; + securitySchemes?: (Record | null | undefined) | null; + security?: (Record | null | undefined) | null; defaultInputModes: string[]; defaultOutputModes: string[]; skills: AgentsAgentSkill.Raw[]; - supportsAuthenticatedExtendedCard?: (boolean | null) | null; - signatures?: (AgentsAgentCardSignature.Raw[] | null) | null; + supportsAuthenticatedExtendedCard?: (boolean | null | undefined) | null; + signatures?: (AgentsAgentCardSignature.Raw[] | null | undefined) | null; } } diff --git a/src/serialization/types/AgentsAgentCardSignature.ts b/src/serialization/types/AgentsAgentCardSignature.ts index 3b495cd9..b9bd1fd0 100644 --- a/src/serialization/types/AgentsAgentCardSignature.ts +++ b/src/serialization/types/AgentsAgentCardSignature.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsAgentCardSignature: core.serialization.ObjectSchema< serializers.AgentsAgentCardSignature.Raw, diff --git a/src/serialization/types/AgentsAgentExpertsItem.ts b/src/serialization/types/AgentsAgentExpertsItem.ts index 379ccb1a..1978ab11 100644 --- a/src/serialization/types/AgentsAgentExpertsItem.ts +++ b/src/serialization/types/AgentsAgentExpertsItem.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsExpert } from "./AgentsExpert.js"; import { AgentsExpertReference } from "./AgentsExpertReference.js"; diff --git a/src/serialization/types/AgentsAgentExtension.ts b/src/serialization/types/AgentsAgentExtension.ts index dc09a4c9..f3dfb95c 100644 --- a/src/serialization/types/AgentsAgentExtension.ts +++ b/src/serialization/types/AgentsAgentExtension.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsAgentExtension: core.serialization.ObjectSchema< serializers.AgentsAgentExtension.Raw, diff --git a/src/serialization/types/AgentsAgentInterface.ts b/src/serialization/types/AgentsAgentInterface.ts index 7117567f..f8c7187e 100644 --- a/src/serialization/types/AgentsAgentInterface.ts +++ b/src/serialization/types/AgentsAgentInterface.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsAgentInterface: core.serialization.ObjectSchema< serializers.AgentsAgentInterface.Raw, diff --git a/src/serialization/types/AgentsAgentProvider.ts b/src/serialization/types/AgentsAgentProvider.ts index 204efdb5..8915c8ef 100644 --- a/src/serialization/types/AgentsAgentProvider.ts +++ b/src/serialization/types/AgentsAgentProvider.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsAgentProvider: core.serialization.ObjectSchema< serializers.AgentsAgentProvider.Raw, diff --git a/src/serialization/types/AgentsAgentReference.ts b/src/serialization/types/AgentsAgentReference.ts index 46cb2c58..6a96a179 100644 --- a/src/serialization/types/AgentsAgentReference.ts +++ b/src/serialization/types/AgentsAgentReference.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { AgentsAgentReferenceType } from "./AgentsAgentReferenceType.js"; export const AgentsAgentReference: core.serialization.ObjectSchema< serializers.AgentsAgentReference.Raw, Corti.AgentsAgentReference > = core.serialization.object({ - type: core.serialization.stringLiteral("reference"), + type: AgentsAgentReferenceType, id: core.serialization.string().optional(), name: core.serialization.string().optional(), }); export declare namespace AgentsAgentReference { export interface Raw { - type: "reference"; + type: AgentsAgentReferenceType.Raw; id?: string | null; name?: string | null; } diff --git a/src/serialization/types/AgentsAgentReferenceType.ts b/src/serialization/types/AgentsAgentReferenceType.ts new file mode 100644 index 00000000..687b73af --- /dev/null +++ b/src/serialization/types/AgentsAgentReferenceType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const AgentsAgentReferenceType: core.serialization.Schema< + serializers.AgentsAgentReferenceType.Raw, + Corti.AgentsAgentReferenceType +> = core.serialization.enum_(["reference"]); + +export declare namespace AgentsAgentReferenceType { + export type Raw = "reference"; +} diff --git a/src/serialization/types/AgentsAgentResponse.ts b/src/serialization/types/AgentsAgentResponse.ts index 28918a51..bd90f605 100644 --- a/src/serialization/types/AgentsAgentResponse.ts +++ b/src/serialization/types/AgentsAgentResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsAgent } from "./AgentsAgent.js"; import { AgentsAgentReference } from "./AgentsAgentReference.js"; diff --git a/src/serialization/types/AgentsAgentSkill.ts b/src/serialization/types/AgentsAgentSkill.ts index ef2f1a2b..789396d3 100644 --- a/src/serialization/types/AgentsAgentSkill.ts +++ b/src/serialization/types/AgentsAgentSkill.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsMessage } from "./AgentsMessage.js"; export const AgentsAgentSkill: core.serialization.ObjectSchema< @@ -27,9 +25,9 @@ export declare namespace AgentsAgentSkill { name: string; description: string; tags: string[]; - examples?: (AgentsMessage.Raw[] | null) | null; - inputModes?: (string[] | null) | null; - outputModes?: (string[] | null) | null; - security?: (Record | null) | null; + examples?: (AgentsMessage.Raw[] | null | undefined) | null; + inputModes?: (string[] | null | undefined) | null; + outputModes?: (string[] | null | undefined) | null; + security?: (Record | null | undefined) | null; } } diff --git a/src/serialization/types/AgentsArtifact.ts b/src/serialization/types/AgentsArtifact.ts index 2118e27e..63d29168 100644 --- a/src/serialization/types/AgentsArtifact.ts +++ b/src/serialization/types/AgentsArtifact.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsPart } from "./AgentsPart.js"; export const AgentsArtifact: core.serialization.ObjectSchema = diff --git a/src/serialization/types/AgentsContext.ts b/src/serialization/types/AgentsContext.ts index d5e31f08..aea565d3 100644 --- a/src/serialization/types/AgentsContext.ts +++ b/src/serialization/types/AgentsContext.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsContextItemsItem } from "./AgentsContextItemsItem.js"; export const AgentsContext: core.serialization.ObjectSchema = diff --git a/src/serialization/types/AgentsContextItemsItem.ts b/src/serialization/types/AgentsContextItemsItem.ts index ff87461d..51296ae8 100644 --- a/src/serialization/types/AgentsContextItemsItem.ts +++ b/src/serialization/types/AgentsContextItemsItem.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { AgentsTask } from "./AgentsTask.js"; +import type * as serializers from "../index.js"; import { AgentsMessage } from "./AgentsMessage.js"; +import { AgentsTask } from "./AgentsTask.js"; export const AgentsContextItemsItem: core.serialization.Schema< serializers.AgentsContextItemsItem.Raw, diff --git a/src/serialization/types/AgentsCreateExpert.ts b/src/serialization/types/AgentsCreateExpert.ts index 98aec015..fb98856f 100644 --- a/src/serialization/types/AgentsCreateExpert.ts +++ b/src/serialization/types/AgentsCreateExpert.ts @@ -1,17 +1,16 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { AgentsCreateExpertType } from "./AgentsCreateExpertType.js"; import { AgentsCreateMcpServer } from "./AgentsCreateMcpServer.js"; export const AgentsCreateExpert: core.serialization.ObjectSchema< serializers.AgentsCreateExpert.Raw, Corti.AgentsCreateExpert > = core.serialization.object({ - type: core.serialization.stringLiteral("new"), + type: AgentsCreateExpertType, name: core.serialization.string(), description: core.serialization.string(), systemPrompt: core.serialization.string().optional(), @@ -20,7 +19,7 @@ export const AgentsCreateExpert: core.serialization.ObjectSchema< export declare namespace AgentsCreateExpert { export interface Raw { - type: "new"; + type: AgentsCreateExpertType.Raw; name: string; description: string; systemPrompt?: string | null; diff --git a/src/serialization/types/AgentsCreateExpertReference.ts b/src/serialization/types/AgentsCreateExpertReference.ts index 8aef1637..535bdd16 100644 --- a/src/serialization/types/AgentsCreateExpertReference.ts +++ b/src/serialization/types/AgentsCreateExpertReference.ts @@ -1,16 +1,15 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { AgentsCreateExpertReferenceType } from "./AgentsCreateExpertReferenceType.js"; export const AgentsCreateExpertReference: core.serialization.ObjectSchema< serializers.AgentsCreateExpertReference.Raw, Corti.AgentsCreateExpertReference > = core.serialization.object({ - type: core.serialization.stringLiteral("reference"), + type: AgentsCreateExpertReferenceType, id: core.serialization.string().optional(), name: core.serialization.string().optional(), systemPrompt: core.serialization.string().optional(), @@ -18,7 +17,7 @@ export const AgentsCreateExpertReference: core.serialization.ObjectSchema< export declare namespace AgentsCreateExpertReference { export interface Raw { - type: "reference"; + type: AgentsCreateExpertReferenceType.Raw; id?: string | null; name?: string | null; systemPrompt?: string | null; diff --git a/src/serialization/types/AgentsCreateExpertReferenceType.ts b/src/serialization/types/AgentsCreateExpertReferenceType.ts new file mode 100644 index 00000000..818e4eaf --- /dev/null +++ b/src/serialization/types/AgentsCreateExpertReferenceType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const AgentsCreateExpertReferenceType: core.serialization.Schema< + serializers.AgentsCreateExpertReferenceType.Raw, + Corti.AgentsCreateExpertReferenceType +> = core.serialization.enum_(["reference"]); + +export declare namespace AgentsCreateExpertReferenceType { + export type Raw = "reference"; +} diff --git a/src/serialization/types/AgentsCreateExpertType.ts b/src/serialization/types/AgentsCreateExpertType.ts new file mode 100644 index 00000000..bde62982 --- /dev/null +++ b/src/serialization/types/AgentsCreateExpertType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const AgentsCreateExpertType: core.serialization.Schema< + serializers.AgentsCreateExpertType.Raw, + Corti.AgentsCreateExpertType +> = core.serialization.enum_(["new"]); + +export declare namespace AgentsCreateExpertType { + export type Raw = "new"; +} diff --git a/src/serialization/types/AgentsCreateMcpServer.ts b/src/serialization/types/AgentsCreateMcpServer.ts index 70106275..a3a17f4b 100644 --- a/src/serialization/types/AgentsCreateMcpServer.ts +++ b/src/serialization/types/AgentsCreateMcpServer.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { AgentsCreateMcpServerTransportType } from "./AgentsCreateMcpServerTransportType.js"; +import type * as serializers from "../index.js"; import { AgentsCreateMcpServerAuthorizationType } from "./AgentsCreateMcpServerAuthorizationType.js"; +import { AgentsCreateMcpServerTransportType } from "./AgentsCreateMcpServerTransportType.js"; export const AgentsCreateMcpServer: core.serialization.ObjectSchema< serializers.AgentsCreateMcpServer.Raw, diff --git a/src/serialization/types/AgentsCreateMcpServerAuthorizationType.ts b/src/serialization/types/AgentsCreateMcpServerAuthorizationType.ts index 18e224c1..9447f5d6 100644 --- a/src/serialization/types/AgentsCreateMcpServerAuthorizationType.ts +++ b/src/serialization/types/AgentsCreateMcpServerAuthorizationType.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsCreateMcpServerAuthorizationType: core.serialization.Schema< serializers.AgentsCreateMcpServerAuthorizationType.Raw, diff --git a/src/serialization/types/AgentsCreateMcpServerTransportType.ts b/src/serialization/types/AgentsCreateMcpServerTransportType.ts index 5ace911f..8e91252c 100644 --- a/src/serialization/types/AgentsCreateMcpServerTransportType.ts +++ b/src/serialization/types/AgentsCreateMcpServerTransportType.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsCreateMcpServerTransportType: core.serialization.Schema< serializers.AgentsCreateMcpServerTransportType.Raw, diff --git a/src/serialization/types/AgentsDataPart.ts b/src/serialization/types/AgentsDataPart.ts index 05d1049e..5dae00cb 100644 --- a/src/serialization/types/AgentsDataPart.ts +++ b/src/serialization/types/AgentsDataPart.ts @@ -1,21 +1,20 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { AgentsDataPartKind } from "./AgentsDataPartKind.js"; export const AgentsDataPart: core.serialization.ObjectSchema = core.serialization.object({ - kind: core.serialization.stringLiteral("data"), + kind: AgentsDataPartKind, data: core.serialization.record(core.serialization.string(), core.serialization.unknown()), metadata: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), }); export declare namespace AgentsDataPart { export interface Raw { - kind: "data"; + kind: AgentsDataPartKind.Raw; data: Record; metadata?: Record | null; } diff --git a/src/serialization/types/AgentsDataPartKind.ts b/src/serialization/types/AgentsDataPartKind.ts new file mode 100644 index 00000000..3f364751 --- /dev/null +++ b/src/serialization/types/AgentsDataPartKind.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const AgentsDataPartKind: core.serialization.Schema< + serializers.AgentsDataPartKind.Raw, + Corti.AgentsDataPartKind +> = core.serialization.enum_(["data"]); + +export declare namespace AgentsDataPartKind { + export type Raw = "data"; +} diff --git a/src/serialization/types/AgentsExpert.ts b/src/serialization/types/AgentsExpert.ts index 298c4b4c..1b03e633 100644 --- a/src/serialization/types/AgentsExpert.ts +++ b/src/serialization/types/AgentsExpert.ts @@ -1,15 +1,14 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { AgentsExpertType } from "./AgentsExpertType.js"; import { AgentsMcpServer } from "./AgentsMcpServer.js"; export const AgentsExpert: core.serialization.ObjectSchema = core.serialization.object({ - type: core.serialization.stringLiteral("expert"), + type: AgentsExpertType, id: core.serialization.string(), name: core.serialization.string(), description: core.serialization.string(), @@ -19,7 +18,7 @@ export const AgentsExpert: core.serialization.ObjectSchema = core.serialization.object({ - type: core.serialization.stringLiteral("reference"), + type: AgentsExpertReferenceType, id: core.serialization.string(), name: core.serialization.string(), systemPrompt: core.serialization.string().optional(), @@ -18,7 +17,7 @@ export const AgentsExpertReference: core.serialization.ObjectSchema< export declare namespace AgentsExpertReference { export interface Raw { - type: "reference"; + type: AgentsExpertReferenceType.Raw; id: string; name: string; systemPrompt?: string | null; diff --git a/src/serialization/types/AgentsExpertReferenceType.ts b/src/serialization/types/AgentsExpertReferenceType.ts new file mode 100644 index 00000000..f6c6d1ea --- /dev/null +++ b/src/serialization/types/AgentsExpertReferenceType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const AgentsExpertReferenceType: core.serialization.Schema< + serializers.AgentsExpertReferenceType.Raw, + Corti.AgentsExpertReferenceType +> = core.serialization.enum_(["reference"]); + +export declare namespace AgentsExpertReferenceType { + export type Raw = "reference"; +} diff --git a/src/serialization/types/AgentsExpertType.ts b/src/serialization/types/AgentsExpertType.ts new file mode 100644 index 00000000..28daa1b9 --- /dev/null +++ b/src/serialization/types/AgentsExpertType.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const AgentsExpertType: core.serialization.Schema = + core.serialization.enum_(["expert"]); + +export declare namespace AgentsExpertType { + export type Raw = "expert"; +} diff --git a/src/serialization/types/AgentsFilePart.ts b/src/serialization/types/AgentsFilePart.ts index 0f059301..8f4d1cea 100644 --- a/src/serialization/types/AgentsFilePart.ts +++ b/src/serialization/types/AgentsFilePart.ts @@ -1,22 +1,21 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsFilePartFile } from "./AgentsFilePartFile.js"; +import { AgentsFilePartKind } from "./AgentsFilePartKind.js"; export const AgentsFilePart: core.serialization.ObjectSchema = core.serialization.object({ - kind: core.serialization.stringLiteral("file"), + kind: AgentsFilePartKind, file: AgentsFilePartFile.optional(), metadata: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), }); export declare namespace AgentsFilePart { export interface Raw { - kind: "file"; + kind: AgentsFilePartKind.Raw; file?: AgentsFilePartFile.Raw | null; metadata?: Record | null; } diff --git a/src/serialization/types/AgentsFilePartFile.ts b/src/serialization/types/AgentsFilePartFile.ts index 8572ae9b..827a1b4c 100644 --- a/src/serialization/types/AgentsFilePartFile.ts +++ b/src/serialization/types/AgentsFilePartFile.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { AgentsFileWithUri } from "./AgentsFileWithUri.js"; +import type * as serializers from "../index.js"; import { AgentsFileWithBytes } from "./AgentsFileWithBytes.js"; +import { AgentsFileWithUri } from "./AgentsFileWithUri.js"; export const AgentsFilePartFile: core.serialization.Schema< serializers.AgentsFilePartFile.Raw, diff --git a/src/serialization/types/AgentsFilePartKind.ts b/src/serialization/types/AgentsFilePartKind.ts new file mode 100644 index 00000000..77d4cd42 --- /dev/null +++ b/src/serialization/types/AgentsFilePartKind.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const AgentsFilePartKind: core.serialization.Schema< + serializers.AgentsFilePartKind.Raw, + Corti.AgentsFilePartKind +> = core.serialization.enum_(["file"]); + +export declare namespace AgentsFilePartKind { + export type Raw = "file"; +} diff --git a/src/serialization/types/AgentsFileWithBytes.ts b/src/serialization/types/AgentsFileWithBytes.ts index a501a7b7..6bf82871 100644 --- a/src/serialization/types/AgentsFileWithBytes.ts +++ b/src/serialization/types/AgentsFileWithBytes.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsFileWithBytes: core.serialization.ObjectSchema< serializers.AgentsFileWithBytes.Raw, diff --git a/src/serialization/types/AgentsFileWithUri.ts b/src/serialization/types/AgentsFileWithUri.ts index 0e753c49..f6025b3e 100644 --- a/src/serialization/types/AgentsFileWithUri.ts +++ b/src/serialization/types/AgentsFileWithUri.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsFileWithUri: core.serialization.ObjectSchema< serializers.AgentsFileWithUri.Raw, diff --git a/src/serialization/types/AgentsMcpServer.ts b/src/serialization/types/AgentsMcpServer.ts index 7f85a4a4..32d26f86 100644 --- a/src/serialization/types/AgentsMcpServer.ts +++ b/src/serialization/types/AgentsMcpServer.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { AgentsMcpServerTransportType } from "./AgentsMcpServerTransportType.js"; +import type * as serializers from "../index.js"; import { AgentsMcpServerAuthorizationType } from "./AgentsMcpServerAuthorizationType.js"; +import { AgentsMcpServerTransportType } from "./AgentsMcpServerTransportType.js"; export const AgentsMcpServer: core.serialization.ObjectSchema = core.serialization.object({ @@ -27,6 +25,6 @@ export declare namespace AgentsMcpServer { authorizationType: AgentsMcpServerAuthorizationType.Raw; authorizationScope?: string | null; url: string; - redirectUrl?: (string | null) | null; + redirectUrl?: (string | null | undefined) | null; } } diff --git a/src/serialization/types/AgentsMcpServerAuthorizationType.ts b/src/serialization/types/AgentsMcpServerAuthorizationType.ts index 79d29ce9..ea666a01 100644 --- a/src/serialization/types/AgentsMcpServerAuthorizationType.ts +++ b/src/serialization/types/AgentsMcpServerAuthorizationType.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsMcpServerAuthorizationType: core.serialization.Schema< serializers.AgentsMcpServerAuthorizationType.Raw, diff --git a/src/serialization/types/AgentsMcpServerTransportType.ts b/src/serialization/types/AgentsMcpServerTransportType.ts index 679cd63c..1b050cca 100644 --- a/src/serialization/types/AgentsMcpServerTransportType.ts +++ b/src/serialization/types/AgentsMcpServerTransportType.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsMcpServerTransportType: core.serialization.Schema< serializers.AgentsMcpServerTransportType.Raw, diff --git a/src/serialization/types/AgentsMessage.ts b/src/serialization/types/AgentsMessage.ts index 0d94a8db..0f50d4cc 100644 --- a/src/serialization/types/AgentsMessage.ts +++ b/src/serialization/types/AgentsMessage.ts @@ -1,10 +1,9 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { AgentsMessageKind } from "./AgentsMessageKind.js"; import { AgentsMessageRole } from "./AgentsMessageRole.js"; import { AgentsPart } from "./AgentsPart.js"; @@ -18,7 +17,7 @@ export const AgentsMessage: core.serialization.ObjectSchema = + core.serialization.enum_(["message"]); + +export declare namespace AgentsMessageKind { + export type Raw = "message"; +} diff --git a/src/serialization/types/AgentsMessageRole.ts b/src/serialization/types/AgentsMessageRole.ts index 006c605d..4c3115f9 100644 --- a/src/serialization/types/AgentsMessageRole.ts +++ b/src/serialization/types/AgentsMessageRole.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsMessageRole: core.serialization.Schema = core.serialization.enum_(["user", "agent"]); diff --git a/src/serialization/types/AgentsMessageSendConfiguration.ts b/src/serialization/types/AgentsMessageSendConfiguration.ts index b0f2bb16..e3bd0a73 100644 --- a/src/serialization/types/AgentsMessageSendConfiguration.ts +++ b/src/serialization/types/AgentsMessageSendConfiguration.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsPushNotificationConfig } from "./AgentsPushNotificationConfig.js"; export const AgentsMessageSendConfiguration: core.serialization.ObjectSchema< diff --git a/src/serialization/types/AgentsPart.ts b/src/serialization/types/AgentsPart.ts index 5a9f895d..cba88209 100644 --- a/src/serialization/types/AgentsPart.ts +++ b/src/serialization/types/AgentsPart.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { AgentsTextPart } from "./AgentsTextPart.js"; -import { AgentsFilePart } from "./AgentsFilePart.js"; +import type * as serializers from "../index.js"; import { AgentsDataPart } from "./AgentsDataPart.js"; +import { AgentsFilePart } from "./AgentsFilePart.js"; +import { AgentsTextPart } from "./AgentsTextPart.js"; export const AgentsPart: core.serialization.Schema = core.serialization.undiscriminatedUnion([AgentsTextPart, AgentsFilePart, AgentsDataPart]); diff --git a/src/serialization/types/AgentsPushNotificationAuthenticationInfo.ts b/src/serialization/types/AgentsPushNotificationAuthenticationInfo.ts index a055bdbb..eb0b5742 100644 --- a/src/serialization/types/AgentsPushNotificationAuthenticationInfo.ts +++ b/src/serialization/types/AgentsPushNotificationAuthenticationInfo.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsPushNotificationAuthenticationInfo: core.serialization.ObjectSchema< serializers.AgentsPushNotificationAuthenticationInfo.Raw, diff --git a/src/serialization/types/AgentsPushNotificationConfig.ts b/src/serialization/types/AgentsPushNotificationConfig.ts index 61f8f7cf..5c809ea9 100644 --- a/src/serialization/types/AgentsPushNotificationConfig.ts +++ b/src/serialization/types/AgentsPushNotificationConfig.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsPushNotificationAuthenticationInfo } from "./AgentsPushNotificationAuthenticationInfo.js"; export const AgentsPushNotificationConfig: core.serialization.ObjectSchema< diff --git a/src/serialization/types/AgentsRegistryExpert.ts b/src/serialization/types/AgentsRegistryExpert.ts index 872a69c4..5a2a27a6 100644 --- a/src/serialization/types/AgentsRegistryExpert.ts +++ b/src/serialization/types/AgentsRegistryExpert.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsRegistryMcpServer } from "./AgentsRegistryMcpServer.js"; export const AgentsRegistryExpert: core.serialization.ObjectSchema< diff --git a/src/serialization/types/AgentsRegistryExpertsResponse.ts b/src/serialization/types/AgentsRegistryExpertsResponse.ts index a16e89bc..a2654f1f 100644 --- a/src/serialization/types/AgentsRegistryExpertsResponse.ts +++ b/src/serialization/types/AgentsRegistryExpertsResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsRegistryExpert } from "./AgentsRegistryExpert.js"; export const AgentsRegistryExpertsResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/AgentsRegistryMcpServer.ts b/src/serialization/types/AgentsRegistryMcpServer.ts index 7b8db826..7b771629 100644 --- a/src/serialization/types/AgentsRegistryMcpServer.ts +++ b/src/serialization/types/AgentsRegistryMcpServer.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { AgentsRegistryMcpServerAuthorizationType } from "./AgentsRegistryMcpServerAuthorizationType.js"; export const AgentsRegistryMcpServer: core.serialization.ObjectSchema< diff --git a/src/serialization/types/AgentsRegistryMcpServerAuthorizationType.ts b/src/serialization/types/AgentsRegistryMcpServerAuthorizationType.ts index ffcbd24b..29d87c55 100644 --- a/src/serialization/types/AgentsRegistryMcpServerAuthorizationType.ts +++ b/src/serialization/types/AgentsRegistryMcpServerAuthorizationType.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsRegistryMcpServerAuthorizationType: core.serialization.Schema< serializers.AgentsRegistryMcpServerAuthorizationType.Raw, diff --git a/src/serialization/types/AgentsTask.ts b/src/serialization/types/AgentsTask.ts index b89efa0a..7e1fa68d 100644 --- a/src/serialization/types/AgentsTask.ts +++ b/src/serialization/types/AgentsTask.ts @@ -1,13 +1,12 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { AgentsTaskStatus } from "./AgentsTaskStatus.js"; -import { AgentsMessage } from "./AgentsMessage.js"; +import type * as serializers from "../index.js"; import { AgentsArtifact } from "./AgentsArtifact.js"; +import { AgentsMessage } from "./AgentsMessage.js"; +import { AgentsTaskKind } from "./AgentsTaskKind.js"; +import { AgentsTaskStatus } from "./AgentsTaskStatus.js"; export const AgentsTask: core.serialization.ObjectSchema = core.serialization.object({ @@ -17,7 +16,7 @@ export const AgentsTask: core.serialization.ObjectSchema | null; - kind: "task"; + kind: AgentsTaskKind.Raw; } } diff --git a/src/serialization/types/AgentsTaskKind.ts b/src/serialization/types/AgentsTaskKind.ts new file mode 100644 index 00000000..dc91c875 --- /dev/null +++ b/src/serialization/types/AgentsTaskKind.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const AgentsTaskKind: core.serialization.Schema = + core.serialization.enum_(["task"]); + +export declare namespace AgentsTaskKind { + export type Raw = "task"; +} diff --git a/src/serialization/types/AgentsTaskStatus.ts b/src/serialization/types/AgentsTaskStatus.ts index cdcaa6c8..4511659b 100644 --- a/src/serialization/types/AgentsTaskStatus.ts +++ b/src/serialization/types/AgentsTaskStatus.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { AgentsTaskStatusState } from "./AgentsTaskStatusState.js"; +import type * as serializers from "../index.js"; import { AgentsMessage } from "./AgentsMessage.js"; +import { AgentsTaskStatusState } from "./AgentsTaskStatusState.js"; export const AgentsTaskStatus: core.serialization.ObjectSchema< serializers.AgentsTaskStatus.Raw, diff --git a/src/serialization/types/AgentsTaskStatusState.ts b/src/serialization/types/AgentsTaskStatusState.ts index f0224368..24e1e1d4 100644 --- a/src/serialization/types/AgentsTaskStatusState.ts +++ b/src/serialization/types/AgentsTaskStatusState.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const AgentsTaskStatusState: core.serialization.Schema< serializers.AgentsTaskStatusState.Raw, diff --git a/src/serialization/types/AgentsTextPart.ts b/src/serialization/types/AgentsTextPart.ts index 1335d71c..79c24b59 100644 --- a/src/serialization/types/AgentsTextPart.ts +++ b/src/serialization/types/AgentsTextPart.ts @@ -1,21 +1,20 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { AgentsTextPartKind } from "./AgentsTextPartKind.js"; export const AgentsTextPart: core.serialization.ObjectSchema = core.serialization.object({ - kind: core.serialization.stringLiteral("text"), + kind: AgentsTextPartKind, text: core.serialization.string(), metadata: core.serialization.record(core.serialization.string(), core.serialization.unknown()).optional(), }); export declare namespace AgentsTextPart { export interface Raw { - kind: "text"; + kind: AgentsTextPartKind.Raw; text: string; metadata?: Record | null; } diff --git a/src/serialization/types/AgentsTextPartKind.ts b/src/serialization/types/AgentsTextPartKind.ts new file mode 100644 index 00000000..202e1895 --- /dev/null +++ b/src/serialization/types/AgentsTextPartKind.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const AgentsTextPartKind: core.serialization.Schema< + serializers.AgentsTextPartKind.Raw, + Corti.AgentsTextPartKind +> = core.serialization.enum_(["text"]); + +export declare namespace AgentsTextPartKind { + export type Raw = "text"; +} diff --git a/src/serialization/types/CodesGeneralReadResponse.ts b/src/serialization/types/CodesGeneralReadResponse.ts index 059871c5..f87c64b3 100644 --- a/src/serialization/types/CodesGeneralReadResponse.ts +++ b/src/serialization/types/CodesGeneralReadResponse.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { CommonCodingSystemEnum } from "./CommonCodingSystemEnum.js"; +import type * as serializers from "../index.js"; import { CodesGeneralReadResponseEvidencesItem } from "./CodesGeneralReadResponseEvidencesItem.js"; +import { CommonCodingSystemEnum } from "./CommonCodingSystemEnum.js"; export const CodesGeneralReadResponse: core.serialization.ObjectSchema< serializers.CodesGeneralReadResponse.Raw, diff --git a/src/serialization/types/CodesGeneralReadResponseEvidencesItem.ts b/src/serialization/types/CodesGeneralReadResponseEvidencesItem.ts index 851f7285..cff7d330 100644 --- a/src/serialization/types/CodesGeneralReadResponseEvidencesItem.ts +++ b/src/serialization/types/CodesGeneralReadResponseEvidencesItem.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const CodesGeneralReadResponseEvidencesItem: core.serialization.ObjectSchema< serializers.CodesGeneralReadResponseEvidencesItem.Raw, diff --git a/src/serialization/types/CodesGeneralResponse.ts b/src/serialization/types/CodesGeneralResponse.ts index 005719b7..6125550e 100644 --- a/src/serialization/types/CodesGeneralResponse.ts +++ b/src/serialization/types/CodesGeneralResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { CodesGeneralReadResponse } from "./CodesGeneralReadResponse.js"; import { CommonUsageInfo } from "./CommonUsageInfo.js"; diff --git a/src/serialization/types/CommonAiContext.ts b/src/serialization/types/CommonAiContext.ts index 98d3042d..3a57f2cb 100644 --- a/src/serialization/types/CommonAiContext.ts +++ b/src/serialization/types/CommonAiContext.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { CommonTextContext } from "./CommonTextContext.js"; +import type * as serializers from "../index.js"; import { CommonDocumentIdContext } from "./CommonDocumentIdContext.js"; +import { CommonTextContext } from "./CommonTextContext.js"; export const CommonAiContext: core.serialization.Schema = core.serialization.undiscriminatedUnion([CommonTextContext, CommonDocumentIdContext]); diff --git a/src/serialization/types/CommonCodingSystemEnum.ts b/src/serialization/types/CommonCodingSystemEnum.ts index d03e68fa..7b5f1a4c 100644 --- a/src/serialization/types/CommonCodingSystemEnum.ts +++ b/src/serialization/types/CommonCodingSystemEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const CommonCodingSystemEnum: core.serialization.Schema< serializers.CommonCodingSystemEnum.Raw, diff --git a/src/serialization/types/CommonDocumentIdContext.ts b/src/serialization/types/CommonDocumentIdContext.ts index eac9eeed..7e57d498 100644 --- a/src/serialization/types/CommonDocumentIdContext.ts +++ b/src/serialization/types/CommonDocumentIdContext.ts @@ -1,22 +1,21 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { CommonDocumentIdContextType } from "./CommonDocumentIdContextType.js"; export const CommonDocumentIdContext: core.serialization.ObjectSchema< serializers.CommonDocumentIdContext.Raw, Corti.CommonDocumentIdContext > = core.serialization.object({ - type: core.serialization.stringLiteral("documentId"), + type: CommonDocumentIdContextType, documentId: core.serialization.string(), }); export declare namespace CommonDocumentIdContext { export interface Raw { - type: "documentId"; + type: CommonDocumentIdContextType.Raw; documentId: string; } } diff --git a/src/serialization/types/CommonDocumentIdContextType.ts b/src/serialization/types/CommonDocumentIdContextType.ts new file mode 100644 index 00000000..4f3dbe6a --- /dev/null +++ b/src/serialization/types/CommonDocumentIdContextType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const CommonDocumentIdContextType: core.serialization.Schema< + serializers.CommonDocumentIdContextType.Raw, + Corti.CommonDocumentIdContextType +> = core.serialization.enum_(["documentId"]); + +export declare namespace CommonDocumentIdContextType { + export type Raw = "documentId"; +} diff --git a/src/serialization/types/CommonSortingDirectionEnum.ts b/src/serialization/types/CommonSortingDirectionEnum.ts index 8c7ed9d1..fc9e2d34 100644 --- a/src/serialization/types/CommonSortingDirectionEnum.ts +++ b/src/serialization/types/CommonSortingDirectionEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const CommonSortingDirectionEnum: core.serialization.Schema< serializers.CommonSortingDirectionEnum.Raw, diff --git a/src/serialization/types/CommonSourceEnum.ts b/src/serialization/types/CommonSourceEnum.ts index 5243d837..ca6ae27c 100644 --- a/src/serialization/types/CommonSourceEnum.ts +++ b/src/serialization/types/CommonSourceEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const CommonSourceEnum: core.serialization.Schema = core.serialization.enum_(["core", "system", "user"]); diff --git a/src/serialization/types/CommonTextContext.ts b/src/serialization/types/CommonTextContext.ts index 6e731bcc..37e4d2f8 100644 --- a/src/serialization/types/CommonTextContext.ts +++ b/src/serialization/types/CommonTextContext.ts @@ -1,22 +1,21 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { CommonTextContextType } from "./CommonTextContextType.js"; export const CommonTextContext: core.serialization.ObjectSchema< serializers.CommonTextContext.Raw, Corti.CommonTextContext > = core.serialization.object({ - type: core.serialization.stringLiteral("text"), + type: CommonTextContextType, text: core.serialization.string(), }); export declare namespace CommonTextContext { export interface Raw { - type: "text"; + type: CommonTextContextType.Raw; text: string; } } diff --git a/src/serialization/types/CommonTextContextType.ts b/src/serialization/types/CommonTextContextType.ts new file mode 100644 index 00000000..7b045c8d --- /dev/null +++ b/src/serialization/types/CommonTextContextType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const CommonTextContextType: core.serialization.Schema< + serializers.CommonTextContextType.Raw, + Corti.CommonTextContextType +> = core.serialization.enum_(["text"]); + +export declare namespace CommonTextContextType { + export type Raw = "text"; +} diff --git a/src/serialization/types/CommonTranscriptRequest.ts b/src/serialization/types/CommonTranscriptRequest.ts index dceb4b68..8efc4be5 100644 --- a/src/serialization/types/CommonTranscriptRequest.ts +++ b/src/serialization/types/CommonTranscriptRequest.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const CommonTranscriptRequest: core.serialization.ObjectSchema< serializers.CommonTranscriptRequest.Raw, diff --git a/src/serialization/types/CommonTranscriptResponse.ts b/src/serialization/types/CommonTranscriptResponse.ts index c156474b..b47d9b4d 100644 --- a/src/serialization/types/CommonTranscriptResponse.ts +++ b/src/serialization/types/CommonTranscriptResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const CommonTranscriptResponse: core.serialization.ObjectSchema< serializers.CommonTranscriptResponse.Raw, diff --git a/src/serialization/types/CommonUsageInfo.ts b/src/serialization/types/CommonUsageInfo.ts index 0df329b4..d69190b6 100644 --- a/src/serialization/types/CommonUsageInfo.ts +++ b/src/serialization/types/CommonUsageInfo.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const CommonUsageInfo: core.serialization.ObjectSchema = core.serialization.object({ diff --git a/src/serialization/types/DocumentsContext.ts b/src/serialization/types/DocumentsContext.ts index 10f2e75f..1085537b 100644 --- a/src/serialization/types/DocumentsContext.ts +++ b/src/serialization/types/DocumentsContext.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { DocumentsContextWithFacts } from "./DocumentsContextWithFacts.js"; -import { DocumentsContextWithTranscript } from "./DocumentsContextWithTranscript.js"; import { DocumentsContextWithString } from "./DocumentsContextWithString.js"; +import { DocumentsContextWithTranscript } from "./DocumentsContextWithTranscript.js"; export const DocumentsContext: core.serialization.Schema = core.serialization.undiscriminatedUnion([ diff --git a/src/serialization/types/DocumentsContextWithFacts.ts b/src/serialization/types/DocumentsContextWithFacts.ts index 5f7bf473..86476e6a 100644 --- a/src/serialization/types/DocumentsContextWithFacts.ts +++ b/src/serialization/types/DocumentsContextWithFacts.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { DocumentsContextWithFactsType } from "./DocumentsContextWithFactsType.js"; import { FactsContext } from "./FactsContext.js"; export const DocumentsContextWithFacts: core.serialization.ObjectSchema< serializers.DocumentsContextWithFacts.Raw, Corti.DocumentsContextWithFacts > = core.serialization.object({ - type: core.serialization.stringLiteral("facts"), + type: DocumentsContextWithFactsType, data: core.serialization.list(FactsContext), }); export declare namespace DocumentsContextWithFacts { export interface Raw { - type: "facts"; + type: DocumentsContextWithFactsType.Raw; data: FactsContext.Raw[]; } } diff --git a/src/serialization/types/DocumentsContextWithFactsType.ts b/src/serialization/types/DocumentsContextWithFactsType.ts new file mode 100644 index 00000000..3b63cf95 --- /dev/null +++ b/src/serialization/types/DocumentsContextWithFactsType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const DocumentsContextWithFactsType: core.serialization.Schema< + serializers.DocumentsContextWithFactsType.Raw, + Corti.DocumentsContextWithFactsType +> = core.serialization.enum_(["facts"]); + +export declare namespace DocumentsContextWithFactsType { + export type Raw = "facts"; +} diff --git a/src/serialization/types/DocumentsContextWithString.ts b/src/serialization/types/DocumentsContextWithString.ts index 1ab1d4ea..cb700baa 100644 --- a/src/serialization/types/DocumentsContextWithString.ts +++ b/src/serialization/types/DocumentsContextWithString.ts @@ -1,22 +1,21 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { DocumentsContextWithStringType } from "./DocumentsContextWithStringType.js"; export const DocumentsContextWithString: core.serialization.ObjectSchema< serializers.DocumentsContextWithString.Raw, Corti.DocumentsContextWithString > = core.serialization.object({ - type: core.serialization.stringLiteral("string"), + type: DocumentsContextWithStringType, data: core.serialization.string(), }); export declare namespace DocumentsContextWithString { export interface Raw { - type: "string"; + type: DocumentsContextWithStringType.Raw; data: string; } } diff --git a/src/serialization/types/DocumentsContextWithStringType.ts b/src/serialization/types/DocumentsContextWithStringType.ts new file mode 100644 index 00000000..aefb35ab --- /dev/null +++ b/src/serialization/types/DocumentsContextWithStringType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const DocumentsContextWithStringType: core.serialization.Schema< + serializers.DocumentsContextWithStringType.Raw, + Corti.DocumentsContextWithStringType +> = core.serialization.enum_(["string"]); + +export declare namespace DocumentsContextWithStringType { + export type Raw = "string"; +} diff --git a/src/serialization/types/DocumentsContextWithTranscript.ts b/src/serialization/types/DocumentsContextWithTranscript.ts index eb23238b..732bd5fb 100644 --- a/src/serialization/types/DocumentsContextWithTranscript.ts +++ b/src/serialization/types/DocumentsContextWithTranscript.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { CommonTranscriptRequest } from "./CommonTranscriptRequest.js"; +import { DocumentsContextWithTranscriptType } from "./DocumentsContextWithTranscriptType.js"; export const DocumentsContextWithTranscript: core.serialization.ObjectSchema< serializers.DocumentsContextWithTranscript.Raw, Corti.DocumentsContextWithTranscript > = core.serialization.object({ - type: core.serialization.stringLiteral("transcript"), + type: DocumentsContextWithTranscriptType, data: CommonTranscriptRequest, }); export declare namespace DocumentsContextWithTranscript { export interface Raw { - type: "transcript"; + type: DocumentsContextWithTranscriptType.Raw; data: CommonTranscriptRequest.Raw; } } diff --git a/src/serialization/types/DocumentsContextWithTranscriptType.ts b/src/serialization/types/DocumentsContextWithTranscriptType.ts new file mode 100644 index 00000000..207b5693 --- /dev/null +++ b/src/serialization/types/DocumentsContextWithTranscriptType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const DocumentsContextWithTranscriptType: core.serialization.Schema< + serializers.DocumentsContextWithTranscriptType.Raw, + Corti.DocumentsContextWithTranscriptType +> = core.serialization.enum_(["transcript"]); + +export declare namespace DocumentsContextWithTranscriptType { + export type Raw = "transcript"; +} diff --git a/src/serialization/types/DocumentsCreateRequest.ts b/src/serialization/types/DocumentsCreateRequestBody.ts similarity index 56% rename from src/serialization/types/DocumentsCreateRequest.ts rename to src/serialization/types/DocumentsCreateRequestBody.ts index 06aeec2d..ae756818 100644 --- a/src/serialization/types/DocumentsCreateRequest.ts +++ b/src/serialization/types/DocumentsCreateRequestBody.ts @@ -1,21 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { DocumentsCreateRequestWithTemplateKey } from "./DocumentsCreateRequestWithTemplateKey.js"; +import type * as serializers from "../index.js"; import { DocumentsCreateRequestWithTemplate } from "./DocumentsCreateRequestWithTemplate.js"; +import { DocumentsCreateRequestWithTemplateKey } from "./DocumentsCreateRequestWithTemplateKey.js"; -export const DocumentsCreateRequest: core.serialization.Schema< - serializers.DocumentsCreateRequest.Raw, - Corti.DocumentsCreateRequest +export const DocumentsCreateRequestBody: core.serialization.Schema< + serializers.DocumentsCreateRequestBody.Raw, + Corti.DocumentsCreateRequestBody > = core.serialization.undiscriminatedUnion([ DocumentsCreateRequestWithTemplateKey, DocumentsCreateRequestWithTemplate, ]); -export declare namespace DocumentsCreateRequest { +export declare namespace DocumentsCreateRequestBody { export type Raw = DocumentsCreateRequestWithTemplateKey.Raw | DocumentsCreateRequestWithTemplate.Raw; } diff --git a/src/serialization/types/DocumentsCreateRequestWithTemplate.ts b/src/serialization/types/DocumentsCreateRequestWithTemplate.ts index 9de28248..9b17b98c 100644 --- a/src/serialization/types/DocumentsCreateRequestWithTemplate.ts +++ b/src/serialization/types/DocumentsCreateRequestWithTemplate.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { DocumentsContext } from "./DocumentsContext.js"; import { DocumentsTemplate } from "./DocumentsTemplate.js"; import { TemplatesDocumentationModeEnum } from "./TemplatesDocumentationModeEnum.js"; diff --git a/src/serialization/types/DocumentsCreateRequestWithTemplateKey.ts b/src/serialization/types/DocumentsCreateRequestWithTemplateKey.ts index 38b27598..b4cc6ea4 100644 --- a/src/serialization/types/DocumentsCreateRequestWithTemplateKey.ts +++ b/src/serialization/types/DocumentsCreateRequestWithTemplateKey.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { DocumentsContext } from "./DocumentsContext.js"; import { TemplatesDocumentationModeEnum } from "./TemplatesDocumentationModeEnum.js"; diff --git a/src/serialization/types/DocumentsGetResponse.ts b/src/serialization/types/DocumentsGetResponse.ts index 695d568e..2eebf07a 100644 --- a/src/serialization/types/DocumentsGetResponse.ts +++ b/src/serialization/types/DocumentsGetResponse.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { Uuid } from "./Uuid.js"; -import { DocumentsSection } from "./DocumentsSection.js"; +import type * as serializers from "../index.js"; import { CommonUsageInfo } from "./CommonUsageInfo.js"; +import { DocumentsSection } from "./DocumentsSection.js"; +import { Uuid } from "./Uuid.js"; export const DocumentsGetResponse: core.serialization.ObjectSchema< serializers.DocumentsGetResponse.Raw, diff --git a/src/serialization/types/DocumentsListResponse.ts b/src/serialization/types/DocumentsListResponse.ts index f8c53aec..d4966afc 100644 --- a/src/serialization/types/DocumentsListResponse.ts +++ b/src/serialization/types/DocumentsListResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { DocumentsGetResponse } from "./DocumentsGetResponse.js"; export const DocumentsListResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/DocumentsSection.ts b/src/serialization/types/DocumentsSection.ts index 08235ad0..b2803f8b 100644 --- a/src/serialization/types/DocumentsSection.ts +++ b/src/serialization/types/DocumentsSection.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const DocumentsSection: core.serialization.ObjectSchema< serializers.DocumentsSection.Raw, diff --git a/src/serialization/types/DocumentsSectionInput.ts b/src/serialization/types/DocumentsSectionInput.ts index 688508d5..0e454878 100644 --- a/src/serialization/types/DocumentsSectionInput.ts +++ b/src/serialization/types/DocumentsSectionInput.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const DocumentsSectionInput: core.serialization.ObjectSchema< serializers.DocumentsSectionInput.Raw, diff --git a/src/serialization/types/DocumentsSectionOverride.ts b/src/serialization/types/DocumentsSectionOverride.ts index 54f079ff..2a78560e 100644 --- a/src/serialization/types/DocumentsSectionOverride.ts +++ b/src/serialization/types/DocumentsSectionOverride.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const DocumentsSectionOverride: core.serialization.ObjectSchema< serializers.DocumentsSectionOverride.Raw, diff --git a/src/serialization/types/DocumentsTemplate.ts b/src/serialization/types/DocumentsTemplate.ts index ebd6c6ab..faf1ccb3 100644 --- a/src/serialization/types/DocumentsTemplate.ts +++ b/src/serialization/types/DocumentsTemplate.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { DocumentsTemplateWithSections } from "./DocumentsTemplateWithSections.js"; +import type * as serializers from "../index.js"; import { DocumentsTemplateWithSectionKeys } from "./DocumentsTemplateWithSectionKeys.js"; +import { DocumentsTemplateWithSections } from "./DocumentsTemplateWithSections.js"; export const DocumentsTemplate: core.serialization.Schema = core.serialization.undiscriminatedUnion([DocumentsTemplateWithSections, DocumentsTemplateWithSectionKeys]); diff --git a/src/serialization/types/DocumentsTemplateWithSectionKeys.ts b/src/serialization/types/DocumentsTemplateWithSectionKeys.ts index baf98322..4b5d13d5 100644 --- a/src/serialization/types/DocumentsTemplateWithSectionKeys.ts +++ b/src/serialization/types/DocumentsTemplateWithSectionKeys.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const DocumentsTemplateWithSectionKeys: core.serialization.ObjectSchema< serializers.DocumentsTemplateWithSectionKeys.Raw, diff --git a/src/serialization/types/DocumentsTemplateWithSections.ts b/src/serialization/types/DocumentsTemplateWithSections.ts index 48fe22b3..0d379f6e 100644 --- a/src/serialization/types/DocumentsTemplateWithSections.ts +++ b/src/serialization/types/DocumentsTemplateWithSections.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { DocumentsSectionOverride } from "./DocumentsSectionOverride.js"; export const DocumentsTemplateWithSections: core.serialization.ObjectSchema< diff --git a/src/serialization/types/ErrorResponse.ts b/src/serialization/types/ErrorResponse.ts index 4851d538..42f4eb72 100644 --- a/src/serialization/types/ErrorResponse.ts +++ b/src/serialization/types/ErrorResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const ErrorResponse: core.serialization.ObjectSchema = core.serialization.object({ diff --git a/src/serialization/types/FactsBatchUpdateInput.ts b/src/serialization/types/FactsBatchUpdateInput.ts index fc30a5fc..b984db6f 100644 --- a/src/serialization/types/FactsBatchUpdateInput.ts +++ b/src/serialization/types/FactsBatchUpdateInput.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const FactsBatchUpdateInput: core.serialization.ObjectSchema< serializers.FactsBatchUpdateInput.Raw, diff --git a/src/serialization/types/FactsBatchUpdateItem.ts b/src/serialization/types/FactsBatchUpdateItem.ts index bd339a35..493abfbb 100644 --- a/src/serialization/types/FactsBatchUpdateItem.ts +++ b/src/serialization/types/FactsBatchUpdateItem.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { Uuid } from "./Uuid.js"; +import type * as serializers from "../index.js"; import { CommonSourceEnum } from "./CommonSourceEnum.js"; +import { Uuid } from "./Uuid.js"; export const FactsBatchUpdateItem: core.serialization.ObjectSchema< serializers.FactsBatchUpdateItem.Raw, diff --git a/src/serialization/types/FactsBatchUpdateResponse.ts b/src/serialization/types/FactsBatchUpdateResponse.ts index be2370d6..4d0f4cab 100644 --- a/src/serialization/types/FactsBatchUpdateResponse.ts +++ b/src/serialization/types/FactsBatchUpdateResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { FactsBatchUpdateItem } from "./FactsBatchUpdateItem.js"; export const FactsBatchUpdateResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/FactsContext.ts b/src/serialization/types/FactsContext.ts index a00966ba..f22cd996 100644 --- a/src/serialization/types/FactsContext.ts +++ b/src/serialization/types/FactsContext.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { CommonSourceEnum } from "./CommonSourceEnum.js"; export const FactsContext: core.serialization.ObjectSchema = diff --git a/src/serialization/types/FactsCreateInput.ts b/src/serialization/types/FactsCreateInput.ts index 1a4a1713..7e31b51b 100644 --- a/src/serialization/types/FactsCreateInput.ts +++ b/src/serialization/types/FactsCreateInput.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { CommonSourceEnum } from "./CommonSourceEnum.js"; export const FactsCreateInput: core.serialization.ObjectSchema< diff --git a/src/serialization/types/FactsCreateItem.ts b/src/serialization/types/FactsCreateItem.ts index a9c750c2..9ae5e667 100644 --- a/src/serialization/types/FactsCreateItem.ts +++ b/src/serialization/types/FactsCreateItem.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { Uuid } from "./Uuid.js"; +import type * as serializers from "../index.js"; import { CommonSourceEnum } from "./CommonSourceEnum.js"; +import { Uuid } from "./Uuid.js"; export const FactsCreateItem: core.serialization.ObjectSchema = core.serialization.object({ diff --git a/src/serialization/types/FactsCreateResponse.ts b/src/serialization/types/FactsCreateResponse.ts index a38c26bf..311f4375 100644 --- a/src/serialization/types/FactsCreateResponse.ts +++ b/src/serialization/types/FactsCreateResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { FactsCreateItem } from "./FactsCreateItem.js"; export const FactsCreateResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/FactsEvidence.ts b/src/serialization/types/FactsEvidence.ts index bfba9204..c1592bfe 100644 --- a/src/serialization/types/FactsEvidence.ts +++ b/src/serialization/types/FactsEvidence.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const FactsEvidence: core.serialization.ObjectSchema = core.serialization.object({ diff --git a/src/serialization/types/FactsExtractResponse.ts b/src/serialization/types/FactsExtractResponse.ts index b0eb6891..f66008f2 100644 --- a/src/serialization/types/FactsExtractResponse.ts +++ b/src/serialization/types/FactsExtractResponse.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { FactsExtractResponseFactsItem } from "./FactsExtractResponseFactsItem.js"; +import type * as serializers from "../index.js"; import { CommonUsageInfo } from "./CommonUsageInfo.js"; +import { FactsExtractResponseFactsItem } from "./FactsExtractResponseFactsItem.js"; export const FactsExtractResponse: core.serialization.ObjectSchema< serializers.FactsExtractResponse.Raw, diff --git a/src/serialization/types/FactsExtractResponseFactsItem.ts b/src/serialization/types/FactsExtractResponseFactsItem.ts index d4c1077c..5dc87d54 100644 --- a/src/serialization/types/FactsExtractResponseFactsItem.ts +++ b/src/serialization/types/FactsExtractResponseFactsItem.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const FactsExtractResponseFactsItem: core.serialization.ObjectSchema< serializers.FactsExtractResponseFactsItem.Raw, diff --git a/src/serialization/types/FactsFactGroupsItem.ts b/src/serialization/types/FactsFactGroupsItem.ts index 363c8675..9fe17a8d 100644 --- a/src/serialization/types/FactsFactGroupsItem.ts +++ b/src/serialization/types/FactsFactGroupsItem.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { Uuid } from "./Uuid.js"; +import type * as serializers from "../index.js"; import { FactsFactGroupsItemTranslationsItem } from "./FactsFactGroupsItemTranslationsItem.js"; +import { Uuid } from "./Uuid.js"; export const FactsFactGroupsItem: core.serialization.ObjectSchema< serializers.FactsFactGroupsItem.Raw, diff --git a/src/serialization/types/FactsFactGroupsItemTranslationsItem.ts b/src/serialization/types/FactsFactGroupsItemTranslationsItem.ts index 0e0b08b2..de72bef8 100644 --- a/src/serialization/types/FactsFactGroupsItemTranslationsItem.ts +++ b/src/serialization/types/FactsFactGroupsItemTranslationsItem.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const FactsFactGroupsItemTranslationsItem: core.serialization.ObjectSchema< serializers.FactsFactGroupsItemTranslationsItem.Raw, diff --git a/src/serialization/types/FactsFactGroupsListResponse.ts b/src/serialization/types/FactsFactGroupsListResponse.ts index b5804e8a..74947df8 100644 --- a/src/serialization/types/FactsFactGroupsListResponse.ts +++ b/src/serialization/types/FactsFactGroupsListResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { FactsFactGroupsItem } from "./FactsFactGroupsItem.js"; export const FactsFactGroupsListResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/FactsListItem.ts b/src/serialization/types/FactsListItem.ts index 42483cd8..33c9ea65 100644 --- a/src/serialization/types/FactsListItem.ts +++ b/src/serialization/types/FactsListItem.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { Uuid } from "./Uuid.js"; +import type * as serializers from "../index.js"; import { CommonSourceEnum } from "./CommonSourceEnum.js"; import { FactsEvidence } from "./FactsEvidence.js"; +import { Uuid } from "./Uuid.js"; export const FactsListItem: core.serialization.ObjectSchema = core.serialization.object({ diff --git a/src/serialization/types/FactsListResponse.ts b/src/serialization/types/FactsListResponse.ts index 91c19ee1..7c84d431 100644 --- a/src/serialization/types/FactsListResponse.ts +++ b/src/serialization/types/FactsListResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { FactsListItem } from "./FactsListItem.js"; export const FactsListResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/FactsUpdateResponse.ts b/src/serialization/types/FactsUpdateResponse.ts index 51ab9597..e3916568 100644 --- a/src/serialization/types/FactsUpdateResponse.ts +++ b/src/serialization/types/FactsUpdateResponse.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { Uuid } from "./Uuid.js"; +import type * as serializers from "../index.js"; import { CommonSourceEnum } from "./CommonSourceEnum.js"; +import { Uuid } from "./Uuid.js"; export const FactsUpdateResponse: core.serialization.ObjectSchema< serializers.FactsUpdateResponse.Raw, diff --git a/src/serialization/types/InteractionsCreateResponse.ts b/src/serialization/types/InteractionsCreateResponse.ts index cdf5c222..08ab99a4 100644 --- a/src/serialization/types/InteractionsCreateResponse.ts +++ b/src/serialization/types/InteractionsCreateResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { Uuid } from "./Uuid.js"; export const InteractionsCreateResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/InteractionsEncounterCreateRequest.ts b/src/serialization/types/InteractionsEncounterCreateRequest.ts index 776e612f..a744e275 100644 --- a/src/serialization/types/InteractionsEncounterCreateRequest.ts +++ b/src/serialization/types/InteractionsEncounterCreateRequest.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { InteractionsEncounterPeriod } from "./InteractionsEncounterPeriod.js"; import { InteractionsEncounterStatusEnum } from "./InteractionsEncounterStatusEnum.js"; import { InteractionsEncounterTypeEnum } from "./InteractionsEncounterTypeEnum.js"; -import { InteractionsEncounterPeriod } from "./InteractionsEncounterPeriod.js"; export const InteractionsEncounterCreateRequest: core.serialization.ObjectSchema< serializers.InteractionsEncounterCreateRequest.Raw, @@ -26,6 +24,6 @@ export declare namespace InteractionsEncounterCreateRequest { status: InteractionsEncounterStatusEnum.Raw; type: InteractionsEncounterTypeEnum.Raw; period?: InteractionsEncounterPeriod.Raw | null; - title?: (string | null) | null; + title?: (string | null | undefined) | null; } } diff --git a/src/serialization/types/InteractionsEncounterPeriod.ts b/src/serialization/types/InteractionsEncounterPeriod.ts index 494e4eb6..1942e1cd 100644 --- a/src/serialization/types/InteractionsEncounterPeriod.ts +++ b/src/serialization/types/InteractionsEncounterPeriod.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const InteractionsEncounterPeriod: core.serialization.ObjectSchema< serializers.InteractionsEncounterPeriod.Raw, @@ -17,6 +15,6 @@ export const InteractionsEncounterPeriod: core.serialization.ObjectSchema< export declare namespace InteractionsEncounterPeriod { export interface Raw { startedAt: string; - endedAt?: (string | null) | null; + endedAt?: (string | null | undefined) | null; } } diff --git a/src/serialization/types/InteractionsEncounterResponse.ts b/src/serialization/types/InteractionsEncounterResponse.ts index 9aba1e9c..682d9816 100644 --- a/src/serialization/types/InteractionsEncounterResponse.ts +++ b/src/serialization/types/InteractionsEncounterResponse.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { InteractionsEncounterPeriod } from "./InteractionsEncounterPeriod.js"; import { InteractionsEncounterStatusEnum } from "./InteractionsEncounterStatusEnum.js"; import { InteractionsEncounterTypeEnum } from "./InteractionsEncounterTypeEnum.js"; -import { InteractionsEncounterPeriod } from "./InteractionsEncounterPeriod.js"; export const InteractionsEncounterResponse: core.serialization.ObjectSchema< serializers.InteractionsEncounterResponse.Raw, @@ -26,6 +24,6 @@ export declare namespace InteractionsEncounterResponse { status: InteractionsEncounterStatusEnum.Raw; type: InteractionsEncounterTypeEnum.Raw; period: InteractionsEncounterPeriod.Raw; - title?: (string | null) | null; + title?: (string | null | undefined) | null; } } diff --git a/src/serialization/types/InteractionsEncounterStatusEnum.ts b/src/serialization/types/InteractionsEncounterStatusEnum.ts index b2be6623..2ea507af 100644 --- a/src/serialization/types/InteractionsEncounterStatusEnum.ts +++ b/src/serialization/types/InteractionsEncounterStatusEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const InteractionsEncounterStatusEnum: core.serialization.Schema< serializers.InteractionsEncounterStatusEnum.Raw, diff --git a/src/serialization/types/InteractionsEncounterTypeEnum.ts b/src/serialization/types/InteractionsEncounterTypeEnum.ts index a537bf32..8abed470 100644 --- a/src/serialization/types/InteractionsEncounterTypeEnum.ts +++ b/src/serialization/types/InteractionsEncounterTypeEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const InteractionsEncounterTypeEnum: core.serialization.Schema< serializers.InteractionsEncounterTypeEnum.Raw, diff --git a/src/serialization/types/InteractionsEncounterUpdateRequest.ts b/src/serialization/types/InteractionsEncounterUpdateRequest.ts index 41758c7b..01102315 100644 --- a/src/serialization/types/InteractionsEncounterUpdateRequest.ts +++ b/src/serialization/types/InteractionsEncounterUpdateRequest.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { InteractionsEncounterPeriod } from "./InteractionsEncounterPeriod.js"; import { InteractionsEncounterStatusEnum } from "./InteractionsEncounterStatusEnum.js"; import { InteractionsEncounterTypeEnum } from "./InteractionsEncounterTypeEnum.js"; -import { InteractionsEncounterPeriod } from "./InteractionsEncounterPeriod.js"; export const InteractionsEncounterUpdateRequest: core.serialization.ObjectSchema< serializers.InteractionsEncounterUpdateRequest.Raw, @@ -26,6 +24,6 @@ export declare namespace InteractionsEncounterUpdateRequest { status?: InteractionsEncounterStatusEnum.Raw | null; type?: InteractionsEncounterTypeEnum.Raw | null; period?: InteractionsEncounterPeriod.Raw | null; - title?: (string | null) | null; + title?: (string | null | undefined) | null; } } diff --git a/src/serialization/types/InteractionsGenderEnum.ts b/src/serialization/types/InteractionsGenderEnum.ts index e3b28064..e3cae371 100644 --- a/src/serialization/types/InteractionsGenderEnum.ts +++ b/src/serialization/types/InteractionsGenderEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const InteractionsGenderEnum: core.serialization.Schema< serializers.InteractionsGenderEnum.Raw, diff --git a/src/serialization/types/InteractionsGetResponse.ts b/src/serialization/types/InteractionsGetResponse.ts index ab6d5898..e7b0a2c0 100644 --- a/src/serialization/types/InteractionsGetResponse.ts +++ b/src/serialization/types/InteractionsGetResponse.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { Uuid } from "./Uuid.js"; +import type * as serializers from "../index.js"; import { InteractionsEncounterResponse } from "./InteractionsEncounterResponse.js"; import { InteractionsPatient } from "./InteractionsPatient.js"; +import { Uuid } from "./Uuid.js"; export const InteractionsGetResponse: core.serialization.ObjectSchema< serializers.InteractionsGetResponse.Raw, @@ -30,7 +28,7 @@ export declare namespace InteractionsGetResponse { assignedUserId: Uuid.Raw; encounter: InteractionsEncounterResponse.Raw; patient: InteractionsPatient.Raw; - endedAt?: (string | null) | null; + endedAt?: (string | null | undefined) | null; createdAt: string; updatedAt: string; websocketUrl: string; diff --git a/src/serialization/types/InteractionsListResponse.ts b/src/serialization/types/InteractionsListResponse.ts index b9e2a35d..8d3b6950 100644 --- a/src/serialization/types/InteractionsListResponse.ts +++ b/src/serialization/types/InteractionsListResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { InteractionsGetResponse } from "./InteractionsGetResponse.js"; export const InteractionsListResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/InteractionsPatient.ts b/src/serialization/types/InteractionsPatient.ts index 0cb14248..7ab9980b 100644 --- a/src/serialization/types/InteractionsPatient.ts +++ b/src/serialization/types/InteractionsPatient.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { InteractionsGenderEnum } from "./InteractionsGenderEnum.js"; export const InteractionsPatient: core.serialization.ObjectSchema< @@ -21,9 +19,9 @@ export const InteractionsPatient: core.serialization.ObjectSchema< export declare namespace InteractionsPatient { export interface Raw { identifier: string; - name?: (string | null) | null; + name?: (string | null | undefined) | null; gender?: InteractionsGenderEnum.Raw | null; - birthDate?: (string | null) | null; - pronouns?: (string | null) | null; + birthDate?: (string | null | undefined) | null; + pronouns?: (string | null | undefined) | null; } } diff --git a/src/serialization/types/RecordingsCreateResponse.ts b/src/serialization/types/RecordingsCreateResponse.ts index 343bd795..0cf50b8c 100644 --- a/src/serialization/types/RecordingsCreateResponse.ts +++ b/src/serialization/types/RecordingsCreateResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { Uuid } from "./Uuid.js"; export const RecordingsCreateResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/RecordingsListResponse.ts b/src/serialization/types/RecordingsListResponse.ts index 3f546662..ab134cf6 100644 --- a/src/serialization/types/RecordingsListResponse.ts +++ b/src/serialization/types/RecordingsListResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { Uuid } from "./Uuid.js"; export const RecordingsListResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/StreamConfig.ts b/src/serialization/types/StreamConfig.ts index ccb98f40..a39b6664 100644 --- a/src/serialization/types/StreamConfig.ts +++ b/src/serialization/types/StreamConfig.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { StreamConfigTranscription } from "./StreamConfigTranscription.js"; +import type * as serializers from "../index.js"; import { StreamConfigMode } from "./StreamConfigMode.js"; +import { StreamConfigTranscription } from "./StreamConfigTranscription.js"; export const StreamConfig: core.serialization.ObjectSchema = core.serialization.object({ diff --git a/src/serialization/types/StreamConfigMessage.ts b/src/serialization/types/StreamConfigMessage.ts index ed35d913..c3c893f5 100644 --- a/src/serialization/types/StreamConfigMessage.ts +++ b/src/serialization/types/StreamConfigMessage.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { StreamConfig } from "./StreamConfig.js"; +import { StreamConfigMessageType } from "./StreamConfigMessageType.js"; export const StreamConfigMessage: core.serialization.ObjectSchema< serializers.StreamConfigMessage.Raw, Corti.StreamConfigMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("config"), + type: StreamConfigMessageType, configuration: StreamConfig, }); export declare namespace StreamConfigMessage { export interface Raw { - type: "config"; + type: StreamConfigMessageType.Raw; configuration: StreamConfig.Raw; } } diff --git a/src/serialization/types/StreamConfigMessageType.ts b/src/serialization/types/StreamConfigMessageType.ts new file mode 100644 index 00000000..372f8ae9 --- /dev/null +++ b/src/serialization/types/StreamConfigMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const StreamConfigMessageType: core.serialization.Schema< + serializers.StreamConfigMessageType.Raw, + Corti.StreamConfigMessageType +> = core.serialization.enum_(["config"]); + +export declare namespace StreamConfigMessageType { + export type Raw = "config"; +} diff --git a/src/serialization/types/StreamConfigMode.ts b/src/serialization/types/StreamConfigMode.ts index 0fb88bad..fe7b58d4 100644 --- a/src/serialization/types/StreamConfigMode.ts +++ b/src/serialization/types/StreamConfigMode.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { StreamConfigModeType } from "./StreamConfigModeType.js"; import { StreamSupportedLanguage } from "./StreamSupportedLanguage.js"; diff --git a/src/serialization/types/StreamConfigModeType.ts b/src/serialization/types/StreamConfigModeType.ts index 4d12ce85..7c004047 100644 --- a/src/serialization/types/StreamConfigModeType.ts +++ b/src/serialization/types/StreamConfigModeType.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const StreamConfigModeType: core.serialization.Schema< serializers.StreamConfigModeType.Raw, diff --git a/src/serialization/types/StreamConfigParticipant.ts b/src/serialization/types/StreamConfigParticipant.ts index 4c7aaafd..eb384c47 100644 --- a/src/serialization/types/StreamConfigParticipant.ts +++ b/src/serialization/types/StreamConfigParticipant.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { StreamConfigParticipantRole } from "./StreamConfigParticipantRole.js"; export const StreamConfigParticipant: core.serialization.ObjectSchema< diff --git a/src/serialization/types/StreamConfigParticipantRole.ts b/src/serialization/types/StreamConfigParticipantRole.ts index 19948650..5ba09d2d 100644 --- a/src/serialization/types/StreamConfigParticipantRole.ts +++ b/src/serialization/types/StreamConfigParticipantRole.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const StreamConfigParticipantRole: core.serialization.Schema< serializers.StreamConfigParticipantRole.Raw, diff --git a/src/serialization/types/StreamConfigStatusMessage.ts b/src/serialization/types/StreamConfigStatusMessage.ts index dcad2498..cf1b8e11 100644 --- a/src/serialization/types/StreamConfigStatusMessage.ts +++ b/src/serialization/types/StreamConfigStatusMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { StreamConfigStatusMessageType } from "./StreamConfigStatusMessageType.js"; export const StreamConfigStatusMessage: core.serialization.ObjectSchema< diff --git a/src/serialization/types/StreamConfigStatusMessageType.ts b/src/serialization/types/StreamConfigStatusMessageType.ts index 014af96d..3c9b378b 100644 --- a/src/serialization/types/StreamConfigStatusMessageType.ts +++ b/src/serialization/types/StreamConfigStatusMessageType.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const StreamConfigStatusMessageType: core.serialization.Schema< serializers.StreamConfigStatusMessageType.Raw, diff --git a/src/serialization/types/StreamConfigTranscription.ts b/src/serialization/types/StreamConfigTranscription.ts index d4f7c36d..a07bf536 100644 --- a/src/serialization/types/StreamConfigTranscription.ts +++ b/src/serialization/types/StreamConfigTranscription.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { StreamSupportedLanguage } from "./StreamSupportedLanguage.js"; +import type * as serializers from "../index.js"; import { StreamConfigParticipant } from "./StreamConfigParticipant.js"; +import { StreamSupportedLanguage } from "./StreamSupportedLanguage.js"; export const StreamConfigTranscription: core.serialization.ObjectSchema< serializers.StreamConfigTranscription.Raw, diff --git a/src/serialization/types/StreamEndMessage.ts b/src/serialization/types/StreamEndMessage.ts index 981f8a61..9757ba3c 100644 --- a/src/serialization/types/StreamEndMessage.ts +++ b/src/serialization/types/StreamEndMessage.ts @@ -1,20 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { StreamEndMessageType } from "./StreamEndMessageType.js"; export const StreamEndMessage: core.serialization.ObjectSchema< serializers.StreamEndMessage.Raw, Corti.StreamEndMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("end"), + type: StreamEndMessageType, }); export declare namespace StreamEndMessage { export interface Raw { - type: "end"; + type: StreamEndMessageType.Raw; } } diff --git a/src/serialization/types/StreamEndMessageType.ts b/src/serialization/types/StreamEndMessageType.ts new file mode 100644 index 00000000..3e6eb2fe --- /dev/null +++ b/src/serialization/types/StreamEndMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const StreamEndMessageType: core.serialization.Schema< + serializers.StreamEndMessageType.Raw, + Corti.StreamEndMessageType +> = core.serialization.enum_(["end"]); + +export declare namespace StreamEndMessageType { + export type Raw = "end"; +} diff --git a/src/serialization/types/StreamEndedMessage.ts b/src/serialization/types/StreamEndedMessage.ts index 2ff74444..bede8b6c 100644 --- a/src/serialization/types/StreamEndedMessage.ts +++ b/src/serialization/types/StreamEndedMessage.ts @@ -1,20 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { StreamEndedMessageType } from "./StreamEndedMessageType.js"; export const StreamEndedMessage: core.serialization.ObjectSchema< serializers.StreamEndedMessage.Raw, Corti.StreamEndedMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("ENDED"), + type: StreamEndedMessageType, }); export declare namespace StreamEndedMessage { export interface Raw { - type: "ENDED"; + type: StreamEndedMessageType.Raw; } } diff --git a/src/serialization/types/StreamEndedMessageType.ts b/src/serialization/types/StreamEndedMessageType.ts new file mode 100644 index 00000000..d3066c2f --- /dev/null +++ b/src/serialization/types/StreamEndedMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const StreamEndedMessageType: core.serialization.Schema< + serializers.StreamEndedMessageType.Raw, + Corti.StreamEndedMessageType +> = core.serialization.enum_(["ENDED"]); + +export declare namespace StreamEndedMessageType { + export type Raw = "ENDED"; +} diff --git a/src/serialization/types/StreamErrorDetail.ts b/src/serialization/types/StreamErrorDetail.ts index eaaa0c1e..153dca11 100644 --- a/src/serialization/types/StreamErrorDetail.ts +++ b/src/serialization/types/StreamErrorDetail.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const StreamErrorDetail: core.serialization.ObjectSchema< serializers.StreamErrorDetail.Raw, diff --git a/src/serialization/types/StreamErrorMessage.ts b/src/serialization/types/StreamErrorMessage.ts index e182559c..832edbcb 100644 --- a/src/serialization/types/StreamErrorMessage.ts +++ b/src/serialization/types/StreamErrorMessage.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { StreamErrorDetail } from "./StreamErrorDetail.js"; +import { StreamErrorMessageType } from "./StreamErrorMessageType.js"; export const StreamErrorMessage: core.serialization.ObjectSchema< serializers.StreamErrorMessage.Raw, Corti.StreamErrorMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("error"), + type: StreamErrorMessageType, error: StreamErrorDetail, }); export declare namespace StreamErrorMessage { export interface Raw { - type: "error"; + type: StreamErrorMessageType.Raw; error: StreamErrorDetail.Raw; } } diff --git a/src/serialization/types/StreamErrorMessageType.ts b/src/serialization/types/StreamErrorMessageType.ts new file mode 100644 index 00000000..407a4d58 --- /dev/null +++ b/src/serialization/types/StreamErrorMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const StreamErrorMessageType: core.serialization.Schema< + serializers.StreamErrorMessageType.Raw, + Corti.StreamErrorMessageType +> = core.serialization.enum_(["error"]); + +export declare namespace StreamErrorMessageType { + export type Raw = "error"; +} diff --git a/src/serialization/types/StreamFact.ts b/src/serialization/types/StreamFact.ts index ab456de0..7f67465f 100644 --- a/src/serialization/types/StreamFact.ts +++ b/src/serialization/types/StreamFact.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const StreamFact: core.serialization.ObjectSchema = core.serialization.object({ diff --git a/src/serialization/types/StreamFactsMessage.ts b/src/serialization/types/StreamFactsMessage.ts index 8ca75483..5eb31f46 100644 --- a/src/serialization/types/StreamFactsMessage.ts +++ b/src/serialization/types/StreamFactsMessage.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { StreamFact } from "./StreamFact.js"; +import { StreamFactsMessageType } from "./StreamFactsMessageType.js"; export const StreamFactsMessage: core.serialization.ObjectSchema< serializers.StreamFactsMessage.Raw, Corti.StreamFactsMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("facts"), + type: StreamFactsMessageType, fact: core.serialization.list(StreamFact), }); export declare namespace StreamFactsMessage { export interface Raw { - type: "facts"; + type: StreamFactsMessageType.Raw; fact: StreamFact.Raw[]; } } diff --git a/src/serialization/types/StreamFactsMessageType.ts b/src/serialization/types/StreamFactsMessageType.ts new file mode 100644 index 00000000..20252269 --- /dev/null +++ b/src/serialization/types/StreamFactsMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const StreamFactsMessageType: core.serialization.Schema< + serializers.StreamFactsMessageType.Raw, + Corti.StreamFactsMessageType +> = core.serialization.enum_(["facts"]); + +export declare namespace StreamFactsMessageType { + export type Raw = "facts"; +} diff --git a/src/serialization/types/StreamFlushMessage.ts b/src/serialization/types/StreamFlushMessage.ts index f1707ac1..8d4edb53 100644 --- a/src/serialization/types/StreamFlushMessage.ts +++ b/src/serialization/types/StreamFlushMessage.ts @@ -1,20 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { StreamFlushMessageType } from "./StreamFlushMessageType.js"; export const StreamFlushMessage: core.serialization.ObjectSchema< serializers.StreamFlushMessage.Raw, Corti.StreamFlushMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("flush"), + type: StreamFlushMessageType, }); export declare namespace StreamFlushMessage { export interface Raw { - type: "flush"; + type: StreamFlushMessageType.Raw; } } diff --git a/src/serialization/types/StreamFlushMessageType.ts b/src/serialization/types/StreamFlushMessageType.ts new file mode 100644 index 00000000..30850327 --- /dev/null +++ b/src/serialization/types/StreamFlushMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const StreamFlushMessageType: core.serialization.Schema< + serializers.StreamFlushMessageType.Raw, + Corti.StreamFlushMessageType +> = core.serialization.enum_(["flush"]); + +export declare namespace StreamFlushMessageType { + export type Raw = "flush"; +} diff --git a/src/serialization/types/StreamFlushedMessage.ts b/src/serialization/types/StreamFlushedMessage.ts index cf022c17..cefcdd07 100644 --- a/src/serialization/types/StreamFlushedMessage.ts +++ b/src/serialization/types/StreamFlushedMessage.ts @@ -1,20 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { StreamFlushedMessageType } from "./StreamFlushedMessageType.js"; export const StreamFlushedMessage: core.serialization.ObjectSchema< serializers.StreamFlushedMessage.Raw, Corti.StreamFlushedMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("flushed"), + type: StreamFlushedMessageType, }); export declare namespace StreamFlushedMessage { export interface Raw { - type: "flushed"; + type: StreamFlushedMessageType.Raw; } } diff --git a/src/serialization/types/StreamFlushedMessageType.ts b/src/serialization/types/StreamFlushedMessageType.ts new file mode 100644 index 00000000..3c1a51dc --- /dev/null +++ b/src/serialization/types/StreamFlushedMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const StreamFlushedMessageType: core.serialization.Schema< + serializers.StreamFlushedMessageType.Raw, + Corti.StreamFlushedMessageType +> = core.serialization.enum_(["flushed"]); + +export declare namespace StreamFlushedMessageType { + export type Raw = "flushed"; +} diff --git a/src/serialization/types/StreamParticipant.ts b/src/serialization/types/StreamParticipant.ts index db5cdae1..d4fb6e90 100644 --- a/src/serialization/types/StreamParticipant.ts +++ b/src/serialization/types/StreamParticipant.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const StreamParticipant: core.serialization.ObjectSchema< serializers.StreamParticipant.Raw, diff --git a/src/serialization/types/StreamSupportedLanguage.ts b/src/serialization/types/StreamSupportedLanguage.ts index 733e9421..1068fcb0 100644 --- a/src/serialization/types/StreamSupportedLanguage.ts +++ b/src/serialization/types/StreamSupportedLanguage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const StreamSupportedLanguage: core.serialization.Schema< serializers.StreamSupportedLanguage.Raw, diff --git a/src/serialization/types/StreamTranscript.ts b/src/serialization/types/StreamTranscript.ts index ffb8829e..6c9e1e4e 100644 --- a/src/serialization/types/StreamTranscript.ts +++ b/src/serialization/types/StreamTranscript.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { StreamParticipant } from "./StreamParticipant.js"; import { StreamTranscriptTime } from "./StreamTranscriptTime.js"; diff --git a/src/serialization/types/StreamTranscriptMessage.ts b/src/serialization/types/StreamTranscriptMessage.ts index 541cf6af..5e1c5b6d 100644 --- a/src/serialization/types/StreamTranscriptMessage.ts +++ b/src/serialization/types/StreamTranscriptMessage.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { StreamTranscript } from "./StreamTranscript.js"; +import { StreamTranscriptMessageType } from "./StreamTranscriptMessageType.js"; export const StreamTranscriptMessage: core.serialization.ObjectSchema< serializers.StreamTranscriptMessage.Raw, Corti.StreamTranscriptMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("transcript"), + type: StreamTranscriptMessageType, data: core.serialization.list(StreamTranscript), }); export declare namespace StreamTranscriptMessage { export interface Raw { - type: "transcript"; + type: StreamTranscriptMessageType.Raw; data: StreamTranscript.Raw[]; } } diff --git a/src/serialization/types/StreamTranscriptMessageType.ts b/src/serialization/types/StreamTranscriptMessageType.ts new file mode 100644 index 00000000..c6c75d1c --- /dev/null +++ b/src/serialization/types/StreamTranscriptMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const StreamTranscriptMessageType: core.serialization.Schema< + serializers.StreamTranscriptMessageType.Raw, + Corti.StreamTranscriptMessageType +> = core.serialization.enum_(["transcript"]); + +export declare namespace StreamTranscriptMessageType { + export type Raw = "transcript"; +} diff --git a/src/serialization/types/StreamTranscriptTime.ts b/src/serialization/types/StreamTranscriptTime.ts index a0674f2a..66153dc2 100644 --- a/src/serialization/types/StreamTranscriptTime.ts +++ b/src/serialization/types/StreamTranscriptTime.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const StreamTranscriptTime: core.serialization.ObjectSchema< serializers.StreamTranscriptTime.Raw, diff --git a/src/serialization/types/StreamUsageMessage.ts b/src/serialization/types/StreamUsageMessage.ts index 3a184b4a..89b40165 100644 --- a/src/serialization/types/StreamUsageMessage.ts +++ b/src/serialization/types/StreamUsageMessage.ts @@ -1,22 +1,21 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { StreamUsageMessageType } from "./StreamUsageMessageType.js"; export const StreamUsageMessage: core.serialization.ObjectSchema< serializers.StreamUsageMessage.Raw, Corti.StreamUsageMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("usage"), + type: StreamUsageMessageType, credits: core.serialization.number(), }); export declare namespace StreamUsageMessage { export interface Raw { - type: "usage"; + type: StreamUsageMessageType.Raw; credits: number; } } diff --git a/src/serialization/types/StreamUsageMessageType.ts b/src/serialization/types/StreamUsageMessageType.ts new file mode 100644 index 00000000..e384429a --- /dev/null +++ b/src/serialization/types/StreamUsageMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const StreamUsageMessageType: core.serialization.Schema< + serializers.StreamUsageMessageType.Raw, + Corti.StreamUsageMessageType +> = core.serialization.enum_(["usage"]); + +export declare namespace StreamUsageMessageType { + export type Raw = "usage"; +} diff --git a/src/serialization/types/TemplatesDocumentationModeEnum.ts b/src/serialization/types/TemplatesDocumentationModeEnum.ts index 653866ae..70cd3303 100644 --- a/src/serialization/types/TemplatesDocumentationModeEnum.ts +++ b/src/serialization/types/TemplatesDocumentationModeEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TemplatesDocumentationModeEnum: core.serialization.Schema< serializers.TemplatesDocumentationModeEnum.Raw, diff --git a/src/serialization/types/TemplatesFormatRule.ts b/src/serialization/types/TemplatesFormatRule.ts index 492c972b..6838a354 100644 --- a/src/serialization/types/TemplatesFormatRule.ts +++ b/src/serialization/types/TemplatesFormatRule.ts @@ -1,20 +1,18 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TemplatesFormatRule: core.serialization.ObjectSchema< serializers.TemplatesFormatRule.Raw, Corti.TemplatesFormatRule > = core.serialization.object({ - name: core.serialization.string().optionalNullable(), + name: core.serialization.string().nullable(), }); export declare namespace TemplatesFormatRule { export interface Raw { - name?: (string | null) | null; + name?: string | null; } } diff --git a/src/serialization/types/TemplatesItem.ts b/src/serialization/types/TemplatesItem.ts index 7c84b2f9..72e829cd 100644 --- a/src/serialization/types/TemplatesItem.ts +++ b/src/serialization/types/TemplatesItem.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TemplatesDocumentationModeEnum } from "./TemplatesDocumentationModeEnum.js"; import { TemplatesSectionSorted } from "./TemplatesSectionSorted.js"; import { TemplatesTranslation } from "./TemplatesTranslation.js"; @@ -24,10 +22,10 @@ export const TemplatesItem: core.serialization.ObjectSchema = core.serialization.object({ id: core.serialization.string(), variables: core.serialization - .record(core.serialization.string(), core.serialization.string().optionalNullable()) + .record(core.serialization.string(), core.serialization.string().nullable()) .optionalNullable(), rawTranscriptText: core.serialization.string(), start: core.serialization.number(), @@ -22,7 +20,7 @@ export const TranscribeCommandData: core.serialization.ObjectSchema< export declare namespace TranscribeCommandData { export interface Raw { id: string; - variables?: (Record | null) | null; + variables?: (Record | null | undefined) | null; rawTranscriptText: string; start: number; end: number; diff --git a/src/serialization/types/TranscribeCommandMessage.ts b/src/serialization/types/TranscribeCommandMessage.ts index 8b6665f1..85c37e59 100644 --- a/src/serialization/types/TranscribeCommandMessage.ts +++ b/src/serialization/types/TranscribeCommandMessage.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscribeCommandData } from "./TranscribeCommandData.js"; +import { TranscribeCommandMessageType } from "./TranscribeCommandMessageType.js"; export const TranscribeCommandMessage: core.serialization.ObjectSchema< serializers.TranscribeCommandMessage.Raw, Corti.TranscribeCommandMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("command"), + type: TranscribeCommandMessageType, data: TranscribeCommandData, }); export declare namespace TranscribeCommandMessage { export interface Raw { - type: "command"; + type: TranscribeCommandMessageType.Raw; data: TranscribeCommandData.Raw; } } diff --git a/src/serialization/types/TranscribeCommandMessageType.ts b/src/serialization/types/TranscribeCommandMessageType.ts new file mode 100644 index 00000000..8c24da23 --- /dev/null +++ b/src/serialization/types/TranscribeCommandMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeCommandMessageType: core.serialization.Schema< + serializers.TranscribeCommandMessageType.Raw, + Corti.TranscribeCommandMessageType +> = core.serialization.enum_(["command"]); + +export declare namespace TranscribeCommandMessageType { + export type Raw = "command"; +} diff --git a/src/serialization/types/TranscribeCommandVariable.ts b/src/serialization/types/TranscribeCommandVariable.ts index c344d506..549c96e3 100644 --- a/src/serialization/types/TranscribeCommandVariable.ts +++ b/src/serialization/types/TranscribeCommandVariable.ts @@ -1,24 +1,23 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { TranscribeCommandVariableType } from "./TranscribeCommandVariableType.js"; export const TranscribeCommandVariable: core.serialization.ObjectSchema< serializers.TranscribeCommandVariable.Raw, Corti.TranscribeCommandVariable > = core.serialization.object({ key: core.serialization.string(), - type: core.serialization.stringLiteral("enum"), + type: TranscribeCommandVariableType, enum: core.serialization.list(core.serialization.string()), }); export declare namespace TranscribeCommandVariable { export interface Raw { key: string; - type: "enum"; + type: TranscribeCommandVariableType.Raw; enum: string[]; } } diff --git a/src/serialization/types/TranscribeCommandVariableType.ts b/src/serialization/types/TranscribeCommandVariableType.ts new file mode 100644 index 00000000..654e11ca --- /dev/null +++ b/src/serialization/types/TranscribeCommandVariableType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeCommandVariableType: core.serialization.Schema< + serializers.TranscribeCommandVariableType.Raw, + Corti.TranscribeCommandVariableType +> = core.serialization.enum_(["enum"]); + +export declare namespace TranscribeCommandVariableType { + export type Raw = "enum"; +} diff --git a/src/serialization/types/TranscribeConfig.ts b/src/serialization/types/TranscribeConfig.ts index 9c644218..ceedea52 100644 --- a/src/serialization/types/TranscribeConfig.ts +++ b/src/serialization/types/TranscribeConfig.ts @@ -1,13 +1,11 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { TranscribeSupportedLanguage } from "./TranscribeSupportedLanguage.js"; +import type * as serializers from "../index.js"; import { TranscribeCommand } from "./TranscribeCommand.js"; import { TranscribeFormatting } from "./TranscribeFormatting.js"; +import { TranscribeSupportedLanguage } from "./TranscribeSupportedLanguage.js"; export const TranscribeConfig: core.serialization.ObjectSchema< serializers.TranscribeConfig.Raw, diff --git a/src/serialization/types/TranscribeConfigMessage.ts b/src/serialization/types/TranscribeConfigMessage.ts index 9014768c..236c8be0 100644 --- a/src/serialization/types/TranscribeConfigMessage.ts +++ b/src/serialization/types/TranscribeConfigMessage.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscribeConfig } from "./TranscribeConfig.js"; +import { TranscribeConfigMessageType } from "./TranscribeConfigMessageType.js"; export const TranscribeConfigMessage: core.serialization.ObjectSchema< serializers.TranscribeConfigMessage.Raw, Corti.TranscribeConfigMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("config"), + type: TranscribeConfigMessageType, configuration: TranscribeConfig, }); export declare namespace TranscribeConfigMessage { export interface Raw { - type: "config"; + type: TranscribeConfigMessageType.Raw; configuration: TranscribeConfig.Raw; } } diff --git a/src/serialization/types/TranscribeConfigMessageType.ts b/src/serialization/types/TranscribeConfigMessageType.ts new file mode 100644 index 00000000..55b423dd --- /dev/null +++ b/src/serialization/types/TranscribeConfigMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeConfigMessageType: core.serialization.Schema< + serializers.TranscribeConfigMessageType.Raw, + Corti.TranscribeConfigMessageType +> = core.serialization.enum_(["config"]); + +export declare namespace TranscribeConfigMessageType { + export type Raw = "config"; +} diff --git a/src/serialization/types/TranscribeConfigStatusMessage.ts b/src/serialization/types/TranscribeConfigStatusMessage.ts index ddadc2ef..d5afff35 100644 --- a/src/serialization/types/TranscribeConfigStatusMessage.ts +++ b/src/serialization/types/TranscribeConfigStatusMessage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscribeConfigStatusMessageType } from "./TranscribeConfigStatusMessageType.js"; export const TranscribeConfigStatusMessage: core.serialization.ObjectSchema< diff --git a/src/serialization/types/TranscribeConfigStatusMessageType.ts b/src/serialization/types/TranscribeConfigStatusMessageType.ts index d486699e..a5a9fdbe 100644 --- a/src/serialization/types/TranscribeConfigStatusMessageType.ts +++ b/src/serialization/types/TranscribeConfigStatusMessageType.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeConfigStatusMessageType: core.serialization.Schema< serializers.TranscribeConfigStatusMessageType.Raw, diff --git a/src/serialization/types/TranscribeEndMessage.ts b/src/serialization/types/TranscribeEndMessage.ts index c4c40e2e..febe83b7 100644 --- a/src/serialization/types/TranscribeEndMessage.ts +++ b/src/serialization/types/TranscribeEndMessage.ts @@ -1,20 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { TranscribeEndMessageType } from "./TranscribeEndMessageType.js"; export const TranscribeEndMessage: core.serialization.ObjectSchema< serializers.TranscribeEndMessage.Raw, Corti.TranscribeEndMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("end"), + type: TranscribeEndMessageType, }); export declare namespace TranscribeEndMessage { export interface Raw { - type: "end"; + type: TranscribeEndMessageType.Raw; } } diff --git a/src/serialization/types/TranscribeEndMessageType.ts b/src/serialization/types/TranscribeEndMessageType.ts new file mode 100644 index 00000000..7919e166 --- /dev/null +++ b/src/serialization/types/TranscribeEndMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeEndMessageType: core.serialization.Schema< + serializers.TranscribeEndMessageType.Raw, + Corti.TranscribeEndMessageType +> = core.serialization.enum_(["end"]); + +export declare namespace TranscribeEndMessageType { + export type Raw = "end"; +} diff --git a/src/serialization/types/TranscribeEndedMessage.ts b/src/serialization/types/TranscribeEndedMessage.ts index b6677e96..00dcf0c8 100644 --- a/src/serialization/types/TranscribeEndedMessage.ts +++ b/src/serialization/types/TranscribeEndedMessage.ts @@ -1,20 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { TranscribeEndedMessageType } from "./TranscribeEndedMessageType.js"; export const TranscribeEndedMessage: core.serialization.ObjectSchema< serializers.TranscribeEndedMessage.Raw, Corti.TranscribeEndedMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("ended"), + type: TranscribeEndedMessageType, }); export declare namespace TranscribeEndedMessage { export interface Raw { - type: "ended"; + type: TranscribeEndedMessageType.Raw; } } diff --git a/src/serialization/types/TranscribeEndedMessageType.ts b/src/serialization/types/TranscribeEndedMessageType.ts new file mode 100644 index 00000000..cee35939 --- /dev/null +++ b/src/serialization/types/TranscribeEndedMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeEndedMessageType: core.serialization.Schema< + serializers.TranscribeEndedMessageType.Raw, + Corti.TranscribeEndedMessageType +> = core.serialization.enum_(["ended"]); + +export declare namespace TranscribeEndedMessageType { + export type Raw = "ended"; +} diff --git a/src/serialization/types/TranscribeErrorMessage.ts b/src/serialization/types/TranscribeErrorMessage.ts index d7506b25..454f7964 100644 --- a/src/serialization/types/TranscribeErrorMessage.ts +++ b/src/serialization/types/TranscribeErrorMessage.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscribeErrorMessageError } from "./TranscribeErrorMessageError.js"; +import { TranscribeErrorMessageType } from "./TranscribeErrorMessageType.js"; export const TranscribeErrorMessage: core.serialization.ObjectSchema< serializers.TranscribeErrorMessage.Raw, Corti.TranscribeErrorMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("error"), + type: TranscribeErrorMessageType, error: TranscribeErrorMessageError, }); export declare namespace TranscribeErrorMessage { export interface Raw { - type: "error"; + type: TranscribeErrorMessageType.Raw; error: TranscribeErrorMessageError.Raw; } } diff --git a/src/serialization/types/TranscribeErrorMessageError.ts b/src/serialization/types/TranscribeErrorMessageError.ts index b15ac32b..9c37d1e4 100644 --- a/src/serialization/types/TranscribeErrorMessageError.ts +++ b/src/serialization/types/TranscribeErrorMessageError.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeErrorMessageError: core.serialization.ObjectSchema< serializers.TranscribeErrorMessageError.Raw, diff --git a/src/serialization/types/TranscribeErrorMessageType.ts b/src/serialization/types/TranscribeErrorMessageType.ts new file mode 100644 index 00000000..f6cb3c23 --- /dev/null +++ b/src/serialization/types/TranscribeErrorMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeErrorMessageType: core.serialization.Schema< + serializers.TranscribeErrorMessageType.Raw, + Corti.TranscribeErrorMessageType +> = core.serialization.enum_(["error"]); + +export declare namespace TranscribeErrorMessageType { + export type Raw = "error"; +} diff --git a/src/serialization/types/TranscribeFlushMessage.ts b/src/serialization/types/TranscribeFlushMessage.ts index ba633dd0..33c73a0e 100644 --- a/src/serialization/types/TranscribeFlushMessage.ts +++ b/src/serialization/types/TranscribeFlushMessage.ts @@ -1,20 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { TranscribeFlushMessageType } from "./TranscribeFlushMessageType.js"; export const TranscribeFlushMessage: core.serialization.ObjectSchema< serializers.TranscribeFlushMessage.Raw, Corti.TranscribeFlushMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("flush"), + type: TranscribeFlushMessageType, }); export declare namespace TranscribeFlushMessage { export interface Raw { - type: "flush"; + type: TranscribeFlushMessageType.Raw; } } diff --git a/src/serialization/types/TranscribeFlushMessageType.ts b/src/serialization/types/TranscribeFlushMessageType.ts new file mode 100644 index 00000000..05db82e7 --- /dev/null +++ b/src/serialization/types/TranscribeFlushMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeFlushMessageType: core.serialization.Schema< + serializers.TranscribeFlushMessageType.Raw, + Corti.TranscribeFlushMessageType +> = core.serialization.enum_(["flush"]); + +export declare namespace TranscribeFlushMessageType { + export type Raw = "flush"; +} diff --git a/src/serialization/types/TranscribeFlushedMessage.ts b/src/serialization/types/TranscribeFlushedMessage.ts index 3869d579..59769fdd 100644 --- a/src/serialization/types/TranscribeFlushedMessage.ts +++ b/src/serialization/types/TranscribeFlushedMessage.ts @@ -1,20 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { TranscribeFlushedMessageType } from "./TranscribeFlushedMessageType.js"; export const TranscribeFlushedMessage: core.serialization.ObjectSchema< serializers.TranscribeFlushedMessage.Raw, Corti.TranscribeFlushedMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("flushed"), + type: TranscribeFlushedMessageType, }); export declare namespace TranscribeFlushedMessage { export interface Raw { - type: "flushed"; + type: TranscribeFlushedMessageType.Raw; } } diff --git a/src/serialization/types/TranscribeFlushedMessageType.ts b/src/serialization/types/TranscribeFlushedMessageType.ts new file mode 100644 index 00000000..177bb35e --- /dev/null +++ b/src/serialization/types/TranscribeFlushedMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeFlushedMessageType: core.serialization.Schema< + serializers.TranscribeFlushedMessageType.Raw, + Corti.TranscribeFlushedMessageType +> = core.serialization.enum_(["flushed"]); + +export declare namespace TranscribeFlushedMessageType { + export type Raw = "flushed"; +} diff --git a/src/serialization/types/TranscribeFormatting.ts b/src/serialization/types/TranscribeFormatting.ts index 5eb4737b..4b5b9b6d 100644 --- a/src/serialization/types/TranscribeFormatting.ts +++ b/src/serialization/types/TranscribeFormatting.ts @@ -1,16 +1,14 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscribeFormattingDates } from "./TranscribeFormattingDates.js"; -import { TranscribeFormattingTimes } from "./TranscribeFormattingTimes.js"; -import { TranscribeFormattingNumbers } from "./TranscribeFormattingNumbers.js"; import { TranscribeFormattingMeasurements } from "./TranscribeFormattingMeasurements.js"; +import { TranscribeFormattingNumbers } from "./TranscribeFormattingNumbers.js"; import { TranscribeFormattingNumericRanges } from "./TranscribeFormattingNumericRanges.js"; import { TranscribeFormattingOrdinals } from "./TranscribeFormattingOrdinals.js"; +import { TranscribeFormattingTimes } from "./TranscribeFormattingTimes.js"; export const TranscribeFormatting: core.serialization.ObjectSchema< serializers.TranscribeFormatting.Raw, diff --git a/src/serialization/types/TranscribeFormattingDates.ts b/src/serialization/types/TranscribeFormattingDates.ts index 3fb4e071..9c228389 100644 --- a/src/serialization/types/TranscribeFormattingDates.ts +++ b/src/serialization/types/TranscribeFormattingDates.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeFormattingDates: core.serialization.Schema< serializers.TranscribeFormattingDates.Raw, diff --git a/src/serialization/types/TranscribeFormattingMeasurements.ts b/src/serialization/types/TranscribeFormattingMeasurements.ts index 697745a3..f94bd733 100644 --- a/src/serialization/types/TranscribeFormattingMeasurements.ts +++ b/src/serialization/types/TranscribeFormattingMeasurements.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeFormattingMeasurements: core.serialization.Schema< serializers.TranscribeFormattingMeasurements.Raw, diff --git a/src/serialization/types/TranscribeFormattingNumbers.ts b/src/serialization/types/TranscribeFormattingNumbers.ts index 5731907c..bfc1886e 100644 --- a/src/serialization/types/TranscribeFormattingNumbers.ts +++ b/src/serialization/types/TranscribeFormattingNumbers.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeFormattingNumbers: core.serialization.Schema< serializers.TranscribeFormattingNumbers.Raw, diff --git a/src/serialization/types/TranscribeFormattingNumericRanges.ts b/src/serialization/types/TranscribeFormattingNumericRanges.ts index 01f59346..d64f27b4 100644 --- a/src/serialization/types/TranscribeFormattingNumericRanges.ts +++ b/src/serialization/types/TranscribeFormattingNumericRanges.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeFormattingNumericRanges: core.serialization.Schema< serializers.TranscribeFormattingNumericRanges.Raw, diff --git a/src/serialization/types/TranscribeFormattingOrdinals.ts b/src/serialization/types/TranscribeFormattingOrdinals.ts index a2077405..cfc7a766 100644 --- a/src/serialization/types/TranscribeFormattingOrdinals.ts +++ b/src/serialization/types/TranscribeFormattingOrdinals.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeFormattingOrdinals: core.serialization.Schema< serializers.TranscribeFormattingOrdinals.Raw, diff --git a/src/serialization/types/TranscribeFormattingTimes.ts b/src/serialization/types/TranscribeFormattingTimes.ts index 76f56cac..740e0505 100644 --- a/src/serialization/types/TranscribeFormattingTimes.ts +++ b/src/serialization/types/TranscribeFormattingTimes.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeFormattingTimes: core.serialization.Schema< serializers.TranscribeFormattingTimes.Raw, diff --git a/src/serialization/types/TranscribeSupportedLanguage.ts b/src/serialization/types/TranscribeSupportedLanguage.ts index dc85dade..1ad617f9 100644 --- a/src/serialization/types/TranscribeSupportedLanguage.ts +++ b/src/serialization/types/TranscribeSupportedLanguage.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeSupportedLanguage: core.serialization.Schema< serializers.TranscribeSupportedLanguage.Raw, diff --git a/src/serialization/types/TranscribeTranscriptData.ts b/src/serialization/types/TranscribeTranscriptData.ts index c2860ce3..c7c59b88 100644 --- a/src/serialization/types/TranscribeTranscriptData.ts +++ b/src/serialization/types/TranscribeTranscriptData.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscribeTranscriptData: core.serialization.ObjectSchema< serializers.TranscribeTranscriptData.Raw, diff --git a/src/serialization/types/TranscribeTranscriptMessage.ts b/src/serialization/types/TranscribeTranscriptMessage.ts index 21f7f5e1..4d6e19ef 100644 --- a/src/serialization/types/TranscribeTranscriptMessage.ts +++ b/src/serialization/types/TranscribeTranscriptMessage.ts @@ -1,23 +1,22 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscribeTranscriptData } from "./TranscribeTranscriptData.js"; +import { TranscribeTranscriptMessageType } from "./TranscribeTranscriptMessageType.js"; export const TranscribeTranscriptMessage: core.serialization.ObjectSchema< serializers.TranscribeTranscriptMessage.Raw, Corti.TranscribeTranscriptMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("transcript"), + type: TranscribeTranscriptMessageType, data: TranscribeTranscriptData, }); export declare namespace TranscribeTranscriptMessage { export interface Raw { - type: "transcript"; + type: TranscribeTranscriptMessageType.Raw; data: TranscribeTranscriptData.Raw; } } diff --git a/src/serialization/types/TranscribeTranscriptMessageType.ts b/src/serialization/types/TranscribeTranscriptMessageType.ts new file mode 100644 index 00000000..f63479b3 --- /dev/null +++ b/src/serialization/types/TranscribeTranscriptMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeTranscriptMessageType: core.serialization.Schema< + serializers.TranscribeTranscriptMessageType.Raw, + Corti.TranscribeTranscriptMessageType +> = core.serialization.enum_(["transcript"]); + +export declare namespace TranscribeTranscriptMessageType { + export type Raw = "transcript"; +} diff --git a/src/serialization/types/TranscribeUsageMessage.ts b/src/serialization/types/TranscribeUsageMessage.ts index 660cd9b4..d9cc1e1d 100644 --- a/src/serialization/types/TranscribeUsageMessage.ts +++ b/src/serialization/types/TranscribeUsageMessage.ts @@ -1,22 +1,21 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; +import { TranscribeUsageMessageType } from "./TranscribeUsageMessageType.js"; export const TranscribeUsageMessage: core.serialization.ObjectSchema< serializers.TranscribeUsageMessage.Raw, Corti.TranscribeUsageMessage > = core.serialization.object({ - type: core.serialization.stringLiteral("usage"), + type: TranscribeUsageMessageType, credits: core.serialization.number(), }); export declare namespace TranscribeUsageMessage { export interface Raw { - type: "usage"; + type: TranscribeUsageMessageType.Raw; credits: number; } } diff --git a/src/serialization/types/TranscribeUsageMessageType.ts b/src/serialization/types/TranscribeUsageMessageType.ts new file mode 100644 index 00000000..74ca73bd --- /dev/null +++ b/src/serialization/types/TranscribeUsageMessageType.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Corti from "../../api/index.js"; +import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; + +export const TranscribeUsageMessageType: core.serialization.Schema< + serializers.TranscribeUsageMessageType.Raw, + Corti.TranscribeUsageMessageType +> = core.serialization.enum_(["usage"]); + +export declare namespace TranscribeUsageMessageType { + export type Raw = "usage"; +} diff --git a/src/serialization/types/TranscriptsData.ts b/src/serialization/types/TranscriptsData.ts index d368d168..4a580b1b 100644 --- a/src/serialization/types/TranscriptsData.ts +++ b/src/serialization/types/TranscriptsData.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { TranscriptsMetadata } from "./TranscriptsMetadata.js"; +import type * as serializers from "../index.js"; import { CommonTranscriptResponse } from "./CommonTranscriptResponse.js"; +import { TranscriptsMetadata } from "./TranscriptsMetadata.js"; export const TranscriptsData: core.serialization.ObjectSchema = core.serialization.object({ diff --git a/src/serialization/types/TranscriptsListItem.ts b/src/serialization/types/TranscriptsListItem.ts index 331861da..505f8956 100644 --- a/src/serialization/types/TranscriptsListItem.ts +++ b/src/serialization/types/TranscriptsListItem.ts @@ -1,12 +1,10 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { Uuid } from "./Uuid.js"; +import type * as serializers from "../index.js"; import { TranscriptsData } from "./TranscriptsData.js"; +import { Uuid } from "./Uuid.js"; export const TranscriptsListItem: core.serialization.ObjectSchema< serializers.TranscriptsListItem.Raw, diff --git a/src/serialization/types/TranscriptsListResponse.ts b/src/serialization/types/TranscriptsListResponse.ts index f54029bf..0dd1a3ea 100644 --- a/src/serialization/types/TranscriptsListResponse.ts +++ b/src/serialization/types/TranscriptsListResponse.ts @@ -1,21 +1,19 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscriptsListItem } from "./TranscriptsListItem.js"; export const TranscriptsListResponse: core.serialization.ObjectSchema< serializers.TranscriptsListResponse.Raw, Corti.TranscriptsListResponse > = core.serialization.object({ - transcripts: core.serialization.list(TranscriptsListItem).optionalNullable(), + transcripts: core.serialization.list(TranscriptsListItem).nullable(), }); export declare namespace TranscriptsListResponse { export interface Raw { - transcripts?: (TranscriptsListItem.Raw[] | null) | null; + transcripts?: TranscriptsListItem.Raw[] | null; } } diff --git a/src/serialization/types/TranscriptsMetadata.ts b/src/serialization/types/TranscriptsMetadata.ts index 9b84afe5..4f188255 100644 --- a/src/serialization/types/TranscriptsMetadata.ts +++ b/src/serialization/types/TranscriptsMetadata.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscriptsParticipant } from "./TranscriptsParticipant.js"; export const TranscriptsMetadata: core.serialization.ObjectSchema< @@ -16,6 +14,6 @@ export const TranscriptsMetadata: core.serialization.ObjectSchema< export declare namespace TranscriptsMetadata { export interface Raw { - participantsRoles?: (TranscriptsParticipant.Raw[] | null) | null; + participantsRoles?: (TranscriptsParticipant.Raw[] | null | undefined) | null; } } diff --git a/src/serialization/types/TranscriptsParticipant.ts b/src/serialization/types/TranscriptsParticipant.ts index 92158ca3..0d75a19e 100644 --- a/src/serialization/types/TranscriptsParticipant.ts +++ b/src/serialization/types/TranscriptsParticipant.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscriptsParticipantRoleEnum } from "./TranscriptsParticipantRoleEnum.js"; export const TranscriptsParticipant: core.serialization.ObjectSchema< diff --git a/src/serialization/types/TranscriptsParticipantRoleEnum.ts b/src/serialization/types/TranscriptsParticipantRoleEnum.ts index 412bb211..10e90f47 100644 --- a/src/serialization/types/TranscriptsParticipantRoleEnum.ts +++ b/src/serialization/types/TranscriptsParticipantRoleEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscriptsParticipantRoleEnum: core.serialization.Schema< serializers.TranscriptsParticipantRoleEnum.Raw, diff --git a/src/serialization/types/TranscriptsResponse.ts b/src/serialization/types/TranscriptsResponse.ts index 1ff66348..c7e4e0af 100644 --- a/src/serialization/types/TranscriptsResponse.ts +++ b/src/serialization/types/TranscriptsResponse.ts @@ -1,15 +1,13 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; -import { Uuid } from "./Uuid.js"; -import { TranscriptsMetadata } from "./TranscriptsMetadata.js"; +import type * as serializers from "../index.js"; import { CommonTranscriptResponse } from "./CommonTranscriptResponse.js"; import { CommonUsageInfo } from "./CommonUsageInfo.js"; +import { TranscriptsMetadata } from "./TranscriptsMetadata.js"; import { TranscriptsStatusEnum } from "./TranscriptsStatusEnum.js"; +import { Uuid } from "./Uuid.js"; export const TranscriptsResponse: core.serialization.ObjectSchema< serializers.TranscriptsResponse.Raw, @@ -17,7 +15,7 @@ export const TranscriptsResponse: core.serialization.ObjectSchema< > = core.serialization.object({ id: Uuid, metadata: TranscriptsMetadata, - transcripts: core.serialization.list(CommonTranscriptResponse).optionalNullable(), + transcripts: core.serialization.list(CommonTranscriptResponse).nullable(), usageInfo: CommonUsageInfo, recordingId: Uuid, status: TranscriptsStatusEnum, @@ -27,7 +25,7 @@ export declare namespace TranscriptsResponse { export interface Raw { id: Uuid.Raw; metadata: TranscriptsMetadata.Raw; - transcripts?: (CommonTranscriptResponse.Raw[] | null) | null; + transcripts?: CommonTranscriptResponse.Raw[] | null; usageInfo: CommonUsageInfo.Raw; recordingId: Uuid.Raw; status: TranscriptsStatusEnum.Raw; diff --git a/src/serialization/types/TranscriptsStatusEnum.ts b/src/serialization/types/TranscriptsStatusEnum.ts index e269f08d..029db38c 100644 --- a/src/serialization/types/TranscriptsStatusEnum.ts +++ b/src/serialization/types/TranscriptsStatusEnum.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const TranscriptsStatusEnum: core.serialization.Schema< serializers.TranscriptsStatusEnum.Raw, diff --git a/src/serialization/types/TranscriptsStatusResponse.ts b/src/serialization/types/TranscriptsStatusResponse.ts index 4e775690..03797c1a 100644 --- a/src/serialization/types/TranscriptsStatusResponse.ts +++ b/src/serialization/types/TranscriptsStatusResponse.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; import { TranscriptsStatusEnum } from "./TranscriptsStatusEnum.js"; export const TranscriptsStatusResponse: core.serialization.ObjectSchema< diff --git a/src/serialization/types/Uuid.ts b/src/serialization/types/Uuid.ts index 86322c94..125a4add 100644 --- a/src/serialization/types/Uuid.ts +++ b/src/serialization/types/Uuid.ts @@ -1,10 +1,8 @@ -/** - * This file was auto-generated by Fern from our API Definition. - */ +// This file was auto-generated by Fern from our API Definition. -import * as serializers from "../index.js"; -import * as Corti from "../../api/index.js"; +import type * as Corti from "../../api/index.js"; import * as core from "../../core/index.js"; +import type * as serializers from "../index.js"; export const Uuid: core.serialization.Schema = core.serialization.string(); diff --git a/src/serialization/types/index.ts b/src/serialization/types/index.ts index f52afcf8..3eb03315 100644 --- a/src/serialization/types/index.ts +++ b/src/serialization/types/index.ts @@ -1,168 +1,202 @@ +export * from "./AgentsAgent.js"; +export * from "./AgentsAgentCapabilities.js"; +export * from "./AgentsAgentCard.js"; +export * from "./AgentsAgentCardSignature.js"; +export * from "./AgentsAgentExpertsItem.js"; +export * from "./AgentsAgentExtension.js"; +export * from "./AgentsAgentInterface.js"; +export * from "./AgentsAgentProvider.js"; +export * from "./AgentsAgentReference.js"; +export * from "./AgentsAgentReferenceType.js"; +export * from "./AgentsAgentResponse.js"; +export * from "./AgentsAgentSkill.js"; +export * from "./AgentsArtifact.js"; +export * from "./AgentsContext.js"; +export * from "./AgentsContextItemsItem.js"; +export * from "./AgentsCreateExpert.js"; +export * from "./AgentsCreateExpertReference.js"; +export * from "./AgentsCreateExpertReferenceType.js"; +export * from "./AgentsCreateExpertType.js"; +export * from "./AgentsCreateMcpServer.js"; +export * from "./AgentsCreateMcpServerAuthorizationType.js"; +export * from "./AgentsCreateMcpServerTransportType.js"; +export * from "./AgentsDataPart.js"; +export * from "./AgentsDataPartKind.js"; +export * from "./AgentsExpert.js"; +export * from "./AgentsExpertReference.js"; +export * from "./AgentsExpertReferenceType.js"; +export * from "./AgentsExpertType.js"; +export * from "./AgentsFilePart.js"; +export * from "./AgentsFilePartFile.js"; +export * from "./AgentsFilePartKind.js"; +export * from "./AgentsFileWithBytes.js"; +export * from "./AgentsFileWithUri.js"; +export * from "./AgentsMcpServer.js"; +export * from "./AgentsMcpServerAuthorizationType.js"; +export * from "./AgentsMcpServerTransportType.js"; +export * from "./AgentsMessage.js"; +export * from "./AgentsMessageKind.js"; +export * from "./AgentsMessageRole.js"; +export * from "./AgentsMessageSendConfiguration.js"; +export * from "./AgentsPart.js"; +export * from "./AgentsPushNotificationAuthenticationInfo.js"; +export * from "./AgentsPushNotificationConfig.js"; +export * from "./AgentsRegistryExpert.js"; +export * from "./AgentsRegistryExpertsResponse.js"; +export * from "./AgentsRegistryMcpServer.js"; +export * from "./AgentsRegistryMcpServerAuthorizationType.js"; +export * from "./AgentsTask.js"; +export * from "./AgentsTaskKind.js"; +export * from "./AgentsTaskStatus.js"; +export * from "./AgentsTaskStatusState.js"; +export * from "./AgentsTextPart.js"; +export * from "./AgentsTextPartKind.js"; +export * from "./CodesGeneralReadResponse.js"; +export * from "./CodesGeneralReadResponseEvidencesItem.js"; +export * from "./CodesGeneralResponse.js"; +export * from "./CommonAiContext.js"; export * from "./CommonCodingSystemEnum.js"; +export * from "./CommonDocumentIdContext.js"; +export * from "./CommonDocumentIdContextType.js"; +export * from "./CommonSortingDirectionEnum.js"; +export * from "./CommonSourceEnum.js"; +export * from "./CommonTextContext.js"; +export * from "./CommonTextContextType.js"; +export * from "./CommonTranscriptRequest.js"; +export * from "./CommonTranscriptResponse.js"; +export * from "./CommonUsageInfo.js"; export * from "./DocumentsContext.js"; export * from "./DocumentsContextWithFacts.js"; -export * from "./DocumentsContextWithTranscript.js"; +export * from "./DocumentsContextWithFactsType.js"; export * from "./DocumentsContextWithString.js"; +export * from "./DocumentsContextWithStringType.js"; +export * from "./DocumentsContextWithTranscript.js"; +export * from "./DocumentsContextWithTranscriptType.js"; +export * from "./DocumentsCreateRequestBody.js"; +export * from "./DocumentsCreateRequestWithTemplate.js"; +export * from "./DocumentsCreateRequestWithTemplateKey.js"; +export * from "./DocumentsGetResponse.js"; +export * from "./DocumentsListResponse.js"; export * from "./DocumentsSection.js"; +export * from "./DocumentsSectionInput.js"; export * from "./DocumentsSectionOverride.js"; export * from "./DocumentsTemplate.js"; export * from "./DocumentsTemplateWithSectionKeys.js"; export * from "./DocumentsTemplateWithSections.js"; -export * from "./InteractionsEncounterCreateRequest.js"; -export * from "./InteractionsEncounterUpdateRequest.js"; -export * from "./InteractionsEncounterResponse.js"; -export * from "./InteractionsEncounterPeriod.js"; export * from "./ErrorResponse.js"; +export * from "./FactsBatchUpdateInput.js"; +export * from "./FactsBatchUpdateItem.js"; +export * from "./FactsBatchUpdateResponse.js"; export * from "./FactsContext.js"; -export * from "./FactsFactGroupsItemTranslationsItem.js"; -export * from "./FactsFactGroupsItem.js"; -export * from "./InteractionsPatient.js"; -export * from "./DocumentsCreateRequest.js"; -export * from "./DocumentsCreateRequestWithTemplateKey.js"; -export * from "./DocumentsCreateRequestWithTemplate.js"; -export * from "./DocumentsSectionInput.js"; -export * from "./CommonDocumentIdContext.js"; -export * from "./CommonTextContext.js"; -export * from "./CommonAiContext.js"; export * from "./FactsCreateInput.js"; -export * from "./FactsBatchUpdateInput.js"; -export * from "./TranscriptsParticipant.js"; -export * from "./TemplatesSectionListResponse.js"; -export * from "./TemplatesListResponse.js"; -export * from "./DocumentsListResponse.js"; -export * from "./DocumentsGetResponse.js"; -export * from "./FactsListItem.js"; export * from "./FactsCreateItem.js"; +export * from "./FactsCreateResponse.js"; export * from "./FactsEvidence.js"; +export * from "./FactsExtractResponse.js"; +export * from "./FactsExtractResponseFactsItem.js"; +export * from "./FactsFactGroupsItem.js"; +export * from "./FactsFactGroupsItemTranslationsItem.js"; export * from "./FactsFactGroupsListResponse.js"; -export * from "./FactsUpdateResponse.js"; -export * from "./FactsCreateResponse.js"; +export * from "./FactsListItem.js"; export * from "./FactsListResponse.js"; -export * from "./FactsBatchUpdateResponse.js"; -export * from "./FactsBatchUpdateItem.js"; -export * from "./CodesGeneralResponse.js"; -export * from "./CodesGeneralReadResponseEvidencesItem.js"; -export * from "./CodesGeneralReadResponse.js"; -export * from "./FactsExtractResponseFactsItem.js"; -export * from "./FactsExtractResponse.js"; -export * from "./InteractionsGetResponse.js"; +export * from "./FactsUpdateResponse.js"; export * from "./InteractionsCreateResponse.js"; -export * from "./InteractionsListResponse.js"; -export * from "./TranscriptsMetadata.js"; -export * from "./RecordingsCreateResponse.js"; -export * from "./RecordingsListResponse.js"; -export * from "./TranscriptsResponse.js"; -export * from "./TranscriptsListResponse.js"; -export * from "./TranscriptsListItem.js"; -export * from "./TranscriptsData.js"; -export * from "./TranscriptsStatusResponse.js"; -export * from "./TranscriptsStatusEnum.js"; -export * from "./TemplatesSection.js"; -export * from "./CommonSortingDirectionEnum.js"; -export * from "./TemplatesDocumentationModeEnum.js"; -export * from "./TemplatesItem.js"; -export * from "./TemplatesSectionSorted.js"; -export * from "./CommonTranscriptRequest.js"; -export * from "./CommonTranscriptResponse.js"; -export * from "./Uuid.js"; -export * from "./CommonUsageInfo.js"; +export * from "./InteractionsEncounterCreateRequest.js"; +export * from "./InteractionsEncounterPeriod.js"; +export * from "./InteractionsEncounterResponse.js"; export * from "./InteractionsEncounterStatusEnum.js"; export * from "./InteractionsEncounterTypeEnum.js"; +export * from "./InteractionsEncounterUpdateRequest.js"; export * from "./InteractionsGenderEnum.js"; -export * from "./CommonSourceEnum.js"; -export * from "./TranscriptsParticipantRoleEnum.js"; -export * from "./TemplatesWritingStyle.js"; -export * from "./TemplatesFormatRule.js"; -export * from "./TemplatesSectionTranslation.js"; -export * from "./TemplatesTranslation.js"; -export * from "./StreamConfigMessage.js"; +export * from "./InteractionsGetResponse.js"; +export * from "./InteractionsListResponse.js"; +export * from "./InteractionsPatient.js"; +export * from "./RecordingsCreateResponse.js"; +export * from "./RecordingsListResponse.js"; export * from "./StreamConfig.js"; -export * from "./StreamConfigTranscription.js"; -export * from "./StreamConfigModeType.js"; +export * from "./StreamConfigMessage.js"; +export * from "./StreamConfigMessageType.js"; export * from "./StreamConfigMode.js"; -export * from "./StreamConfigStatusMessageType.js"; +export * from "./StreamConfigModeType.js"; +export * from "./StreamConfigParticipant.js"; +export * from "./StreamConfigParticipantRole.js"; export * from "./StreamConfigStatusMessage.js"; +export * from "./StreamConfigStatusMessageType.js"; +export * from "./StreamConfigTranscription.js"; export * from "./StreamEndedMessage.js"; -export * from "./StreamFlushedMessage.js"; -export * from "./StreamUsageMessage.js"; -export * from "./StreamErrorMessage.js"; +export * from "./StreamEndedMessageType.js"; +export * from "./StreamEndMessage.js"; +export * from "./StreamEndMessageType.js"; export * from "./StreamErrorDetail.js"; -export * from "./StreamTranscriptMessage.js"; -export * from "./StreamTranscript.js"; -export * from "./StreamParticipant.js"; -export * from "./StreamConfigParticipantRole.js"; -export * from "./StreamConfigParticipant.js"; -export * from "./StreamTranscriptTime.js"; -export * from "./StreamFactsMessage.js"; +export * from "./StreamErrorMessage.js"; +export * from "./StreamErrorMessageType.js"; export * from "./StreamFact.js"; -export * from "./StreamEndMessage.js"; +export * from "./StreamFactsMessage.js"; +export * from "./StreamFactsMessageType.js"; +export * from "./StreamFlushedMessage.js"; +export * from "./StreamFlushedMessageType.js"; export * from "./StreamFlushMessage.js"; +export * from "./StreamFlushMessageType.js"; +export * from "./StreamParticipant.js"; export * from "./StreamSupportedLanguage.js"; -export * from "./TranscribeSupportedLanguage.js"; -export * from "./TranscribeConfig.js"; -export * from "./TranscribeConfigMessage.js"; +export * from "./StreamTranscript.js"; +export * from "./StreamTranscriptMessage.js"; +export * from "./StreamTranscriptMessageType.js"; +export * from "./StreamTranscriptTime.js"; +export * from "./StreamUsageMessage.js"; +export * from "./StreamUsageMessageType.js"; +export * from "./TemplatesDocumentationModeEnum.js"; +export * from "./TemplatesFormatRule.js"; +export * from "./TemplatesItem.js"; +export * from "./TemplatesListResponse.js"; +export * from "./TemplatesSection.js"; +export * from "./TemplatesSectionListResponse.js"; +export * from "./TemplatesSectionSorted.js"; +export * from "./TemplatesSectionTranslation.js"; +export * from "./TemplatesTranslation.js"; +export * from "./TemplatesWritingStyle.js"; export * from "./TranscribeCommand.js"; +export * from "./TranscribeCommandData.js"; +export * from "./TranscribeCommandMessage.js"; +export * from "./TranscribeCommandMessageType.js"; export * from "./TranscribeCommandVariable.js"; -export * from "./TranscribeConfigStatusMessageType.js"; +export * from "./TranscribeCommandVariableType.js"; +export * from "./TranscribeConfig.js"; +export * from "./TranscribeConfigMessage.js"; +export * from "./TranscribeConfigMessageType.js"; export * from "./TranscribeConfigStatusMessage.js"; -export * from "./TranscribeEndMessage.js"; -export * from "./TranscribeFlushMessage.js"; -export * from "./TranscribeUsageMessage.js"; +export * from "./TranscribeConfigStatusMessageType.js"; export * from "./TranscribeEndedMessage.js"; -export * from "./TranscribeFlushedMessage.js"; -export * from "./TranscribeErrorMessageError.js"; +export * from "./TranscribeEndedMessageType.js"; +export * from "./TranscribeEndMessage.js"; +export * from "./TranscribeEndMessageType.js"; export * from "./TranscribeErrorMessage.js"; -export * from "./TranscribeTranscriptData.js"; -export * from "./TranscribeCommandData.js"; -export * from "./TranscribeTranscriptMessage.js"; -export * from "./TranscribeCommandMessage.js"; +export * from "./TranscribeErrorMessageError.js"; +export * from "./TranscribeErrorMessageType.js"; +export * from "./TranscribeFlushedMessage.js"; +export * from "./TranscribeFlushedMessageType.js"; +export * from "./TranscribeFlushMessage.js"; +export * from "./TranscribeFlushMessageType.js"; +export * from "./TranscribeFormatting.js"; export * from "./TranscribeFormattingDates.js"; -export * from "./TranscribeFormattingTimes.js"; -export * from "./TranscribeFormattingNumbers.js"; export * from "./TranscribeFormattingMeasurements.js"; +export * from "./TranscribeFormattingNumbers.js"; export * from "./TranscribeFormattingNumericRanges.js"; export * from "./TranscribeFormattingOrdinals.js"; -export * from "./TranscribeFormatting.js"; -export * from "./AgentsTaskStatusState.js"; -export * from "./AgentsTaskStatus.js"; -export * from "./AgentsTextPart.js"; -export * from "./AgentsFileWithUri.js"; -export * from "./AgentsFileWithBytes.js"; -export * from "./AgentsFilePartFile.js"; -export * from "./AgentsFilePart.js"; -export * from "./AgentsDataPart.js"; -export * from "./AgentsPart.js"; -export * from "./AgentsMessageRole.js"; -export * from "./AgentsMessage.js"; -export * from "./AgentsArtifact.js"; -export * from "./AgentsTask.js"; -export * from "./AgentsPushNotificationAuthenticationInfo.js"; -export * from "./AgentsPushNotificationConfig.js"; -export * from "./AgentsMessageSendConfiguration.js"; -export * from "./AgentsCreateMcpServerTransportType.js"; -export * from "./AgentsCreateMcpServerAuthorizationType.js"; -export * from "./AgentsCreateMcpServer.js"; -export * from "./AgentsMcpServerTransportType.js"; -export * from "./AgentsMcpServerAuthorizationType.js"; -export * from "./AgentsMcpServer.js"; -export * from "./AgentsRegistryMcpServerAuthorizationType.js"; -export * from "./AgentsRegistryMcpServer.js"; -export * from "./AgentsAgentExpertsItem.js"; -export * from "./AgentsAgent.js"; -export * from "./AgentsAgentReference.js"; -export * from "./AgentsCreateExpert.js"; -export * from "./AgentsCreateExpertReference.js"; -export * from "./AgentsExpert.js"; -export * from "./AgentsExpertReference.js"; -export * from "./AgentsAgentResponse.js"; -export * from "./AgentsAgentInterface.js"; -export * from "./AgentsAgentProvider.js"; -export * from "./AgentsAgentCapabilities.js"; -export * from "./AgentsAgentExtension.js"; -export * from "./AgentsAgentSkill.js"; -export * from "./AgentsAgentCardSignature.js"; -export * from "./AgentsAgentCard.js"; -export * from "./AgentsContextItemsItem.js"; -export * from "./AgentsContext.js"; -export * from "./AgentsRegistryExpert.js"; -export * from "./AgentsRegistryExpertsResponse.js"; +export * from "./TranscribeFormattingTimes.js"; +export * from "./TranscribeSupportedLanguage.js"; +export * from "./TranscribeTranscriptData.js"; +export * from "./TranscribeTranscriptMessage.js"; +export * from "./TranscribeTranscriptMessageType.js"; +export * from "./TranscribeUsageMessage.js"; +export * from "./TranscribeUsageMessageType.js"; +export * from "./TranscriptsData.js"; +export * from "./TranscriptsListItem.js"; +export * from "./TranscriptsListResponse.js"; +export * from "./TranscriptsMetadata.js"; +export * from "./TranscriptsParticipant.js"; +export * from "./TranscriptsParticipantRoleEnum.js"; +export * from "./TranscriptsResponse.js"; +export * from "./TranscriptsStatusEnum.js"; +export * from "./TranscriptsStatusResponse.js"; +export * from "./Uuid.js"; diff --git a/tests/BrowserTestEnvironment.ts b/tests/BrowserTestEnvironment.ts deleted file mode 100644 index 0f32bf7b..00000000 --- a/tests/BrowserTestEnvironment.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { TestEnvironment } from "jest-environment-jsdom"; - -class BrowserTestEnvironment extends TestEnvironment { - async setup() { - await super.setup(); - this.global.Request = Request; - this.global.Response = Response; - this.global.ReadableStream = ReadableStream; - this.global.TextEncoder = TextEncoder; - this.global.TextDecoder = TextDecoder; - this.global.FormData = FormData; - this.global.File = File; - this.global.Blob = Blob; - } -} - -export default BrowserTestEnvironment; diff --git a/tests/custom/agents.create.integration.ts b/tests/custom/agents.create.integration.ts deleted file mode 100644 index 49297e70..00000000 --- a/tests/custom/agents.create.integration.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, cleanupAgents, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.agents.create", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdAgentIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdAgentIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupAgents(cortiClient, createdAgentIds); - createdAgentIds = []; - }); - - describe("should create agent with only required values", () => { - it("should create agent with only name and description without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.create({ - name: faker.lorem.words(3), - description: faker.lorem.sentence(), - }); - - createdAgentIds.push(result.id); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create agent with all optional values", () => { - it("should create agent with systemPrompt without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.create({ - name: faker.lorem.words(3), - description: faker.lorem.sentence(), - systemPrompt: faker.lorem.paragraph(), - }); - - createdAgentIds.push(result.id); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create agent with ephemeral set to true without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.create({ - name: faker.lorem.words(3), - description: faker.lorem.sentence(), - ephemeral: true, - }); - - createdAgentIds.push(result.id); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create agent with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.create({ - name: faker.lorem.words(3), - description: faker.lorem.sentence(), - systemPrompt: faker.lorem.paragraph(), - ephemeral: false, - }); - - createdAgentIds.push(result.id); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should handle errors when required parameters are missing", () => { - it("should throw error when name is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.agents.create({ - description: faker.lorem.sentence(), - } as any), - ).rejects.toThrow('Missing required key "name"'); - }); - - it("should throw error when description is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.agents.create({ - name: faker.lorem.words(3), - } as any), - ).rejects.toThrow('Missing required key "description"'); - }); - }); -}); diff --git a/tests/custom/agents.delete.integration.ts b/tests/custom/agents.delete.integration.ts deleted file mode 100644 index 8cdd06ea..00000000 --- a/tests/custom/agents.delete.integration.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestAgent, cleanupAgents, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.agents.delete", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdAgentIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdAgentIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupAgents(cortiClient, createdAgentIds); - createdAgentIds = []; - }); - - describe("should delete agent with only required values", () => { - it("should successfully delete an existing agent without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const result = await cortiClient.agents.delete(agent.id); - - expect(result).toBeUndefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should throw error when required parameters are missing", () => { - it("should throw error when agent ID is missing", async () => { - expect.assertions(1); - - await expect(cortiClient.agents.delete(undefined as any)).rejects.toThrow(); - }); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when agent ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.agents.delete("invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when agent ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.agents.delete(faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/agents.get.integration.ts b/tests/custom/agents.get.integration.ts deleted file mode 100644 index 26e9e497..00000000 --- a/tests/custom/agents.get.integration.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestAgent, cleanupAgents, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.agents.get", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdAgentIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdAgentIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupAgents(cortiClient, createdAgentIds); - createdAgentIds = []; - }); - - describe("should retrieve agent with only required values", () => { - it("should successfully retrieve an existing agent without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const result = await cortiClient.agents.get(agent.id); - - expect(result.id).toBe(agent.id); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should throw error when required parameters are missing", () => { - it("should throw error when agent ID is missing", async () => { - expect.assertions(1); - - await expect(cortiClient.agents.get(undefined as any)).rejects.toThrow(); - }); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when agent ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.agents.get("invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when agent ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.agents.get(faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/agents.getCard.integration.ts b/tests/custom/agents.getCard.integration.ts deleted file mode 100644 index 23db8854..00000000 --- a/tests/custom/agents.getCard.integration.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestAgent, cleanupAgents, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.agents.getCard", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdAgentIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdAgentIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupAgents(cortiClient, createdAgentIds); - createdAgentIds = []; - }); - - it("should successfully retrieve an agent card without errors or warnings", async () => { - expect.assertions(3); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const result = await cortiClient.agents.getCard(agent.id); - - expect(result).toBeDefined(); - expect(result.name).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when agent ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.agents.getCard("invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when agent ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.agents.getCard(faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/agents.getContext.integration.ts b/tests/custom/agents.getContext.integration.ts deleted file mode 100644 index 7575cd1c..00000000 --- a/tests/custom/agents.getContext.integration.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestAgent, - cleanupAgents, - setupConsoleWarnSpy, - sendTestMessage, -} from "./testUtils"; - -describe("cortiClient.agents.getContext", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdAgentIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdAgentIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupAgents(cortiClient, createdAgentIds); - createdAgentIds = []; - }); - - describe("should retrieve context with only required values", () => { - it("should successfully retrieve a context without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - const contextId = messageResponse.task?.contextId; - - if (!contextId) { - throw new Error("No context ID returned from message send"); - } - - const result = await cortiClient.agents.getContext(agent.id, contextId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - it("should retrieve context with limit parameter without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - const contextId = messageResponse.task?.contextId; - - if (!contextId) { - throw new Error("No context ID returned from message send"); - } - - const result = await cortiClient.agents.getContext(agent.id, contextId, { - limit: faker.number.int({ min: 1, max: 100 }), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should retrieve context with offset parameter without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - const contextId = messageResponse.task?.contextId; - - if (!contextId) { - throw new Error("No context ID returned from message send"); - } - - const result = await cortiClient.agents.getContext(agent.id, contextId, { - offset: faker.number.int({ min: 0, max: 100 }), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should retrieve context with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - const contextId = messageResponse.task?.contextId; - - if (!contextId) { - throw new Error("No context ID returned from message send"); - } - - const result = await cortiClient.agents.getContext(agent.id, contextId, { - limit: faker.number.int({ min: 1, max: 100 }), - offset: faker.number.int({ min: 0, max: 100 }), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when agent ID is invalid format", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - const contextId = messageResponse.task?.contextId; - - if (!contextId) { - throw new Error("No context ID returned from message send"); - } - - await expect(cortiClient.agents.getContext("invalid-uuid", contextId)).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when context ID is invalid format", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect(cortiClient.agents.getContext(agent.id, "invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when agent ID does not exist", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - const contextId = messageResponse.task?.contextId; - - if (!contextId) { - throw new Error("No context ID returned from message send"); - } - - await expect(cortiClient.agents.getContext(faker.string.uuid(), contextId)).rejects.toThrow( - "Status code: 404", - ); - }); - - it("should throw error when context ID does not exist", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect(cortiClient.agents.getContext(agent.id, faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - }); -}); diff --git a/tests/custom/agents.getRegistryExperts.integration.ts b/tests/custom/agents.getRegistryExperts.integration.ts deleted file mode 100644 index 7d9d75b0..00000000 --- a/tests/custom/agents.getRegistryExperts.integration.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.agents.getRegistryExperts", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - it("should return registry experts without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.getRegistryExperts(); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return registry experts with limit parameter without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.getRegistryExperts({ - limit: faker.number.int({ min: 1, max: 100 }), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return registry experts with offset parameter without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.getRegistryExperts({ - offset: faker.number.int({ min: 0, max: 100 }), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return registry experts with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.getRegistryExperts({ - limit: faker.number.int({ min: 1, max: 100 }), - offset: faker.number.int({ min: 0, max: 100 }), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); -}); diff --git a/tests/custom/agents.getTask.integration.ts b/tests/custom/agents.getTask.integration.ts deleted file mode 100644 index 89befa0b..00000000 --- a/tests/custom/agents.getTask.integration.ts +++ /dev/null @@ -1,115 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestAgent, - cleanupAgents, - setupConsoleWarnSpy, - sendTestMessage, -} from "./testUtils"; - -describe("cortiClient.agents.getTask", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdAgentIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdAgentIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupAgents(cortiClient, createdAgentIds); - createdAgentIds = []; - }); - - it("should successfully retrieve a task without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - - const taskId = messageResponse.task?.id; - - if (!taskId) { - throw new Error("No task ID returned from message send"); - } - - const result = await cortiClient.agents.getTask(agent.id, taskId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should retrieve task with historyLength parameter without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - const taskId = messageResponse.task?.id; - - if (!taskId) { - throw new Error("No task ID returned from message send"); - } - - const result = await cortiClient.agents.getTask(agent.id, taskId, { - historyLength: faker.number.int({ min: 1, max: 100 }), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - // FIXME: re-enable when validation is implemented - it.skip("should throw error when agent ID is invalid format", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - const taskId = messageResponse.task?.id; - - if (!taskId) { - throw new Error("No task ID returned from message send"); - } - - await expect(cortiClient.agents.getTask("invalid-uuid", taskId)).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when task ID is invalid format", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect(cortiClient.agents.getTask(agent.id, "invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - // FIXME: re-enable when proper error handling is implemented - it.skip("should throw error when agent ID does not exist", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - const messageResponse = await sendTestMessage(cortiClient, agent.id); - const taskId = messageResponse.task?.id; - - if (!taskId) { - throw new Error("No task ID returned from message send"); - } - - await expect(cortiClient.agents.getTask(faker.string.uuid(), taskId)).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when task ID does not exist", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect(cortiClient.agents.getTask(agent.id, faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/agents.list.integration.ts b/tests/custom/agents.list.integration.ts deleted file mode 100644 index 641bf061..00000000 --- a/tests/custom/agents.list.integration.ts +++ /dev/null @@ -1,109 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestAgent, cleanupAgents, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.agents.list", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdAgentIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdAgentIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupAgents(cortiClient, createdAgentIds); - createdAgentIds = []; - }); - - // FIXME: re-enable when deletion issues are resolved - it.skip("should return empty list when no agents exist", async () => { - expect.assertions(2); - - const existingAgents = await cortiClient.agents.list(); - const agentIds: string[] = []; - - for (const agent of existingAgents) { - if ("id" in agent && agent.id) { - agentIds.push(agent.id); - } - } - - if (agentIds.length > 0) { - await cleanupAgents(cortiClient, agentIds); - } - - const result = await cortiClient.agents.list(); - - expect(result.length).toBe(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should list agents with only required values", () => { - it("should return created agent in list without errors or warnings", async () => { - expect.assertions(3); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const result = await cortiClient.agents.list(); - - expect(result.length).toBeGreaterThan(0); - expect(result.some((listAgent: any) => listAgent.id === agent.id)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should return list with optional parameters", () => { - it("should return list with limit parameter without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.list({ - limit: faker.number.int({ min: 1, max: 10 }), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return list with offset parameter without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.list({ - offset: faker.number.int({ min: 0, max: 10 }), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return list with ephemeral parameter without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.list({ - ephemeral: false, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return list with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.agents.list({ - limit: faker.number.int({ min: 1, max: 10 }), - offset: faker.number.int({ min: 0, max: 10 }), - ephemeral: false, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/tests/custom/agents.messageSend.integration.ts b/tests/custom/agents.messageSend.integration.ts deleted file mode 100644 index 09114f4c..00000000 --- a/tests/custom/agents.messageSend.integration.ts +++ /dev/null @@ -1,399 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestAgent, cleanupAgents, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.agents.messageSend", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdAgentIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdAgentIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupAgents(cortiClient, createdAgentIds); - createdAgentIds = []; - }); - - describe("should send message with minimal fields", () => { - it("should send message with only required fields without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const result = await cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should send message with agent role without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const result = await cortiClient.agents.messageSend(agent.id, { - message: { - role: "agent", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should send message with all optional fields", () => { - it("should send message with metadata without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const result = await cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - metadata: { - testKey: faker.lorem.word(), - }, - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should send message with extensions without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const result = await cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - extensions: [faker.lorem.word()], - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME: We need to be able to get a task in not final state, otherwise error is valid - it.skip("should send message with taskId and contextId without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const firstMessage = await cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - }, - }); - - const taskId = firstMessage.task?.id; - const contextId = firstMessage.task?.contextId; - - const result = await cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - taskId: taskId, - contextId: contextId, - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should send message with referenceTaskIds without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const result = await cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - referenceTaskIds: [faker.string.uuid()], - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME: We need to be able to get a task in not final state, otherwise error is valid - it.skip("should send message with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const firstMessage = await cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - }, - }); - - const taskId = firstMessage.task?.id; - const contextId = firstMessage.task?.contextId; - - const result = await cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - metadata: { - testKey: faker.lorem.word(), - }, - extensions: [faker.lorem.word()], - taskId: taskId, - contextId: contextId, - referenceTaskIds: [faker.string.uuid()], - }, - configuration: { - blocking: true, - }, - metadata: { - testMetadata: faker.lorem.word(), - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should throw error when required parameters are missing", () => { - it("should throw error when message is missing", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect(cortiClient.agents.messageSend(agent.id, {} as any)).rejects.toThrow( - 'Missing required key "message"', - ); - }); - - it("should throw error when role is missing", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.messageSend(agent.id, { - message: { - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - } as any, - }), - ).rejects.toThrow('Missing required key "role"'); - }); - - it("should throw error when parts is missing", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - messageId: faker.string.uuid(), - kind: "message", - } as any, - }), - ).rejects.toThrow('Missing required key "parts"'); - }); - - it("should throw error when messageId is missing", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - kind: "message", - } as any, - }), - ).rejects.toThrow('Missing required key "messageId"'); - }); - - it("should throw error when kind is missing", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - } as any, - }), - ).rejects.toThrow('Missing required key "kind"'); - }); - - it("should throw error when text is missing in text part", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.messageSend(agent.id, { - message: { - role: "user", - parts: [ - { - kind: "text", - } as any, - ], - messageId: faker.string.uuid(), - kind: "message", - }, - }), - ).rejects.toThrow('Missing required key "text"'); - }); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when agent ID is invalid format", async () => { - expect.assertions(1); - - await expect( - cortiClient.agents.messageSend("invalid-uuid", { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - }, - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when agent ID does not exist", async () => { - expect.assertions(1); - - await expect( - cortiClient.agents.messageSend(faker.string.uuid(), { - message: { - role: "user", - parts: [ - { - kind: "text", - text: faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - }, - }), - ).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/agents.update.integration.ts b/tests/custom/agents.update.integration.ts deleted file mode 100644 index 874e09d8..00000000 --- a/tests/custom/agents.update.integration.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestAgent, cleanupAgents, setupConsoleWarnSpy } from "./testUtils"; - -// FIXME : Skipping until update agent functionality is restored -describe.skip("cortiClient.agents.update", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdAgentIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdAgentIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupAgents(cortiClient, createdAgentIds); - createdAgentIds = []; - }); - - describe("should update agent with minimal fields", () => { - it("should update agent with only name without errors or warnings", async () => { - expect.assertions(4); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const newName = faker.lorem.words(3); - - const result = await cortiClient.agents.update(agent.id, { - id: agent.id, - name: newName, - description: agent.description, - systemPrompt: agent.systemPrompt, - }); - - expect(result).toBeDefined(); - expect(result.name).toBe(newName); - expect(result.name).not.toBe(agent.name); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update agent with only description without errors or warnings", async () => { - expect.assertions(4); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const newDescription = faker.lorem.sentence(); - - const result = await cortiClient.agents.update(agent.id, { - id: agent.id, - name: agent.name, - description: newDescription, - systemPrompt: agent.systemPrompt, - }); - - expect(result).toBeDefined(); - expect(result.description).toBe(newDescription); - expect(result.description).not.toBe(agent.description); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update agent with only systemPrompt without errors or warnings", async () => { - expect.assertions(3); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const newSystemPrompt = faker.lorem.paragraph(); - - const result = await cortiClient.agents.update(agent.id, { - id: agent.id, - name: agent.name, - description: agent.description, - systemPrompt: newSystemPrompt, - }); - - expect(result).toBeDefined(); - expect(result.systemPrompt).toBe(newSystemPrompt); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - it("should update agent with all possible parameters without errors or warnings", async () => { - expect.assertions(6); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - const newName = faker.lorem.words(4); - const newDescription = faker.lorem.sentence(); - const newSystemPrompt = faker.lorem.paragraph(); - - const result = await cortiClient.agents.update(agent.id, { - id: agent.id, - name: newName, - description: newDescription, - systemPrompt: newSystemPrompt, - }); - - expect(result).toBeDefined(); - expect(result.name).toBe(newName); - expect(result.name).not.toBe(agent.name); - expect(result.description).toBe(newDescription); - expect(result.description).not.toBe(agent.description); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when agent ID is invalid", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.update("invalid-uuid", { - id: agent.id, - name: agent.name, - description: agent.description, - systemPrompt: agent.systemPrompt, - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when agent ID does not exist", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.update(faker.string.uuid(), { - id: agent.id, - name: agent.name, - description: agent.description, - systemPrompt: agent.systemPrompt, - }), - ).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when id is missing", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.update(agent.id, { - name: agent.name, - description: agent.description, - systemPrompt: agent.systemPrompt, - } as any), - ).rejects.toThrow('Missing required key "id"'); - }); - - it("should throw error when name is missing", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.update(agent.id, { - id: agent.id, - description: agent.description, - systemPrompt: agent.systemPrompt, - } as any), - ).rejects.toThrow('Missing required key "name"'); - }); - - it("should throw error when description is missing", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.update(agent.id, { - id: agent.id, - name: agent.name, - systemPrompt: agent.systemPrompt, - } as any), - ).rejects.toThrow('Missing required key "description"'); - }); - - it("should throw error when systemPrompt is missing", async () => { - expect.assertions(1); - - const agent = await createTestAgent(cortiClient, createdAgentIds); - - await expect( - cortiClient.agents.update(agent.id, { - id: agent.id, - name: agent.name, - description: agent.description, - } as any), - ).rejects.toThrow('Missing required key "systemPrompt"'); - }); - }); -}); diff --git a/tests/custom/codes.predict.integration.ts b/tests/custom/codes.predict.integration.ts deleted file mode 100644 index 8365c3c2..00000000 --- a/tests/custom/codes.predict.integration.ts +++ /dev/null @@ -1,230 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestDocument, createTestInteraction, cleanupInteractions, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.codes.predict", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - describe("should predict codes with only required values", () => { - it("should predict codes with text context without errors or warnings", async () => { - expect.assertions(4); - - const result = await cortiClient.codes.predict({ - system: ["icd10cm"], - context: [ - { - type: "text", - text: faker.lorem.sentence(), - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.codes).toBeDefined(); - expect(Array.isArray(result.codes)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should predict codes with all optional parameters", () => { - it("should predict codes with maxCandidates without errors or warnings", async () => { - expect.assertions(5); - - const result = await cortiClient.codes.predict({ - system: ["icd10cm"], - context: [ - { - type: "text", - text: faker.lorem.sentence(), - }, - ], - maxCandidates: faker.number.int({ min: 1, max: 10 }), - }); - - expect(result).toBeDefined(); - expect(result.codes).toBeDefined(); - expect(result.candidates).toBeDefined(); - expect(Array.isArray(result.candidates)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should predict codes with all system enum values", () => { - it("should predict codes with system icd10cm without errors or warnings", async () => { - expect.assertions(4); - - const result = await cortiClient.codes.predict({ - system: ["icd10cm"], - context: [{ type: "text", text: faker.lorem.sentence() }], - }); - - expect(result).toBeDefined(); - expect(result.codes).toBeDefined(); - expect(result.candidates).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should predict codes with system icd10pcs without errors or warnings", async () => { - expect.assertions(4); - - const result = await cortiClient.codes.predict({ - system: ["icd10pcs"], - context: [{ type: "text", text: faker.lorem.sentence() }], - }); - - expect(result).toBeDefined(); - expect(result.codes).toBeDefined(); - expect(result.candidates).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should predict codes with system cpt without errors or warnings", async () => { - expect.assertions(4); - - const result = await cortiClient.codes.predict({ - system: ["cpt"], - context: [{ type: "text", text: faker.lorem.sentence() }], - }); - - expect(result).toBeDefined(); - expect(result.codes).toBeDefined(); - expect(result.candidates).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should predict codes with documentId context", () => { - const createdInteractionIds: string[] = []; - - afterEach(async () => { - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds.length = 0; - }); - - it("should predict codes when context is documentId without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - const result = await cortiClient.codes.predict({ - system: ["icd10cm"], - context: [ - { - type: "documentId", - documentId, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.codes).toBeDefined(); - expect(Array.isArray(result.codes)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should return response with expected shape", () => { - it("should return codes and candidates arrays", async () => { - expect.assertions(4); - - const result = await cortiClient.codes.predict({ - system: ["icd10cm"], - context: [{ type: "text", text: faker.lorem.sentence() }], - }); - - expect(result).toHaveProperty("codes"); - expect(result).toHaveProperty("candidates"); - expect(Array.isArray(result.codes)).toBe(true); - expect(Array.isArray(result.candidates)).toBe(true); - }); - }); - - describe("should throw error when required parameters are missing", () => { - it("should throw error when system is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.codes.predict({ - context: [{ type: "text", text: faker.lorem.sentence() }], - } as any), - ).rejects.toThrow(); - }); - - // FIXME: doesn't throw error when context is empty array, but it should - it.skip("should throw error when context is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.codes.predict({ - system: ["icd10cm"], - context: [], - }), - ).rejects.toThrow(); - }); - - it("should throw error when text is missing in text context", async () => { - expect.assertions(1); - - await expect( - cortiClient.codes.predict({ - system: ["icd10cm"], - context: [{ type: "text" }] as any, - }), - ).rejects.toThrow(); - }); - - it("should throw error when documentId is missing in documentId context", async () => { - expect.assertions(1); - - await expect( - cortiClient.codes.predict({ - system: ["icd10cm"], - context: [{ type: "documentId" }] as any, - }), - ).rejects.toThrow(); - }); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when system is empty", async () => { - expect.assertions(1); - - await expect( - cortiClient.codes.predict({ - system: [], - context: [{ type: "text", text: faker.lorem.sentence() }], - } as any), - ).rejects.toThrow(); - }); - - it("should throw error when documentId does not exist", async () => { - expect.assertions(1); - - await expect( - cortiClient.codes.predict({ - system: ["icd10cm"], - context: [ - { - type: "documentId", - documentId: faker.string.uuid(), - }, - ], - }), - ).rejects.toThrow(); - }); - }); -}); diff --git a/tests/custom/documents.create.integration.ts b/tests/custom/documents.create.integration.ts deleted file mode 100644 index b74da4aa..00000000 --- a/tests/custom/documents.create.integration.ts +++ /dev/null @@ -1,1342 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - cleanupInteractions, - setupConsoleWarnSpy, - getValidTemplateKeyAndLanguage, - getValidFactGroups, - getValidSectionKeys, -} from "./testUtils"; - -describe("cortiClient.documents.create", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - let templateKey: string; - let outputLanguage: string; - let validFactGroups: string[] = []; - let validSectionKeys: string[] = []; - - beforeAll(async () => { - cortiClient = createTestCortiClient(); - const templateData = await getValidTemplateKeyAndLanguage(cortiClient); - templateKey = templateData.templateKey; - outputLanguage = templateData.outputLanguage; - validFactGroups = await getValidFactGroups(cortiClient); - validSectionKeys = await getValidSectionKeys(cortiClient); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - describe("should create document with only required values", () => { - it("should create document with DocumentsCreateRequestWithTemplateKey using facts context", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - source: "user", - }, - ], - }, - ], - templateKey, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplateKey using transcript context", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "transcript", - data: { - text: faker.lorem.paragraphs(2), - start: faker.number.int({ min: 0, max: 1000 }), - end: faker.number.int({ min: 1001, max: 5000 }), - channel: faker.number.int({ min: 0, max: 1 }), - participant: faker.number.int({ min: 0, max: 1 }), - speakerId: faker.number.int({ min: 1, max: 10 }), - }, - }, - ], - templateKey, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplateKey using string context", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - templateKey, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplate using facts context and sectionKeys", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - source: "user", - }, - ], - }, - ], - template: { - sectionKeys: [faker.helpers.arrayElement(validSectionKeys)], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplate using transcript context and sectionKeys", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "transcript", - data: { - text: faker.lorem.paragraphs(2), - start: faker.number.int({ min: 0, max: 1000 }), - end: faker.number.int({ min: 1001, max: 5000 }), - channel: faker.number.int({ min: 0, max: 1 }), - participant: faker.number.int({ min: 0, max: 1 }), - speakerId: faker.number.int({ min: 1, max: 10 }), - }, - }, - ], - template: { - sectionKeys: [faker.helpers.arrayElement(validSectionKeys)], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplate using string context and sectionKeys", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sectionKeys: [faker.helpers.arrayElement(validSectionKeys)], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create document with all optional values", () => { - it("should create document with DocumentsCreateRequestWithTemplateKey using facts context", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "user", - }, - ], - }, - ], - templateKey, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplateKey using transcript context", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "transcript", - data: { - text: faker.lorem.paragraphs(2), - start: faker.number.int({ min: 0, max: 1000 }), - end: faker.number.int({ min: 1001, max: 5000 }), - channel: faker.number.int({ min: 0, max: 1 }), - participant: faker.number.int({ min: 0, max: 1 }), - speakerId: faker.number.int({ min: 1, max: 10 }), - }, - }, - ], - templateKey, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplateKey using string context", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - templateKey, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplate using facts context", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "user", - }, - ], - }, - ], - template: { - documentName: faker.lorem.words(3), - additionalInstructions: faker.lorem.sentence(), - sectionKeys: [ - faker.helpers.arrayElement(validSectionKeys), - faker.helpers.arrayElement(validSectionKeys), - ], - }, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplate using transcript context", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "transcript", - data: { - text: faker.lorem.paragraphs(2), - start: faker.number.int({ min: 0, max: 1000 }), - end: faker.number.int({ min: 1001, max: 5000 }), - channel: faker.number.int({ min: 0, max: 1 }), - participant: faker.number.int({ min: 0, max: 1 }), - speakerId: faker.number.int({ min: 1, max: 10 }), - }, - }, - ], - template: { - documentName: faker.lorem.words(3), - additionalInstructions: faker.lorem.sentence(), - sectionKeys: [ - faker.helpers.arrayElement(validSectionKeys), - faker.helpers.arrayElement(validSectionKeys), - ], - }, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplate using string context", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - documentName: faker.lorem.words(3), - additionalInstructions: faker.lorem.sentence(), - sectionKeys: [ - faker.helpers.arrayElement(validSectionKeys), - faker.helpers.arrayElement(validSectionKeys), - ], - }, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create document with all source enum values in facts context", () => { - it("should create document with DocumentsCreateRequestWithTemplateKey using source: core", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "core", - }, - ], - }, - ], - templateKey, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplateKey using source: system", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "system", - }, - ], - }, - ], - templateKey, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplateKey using source: user", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "user", - }, - ], - }, - ], - templateKey, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplate using source: core", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "core", - }, - ], - }, - ], - template: { - documentName: faker.lorem.words(3), - additionalInstructions: faker.lorem.sentence(), - sectionKeys: [ - faker.helpers.arrayElement(validSectionKeys), - faker.helpers.arrayElement(validSectionKeys), - ], - }, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplate using source: system", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "system", - }, - ], - }, - ], - template: { - documentName: faker.lorem.words(3), - additionalInstructions: faker.lorem.sentence(), - sectionKeys: [ - faker.helpers.arrayElement(validSectionKeys), - faker.helpers.arrayElement(validSectionKeys), - ], - }, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with DocumentsCreateRequestWithTemplate using source: user", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "user", - }, - ], - }, - ], - template: { - documentName: faker.lorem.words(3), - additionalInstructions: faker.lorem.sentence(), - sectionKeys: [ - faker.helpers.arrayElement(validSectionKeys), - faker.helpers.arrayElement(validSectionKeys), - ], - }, - name: faker.lorem.words(3), - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create document with DocumentsTemplateWithSections", () => { - it("should create document with sections array with single section", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - }, - ], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with multiple sections", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - }, - { - key: faker.helpers.arrayElement(validSectionKeys), - }, - ], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with nameOverride", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - nameOverride: faker.lorem.words(2), - }, - ], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with writingStyleOverride", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - writingStyleOverride: "Use bullet points and short sentences", - }, - ], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with formatRuleOverride", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - formatRuleOverride: "Format as numbered list", - }, - ], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with additionalInstructionsOverride", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - additionalInstructionsOverride: faker.lorem.sentence(), - }, - ], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with contentOverride", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - contentOverride: faker.lorem.sentence(), - }, - ], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with all overrides", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - nameOverride: faker.lorem.words(2), - writingStyleOverride: "Use formal medical terminology", - formatRuleOverride: "Use headers and subheaders", - additionalInstructionsOverride: faker.lorem.sentence(), - contentOverride: faker.lorem.sentence(), - }, - ], - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with template description", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - }, - ], - description: faker.lorem.sentence(), - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with template additionalInstructionsOverride", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - }, - ], - additionalInstructionsOverride: faker.lorem.sentence(), - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with sections array with all template-level options", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - nameOverride: faker.lorem.words(2), - }, - { - key: faker.helpers.arrayElement(validSectionKeys), - writingStyleOverride: faker.lorem.sentence(), - }, - ], - description: faker.lorem.sentence(), - additionalInstructionsOverride: faker.lorem.sentence(), - }, - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create document with documentationMode", () => { - it("should create document with documentationMode: global_sequential using templateKey", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - templateKey, - outputLanguage: "en", - documentationMode: "global_sequential", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with documentationMode: global_sequential using template with sectionKeys", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sectionKeys: [faker.helpers.arrayElement(validSectionKeys)], - }, - outputLanguage: "en", - documentationMode: "global_sequential", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with documentationMode: routed_parallel using template with sectionKeys", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sectionKeys: [faker.helpers.arrayElement(validSectionKeys)], - }, - outputLanguage: "en", - documentationMode: "routed_parallel", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with documentationMode: global_sequential using template with sections", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - }, - ], - }, - outputLanguage: "en", - documentationMode: "global_sequential", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create document with documentationMode: routed_parallel using template with sections", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: faker.helpers.arrayElement(validSectionKeys), - }, - ], - }, - outputLanguage: "en", - documentationMode: "routed_parallel", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should throw error for invalid documentationMode requests", () => { - it("should throw error when documentationMode is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - templateKey, - outputLanguage: "en", - documentationMode: "invalid_mode" as any, - }), - ).rejects.toThrow(); - }); - }); - - describe("should handle templateKey vs template mutual exclusion", () => { - it("should create document when both templateKey and template provided (templateKey takes precedence)", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - // API should accept this - templateKey takes precedence over template - const result = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - templateKey, - template: { - sectionKeys: [faker.helpers.arrayElement(validSectionKeys)], - }, - outputLanguage: "en", - } as any); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should throw error for invalid DocumentsTemplateWithSections requests", () => { - it("should throw error when sections array is empty", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [], - }, - outputLanguage: "en", - }), - ).rejects.toThrow("BadRequestError"); - }); - - it("should throw error when section key is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - {} as any, - ], - }, - outputLanguage: "en", - }), - ).rejects.toThrow(); - }); - - it("should throw error when section key is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - template: { - sections: [ - { - key: "invalid_section_key_that_does_not_exist", - }, - ], - }, - outputLanguage: "en", - }), - ).rejects.toThrow("Status code: 404"); - }); - }); - - describe("should handle errors when required parameters are missing", () => { - it("should throw error when context is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - templateKey, - outputLanguage: "en", - } as any), - ).rejects.toThrow('Missing required key "context"'); - }); - - it("should throw error when context is empty array", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [], - templateKey, - outputLanguage: "en", - }), - ).rejects.toThrow("BadRequestError"); - }); - - it("should throw error when outputLanguage is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "user", - }, - ], - }, - ], - templateKey, - } as any), - ).rejects.toThrow('Missing required key "outputLanguage"'); - }); - - it("should throw error when templateKey is missing for DocumentsCreateRequestWithTemplateKey", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "user", - }, - ], - }, - ], - outputLanguage: "en", - } as any), - ).rejects.toThrow('Missing required key "templateKey"'); - }); - - it("should throw error when text is missing in facts context", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - group: faker.helpers.arrayElement(validFactGroups), - source: "user", - }, - ], - }, - ], - templateKey, - outputLanguage: "en", - } as any), - ).rejects.toThrow('Missing required key "text"'); - }); - - it("should throw error when source is missing in facts context", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - }, - ], - }, - ], - templateKey, - outputLanguage: "en", - } as any), - ).rejects.toThrow('Missing required key "source"'); - }); - - it("should throw error when transcript text is missing in transcript context", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "transcript", - data: { - start: faker.number.int({ min: 0, max: 1000 }), - end: faker.number.int({ min: 1001, max: 5000 }), - channel: faker.number.int({ min: 0, max: 1 }), - participant: faker.number.int({ min: 0, max: 1 }), - speakerId: faker.number.int({ min: 1, max: 10 }), - }, - }, - ], - templateKey, - outputLanguage: "en", - } as any), - ).rejects.toThrow('Missing required key "text"'); - }); - - it("should throw error when string data is missing in string context", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: undefined, - }, - ], - templateKey, - outputLanguage: "en", - } as any), - ).rejects.toThrow("Expected string. Received undefined."); - }); - - it("should throw error when template is missing for DocumentsCreateRequestWithTemplate", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "user", - }, - ], - }, - ], - outputLanguage: "en", - } as any), - ).rejects.toThrow('Missing required key "template"'); - }); - - it("should throw error when context type is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "invalid_type", - data: "some data", - }, - ], - templateKey, - outputLanguage: "en", - } as any), - ).rejects.toThrow('Received "invalid_type"'); - }); - - it("should throw error when outputLanguage is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.create(interactionId, { - context: [ - { - type: "facts", - data: [ - { - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - source: "user", - }, - ], - }, - ], - templateKey, - outputLanguage: "invalid_language", - }), - ).rejects.toThrow("BadRequestError"); - }); - }); -}); \ No newline at end of file diff --git a/tests/custom/documents.delete.integration.ts b/tests/custom/documents.delete.integration.ts deleted file mode 100644 index 26e11c6e..00000000 --- a/tests/custom/documents.delete.integration.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestInteraction, createTestDocument, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.documents.delete", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - it("should successfully delete an existing document without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - const result = await cortiClient.documents.delete(interactionId, documentId); - - expect(result).toBeUndefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.documents.delete("invalid-uuid", faker.string.uuid())).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when document ID is invalid format", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.documents.delete(interactionId, "invalid-uuid")).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.documents.delete(faker.string.uuid(), faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - }); -}); diff --git a/tests/custom/documents.get.integration.ts b/tests/custom/documents.get.integration.ts deleted file mode 100644 index 8016bf0f..00000000 --- a/tests/custom/documents.get.integration.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestInteraction, createTestDocument, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.documents.get", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - it("should successfully retrieve an existing document without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - const result = await cortiClient.documents.get(interactionId, documentId); - - expect(result.id).toBe(documentId); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.documents.get("invalid-uuid", faker.string.uuid())).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when document ID is invalid format", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.documents.get(interactionId, "invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.documents.get(faker.string.uuid(), faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - - it("should throw error when document ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.documents.get(interactionId, faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - }); -}); diff --git a/tests/custom/documents.list.integration.ts b/tests/custom/documents.list.integration.ts deleted file mode 100644 index 48917d88..00000000 --- a/tests/custom/documents.list.integration.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestInteraction, createTestDocument, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.documents.list", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - it("should return empty list when interaction has no documents", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.documents.list(interactionId); - - expect(result.data.length).toBe(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return documents when interaction has documents", async () => { - expect.assertions(3); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - const result = await cortiClient.documents.list(interactionId); - - expect(result.data.length).toBeGreaterThan(0); - expect(result.data.some((doc: any) => doc.id === documentId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.documents.list("invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.documents.list(faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/documents.update.integration.ts b/tests/custom/documents.update.integration.ts deleted file mode 100644 index 0e7474bf..00000000 --- a/tests/custom/documents.update.integration.ts +++ /dev/null @@ -1,255 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - createTestDocument, - cleanupInteractions, - setupConsoleWarnSpy, - getValidSectionKeys, -} from "./testUtils"; - -describe("cortiClient.documents.update", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - let validSectionKeys: string[] = []; - - beforeAll(async () => { - cortiClient = createTestCortiClient(); - validSectionKeys = await getValidSectionKeys(cortiClient); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - describe("should update document with minimal fields", () => { - it("should update document with empty request (no changes) without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - const result = await cortiClient.documents.update(interactionId, documentId, {}); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update document with only name without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - const originalDocument = await cortiClient.documents.get(interactionId, documentId); - const originalName = originalDocument.name; - - const newName = faker.lorem.words(3); - - const result = await cortiClient.documents.update(interactionId, documentId, { - name: newName, - }); - - expect(result).toBeDefined(); - expect(result.name).toBe(newName); - expect(result.name).not.toBe(originalName); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update document with only sections without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - const sectionKey = faker.helpers.arrayElement(validSectionKeys); - - const result = await cortiClient.documents.update(interactionId, documentId, { - sections: [ - { - key: sectionKey, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.sections).toBeDefined(); - expect(result.sections.some((section) => section.key === sectionKey)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should update document with section variations", () => { - it("should update document with section containing all optional fields without errors or warnings", async () => { - expect.assertions(7); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - const originalDocument = await cortiClient.documents.get(interactionId, documentId); - - const sectionKey = faker.helpers.arrayElement(validSectionKeys); - const sectionName = faker.lorem.words(3); - const sectionText = faker.lorem.paragraphs(3); - - const result = await cortiClient.documents.update(interactionId, documentId, { - sections: [ - { - key: sectionKey, - name: sectionName, - text: sectionText, - sort: 0, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.sections).toBeDefined(); - - const updatedSection = result.sections.find((section) => section.key === sectionKey); - const originalSection = originalDocument.sections.find((section) => section.key === sectionKey); - - expect(updatedSection).toBeDefined(); - expect(updatedSection?.name).toBe(sectionName); - expect(updatedSection?.text).toBe(sectionText); - - const hasChanged = - !originalSection || - updatedSection?.name !== originalSection.name || - updatedSection?.text !== originalSection.text; - expect(hasChanged).toBe(true); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update document with empty sections array without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - const result = await cortiClient.documents.update(interactionId, documentId, { - sections: [], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - it("should update document with all possible optional parameters without errors or warnings", async () => { - expect.assertions(8); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - const originalDocument = await cortiClient.documents.get(interactionId, documentId); - const originalName = originalDocument.name; - - const newName = faker.lorem.words(4); - const sectionKey = faker.helpers.arrayElement(validSectionKeys); - const sectionName = faker.lorem.words(3); - const sectionText = faker.lorem.paragraphs(2); - - const result = await cortiClient.documents.update(interactionId, documentId, { - name: newName, - sections: [ - { - key: sectionKey, - name: sectionName, - text: sectionText, - sort: 0, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.name).toBe(newName); - expect(result.name).not.toBe(originalName); - expect(result.sections).toBeDefined(); - - const updatedSection = result.sections.find((section) => section.key === sectionKey); - expect(updatedSection).toBeDefined(); - expect(updatedSection?.name).toBe(sectionName); - expect(updatedSection?.text).toBe(sectionText); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - await expect( - cortiClient.documents.update("invalid-uuid", documentId, { - name: faker.lorem.words(3), - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when document ID is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.update(interactionId, "invalid-uuid", { - name: faker.lorem.words(3), - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - await expect( - cortiClient.documents.update(faker.string.uuid(), documentId, { - name: faker.lorem.words(3), - }), - ).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when document ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.documents.update(interactionId, faker.string.uuid(), { - name: faker.lorem.words(3), - }), - ).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when section key is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const documentId = await createTestDocument(cortiClient, interactionId); - - await expect( - cortiClient.documents.update(interactionId, documentId, { - sections: [ - { - name: faker.lorem.words(2), - text: faker.lorem.paragraph(), - }, - ], - } as any), - ).rejects.toThrow('Missing required key "key"'); - }); - }); -}); diff --git a/tests/custom/facts.batchUpdate.integration.ts b/tests/custom/facts.batchUpdate.integration.ts deleted file mode 100644 index 10b84f09..00000000 --- a/tests/custom/facts.batchUpdate.integration.ts +++ /dev/null @@ -1,372 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - createTestFacts, - cleanupInteractions, - setupConsoleWarnSpy, - getValidFactGroups, -} from "./testUtils"; - -describe("cortiClient.facts.batchUpdate", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - let validFactGroups: string[] = []; - - beforeAll(async () => { - cortiClient = createTestCortiClient(); - validFactGroups = await getValidFactGroups(cortiClient); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - describe("should batch update facts with minimal fields", () => { - it("should batch update single fact with empty request (no changes) without errors or warnings", async () => { - expect.assertions(3); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - - const result = await cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: factIds[0], - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.facts).toHaveLength(1); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should batch update single fact with only text without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const newText = faker.lorem.sentence(); - - const result = await cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: factIds[0], - text: newText, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.facts).toHaveLength(1); - expect(result.facts[0].text).toBe(newText); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should batch update single fact with only group without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const newGroup = faker.helpers.arrayElement(validFactGroups); - - const result = await cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: factIds[0], - group: newGroup, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.facts).toHaveLength(1); - expect(result.facts[0].group).toBe(newGroup); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should batch update single fact with only isDiscarded without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - - const result = await cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: factIds[0], - isDiscarded: true, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.facts).toHaveLength(1); - expect(result.facts[0].isDiscarded).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should batch update multiple facts", () => { - it("should batch update multiple facts with different fields without errors or warnings", async () => { - expect.assertions(6); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 3); - const newText1 = faker.lorem.sentence(); - const newGroup2 = faker.helpers.arrayElement(validFactGroups); - - const result = await cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: factIds[0], - text: newText1, - }, - { - factId: factIds[1], - group: newGroup2, - }, - { - factId: factIds[2], - isDiscarded: true, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.facts).toHaveLength(3); - expect(result.facts[0].text).toBe(newText1); - expect(result.facts[1].group).toBe(newGroup2); - expect(result.facts[2].isDiscarded).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should batch update multiple facts with all fields without errors or warnings", async () => { - expect.assertions(9); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 2); - const newText1 = faker.lorem.sentence(); - const newGroup1 = faker.helpers.arrayElement(validFactGroups); - const newText2 = faker.lorem.sentence(); - const newGroup2 = faker.helpers.arrayElement(validFactGroups); - - const result = await cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: factIds[0], - text: newText1, - group: newGroup1, - isDiscarded: false, - }, - { - factId: factIds[1], - text: newText2, - group: newGroup2, - isDiscarded: true, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.facts).toHaveLength(2); - expect(result.facts[0].text).toBe(newText1); - expect(result.facts[0].group).toBe(newGroup1); - expect(result.facts[0].isDiscarded).toBe(false); - expect(result.facts[1].text).toBe(newText2); - expect(result.facts[1].group).toBe(newGroup2); - expect(result.facts[1].isDiscarded).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should batch update facts with isDiscarded boolean values", () => { - it("should batch update fact with isDiscarded set to true without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - - const result = await cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: factIds[0], - isDiscarded: true, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.facts).toHaveLength(1); - expect(result.facts[0].isDiscarded).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should batch update fact with isDiscarded set to false without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - - const result = await cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: factIds[0], - isDiscarded: false, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.facts).toHaveLength(1); - expect(result.facts[0].isDiscarded).toBe(false); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - it("should batch update facts with all optional parameters without errors or warnings", async () => { - expect.assertions(7); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 2); - const newText1 = faker.lorem.sentence(); - const newGroup1 = faker.helpers.arrayElement(validFactGroups); - const newText2 = faker.lorem.sentence(); - const newGroup2 = faker.helpers.arrayElement(validFactGroups); - - const result = await cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: factIds[0], - text: newText1, - group: newGroup1, - isDiscarded: true, - }, - { - factId: factIds[1], - text: newText2, - group: newGroup2, - isDiscarded: false, - }, - ], - }); - - expect(result).toBeDefined(); - expect(result.facts).toHaveLength(2); - expect(result.facts[0].text).toBe(newText1); - expect(result.facts[0].group).toBe(newGroup1); - expect(result.facts[0].isDiscarded).toBe(true); - expect(result.facts[1].isDiscarded).toBe(false); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - - await expect( - cortiClient.facts.batchUpdate("invalid-uuid", { - facts: [ - { - factId: factIds[0], - text: faker.lorem.sentence(), - }, - ], - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when fact ID is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: "invalid-uuid", - text: faker.lorem.sentence(), - }, - ], - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - - await expect( - cortiClient.facts.batchUpdate(faker.string.uuid(), { - facts: [ - { - factId: factIds[0], - text: faker.lorem.sentence(), - }, - ], - }), - ).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when fact ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - factId: faker.string.uuid(), - text: faker.lorem.sentence(), - }, - ], - }), - ).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when facts array is empty", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.facts.batchUpdate(interactionId, { - facts: [], - }), - ).rejects.toThrow(); - }); - - it("should throw error when factId is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.facts.batchUpdate(interactionId, { - facts: [ - { - text: faker.lorem.sentence(), - }, - ], - } as any), - ).rejects.toThrow('Missing required key "factId"'); - }); - }); -}); diff --git a/tests/custom/facts.create.integration.ts b/tests/custom/facts.create.integration.ts deleted file mode 100644 index 492ccf46..00000000 --- a/tests/custom/facts.create.integration.ts +++ /dev/null @@ -1,249 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - cleanupInteractions, - setupConsoleWarnSpy, - getValidFactGroups, -} from "./testUtils"; - -describe("cortiClient.facts.create", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - let validFactGroups: string[] = []; - - beforeAll(async () => { - cortiClient = createTestCortiClient(); - validFactGroups = await getValidFactGroups(cortiClient); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - - await cleanupInteractions(cortiClient, createdInteractionIds); - - createdInteractionIds = []; - }); - - const getValidFactGroup = (): string => { - return faker.helpers.arrayElement(validFactGroups); - }; - - describe("should create facts with only required values", () => { - it("should create single fact with only required fields without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.facts.create(interactionId, { - facts: [ - { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create multiple facts with only required fields without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.facts.create(interactionId, { - facts: [ - { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - }, - { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - }, - { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create facts with all source enum values", () => { - it('should create fact with source "core"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.facts.create(interactionId, { - facts: [ - { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - source: "core", - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create fact with source "system"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.facts.create(interactionId, { - facts: [ - { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - source: "system", - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create fact with source "user"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.facts.create(interactionId, { - facts: [ - { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - source: "user", - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - it("should create facts with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.facts.create(interactionId, { - facts: [ - { - text: faker.lorem.paragraph(), - group: getValidFactGroup(), - source: "user", - }, - { - text: faker.lorem.paragraph(), - group: getValidFactGroup(), - source: "system", - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when required fields are missing", () => { - it("should throw error when facts array is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.facts.create(interactionId, {} as any)).rejects.toThrow( - 'Missing required key "facts"', - ); - }); - - it("should throw error when facts array is empty", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.facts.create(interactionId, { facts: [] })).rejects.toThrow(); - }); - - it("should throw error when fact text is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.facts.create(interactionId, { - facts: [ - { - group: getValidFactGroup(), - } as any, - ], - }), - ).rejects.toThrow('Missing required key "text"'); - }); - - it("should throw error when fact group is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.facts.create(interactionId, { - facts: [ - { - text: faker.lorem.sentence(), - } as any, - ], - }), - ).rejects.toThrow('Missing required key "group"'); - }); - - it("should throw error when interaction ID is invalid", async () => { - expect.assertions(1); - - await expect( - cortiClient.facts.create("invalid-uuid", { - facts: [ - { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - }, - ], - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect( - cortiClient.facts.create(faker.string.uuid(), { - facts: [ - { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - }, - ], - }), - ).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/facts.extract.integration.ts b/tests/custom/facts.extract.integration.ts deleted file mode 100644 index 88250c53..00000000 --- a/tests/custom/facts.extract.integration.ts +++ /dev/null @@ -1,304 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.facts.extract", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - describe("should extract facts with only required values", () => { - it("should extract facts with single text context without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.facts.extract({ - context: [ - { - type: "text", - text: faker.lorem.paragraph(), - }, - ], - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME : Temporarily skip this test until multiple contexts are supported - it.skip("should extract facts with multiple text contexts without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.facts.extract({ - context: [ - { - type: "text", - text: faker.lorem.paragraph(), - }, - { - type: "text", - text: faker.lorem.paragraph(), - }, - { - type: "text", - text: faker.lorem.paragraph(), - }, - ], - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should extract facts with different output languages", () => { - it("should extract facts with English output language without errors or warnings", async () => { - expect.assertions(3); - - const result = await cortiClient.facts.extract({ - context: [ - { - type: "text", - text: faker.lorem.paragraph(), - }, - ], - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(result.outputLanguage).toBe("en"); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should extract facts with Danish output language without errors or warnings", async () => { - expect.assertions(3); - - const result = await cortiClient.facts.extract({ - context: [ - { - type: "text", - text: faker.lorem.paragraph(), - }, - ], - outputLanguage: "da", - }); - - expect(result).toBeDefined(); - expect(result.outputLanguage).toBe("da"); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should extract facts with German output language without errors or warnings", async () => { - expect.assertions(3); - - const result = await cortiClient.facts.extract({ - context: [ - { - type: "text", - text: faker.lorem.paragraph(), - }, - ], - outputLanguage: "de", - }); - - expect(result).toBeDefined(); - expect(result.outputLanguage).toBe("de"); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should extract facts with meaningful medical text", () => { - it("should extract facts from medical context text without errors or warnings", async () => { - expect.assertions(2); - - const medicalText = - "Patient presents with chest pain, shortness of breath, and elevated blood pressure of 140/90. Patient has a history of hypertension and diabetes."; - - const result = await cortiClient.facts.extract({ - context: [ - { - type: "text", - text: medicalText, - }, - ], - outputLanguage: "en", - }); - - expect(result.facts).not.toEqual([]); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should extract facts from another medical text without errors or warnings", async () => { - expect.assertions(2); - - const medicalText = "Patient has fever of 38.5 degrees Celsius and cough for 3 days."; - - const result = await cortiClient.facts.extract({ - context: [ - { - type: "text", - text: medicalText, - }, - ], - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should extract facts with minimal text", () => { - it("should handle extraction with minimal text without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.facts.extract({ - context: [ - { - type: "text", - text: faker.lorem.word(), - }, - ], - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should extract facts with long text", () => { - it("should extract facts from long text without errors or warnings", async () => { - expect.assertions(2); - - const longText = faker.lorem.paragraphs(10); - - const result = await cortiClient.facts.extract({ - context: [ - { - type: "text", - text: longText, - }, - ], - outputLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should throw error when required parameters are missing", () => { - it("should throw error when context is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.facts.extract({ - outputLanguage: "en", - } as any), - ).rejects.toThrow('Missing required key "context"'); - }); - - it("should throw error when outputLanguage is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.facts.extract({ - context: [ - { - type: "text", - text: faker.lorem.paragraph(), - }, - ], - } as any), - ).rejects.toThrow('Missing required key "outputLanguage"'); - }); - - it("should throw error when context item is missing type", async () => { - expect.assertions(1); - - await expect( - cortiClient.facts.extract({ - context: [ - { - text: faker.lorem.paragraph(), - }, - ] as any, - outputLanguage: "en", - }), - ).rejects.toThrow(); - }); - - it("should throw error when context item is missing text", async () => { - expect.assertions(1); - - await expect( - cortiClient.facts.extract({ - context: [ - { - type: "text", - }, - ] as any, - outputLanguage: "en", - }), - ).rejects.toThrow(); - }); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when context is empty array", async () => { - expect.assertions(1); - - await expect( - cortiClient.facts.extract({ - context: [], - outputLanguage: "en", - }), - ).rejects.toThrow(); - }); - - it("should throw error when context text is empty", async () => { - expect.assertions(1); - - await expect( - cortiClient.facts.extract({ - context: [ - { - type: "text", - text: "", - }, - ], - outputLanguage: "en", - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when context item has incorrect type value", async () => { - expect.assertions(1); - - await expect( - cortiClient.facts.extract({ - context: [ - { - type: "invalid-type", - text: faker.lorem.paragraph(), - }, - ] as any, - outputLanguage: "en", - }), - ).rejects.toThrow(); - }); - }); -}); diff --git a/tests/custom/facts.factGroupsList.integration.ts b/tests/custom/facts.factGroupsList.integration.ts deleted file mode 100644 index a23a00bc..00000000 --- a/tests/custom/facts.factGroupsList.integration.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { CortiClient } from "../../src"; -import { createTestCortiClient, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.facts.factGroupsList", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - it("should successfully retrieve fact groups list without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.facts.factGroupsList(); - - expect(result.data.length).toBeGreaterThan(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); -}); diff --git a/tests/custom/facts.list.integration.ts b/tests/custom/facts.list.integration.ts deleted file mode 100644 index 87718a43..00000000 --- a/tests/custom/facts.list.integration.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestInteraction, createTestFacts, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.facts.list", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - it("should return empty list when interaction has no facts", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.facts.list(interactionId); - - expect(result.facts.length).toBe(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return facts when interaction has facts", async () => { - expect.assertions(3); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.list(interactionId); - - expect(result.facts.length).toBeGreaterThan(0); - expect(result.facts.some((fact: any) => fact.id === factId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.facts.list("invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.facts.list(faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/facts.update.integration.ts b/tests/custom/facts.update.integration.ts deleted file mode 100644 index 51b11092..00000000 --- a/tests/custom/facts.update.integration.ts +++ /dev/null @@ -1,248 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - createTestFacts, - cleanupInteractions, - setupConsoleWarnSpy, - getValidFactGroups, -} from "./testUtils"; - -describe("cortiClient.facts.update", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - let validFactGroups: string[] = []; - - beforeAll(async () => { - cortiClient = createTestCortiClient(); - validFactGroups = await getValidFactGroups(cortiClient); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - const getValidFactGroup = (): string => { - return faker.helpers.arrayElement(validFactGroups); - }; - - describe("should update fact with minimal fields", () => { - it("should update fact with empty request (no changes) without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, {}); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update fact with only text without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, { - text: faker.lorem.sentence(), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update fact with only group without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, { - group: getValidFactGroup(), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update fact with only isDiscarded without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, { - isDiscarded: true, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should update fact with all source enum values", () => { - it('should update fact with source "core"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, { - source: "core", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update fact with source "system"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, { - source: "system", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update fact with source "user"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, { - source: "user", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should update fact with isDiscarded boolean values", () => { - it("should update fact with isDiscarded set to true without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, { - isDiscarded: true, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update fact with isDiscarded set to false without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, { - isDiscarded: false, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - it("should update fact with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - const result = await cortiClient.facts.update(interactionId, factId, { - text: faker.lorem.sentence(), - group: getValidFactGroup(), - source: "user", - isDiscarded: faker.datatype.boolean(), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - await expect( - cortiClient.facts.update("invalid-uuid", factId, { - text: faker.lorem.sentence(), - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when fact ID is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.facts.update(interactionId, "invalid-uuid", { - text: faker.lorem.sentence(), - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const factIds = await createTestFacts(cortiClient, interactionId, 1); - const factId = factIds[0]; - - await expect( - cortiClient.facts.update(faker.string.uuid(), factId, { - text: faker.lorem.sentence(), - }), - ).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when fact ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.facts.update(interactionId, faker.string.uuid(), { - text: faker.lorem.sentence(), - }), - ).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/interactions.create.integration.ts b/tests/custom/interactions.create.integration.ts deleted file mode 100644 index a5a0bed5..00000000 --- a/tests/custom/interactions.create.integration.ts +++ /dev/null @@ -1,440 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, cleanupInteractions, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.interactions.create", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - describe("should create interaction with only required values", () => { - it("should create interaction with only encounter required fields without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create interaction with patient having only required identifier without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - patient: { - identifier: faker.string.alphanumeric(15), - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create interaction with all status enum values", () => { - it('should create interaction with status "planned"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with status "in-progress"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "in-progress", - type: "first_consultation", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with status "on-hold"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "on-hold", - type: "first_consultation", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with status "completed"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "completed", - type: "first_consultation", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with status "cancelled"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "cancelled", - type: "first_consultation", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with status "deleted"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "deleted", - type: "first_consultation", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create interaction with all type enum values", () => { - it('should create interaction with type "first_consultation"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with type "consultation"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "consultation", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with type "emergency"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "emergency", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with type "inpatient"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "inpatient", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with type "outpatient"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "outpatient", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create interaction with all gender enum values", () => { - it('should create interaction with gender "male"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - patient: { - identifier: faker.string.alphanumeric(15), - gender: "male", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with gender "female"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - patient: { - identifier: faker.string.alphanumeric(15), - gender: "female", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with gender "unknown"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - patient: { - identifier: faker.string.alphanumeric(15), - gender: "unknown", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create interaction with gender "other"', async () => { - expect.assertions(2); - - const result = await cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - patient: { - identifier: faker.string.alphanumeric(15), - gender: "other", - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - it("should create interaction with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const startDate = faker.date.recent(); - const endDate = faker.date.future({ refDate: startDate }); - const birthDate = faker.date.birthdate({ min: 18, max: 100, mode: "age" }); - - const result = await cortiClient.interactions.create({ - assignedUserId: faker.string.uuid(), - encounter: { - identifier: faker.string.alphanumeric(20), - status: "in-progress", - type: "consultation", - title: faker.lorem.sentence(), - period: { - startedAt: startDate, - endedAt: endDate, - }, - }, - patient: { - identifier: faker.string.alphanumeric(15), - name: faker.person.fullName(), - gender: "male", - birthDate: birthDate, - pronouns: faker.helpers.arrayElement(["he/him", "she/her", "they/them"]), - }, - }); - - createdInteractionIds.push(result.interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when required fields are missing", () => { - it("should throw error when encounter is missing", async () => { - expect.assertions(1); - - await expect(cortiClient.interactions.create({} as any)).rejects.toThrow( - 'Missing required key "encounter"', - ); - }); - - it("should throw error when encounter.identifier is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.interactions.create({ - encounter: { - status: "planned", - type: "first_consultation", - } as any, - }), - ).rejects.toThrow('Missing required key "identifier"'); - }); - - it("should throw error when encounter.status is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - type: "first_consultation", - } as any, - }), - ).rejects.toThrow('Missing required key "status"'); - }); - - it("should throw error when encounter.type is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - } as any, - }), - ).rejects.toThrow('Missing required key "type"'); - }); - - it("should throw error when patient.identifier is missing", async () => { - expect.assertions(1); - - await expect( - cortiClient.interactions.create({ - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - patient: { - name: faker.person.fullName(), - } as any, - }), - ).rejects.toThrow('Missing required key "identifier"'); - }); - }); -}); diff --git a/tests/custom/interactions.delete.integration.ts b/tests/custom/interactions.delete.integration.ts deleted file mode 100644 index fda80fc5..00000000 --- a/tests/custom/interactions.delete.integration.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestInteraction, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.interactions.delete", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - it("should successfully delete an existing interaction without errors or warnings", async () => { - expect.assertions(2); - - const createdInteractionIds: string[] = []; - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.delete(interactionId); - - expect(result).toBeUndefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.interactions.delete("invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.interactions.delete(faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/interactions.get.integration.ts b/tests/custom/interactions.get.integration.ts deleted file mode 100644 index 89a118c3..00000000 --- a/tests/custom/interactions.get.integration.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestInteraction, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.interactions.get", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - it("should successfully retrieve an existing interaction without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.get(interactionId); - - expect(result.id).toBe(interactionId); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.interactions.get("invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.interactions.get(faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/interactions.list.integration.ts b/tests/custom/interactions.list.integration.ts deleted file mode 100644 index abd7f088..00000000 --- a/tests/custom/interactions.list.integration.ts +++ /dev/null @@ -1,684 +0,0 @@ -import { CortiClient } from "../../src"; -import { createTestCortiClient, setupConsoleWarnSpy, cleanupInteractions, createTestInteraction } from "./testUtils"; -import { faker } from "@faker-js/faker"; - -describe("cortiClient.interactions.list", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds.length = 0; - }); - - describe("should list interactions with only required values", () => { - it("should return empty result when no interactions exist", async () => { - expect.assertions(3); - - const response = await cortiClient.interactions.list(); - const interactionIds: string[] = []; - - for await (const interaction of response) { - interactionIds.push(interaction.id); - } - - if (interactionIds.length > 0) { - await cleanupInteractions(cortiClient, interactionIds); - } - - const result = await cortiClient.interactions.list(); - - expect(result.data).toEqual([]); - expect(result.hasNextPage()).toBe(false); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return interactions when they exist without errors or warnings", async () => { - expect.assertions(4); - - const interactionId1 = await createTestInteraction(cortiClient, createdInteractionIds); - const interactionId2 = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.list(); - - expect(result.data.length).toBeGreaterThanOrEqual(2); - expect(result.data.some((interaction) => interaction.id === interactionId1)).toBe(true); - expect(result.data.some((interaction) => interaction.id === interactionId2)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("filtering by patient", () => { - it("should return only interactions for specified patient", async () => { - expect.assertions(5); - - const patient1Id = faker.string.alphanumeric(15); - const patient2Id = faker.string.alphanumeric(15); - const patient3Id = faker.string.alphanumeric(15); - - const interaction1Id = await createTestInteraction(cortiClient, createdInteractionIds, { - patient: { identifier: patient1Id }, - }); - - const interaction2Id = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { type: "consultation" }, - patient: { identifier: patient1Id }, - }); - - await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { type: "outpatient" }, - patient: { identifier: patient2Id }, - }); - - await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "in-progress", type: "emergency" }, - patient: { identifier: patient3Id }, - }); - - const result = await cortiClient.interactions.list({ patient: patient1Id }); - - expect(result.data.length).toBe(2); - expect(result.data.every((interaction) => interaction.patient?.identifier === patient1Id)).toBe(true); - expect(result.data.some((interaction) => interaction.id === interaction1Id)).toBe(true); - expect(result.data.some((interaction) => interaction.id === interaction2Id)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return empty result for non-existent patient", async () => { - expect.assertions(3); - - await createTestInteraction(cortiClient, createdInteractionIds, { - patient: { identifier: faker.string.alphanumeric(15) }, - }); - - await createTestInteraction(cortiClient, createdInteractionIds, { - patient: { identifier: faker.string.alphanumeric(15) }, - }); - - const nonExistentPatientId = faker.string.alphanumeric(15); - const result = await cortiClient.interactions.list({ patient: nonExistentPatientId }); - - expect(result.data).toEqual([]); - expect(result.data.length).toBe(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("filtering by encounterStatus", () => { - it("should filter by single encounterStatus string", async () => { - expect.assertions(4); - - const plannedId = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "planned" }, - }); - - await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "in-progress" }, - }); - - await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "completed" }, - }); - - const result = await cortiClient.interactions.list({ encounterStatus: "planned" }); - - expect(result.data.length).toBeGreaterThanOrEqual(1); - expect(result.data.every((interaction) => interaction.encounter?.status === "planned")).toBe(true); - expect(result.data.some((interaction) => interaction.id === plannedId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME Doesn't work on API side https://linear.app/corti/issue/TGT-399/fix-db-code-to-accept-multiple-params-as-per-spec - it.skip("should filter by multiple encounterStatus array", async () => { - expect.assertions(5); - - const plannedId = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "planned" }, - }); - - const inProgressId = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "in-progress" }, - }); - - await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "completed" }, - }); - - await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "cancelled" }, - }); - - const result = await cortiClient.interactions.list({ - encounterStatus: ["planned", "in-progress"], - }); - - expect(result.data.length).toBeGreaterThanOrEqual(2); - expect( - result.data.every((interaction) => - ["planned", "in-progress"].includes(interaction.encounter?.status || ""), - ), - ).toBe(true); - expect(result.data.some((interaction) => interaction.id === plannedId)).toBe(true); - expect(result.data.some((interaction) => interaction.id === inProgressId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should find interactions for all valid status enum values", () => { - it("should find planned interactions", async () => { - expect.assertions(3); - - const plannedId = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "planned" }, - }); - - const result = await cortiClient.interactions.list({ encounterStatus: "planned" }); - - expect(result.data.length).toBeGreaterThanOrEqual(1); - expect(result.data.some((interaction) => interaction.id === plannedId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should find in-progress interactions", async () => { - expect.assertions(3); - - const inProgressId = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "in-progress" }, - }); - - const result = await cortiClient.interactions.list({ encounterStatus: "in-progress" }); - - expect(result.data.length).toBeGreaterThanOrEqual(1); - expect(result.data.some((interaction) => interaction.id === inProgressId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should find on-hold interactions", async () => { - expect.assertions(3); - - const onHoldId = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "on-hold" }, - }); - - const result = await cortiClient.interactions.list({ encounterStatus: "on-hold" }); - - expect(result.data.length).toBeGreaterThanOrEqual(1); - expect(result.data.some((interaction) => interaction.id === onHoldId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should find completed interactions", async () => { - expect.assertions(3); - - const completedId = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "completed" }, - }); - - const result = await cortiClient.interactions.list({ encounterStatus: "completed" }); - - expect(result.data.length).toBeGreaterThanOrEqual(1); - expect(result.data.some((interaction) => interaction.id === completedId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should find cancelled interactions", async () => { - expect.assertions(3); - - const cancelledId = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "cancelled" }, - }); - - const result = await cortiClient.interactions.list({ encounterStatus: "cancelled" }); - - expect(result.data.length).toBeGreaterThanOrEqual(1); - expect(result.data.some((interaction) => interaction.id === cancelledId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should find deleted interactions", async () => { - expect.assertions(3); - - const deletedId = await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "deleted" }, - }); - - const result = await cortiClient.interactions.list({ encounterStatus: "deleted" }); - - expect(result.data.length).toBeGreaterThanOrEqual(1); - expect(result.data.some((interaction) => interaction.id === deletedId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error for invalid encounterStatus", async () => { - expect.assertions(1); - - await createTestInteraction(cortiClient, createdInteractionIds, { - encounter: { status: "planned" }, - }); - - await expect( - cortiClient.interactions.list({ - encounterStatus: "non-existent-status" as any, - }), - ).rejects.toThrow('Expected enum. Received "non-existent-status".'); - }); - }); - - describe("sorting", () => { - it("should sort by default (createdAt desc) when no sort parameters provided", async () => { - expect.assertions(3); - - const firstId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const secondId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const thirdId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.list(); - - const ourInteractions = result.data.filter((interaction) => - [firstId, secondId, thirdId].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(3); - expect(ourInteractions[0].id).toBe(thirdId); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("sort by createdAt", () => { - it("should sort by createdAt desc", async () => { - expect.assertions(4); - - const firstId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const secondId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const thirdId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.list({ - sort: "createdAt", - direction: "desc", - }); - - const ourInteractions = result.data.filter((interaction) => - [firstId, secondId, thirdId].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(3); - expect(ourInteractions[0].id).toBe(thirdId); - expect(ourInteractions[2].id).toBe(firstId); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should sort by createdAt asc", async () => { - expect.assertions(4); - - const firstId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const secondId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const thirdId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.list({ - sort: "createdAt", - direction: "asc", - }); - - const ourInteractions = result.data.filter((interaction) => - [firstId, secondId, thirdId].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(3); - expect(ourInteractions[0].id).toBe(firstId); - expect(ourInteractions[2].id).toBe(thirdId); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should sort by createdAt with default direction (desc) when direction not specified", async () => { - expect.assertions(3); - - const firstId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const secondId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.list({ sort: "createdAt" }); - - const ourInteractions = result.data.filter((interaction) => - [firstId, secondId].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(2); - expect(ourInteractions[0].id).toBe(secondId); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("sort by updatedAt", () => { - it("should sort by updatedAt desc", async () => { - expect.assertions(4); - - const firstId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const secondId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const thirdId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.list({ - sort: "updatedAt", - direction: "desc", - }); - - const ourInteractions = result.data.filter((interaction) => - [firstId, secondId, thirdId].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(3); - expect(ourInteractions[0].id).toBe(thirdId); - expect(ourInteractions[2].id).toBe(firstId); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should sort by updatedAt asc", async () => { - expect.assertions(4); - - const firstId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const secondId = await createTestInteraction(cortiClient, createdInteractionIds); - await new Promise((resolve) => setTimeout(resolve, 100)); - - const thirdId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.list({ - sort: "updatedAt", - direction: "asc", - }); - - const ourInteractions = result.data.filter((interaction) => - [firstId, secondId, thirdId].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(3); - expect(ourInteractions[0].id).toBe(firstId); - expect(ourInteractions[2].id).toBe(thirdId); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("sort by id", () => { - it("should sort by id desc", async () => { - expect.assertions(4); - - const firstId = await createTestInteraction(cortiClient, createdInteractionIds); - const secondId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.list({ - sort: "id", - direction: "desc", - }); - - const ourInteractions = result.data.filter((interaction) => - [firstId, secondId].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(2); - const expectedFirst = firstId > secondId ? firstId : secondId; - const expectedSecond = firstId === expectedFirst ? secondId : firstId; - expect(ourInteractions[0].id).toBe(expectedFirst); - expect(ourInteractions[1].id).toBe(expectedSecond); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should sort by id asc", async () => { - expect.assertions(4); - - const firstId = await createTestInteraction(cortiClient, createdInteractionIds); - const secondId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.list({ - sort: "id", - direction: "asc", - }); - - const ourInteractions = result.data.filter((interaction) => - [firstId, secondId].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(2); - const expectedFirst = firstId < secondId ? firstId : secondId; - const expectedSecond = firstId === expectedFirst ? secondId : firstId; - expect(ourInteractions[0].id).toBe(expectedFirst); - expect(ourInteractions[1].id).toBe(expectedSecond); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("sort by assignedUserId", () => { - it("should sort by assignedUserId desc", async () => { - expect.assertions(4); - - const userA = faker.string.uuid(); - const userB = faker.string.uuid(); - - const interactionA = await createTestInteraction(cortiClient, createdInteractionIds, { - assignedUserId: userA, - }); - - const interactionB = await createTestInteraction(cortiClient, createdInteractionIds, { - assignedUserId: userB, - }); - - const result = await cortiClient.interactions.list({ - sort: "assignedUserId", - direction: "desc", - }); - - const ourInteractions = result.data.filter((interaction) => - [interactionA, interactionB].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(2); - const expectedFirst = userA > userB ? userA : userB; - const expectedSecond = userA === expectedFirst ? userB : userA; - expect(ourInteractions[0].assignedUserId).toBe(expectedFirst); - expect(ourInteractions[1].assignedUserId).toBe(expectedSecond); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should sort by assignedUserId asc", async () => { - expect.assertions(4); - - const userA = faker.string.uuid(); - const userB = faker.string.uuid(); - - const interactionA = await createTestInteraction(cortiClient, createdInteractionIds, { - assignedUserId: userA, - }); - - const interactionB = await createTestInteraction(cortiClient, createdInteractionIds, { - assignedUserId: userB, - }); - - const result = await cortiClient.interactions.list({ - sort: "assignedUserId", - direction: "asc", - }); - - const ourInteractions = result.data.filter((interaction) => - [interactionA, interactionB].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(2); - const expectedFirst = userA < userB ? userA : userB; - const expectedSecond = userA === expectedFirst ? userB : userA; - expect(ourInteractions[0].assignedUserId).toBe(expectedFirst); - expect(ourInteractions[1].assignedUserId).toBe(expectedSecond); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - // FIXME Should work, but return different results every time - describe.skip("sort by patient", () => { - it("should sort by patient desc", async () => { - expect.assertions(4); - - const patientA = "a-" + faker.string.alphanumeric(15); - const patientB = "b-" + faker.string.alphanumeric(15); - - const interactionA = await createTestInteraction(cortiClient, createdInteractionIds, { - patient: { identifier: patientA }, - }); - - const interactionB = await createTestInteraction(cortiClient, createdInteractionIds, { - patient: { identifier: patientB }, - }); - - const result = await cortiClient.interactions.list({ - sort: "patient", - direction: "desc", - }); - - const ourInteractions = result.data.filter((interaction) => - [interactionA, interactionB].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(2); - - const expectedFirst = patientA > patientB ? patientA : patientB; - const expectedSecond = patientA === expectedFirst ? patientB : patientA; - - expect(ourInteractions[0].patient?.identifier).toBe(expectedFirst); - expect(ourInteractions[1].patient?.identifier).toBe(expectedSecond); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should sort by patient asc", async () => { - expect.assertions(4); - - const patientA = "a-" + faker.string.alphanumeric(15); - const patientB = "b-" + faker.string.alphanumeric(15); - - const interactionA = await createTestInteraction(cortiClient, createdInteractionIds, { - patient: { identifier: patientA }, - }); - - const interactionB = await createTestInteraction(cortiClient, createdInteractionIds, { - patient: { identifier: patientB }, - }); - - const result = await cortiClient.interactions.list({ - sort: "patient", - direction: "asc", - }); - - const ourInteractions = result.data.filter((interaction) => - [interactionA, interactionB].includes(interaction.id), - ); - - expect(ourInteractions.length).toBe(2); - - const expectedFirst = patientA < patientB ? patientA : patientB; - const expectedSecond = patientA === expectedFirst ? patientB : patientA; - - expect(ourInteractions[0].patient?.identifier).toBe(expectedFirst); - expect(ourInteractions[1].patient?.identifier).toBe(expectedSecond); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - }); - - describe("pagination", () => { - it("should iterate through all interactions using async iterator", async () => { - expect.assertions(4); - - const createdIds: string[] = []; - for (let i = 0; i < 15; i++) { - const id = await createTestInteraction(cortiClient, createdInteractionIds); - createdIds.push(id); - } - - const response = await cortiClient.interactions.list({ pageSize: 5 }); - const collectedInteractions: string[] = []; - - expect(response.data.length).toBeLessThanOrEqual(5); - - for await (const interaction of response) { - if (createdIds.includes(interaction.id)) { - collectedInteractions.push(interaction.id); - } - } - - expect(collectedInteractions.length).toBe(15); - expect(createdIds.every((id) => collectedInteractions.includes(id))).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should iterate through pages manually using hasNextPage and getNextPage", async () => { - expect.assertions(4); - - const createdIds: string[] = []; - for (let i = 0; i < 12; i++) { - const id = await createTestInteraction(cortiClient, createdInteractionIds); - createdIds.push(id); - } - - let page = await cortiClient.interactions.list({ pageSize: 4 }); - const collectedInteractions: string[] = []; - - expect(page.data.length).toBeLessThanOrEqual(4); - - page.data.forEach((interaction) => { - if (createdIds.includes(interaction.id)) { - collectedInteractions.push(interaction.id); - } - }); - - while (page.hasNextPage()) { - page = await page.getNextPage(); - page.data.forEach((interaction) => { - if (createdIds.includes(interaction.id)) { - collectedInteractions.push(interaction.id); - } - }); - } - - expect(collectedInteractions.length).toBe(12); - expect(createdIds.every((id) => collectedInteractions.includes(id))).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should use default pageSize when not specified", async () => { - expect.assertions(2); - - for (let i = 0; i < 5; i++) { - await createTestInteraction(cortiClient, createdInteractionIds); - } - - const result = await cortiClient.interactions.list(); - - expect(result.data.length).toBeLessThanOrEqual(10); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/tests/custom/interactions.update.integration.ts b/tests/custom/interactions.update.integration.ts deleted file mode 100644 index 64e81dad..00000000 --- a/tests/custom/interactions.update.integration.ts +++ /dev/null @@ -1,370 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, createTestInteraction, cleanupInteractions, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.interactions.update", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - describe("should update interaction with minimal fields", () => { - it("should update interaction with empty request (no changes) without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, {}); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update interaction with only assignedUserId without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - assignedUserId: faker.string.uuid(), - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update interaction with only encounter identifier without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - identifier: faker.string.alphanumeric(20), - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should update interaction with only patient identifier without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - patient: { - identifier: faker.string.alphanumeric(15), - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should update interaction with all status enum values", () => { - it('should update interaction with status "planned"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - status: "planned", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with status "in-progress"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - status: "in-progress", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with status "on-hold"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - status: "on-hold", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with status "completed"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - status: "completed", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with status "cancelled"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - status: "cancelled", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with status "deleted"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - status: "deleted", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should update interaction with all type enum values", () => { - it('should update interaction with type "first_consultation"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - type: "first_consultation", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with type "consultation"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - type: "consultation", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with type "emergency"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - type: "emergency", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with type "inpatient"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - type: "inpatient", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with type "outpatient"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - encounter: { - type: "outpatient", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should update interaction with all gender enum values", () => { - it('should update interaction with gender "male"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - patient: { - identifier: faker.string.alphanumeric(15), - gender: "male", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with gender "female"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - patient: { - identifier: faker.string.alphanumeric(15), - gender: "female", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with gender "unknown"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - patient: { - identifier: faker.string.alphanumeric(15), - gender: "unknown", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should update interaction with gender "other"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.interactions.update(interactionId, { - patient: { - identifier: faker.string.alphanumeric(15), - gender: "other", - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - it("should update interaction with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const startDate = faker.date.recent(); - const endDate = faker.date.future({ refDate: startDate }); - const birthDate = faker.date.birthdate({ min: 18, max: 100, mode: "age" }); - - const result = await cortiClient.interactions.update(interactionId, { - assignedUserId: faker.string.uuid(), - encounter: { - identifier: faker.string.alphanumeric(20), - status: "in-progress", - type: "consultation", - title: faker.lorem.sentence(), - period: { - startedAt: startDate, - endedAt: endDate, - }, - }, - patient: { - identifier: faker.string.alphanumeric(15), - name: faker.person.fullName(), - gender: "male", - birthDate: birthDate, - pronouns: faker.helpers.arrayElement(["he/him", "she/her", "they/them"]), - }, - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid", async () => { - expect.assertions(1); - - await expect( - cortiClient.interactions.update("invalid-uuid", { - assignedUserId: faker.string.uuid(), - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect( - cortiClient.interactions.update(faker.string.uuid(), { - assignedUserId: faker.string.uuid(), - }), - ).rejects.toThrow("Status code: 404"); - }); - }); -}); diff --git a/tests/custom/recordings.delete.integration.ts b/tests/custom/recordings.delete.integration.ts deleted file mode 100644 index 9123bd5d..00000000 --- a/tests/custom/recordings.delete.integration.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - createTestRecording, - setupConsoleWarnSpy, - cleanupInteractions, -} from "./testUtils"; - -describe("cortiClient.recordings.delete", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds.length = 0; - }); - - it("should successfully delete an existing recording without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const result = await cortiClient.recordings.delete(interactionId, recordingId); - - expect(result).toBeUndefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should not throw error when recording ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.recordings.delete(interactionId, faker.string.uuid())).resolves.toBe(undefined); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.delete("invalid-uuid", faker.string.uuid())).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when recording ID is invalid format", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.recordings.delete(interactionId, "invalid-uuid")).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.delete(faker.string.uuid(), faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - - it("should throw error when interaction ID is null", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.delete(null as any, faker.string.uuid())).rejects.toThrow( - "Expected string. Received null.", - ); - }); - - it("should throw error when recording ID is null", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.recordings.delete(interactionId, null as any)).rejects.toThrow( - "Expected string. Received null.", - ); - }); - - it("should throw error when interaction ID is undefined", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.delete(undefined as any, faker.string.uuid())).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - - it("should throw error when recording ID is undefined", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.recordings.delete(interactionId, undefined as any)).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - }); -}); diff --git a/tests/custom/recordings.get.integration.ts b/tests/custom/recordings.get.integration.ts deleted file mode 100644 index f5b92697..00000000 --- a/tests/custom/recordings.get.integration.ts +++ /dev/null @@ -1,174 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createReadStream, readFileSync, createWriteStream } from "fs"; -import { Readable } from "stream"; -import { - createTestCortiClient, - createTestInteraction, - createTestRecording, - cleanupInteractions, - setupConsoleWarnSpy, -} from "./testUtils"; - -describe("cortiClient.recordings.get", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - describe("should get recording from server-side", () => { - it("should get recording using stream() method without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const getResponse = await cortiClient.recordings.get(interactionId, recordingId); - - expect(getResponse).toBeDefined(); - expect(getResponse.bodyUsed).toBe(false); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - - const webStream = getResponse.stream() as ReadableStream; - expect(webStream).toBeInstanceOf(ReadableStream); - }); - - it("should get recording using blob() method without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const getResponse = await cortiClient.recordings.get(interactionId, recordingId); - - expect(getResponse).toBeDefined(); - expect(getResponse.bodyUsed).toBe(false); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - - const blob = await getResponse.blob(); - expect(blob).toBeInstanceOf(Blob); - }); - - it("should get recording using arrayBuffer() method without errors or warnings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const getResponse = await cortiClient.recordings.get(interactionId, recordingId); - - expect(getResponse).toBeDefined(); - expect(getResponse.bodyUsed).toBe(false); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - - const arrayBuffer = await getResponse.arrayBuffer(); - expect(arrayBuffer).toBeInstanceOf(ArrayBuffer); - }); - - it("should verify downloaded file is not corrupted", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const getResponse = await cortiClient.recordings.get(interactionId, recordingId); - - const originalFileBuffer = readFileSync("tests/custom/trouble-breathing.mp3"); - const originalSize = originalFileBuffer.length; - - const downloadedArrayBuffer = await getResponse.arrayBuffer(); - const downloadedSize = downloadedArrayBuffer.byteLength; - - expect(getResponse).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - expect(downloadedSize).toBe(originalSize); - expect(downloadedSize).toBeGreaterThan(0); - }); - }); - - describe("should handle get errors", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.get("invalid-uuid", faker.string.uuid())).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when recording ID is invalid format", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.recordings.get(interactionId, "invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.get(faker.string.uuid(), faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - - it("should throw error when recording ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.recordings.get(interactionId, faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - - it("should throw error when interaction ID is null", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.get(null as any, faker.string.uuid())).rejects.toThrow( - "Expected string. Received null.", - ); - }); - - it("should throw error when recording ID is null", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.recordings.get(interactionId, null as any)).rejects.toThrow( - "Expected string. Received null.", - ); - }); - - it("should throw error when interaction ID is undefined", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.get(undefined as any, faker.string.uuid())).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - - it("should throw error when recording ID is undefined", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.recordings.get(interactionId, undefined as any)).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - }); -}); diff --git a/tests/custom/recordings.list.integration.ts b/tests/custom/recordings.list.integration.ts deleted file mode 100644 index 0f0d881e..00000000 --- a/tests/custom/recordings.list.integration.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - createTestRecording, - setupConsoleWarnSpy, - cleanupInteractions, -} from "./testUtils"; - -describe("cortiClient.recordings.list", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds.length = 0; - }); - - it("should return empty list when interaction has no recordings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.recordings.list(interactionId); - - expect(result.recordings.length).toBe(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return recordings when interaction has recordings", async () => { - expect.assertions(3); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const result = await cortiClient.recordings.list(interactionId); - - expect(result.recordings.length).toBeGreaterThan(0); - expect(result.recordings.includes(recordingId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return multiple recordings when interaction has multiple recordings", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId1 = await createTestRecording(cortiClient, interactionId); - const recordingId2 = await createTestRecording(cortiClient, interactionId); - - const result = await cortiClient.recordings.list(interactionId); - - expect(result.recordings.length).toBeGreaterThanOrEqual(2); - expect(result.recordings.includes(recordingId1)).toBe(true); - expect(result.recordings.includes(recordingId2)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.list("invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.list(faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when interaction ID is null", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.list(null as any)).rejects.toThrow("Expected string. Received null."); - }); - - it("should throw error when interaction ID is undefined", async () => { - expect.assertions(1); - - await expect(cortiClient.recordings.list(undefined as any)).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - }); -}); diff --git a/tests/custom/recordings.upload.integration.ts b/tests/custom/recordings.upload.integration.ts deleted file mode 100644 index cd2b39d8..00000000 --- a/tests/custom/recordings.upload.integration.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createReadStream, readFileSync } from "fs"; -import { createTestCortiClient, createTestInteraction, cleanupInteractions, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.recordings.upload", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - describe("should upload recording from server-side file stream", () => { - it("should upload trouble-breathing.mp3 using createReadStream without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const file = createReadStream("tests/custom/trouble-breathing.mp3", { - autoClose: true, - }); - - const result = await cortiClient.recordings.upload(file, interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should upload trouble-breathing.mp3 using File object without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const fileBuffer = readFileSync("tests/custom/trouble-breathing.mp3"); - - // Create a File object (simulating browser environment) - const file = new File([fileBuffer], "trouble-breathing.mp3", { - type: "audio/mpeg", - }); - - const result = await cortiClient.recordings.upload(file, interactionId); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should handle upload errors", () => { - it("should throw error when uploading to non-existent interaction", async () => { - expect.assertions(1); - - const nonExistentInteractionId = faker.string.uuid(); - const file = createReadStream("tests/custom/trouble-breathing.mp3", { - autoClose: true, - }); - - await expect(cortiClient.recordings.upload(file, nonExistentInteractionId)).rejects.toThrow( - "Status code: 404", - ); - }); - - it("should throw error when uploading with invalid interaction ID format", async () => { - expect.assertions(1); - - const invalidInteractionId = "invalid-uuid-format"; - const file = createReadStream("tests/custom/trouble-breathing.mp3", { - autoClose: true, - }); - - await expect(cortiClient.recordings.upload(file, invalidInteractionId)).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when uploading with null interaction ID", async () => { - expect.assertions(1); - - const file = createReadStream("tests/custom/trouble-breathing.mp3", { - autoClose: true, - }); - - await expect(cortiClient.recordings.upload(file, null as any)).rejects.toThrow( - "Expected string. Received null.", - ); - }); - - it("should throw error when uploading with undefined interaction ID", async () => { - expect.assertions(1); - - const file = createReadStream("tests/custom/trouble-breathing.mp3", { - autoClose: true, - }); - - await expect(cortiClient.recordings.upload(file, undefined as any)).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - }); -}); diff --git a/tests/custom/stream.connect.integration.ts b/tests/custom/stream.connect.integration.ts deleted file mode 100644 index 8bc14a10..00000000 --- a/tests/custom/stream.connect.integration.ts +++ /dev/null @@ -1,569 +0,0 @@ -import { CortiClient } from "../../src/custom/CortiClient"; -import { faker } from "@faker-js/faker"; -import fs from "fs"; -import path from "path"; -import { - createTestCortiClient, - createTestInteraction, - cleanupInteractions, - setupConsoleWarnSpy, - waitForWebSocketMessage, -} from "./testUtils"; - -describe("cortiClient.stream.connect", () => { - let cortiClient: CortiClient; - let createdInteractionIds: string[]; - let consoleWarnSpy: jest.SpyInstance; - let activeSockets: any[] = []; - - beforeAll(async () => { - cortiClient = createTestCortiClient(); - createdInteractionIds = []; - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - activeSockets = []; - }); - - afterEach(async () => { - // Close all active sockets to ensure cleanup - activeSockets.forEach((socket) => { - if (socket && typeof socket.close === "function") { - try { - socket.close(); - } catch (error) { - // Ignore errors during cleanup - } - } - }); - activeSockets = []; - - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - describe("should connect with minimal configuration", () => { - // FIXME Mismatch with types: outputLocale is optional in FactsModeConfig but required in fact - it.skip("should connect with minimal configuration passed to connect", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - ], - }, - mode: { - type: "facts", - }, - }, - }); - activeSockets.push(streamSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { messages, rejectOnWrongMessage: true }); - - expect(streamSocket).toBeDefined(); - expect(streamSocket.socket).toBeDefined(); - expect(streamSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME Mismatch with types: outputLocale is optional in FactsModeConfig but required in fact - it.skip("should connect and send configuration manually on open event", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - }); - activeSockets.push(streamSocket); - - streamSocket.on("open", () => { - streamSocket.sendConfiguration({ - type: "config", - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - ], - }, - mode: { - type: "facts", - }, - }, - }); - }); - - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { rejectOnWrongMessage: true }); - - expect(streamSocket).toBeDefined(); - expect(streamSocket.socket).toBeDefined(); - expect(streamSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should connect with full configuration", () => { - it("should connect with full configuration passed to connect", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - isDiarization: true, - isMultichannel: true, - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "patient", - }, - ], - }, - mode: { - type: "facts", - outputLocale: "en", - }, - }, - }); - activeSockets.push(streamSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { messages, rejectOnWrongMessage: true }); - - expect(streamSocket).toBeDefined(); - expect(streamSocket.socket).toBeDefined(); - expect(streamSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect and send full configuration manually on open event", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - }); - activeSockets.push(streamSocket); - - streamSocket.on("open", () => { - streamSocket.sendConfiguration({ - type: "config", - configuration: { - transcription: { - primaryLanguage: "en", - isDiarization: true, - isMultichannel: true, - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "patient", - }, - ], - }, - mode: { - type: "facts", - outputLocale: "en", - }, - }, - }); - }); - - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { rejectOnWrongMessage: true }); - - expect(streamSocket).toBeDefined(); - expect(streamSocket.socket).toBeDefined(); - expect(streamSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should connect with different participant roles", () => { - it("should connect with doctor role", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - ], - }, - mode: { - type: "facts", - outputLocale: "en" - }, - }, - }); - activeSockets.push(streamSocket); - - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { rejectOnWrongMessage: true }); - - expect(streamSocket).toBeDefined(); - expect(streamSocket.socket).toBeDefined(); - expect(streamSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with patient role", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "patient", - }, - ], - }, - mode: { - type: "facts", - outputLocale: "en" - }, - }, - }); - activeSockets.push(streamSocket); - - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { rejectOnWrongMessage: true }); - - expect(streamSocket).toBeDefined(); - expect(streamSocket.socket).toBeDefined(); - expect(streamSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with multiple role", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "multiple", - }, - ], - }, - mode: { - type: "facts", - outputLocale: "en" - }, - }, - }); - activeSockets.push(streamSocket); - - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { rejectOnWrongMessage: true }); - - expect(streamSocket).toBeDefined(); - expect(streamSocket.socket).toBeDefined(); - expect(streamSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should connect with different mode types", () => { - it("should connect with facts mode", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - ], - }, - mode: { - type: "facts", - outputLocale: "en" - }, - }, - }); - activeSockets.push(streamSocket); - - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { rejectOnWrongMessage: true }); - - expect(streamSocket).toBeDefined(); - expect(streamSocket.socket).toBeDefined(); - expect(streamSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with transcription mode", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - ], - }, - mode: { - type: "transcription", - }, - }, - }); - activeSockets.push(streamSocket); - - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { rejectOnWrongMessage: true }); - - expect(streamSocket).toBeDefined(); - expect(streamSocket.socket).toBeDefined(); - expect(streamSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should handle transcription scenario with audio", () => { - it("should process audio and receive transcription messages", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "patient", - }, - ], - }, - mode: { - type: "transcription", - }, - }, - }); - activeSockets.push(streamSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { messages, rejectOnWrongMessage: true }); - - const audioFilePath = path.join(__dirname, "trouble-breathing.mp3"); - const audioBuffer = fs.readFileSync(audioFilePath); - - for (let i = 0; i < 3; i++) { - const chunk = audioBuffer.subarray(i * 60 * 1024, (i + 1) * 60 * 1024); - streamSocket.sendAudio(chunk); - } - - streamSocket.sendFlush({ type: "flush" }); - - await waitForWebSocketMessage(streamSocket, "transcript", { messages, timeoutMs: 30000 }); - - streamSocket.sendEnd({ type: "end" }); - - await waitForWebSocketMessage(streamSocket, "usage", { messages }); - - await waitForWebSocketMessage(streamSocket, "ENDED", { messages }); - - expect([2, 3]).toContain(streamSocket.socket.readyState); // CLOSING or CLOSED - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME takes too much time to have facts - it.skip("should process audio and receive facts messages", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "patient", - }, - ], - }, - mode: { - type: "facts", - }, - }, - }); - activeSockets.push(streamSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(streamSocket, "CONFIG_ACCEPTED", { messages, rejectOnWrongMessage: true }); - - const audioFilePath = path.join(__dirname, "trouble-breathing.mp3"); - const audioBuffer = fs.readFileSync(audioFilePath); - - for (let i = 0; i < 6; i++) { - const chunk = audioBuffer.subarray(i * 60 * 1024, (i + 1) * 60 * 1024); - streamSocket.sendAudio(chunk); - } - - await waitForWebSocketMessage(streamSocket, "transcript", { messages, timeoutMs: 30000 }); - await waitForWebSocketMessage(streamSocket, "facts", { messages, timeoutMs: 60000 }); - - streamSocket.sendEnd({ type: "end" }); - - await waitForWebSocketMessage(streamSocket, "usage", { messages }); - - await waitForWebSocketMessage(streamSocket, "ENDED", { messages }); - - expect([2, 3]).toContain(streamSocket.socket.readyState); // CLOSING or CLOSED - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should handle configuration errors", () => { - it("should reject invalid configuration", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "invalid_language", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "doctor", - }, - ], - }, - mode: { - type: "transcription", - }, - }, - }); - activeSockets.push(streamSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(streamSocket, "CONFIG_DENIED", { messages, rejectOnWrongMessage: true }); - - expect([2, 3]).toContain(streamSocket.socket.readyState); // CLOSING or CLOSED - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME no message received from WS - it.skip("should reject missing configuration", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - }); - activeSockets.push(streamSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(streamSocket, "CONFIG_MISSING", { - messages, - rejectOnWrongMessage: true, - timeoutMs: 60000, - }); - - expect([2, 3]).toContain(streamSocket.socket.readyState); // CLOSING or CLOSED - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should reject configuration with invalid participant role", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const streamSocket = await cortiClient.stream.connect({ - id: interactionId, - configuration: { - transcription: { - primaryLanguage: "en", - participants: [ - { - channel: faker.number.int({ min: 0, max: 10 }), - role: "invalid_role" as any, - }, - ], - }, - mode: { - type: "transcription", - }, - }, - }); - activeSockets.push(streamSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(streamSocket, "CONFIG_DENIED", { messages, rejectOnWrongMessage: true }); - - expect([2, 3]).toContain(streamSocket.socket.readyState); // CLOSING or CLOSED - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/tests/custom/templates.get.integration.ts b/tests/custom/templates.get.integration.ts deleted file mode 100644 index 62ea1b1a..00000000 --- a/tests/custom/templates.get.integration.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createTestCortiClient, getValidTemplateKeyAndLanguage, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.templates.get", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - describe("should retrieve template with only required values", () => { - it("should successfully retrieve an existing template without errors or warnings", async () => { - expect.assertions(2); - - const templateData = await getValidTemplateKeyAndLanguage(cortiClient); - - const result = await cortiClient.templates.get(templateData.templateKey); - - expect(result.key).toBe(templateData.templateKey); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should return template with section defaultFormatRule", () => { - it("should return section with defaultFormatRule field", async () => { - expect.assertions(3); - - const templateData = await getValidTemplateKeyAndLanguage(cortiClient); - - const result = await cortiClient.templates.get(templateData.templateKey); - const section = result.templateSections[0]?.section; - - expect(section).toBeDefined(); - expect("defaultFormatRule" in section || section.defaultFormatRule === undefined).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return defaultFormatRule with name field if present", async () => { - expect.assertions(2); - - const templateData = await getValidTemplateKeyAndLanguage(cortiClient); - - const result = await cortiClient.templates.get(templateData.templateKey); - const section = result.templateSections[0]?.section; - - if (section.defaultFormatRule) { - expect("name" in section.defaultFormatRule).toBe(true); - } else { - expect(section.defaultFormatRule).toBeUndefined(); - } - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should throw error when required parameters are missing", () => { - it("should throw error when template key is missing", async () => { - expect.assertions(1); - - await expect(cortiClient.templates.get(undefined as any)).rejects.toThrow(); - }); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when template key does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.templates.get(faker.lorem.word())).rejects.toThrow("Status code: 500"); - }); - }); -}); diff --git a/tests/custom/templates.list.integration.ts b/tests/custom/templates.list.integration.ts deleted file mode 100644 index b8446110..00000000 --- a/tests/custom/templates.list.integration.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { CortiClient } from "../../src"; -import { createTestCortiClient, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.templates.list", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - describe("should list templates with only required values", () => { - it("should retrieve templates without parameters without errors or warnings", async () => { - expect.assertions(2); - - const result = await cortiClient.templates.list(); - - expect(result.data.length).toBeGreaterThan(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("language filtering (lang parameter)", () => { - // FIXME Skipped because of https://linear.app/corti/issue/TGT-383/get-templates-endpoint-returns-inconsistent-results - it.skip('should filter templates by single language (lang: "en")', async () => { - expect.assertions(4); - - const unfilteredResult = await cortiClient.templates.list(); - - const filteredResult = await cortiClient.templates.list({ lang: "en" }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(filteredResult.data.length).toBeGreaterThan(0); - - expect(JSON.stringify(unfilteredResult.data)).not.toBe(JSON.stringify(filteredResult.data)); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME Skipped because of https://linear.app/corti/issue/TGT-383/get-templates-endpoint-returns-inconsistent-results - it.skip('should filter templates by multiple languages (lang: ["da", "en"])', async () => { - expect.assertions(5); - - const unfilteredResult = await cortiClient.templates.list(); - const singleLangResult = await cortiClient.templates.list({ lang: "en" }); - const multiLangResult = await cortiClient.templates.list({ lang: ["da", "en"] }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(multiLangResult.data.length).toBeGreaterThan(0); - - expect(JSON.stringify(unfilteredResult.data)).not.toBe(JSON.stringify(multiLangResult.data)); - expect(JSON.stringify(singleLangResult.data)).not.toBe(JSON.stringify(multiLangResult.data)); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("organization filtering (org parameter)", () => { - // FIXME Skipped because of https://linear.app/corti/issue/TGT-383/get-templates-endpoint-returns-inconsistent-results - it.skip('should filter templates by single organization (org: "corti")', async () => { - expect.assertions(3); - - const unfilteredResult = await cortiClient.templates.list(); - - const filteredResult = await cortiClient.templates.list({ org: "corti" }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(filteredResult.data.length).toBeGreaterThan(0); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME Skipped because of https://linear.app/corti/issue/TGT-383/get-templates-endpoint-returns-inconsistent-results - it.skip('should filter templates by multiple organizations (org: ["corti", "another-org"])', async () => { - expect.assertions(3); - - const unfilteredResult = await cortiClient.templates.list(); - const multiOrgResult = await cortiClient.templates.list({ org: ["corti", "another-org"] }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(multiOrgResult.data.length).toBeGreaterThan(0); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return empty or filtered results for non-existent organization", async () => { - expect.assertions(2); - - const filteredResult = await cortiClient.templates.list({ org: "nonexistent-org" }); - - expect(filteredResult.data.length).toBeGreaterThanOrEqual(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("status filtering (status parameter)", () => { - // FIXME Skipped because of https://linear.app/corti/issue/TGT-383/get-templates-endpoint-returns-inconsistent-results - it.skip('should filter templates by single status (status: "published")', async () => { - expect.assertions(4); - - const unfilteredResult = await cortiClient.templates.list(); - - const filteredResult = await cortiClient.templates.list({ status: "published" }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(filteredResult.data.length).toBe(unfilteredResult.data.length); - - expect(JSON.stringify(unfilteredResult.data)).toBe(JSON.stringify(filteredResult.data)); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - // FIXME Skipped because of https://linear.app/corti/issue/TGT-383/get-templates-endpoint-returns-inconsistent-results - it.skip('should filter templates by multiple statuses (status: ["published", "draft"])', async () => { - expect.assertions(4); - - const unfilteredResult = await cortiClient.templates.list(); - const multiStatusResult = await cortiClient.templates.list({ status: ["published", "draft"] }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(multiStatusResult.data.length).toBeGreaterThanOrEqual(unfilteredResult.data.length); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return empty or filtered results for non-existent status", async () => { - expect.assertions(2); - - const filteredResult = await cortiClient.templates.list({ status: "nonexistent-status" }); - - expect(filteredResult.data.length).toBeGreaterThanOrEqual(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - // FIXME Skipped because of https://linear.app/corti/issue/TGT-383/get-templates-endpoint-returns-inconsistent-results - describe.skip("combined filtering (lang, org, and status parameters)", () => { - it("should filter templates using all parameters together", async () => { - expect.assertions(4); - - const unfilteredResult = await cortiClient.templates.list(); - const combinedResult = await cortiClient.templates.list({ - lang: ["da", "en"], - org: ["corti", "another-org"], - status: ["published", "draft"], - }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(combinedResult.data.length).toBeGreaterThan(0); - - expect(JSON.stringify(unfilteredResult.data)).not.toBe(JSON.stringify(combinedResult.data)); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/tests/custom/templates.sectionList.integration.ts b/tests/custom/templates.sectionList.integration.ts deleted file mode 100644 index a501de77..00000000 --- a/tests/custom/templates.sectionList.integration.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { CortiClient } from "../../src"; -import { createTestCortiClient, setupConsoleWarnSpy } from "./testUtils"; - -describe("cortiClient.templates.sectionList", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(() => { - consoleWarnSpy.mockRestore(); - }); - - it("should retrieve template sections without parameters", async () => { - expect.assertions(2); - - const result = await cortiClient.templates.sectionList(); - - expect(result.data.length).toBeGreaterThan(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("language filtering (lang parameter)", () => { - it('should filter template sections by single language (lang: "en")', async () => { - expect.assertions(4); - - const unfilteredResult = await cortiClient.templates.sectionList(); - - const filteredResult = await cortiClient.templates.sectionList({ lang: "en" }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(filteredResult.data.length).toBeGreaterThan(0); - - expect(JSON.stringify(unfilteredResult.data)).not.toBe(JSON.stringify(filteredResult.data)); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should filter template sections by multiple languages (lang: ["da", "en"])', async () => { - expect.assertions(5); - - const unfilteredResult = await cortiClient.templates.sectionList(); - const singleLangResult = await cortiClient.templates.sectionList({ lang: "en" }); - const multiLangResult = await cortiClient.templates.sectionList({ lang: ["da", "en"] }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(multiLangResult.data.length).toBeGreaterThan(0); - - expect(JSON.stringify(unfilteredResult.data)).not.toBe(JSON.stringify(multiLangResult.data)); - expect(JSON.stringify(singleLangResult.data)).not.toBe(JSON.stringify(multiLangResult.data)); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("organization filtering (org parameter)", () => { - it('should filter template sections by single organization (org: "corti")', async () => { - expect.assertions(3); - - const unfilteredResult = await cortiClient.templates.sectionList(); - - const filteredResult = await cortiClient.templates.sectionList({ org: "corti" }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(filteredResult.data.length).toBeGreaterThan(0); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should filter template sections by multiple organizations (org: ["corti", "another-org"])', async () => { - expect.assertions(3); - - const unfilteredResult = await cortiClient.templates.sectionList(); - const multiOrgResult = await cortiClient.templates.sectionList({ org: ["corti", "another-org"] }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(multiOrgResult.data.length).toBeGreaterThan(0); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return empty results for non-existent organization", async () => { - expect.assertions(2); - - const filteredResult = await cortiClient.templates.sectionList({ org: "nonexistent-org" }); - - expect(filteredResult.data.length).toBeGreaterThanOrEqual(0); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("combined filtering (lang and org parameters)", () => { - it("should filter template sections using both language and organization parameters", async () => { - expect.assertions(4); - - const unfilteredResult = await cortiClient.templates.sectionList(); - const combinedResult = await cortiClient.templates.sectionList({ - lang: ["da", "en"], - org: ["corti", "another-org"], - }); - - expect(unfilteredResult.data.length).toBeGreaterThan(0); - expect(combinedResult.data.length).toBeGreaterThan(0); - - expect(JSON.stringify(unfilteredResult.data)).not.toBe(JSON.stringify(combinedResult.data)); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/tests/custom/testUtils.ts b/tests/custom/testUtils.ts deleted file mode 100644 index bf295a5b..00000000 --- a/tests/custom/testUtils.ts +++ /dev/null @@ -1,352 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { createReadStream } from "fs"; -import { StreamSocket } from "../../src/custom/CustomStreamSocket"; -import { TranscribeSocket } from "../../src/custom/CustomTranscribeSocket"; - -/** - * Creates a CortiClient instance configured for testing - */ -export function createTestCortiClient(): CortiClient { - if ( - !process.env.CORTI_ENVIRONMENT || - !process.env.CORTI_TENANT_NAME || - !process.env.CORTI_CLIENT_ID || - !process.env.CORTI_CLIENT_SECRET - ) { - throw new Error("Missing required environment variables for CortiClient"); - } - - return new CortiClient({ - environment: process.env.CORTI_ENVIRONMENT, - tenantName: process.env.CORTI_TENANT_NAME, - auth: { - clientId: process.env.CORTI_CLIENT_ID, - clientSecret: process.env.CORTI_CLIENT_SECRET, - }, - }); -} - -/** - * Creates a test interaction using faker data - * Optionally pushes the created interactionId to the provided array - * Allows overriding default interaction data - */ -export async function createTestInteraction( - cortiClient: CortiClient, - createdInteractionIds?: string[], - overrideData?: any, -): Promise { - const defaultData = { - encounter: { - identifier: faker.string.alphanumeric(20), - status: "planned", - type: "first_consultation", - }, - }; - - const interactionData = overrideData - ? { - ...defaultData, - ...overrideData, - encounter: overrideData.encounter - ? { ...defaultData.encounter, ...overrideData.encounter } - : defaultData.encounter, - } - : defaultData; - - const interaction = await cortiClient.interactions.create(interactionData); - - if (createdInteractionIds) { - createdInteractionIds.push(interaction.interactionId); - } - - await pause(); - - return interaction.interactionId; -} - -/** - * Cleans up interactions by deleting them (this will cascade delete all associated resources) - */ -export async function cleanupInteractions(cortiClient: CortiClient, interactionIds: string[]): Promise { - for (const interactionId of interactionIds) { - try { - await cortiClient.interactions.delete(interactionId); - } catch (error) { - console.warn(`Failed to clean up interaction ${interactionId}:`, error); - } - } -} - -/** - * Sets up console.warn spy for tests - */ -export function setupConsoleWarnSpy(): jest.SpyInstance { - return jest.spyOn(console, "warn").mockImplementation(() => {}); -} - -/** - * Adds a pause to ensure backend processing is complete - * @param ms - Duration to pause in milliseconds (default: 1000ms) - */ -export function pause(ms: number = 1000): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -/** - * Gets valid fact groups from the API, with fallback to 'other' - */ -export async function getValidFactGroups(cortiClient: CortiClient): Promise { - const factGroupsResponse = await cortiClient.facts.factGroupsList(); - const factGroups = factGroupsResponse.data - .map((factGroup) => factGroup.key) - .filter((key): key is string => key !== undefined); - - return [...new Set(factGroups)]; -} - -export async function getValidSectionKeys(cortiClient: CortiClient): Promise { - const sectionsResponse = await cortiClient.templates.sectionList(); - const sectionKeys = sectionsResponse.data - .map((section) => section.key) - .filter((key): key is string => key !== undefined); - - return [...new Set(sectionKeys)]; -} - -/** - * Gets a valid template key and output language from the API for document tests - */ -export async function getValidTemplateKeyAndLanguage( - cortiClient: CortiClient, -): Promise<{ templateKey: string; outputLanguage: string }> { - const templatesList = await cortiClient.templates.list(); - const first = templatesList.data?.[0]; - - if (!first) { - throw new Error("No templates available for testing"); - } - - const outputLanguage = first.translations?.[0]?.languageId || "en"; - - return { templateKey: first.key, outputLanguage }; -} - -/** - * Creates test facts using faker data and returns their IDs - * Used for testing facts.update functionality - */ -export async function createTestFacts( - cortiClient: CortiClient, - interactionId: string, - count: number = 1, -): Promise { - const validFactGroups = await getValidFactGroups(cortiClient); - - const factsToCreate = Array.from({ length: count }, () => ({ - text: faker.lorem.sentence(), - group: faker.helpers.arrayElement(validFactGroups), - })); - - const response = await cortiClient.facts.create(interactionId, { - facts: factsToCreate, - }); - - const factIds = response.facts.map((fact) => fact.id).filter((id): id is string => id !== undefined); - - await pause(); - - return factIds; -} - -/** - * Creates a single test document using faker data and returns its ID - * Used for testing documents functionality - */ -export async function createTestDocument(cortiClient: CortiClient, interactionId: string): Promise { - const templateData = await getValidTemplateKeyAndLanguage(cortiClient); - - const response = await cortiClient.documents.create(interactionId, { - context: [ - { - type: "string", - data: faker.lorem.paragraph(), - }, - ], - templateKey: templateData.templateKey, - outputLanguage: templateData.outputLanguage, - }); - - if (!response.id) { - throw new Error("Document creation failed - no ID returned."); - } - - await pause(); - - return response.id; -} - -/** - * Creates a test recording using the trouble-breathing.mp3 file - * Optionally pushes the created recordingId to the provided array - * Used for testing recordings functionality - */ -export async function createTestRecording( - cortiClient: CortiClient, - interactionId: string, - createdRecordingIds?: string[], -): Promise { - const uploadFile = createReadStream("tests/custom/trouble-breathing.mp3", { - autoClose: true, - }); - - const uploadResult = await cortiClient.recordings.upload(uploadFile, interactionId); - - if (createdRecordingIds) { - createdRecordingIds.push(uploadResult.recordingId); - } - - await pause(); - - return uploadResult.recordingId; -} - -/** - * Creates a test transcript for a given interaction and recording - * Used for testing transcripts functionality - * Note: This requires a valid language/model combination to work - */ -export async function createTestTranscript( - cortiClient: CortiClient, - interactionId: string, - recordingId: string, -): Promise { - // Note: Using a supported language/model combination - // This may need to be updated based on actual supported languages - const transcriptResult = await cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - }); - - if (!transcriptResult.id) { - throw new Error("Transcript creation failed - no ID returned."); - } - - await pause(); - - return transcriptResult.id; -} - -/** - * Creates a promise that waits for a specific WebSocket message type - * Used for testing WebSocket message handling in stream tests - */ -export function waitForWebSocketMessage( - streamSocket: StreamSocket | TranscribeSocket, - expectedMessageType: string, - options: { - messages?: any[]; - rejectOnWrongMessage?: boolean; - timeoutMs?: number; - } = {}, -): Promise { - return new Promise((resolve, reject) => { - const { messages = [], rejectOnWrongMessage = false, timeoutMs = 10000 } = options; - - const timeout = setTimeout(() => { - reject(new Error(`Timeout waiting for message type: ${expectedMessageType}`)); - }, timeoutMs); - - // Check if message already exists in the array - if (messages.some((msg: any) => msg.type === expectedMessageType)) { - clearTimeout(timeout); - resolve(); - return; - } - - const messageHandler = (data: any) => { - console.log("incoming message", data); - - // Add message to the array - messages.push(data); - - if (data.type === expectedMessageType) { - clearTimeout(timeout); - resolve(); - } else if (rejectOnWrongMessage) { - clearTimeout(timeout); - reject(new Error(`Unexpected message type: ${data.type}, expected: ${expectedMessageType}`)); - } - }; - - streamSocket.on("message", messageHandler); - - streamSocket.on("error", (error: any) => { - clearTimeout(timeout); - reject(new Error(`WebSocket error: ${error.message}`)); - }); - }); -} - -/** - * Creates a test agent using faker data and returns its ID - * Optionally pushes the created agentId to the provided array - * Used for testing agents functionality - */ -export async function createTestAgent(cortiClient: CortiClient, createdAgentIds?: string[]): Promise { - const agent = await cortiClient.agents.create({ - name: faker.lorem.words(3), - description: faker.lorem.sentence(), - }); - - if (!agent.id) { - throw new Error("Agent creation failed - no ID returned."); - } - - if (createdAgentIds) { - createdAgentIds.push(agent.id); - } - - await pause(); - - return agent; -} - -/** - * Cleans up agents by deleting them - */ -export async function cleanupAgents(cortiClient: CortiClient, agentIds: string[]): Promise { - for (const agentId of agentIds) { - try { - console.log(`Cleanup agent ${agentId}`); - await cortiClient.agents.delete(agentId); - } catch (error) { - console.warn(`Failed to clean up agent ${agentId}:`, error); - } - } -} - -/** - * Sends a test message to an agent and returns the response - * Used for testing agents.messageSend functionality - */ -export async function sendTestMessage(cortiClient: CortiClient, agentId: string, messageText?: string) { - const message = await cortiClient.agents.messageSend(agentId, { - message: { - role: "user", - parts: [ - { - kind: "text", - text: messageText || faker.lorem.sentence(), - }, - ], - messageId: faker.string.uuid(), - kind: "message", - }, - }); - - await pause(); - - return message; -} diff --git a/tests/custom/transcribe.connect.integration.ts b/tests/custom/transcribe.connect.integration.ts deleted file mode 100644 index e3f0ec6d..00000000 --- a/tests/custom/transcribe.connect.integration.ts +++ /dev/null @@ -1,444 +0,0 @@ -import { CortiClient } from "../../src/custom/CortiClient"; -import { faker } from "@faker-js/faker"; -import * as fs from "fs"; -import * as path from "path"; -import { createTestCortiClient, setupConsoleWarnSpy, waitForWebSocketMessage } from "./testUtils"; - -describe("cortiClient.transcribe.connect", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let activeSockets: any[] = []; - - beforeAll(async () => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - activeSockets = []; - }); - - afterEach(() => { - // Close all active sockets to ensure cleanup - activeSockets.forEach((socket) => { - if (socket && typeof socket.close === "function") { - try { - socket.close(); - } catch (error) { - // Ignore errors during cleanup - } - } - }); - activeSockets = []; - }); - - describe("should connect with minimal configuration", () => { - it("should connect with minimal configuration passed to connect", async () => { - expect.assertions(4); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect and send configuration manually on open event", async () => { - expect.assertions(4); - - const transcribeSocket = await cortiClient.transcribe.connect(); - activeSockets.push(transcribeSocket); - - transcribeSocket.on("open", () => { - transcribeSocket.sendConfiguration({ - type: "config", - configuration: { - primaryLanguage: "en", - }, - }); - }); - - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { rejectOnWrongMessage: true }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should connect with full configuration", () => { - it("should connect with full configuration passed to connect", async () => { - expect.assertions(4); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - interimResults: true, - spokenPunctuation: true, - automaticPunctuation: true, - commands: [ - { - id: faker.string.alphanumeric(8), - phrases: ["stop recording", "end session"], - }, - ], - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect and send full configuration manually on open event", async () => { - expect.assertions(4); - - const transcribeSocket = await cortiClient.transcribe.connect(); - activeSockets.push(transcribeSocket); - - transcribeSocket.on("open", () => { - transcribeSocket.sendConfiguration({ - type: "config", - configuration: { - primaryLanguage: "en", - interimResults: true, - spokenPunctuation: true, - automaticPunctuation: true, - commands: [ - { - id: faker.string.alphanumeric(8), - phrases: ["stop recording", "end session"], - }, - ], - }, - }); - }); - - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { rejectOnWrongMessage: true }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with full configuration including command variables", async () => { - expect.assertions(4); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - interimResults: true, - spokenPunctuation: true, - automaticPunctuation: true, - commands: [ - { - id: faker.string.alphanumeric(8), - phrases: ["set status to", "change status to"], - variables: [ - { - key: "status", - type: "enum", - enum: ["active", "inactive", "pending", "completed"], - }, - ], - }, - ], - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); // OPEN - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should handle transcription scenario with audio", () => { - it("should process audio and receive transcription messages", async () => { - expect.assertions(1); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - const audioFilePath = path.join(__dirname, "trouble-breathing.mp3"); - const audioBuffer = fs.readFileSync(audioFilePath); - - for (let i = 0; i < 3; i++) { - const chunk = audioBuffer.subarray(i * 60 * 1024, (i + 1) * 60 * 1024); - transcribeSocket.sendAudio(chunk); - } - - await waitForWebSocketMessage(transcribeSocket, "transcript", { messages, timeoutMs: 30000 }); - - transcribeSocket.sendEnd({ type: "end" }); - - // FIXME skip this part of the test since it takes too long on production to get these messages - // await waitForWebSocketMessage(transcribeSocket, 'usage', { messages }); - // - // await waitForWebSocketMessage(transcribeSocket, 'ended', { messages }); - - // expect([2, 3]).toContain(transcribeSocket.socket.readyState); // CLOSING or CLOSED - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should handle configuration errors", () => { - it("should reject invalid configuration", async () => { - expect.assertions(2); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "invalid_language", - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_DENIED", { messages, rejectOnWrongMessage: true }); - - expect([2, 3]).toContain(transcribeSocket.socket.readyState); // CLOSING or CLOSED - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should reject missing configuration", async () => { - expect.assertions(1); - - const transcribeSocket = await cortiClient.transcribe.connect(); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_TIMEOUT", { - messages, - rejectOnWrongMessage: true, - timeoutMs: 60000, - }); - - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should reject configuration with invalid command", async () => { - expect.assertions(2); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - commands: [ - { - id: "", - phrases: [], - } as any, - ], - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_DENIED", { messages, rejectOnWrongMessage: true }); - - expect([2, 3]).toContain(transcribeSocket.socket.readyState); // CLOSING or CLOSED - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should connect with formatting configuration", () => { - it("should connect with dates formatting", async () => { - expect.assertions(3); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - formatting: { dates: "long_text" }, - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with times formatting", async () => { - expect.assertions(3); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - formatting: { times: "h12" }, - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with numbers formatting", async () => { - expect.assertions(3); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - formatting: { numbers: "numerals" }, - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with measurements formatting", async () => { - expect.assertions(3); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - formatting: { measurements: "abbreviated" }, - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with numeric ranges formatting", async () => { - expect.assertions(3); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - formatting: { numericRanges: "numerals" }, - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with ordinals formatting", async () => { - expect.assertions(3); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - formatting: { ordinals: "numerals" }, - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should connect with full formatting configuration", async () => { - expect.assertions(3); - - const transcribeSocket = await cortiClient.transcribe.connect({ - configuration: { - primaryLanguage: "en", - formatting: { - dates: "long_text", - times: "h12", - numbers: "numerals", - measurements: "abbreviated", - numericRanges: "numerals", - ordinals: "numerals", - }, - }, - }); - activeSockets.push(transcribeSocket); - - const messages: any[] = []; - await waitForWebSocketMessage(transcribeSocket, "CONFIG_ACCEPTED", { - messages, - rejectOnWrongMessage: true, - }); - - expect(transcribeSocket).toBeDefined(); - expect(transcribeSocket.socket.readyState).toBe(1); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); -}); diff --git a/tests/custom/transcripts.create.integration.ts b/tests/custom/transcripts.create.integration.ts deleted file mode 100644 index 620f669e..00000000 --- a/tests/custom/transcripts.create.integration.ts +++ /dev/null @@ -1,337 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - createTestRecording, - cleanupInteractions, - setupConsoleWarnSpy, -} from "./testUtils"; - -describe("cortiClient.transcripts.create", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - describe("should create transcript with only required values", () => { - it("should create transcript with only required fields without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const result = await cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should create transcript with all participant role enum values", () => { - it('should create transcript with participant role "doctor"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const result = await cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - participants: [ - { - channel: 0, - role: "doctor", - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create transcript with participant role "patient"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const result = await cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - participants: [ - { - channel: 0, - role: "patient", - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it('should create transcript with participant role "multiple"', async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const result = await cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - participants: [ - { - channel: 0, - role: "multiple", - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should create transcript with multiple participants", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const result = await cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - participants: [ - { - channel: 0, - role: "doctor", - }, - { - channel: 1, - role: "patient", - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - it("should create transcript with all optional parameters without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - const isMultichannel = faker.datatype.boolean(); - const diarize = isMultichannel ? faker.datatype.boolean() : false; // diarize can only be true if isMultichannel is true - - const result = await cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - isDictation: faker.datatype.boolean(), - isMultichannel, - diarize, - participants: [ - { - channel: faker.number.int({ min: 0, max: 1 }), - role: faker.helpers.arrayElement(["doctor", "patient", "multiple"]), - }, - ], - }); - - expect(result).toBeDefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when required fields are missing", () => { - it("should throw error when recordingId is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.transcripts.create(interactionId, { - primaryLanguage: "en", - } as any), - ).rejects.toThrow('Missing required key "recordingId"'); - }); - - it("should throw error when primaryLanguage is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - await expect( - cortiClient.transcripts.create(interactionId, { - recordingId, - } as any), - ).rejects.toThrow('Missing required key "primaryLanguage"'); - }); - - it("should throw error when participant channel is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - await expect( - cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - participants: [ - { - role: "doctor", - } as any, - ], - }), - ).rejects.toThrow('Missing required key "channel"'); - }); - - it("should throw error when participant role is missing", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - await expect( - cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - participants: [ - { - channel: 0, - } as any, - ], - }), - ).rejects.toThrow('Missing required key "role"'); - }); - - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - const recordingId = faker.string.uuid(); - - await expect( - cortiClient.transcripts.create("invalid-uuid", { - recordingId, - primaryLanguage: "en", - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - const recordingId = faker.string.uuid(); - - await expect( - cortiClient.transcripts.create(faker.string.uuid(), { - recordingId, - primaryLanguage: "en", - }), - ).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when recordingId does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.transcripts.create(interactionId, { - recordingId: faker.string.uuid(), - primaryLanguage: "en", - }), - ).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when recordingId is invalid format", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect( - cortiClient.transcripts.create(interactionId, { - recordingId: "invalid-uuid", - primaryLanguage: "en", - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when primaryLanguage is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - await expect( - cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "invalid-language", - }), - ).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when participant role is invalid", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - await expect( - cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - participants: [ - { - channel: 0, - role: "invalid-role" as any, - }, - ], - }), - ).rejects.toThrow('Expected enum. Received "invalid-role"'); - }); - - it("should throw error when diarize is true but isMultichannel is false", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - await expect( - cortiClient.transcripts.create(interactionId, { - recordingId, - primaryLanguage: "en", - isMultichannel: false, - diarize: true, - participants: [ - { - channel: faker.number.int({ min: 0, max: 1 }), - role: faker.helpers.arrayElement(["doctor", "patient", "multiple"]), - }, - ], - }), - ).rejects.toThrow("BadRequestError"); - }); - }); -}); diff --git a/tests/custom/transcripts.delete.integration.ts b/tests/custom/transcripts.delete.integration.ts deleted file mode 100644 index ed0f6da1..00000000 --- a/tests/custom/transcripts.delete.integration.ts +++ /dev/null @@ -1,117 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - createTestRecording, - createTestTranscript, - setupConsoleWarnSpy, - cleanupInteractions, -} from "./testUtils"; - -describe("cortiClient.transcripts.delete", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds.length = 0; - }); - - it("should successfully delete an existing transcript without errors or warnings", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - const transcriptId = await createTestTranscript(cortiClient, interactionId, recordingId); - - const result = await cortiClient.transcripts.delete(interactionId, transcriptId); - - expect(result).toBeUndefined(); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.delete("invalid-uuid", faker.string.uuid())).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when transcript ID is invalid format", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.transcripts.delete(interactionId, "invalid-uuid")).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.delete(faker.string.uuid(), faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - - it("should throw error when interaction ID is null", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.delete(null as any, faker.string.uuid())).rejects.toThrow( - "Expected string. Received null.", - ); - }); - - it("should throw error when transcript ID is null", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.transcripts.delete(interactionId, null as any)).rejects.toThrow( - "Expected string. Received null.", - ); - }); - - it("should throw error when interaction ID is undefined", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.delete(undefined as any, faker.string.uuid())).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - - it("should throw error when transcript ID is undefined", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.transcripts.delete(interactionId, undefined as any)).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - - it("should throw error when transcript ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.transcripts.delete(interactionId, faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - }); -}); diff --git a/tests/custom/transcripts.get.integration.ts b/tests/custom/transcripts.get.integration.ts deleted file mode 100644 index 02ccd83d..00000000 --- a/tests/custom/transcripts.get.integration.ts +++ /dev/null @@ -1,119 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - createTestRecording, - createTestTranscript, - cleanupInteractions, - setupConsoleWarnSpy, -} from "./testUtils"; - -describe("cortiClient.transcripts.get", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - let createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - createdInteractionIds = []; - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds = []; - }); - - it("should successfully retrieve an existing transcript without errors or warnings", async () => { - expect.assertions(3); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - const transcriptId = await createTestTranscript(cortiClient, interactionId, recordingId); - - const result = await cortiClient.transcripts.get(interactionId, transcriptId); - - expect(result).toBeDefined(); - expect(result.id).toBe(transcriptId); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("should handle get errors", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.get("invalid-uuid", faker.string.uuid())).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when transcript ID is invalid format", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.transcripts.get(interactionId, "invalid-uuid")).rejects.toThrow( - "Status code: 400", - ); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.get(faker.string.uuid(), faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - - it("should throw error when transcript ID does not exist", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.transcripts.get(interactionId, faker.string.uuid())).rejects.toThrow( - "Status code: 404", - ); - }); - - it("should throw error when interaction ID is null", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.get(null as any, faker.string.uuid())).rejects.toThrow( - "Expected string. Received null.", - ); - }); - - it("should throw error when transcript ID is null", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.transcripts.get(interactionId, null as any)).rejects.toThrow( - "Expected string. Received null.", - ); - }); - - it("should throw error when interaction ID is undefined", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.get(undefined as any, faker.string.uuid())).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - - it("should throw error when transcript ID is undefined", async () => { - expect.assertions(1); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - await expect(cortiClient.transcripts.get(interactionId, undefined as any)).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - }); -}); diff --git a/tests/custom/transcripts.list.integration.ts b/tests/custom/transcripts.list.integration.ts deleted file mode 100644 index 597d97eb..00000000 --- a/tests/custom/transcripts.list.integration.ts +++ /dev/null @@ -1,147 +0,0 @@ -import { CortiClient } from "../../src"; -import { faker } from "@faker-js/faker"; -import { - createTestCortiClient, - createTestInteraction, - createTestRecording, - createTestTranscript, - setupConsoleWarnSpy, - cleanupInteractions, -} from "./testUtils"; - -describe("cortiClient.transcripts.list", () => { - let cortiClient: CortiClient; - let consoleWarnSpy: jest.SpyInstance; - const createdInteractionIds: string[] = []; - - beforeAll(() => { - cortiClient = createTestCortiClient(); - }); - - beforeEach(() => { - consoleWarnSpy = setupConsoleWarnSpy(); - }); - - afterEach(async () => { - consoleWarnSpy.mockRestore(); - await cleanupInteractions(cortiClient, createdInteractionIds); - createdInteractionIds.length = 0; - }); - - it("should return empty list when interaction has no transcripts", async () => { - expect.assertions(2); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - - const result = await cortiClient.transcripts.list(interactionId); - - expect(result.transcripts).toBe(null); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return transcripts when interaction has transcripts", async () => { - expect.assertions(3); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - const transcriptId = await createTestTranscript(cortiClient, interactionId, recordingId); - - const result = await cortiClient.transcripts.list(interactionId); - - expect(result.transcripts?.length || 0).toBeGreaterThan(0); - expect(result.transcripts?.some((transcript) => transcript.id === transcriptId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return multiple transcripts when interaction has multiple transcripts", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId1 = await createTestRecording(cortiClient, interactionId); - const recordingId2 = await createTestRecording(cortiClient, interactionId); - const transcriptId1 = await createTestTranscript(cortiClient, interactionId, recordingId1); - const transcriptId2 = await createTestTranscript(cortiClient, interactionId, recordingId2); - - const result = await cortiClient.transcripts.list(interactionId); - - expect(result.transcripts?.length || 0).toBeGreaterThanOrEqual(2); - expect(result.transcripts?.some((transcript) => transcript.id === transcriptId1)).toBe(true); - expect(result.transcripts?.some((transcript) => transcript.id === transcriptId2)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - describe("full parameter tests", () => { - it("should return transcripts with full parameter set to true", async () => { - expect.assertions(3); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - const transcriptId = await createTestTranscript(cortiClient, interactionId, recordingId); - - const result = await cortiClient.transcripts.list(interactionId, { full: true }); - - expect(result.transcripts?.length || 0).toBeGreaterThan(0); - expect(result.transcripts?.some((transcript) => transcript.id === transcriptId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return transcripts with full parameter set to false", async () => { - expect.assertions(3); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - const transcriptId = await createTestTranscript(cortiClient, interactionId, recordingId); - - const result = await cortiClient.transcripts.list(interactionId, { full: false }); - - expect(result.transcripts?.length || 0).toBeGreaterThan(0); - expect(result.transcripts?.some((transcript) => transcript.id === transcriptId)).toBe(true); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - - it("should return different responses when full parameter is true vs false", async () => { - expect.assertions(4); - - const interactionId = await createTestInteraction(cortiClient, createdInteractionIds); - const recordingId = await createTestRecording(cortiClient, interactionId); - - await createTestTranscript(cortiClient, interactionId, recordingId); - - const resultFull = await cortiClient.transcripts.list(interactionId, { full: true }); - const resultBasic = await cortiClient.transcripts.list(interactionId, { full: false }); - - expect(resultFull.transcripts?.length || 0).toBeGreaterThan(0); - expect(resultBasic.transcripts?.length || 0).toBeGreaterThan(0); - expect(JSON.stringify(resultFull)).not.toBe(JSON.stringify(resultBasic)); - expect(consoleWarnSpy).not.toHaveBeenCalled(); - }); - }); - - describe("should throw error when invalid parameters are provided", () => { - it("should throw error when interaction ID is invalid format", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.list("invalid-uuid")).rejects.toThrow("Status code: 400"); - }); - - it("should throw error when interaction ID does not exist", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.list(faker.string.uuid())).rejects.toThrow("Status code: 404"); - }); - - it("should throw error when interaction ID is null", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.list(null as any)).rejects.toThrow("Expected string. Received null."); - }); - - it("should throw error when interaction ID is undefined", async () => { - expect.assertions(1); - - await expect(cortiClient.transcripts.list(undefined as any)).rejects.toThrow( - "Expected string. Received undefined.", - ); - }); - }); -}); diff --git a/tests/custom/trouble-breathing.mp3 b/tests/custom/trouble-breathing.mp3 deleted file mode 100644 index 5dab309d902159aecfb37d5922e18393392f9299..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2008239 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

fs1@kzAckXtEa$~VT}BM+QlF*TgGS(hwvx! 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

I`uAO1 zH>2YaHmt6QMI(Sm>Ih+HD1!k>A?b+Ocvh#OU`Q;^)V-y$SI!|mP8Xw})LwG(>=&K{ zJ&-zOJ;EktMK9f=Bq}doyY`nj#3tjs^DDhW6SjxNYjX=|5EPxWUxNQ{bPuf zOh+9r9Fw0G9vV7Yd0WiM>=|1vwV0#tvbp_N2CG`@&o?T_bdV8zH;tWPY)6YfP#>Sx z07#rjvmYL&s!{;`@MGz z2x%EIH=*U*@k=52qV9|E`-hC{*EM|}2WMe5t_a`E-1ell-mZ-V7G2@xr71#%uzG_!@BukQui__AO7q@k*G(&y1(=jQ~Dj5BH~DRG^27d*D&G3#JF(PXIsn8Pig|h2B~@Ifeo=i z)Qm=u)f9ywCK?hGUx@$4_P1^`zC1Xz)tnQ|V6AW&KOe~){UUR!;_yxt2+g$ExL@ZEsPgDsWh)w% zJ0Fgvqm<|N$<2p$3Bz360kJk*Oz?QfxZ8Vc*LTqKZqt9qUGv(vKGF{bAG(KyC}&Kdy|GnW4&iY zpv&J*j1io4>S3!8z^dQe%<$CBeYE*=mhB3ZQ_x|8BPg$9ppB+by52C$v&|MD@5f*n zde#L8>bcSSx`ks0_!w`qOAE;*X~`h9f%TXmotFz%X1%vx&!S&?MajAR@EDklBH!*vB{fUHqOG3TIo!Tnve#>+G56`L3 z2txku{K5055Hoea$&y)Fd-2W8ww7G&ZFkon8*_rxchsFao7%D%-g=*_&)@BXDO*vM z=Sf-zq7xFLiLzXZVkoeY_&gi~&}L1yy@%V4*ebFHOxx`f&Ys11J1+4l!T{iH%$7Z9 z=~M0G1J&gI$F%x+bgNoYO>cEL9py2De6V#oP?MjfNwtaOCp*n|5fFJPa9qL2y=U3^ z4YRhdK0AfLPzwbO!KJg7Mk%SITPoxT-ILQpXU7Yn?F-I@2H$|AXh2cdS{Ln&4dGaH~=fEO@;IjT1tFG=;?U=Y7EC5F47* zr_#<%(yB{dc|Ckz((hABF%&SfY&M%({nT38c1Zwu_eYBe-PnaAyU!#D-m5~i?vg0= zV)f~9c3O#qs5~*{URIUNe)^Z1!9`cuV0fM#NwNW{h%@iu>)AeLQ)N~R_hj9o@sWN0 z%GL#58tIni-P+xEuIH{7+?6UhRw=g{uo}8LMOYb>bQj7rv9w%vkZtW=79VF?w2NXD zvDCRcac7;jPm=YSbk;I}EWOy1x_txS2)a^_jx(?GuTxs(Syxl1G@SW z;+VtHO^K95n6cmAn}Is{b$pv15~a!aD4mj;EbLrJ>?IQuT)0vt)NC4oTdSgZYr`WIj)29+`Cq38CtL~Vw(cE5lzzZ4!X~4b^vC^8sw5Pq?lndNl6_HGIaDUG{1|U ztyiYM!x;9y)BcHIax{nrHTnDUb25EN_wR$mJC8;G++5BH1J0qHrH94*4E_p2dZ8t#t~s5JiIk^xX8AJk$Oox|Jq8y z9J!*%0BfD&qaXK9>i1{n7dsl;_UorRmR*Q5scd`t1!%NC_T|TN#LHzH_j}_VG2l^z zy3mQOAHG41xLsF%x5FyS&7ZawS?i$| z&#n1HedL3-wjKv7*{L_}dnzZqfY-HwZv@5!+R3KDsnNSFNCxuk> zlqh=VNtkFZ=zC^WVz0Hgn9c@K6B(-}_AxD$0*l2yRZV~wiCXV5eYFwYj92%)s!=~$ z4=v_*@{>8HlFX0D2$gWFMys!!Vw+E8+;8M*2^%ne&xMRGcM+7 z*Jee;8)_aw>NFz84W2ym5(vt?%4}*DFRi}?ob}hg_p-i5iKvy6wrNRtz>J)h=oi2J zz@2KTXnKk}um6p=^9!2#7m0uK*JT`)*s7ipJ4a$Ge87+j9@7Ky)7g|gXc+C*CV8q77eCQOxN&?l zDa$+sq-U}4p}c{AVT>&!{`OV&okAykfp(2G^ib!fM{d>1O?xcQ6W1GPll(B(P5Y=4 z7Y{=V6I9quMR$E9gen2AsrFS6O1X5x(62*FyD-q2xe~{oZWH=+3E>5}tyf!?GAt;A z%;!CHn_}a>HWBbanp0u?gI7Kn#ue^Sm@!2{X)fGM-*k4BKCgl?FF80r-}^0JZxgLE z*>Sd}lmvrZ#}BO!zwjaKbLuK<-8a_%51+znC($~teMc3NBwSuqUaZ0(fSc`G$805i-k99Xpz>X zjVJ99Bj`vtdVy!JP}{GiPgIhdBm zO1YAeEIimo>Ts6}ios2ig zQ%`hlSTu0(1-GNmlI00l>71D0)GI!PP>((yO`#}uta1&;Y9zekoUs&+d_HkQWi59| zo=3FSEC1sS$qa#wC30!~%kKxZQ_u_+_22y)?o{ro`hK!Lp`rc#KMVEWrKwws8UB-x zHTtweJZs(w{sjWMb4VG8o277tAJ#P8xmdSCPS3qB*H33=1L`3wGm*U8^u~fEwhz7T zXd}YHLVHc#Ux750j$HVb@tEoPKbn_guBjc%?f^1k43=91LZm-E742OV@6psqy1FW# zs2NiQ?LmppOm#8AaNmvD6Nb#IZwzcf1GKOT(^R7fK};1|pb{(Z5|`$UOMd2g?CXBp z$%}=LGB)decnMOoJKhrl7rAG-3-PPtQU#h}*zKp+;}PZ^$$ZyZ2;Oj&%`s+TBDYFGfQu4*9W6v%%a-74PBQI-v0g83Gnk?HXh&8T87R*!N3=l*+wg0 zo>;ND1ALrZPhK`|{cDRqY1}~5DOa65Aur&<9J3Z#Y;L}wEa9b85LzgYGaqIVrSP$q zu8UdMB@prfOb(KfpszoS|D-}g58HB5j>X!q-gmG@$s=PuBK4lB~8P!tG6k0_y`d~X#NFN($QB{(xoMmS_;+pvHwtwHavlgSl^IFn9UJXFR zyVh@((Y^f^%arPV=XKMtqC6!kUT-#vsTH<@x#5S326`d%v3i>u$D+FFnr%3T&a}^c%BvXY zxK+9MDn^^q}*n^Iw7(MCQW$3*Vt@@1LUg%$p@Sc zRLuwCQPmY{=H)o4e9*bp?QZOq?C`fyMUcw^W&gO*-rK^gTOv0YYC`J7s&*rM;B{4M z5}bC_bT2zHdbsZ?OCX;Hjn;9_gWj1@(Tpv;w7nuBLPaLogwHO>n#^fBPq9{f%SB)0 zdTtjz8X8)4&}?|Cfo~a3ybCiphAijZLECyoWBqEvyiG3XY=irn1p?&fLsW%iiNoc0 zcC6$CiJ@+)qA`S`kiMrkz(aWNApB2-oni?11pTi*LVr*tN=V@T#E2cAsGSswDEI{e-MvO_eS0+w!!x z*tDNH0<^ra)}W1{rrFFtub6x z-!L|S|HTLWgCem>qWe$0_05#01XG-r<#0;+=l>8g-K4~#D_WmBg**%timkvrIxV-* zw-9oc5H6($$Hv~hd;i5PDESQ`k-Srlw14$|zdzA3z#4R_Xm!1EBXH8~BhxX6qjvwaM_6ySEt zKr=fOkExep5xs|E)wNsh82eYXmYt++rh(^D{Yn}wolfq6 zE1{aZFAG!Crtu&EV}@{|6_ZJRGXS;cP&Qi~U~u(Qc{JwdDb?8@$8BIB24=} z$$EDN0<;UX{oSwPPFV@~SpWBb1kKqc^jFE?Klsp?o13c2C_2_C7PeZ5(&xMoSmv*8 z3+2?>LC2G{frcY7?4!yUG?KAMQr-U@Rm-zFWg+dnd0l_mOl%1W6G)jP(B0L=!?~%5 zWLl?cVLvNJYddg3Dv+5^iN*8fn~i2mulLe($INk~!ocZa1+wnN@4P~`x~w1Mgu10} zHNN2frr9?WTYO8xUuE>3UV#QZ@LP0_KH~WNqjLN6qbzQ?Tw?z?mxT{GP!Sm>t%H$E zYz{QYjYuhgJ%Jy8>gNKus)$#N-;MP^O*qgL0o~Hwjq4pk6$Y z*}jc!WaG%^^LqoMubHb!{0p;x#T&t&)Z(i4eVYI7m!Ydam<}2PivIFjQ-uh7F~6pz zh3iVkpp-C=okhalc|3UrH`nYPO8apONY356IrqJ8;mGe~MNo?_CCH`yQz9jpUto;N zV%{()hs*2UnWi;lNI`q%oRz0 zEo;QZS2_i-*Wl7<2~yjnl?}I#{OTPMe)HKhbW@5Ha0L=9F(7UpE5I>ubSmb{C2;Q& zuUemWdhc?0!C&|TcQaZ)=G)Lz(x4mj$d?N%sTv4HhaTacl+dr@PQ|WjelsxmkFSP* z(9~li{^lc*i8EasJz1WsC1s}n6sqUci=ZrqGEzvD5}<~wgl?{Wo8-tr$qU((XS|IP zYPS;!cz6n&)aMOND6vGmbSH!6r?ePibI5PdN_I3>#7XXjmV%C?M#|DInz8c$6-ksb zuN=w5O$T0vF;K@~iN1>)c~jbkl+lHY!1bX+u6!tDFk+uyyT3G!i{DL(xSu5OZf2cm zjni)Is6}hAK72r_`McP|otn2VF1H?#vNtOtOl98!*hf7gBe;=uC0fwpI#dA4!!Qn$ zcN5&4Vo82on7TSg?lzmWgJxYjb*x~5C*V|)gvdl~M;x(bG#JM2iINfjOh%nWvi&O` z3Hm==D%$r&3~K)J75URm@npKpexc<}Vmp-$@pbp@f5zyL+Xf%HF6gp(1N@JK_H<~$9xKK!Da1sn zG8P;Ia=|MR_w_}dE|b4Wtr66}T^K9dA%anPz5Eq|<7pXtF_+jJ6bMMY>MMD{eQv`Y zqvgZwABh%uLbTcDzVN8V-ZA)EWQI+Y%t-WJTv;Huf~D`pV=f+r?1^zQUjV-B(LX$N z<8-wxlWb3v?U8SVi3S$lxg=S?g+rpWGm2B;R5owY?X2DSCM;4WpoQ8 zqdr+QUp*&bDD^AeegIC1lr@~iu}**Rq!l=(`2XtT^VT5DoV`J(#J@_)_cuT9jb_#L z-4S*?yzgzK5G}-Y>&r>UG7?~FxQIs{HELa^3t_1QSo_iBGPJQ{*5CAWxILRcknDw& za6nBca;d&#`hMPQmLNTmY~Z;ZBO;6l5InnsJX<1uJzn?^!W7P5^GpTighzBpFeQ9e?uvCqLPW#ESTV_29*qSXR>HpwT7}Re#pQnhJ0|(v+w6Jq=$B}ED zQs$tctB&3?P|Vo-mrHt$OwgY!H!we(gp!U|5(6VSNLK!lUc^>HYC`V;BUGpv#*xGM zHP8qnqQLlnzR^x2FA(9SM7tpsS9jx_f8p~5aB8cdv7h7g-~S`#Gfn;f<~fS#y2gcC z8c#Jcp0QKfZq99{f4SJqw-&|6@|(WQjCg8=FwwYMHgR)*ZUd9^9DFFo_sG4DJghqp zuFIT;>;-^Sg>_%3jgtQKB~3+TOtI40@+@}yG;ByRLdd>-A#vgiEVw}w6&2eF>-M`M z$DdR%ALUr7I5pex1kc#QuWj_aC)RLZAy(+FQMt$Zb34ego+vWhbK6QU=d?yiyuA@; zgMMJ3$dnwJHM+o_OkPVt){s$JtA(eyj=VL(TA4x2FYAa@=xs$B#Vlv+UE=0hi}ywi zZ_sxUpQdH1_lBD@S-Q?ZON^A2BSAk3rQA<=um7vx z2>t$p;5Qw=`iIYl?|*!XkPhdrwrUhw%}+Ay1(6QP0P?kQP-bFY(y-|&qSE+A7FBQ6 z&?5nDT;F7-V-P09)J0lT*?m-2P(2zlAx2nlksY0G&BwnO4*M|}Ed>^Dy#Ss!RZcyv zn3HMCfhHkCnL<_ z$dm1`9_vq)<>`I;$G{-0D~A456!uC2l8FRKh-jD&4}PfO?b77Ugqd1PYsmrI`^`W1@;s9XkegQ70GiM1JCrxEci6x$7j9`9!N@G5vDNMwXJCzyFWE z15S;v_H5j7p8A`Qaz7vmFT`Ea z-GtQ~e&oZV*_mlG?{44@Iu7kgix(LThUM~5oN&gpUK1!R6+x=PifpHQynCE3+asOO zJ{5X{uB9irm>m3%qiW##NrmBy=-2Cl9U*xmb~)=`?QZ__G}BilDl=~BR-j(GNh^Ts zMDn^q&~Gm#hac)^u`3JuA}2RI0Ze>z>sYj9}h43 z5*wr0Ru}71AO{QQF8Y;^M*u>7>~&85Uq3eYFInPR*x&jX&Xv5GFDPfAz%kUmqM^nR zZ^a>|0*{H!RZs8DMW$H#+>8i=uTeS8`|!!BXn37%Y|u+>g_}j4?wdM@+;eq5mDWo_ zZ>IL=ApyoA*U75us_0SH#9}TUMHYVgHU5m1h98-D8TG_^37p~8nHX5%51vqc*S{LpulT@wU z6QIZ$nKFMqYA?sDH{*ePP4R|<7bubSEV|-XJ`(mn)l_=-jh#;Z#!tr&iiZF74@Ucg zYaIg=*u?qg0psJdpy-!w*VRo-#+N|N#%LHYx^Z;M zj}`=VgVCcqr5mILM5Vh!!K4KNMX@l?^yvSb_rvyu5A1sHc%D11>uBv@cZ~|NPU?1Q z=w4~HA7%Cqy!Y%ZL`GD?=CxAWiq=k3iSSs@+Oi)-IctguRC1;9`Idal(oLj9+y4Ho zCJr+82#O@{qKFzLni+Uq}U`z-twwoU%P;<)}yNNJe+?$|H65n6uI%(*~cgh zK1czaY~ARf=4_6B)>kMV48up%bui?`)l)2M#M~?+(uh*~(w?2&arWw}1ur<2?PopoaZ)bIzDXoARoQh|3l2M~xBx|Na;M83KM#x4I_&vp3a(^d|MD7Z*;(?Ry0e$ERr(+*ZVy5eRhO z_n+|&-_{(4;oIAs!9nk3;9t5UUKCftzd~dYSDiwplV|3F{p+(PCtfpc%J({73czw( zZhY^e?{^h%$&(M|Njesjy2t2`ZzzDR?m=_duQuT&8+J6?hD5ig!dkPvTPB;YL(R-& z2HnaFSSf0jm!meBY`bl6Vl6JZJbCzL7Je0JM%MBSy+^pM%*=i!VfW-LS%oB>oRKHl zyu9MNb!c#R9&E>~p&#|__nW^0D4((zHn zw>7Qj+Qecbx{vM~+?udxy!~**(xyR zNKLOV^22p)wD6y2p#a2YmII5uy|w8?sUa2tAZ4PMLxEsy9LlDy`3(2Bg}ABm4VEzU z+ggw3D{)odkXG55au%6mxV55$>^)`6=L}l5S(rce1|aGSYZL1g=zso8f6RVzKf~v5 z{09o=9hZab*OjomMb}l2)w|7lq5jYiK}fIS*0Q;YO35JkNml@KHw>Q#A2x{WiMl4- zGa;ai8q=4!IAPdtzn}*r>U;=Ne-z1#1vsN0pCXv zCMf)D0T~FQ1=w8D8rrQ((5Ls*@@9t9PzZ&|j^v_bDt66zWn|Ix>{%JLMRBAGyxFim zn1I1RBlym;3=iX)7&#{>^=+4Z04-%)dec^%0ozuVdoU*JH=e(+pg@(;)2sjE=YbY+ zFW=vwzyVKz}XE9FTmyHGQ!=sYEKB!Oa~2Y3dN0T) z7PFx6XuOEwfE(86S0$tOi!wmG@MDA#*(D{0nR z6#WDDl#~K7m)_eF*77j-g4*N2tpdZKqU|chDSUioR!q@~ref_}6YuDfLF(^)oD%?; zPjC9?H4h?yfA}1jV?JvA_`mwOzxf>A2k(SyI1-pt=7Y*rsk5F5NlsGp=Ltvnx@q%` z$@*loF!_2ex?Htgty8nRLXt9{T&gI|kfMLUly9;kJC> zS{h}gYcM%OFe+jX;C;Q=T>L!=0M@dwMu{UheK}phladDl1X8YOGeO}&V-IA46hKx$ zZqrPwtpnZ@X%D4rQ%~rRY-{RMx?1`Rz1}{Hfy0&t5H4%X!mVtl`OcjOkGiY&_}xL? zI5dGX!_n=?x>jqMd1IqN$>qH=EG_DKzU-hFt(~CL0Vh(~=uK-a-E8%R3}o6?3_+UQ zT&I5*Q~?5*kp*2vrzM&fC4op_0i1=O5|n|xkh3n#$ppmnmTd{r->4?|tG7ZE(!t4m~S|2H(pPjTa-w$cidA%fcJ5n!#}eR&d5p zRRI|W?Moo|J9jpES{G_8Ar_dF5W8tihFqCtQ|CXaudd~28j4LsFAJ)j-ZT@;TKVlS zAF&^-i1VUm?!mxH|X?5P@wi#+-#Ln`xsxftFWlpZQaV z$+4SWQ;T++^pp23xRwxcE#lhCX--T90B~4)4g=CuCCdUhk1H75RB+2ed=yZDFjs&v z2}aar6`C{EfPiffOkOfdW_ESHc{slV#K40Z`8-n)J6YD*uG>&;RXP|WrIntuME>Ne zz2W_gs(K`E4WyFc3%c?M_QiF*Dq+huKY1@lE#URla#=%2<4K;rhmpiL`R2A7=CVKw z4OPf|#zPUWm%@Fao@@Kx@0|Zq^|MdyDybSQpv`$n*K$|gb^YZZcmMtIWBNtu^n7%~ zJ%?Gb0KgC#0P;KE5%r`Z)MtqNy8q@+nBeE^M7?R^BmbLECJ-aU!8x@wvxv1+K(~xz zv>~`TZW4Mtgq{*iCiWhUUgqo-qmoE8&J~1a)+Gmpc!qiBun&PeVn-)4$dT+Y8WO>d zZxkwW6*OQV1CB~&S+B-Ek6DBnDG}yd$;~dyWh}VRY-7|dM3iY@qr|W$6X^5noQky8 zArAY))~)A42ILR2+Cp>+f_EIYhfo*r9RzYXsO_m%Kou?r0#l`x^CY*gip}ert(M!l zBzl_!34uFK;5&gx5-LE8?Mvo|?#K6;$H@ookV@J@%-N|(WS>S6;rMDh+e7@?UT3Q<(i-Gphvr;UM?2E(c4M`^tj9yLr)scNvLpy>LraTLVS8jDFL5^w}O^XsD zmjD&X_Bf3&CXkQ(XT6TXU@y)>&Y}{BP~$=v1^ZIPYF9VQVCM2hSR)F^PtOVK$T1c8 zFrF!s012^_ntPl|#?M0Ukw`{P!xGgP{ot48uZv&5(s<NVp)xZ|HS3H+Cf)2qiqZHV$(AqtPv*^)ygv>n8;On8GA8+cbd_>cN#rR`w!3XM zBRnLYCI)c=Apsx~lr}So11u|tl0rsSwgGL8ml9%Chs(KNSCeH76$Ziga)1r8d!$VC z^4aHf+_KAZ@^NgkN?NOd*0N*_7Mb)i`ND-KTHqzj7TRDFG#3P0i-!>GrpXsXBqm2` zpnKyZkVAl!*nhf0O`L9f03lM2-+Ga+Nj^K8&i(R7Q2lOe4&e_&qzUS#glw~xX!jmZFQrZFf%(sl}c)@N|MI$0#5hBsRWie~8 zI|58qgyc^oELT&>FSO9!)Nxv!R3@S0vqU|cVU_Vgb)Umdp56l902PAb6->42AiM7a z0iNUl_S9Hz(7dqX%0xCaY~opPN<@$iXG!uGW<}J-Q(=t@5D2k8QFNC~j-j0PdahO2 zuh4;4M3ecY2(JZ{S%J)k=Hr2kXc4MOo0}#UcZqoy5OB)r*2BK4XdeD#gv^GFlv;`PYvhnNC9{$1 zqBE<2As2+XBcYUPihLJk3l=iy;B8~A$@=tl9zLhAgJ06#pgvBQu@Maq-)Hu9w8leM zgpIvYrJhvxh*WmA5&6k;iTg62mo4VLIdJ`ppA36MeM8p+>|gtVezX`UQyrOg8nNyME!Z}E|z0g_sM4@of!iqyNY54|; zu_`7$-Yy_jlcaBe_w#9zvFCj>>^@GMY}iI@_Vu-?VgV_m$fbK*sB=gwpK8fgM?RsUuwgmu z1V#8-p(Vcw0QPy=*gx!Df^dVmm`i`-zYF+KK;)ORyAJ<*9$-X$mONEYtN4q*>5^-Z zVN#m=5+7hY6H8932R(Wbh@>(YBS-IaM#kFCE;)a`CvAp2c|cRGl=^Wim{01`M*)Pa zP1l6%f$AB*lZEn{2$!M0=z2Ollb(?l39}J(;p6c2*$=7hxc(Adcq9JBj_WAO=uT>W zG@WeV{36vObf{%Xi%LAf+g2=eF|QvEY^sZQy!CL4<06(S(a0`=9O82wtSh>lK621* zPM0lxaG)ip&kUB7eF|iHH&lh9o`xtWhD{z}lr>y4r0=!1blpP*s)0Ss`|S!<8E{2D z-+w&S@GFvi{5U_Iaz>$8t;}TJ-PwOEO~u-^Qc*6nv!+zogrij3b~@d3ms!GR;kAp_ z{+nqF)sY{TibXbnhxY}ao;HwbTk_*UX9p})P?Iq?EXGNLGh0UFY9lm=3WI<@Nn0xs z+H(!403xUsFf_4B^g`@Ck$mDspYfGX#Jx*r+N%HXul@vlNK&7TE;RaQ|BPzql5hT> zzUQ%e$7M1bb-1eR3~nhA12L(&74U?MHZsi zMVL7mYeXc{l(G;r0T>t%N9FB+2d35e!xMB+KM(}&)?!o% zDd3E$1HNcLk^m8qLO3B-pUJ+MtLJ@oZc#M18*}q+!`|A$)yxEg0gg#tqv*0o_>xud ztm>N+i_)n_ez%Q9^BiOE+r4vo&Hh{<#(GyXo&$n(mfuH^q6OOEP?d3 zDsyNer>ZhcRpRh%rp=IX4PY;NT8$bQktT=$_{J^y3jT7LzBo6ZV!RnBtXK@LSln$M z@D1;Ij7x5fxIX##_2;zd=e_;p+MUW$*Y8scXDyD&;LUUd8B0Gi^>de$9Dg?bZp=ip zh3b(&>-rQ(DH?nO=H9diPeJlnUiP`oeRunwx5t>3&7<%bKouryZ|Mz}?$49Upo}Mp z&&HC@M_IWmkyY?QcicfR-FW!w!jNy$FgkWGHfID;!C<2`k<`Nu&3e$45`3NV>@_7~ z%RIBEh!z{Gn8=jKeSTJrH?+PEISC>S38zE^DjK_2t>h54Y+#ZV_#BfPO`Gr zqPSAi0ThpH4l|67E!w|^zi6BA5-6yMuboWi<>4u7Og|Pcn@p;<>Z?hp6y@EUotYG_ z0)MA?quit+dMPWluQj%Y{9(ibK%O}po-XE9ZsTqQqJ{AxNT#8pDT>Vrdh%;8P}V7F z*&o|qO|Iot0)^d-RzXtNW0gmI9VZ!Wj@wX@qnV>ov2qAgoA(p<-m=6mvVj`eob9|s%R;}*m;87bl{`t9r@uUr<>7`Bhvf9F>PO{obt@C+mMW`5vsnVV{V2jclT zJIchcXmSaU#+H}s67{uzpI#%@)V16gCZdfk{TLD z(%89;@ED*$iSqt*rI_x($<1VYdiBqk!WQoGKGhY$GcpRU#D#`q|I17T!(CF$N=760 zCj*Z9w`TH&WjgJl`OY%pQkMi=!~DyX9ahEL@Lz#?Oyq%K4ShO3Km1nfd8)78vyKhU z+0DILrihSiV_{I)=b^2s@x>DL@>#igGJC{sQ`FBKGRK;H#c;JAH-@CJ79z-m4_d*JGV(|=gStSy zfED!XW)tS3@(i&M{%C}d361uFx^M`4-wCJsr~=Gx+v$ZENis_YC92?|^culJsE4HR>51kzaj zu*+z+@@{6mN#%7W7j$yT&5bPJcRV5Tu{3Hf5%n&={L6RPA6ow(zh3~kzK2JMhl^-# z9zAf!U`?GR!=&Nsdst~SvG?~u{@bj5*#ov8Dmz@Niq)_1~fU19EEumjcfdgoVa-2UK*t!-rkd_uMc*v%Od?sPw4C3)*v@{AxOOrTN*yR&pkOAIdp>nU3 z0kX%z#!h0LY1=IB*|t1{SPl4ZlQYGSGiEuds(q-{NpJK0x$&%P<(Ac3`x}*NV!Yh) zLt)N1hc!VqITH$H(rEdHr08#Ol65`iY|q}t5mg&55po51r=Nr2xvNq_Cs`MDh~7-z`LRpYtD88~m`?(WRdp+4g92lJ_YN zT1~YdSUpd4(bNdf@R`lg$W=u0gU{I2#ruPJ1_yF1KYv`Jv3DKPi)Atsqk|Mj)p8&) zRpip5%}{1Bsu~^kmlQOKR?CzMBjHDbeN4gKDWb+zqUSQjCbp%MPhs)>*_Jh#k`)|A zdm79$VFMkWP_12(xra4#!9m*7Pdw@Rt8VeSZ(G18zk6rS20M@Aj@0xerEdI|v9{VM z?3;J=$Y@19_vKGPQ=bhb2j#04BqABOej+d5E6XAaXoa)mV)0tx9RKz&k~J5jum3-O zs_tLvr`xGRf8%Y2c6N3W8N~l`3IFpq=yVNT*t-VEsk=%3SZRy%=QF2aUlhq=9 zOXvcv3^G3Zu5s@)p+{WoR24PXA1qQ>r1|nQn7_bU5}>-_s&PUHQ8b*U+u9vT&b)d%77^WS=|SeYlrVI$QTzAMfc;vzQ$zo3J$I~OAsi&$eFpnXJ2Z+(a9~QKZCzeXMXqn zcl_e9k~P&>J&61^Fej73tk zdEa7K~>8#a-ti}aGkej)Rp0%~#%(wfooI?P5z%A{`!09@U#yImWxZt@x zJ;1}ZXs3j^D6gmjvL}W2HF>-frOVic!fn%DVL5pm<}GSXlcRTYK*s9+D&*N+)-jo+ z!pfv7{GqTgtS_E}Ue*-D;|mZNV&sLOj12UNxw~3xYAb%&v}ty;&QU-(1<|Zol)U^i zO7$`a6IBHAzA|16z417vq)&tc8YS45S?=?kRP zb`QcEIiH=Ff`aY8Hgi<)ZF*$}cdBMMjHrh~IyxG2=MS45gD<4VKj;9r9*4ZSa(s$w z4&qh7!p9_W2|jrVq$G?;70fHYQEw6lvDn*nD+sHpMoUI<5+H!ntvI=&YHf?LrB)B? zULsZiC4AP;Nod#1INNE5qx%jljXFC z?hH5YL?N|c;Nh3Nl$d*a6BPs06aW}A{sSi`B?>W7P|(jffpttXZuH(1p=Ih{;^&wb8l^q+`BqievC6I_f+=2)%B9l`>=cX9kA#JBXby}ilRmMt33t2g?AVXgo?8~Qu zrasJ^UTa*%FjLrnLVNjZ+Bo_ z=!`cU!*6@hWRfJ-^p_sV@=pB5{{r_ZPy=;-eJb|fd06MO%KR(9KYJ!Mg-=QYf_JmX zC?zAI+ZE)oq!Ab_To_%F{~c^siqdLnjyyMR@v1_mxfZof2q0JXia6w9Pdi4l%#~>c z1aYK-5UThhszIyadJvaxYGk#$j>TI4wUmd?Z_cdv1hXaiJpN02WYu({Dl{SAh+8Y$Ic}M zGh9A#DuW~J#~|zzq%{~-tXm#Dn}T4iiK}z#jkS$lCG+jH;MHR<{$_OkO+HAe1@!y#F5$lL2qPdBm% zrf@<|59(c>Cg7pezK$4kM^&Hfh@Yd2_HX=mai4hAQRnuf|K=H3=szl*dIOUF+JB(~ zm#{J5iT1PjgguFEc`NGK)$-=pA2fa(+|O!Fry1V_Gg$K5Ro0(f9KhxdE*!S`Q7w`| z+)X8H3oG{jIbM@b6NB{u^Ds~>{WEf>WxPxi>2UG3HYJK`S9Daz8*aDNl*!3S{zj1T zb%v_!eHM-m6*0d<1vY{xr#XSK42VXklEhu~`-I-Qv75EFB**tCzp~4iT86v^7IY!v zNg`9lmwC&Wu7EDxI8l@~RWPO7)F6T{eSLMbxR8u=eO6F^j(=3JuAYB|Y7L0S8i`Xq z9)Dd}`ZXy;i313u>EI7mPStw(Q%Yh|kXk`;e7H&`GR#{$S0MvDB;ncK>gO@J^+5mj zK-;QElq<{eI7azK^JN?qdDk$b4y`X(&eBX#Tu|w9^sdMx{xCU$5i)a3U0=N!<{5(C zvk_-adzrR^z%Gk?wMD#3qoq2aO_c4aIuiBR+}PU=hyTX^Dd0nw+5(a9apkZ5GXXBt ziTn(Rzxb!oaz}X?tC&Suhxu3IM1Xi0Um++ds&e+AaHiO`z#R8w0ZzYCMysW~J~0It zCJ~}#?)RMfRC$O=r43z-d$0ThJgoDc^!RpMq;71Bc`fxUNo|(m*xuI7ncO0=3)VzY zo=Uf^cLHy$8C|?6Bp&pXD^6>*@Sty!nCS z)oyU!BWsb;KI<-)ZtoB`oaq@vbp<}Uw?B*IW$0V6m#gp?6y~68%iA3zOA>Url7wU( zmL{{;bEM`gb<5mo;HKIEM;KBzys;ERVZZYNUdCk97)a7RA?T5Z5{E17R&BW;Rz}Mo zt_d>j)`gkmExPN@jH-5UJS%SA_@Lw}Y5Lyp?TaTCLoEb)=C^)Nnu8<8THWUeENKl>-s*W>neFrvE2>d+vp^=5zr$_PT>lXRMtTMi5))DN%P#gx-M zyaFu+|GXz#5T#S=d)T9sDPzoMn9}w+rTLe1maH0aikDAdf_Axf&j(8*(}4RNo0iER z&5s8o@*mSA#A0Q{S9CP#z0%}G4oY}wVr%s}I!Fss5+bq-f&ex&eYo>EV$UrC<@TXS z#sd|E?gOA@0buSW3pGyih`M>vdi}#%lu8pBxnLh4{wk~~ACu9b0JV9P|B$Dj`N5-o z+o;y9Z<_BP>AY|9Aso*#y6fs2;g=iqp%1gpl>_2P!x=k068}$&43yVi!y9XauOh7jgBQ5!rqXSy(V1- zcAJEbYAc=3*P4koXu3?r$v-cA{5sD{kT>5{|M=4@6}D%$9j%jE^qO+_w0`D_%zGTo zm)UT;O_eIpx=pmGUVcTGFY3vKn6t^`87GAqZCefLtVidGo~%|-g9}?k8#5)}ryR8L z!cp6Ro##Si6i_n6Y}kiC_W7ItVey;Y|M*52r!F*4)ieI#3D&Yp@ok%mQhya+JwdIT9H7GPv7B` zk;HLUXWnCs&$QwK4|tJ9dv(3l;i0DTdV$qIO_Wfpio{1CuYE&P>VtFyQ{R-a42-UJQpi-ei(e@&?d#)oIW$OQO-Qz z_@MhUn@*lMDpg3BLWL1gm}@UI_HJf;!YbleHR}nKjfWCx`J=wwP|!7Jbj^JU2&&$l z?OkgTe_p4P+c_W56ViyH-0^aL@$?dglnOB0C(h?aQ>x3a13{XBMhZxi#ZeFVNA4c^ zH2Jv2vaF49_W4yKf}XQtx=W6|Cir#Z{^FUaZWbLCrTo`E8SFl*oZio<_-mgBsUDWH zSpc$v={7K}^03o$*r7OCk(jW?XZq!~Wc=d@rLr3#W6EYNUc2zZq2=$QCD!aGW^8kG zYpg5M0@4a4lW24hL7QlQtGphK0gObv4^Jxu3p8>)X@h0hk+R{~lycgGAQxuI7 z;KmjmPwE+}b;_Bm-`{(3h>~tLDX?Vo8T@J_`od3;fqPQt=*ko2Ie&A8HzVx!&o?dX zIq`toiyil5ZFp~!0(-7;l}PQ~bQal3jHp6Q*|o9hkAmkVS&poct|1jo;{t1KHLp7Bj~gQqw6Jn;Aw{@?Y73&01Y+VB3m-#b0zazfJu0z*P1p@O6;CY#SH9i2+LVnbxmoU9u_-$d>xECZV*a!L zb&5Uzs-pYN9ux8xA9{~drqlnoPl2R6S4i$J^K=u}={MJm$d2-~C01+wk*ZbOQZJy{16FWVTT)u(Tg84-oc%+6BF-pNzvm?Wi%T}zF@YM8V0kQ`IIvs z>b&72Z`GJri^QlbjStQ`(#;J*E|ZSEym0)XB`)n4L`HqB@t69N-TjChPMNYsLg2k` zL^A&$=}Py1_n^Q1;kP03V{obKf0K4E{AWMy=L|$WAOO)Hf6s6H{>y3uB?TA=9?{F^ z>eCclDFT=p(UvSV6-t)9^nGq8hmqRkbXT#f;EW)G36I<#|wjs$Dv-182Ncq+H<-+|0@qs>g1VC%d^fc7uHeeJ2dqndERof{8yU zn|H;2*4lce!ph%hf8d*TkPhzDg|Ml}9&L|$m8a(Uk_f=hi(ACcuQB2dUg72>2CKdZ zk|qw`T+G$PZ=&uFeJL5QiQq^>T~EHJc9YE0&z~gGuL&VCPnGf8FJkdWBMqa0&WS zh~l)2ViXOfX`kNc7k&BgfJwjb*R{+z^%qq(?&GP2XVyV3V*$-M{z^ADd}U;1gfH=b z^j(dv%9yaq=2k}Fh5h*Dx4B{>hH`>xRsbR%7=|H`ze$RkD|t9Rn8eG*2uV8EdkO4J zf?bih@0voQoJOdr?u^M-PX8b{4v{v(OFZl-(MIfFW?A;U68VVvXtzxNna_L zKAnNTTFa3Ra-_&*a!&{T(9#2xA0(^>Ch=OLp`RLjiQbDrU_9L72C#YHGAZ%S6n}dYwygteHdkI_6~);eABh4kZ&d)`UUIhfoJM3!>j)$A6@p$_o~dq zmGz``52>C)z{A>Jl37JiKNDzsLLIN05hvF5cm5*ogFIA6|MK1XH}An1L*%#g+{OIO zU!$T=^{DC9`*kjjiAFjMRpm;?Ei>puv~qHomQZ;*k-kF-dG9DFCrKxrm;Mx;Ik@zi z{{Zj5nb|F4clL};WVx8r8iMk15@cpE#=n6;@@(%OfddUx@13X7YH~(<78LGzL{8cY zw-8p#CP}+rvl@-Xgs_{6JZ+Nq!UBq@^$ zxmt{eMm}RPjfZ<2&5r1^la{0XP@kWLhh_*Dv*M%bT6F7Rmu~mR7trd_i#WOb5{KNx z5YG0&IBB^<>-{tfE?#iWkYYNBgvM2-d50v{X2CeeVQ}LT07OOL{EKIxIy%%o^7`NS z!vy(E><1lG{KbvwAr|u{- z0NgH=^>R~lIWuwCT0>`*teo+kj-1I_;1M|goWA?kN`$}*sw$o`jp}A=?)9q;ZllVb zX}R&uQLHGxvNnQg!*ovzp^aiW1jUvvkV;NV(jDLu*Xt%JvK8iM4$ zt(sop{NnB*qbPz7y@cRLG$LusMrQ7v#ou@m z`L)tDOupGi5)Jatd?TY1@qDG8IrJA#hLH>@QETLCI^F1m^K)A+N0wy9kP7Bgi7A5; z4vE$vmf2!o%a`WEpm&i*rsBl9z5$(>XPQ^{uM$U5yQB9B0>yQb0#3sm&~%Eu@pW-y zsnTM-V`erwLE8-WPJ}W>DY>C6A44N0F*{4+tTRk9w*cZ|#UO>i={~MPSST1k0f3^J zY<-5T6x^y3IzZIpvY2HF5OQDM$W`wKu=E+hr67Ix&hzfrb%lq9}ffoB086BLO%wVT`J! z4z1aZdgRkCro?cbMo+V5BRA-74dXAW&a(V& zd%$3S$lk}WCRdU;p>lLhU*UHs?UaYNADW&-udYn$VG!*zyLqOW_0+GSZq&~fNsY+M zwkF+BMOXs%Zr73y-|Sr1Z0Ud;!TA@CsWMNH%jT+Z}K>Yx9sH3H`U7B7zqE zQ%Y#p3Ym%bco8h=y;G@|7|Mn@nf49pIT8A=r17ydo~|WW8@=*;gA#|N_^hD#4xLly zJIJjYYvycF>7cF4XMiv38Y|fRFsM&kckOr`~r#Y@C*9n#V@oTY$40 z8g@RM6+SDp4iEX3%am;FEXC@GG!VkjuXjC`{Dt-7^`e#!sTHD9i-C)OU#i;1#FbZtoNtpf5I^c&MF}dGm@n=lEk?w~@+ zU@oFF*cILG(}VyFn5#n^BLNlsG=}O-+LTHP0iX*iF@Ab%SYeA4T3sbLTc9B~ar@9u z8dM^1r|)s`u8~FHEaH~LXyA8^CWDsePJSw=F+PDuELB{8_?C%yx~nY``;Y(PC!@r< zQtNhd!(Tjkqi`ajY_x1L~lCcTQH}Hw%K7&%pJ6aodFt; z(Oi4bQoc(4)TaH%i}0LISm|cw*JueNt5v0*U)Z;dx|f%-_lEqfC@zEOL8O4{EB`{nU6zD1Qk{6tHOS^!{>QCpJDE>HR5vOAR z9;@+;`D*iNimg7w`#wRv%7rHDVmMc^+7wZfSWvZj zgQ6;(BDZ0V^78!xB3TzYp2@0W}1s=UIXjKF9>Lh>_+02;vnb0?OXY0(-v zi6c8WmEU+0_r+Y)O^?lti5JZOn_u=mOSbv$!~WulA25&a8?1aCJmRG-M*svQO*tfd zO?GLNaoS)p_!-S@%xq;^VctfaLz=3+|7oQ^LH4MO4qa_(^SSl)wN7(KGH9Z#!;Ic5 zMZpzSkJ{U}C0A?nF``?qN%s@Hyytj$cbedQMPf-MJx|&xAWFN`I^N~JD6d?eVXLhF zXfD%$MwT-r0K)wCT1$2vcO&hk|PmRkI;!;_ZH9JOf z4qr-}a}Qww2NvA*Z)@iOz&MoJw5ZkX1W6|*LNaMaq$pauF^mL&*;9J(`3z8-T>yPe#x$g?*L&J!qRd2c%8IM@BHyZE6~R-w!z zhh&?KlLv~wx+Yp_@1F*LK$C+97mw)iUv#Lzu-OsLagXqAJU@v}zHPiWqewgXQc`Jb z6}xq{2SU_DB{620ACS%`i^tGUg;NtmSoufmjN}(aLT!|MK*CLkY0;| z!x>gmpu7-5dq~#}>jv+!fLqXSbqw*+M=3sMt`WjS&e+(#HvR_a>W3Ud=M6|U*Jb^es>d#}AH zfwNHZ(wmp)0d6(8_*5@%ixQ6=cYc{XtR9zb(RV98!&1RwAEy4cN!R#M(K-_j8rjz^ z^Oa0Y$-}_W%T$mSCZ(3#yf?08ykEo;EkemfZ7mGgxaJ}$I0<&_+Vo#^**pArOaZG$LL+67+MR6n2Fnx4H21pok?^a}8B?Lx9g zDwfJ=X!1d}>1QUK(5$KtOz$@8icy-~Q{~M3=5!>1w$2MDZa*A+H$E`G8C+=o`9|Y| z8RyAmbrt$sPTrmQa}Q1iF0BpFw!Qr%1L?RJfAkQ!ZPYiG<)g}o@3YE~?W}6bYWiNV zKM^1rFj6p-yDQNn?euDM#5TbCk$w{IC`KHxbU2!h6$rKxSMG!4B3T~wS0?!Ue!nlU zU#byP{!!0H{@OoF;b(PXKN0)){dPF|u8Fn1c~D#T9|iybx@Ob+13+8!eG*Hm@Fi@+ z8Pz!mFmcz}P0u3$O-2#wb)u}0 zIq|DqqS@xXrOq&(|(~=>1vM{my3SjluJ8jz4S(3%jN4w6eYF z%a5xAdg4j)&O)PUa)Fc{!0_xZGeF*kdor$+cznZ+oIZLEj)oBT7Kxq?{@4gyH{)B0!2>BQP^%psIJ}0pfq;UJwuf%-< zYY_Vpb6@|yUskJcx+lk=fBw4?#rP3il$B5U4pQF96MZ8_ZA@sAx=)GCQ$HJ6-^xm! zO&yik5n(HpB&$0!RPfqa`02_ElZR~|)tioL_GTpIdtwcfSe(pgF%9bkfQ!4ekYs5&oM6^FAY)3mQzup6^)*(&i^$BRzWGP9?2@l8k6*&yn@jOaBe?`3Vf3~Lc587 z1pTIc3fpCkQ)hOIx>w^u5rBYH; zsK8aZbZs(DI7BD2j~5Gpsm$?d#qv(b%XG&ph{V4i&bBkFW9ID;feF7Jh^)DgeNyRk zivBY%v55PqrM~>lY&7zpf8`SU#jpO?udhq#G^bUTY-K-%J$b?8YRYe1iP1m1tqV;Q%khI)~Tcp_48ac%i@oBsCD+Gx=|wT zCcw7EXZWtJMwSpKGN+*>OR?osQHiVp56{PuV5bK~=`K1VhhF2-4c0(rypqDD z-gQLAnKzvJ5~@MF7%S+v>czx>5Ebs>H7kOA>GzKN~|vhI|L#YL`YW;aOgI?^$BQbm%+a1%iB3zGc0H3aoNv zUKo{~Oit$rlDpqaoPPw6j0UAL-ppMB=?s#o_qPjH^SWeDpmfL*ve?1VtV~mJB8!xM zNQS*^Wm*+mjSK_>y1O=~QtXT=EwPkc1Pd3C1P?a;w*Zy!9`SixX#BvkNMea&EsBeUb83}t0uH2^FH zbO{3Di3?=c@r~m_H4tsde5x{u7aC-9cMEIY%hjqNquKV}9o*4Q-Of#DxoebWuEN_^ zt$EE>WbrYTm$hXy$i)9HRb8Z@`3-!f2B)m)L8Cx~AH6(3#G0|R=*o&{g4NyII8Ls{6Xm z^LAd>snUzd&SwuMl@IqrT9Pk+o7^k9`>3ZNC&AVx%$ENmj~6gYzcn?7-I!aP1Q0Xn zf$9qRxjaO3LE?@G@*M>ELpL9yheSva>*UxVD7NgsXy`^^l>Hif>cVUcyf?+05@+XN zY0R+@W7m>5%1AHF8)MSCDTpyq-6+ZQX$%~$Sp)W{@W3E3;_j;V2k;a~Rn#mV(?HZ6 z)Sn_alGGD={a`Ez+BE)rUv-Ub;0-T3n&oj8s5B3+r#wIf4}|rY=KKdw$TgK=5s=9rsSRg&;@?jxpxorPiA(>MIV^SBuHMi#3%K`~bV0J;!%cdAQWYb- z-RLNN#(=UU0=nrgrk^59MRE00xT7f-gs7`(qB9nb+ri+xEJfLoDA0r^j^Xkfr+lt1 zs%z3=!4n*`vvKdNs_bsLT`bD^y%ri)$0cpAL4acDh z>eA1?(+YjDVo=V=zv`^XS204N`I*xdAT12!vF`n}dt5$OXeeOwzhi81hLyoSqpRmD1?T6>r+tM$vE{GW3v=&HDIJLfe zQtQ^M?Y4V1`poi#&0SKFac%hCM2(JBP&L7{re~FKw*No_y&bbrD>I%`b8nL;yq2W7 zK`8<9$nQ){cP`H%whUZEHADn{%E70nSP$>n2=iyn)U-Q0{FZ6C|4 zaYyAG_bxI-%yH?Va7?uD=B!(nZYC_PN0^dt+;6J@mhNTO!$#h~!`gWD(v&byCGOjs zJFHy(F-tC8Nqd>}v)qW3C}H}pyXL!Jo+wm#1;$?CG)<`%q^**ICVKIkfghT(e;%xJ zep%d1?%_Ph?&}UVpr(;3qQzigaWh#!P33-7*?R|sHjd0rLn^xuYCIMs#LY!hl1e%7 zH7(6_`ssZIrdbI2q_1uev`Ho#j1;li4qj8IZ}()#HFgzZORi@dSP5LQSbg@FgPVZb z@j8K)o34RkpI1_j&^P$3LCB~|=Yf3u4nW;H&dx;p9KQl*#tz#}-ISlGnF3IdlNLik zrrIh}{`_m-il8!kCJiq)u`ZDkMLA3N;uPkuLKnwJ(z-7^bRoID}M}{Ke zB70nYAK5nlf;dNU_6Y+%UD>Nw;tDf<>5k=ntE=4jlg$Yum8;!VwhH`g0!|_g&K8+L zQOld=8RBv_oCO#q(F<}3IbBZ*v2zl{*eY!SlA_f1Rpq6BfO~GuZe3apuA9i z9-_pCx{T`VQZY*)YQzhNM{Jf5#XQ3c+@EU6x=sS$sJjnez}!)yzMvPR}-@M@tT z3@^v5u zA>+HlSXz@MT8WH7L9j-B>~Z234LakvCEU9aSIOBp{?iQw*Ehs7ii28bKhdVucW+jM zynA*t{SSK6yXUGkf<9%aytyhGkOHy-K*`rbbUyxrV{96(&0>GjZ^ek=i5^hfIC2)% zw$#d^i%-`ihaq8ZxPI6iy&mzVIHWoF?iA+LMXl+?05j>7FI!rI93LQ)Mee7lyD3Am z+%<|o?!tmrk&Vz=D{bfd-m`5nn|J2|2&Ril7cYu5dPuAA+`=WCNJDkR)ud(S?cDCY zKDau)jm)*F%yBF&dMHs+l6uWSphs56XIiCa5&-x;T}&t5-(gh60igI+|9ou@y_nP} zA~%0Ce&+@83VCD<;u=ykN-rfbfC!DEk0O%h6-j)3c+$S4p>IUwA3PCb$I>J`NomwC zJVAI&zb3?x4$n0Bg2j*-Kn~1u7y|vov1u(Wqhk4COG>Cll%bc37K^FEktW)iFIvBr zp{@#mXo48!OD#w-0*XC~Blq5!u{(Ly#s{ULy@*|B(pSaesPM_rwV7Da#a0C9p{%84 zsc9g>RZ+*5{vRiky+QR0=eJ*S*(s%hdL%4W?BbLVHzdAyn+!Yua}5RanOZzt%M+Pe zipO|V->&FW5jnhT-PH9_7ytw6lBisy)$uk;l;lDO)Id`?TAc$UVummc{Frz8%ms6F z|FXz{8qx*Fp@zSvOVUyE!dX*!72*=9wM+}J(y#@xStBx8;ZwZ$&-!Qw4<$)|+zJ7H z-OrNZ9VhCTuj??A^yRwg|@$PH-dt2Q|L3 zM-bk1RWnqZU>1cULGS6`S51@{vu8xFON-^-;yaMdYOSGvkuvF?S1V>&RrBxYR%okC zM`_(1=#Qrpn{z*d=fB_nCOv)-0NL2FulHqu-Tc0IuC9UJb@q2bMd|r=3V5<4b%2ly z0PGJzz={4RiHrkry^R+hkcM~B{gI5`5{Mr(={xckMo-J{6Xt?sTspYO)j}0z!bVL5 zZ5EH*)%~W51Ip~|`=3y*jU>Lenw~7c%$u3R&6wavcCVhY+&6J9BW{RW?TyAQFlqUc zJGhPn-+W5V+@P=r0D3ljdW-()aFE~p%1or+mQ0$E%#;C*Oap@371&bs@yOUy{l$0j z44}A1nt!-KqCO(oQa=DN1RnE0dWgsTj*t92TDj+v*7*u3-A#Ww%R%lvttfv(;^(WbV=k&;L}>6JR6$vdgi>#lk0`AX6`n z9HG2bW}$MSEUEYOd4pEDeNm%>(r5EmFZV5%qz3PX%L4%T0eE7nu9{!(rv-p=V?ix? zQFr#82clMp(Xa8*k(p|<1R5x&Rt{;6vnsfjC9!SZDqnX@S`oyUVO z3qs}Wt5{5STLDY{TfgR|kMWRd z72R7`0od<+5-CQ(`1yDKL;8IQ{#_!$ciXpb(P;!fWRbREBUbG#Y+`OeK~G&hebn$ zqOtGQ-crd{s~fjE=2tk^ zIx?ukRxK}6nQGDf9aDOq@rj+qpyU}Y7m?^*l|mC^{*1-8-(;k6v%Mb2Nk{GOq-djl ze7CNylLRQK>m+#L3z++=LNg^cRV~ z)4)5bG*$7tw5I&t5ftX@;FNK7GX%fB9UHRnUdD{UP_jlTQ*mOjWzuQ1FkI93fqlj3 zC>)lQucA>wQL}WZD2`CXYBTS5@A=M3P9t z8t0#&(}A$4>gM~Zz8Ol|K)NcLQ{XzX36Hp!JsP!=65q{yGIsT@2l#NZSWxc=F`}IQ z?L6kBaegf}N|~g>szNdJoHpHL@Zvd|WbCF-c86kZYKc?`{4ivDaqo z9B~PhhfU8}oQxy(wY+7VfH#`Uy{D9mcsCUg!7;N1HI-U-Qnw)vET8R)`ktH2ll>QsX@pb z)u1$+-yKQ4z$Nd+#o)y0KAN!J+B51jX#MCGWk)#wg0g@%g{({ENeZhIuPqy6SaE9J ztA}htqUVH@c~JDu^Zb8{#)&?{9Q{mcRW+x?qjbuolDBNM6!Zz}1mwk-pgekTv{7jd z!%ldTc7QfHD=l>t%W)#K&b`-Ek%}Qv1l;DfOVmA1r;8)c7~v{6?qGd4oLAWVxDze_ zQXfA`HsX&7s!&&=7}bvHZm&4OwvCw82-^#mflK!*aiwLvTl5vGhBw>W_U}MgRwOQc zw)0J4biST~!4KLk)2%Aj8)|-6<-Q_Nx%Tx#8_1Nz=Md}m4u57s(m%5Ouf7AL@;UQ6 z?~VT7_zck>j9M_ULyET?h>OE)_ooU9rSj3FXl*cMdj-qHj74aXQC3bcd?j-e3&h2# zwr>H-SjE9hXMPZ>Y!<~G$Jhb)79_8QnhKffOi{$5G3wmFeevDdXh;vs9ffDf?hggf`>Sg~#yW`~z{^(#+`wu)RPgaThr|5iQ~9s|B-ywG^X*RNirLI|A7MS&mYHspWx8&B}(J|zC? zHJ8BO`7`6UbCGwiQ`djvd2{!H$ulN^=CO_3EY#+hP4$H(hC4L!TP{rST;?DGp#N+Jm_ z<@%1>KE4!V({M`dJ6ScX+Mb2<<>o&t&eq(ml+rucy;qP9b{Z!emqESP&`yBJ+I zifzfwJm}MjZ;!WIzB>~7;Li4B0KhN-6ubj3-?`ucGDKh()|qlakY`uM zMSSSO@dP#o*-EnxH9r+8wUyKXEnFD*jvWVWQXP3=L7*7Q*#utbCNR5!y#RHwA|eev zUI(S8kSl@jChLD3QdOOmXK@8PXCOv38HgxV@6ggDJg^RCjGD6Yv~cwkHw4(R^001R zltUXOx#}AZW+J+R1;PkQF?Bvd)o>1}vLdjYTS^B4QtPFWKB%)@$5budIL(dzpZ5G2 zf3~YU@iqUyd<9JKkJ9b`;RF0RA6xk%@kr4<1}`c!Z98Gz!+$`C;9NsHq?Jy#d!V=) zA;9Fp%VkFzKsr(xndN=7_>d>b_s*oPo4=4zo-D7W(5izx@@J_3I{ou`hOXMjBi{ZS z$kQr<@X_&kOC1-VRyyr($PO;05eP`k?^icC`Xn8E+{I65c9$nq@3Lr3RO*^Ax~zI8 zWrT3oK+f5VZ7$g+x&NcV6nCzEUuY59e-zu!*3G;rtsMM$vZISj60=#c*2r!xb5NiB z*!;3nOAQ->w5_{1b>mUQ*jp%-*q3q{D{#4<;7Rkvdt=snKv}jb`MU-D@|XofKC3Y_ zGZQc`uNt)>0&j?cnX1jP7wjP8xyfE49D4;5uPwTilo31I?ZogDvjXa^qo_hE`T*_J zE$p`7Sa>iY-5ATLvAEiMt@I(FhgtKL-zoJMK*uX~aD1G1;mWOwIHbvC@6s)_((!Ql z%TccWL(^29#pS;XL?jXqB-ip*M1L@z->5pbLTx{$+9Fhjao|!AKe#w;nrP zfJ|6%8W|#KWy|a{XS3V7E{j=qa%0LYU< z?@Bz8xW_-98syKW*-u%VF-?R}uOuw5RIen$Vu+98g>s!ckd9QlsR&o%ZahyMV2!Mz zejTN&mE3a|MOh2u7E=4y9|Gc#1Y5;DH(d9cFoO>wR-YLk9gPkr4bQ@GZ{mln(I-A{ zs#oCw6r;k5&Ts*ohY#;)EKHG`_K{>$6yOy*_Czz0#t7*(kw}nF-AOdsuaj?d% zHq4to7t=X$+=LpD{B#HF$SE0dQ3|dPbkKd}mfjs(f2tu^Na(#M?SmQQapkQg@ES=r zD-U?MGNvU{RLMZtwL~EhWCY+6B^d**;-k-JBIt8ti8oPOx#eo)-8~6v&^jiFhNhZ1 zX@(PwYcj+lkUO^AT}gmR2sIZdP6GpmLN@ijr0n{lB+5jpeg3(*VXz(A z=mBrQ7#S?DqQ&?vP2!!=*2^BCNPl||zi#cvtc6k~m~HrsTHVsW0{S0smbd*)`rrTl zJr7P|(1n^j0PTQBH5HafwP=&45cCy!wnwIHX)aGL-uXdRn28kLhPuh5m7G|`ug%ll zi{+%9i&p^zvrIp+zTF=gn?R?TyeM4Vo7wmAd?(lz!gR04O`NWfiF~wtzIkVG9v?d- z12f)ssun)q&$hKS=yNyYWwFh9_uSIYLUttJ=08^IZsnWeo!L_vR*LPqBvD$yk#%7+1^X)izc1Bn z%;ubO5bd4hW&v3n4~OLcrHB5^KWk5B^^-U=Sj_v z!M-i?Y;N~ORhZfgDxyJj4j)0A%DOU-08XBx6~{S3WU1wp%#_{ir*V4p^TEc1Iky+m zqk&mbuZ1mgbSp|{NV8L3BrR$qs)+k{`Xw1GP8ODEec7ZLe=$tfO|bp=M>_fl>oj!|78H8`tB25yzDabMeQ8;tQTrKGy_n8}&ap zS%D$*Gu+`lPmM{J;>sX`J2LG?+)Nr5yhdSagmWs4b&3~G_)Ipna*g24N3e$w8lZ4m z=ya3gQ~`6j2XnGve}7DtAkU1PuH-s8(UO-VMngkwQNraG`Y`Q!x3n&(V zb28mA{l_7an9U?=@3=68C)K~d^knmtr}u6DpN|Xn@nZXb;@40A>4h3DNtXC*C=|`w z9||ICm+S4OkMzp|F=m8Z+>K&z6lW}0Rd_d)$NKly+`~BNB?Dq%PR#sgq1uG^Ehpp&CNSdm15 z!QUM7mn^AssFdYK%#o4{F$da7R(CCRoUbTkXbM>szTstY%LHpC6dAEUvOX--UfM}`D#^1X0HQWp4c4NeRAdE(ppQi#Q2ntxk zTY>%J?($cmGm0U>15pn|yrYzTEI|NUI4-fOpjts*INk4F*(aF^mgBywjQKrkjRzO5 zr@plFFE?sB{wL6t#k1pZA|DFv`NxDq2jo*i;*ZUCdk0WtDC;eS<4FhRKj%f}Sk~$P z>sdRuq#fU+*wc9)!(h6kqrdXbIdl}YtHYAdU*-cP$Hinv5#zQdbcCTZ?j z4LUdN?;-dAAZqnrJQF%lpUMn`kx#JV!DA?OWl*@?G8au$wn7$)6P~M*ThcK$4C)qm@aIqo#_tX4cIjSJ z6JU_MYAiV2`dQRa6_fhcVhZ)3Prp`#RKkTup3dv>v)A<7rwANj@Z*To`!yGXnN4$? zjKeM0AU@fn1IM>~-79OeRKOl9_Fb_L?eW{S_$j*R_wH=Mn*KoaM0do?e#P&`Xo@(N0s* zRfeX9ZBg9$UtYI*!-d}>(>tKa5SoN){jz}<#WXKh7SY35YD|VDKhVOLqD_WTmv$X> z6p(}HJU#!%Om1^E-83U9dMOSr{3)yG)92CEUcLfy3U=jb4JSPFgL@s+o@qkcq^#jN z^P{f-N+3in-)Hoa*}1jbR6&%BcIrWEsCOa74Q!`oAuS$8{-ax8v^$qM;yqSS{K@B4 z1BXrhr7wsv)-m&ju3R!L%W4Vgn$8bqmk25MSxx3@3_0_S@3pF1U6jQX*q!!_1Pi5X z8+d<*szzm!O((fW;CdEr(5~@+0O4QV(<&lI?1*kHm~e-Q~nZ<^>0nW}gHGb_rFET@F9}38|kD zPU55ce?Dr4wsWDz-Gueu_;WK#jzx0RdL8P1+Qkv>zIT-BAIo<$U{^Og-jLTh)A19# zl0ntb%-1+kl`F<-=+zm*e&LqT_V-<-mM0f-e3`FuOH(b&H2n?Q`}8!0QoQ3500Q{0 zCEr>zrJzV<*ByC6YjrRm)vp^5T!D#716ewjGS4-n;UF4(e2#7V-sm@-S(R!;G{J6c zg^FcDD7NS2Rc$_D5gp;mOI~Fb+F>RAjejZ89WPazJ#M>mVd&zw$pn7ki~nCwF7Yc-JLl+;%;qF zwj8Q9FAkYKFo-68)=Q^AdNs*ouuw|(dMKI9Ym7k(r6XT?Qzvz1wnSW526Ag^(U(!) z(=78Q%hJ#O3~3%dO~qi}#PH924*l3i5t5!A?l+!G7vp9UGzzvBJWLsnz7^_`%cpb5 zc&nSB#R!=qCLNVN{>T-sN2m5g%`hWvI1wH3`GaV8+WE}vlGLN~FI|3Nn*M^z?NX0y z|8iWL0085K-P=F#tO}9=tymEy9%)`CY}D)%prK>|hk!@C{_aeQ_~{^265eRh2i;%T zf`PZ2S1cZ67F3W|OIwx%Dz5+FE5v~ zre~ajqJqlL*U>xoc^6|XuWg3#HQY1GbC(hRoXNjxAI?udee?wJK=%16z{KfZGgq(x z3@hXyP^iyoP`AMlE!eoWwmoHNlE+VbBk7A>Q!%)4)y?*I{?EvCE=I!VkG#w`sQ&$!z{fX}OJO45}x3|?v{?$@p>35yZQ$sE~0Ayg@ zMBm4K{oo-o&6!kA0VztNoi=WLEWhF%D4I@YPVH*LF(_&}t(ctu!Q~{!wPvrBt_$ew zBH>bIieW9}3Y)HDwZ_{AdkuRs5BeI87dE3W4a|C3HI2zvS_yXLkN?Q$z-bC@V z)C=npMVV$?(*g>e)Ll}>xERyykLdN!a}@_Z$??Q|KylOk#Pcxm%tB?7q@VKXH=guO z=R*I(U#dAaLoo<*BYTqVreW?=&RF3KJChF`s{yntYzD%Pg%`jP~A#cNis~%!r2l3HLs=f800}C@U8q9vp zFy&`EH8%xEu0n=$=7@uHWThYz>N$(_1~(C=g1R_nC+*NP(JnU%;Y3vlrL=EL3)c^o z;I|${c{)ESz=|X2dZ|VG?NIB-%w&QZf>hX2_VPxyC}DnGs$rNUm=`*io=jK6<03TX z9)phdx-dLf&$3Lf)i^TZG5e6y#EL{MnJry6e%B9h1CTcHZPNH)FE%sn50a%`j+^8) z5alPVSQ?E4=um2~trlfx7NYq}{l$!t)4U1`Q47sAGr_`w9KpTz9P|4mKAccDlD@pV zir&|JXRkkaB94U)w_|F4pWg{7`;EZ-y6ws><@CKRkJ*(_@>rhNoR;*k*bj-Zy;}Y` z;!6l-#epoANcuTG;iNIhYiT2Ny5CDq9p~{R0*9oekuCnnnGZ zJ)PXzQEjWa@Yq;i+t}8c*XHKk>sP^>&0{YbGKL=OcS%MZP!(j`2Hjd%Pp+x(im_%c zQ;fW6tbNFl&D!jV#BI{6?_R7O*&Y`-xF(Eh~0Y)WHTuD_i2YDkS^QCI8&*m-pJOBA$;IWfOT8Z-1JOzyx%$gK zN=j{tk2)q{{&9OjYP313WTi1H6kI$FslvuvF9mX}+E*FF8 z)6(*^g54ky$)w!xK#<+6_2T7qCo{au;z?u5Hiw7f64?*>kE&jDVx7Aa10h^CZ`y94 zG|z~360(Bc(J)Nh-p$>hiHb9A7S`*N^tn5Wm+8Y5;U6@9Fm$1fXXkbM-^TeW%on2B zyy!1kebZmd;=pAm7HFu-W%Bv(_$YERS80zgzHo}-DwogC)*>JnlAMjS(F3$~i97X7 znU z7LVOKBfH1Um@o@aqIW|J0v>JVu5IU>WRD9$K8v?accOd_BEX4G8oEG9a(^QmZ+HI| z_br)gCk$33nXO=@7iPX?2>G1hZ$v%_COxXe6qP>cQEzi0dArL-;*fpW-z$<`szc+p zR20&^lu7_LNue_LB?g={=$~jP`u^Tnx6{L!<(UGD^6bRcT=1~AChDzK^QDHn#?P(p zfNya5qEyCnWK=KHnbK2IaEdq2G;i5anyE4P5rxn)p9EiTK#{sWwfXYp61oq$5wK1Ad{d*0 zN3kC`-qxjY?q9`8cIK`}jj&*M-SX^Xd9P#yg>h%O4g)nXb*L0`c{yh;EM~YOw{&rh zSz?KPkAN<1zhOA`fM3)f2nEB_WcmrKG4c`1(XccYIiJb85NY;k+^H%T*486#phG(PIuv>+l4{ReqNa`}LKw)+s(+Q!g_67`k7U;KZOL=)N zWHxthGyvbg*a48pP~db3<>UxNv3a)!%G^bX6w9(x zSSXgtoBza<6fe3|bV&1}Bm?`^&!mSRvo$=DM*YS!X&&?4Qb5lxh$U)}Hl1?@G^6~o zULc{BgKae#+2wcL#zJd5G)|zQ64rmyR-d1f&R5@G0sI5MzFvGYI21(*LjAbDDlq!= zzGX04zS&dmmBt(PHDBEjsk3IhF*;Ch)%zK!q`A_rmo2rlIgsttJ;V*&A)3f!HIHCN z<+j`My?w2%Y>?$$aEZZ35S}I38KK4)RBU9xP*_;3`DsKIlYep=9?_MfLMh7ygpUUJ zxSEt$9V~S9o8{~01TA}&y3e*+l+Wued^>T}=8nxK7}_YYy4w#nVixCn_^+BA^qZ;V z#Fa9=P7qXjlzh-Ip{fU)M&n_}iJ3_Js6VW(WI)3fvE^mLoFS#5dl$u~5w9kN3(S?_ zscdhuoo;dE#qgsQbr0Mc)dN_>R1OpN#-r<0Di{0 zcC4f1g`7wC)qAt6DHen$ndTJ$h9Ffx^Bl;;%v(zKw zjuc9B%qE+W*S|u)G&S5OiWdKI6(9CACO%r9E%43Q=LgE_g)j_6Ss%M&7VW0a#4gij zNam%#5}ZKk=3UOS@#@<6zZNfsEy@iV76uIjwbI{O4<$+8P*y!nHg$Fz@t%ut(MK^n z=L7EkmLU*PPiitfH$#DD7x`C}43 z5`XFo(e@e$ctGBV8=5LV6_N{vhhE5CvUzHs?0TKB?X1_DQ(0OLz4C?6=_>WNrUZ2r zV_3;FWAY?5QxOBR%s50}1Sw#e_w2Q0m|(ZIg!{z1ZuQF-D6CXsLQi+i4hY&ONjz_!6{C?%m*zmY5n=F zZPS5XWvBl&I}5Yw@77ZJZULF7>AV z^6&s(F@PJsSR<`x7^I3L^F{9GOMr?HD3;Rb%J{U(Kp-W)&jK0f`dMG_C!X(sv&$-D zr23Zx;IH$`0QtyAvNzS=_Es6^>;zwT&=mZqFvuAE!;_V_O!6ejt~H7OEj87{(Od2# zW#j9m!3Nw@H1!7HlgyT(gtx*)@iLOn7IG+#ocs-r6ni4Hl38^IW_Y zIyH0E9|ugtJSgb$D6x&gL0}rvmbWgz%_;WF(GH@}c7g{F+b8 z9k*@zt~j52`M83t!!PBk(&|E7?~!q|-fhSW6#86kL54MbSmi5r^gcOO7T(<9zsMjk zv+L<9p1S*qU7FS*-+IjQh*nXK6Nf6gq{JTOX81rXL!E{WrvzbP?mu4n5+`*%@c7CE zt*^6a!4Kly5$A6xtlc@fKz6w&uS7pagRQnB$Q_;T3Zz?tCGOLn_h=!W1bg*GdT z*LdQS7-9BSa0$|wlMz!6VYW43K8r?^8HAXUA3K#z6h1r{|LP@LciGv+^%Nm$Z%AFl zq7&$*5_vQCCblLiIPi@BUZdnse@Nm>4_DEx&7G;qCCE7Nz zFNZgZYT9KO^B);IEF^V`1+(qRH~LQ+?Zn9l`_p77?x02IF% zllaHhf8#?H+mF7ziHU7;iQVI;dQz?Js)@*p&WL=CzArl8+@Ji|ikGMR5syF5z|F8r z@}_NlUe-o|{`85_b8b!O`YZ9ByKo%_ir^O^22&@NjlJXM26{GJ#`90Vv+IfC^&3E` zGcgH9O_q{d>at{0rGL$k~=lInU)wksIOHBUgSD z7WJ!fPv^ZGj5HNb&~wEyYUwZ;DmXYrjN`T%W#AnosKTvuJ8~*BSZPa!Tf`u#&NQ#I zqEJU#g@RG4rm$#;F|)=kgEB7#-D0=InOoBJ*@yqY@g{;g-hE>-h%=3r zm7evvBD$y~Ht{?X7y_8TJPv_+7f@-8%h7ySw-D7(k1XWK8TWI4pO~V@*5wvALID}@oX3wBphHO ztMHeKn!=qTLT}BIl;FpZ7DYQ#>h8oztfIR1Wu(k_4mi}aS71g^HbW>`Z z>A-*J!8I|x*fP5dQF~60tcTOIP|{-wiCfoH;quGx!!}QSw80aZr^gP+Lm^=DW@vJgfR4gABY*}?9cb+qcpsFel zD^2ze*nl^i*E+BppXNNtfmQUAV8?>FYG5=r!Eg{Pj#12b_ZCa)_XRk~fp4V(8 zPG$HFzEjoJz7lZN=1F?2$8fxyG44>1_rAwo)&1)(DLUfOEaZ~qd>VWwuEFKzs1(EV z$@NjgR_!}>Jh<2x!`Z-81(ybS`5+`uRLjL)bzwx6;yY}vLJ1UuOYSz7)1XG|gdwD6 z&!W_+XL1k>;WR*O%lllz7H^i1)8glMI2_+ODNBkGJp&#|AE#6;yx~c_^)cvmJB54b z;dEFh)rN2v%9<{y8?Bzg8l-G{OI9mvRhkR|=p_F0FAjvBqR2>ymsoKygP|Z94D>nc zrP_qKAsL){K2}>x@_{lX4#BjEV<$76fRbkcWYQwqhGakQe|LcMJmv8lwB?vh@W|>7YswJR-TNqY+hOUn;2+rrLa6q|@6vg3ukd_980U{pRrHkx zQXv*`5{B!3dW-ip+bYPVWIN2i^|-|Pj^Cb20DonDcI7f8eNvBR>$*^Cm8EQfP^htv zRX(j>FfEc0kEsy0EPEkFj1A@2l&=#*XdO8?l$+>U+C24#r9#Koxv z7yq^|$?k?kPm<9?YTAa-_2kD>2ZUtXGC}4b(*o#uPDuz!9RayOqpyGXBj{$Zg)+HWS2!B1D@GY%oI;5|gEea+)BDyygeaO0Jq zVHod|G{kb}k07PmgEE7tl zws)OkwPZ(h$M%`Hnw7QJJ}6d+WdX zfabYcqe|)@|1-km#^D_P~9hy}qi~BbK$G+>=Y=y;9o#+_%ik6zao3Rzg2GAkM z=E;aw>==m~Bzfq>#h_yNgPLg8)BM=P*JaE9E)*kmXxga?L1t`Oc$bB^ z#?{j;4+bZd2*SyNZNq%lLkPJg{=1en>gxzmhy-)BCpvmkb{}!;I_mJ4?$g0m|K+T+Cg%zRV$1 zC3Xa97n|tb>e@EiXpML_uNW74#i?f2c(dCS{E64z{u z_*#`eK5=5}bdmJ#)JVj3Kew=|Ad$+p>hwtyrD?^K7=m52X zMOOa{n4f}#071{y`Ha19pLthJUC`w;-<|nI^f+bdUgq+*LW~p0Icwv!*UM9q#`5yT zE88>Tsc-d0gc zvHj$++=2c_H6em(La3mywBBWIbGi17%CPmlhT6CMuKGiw-kc2gpBHl_pQ|61N^N;v zn2bH?(1?Wd`zRopEv-f(jF(af4u#N_(7;P7IeX=WXI}b+Piju&xD~9fzT2w|Lb(6{ z`3}365VF<6hN!8ZZni(ap`(^qINbLzj$ z0UK~tn4u8SiNEI|>bq+#AZh>>`j?F=`DvWe!oOx$M1+e8PZ<(}iZ>FflUx;OZEu0p zP3}5(m8WG3jZGRC#x@o%cJpj{ODO%*f%L#X$ZN~G5vUDb82x;a=}bUt`k$vc3}EaH zsvcc!_a|IX_d(goG*fdZ`G8u6U|cky0(4qVc{fPHw4;-L;`xE>EJS7c)Wi+@2T$Th z>FMoF{BJy2eDl3qT)4@j!VP#ol;{`p_kIzN2ZbkY47sGoW8wnmG?r$`4aDflqtiP% z_sDG;j&Cq@?NcjBxhP#PigJP~*0?Qt)tjs!+Oq64NwkYfEU7HpYC-|ZG>rAaU}ODh zMq9n7b9~5Wrre;jT5X;Dse>QA>d+%V@>*)=dimSysu<&*u?Xt>!Bs(5*b?Iya7A)g zU|4JwHK#`ncl|}`@w8}jft1?iTT*%F+YTUJR%ZRfD=mj6#DFFGi6yzv5ww>KoNw`A zqcFXRWBKr~9w)B1C|a@cq^N6koB5==HJg7e=KP`d=4r0vWoxeKx0DCsI#M-fCdE5j zDU?dm6IlntRz+a^@ja)z_lopg774MSy8c8pn$F=hgf*7FIx?;FKF_PyjTUx4@%#ch zdqLuly8d6jN5-0ul84SafAGW>iJR|x3U%DsBHSvX?x64Nu`YrX&R@mO3|n}YmaQ589i~IVqnFq<57GB>Esw3;GD7)+eAhm!RkxqcmCI?=C0-6m3Lx`UfIYMe{&WP z(JvKpwpj4e6LK;&Ph1>19hev?pKmE^^wEiqraYvzvyZrGbBj+{YBXRF~|?Y>IC;u{>o&)c1?mrm4g zbxWI#WX~AMUwj0h{wZ75gliR*d!tDEPMd$ZXj@g&n_9vesH?PKqFk^#PXkok zVoDo)8WOmpO?w5$%uR*%g!{C{+lu2=-5a5*Ni3c`IHP?>zd17&HjZnrrY4*ao(u)N@{E+{Ccvnp1-9fDUuA48y5Ymq0UZ-L2=ELGZUP zP?2*%Sy1+xBTEZQ;<1_A$%DsWkrEb`2Tk`}rQ4F{APc=x8LKOSpdk*2;&r}cFn;qX z6`7$Xxg$ewqi{@G3~q01#^qOhC*7~*kofbv{@Wj5M1H*d?)6^D@ADo-CqHau%dA-n zL=N$oRb1=WW5?awV;s1a8}v#n(SnP3(-4&>*V!;Nb(mYK8CT1qIinGkrZjTBvYktRP%V z>AibDoWRG4Ux4Pundcny_OW>F!^+~m#b`t2chf~NN$RyM1t0yKNBx+d?%TP9F3z6$ zAqHEpx`RkRp$tL&s!P&mU&I9L%0O^m`T`A|N`RpZe=WHY2S;tqC-)(kUa4T9B>!P9H zEGy|Q!WKp8gXEQY&48mcb1l^em5wDsLi2>=;A20}I|Omdid{pPGuX?p!1nXlu*#8$Bs@s#$ zRKW=;xeTp{^4h@}D=3dP96#E+=5R5`&4}v+DqA zSS#mYKW{(w2tHU_&YwP5Qch+A51>_$BuON~JA6nyrt}O~W1IT3nFD{#bAABMib;BE zw%5IWFrA-Gop#*D$^#@G7Z?>=yHhzMv_GHs5`L0Fk;q0JKv?AEp47+Zz=cy9R$YtP)!KmXca znL|<R4b2Ct2VI)|r?L9z5;mN>h?{(4)!4l+WAyVHgXU21bWh38_L}y$i z#-X!@$87Y>Li6VR1?EJo8pWs)x!GCMBPG+xXZ$4B6GF-J{$b8LfB6}ItoX@otN0I| z8yVc1P&PQf=1TVvnbY+O*WPXT;bKU}{<#r6?#=NLJ{^ zfN+d1j>%Qp=1V60cs(Kr8if;#v;KW6T7h?9*CH-wYtk$p&s&v4&PV_HJD8vOWjOt} z-&94;M^cA>@$}wyscWp}DqsYs)3aJ(Vudou$_?wq+xm`NnOO9@@wTf!%1-5kp)vSo z_g&MZxU4pJhq^0TwVQje-xWE%uv!Jt#aE8#hSlxo>*?yG@$_j4@X|MyjxJBn+-rmC z7AS5b>m>l%S7v5ngcQY>9nxhCOT)foMM~)a2X~2kSfNV8yq2??3 zPN6Zy_^R-GXaCg-JLYMOM8Zzc1wI;FVFI9#l1E!DsiXbk{QHcfNAM4HaU+!*)VirH z>mwJbQQxslG162w#l9S9-W{%1P)?1*;s(-aA>p@MHBwV!r;=UO-^@~?d2b1F5`HnI z)_k7)_`=O2gBr(VmRWr0gBzVboyBJJ_lSvPgr&qOp)))gRpNR_FVU3?(5vBq+ADsL z>WoHByR_#YUqqhOuXX`6k($%Lg9u~*|J7r&Bp>Vi$|Hfvc%IEK2o;YBMPd`oP*{fx zstJopUJA5&8J)(BTH*WI-wLY-)wf=$Xt+*Eqq4S5lX>z??gF6%RIaf3W>Hje>Qz}$ zHr9Cc@>4e5V!^vbpNaE=Y;}g*=n=?p%JNhc@)vs9NceNe$+fmIe)9i!H#GB~sp=88 z?qx38-JFgvjnl7tRDpxJHw8;J#IL|myM67e(4-Hk;9Yz#n1Ylo7W0|98G!;kyo`{ z6_7l-)B5nkhc@Z67tM4GdE$j{=++XZw@~f8p@0=Pnb8Zba5QI9=?6}lN7*^Ii!313 z9Cp4%?Wy;dN>b$EuR8bkXACVgzqQF`zvdZavolSfZ>p;cxnkoJ5HvWyypz+snE9IX zqbTRA_@mlf2;SZ9;aq~G2?|bLU12iQxZPfzJrmgU_(7VDX7}gj7u-~WrVGW4em4Xk z$Tf4hw2)WW>Z>1^Pyo};&dX2IF^%fn4~6i*_ggm1@x_VvAl#q$EPDI(tITLb#DXrz zIjMs9!a-mojY=RtjT0qa8X!j<@aqO5SO~G|D>6Yse)h@?D@!R46?f>DGR>R0l1T5) z%76){9;jzT-&ZcW)4>mBw6c-jeMe8x-H0;I*Kx*v`Z z$?Twc`nZQ!#B%3T7Rg7G$&6~ z2P`$T=^dFq90;VNRALlN?4$wB9E-C_Uebxywph^SMiAyF!zDwb2^M}0uhy#YjIp#{ zwP3<&v!xsOZ3GcU^Z>j|VB$MPyOK~}DR=fPQ!-!vwksF42P zdECc~p-x-FrXGB_#hJKs1zMU8m;F7+nK>5(gMCkJv2xl^)PEW_$nRakFE%oqICxxt z`RbL!e2U%PWC|s%@e(QC%qSLxw@Pnl@b-ry(oS~AwP+$+0E4g(t@h8Zc+&EV+Fco^ zM`fj^F`8h8fF{hUt@Ad~^7q_ZSNgB&d*#YOe3-qPZ1>JtCKG`D}ygc3tnO!K{;s? zlVU|Or~DDkKczRB)oY4J*OH$1ONYHkFGe6{Ul(u8dFxlzfFw9TDKH2vvrppy1rRRf znPTV?OWc5BKf%mcU0umal+77^p(caC4vea`Sdq&(hLojO#wh5K{gU|0F3 zIFR8{Wx`C@zQm$Tj%klL_f_`i7=F?%P z+`@)8LT-R3A2m4|Rv!o~)#76e+4!3bN;v#kV{sIkQ8lf{I$^Mf!=*`rNuuB#Yl@)! zX4|s)UxMWW(baenK7Cb4ae^ehUE7`cD7$J`{M$~#iC$|C>4KKA?^wHn&?OC>YTcr~P=1%rkBaxN^mpN}~EVk;8~=^-vAX1WTF zl)QJ-^IJsFtwXd0P-+!sKHJgYI(8dn@vs?1xcQexsFe9RVuuXW<}6=qMSa~=oeT;e z`^$ee%r~{k%YeW5e-vAHl=cN~_L-54r}??;qQtBc6SJ^l>3lg{5$x7F1ptk6#$-}c-0z-7&>A6@p3t6*yY^Wb$O!|uhfFpUty)L;gVy!A@tWfmh z)#94_IIa~N7tU(p?#%l{%5P! zXDTptQTmuV%Z4rlhM!F|X|OV@VGaewo#vR+M)2-SZwEF^cNFAsndQe^yO}G>SEH1$ zu9U2t3hD-0rMctluGef{NbV~#;?p&IIU#4}9-4l|6946e@6;?>zkMKzZEE6EN3cac znh4IIuw}wBK*SJp6*5Qwf234Cu=J%u;}lM6M(2%f3{jpM+0D0wvhuRx37lEZ8z^aa zLPw`a(CRWR#5@+Nd$-uwtsyG#0CU4!RkiEsT-c2xyh%`UZTI)gKm!&3fkCGO&JR|L znf5jij)s}wd zKk<_=Dl&8~LEO4u6M|HTlPaI2LU##iCKAKbE3ZyM=Y7(x77bY`1TJLHFf-mic9`z7 zi@P{{d0+67dnS@?s4)0Q4^wNMU5E09JlLJhPn`_4WEIoAMxIhB5p1Qi^|Q6Uhht?? zbGqE@-6NB42IgT5s9MHBJ_t}^qmt3=PSl+Iq*7S0D|^PRWJlNK-DGq8aPRJ=xwCvt z-ap`|YD(Up=J*GH_?K_;4eQ&aKk+Tw@`Nty3GtQL_0orojAl3B8iOoN=80ihu+H*h zDLG-JiQ{rFrdYTT9`=0dg=qaETkga2G^KQiLC;y2uMgi_{P-kn)1Q4aa6abPOgYI? zhQlF}fMiZ_c}b#1XoaTyytBqoXVrUe(jQX=_AQ{XAkZ1mU@H`JshXwXPM2LX#kFYx zdB!D#rGn-nU2~CZig(;&OEmK<`6``?G?C1cp%-4U3S>J`;@rF_tc3iV!LG-gh?XuFS(vvtSOI?boObkhg) z!jAN*`|u-DB|Xde%t4!E<3JJ0CY`Y9Yr~gXF4oh!%jKv#`5y zkj^~ATdMBA>$%Y@dY%YC*(9g6cCJBstV}?Q(;$lN2dkdFRd4lE`GGPKy=I33v=9wf zSKOEy?baRd1i~AE_fRXrUgqR!J#Gchud$`G?_NeMdW*K|bFK)p=RH&uYrn+W?@Z?+ zV*$&tR-&$qqt=<|oB0S%F@MI6Tp<>V#jnH12m1 zmlK@%HgcT5Zq=ki}YbN)BkPfq{EbE!uYqL9(; zmbr1iqO>Y|WJn|@IO%8Nqbwy=#r?BP}pIEczQkau_SP3V& z(xG8&g{6~@KfsM!2T(AFx8Idm{X*NJe~egtF@fY55rGuZifZP+n&S|oIM>qa+|z4b z)irnA0vtJ^-}n_$`t@dk&)a=Q$0ThT=9pzaM?7Wzqx>nf{$`Y7^Xo05IkA1M$V?f{ z!dyYnU`*7ILe}-E_fG}Lu*S@HYkLl6+!M@QzB!Wr%rxxPf6g!L z?TO6CCo<&Yj3u98P!YJhftsWPEHR}Dyg0(A2HsK0va%e$tqg5OWm0ioGg7y)Px2h= zu)OQ@F~c1tRi71Tf~Satf~bn1nO}mlucq^zXQ6L#j9=mz9qHNV8Q(cafIzY`9)2kS z-z5d?t1EM?x+!PIlks$#xzfsW~OXuu9eU9why(-7@}+)KC$AjqsJ`IydD-r(izAG?lBOYN{5ZI#Sa>*kcs)J{_~&Ai2}47vFtNU!0#dO zULSVg-F~@jGT#$2V+Qb%*KCy|at2aNZO1(R#@T zcFoaKEvsf>@RbNU_YTvp{{TB(GUUh51Bar%Fd!^b6!MJ+dQ{+9=WfU}@fQ~>DWdV4 z|LW(z0FJ^{&-k|VHy(nI$^KSSh(CBzxicy_gB+bQ_~$_!w6J&*iA2}yD@Lgh%8AXy zBrqorW>|$6Ss!z1^}Q9Q$NOP^q_MX@`G7;|xmMq*gw%ykjxOUp%+UjS2$x|*jE5OT zOT6`#H;&dfG6x(a&nIvo5zQPy*s4iP<12^+-07k?r11vmo;PeQ!M^y03Ct3?*Z) zRm0=&HgMETx=uYCf9y6*=I}hbxil8tKz^^vgt#VzWHPu9#s}tb9HDJ6hZP8q zUQ>>5KcDQuqPtbCdB@f~ofTy!>W2)j6G@Sc2k`%l@{LMufk>V;xdNGz*=@ z_Ok`+4tb5IpN0Dyp9wU8{N_-R4(67mS6yWJlH|)ir6ji5sr%0u`jcS#i^20D+cxQ< z@3qG*t_2Ll&VtYuxea?QSRr;i(2nZojY^c&&o+6gXGX8x7oOh_J*Or3%=Po+=zMb8 zoGE%pJ5TfpWH!RQ$5gV@rpl}D-}mF$K9-3?{hQ=~@NYez1$QF(fBH>U)I8-W;w#3% z_4Yd8JivomMy8Huc?&YNH~_^ScmG7POl0(d6}kf(t&b|ptdkydD#!t_;g{lfkz#aF z_-blF0j2nO3%4+0O2G^7)bdD49izoObZJFgt+7@5(!G>AHwu$BP=VTrt0#tg5G%lbMrx02@_ND%CA>(w{hfX*A@%H`WlGfX57E@ za4tVHynHvNv_RG=w}fjso}*R2v?@$&D+<&zL6uy(BM-l1@I(x)zuGY+#@6*(*m~Jp zl5qG8WMNBj~8J@t@Fr-@wzW?+G4eP zJ27ZxDhl`{Up*B)%HvP5YQ@M$)tlzKm*=a+FLg$ljNS>~X5Euw|58l(utw zXs;SuHapLwMe*BLn?&X_xI82h3l^KJG>=w!CZ6Sg`N5vRt+M?YaM57AkM9NQ(%~=>0dIp8}32$o&`FKCZv<-0GXr zN7XFyarig>2x)V2;lj!%bUndq>c+9{fL1I@p;>&4*6}VYmn684KA36zVBCdJ5IEA$AOM(vsJ)?TV&t7pr+;v%g@zePe(r{nO!v3 z_}QCcd*1bF)8^X*mdT~8P#Z}eF1XQnZvsd6t+v)cP)$|v^?y1YDF%{ROye=xB3aI2 z$Q~g!AOyT2Wf_HXUN@ipg`!MMk`^K`BI?-R(0>Z@zmiKwlhK^p*jf?@*DZ@E_g9sS zFh&|t@F8NC6($9AbK`1wopWQ>QQhGt_Dpr0h!7hOt7SD6jQl&&) zYzGI&%dnewIC%)MV|^k}5eaeja~u@odNl%VEl?^zvTRwt7-3*SSHoYi6cI`GgNt_E zB^_m6Ad=q;{(tc#e3PI0-~Cq8$}==o1F9jKbIPitlLUF7G;6`qkbk8jxubC$nf0Z)fj`G^YWM5V>LTqVZrpNyq(4&x)*Fhm;M- zI+VXFRmL|I8J8D9N5g1M+JEE{_+!*CqNG?#1|&f9GCtJvX*z-jXc?<*wZR-Ln|qgU zV*((;Kx76RD3}}D3~C7H)%Ab>A*3;ST?m$cRa*6$XVM{aL!MdQM^VGd5u?_8^x%C$ z-+DDOt4*~Vu36BTZ<_wVMElCzPOPPDdriwDYRCHz??2+_v|Hw@eRF>D3-Vg-)zgWl z`6&tE^$|O+Ou>(r%G$?i_n+#G&y}osb!2p>e-_LB=VadlWDelgjYvOV0P9GN;!MN@ zsP)iMkWzZf&+sJsy%wk%U$_2m{~FePC{Om2s`|rEt_wkw=wLTtbv$lvt+|5~AEPxK zM+1>^(`z>8s-7fw@~9PN`h|QWSsCIusVVJ-RC-yqIo$O!NtjBiyLBANoM6(%8X_18 zW_j%k2G-z>iK?#I7$8;5qXj?j24XYc8cOpJpRpxL078ve)OLz{WLKKT<3K%V%*^8W z)5e+LA%8xImpkOqg(=qR2MYVFjMhU|Gf-#fmgD&c6)~v2{JcR1vzs>`{E*U&)^y+5 z9@FEqB=Z?vBJ)_Byvc^T?ihX7D%Ba`2@47q-HZGT{fjOMChLBMca<-g%P z)>%(3FwbW(^R1RE-$@R1mJs~D;cR!O65a90H{!dkX3&kA5N@{1Qwz^I%tkdU_~EhK zlYTVRM)NMp>Rwysm|}w^Ijtt*F>2Yf6;eKwt1Tjf&_Bu3Oh@|P$rhKH&DT-^^*M6&`%|w zxe%0fv@evFD61&ysqj&;?FrJ{RL0HhoH)9Y^o4{bxqC6X@J4#hyRvQg_=b5yi2Y=g zIpr64yIkJpktczc&r*ZK+jcOogZf1k_@G^@)_1p08ub7 z*4Rr zZH?Ur`pP5YN}4VUB~SPy(opIg9RG4)-GXQMuak~uRVMy%TLYfOhc)v4HuH4N)k z@1#wFqczr^Puz=H_kk%e$E#GP7L0fgNgqqjNPi`+g$;Yn(6U{}Ct5wI#ai*w*g5*2 zz>bu=msMrv?Fy5urIcKUbN3d(?u3mUsfaCex6rr{Tdqt1lcB*3b#jHTCdl|DTX@<| z1lj8%tTon%Rm94hQEac@*`0<-@)3 z$tR+@8%?O9q5_+jbXofrRmqEsQSpNrT)@y_STi_5lRWp7g(PffR$}FtW-Gw?)N_h)l*wYE02rV&g^Pg~qOQXzH@c4ok4H4uU}ndTxJt~j z%(N6<>RzbLk?u=zyLcIE1u@6*a@8w}GA1!<(_B6hzy;2>YKee7&)&=AeJ{Q$!`H3C z`u@ac=*l-{vVNHKC!Xvd32eh^G_A&S4Xp*4jo_@$iHl;1r*STiST&+#KovD|xm0_v z9J(=si|jvIj~C0+Nv88DVTQRO+|3K@qBerOFK_DppxGY#a)T*Fe>j5EB|3?PVK#e7>>e`>e`kM$;C1!h z!%-tWIbu~%@_qoZp~=>Za44{TvLcQ*yEtfBR4Zodd-Z#Xwe@oP+e|9}WdtdD5}S=f zHSXv0@Rf^icuV(SqAq!inbgsx+v?2J=y5N&87bQs`)NrRome84vf^D5mSJANN|9=% zYfq|n6v_T{|M~@7P$K-0)cad+glcawe|VDcm!G=vdojxxvwKqM{o!A3sa|6c zyIY_?wcQ`~g*~}VkcD2=9*-H_5DBN8zi?I5z18HRt8dPG<*(ZdLI|#AK~Ro1)?c2I zbdN5Iya@>~n;tAiQy2>?)9ER<0%0&Hb~puum6ifO6Dd%gj0kH4Xan<=m>Teo(0+s! zq^URq)^M)ThV6CdgEC`t*EEU?xMYd<1r&VZJm>JsIT;4fuueV2`+~1ruX1I5@9EEU z7Rez(b&>aPx!(b=faku{9mrF-WOGW6Yqox4SiHM%%d)Rtw{gWlTUtkvw&#Ug)&AAO z*RQhQ)P|3(vR!1^3q4o*+)3Yr@Xz-^DW#+LH33(|b1Jw207eQnec^Kk)jSi|X!TpL z5P90c#78i&fU#QEMf@gzPawq^-+q&hgj5OMlFn;?_y#N5g^~N?U^3s%`r|$my_lg) z!dyC`rwP^LFE#`vOy&2Ti&$`^n2VOc_HTMQ%QBPV)kSrMG+mu*wuo*Z%$F>7Em`Af zT=*;V;aT*CH)9TAq7--FoUu<{rf zWDh_AU13aveLYO*$1+GI4lqAe1R%+Zj$NFC1HzM0YI~O^%kL zgQ%$;cW7+DHjZmm+dVu1j-YdztlHi8gg&InTdo+RGb`l*K{J305uVp?YLMJ<+n5no zYHCu84+}N6F&sjT!@9)v!TVWRDQKIBfb|#vN$vh(_gVkqkVLhrqIK&kh@64`?RTGd zJrwMCO(w>F@=+cS@@EbAb~99)rRs5qQ+A)TH2(uBR)}jia8Fq;a8B0NlXXv{VDOOp zLn_mTgEc}LcPrD&&4m9>+URF4p7OM=X0q0ht6>zJzBzKxBv7;bLbb+r;$dc&L*j#5 zEvv(<6cjffyEZ})6ez8Hl90!A6=p*3Hl=3I2niKjL&MJnCT(-dbEGFaNrS;d0yS?X zLd*lM0_OP7nVWy^uNaLpq$!FweMIw#kIBw6lPvKeI!C)0CIu;)8Vn}hp#yF~n?W?a z;p7)%z2OMKQ@FA9oWn*lG9z{{!5BeOVI_(_=MqM_c6q}*dOuzRlB5*k^Vzh+0bl^o zKv|H)0Eo%h0x+w9lee*o%c$A9C}+^*%Jb2fXR;bnRaACinYRY=DSG`QwWo<49zIT~ zEZR4EN0*}kMPE4&6++ovPVATJ_H~thD)agG5WR&cYE!QMcD{S)&#T2#u2HM^xhMGC zGlQq=c|x1bJNKlYZkhb*D)bk8I9GOyJ8bRh$5%JsTxH1XhlNIt-2aw&KD0VNiKBNP5V z`L6p|#?a}%`%-9|8I>qdV7N7j5sW9h@-_+{bVc4SRlMoi! z>n_)&rHYQ7-A!bhk;{v=Yx!vY^lL-)XVlSfM1qG*Z7f#wMrS?f;rpn%E*m z^>sYRFST?$;=kR5vUw`}bGVnC7;<>tv+B4-S=05nRO?yLOmiLZ=T zeI7wrI~wsN*miyAhGku8$!%@nvBVfG>=)oBd#Z->R9jCx3Hh|8$4chj7aTQ%keKEf zp5Fn-KB^P%3ubEm#1nY%p|Zi&yPZGzD~B&U-V?M$1$p5*0*2TuOKEz?MQ%)y}h ztCgFeESE{LKQ!@{f@j6?12QOp8rpjEp3aEkvH}{q@o6y0`Gu&rswaxdGosJ!%Y-af zhHSO%L3hr)$}c0?lD8U~TMT-_F(r=7x-1W+>-BAkH%w-0INy7vFn#Gh+T%Pee|W)s z@4EeQ$;?fYb-~;hnT6NK%a(VY6S{XkESQeYW9CiV)^3MIM-@oP8NW=cQRK`I2} z1wb9>^JvDX05dBsj!PX<3bm6UX-ay+HS4l$m&$?0JtAL*%0FvpPI2Lf~_$v_|rt%(nTfKMj_*lTpc~eG)q63@e5fmm zFU{jQRjuNuH&X652agKT70t$G+`S_#kCqF}u5;8lpZSm*_b4OV_yvx-@Kuj`kSbv? zMfP&CXGNeZeIv6CiWp8g=@EIr5wUZI=N{n5M|Jjnn6t-UJXyXO)T^dB{=w5gs2DGd ztF#u}Pd%(E(C~G?a=~4n_qpNHK)UsIazGwv)=)!~p3-c*tu()eGdoGmQ@vg!|WCqtXnwt~O_ON-6 zCB{6@8Mx(B3`zo{I5CKQ#Gu-1Nc=jNsV1&Kd%Bq!uc4CdTzj2j@MP`8y=ONOY*4JC z5K^6*OPv(y)HauZ!Y~WsKRR_ZWJRq^FTY)l2-7hI10R6mNh3BU+EoNse(10eKpXZ9 zFW&Q<9@sC}Yarr6V430sv(YIyMRUSG?|GC)0rcC>@ccqLN>H69?`QZw_4bS8`)d3j zJV%+N-3fEAdWodcs>-U>INzo*3WU-d=5q03=c%wB=VyZj3sYW#(^b0ZfmNAEp;)WA zWQq(-SZ9@?Wab5ozSTKRtIpzrDpKW$`9*12{dlBAd$vQIx3OZ7*PTRzuI~CD zh93-5>?afr)P4sbtX3kAZG0Wx!Lx{v#9=}s$`Zx)1pLu+d2}BrDasm^0j^Qb!s9hl zDMzqj`;fP(jV=BU3=`9{^t|-k6Yj)MtVh8m@>CJ&Cymy6aNf%`!KRX8sRR5&E5*FH z{8NfCg$d~qtfd}N!dZ*AlEaTl&M|#_CA0jLmgs|G;E_p*xJ=g9MY|r8johJ?G$_rCiPF(AkhAG5E&Z$%7`85QQ=2nF74!ZhOTyK;U zWqBY(s&KRd5KJ)1$~`FzhkYl6ms`1%FX+qF>3s8qWju<)M?DHdg`k`K^pkq9GJ)5> z13cF^)T1fc76tlaicBO}Accf)UWY%sxjO~ly~P(FVFXeiNv>?^nIJiNHXDVT8 z>DX;9LXG-F{yvXjjr2jjdS0PQ#u()F%utSEZtL)}Q~Adux!*0E*c%olRt-#XSg7$C zp5%QOX=MG6*e&fp=N*>+P4UB%l%79$@}&y5UZ~p8(SV)iLTq&3)N>o@3E!8j(Eg3j zaqNZCYL>HamPmCpkLbTn`mJzW2{RE6X>32~X%cIwqA@ zDS$08^J{>Uj0g^YSO$=@kNOh|FoU{n{mCpTN6JdM?No1e2;?cQDrmpWxF(Z(?A^K3 zelj)cI6OrYFXk^;y#43B5TG)7UFm=RCQ$M`(N@e~Jo#g*`!(=Km|cwphPP2c5lPdBl1I`yF5@gzBleHK#;5_l0$h(< z?>}38{X)x^fBA5Qc!=ApV#A~(jF2Tg`7B3Hzp zBq++dn~Do|agA=6aRZ+|&*^Z z6PAB#9_pC#DiwXs%fFAZhv~FNyRtlQ)04kEzSbD4C3k`E-qSZ%{ARg3i=i|e!~%g) zoZ2Q(2-CCADP+)-812+priM$Q%~7im)ji|eKE+X$s@@Ol|IVv21J3YCSo_1bXcn)u z=G}^?zoe^!=qvM1W;(Nkw2F&BDQYJ>$+xlx;2yf%=>x`seOVqEY5mpvs7A#EsGVtB*+K}zEs`q(Tt-~QwVnfm%zh%TuwQOF#E~g2O zhk|p9*F7VqG#iq+)_pvH6vfFTK1ZBuZ@;NVRvUB4yh1b5Q!U5vO{?JT?1wbWs6*wH zuP;1zdGD~)+c5b)b|=qJtFyIrXBwKA^Yr2~Ba~8UUENrK+^=LlQCG=Ff2NG%I!iSJK zRl_!7N=S`an5=2h{+*a?yfNv4F4#CF3d8b_z`tGH>!Zmq3xJ%JxBRDVuAabd^h?#m_-g;Wlf#b`GZpD$nHr`Rs?pL@D>&vHth z)z+K-2}5q%t@p#)$D8#Urtes%kK2=5!)FwJWk(*gGt|>1)ONSu{=Luxu&IcZn)yuh zUE=T`>Y%D*;=fS1k}Rf3+vM1!Wmdg1NURYh2BM@TXayspwP zyHbX(Td^OCK!m<|p#7ys#1U_CK$38GUi*4+bR^MIgdyV4tN|fb0~clAsu)#buxIN| zm1(^!B;;GvciOtrz%pIt)a&S!T38 zo+4p}4Jv&jJ3A}m{q&%eI-svK+D(|dk_wzbt(G1(rvs&S>`|~T4|dn2)b_Y)Ze5{? zU|``E0&}b+I$=C3oP~Bd?$81pOPVq%Vxe%3cmN|*W_Zh8F{DD+U*ltT6J4E0`!L>w*oWCEz=JVCtqp2k39BaODPUMa zRjl75Z4871+}FpKGI*^Py<8<`-RitNX(*Kut2jd2Q_S%wKr>ie{cW0B4(Xn>nvUQy zP-UX&##k3a$E*o}_Ka`eBaXP02=Dc8n*8A#bZ3{DyblfcCmw3bq4?Y~L`|x@cA3aF zv+tywr|U-3WTezgCs6Q(e1AUbVYU3gT?Y`rF_xn@7O`GMz)~^HJomvry6W*fTVDSu z00#m4N9;);c{uwiYPkwZI(M`nqF=RN%9~4iGnKV8rU1>o5(6Tt?-)7zJcDc*_Fsx! z{~paFIhAv_-7m8|f=@1oh+QshzbT*4$N)f1nrKxT09&>!M<0O8_4A8|^OEfqhFmPq zp+r38fL!~R$rgYXLfh+Iem`kom#4DQQ%Azk`90baD61wg^=xR2#PW_EptuYWHpPq! z56WbwCyAqwbc`gce99pzSR2Ywy>Lylte^^eR&U=2979z#uIIb_?ZGk*N~R5u?^Nz2(YZ`&UDse!VE+UAq0O$$r>IP-a~;d+mc& zP+?%Z!x!eGmA8$eAH}k@M9q^sebr|C-%xizL-N&}Yeo6m=KTSKrbtJ4qu6K(m3(Z3 z1hNj72t)we?>^U_FMmr^pzPjb+kj>vMf-R-I)&%n(GTlT?wDxpN~xE!YYQFRLcre@ zUt|Dkr*a5{DZr+sE=374f< zN%f7+fv!XVGr0TLtI!!C3KGD7o@}NnCxg7t08+%BX7|yqXYvh>^-&n-f^{2T=m+dj zjE~2nc(`L!6xbAKi-vk!G@|#fFv6Yr;+QCrbo9D!znHzn#~CKF!02TSHMK!hbihC= z90$(hyUSqhBWlhK3b^=kp4DQOiU&m++!-IxXA(Aj)h4AN)#za<^r zQ8gs%i^u`tKl&EZH`(Jl0Qv9V`tu~S7^sz2#{|N7cgt~Y$z0$m8g^~W0w!57X9$gU z6kFh5K-vgZQjpkWQ0~dkKxI&pM3=l-{6<9$rgg(JtoPt1y62&DRMo-T@Di4n>FE@h zTentKx@gHhXDLYF)Wb``}dX=;1tD&huZLK?Uv12L&jMr!xBY_kYF+IhAStdXuxKB<%C@F>dks?L(>V_$66hwQL z9DmBme!(=fD$j2P5lCnF_W%IgW}hWbCdu&sr@jqdS;Zf+CQf=}Vmj(T^HM~s6>k$y za0EfyY}`O!A32HFe=B5BO{>N4+=qZ&E{C$PgSe2A(?l^k1c!t(zvH|0jR5eNMr6dS z0v^aukB-cD#5tyVQ z3fD3JNswb?4__bs4v9AVu}1WpvtIVd+0U;m_YEEMkb5MkX%B~*X9sUlv3k36wRV+L zU9^4)A&Nl2NUzg2MMhClC2eB>{p%+|3Lx+kXH14{hIiI7{IkrUUA zt4+WEL)2TdN~RTwyX^4ld3mYX7fr!~AI&!&)Px#yorEBtTAfZ=2D&kcBNfr{mw8)X zJ+kgLsrCQpwOFR~P|arYy{6YWyzRY&tlz(;q=lhcTJJcQ!QAKTQGiAnMDz~UcT}3_!&Sak@ z(N;k;+a&|x{Y^pE|rev&?;m%us$Dpa#2`yqFb%4Ly@xVd$i{Ho)=HvA`CEJ zwoP>vfR2zQrXvR4E5=fr%Ph!LS3*e|x#FuKDwrqBc4IEztIN-rHO{7f^dFbH`T

PLWUHX5*IhyRJJap1~gJ`0wREp8PGa76y8;GNhj<;km;YM=> zg8?tPc{DvDt7=B1u`xhK5}Qh}GQ0jTtlW94qiSD<_6O$`TU93Js{0o%vOF}Sooj%9 zwX8$Ga*%R=mqGeb*oI ziKvR@47dtTa$TnyI0r`+=DLMh`Ck&|P%-REubJDPWa|iJM{V*6e!9>po3Jcf`<7xk zDk$;}w46{9`B+2)ppraxMcF2jj_Y6k1CF`LdSENEQ}TcE3-iE<_~b?Ao)cQ=bZgk zi}QpErGMfSQBpRPl5$^BS1|R+-tD>D;&KI&Icl!&dsR0w=bH8h!|+iD)OyE;&v_=g zNa=T}7HE@ImDZTIOYR#vH%#nS2i2&qW+S{G&*GrLVkD0kw*_g13`ZF{5x6BCkQ2-q zrtjzomSR!6dQ>&~xZIpZroN&Q_+A|Hs*wJnY2AFU*OQcx2nF%6pTlN6*QKeua?h*k ziNO-8_kvwRzg9R5UUGO6b2*JSc`P}O-ELxTCY})DewlWxO+-WkLbdUcP%_JsdOw}w z#fj^C!b1FQbH5&{4pQH$JdO&PEg9RI$;3Oi7MMP&h+B#$PEfF56%vXy^!c5r>irTo z?w()TGvPieJ{&hEy0%@~a=dL?3geFxEWG(f>+Jqd*8ksBA>;2t{DVK-=bQXT zspH~5_?NuXeQDF2qUT(;;ysabzfP!B)%<6xILGg9%ue)SiTrH z1m8RzeV)IEF2*{Zr1w>xDl#Ln%;cV) zsDDqyL9T=0;%qBc_RiF;Xu=TYg3?{I<|Blnd`+GyPy5bZ_dxSUJHZQmE7FK`u|Tg| zDN)~qj>LiLHF;^nZ-~G+S**;rACB}wm!HQS>8cRr@@u1!Zf;u>{5n>qcJ3Vi_IJpB zD-r+hL-_s|AC+U-`t_u>KltETjj7&%j{6~Q@J_VhOt_)1 zgw8FABGYO6$4#`DseZ?e{%=LFMUruKB)kFwTjDOGsZnp+6Jy;R&DCL3^ z5dN+pyvFB{#(-ZJN1dX3_g5Rq$)7I;{LX=cni^usuiXPkx8fGyV$&v2!D34Xi9EBL zNYK)vgVMHCQOw=t=CC&G#fwJLKXqP4W1`aeTYVR-m|F06=_CCm($s(Dpz!~XsjCcY zvTxtp*kHhbZPZ9dk94C!z|q|y?dVieM63Y=MmjoGx&$N@dvqf$0xB&a`k;b>`5(`# z@B80}`#ARTKJTl3*YCQ{Q-VI1BWYqLQ`JH}Z9=M+Owa(=T6i!%@+XH&Q#-rL8`*_b zHF(KeS+nU+lMXSG%1r|IXijA?}~o7OU+i&_zufKolJ!ajzaAv;#o~5Z90i=_V{P-cj2d`GB4Sc*(c9e40#NB_j zEI?Gqvn-S-bWKEnrV@O0*;lUlO2(;*0A5+7ZEYrI@PsSFRYE)==8XazqsD8#BQXn2qVZ}OllWRPMg`3n}dhtc>W zg3_RY`w*Ont;Jc6DL8p~*2yH@90~7V{oEpIVpx0rtD2>{kwl@IhZp_7{WsdYO$1GU z>W1mx`!d7?t)ID)`Zpei$IGgDuy(fSlVq|W-;^21Io`H9K7%hA}X&-Z(g=>CZ--q(*8raJy{nNCHT>k`lRQlC=6^RWd*q6)Iqs6n=@#M9b|?eVNxSkv_5I$M!W-AskGt zY41{m$o&UMB`ZJc2aP)CQ^cqA;LYZ#kG;UE{!ll@f($w<2OiA?DVk8%<+`sg0PYbC zzDig)#<;(p4ah&AmE!$6O@y}?QjpJh>mppakVHipoOf44m08$y*EP%bDl&w( zkKAik5C}AY6>od_pJeaR@C5ArEJL1^8H(blcFr*iE8rMj&)EOw7gG@^d>U$ikSGTV zQKwp5ndMEa;8e~oQ8T=@-I86pKKDD!<&r7h1(vex=E6L7Tyk04r##7Pq@XZ%Nxp#( zUt@dS3JH z?7MrVM zmm6V|d{kL#(H7l5@r0lAlefXj!w+Kzd@ z-+|!wkD;6fP?15l0Fhiw-^vc>G|U~0qgspY!{t1Q>#>jvN{->1{?_;HhjM$GVEAsx zk8uHQxTAB?pqRt%t2Uu-SvH4(OFoE1k@2)*KExvOz6B)vRP%0YzRmUpx#s)Q{f*y( zFGWR-1>QeraC@sGShBA5{o>R+rwQvMbbQeHV3y>%%u;t zqF$NLHQ{+<3G-wMUA?fgKb;9vA5a9E3{cME112wU%Dy4!1ru;AXA)P?BT)YMpm3 z?{Nnr^&{@LO=jF+c|dM@YxvOj#2OIKIn&IXaUGxTP`E(u1={Pd(*JG(aKdoiWnXmB z@u$nXOOGnpq;##Muq~xVou$i}P$Kq{UKc67w6?TQJm8k1ls1z&n-cw*sTWsV6#0DC zuJC_K<%|xs9`_8iu)@urViWSF=<7HjRUWmK??v6P5j0rJxoB}>9d6FHZ_OvD`{Yvl z?fTcEwKZ3-OGk38Ya{#ms9zMG%m3skEMgc=BXR0XkXz!We1z6X-71{^y2RsnvJBWa z)EEnjHu)Q$k*c(P!2i{&&$zNNCb{6KYVy`u`-}V{_v4ZYC&s$kg zp@Vsb$4IUng#A)ZKR$Pht$d2Oj+Q;~f`d_*cXb~>e{W#!ACZtf1RqkKI^9umwzQjbPTrrC4UJ zDiR#)p@(L-gFmX4073#-@A6I)U-Fw*J^M$`W-hGemuua(_7v#z+#pYBy1{WKs>}t> zThMo&hyIUM=-10M*c#&XBvzx>53=)~%Q#vk(A^(6kuyTxXwC7HVsISkYs=>FdtJt} z+9T=qFMq-o`QWWIh$wcQA$l{(06V*97$62tx9#prz-7Vp8efaib@$4;!4pjUr|ApbJVj+tZKx9hD=^9A&iyWr0pNseJ z+xE`dM3(n=6T|C*eHZp^IUnb$wQ z|LS?O88bCE?Q^4FvZd@kJa)dwTO|#c({hNIFZVLbQfc~UXSl7px+CztS(ArpjIkzP zjM(|RVv|yu6Mm$h-`Z~$WUl0#(hOgUnfdW9oj2@e09aiHfCU1q;4CN4(-fpnk8bn9 z#_x=oQDFTK(kGdsj{iL`Ab)&SY4pgXIiw;H0067O)FGqqOw1hl&F5vz zIZvChagPe3``*oe+Uw#e3PM4kw#2^u9rX(f8yXjf?KR>;s&q&qg`_tSRMy-j{`3#C!)jDvI8} zn5b2=5mMjzI9Gm7=cAa-9nt=-Onh{wFz3}1b-lRTwXk>DDtNnYVq+NEOji1_#UMH`dJ+2)ISnE{#!iDG7|=Vo zEBv-K;$SX8Nw|)&-O@^Hx`5iRQ~&l`h~PO*t8+mBrek|P-rq6j!#TZ*!_)9Q-rs@R z&jkk13typssTln^(_Y>KiHMMA0BWODTXGXJ`H{T2P_tO#4llJ&2wx^@o2LP0W?+U8 zomaBGdE?NMgTqWP|Fj{{G-Wo?$>x_GJ(DAgoP5@_?Md09Qs@nw2hh4(IGz`F=G_BR z*El>J-b`4=+nr{=USV-_b8}(j?3k_Gpd%HequBah)(Rdo62+%*STbr7zVz8+(?I02voVeJ%jE+z%%%`ej4=^_j4xzniP@F=t@J?dQAmyl6+mI1)D zfB`#Wyzc3)NP3i(I?BNs)oRC6?vqBw)8wEZ;U>p4&{Z}v3HD`arc_Z!RP8-qe(OTk zZ}~DP0TU8~aa>Cn4_+Z2>OEP6({*~RQKC@oKa}Bq!?;u)0CF743Sn>jbdjU8(>Pk4 zQv;#VCi%1|XuA|AywvQ!LmmlstiJC2e&*-z@9o~Nh|ntr10OCE;D7QXZ}UfyqgOQK z|AT*V%p!{-*Zc|P7SpJ{!wn747nhrL?6>QDo!nKBsb{mM4DR??8oS?p^#QCK{cc|GN3iYG6K|J(zyA#wG%y=o z`qrB!0NdsQ>d+IyhesnZV68Y$ArE-CSI2%}y#^de6vm&{v|{LPWIpfbuC86rqTn9B zh%n?rEDi2Yx=OHKkP;BS1o$Ff^^>!i6WdYsmTRt3%%mw#J_@F;`ZS3%a-ktG=-MQg zg6;gQS4eb=unswoN5npPECg5HLG?-OUHH;)c$td^ttgTp57nKsafH(T3>x9g9*ph} zm@1^v5$0dWoEfXFoauvc!WgLj{h}m@B9q7tq50o(0c?UIMACw74|{tfxgf+ME1m9{$RKQpbHF`cHi;XZzOc)OAb1 z6YP7@F>t@yz{cn4LesPEzo!7O2u_^b_$2$!ybeYJ0GQeuU6_!anE}k;NuckXvg858 zYL`rO7hr%qNGsF{z@?kZmr*ZMx6=;=3OM3dl1gO@M3b;I(MD+E%4nXd_yX9Uq)jvv zmC_3s+zf|$()W{GJ!2D9Nu2ibU7wkN;Dka(0$8S>II4y`CcX3x{tsus;>V{A!hCJW>y?wr?B~tx6@a){&BB5B*qn(+0)9 z9I=`DJz`PJ3+IQsLS)YFGG+Y?@ZC6g@7!;lHufXjC!Na;QnjOy-+1{rGW_S)|DDdT z?os~3pj_{cr{cK#nI?JDoJfZsIKE%|Mr7dD82ELWNcrQBf-3@iNAHO=JNY*r zM(8jq>-0R0QiTxKvjcQ-eG1NY%H4EIMnHK!p{yP5RGd&&4FjP81OlF&Sq%(|)7IAA#438kX+xHY!c;&w z$U$*p8Gz--b3pIFFhU-t)ldMINFj7$_Us?`8l{IO=UI12Mo#My#ATo!#I7U{d_wd? zW-EFQmmvx#9dl{{nV0jvkHxIca`@XAUML#doVA$Hqf@#mFHBxV^O({ZVy)QSnd60A z9!X~|T|B2bK6wS6a?&{I_wOS#><$gFpG@~z*wUVpTFOy)0mj(s1UgHr_JJ-KabC!+ z21Pbf?1XtwEh28jR*_Lcqv;(9-XRLF%cSiW9aN_e!h2Rs9)y)=EL7ggvA|CrYE>Bq zCM^2iwOhL~9c-Ut`q9V1Z#6v8WSn2w>=SjgmDh!N@-W_(#gU(qoXlv|MJH?$i@4b` z@r;pBRNEnaW!Bo$KGwGazBbWu;$Gg+_L>xxI(3WwV19fZK^n5XXfO5Q*}~Y{>#MZd z+#7$dU*npOo-f*$ULRX20tbr&X#BvHG`(!-Swo9!A>OnP`tNy!GxXr}|GQrcw_4dV zy5!r{)7PjVPiFB)cE`mv@cwV-6+Cz2iik=2`Y}WuhggW#0d256W&b#X2 ze59Je(dYjPRh&Kv!r!#?qKkEdI|>zVhl2YLAE%OO2~`}3TYzs+}_A(mH&XQ zuly+LZTS-iBi31s)Pi)QC%U$E_A~wBp*HuVTx?oTJTvJ>G3TlCD!jw31@!H3U8acc zNTPHy#lMx1l8fLv&h&Avm8j)OnhtG<^t?HILd2IQXvJRciZ_RE^3>1<&vc`G`M=Gnww=n4!P|YB^9F6c1rxJIgrUC`s4P zTvGp8*XJDCu??gOZt1L~#C`n!&n4=PYlZhd=*4^vM9;?Arx~M^JHXtR>5n|cm#&@N zlvNt{(F${3W9DT~gjsj}3Ew>f`xHFri)F3}2ay>BXt`@nQOHlsxWH85H!zFj4 z-ht8_s8t0Z2T{C9EErr@7C)G(dg@R{5oFgRhy{&O!9aSXA`>8WJSdhiHXdt2I920F)}2MS#FvthF|=l6DPxSjkv&ns_`CoDzg}BTne00?(&g zXGqA>iog%fXCywp^1MuMb>51=V zz1@HC=Vhc*d;bnc{e!M(y`GN~0-jO+~cU8w@s)%RW$4rk5C{ z5%tQYpe#J|NUghEsn7-J%>0;_gGdtuhtX8?>U2usxgj5*^r4VL`TwW`ZXp=zdX=AIJ?L@5z43-I}LYxnJ0nKKsB zvNwZLIp;zIQpE37ica410zJ(B^i8V`l6hiM2Yr50ap9iH7dr-Txsh*keC*z``;SSA z#!%S9<&}|cZb|8>8FY@MR8HSwCuO`yoOm0^UqXsw#%FX1mNcjC&jHd3N*S42$nC87 zH)JR=XF*^PC5~_qh_#a+!e>C@2g#FX?%+p^F-?#e({*b;{*y}87*7}<9 z)Wvk}bq*u>W=s`67M-1Vp4VEZIQ}eZ*K%68a=ixi|t(ovAHgYE}%qKH;c~kq2-CS=cqkr>cg&VyuyAoZCc8aw2voVx%80FSa zI(m`Z`}V}Z>m`FqPw|aM^EPfJ{f&^37c26e)6~6FT5jlE*_E&kkVh#KOv)ns55=?3 z@Z5S_*E+GryRKMK`vHe_6ya4lBkOaTCEVub@Y73Pa`zQkuxaf$4^~Mc)BCL593{Iz9e!$HXtc<#RrlsO7>~&yrTYSyhbij1MB%!Q%Tj%=f7ngOG z*wsAV9Q)TS@ZhV~^Y1Z(fIs+i?jC8sSKuQ4!T(6l-Djxg?8ql)CbngCgtcE<_TBOs zD}hE1o#90p!6nzI2(J&Iru;G1@dWM6t_R)?hN_4(J=$966nMxcS-)9Wur!0(tEO-B z(f^@Wm;_QVmtqJH)LONEVcI{Dp!4)p8=7b=x=har#1KZAHYMq{JObf~pwz(t4cTfv z5gD&arC8RIe8Bb@<04M%Dn^kidRjl7$PwtPvyHn4T1m6uOzAT&AxI@t(~Eb{Wkk`K zpIidJ%LW)3Zrz`f+D`c4`v6^&Yhou>SG=)%riM;2IgegiMMlz`x0AmkF?$B?fli1;viVf|sQZM~g+l2aI9ja&+&K$zLnn9@<)H>av)Y+d3Bfpjk)P?E!lXmiziH6u74Xk#3UGofNi1WEoD@Dwm65x!KvPNt%jIFJ(4U zL=%Ko4iZZI2wn1lN8@gdkpLcKEMCQYbcyY3B2c}#qEwGq7Q5M9GYYraL92~B8juRe z`N#de@5KE{jj7B3yZ>Tu_)3#_+5G!`lSZrU^vc)Qncmh0_wA3d+c*o^@W{P>9O3Xo zFIIlV{aUJ2SlVZK3p?iwjrz~Y6AuUB`fzJLd~=x|4((koq?coDQ*E7zOsj~iG*9eJ zOC0K>NJyI4mdTepAacYPwB>8-dq6Ja30CaZL{36kl74ErFdm{Lh4yFBpkD%6G51P@ zBGl4l?Kv-4-RSppiZg>sN%6|3eH`MYEXY}AZ(Y{n&1K4a`$dy1O!|I;RFZh2@7va= zD4mJ7kbo)I!BCm5YrIT*Hwpm!{6IbdpU1y_ZTXTb)k+U!0wdy(q3seZNrw+=zKl<; z-tZ$I!R*v;7=3`xkF|W3ewlo|q|ABeTY`2qh!{+}npkkMX4KC#KN!&Tg1){qYw>?N?(OzvAC~RJ2rY^laWY{Jxy@Vp#qc z5gA|esJJ_yaV1K8N$%W?Kd;_mRM5Zb+SzvNL$hzZKA=WFYE?Cd*(?e^0yKb{`sYFW zhuF*X^{X3@x$4(3%gRrGtDO0AS~y^D8f$%IQ_v>yzIdUEwxt&9ogcjF;*_T}And+R zeffAV3Ala(|0Lkm?64ycJ1_`InGo}WLg=ybO2 z2(#}=F%K4X#`LaPxBSiNa#zRDUfu$VQMJC%wbpwL%`C~!vy9Im@yXiix?&5mKVLMf5=o2PgGu{qr^)bBdAk8B9kKd?&yHRSABZFD*A`&GX8M4&o{=m9->Ms8@oygCy$Jg!Oz zQ6@a194CY(`vTR)(L1*T*XnQymX%pP?Gz&iAc}oOf&UO9Jv$WrLN{aX^*p_B={ujz zpumM`q=I<+qq9{H`#nUulNjyY|9Q2$aDADUBnL?yY{XU4Xer!^r=7mv9Kw*`Vp&SU zBB0FXbN(c;*ScbKL=h?X)zeHji+lbNy~gYn^rS^e3>)SaX%-+e#3B~?yy6-EWiI)B z?W5sQah0%EW$}lP1oYXg^_@9T<8W1^%q`p`-DxzeU%(M|oKJUw2QFIXm(BWW|JWy& z<5%hTZvixO{r9{!mPoG#0%DM~QS}C&Vpg+ATf63+g?Bh6K_M9#o1SEPpHi73Pzkl4 zIVGMfW~IGsEz53a{oRQw+LL|Jo+ddv6gW%;sMq{ z#VYDwD@`LuF868M=4Qk6tEP-~56Af#7mR+W2w!`{X!cpgK8iTSGz0^5-E1Jq!(c+; ziv{ONdLU7`Fqj`pfz&0(Qlkm&o=9~23WYI;c(W+G9F(XytNB99140(6|~1uSj^9BdZ~rRpIk}fv;9Jw z4!-O(_;3H8mX-OjKh@s*S<=kmU;K-D_5?k@5KSA|OPNyy9O0#934O8(=60zi%>-30 zy=A3_b5AlNU>7~$eD{S*tuH>{7=nutjp&w4)#%)5`me(o-#HL^9DT)onO@tx&sDZ_7fd}{BbeE@hWq-c!18^}tqY2jBk>L|0rioVJPuQ}u}} z;9|fZdJt6TGtVa&Bv!*ADf2w<#yfe|nR2Du!Pr{+jzhBhGlb6$gG>-Jn+jjzYwk~Z zzk^Jd2jjE(lb>Z3j6_9?m;Lx>vdMt=owntVrZpiw<)ughFe{Uxi|W$%ONr7U&8)oK zn9tdUzr&&{6*l?q9%sturfMnZqPVn7>`U9Q%m?2SPcU?}*;?v*Mnu)Te|e>0_ffSP z4}c1JbG}QQ_s6ZTtkEz>2A&5z6O^>oSnb{fh|Az7(&5$iu-wl>1soz1EI=Dg)Y($ViBgza)S7er<`2s?77?#G_Ad3 z|2hDE$=0;Gd}?svZ@pwk)4SA#(jxA^-2n?*Koy(}^FYV(9V;fH?Y{=MjXiDn!_ zYwQj#^bNhkFWM9WO%>xx1tJXU%JLljfjr(M13Y=~3?&)VhmCW57wKSaZ3K{&XA>AD zEG8~JGKaPW{EASjfBSatuCQTql>o+MV{hWbluD_Lvu}g0<-mN3^w)dW?2V`sHq{G??^WRTCxLOPs9gCXbcxs zfphemVUgB~ss58xFCdHAQ%+of*-ud~6)3`rsuTaXZ+vDPU_C8K({W84*=8qx3KN!p z=x6TsXm=>eDRfp7#lTZ5bADRv^^8L7#NJ@em8j-W-qg5LUnDfPzg4qKXHTxJW*7X- z{#4vhS6J^~8Wt?HMTh7@Kz9q3BRA_!2Bv}=R_pV7?c%tNVm}Cn>8XiP!1ju6X2S~O z(L<$zTm&(mm5SqhLED!J(VYB#^1u3+h}~m;fE(mL`1i%tjh4y_`kYGxs2elANDd5@ zDs64xHE~G5;TXG2#mYyoS2$W#eZ7}xXr%pO){776iyKpH@ zTDYVBNzdHmEq=5*DbuEB1}q%Yt{B8LC@m7Ytv)*`oK?SM_aHkbbt0|M&9o%zgi`dz z^jQF)%BR})X+Hi$1^K-4PDO9gDeDL|E~VJaF7{`HhlH@M1{U@9gjfKQxanVs2c|Q! z^{ocUA)jkn9F zwx2J&^{w6-EO~ve#jWg{>lH0Sf|s<($9#(bPPkpCShmbp>qQd)U0@PZ()C|NfEnw( z369gTW9V_n$rzw03P+IZCJYS9Nr)=kN@!*9O{Xpy zaaXaN7u=Lf2OI0DDY}!BH+n}j+|HVCq~0jMnyhiqm-Vfkvsz!bP54p%xsFB>ZHz2h z$=>PNZ!4Zm;z?f(O@a6IW+O7(jsYZM_1H!YZU8414Av_(YG)ddy~>-Ds5o;r3L$^r zqv!_nrwuK$Zl3FAxmj|VUS%@;V%anCHRW~~@6xP_?5(Zn?dYa&gv#cwFVvDpz$jLc z_7P@5#}4TJa#z^u{8ppX=UWL<9}i3-?#wgNQU z=YIbBL{tQ-eJgmWmpzFvlT(HWChQ~m5Aee>POJDnVItssk8vDb> zr)+Z=SZjBl1&oWc=2`hsZiw)1GI1rQZSkf%hnfbj2PDL65L+$D4Z;!<1-#rT6JsNQ zmO>=5&}v9XbZKvYXH2L>??*u&>$|Ud4I4!hyMy2Q4MnqUS{V-{0H7oxl`|J!?J+Wm zr!*D}iuw={*}DC_sQ4X)JQa#cyLKs_NC%-akKmXTS~ajY{5pVO0O*&>PZ~0PIL4F4 zuNbR2{JrqM^UO%A1Iea<_`m+{@{QCwoqz6b=dO^aZmkg*AjM!_u2xS!GY>$)o`&+N zgbL&)vrc&BWMNY%e6EJ^U?>i5ZAB#75F)sAloEQp&nxSBiPKo3r=3g{C?63*wjcE?X06-2+xAf_eo+Q1nBT|-oTy)NXpnJ?<-4v^dM zxkb6p#84=BPyE8esOB&@5AH^3L4TZYSiol~<}^_&HOy))J(E94tF9?9B)-lx(%Qax z^`dBZzT{*xyRBUrATO;{w84CeKm*2wYWn}`M^F3#{$LrNp7WEdlKi59DxTY*09=+68p{l?d z+>Hxte<`NGdt>ZpBp7*NXMW2wo4VoYT= zVQWtm>VIylL~`_I(-+NRc-Vm?_7n7OIIk&R;^`6b*l+vDNFUypvM(AV*<}BzSA9w- z|7AYdY*cdn7FQ1jMi6c8RsH3?Dt{4o^;zR9Pd&*u_no=|GY5GFb|O`2JM6qJNq{zZ zKxB3@vz~vbgMgO*iM&@!*Tf{(f1wZcru7w)x$brgn^YH3WM?Brn^EQ5)pV+Is0#&D zVx81)&8g8d=?lMp9M{_$fJ35=={t=#ynoL-)Fa*9w}8L+>z&&Mz=68Zlj>|j!VmFeeH9g#VI%P&=xNsb<8sCM-aP63 zS{yt9XK=pE@ubs+oz6G+{Ztw!9V-faTCQ5now?mJmw2DgI6~l(>eK6j?WY6pD7`Tt zPW<>`vb$$hliNHiS@7=OhLqq^sS)>QN{QB+Yj3Z9&U#Y-0EB7t`xt6SMgd)b{t!?4 zUQdzWOogr`vJ)KDWK)&~Wh0gdO$ppD zh}-WtIMyA8-<0%TxG=;q!bBNu|A5%YiYD-zATGji{i*DtiaTP<6QDx_{a$|WN-JqI zTLKBB%-cb`Ln!dd-kZe%Ct}=T?H<)7I*~5ARAVBe8yogK43Z=(_5A7X-5kpz+VGfD zJkz}Tq0hcM8gI@ot7`Dk3^tF_`8f{AyAf5g3Cb(S#u6#PWuoU{Zy$7D$n&Y~VE2wV z#TTzme!#os_O`fL-!WMBu6@SL$DC2d8MPc*uQA=mW{M}PxZh1(VSLC#_xUB{>H0Sbsk6kE6<*t*!8#RXw@0x z{X$n2)2LzDm?P_61 zy`~PaMP#l<(PWAk(2Dz}Hhi=*xO7x+?oz6ORApZNeY;)y~y#9q7tX26>(XTQChO+kwS0IE5$cff>k zMv<6;qHQ%gExbHqt<2{*!z8g7{d?_TV4ic4O>ug1E~a%V=!2g1a+C+_`h`t0b)PeE zME3E=i}v*kvD`7m3M!eEl{Oc|Px;wjk})^48^snTvVvH_yw#N?NMaJ7i7g0X3I;%} z^FoJ3grnuHn9-xvyfccjO|<#I${{H8@!!wm=jFCiV zE#t#C3d91dMYyu?Ga{jx>i+$7;PQ!{1UfpjDsk_ew|ZtMo^mAWWSR{kBV_9an9O{%{3A~|@%P6N|?CuBkwkU5%-NiFa|5rqTU zRdw)ggl11rHtW12$0h5Ttdr%ROuN={(3ebXN)hKNf+f{NJ00z_!s{q2-Q+Gq2OCMX@f}?*+_`H>ER)8TidhBTRZx3ho^RBr z7o-b31J-zCMe%B28ionoquS3y&!nDLSMZ4UO2XZC`tE6~A+49iM^boe5;Yk~6#_QhMlaQ^%TMRa8vAF?VyrK}&@(pPn!Cc95+^YxXxlG&NTF$+{ zYqVfhcUv-3YS!yiuWBZ0Y*r<2V6d||j^k-Iz!h+)n^xN(OSU?4k!=x{OwH0ODegn8 z4|_<=h{Ib>>$)(vh!?^3hUil-#9&i0f2VYiJ-!e{5qu&0;*jwS(Y42WvkKScvW#!n_FXdF|EPmo zkGt1ar_VBByGXJCGbFQ#+$alscj>C(*kCMv0!X+x9zUBKG5Uc69Nd0jj)GXVrl1XwYa zrK$Q7z&Ej8dhsME3@mkJv`z&y8h|awqe5dh+MH!XkJt8r-DwZ7LlA?dPH{-W1me+(j|hM-iER?)ma41@$cbSva5=V3-&f}xsuJ(RE}7AX zCIFKMAb6vXqTX_z6bw-&T=Al-r-tyQ@`63O7KlNWrzHO0eTNMII8n3j>TyS#Hvdpc z>!*z|NFTjI(*FKCKgP)ASHq__7j>?m$@PA63L!0d1i+!BS=RfT%NzjLmRtdg;G!if z%%S{@K9sal3O261a!Y?RmMElyzJS~vKomD@^0BterEx$9Q6Rpj)jP53-Aq6ztELhK z^+6+fLE}_hLrBG`u+&O3_3)mJ>6$dmVz`@EY5V%5u}X(ptX^9+zB*a!v#v#V+Uqwo zD4ym&qCGzZpBiv~U%y0#5Iydo{prrqDNE^g^3#jbidHNDMBsNOP_^+Q>vxX9k>ZV)<$aYqh}PiVxU+Z6;)lV+^rRZ2?|Z~ayeTCJZx(YV4F zb#C#3RX{?8FcZi*RiILF z>g@B2=w9?s1NKEov&w^}`x!G#{p%Mq@dDM3Idi{rz!=33ik6yGc{3$Wr6tEd=j$i5 z{*ROA;h*@1_(9Y6@k!eH6W^>hSqvGP5L_%~96V8D@G0)mF%l=2ZQ00%bHN*vBAD>1 zB#vu^TS)Un>_D<;f_86swP&*7trZAH1U zm{aR4^N9YY!*{bLEp`9ONQ;f0*l0e!@7mTF)*DUSNzSvj*t&X>)74+gD2fBTMVnnA z7zo}h*a=UfLoSt<*%_e9Zg2&gvBy$kvsTcpneLuA*&xgKGk&{s$o*$Pd?kzH`PiHK zZIofYV&9~d#({jr@S8bgFp+@Cx9Pv=T4(>uW5;uvqb4y?d0?@+VeY0{)kxBg%!Qhh zf|(D@FndFu))<>o3an>k|J_-*5wK`ovAQb7a1hV*X@`94_iH+^(pyyM!I~((9{_BW zg+q^MeDcS9+6OwCV?nNiv|`}jc`d|`ui7-eO~M~MIn+tQTmY;wG?g$X^d+Mx=t)PU z8+5pKLSOF;UjpOO2beDggBdOeQ5Js-ijPU)-!^L%8dwpT4Nxy*bVafC?vp;QZkm=| z4IkEKSqlDn*U>e2GJqw(m;60jM3OzeD-s zy&LQfTg!m)V6vbS*RWR6I&n&@gpQt`#LGpXlehns0d4QKh=ctUj?Uj?_^I)8`;|{1 z%x?a>_fmS?<46VH;$B(7+V;RpH>2*_NKDK0>#BMBJuLm~O)%(^FF<2X2v}j6%Pr`= zqnDTB-zDvI2KTTO7`-%t*M{rFamZvQ(d}E9rjS_c11D7$cLCe%h8*J!DjEHb@%)Fl|47S<#-9-V7f%w+J~gw^fAD;J7+X?p7#?$$ zQYl9Vz0cmQQ?8QctuYp2S3B{E!&#;F>%}kqE$opV4dOi?VGaseIEm2ErM7254qX); zQa$Z!TWTTR5uR>$Yg(5E{N`^I$jKzz+0Oao`LkN!ns%^lZb*X7|?_AGr(rjAw;!_cAQ(?BK=#hE}XezsJ+2$Mk31c})xGJh)7bQMAV@?QnnVsI4QZ z-{5_t`u!I-%-Bd}!voAku8*WVwQiJ>;{>xkTfxGdKkCjs1`YB)scfqFEcICNH{riNa+@)gfuE&~T=THQG*4I7;!$!B(qC!tg6 z-1_{JXQb1fIH;eIsE%Iv(lRrfHrjBVQ)++_^ai&AId@BR{1gHp56KI?pHD!PLPjSI z6`*71dY(Q0t|ML@#GTHC)Z*5Wnbpew=5Pa)iz9~(;-?!YOa=q*>Ad>+{+Qo`razmY zW&Z#8pApMn6&hFm+dq#l*oLhN_=+tk*BLY&!N_;g_J3sj!G8#m9QcfU{VakZ( zptgi+YJ-^dDHA0HE_#%BKvC#TnTxIpZFR^E3~3{mOc!a}MNVv}F~&Xvw3^~BXAS9gq=93XV^%co{gcWET%Lc&nId7`m1$P+J8 zF~Fpuw^q&T!LBzvHf8E`)=a?6Bz(Ba*VAmWDtUru0)TW*%D)%#4loFUnKaB>nYkK` z0b%^R7@L%8G^<%Kp@Nb3=`o%(e$E@3W;DJy$G`D#=HMg^&%g1IKE5tK>1OVgD@;2^ zS=n%<_)358$OX_jTq0k;_qr6K!&F!r zj7~$AWRpRM@o*yS0ZX&1&SwSRK#yd45|meXug9cN6cWG|?^=XuJ2E0Y=W)u~AXn`~ z>E2Wh6XvXQv=lzcwZdk~07|Hu2G#FCP8I(jQ{NrWhWfsp5F=(1dnd$>J!%VL?^zTj z_N-l0+t{&cD@rSM9mlTOW45}^dDHXO`TqWU{=PofeLwfUb`O)j6Wbm3 z_Jk^DOgeYvW_vURi$eO6i<#s#3z7Zy$jHZ&To;>0f5-emjV5W9yMFthKX-wtB!SdC zP!b?{Zg31}2yFIIXn;}Dl_qn;>LtL_%P49|2`VGF{;a}wx50SOH?Tvq-uvJG1#s@B zIzhZQP7HYd|9`D_CV14FQT>~r5_J0XZzYN{Mou0yWh7!vk&b~2$E_h|K8w%!wS;L# zgZFcmZYq16loOS79Wy6VrSt>-dg>M}dzQGaBBRoh#PIc7!j3u0@pf;03dn%OD=DJp ze#cTN%@%sfEgeOO#XU59NhZt5p^ElSSO)G|@3hs^^ky;8&RX(!Y0y>6ye1nfDz039 zz+KBvi$w@c_2CSqta!MqR6~6^C+jG1vVpX^ge^So#4+l&f6!1x;63Gx(Iyo?J3IH+ zoK0b4;hHLuEsMufQTG}u(_&i$oeOg28e2LZIlQQ-F(~?K9{`|99xSW4GoB9ewh`OJ zBhj2Gt=#=1?AauSA}We*t5cEMIV+yB)~*hx3@#5X%JHLxpMk>bcq~fQiSY$hrCR}glQCyF3_wX$aBHnIfOV0XG zIWh>u$N8a8;^Tc;@JnVmK(GiM_3l(C$_e^pk8?b27Zr1d=MrsU61u#fF9B8cMB( zt@`uV;=+!*uL{JaZSPKUwY+7fWfD1~`^Rr|tUk^HutIWe&wCwDb%`SyS&OuEkpF(cVVq9%!4us?W!}{XtVFC3(Ti zEhk?+hflEK5lmBZp4aN5@meiaM4{co`=MbtvL#GfQ8|h;`gDn!ipzNDt#l?k3tFn4 zOUXgH-#&N*>kd#b2QflPH>>qEsW#C9;dg@pF@s%Vl#TH-c%{r&^t5IUF-jfg5-o0d zO4qzj#9lxCX<-K4@UDn$;rKa-hq#iPqVUhazE#EK-CRkl-FKy93x^tixD|QVJ z6vilw47Mp#(kdi5Aumb#{DoC)u~DpmJ7~5CGSJe3W)@xti{}iyhxKWy-U(xmSfptP z5FJ9n&DR^DZ6)`r9ZEXD;M_ZL1;gky6M;6jS+n;BN9n)#_9f>0x{}U!iU0JqAzmN3 zj#S02_~vsiHfm&5Trb{09vg#fO9D=F_F&{B+L|kTIow6_#yBEYG{dj2j-S48EN{1d z>)-Jl=>?$aS%jc~%!h1Q>J3>m3uC>8lw;&139`b5wfCvk*&skZITo_^rp@cHZ0siA zaE@NTV{r=7Qfj7Di$@wMyc6JN@Q@)l55-Ov8)~tEvi^JHYa}eP3aTr`t1V=n;(*%% zfAD%3r!p3Lrt(^$DRTmEV+bh~+R$F;(w9WI9tAAjaLd90PZqL#X>EBoNs}7m&F;Rf zO`DZ5)a=8iYkancAtH+VEAsIj#~Bh;Eql0+TGIo0=CtGCG4OUAbu4UG1>Z@15q*2Bw=ZdO# z^eJ*;&8Z;TNR74dWjm;q{i8Xj{8rx^IIx5={B}h6bq)-U{KTS&^z~XMAE<_PRtx z!eq}b3820T^a54bqZj^_)32Q{9_)2Iwj{y^fcMiWOw5{O|5^hHtwug*L1Z&nLH=W)SOQyOhwt_OS z9B+4+Iii=I-)DUk@x&|g^u8?Z`PbD%A*a?qZ0bpCn|zQur4g;OB6u~LJORA45iYF` z0_WHI#kZfha~WkV-~Xe(R=)>rQ2kGTjgwN6juyc`#mi=;~x9S z1+sTq`N*IoFoVDkA3p9A&2ej1hvtDYwTwx(oyLNdPamwPxavNW<^{oRdU(wQEb;;t(}(c#}QrgWGpUkxa^``8dYD6 z`t#iAePt^LU#l&u>wftC2n+a_bPr#U!HZf8UdgFHY)_E#MLV}722ac%89F?r#HI<{ zlW*tcl21tlN$M-LELT*7YfJHFRFSN6GEr@cG7pqi81v{4{=$biA407%dSYl zYAa+e>j|Nx^1~t?Ddj(D7h^~HPS0fTkA1jLCldybjP+27*k8a88!(aPnRu&o_8)kl zblOEcCUX_Eu6b{=`0W{&Km6bVb~PukKj#JFPr@2{R#_y>60;~)l-;j48)FZbN^5KC zYLfr?=?V}Wi47^hj9DRT^x{jyHz%RvfW#saNd}3Lo?r#F0zfl|SdO*zIht-O2N}Kb}*?6c!)n?&uHJU)(x z)HG7n*I~1S$Y<>VWzd~|r63?{-dLu6dP;IS5C2^zTY@F6tB^f6tklosEx)}kqcNh$ zYJySBn!1*#NqYD1jwU+XUOJ{yR;x@W$X17W*#QKk|a$n@> z3i=IvbzXaU+fN4@GN$cH@iX7aKc{7N*3CnA5*x*)l|61(a?jlJ$O_l_$>4uDT`u>+fT${uSDr@zTp)(^H#;HB?yvbZ9n?clkK+7!63raH;L zV+l?dqq{X8PlmXs3#dwkNv&yU+qgE;Qa!U1vNx3LOGIq71u%c~r4SxlHd)W_|7Kmd zWnaAMs>npO;6u~%@YE*&w(%K{d;G#J-PY>_kaq9-$(EYPi8UvoOnAO+@=)5Cd!d0Y`_n<)-Duedfbc}m+m^w0ynt0Z?-6kE zj9EU81`aaaSav>rXu|yGAlgNG2XG|rn)8cqySQ@|HN86$|I>r0|IT*Uo9Xo%pO|CT zd}f{^VM=36%Gr^Gc}To8L(FPtE~Y0%llS3pd8`YgHa`>QqfwETf8?Z>;eO)Dw^QwR zwIB(}JPi%n!JGxTPOp|Eh>-28Kf|YKRWvf+*l!>KnOK6V-W@;Bs*`U61hc-E~)gG zopV&MEpC3!t;=uH3uF;+3~7*J<>h++e&uO%89*s7OLi7_ElDS@piE3SNr=S0ed(j- zvNo^{<0HVRG2BOQVEvhYPN9S+rDC4lolTF13Y12)s#?GUN(3OjSq-5ja;^i`BNBxA|u1jUy#1LGVjK}*nX2F5`4IuXN^C1!6gJW|G zOX%{YTxHNpcCFBST(=U(zUgq=uz$2kRo9P`@T6>+ern~F=@#EM$shh^yqt73%d{h{ zd6$1XDcI((ECxLY4eCdXgbLAI^KfE)%Xm^QtI(n0T=UbD<*(BBCUu6AI_Z2jb|ZsJ z?lHKg9h@~aVqbA{SAYGy|5=>4&GE!|Km`CcbWv;S2GwLXz$uV)LOcgTFB$aN0RTwFfkFee%JoC$b z{|1~psg2$-GU~pv-}s+QMEwZo-~6mFiQsm_Fw50Z-9#rV%4k~$-Yr!~W$Ac8#-u~c zv_bjwjGEGVZ@orFb0yUhyq|s}vu1zWFn50`W=ai1IS6E?VT3}m_WC@8XEcHCs;LGd z6|?4V-1cI#soA#j`e#Xxinm8M<`F8 zS#7Y5rRc6Z|3&oz0eM}|)@bF`?ki&F=J>L-x$V=}j?U2f^~<5nw~u}EzuuEzQT3m# z*!05D!!q?5Ad;GS{Cj7VvJr+rQ{6%rLH1MMmh)}@a(Bh->zS=T^=?d`iPs1Wxh@}8 zpQkf{N6j1&G$>DDEb15EjsfSf>N?*eB8VU8|L0rZ8B;^AB>p!()urkzloSWI7XPwY z@Wk(r2nc#6Q)=_k5(JEL83g7ugI!{QGDe9yq}8i}=97R!66VxZ7~U%pOjfO_h&vTiv@KW#V~8$`b7Sk=>cXor8SR>*tRz5 z8}XJ5TG<8C>>6;%P6~Q6juBo8OouJE;S6^MW!3}z!@R^Ne)cxvLwJm6K1;u#aEb4X zsd!SX`QEtQH6|9Oy5~1A*G$Z6^I48QM|6Gs{71d(oB5l$_uEg${j!n3!_9AS$(NcS z&Dabo2-Sh^jnKLyaB59a{q?-YI;yT)GI-SMq*aGft8|QNJ1h`Yz`t!aQ-DHw@pTlD zH`7jFl3tRme!k9_pRLn2oBKFMxJI_CkMq8 z6_tWCXqQ7sowd8|8360tWJ6mdyU$=!K_*F4!O4+|YNe8AXfj>?dl&k`vUq_>$Dnn$%! z8}haNPyY+D^&MK@n>qFyA1%doR(2Q=9s$R9aTTKx0#3pR4A6tS46C2_pe%G)L?XUs zJsH7nPw^2Sfz#W@Jm?Q{;WG{^3T<8-o zQiB1?$`$pTCM;0_J)FklCxYfv&KcQ15{e(pkn-v!-c(itnVdM|Jd~0LHs^dakgVi5 zy|ud14VxyxeQbRuM^f~yS@X16TW?;4~?!ibGf5qTHt&Qt;q~}JY42Fb=YRKXUpT; zOzB_Ei)Z{degm9as1Lc``fr{biu+05s49m0jStPwKcgPwBS^Spd3e|%Lqp~Lru~D= z*C~&bdeZd33FR7Hj7O!O=KZaNwK?EwY^H}2sLHg)1)d7@k^bsd6uyzzu!91-zIh^B zy|6#pjM-?DgGJplavD3;dumy4+ff6vrigb>boc*`R`Z2tt)ofM2)Cr*48jfJ`*sF2 z00X83j#^pS*G#6bz^qY^-xZxt&BU%`gl zdS}(|-1BSsv-LK*>PcTHr}N`;Nrh~|&MjqYa(IR3c@*aNZ6U`$krj*;%Ik{xD?Cw4+qF|oog=fdfa+Z1@XV|B=&2Z)P{XcvG%|H8w~Z6?Pxt=?KhqVPh6%L<3#NA z#dvFK*ILP9{<&pR`=n2+q{phYx_ne3-m$F@ zd#ufwm%muda@WIwKE++CbWLA4_k(bOqyVR=-{T*;3ouH9$v@d@j6-}W@d=;9JnI`@ zHY66vd=ZK0n8?d}kN-M?*B)W7u~;#HFj zT2gYDS(=}`x&Lb&Rv&>H`;f~)iv!Jhw7>BA3vkY* zg7J;`pMOJN(59X;?DmTO3xJ- z-`^l^KFtghi-Ch2t~bIL+5h@`^`|sYG1?kYtT*_12vU!)UZXP?f&lQl0d;mV85}md zh|c#nlSe*0CtEwx&bTSd`5uz4z1gS8F-nKBKP7cXsmn=6q_1wY@uhY|g*!$Z`TXsE zc|gHfY+qEnHCZU~%nIv;jrzFH!p35%%eZccn~ym zX*~$ZpPqSi>E9|P4~qvuuIqOh+=rV`R!rsPj%xIUSFz_lHCNH(DuhCYnw_%zjR*Z* zWg%ZXT!eW>6ytpLxluWE6D`e^op6%_}YU# zm?^!Rwh$!SZ?Dae4}qCZkA6AH**=0(A7-0iNd1|-0O!5F_0MHC)EQ73462jaE3D9EyCfl#X<5CV16 zT5!1K;9abhmDe}^r|#)+o;u?FC}O+;I6G4v+Kh0y>hD7qi1oDI)T{p#(+#?|%rgWu z=xV;Zk>fW+kP+R_%G3QpSo(1JjMIq{pM=l%_s@cWPkXDWBo4%kjwy9wSrxNuqk?#6 zBL>XtJ;f|Y&qXiHcld_q8r(`Fo?!F7lu2~N>#9l8&(UK#~D74s9wFVTa z>5>ydF$u%#G{rhxw4|;1V^Q~9N4GU?T{jDRNTsViD+3=#nU~TTOBKOhks}J7F-wov zPZ2m9z3axL81xV&I5Wv!NZZ509a8KT(*~l+9T$%DOLYhyTQF`zGc?oCi@@Z`H%e=L zVY$-z-qug~>kA(t!yO-ERdR)A+&iBINGyg9+|P;rWsirr za~su>JEm@4SNW0G83(bxv3vDD4wI4OTg=PpqZfg}n%_=l+D!RkE}q8n2{K^UtN7Ge z)H2VDn?cnz!7V4>4((^_?><=3Ad@R`+BPP?CvaRe=j@zJ6b*O_ z8c^n8eMSQv3ul30*}#`b)MTb1U*Q0XJ0U5x;yYfR*+>?Xvl~k=)Q=j=F6s z)m5(hpy!)EX5mh}GN!H-)zXOv-1EI0VPX<@rKh(razz*WD5=L}-?B}fAQ|%7ruM_t z28i%elfk%0_^BQxcgVeaBV4M3AAkFcZ>Pk5it2!Cr1KR%Fv$zrM)$R=|52%Ue9=66 zG1!wLgfs!NoEz>DtXu?k)e>V$PxeePX38fMb;TB zz6~ZCU4O!m>YY~?zFYmJQ7hlU_BM=($M;a1_D|qWI(#pSJ}zs@sPxtF2+#;sJb9WO zBTr^tJ$Bqf63?wQmPBsb>F`<8@pF>iIDhuJpOD>h{6e3flSilu1G|jaEN`Hi4G-hq zfKzdKDS-1Jl_B4V2qJ+0=I=1% z8OxDN^3{I|0%!-)D!i$MNHC#Ll;fG?3}iIM;4M=rgpDgakx{KzW?OPy_`ynf?q4mD z%6~Uy25N_{l#TII3JA)3l7h{0ImMODg6~CA9`kW>moZBRB;BT)4ta+v-upI^lbiia z!R)5M<631yUqt4nJ^)*)qo5OLQ~5v-EFl%cz|MvOCL{2m2?EeuL$VwKL7g*NycMAK z^!76Ajw$n_eSet#-gHZeCV|5;i#pHIRh8~yMVo(l;+C~9-47pQp?9H0%~EH%~_J@u$O*?PY2@*9pJmH0^zKjk^%_y{)2wvW~`i`U;K!J zE3>RK^)5oZC={>2T>Ode*d^FQNS!V(PhuU-rE4S!4ZEoYug%vXwfs1cj#XcO*-?L{4j`z?u!)+H!oE-9xG>F~p=B7v?+Vwy5ZWoOq)( zXU&)hS9^~--^TIkO54aEFP3E0gzzsO zZ}hq>c(~7{+^8-QDUqu4Of6nFDY%X>-}fv?bk~IE{~1Vn1DFjcXCg>$>u?nG>A0JL zyyn5zZT#!{Byc}l|-^tV~%1DvyS9)7nURJ6F4h8-DUUcAu zP7}q!mJPg3Q=@5D%<`)@FK+be!Kgak0n<7y`0$z;2{KAv?C334|ILU@X|h_0Rg_6< z44ktHs8ihL3!tF{l3KJBB>uvac#r6#sxEOp#*ghk+PV(lrV}%?jS{{McDS zp~E^2hR2{o1eQ_6oT=~69(2|u?4Pvay*wIR?_p|PpdDcaK^CX?0q!K~sqjIiw8G1b z5^b4*&`gRXI@&fv*9qA+zA{bADt99W&ANfXKXuptBuS_oLrfU7iE%&m$R1|rB!Xo< z8oWd~5-~PCnrXsAN17qH_i(l)h18fYb6LZ`^PI$b-DA~pV*G=?!qe!2r@l7_@Egx; zwwQgDTP0O{IdZ%0dL{VqEoQUOQkUjPPW_j0ac45xnRVhN^prU*M-&wd^Mx-U+~N{= z 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ⅅho%_RoP^?gDkQo0Ip0%In{;$%b)5;lC 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 z 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

Zkcekx+Y?6LF&qcuS|axL7&1GRg=-D&c)6 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%0Dpx6kN@{!KHmlRI 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