From 2062adac665fa634cb365c362ac800934bd40d7a Mon Sep 17 00:00:00 2001 From: Stanislav Novosad Date: Thu, 23 Oct 2025 20:14:59 -0600 Subject: [PATCH] Generate Fern TypeSscript SDK (#3785) --- fern/.gitignore | 1 + fern/credentials/introduction.mdx | 2 +- fern/docs.yml | 1 + fern/fern.config.json | 2 +- fern/generators.yml | 13 +- scripts/fern_build_python_sdk.sh | 4 + scripts/fern_build_ts_sdk.sh | 4 + skyvern-ts/client/README.md | 183 ++ skyvern-ts/client/biome.json | 69 + skyvern-ts/client/package.json | 65 + skyvern-ts/client/pnpm-lock.yaml | 1649 +++++++++++ skyvern-ts/client/pnpm-workspace.yaml | 1 + skyvern-ts/client/reference.md | 141 + .../client/scripts/rename-to-esm-files.js | 126 + skyvern-ts/client/src/BaseClient.ts | 34 + skyvern-ts/client/src/Client.ts | 2284 ++++++++++++++++ skyvern-ts/client/src/api/client/index.ts | 1 + .../requests/CreateBrowserSessionRequest.ts | 37 + .../requests/CreateCredentialRequest.ts | 31 + .../client/requests/CreateScriptRequest.ts | 16 + .../client/requests/DeployScriptRequest.ts | 17 + .../client/requests/GetCredentialsRequest.ts | 15 + .../client/requests/GetRunArtifactsRequest.ts | 11 + .../api/client/requests/GetScriptsRequest.ts | 15 + .../client/requests/GetWorkflowsRequest.ts | 25 + .../src/api/client/requests/LoginRequest.ts | 52 + .../src/api/client/requests/RunTaskRequest.ts | 17 + .../api/client/requests/RunWorkflowRequest.ts | 21 + .../src/api/client/requests/TotpCodeCreate.ts | 25 + .../client/src/api/client/requests/index.ts | 12 + .../client/src/api/errors/BadRequestError.ts | 16 + .../client/src/api/errors/ForbiddenError.ts | 16 + .../client/src/api/errors/NotFoundError.ts | 16 + .../api/errors/UnprocessableEntityError.ts | 16 + skyvern-ts/client/src/api/errors/index.ts | 4 + skyvern-ts/client/src/api/index.ts | 4 + skyvern-ts/client/src/api/resources/index.ts | 1 + .../api/resources/scripts/client/Client.ts | 102 + .../src/api/resources/scripts/client/index.ts | 1 + .../client/src/api/resources/scripts/index.ts | 1 + skyvern-ts/client/src/api/types/Action.ts | 41 + .../client/src/api/types/ActionBlock.ts | 36 + .../api/types/ActionBlockParametersItem.ts | 62 + .../client/src/api/types/ActionBlockYaml.ts | 22 + .../client/src/api/types/ActionStatus.ts | 9 + skyvern-ts/client/src/api/types/ActionType.ts | 25 + skyvern-ts/client/src/api/types/Artifact.ts | 22 + .../client/src/api/types/ArtifactType.ts | 31 + .../src/api/types/AwsSecretParameter.ts | 12 + .../src/api/types/AwsSecretParameterYaml.ts | 7 + .../src/api/types/AzureSecretParameter.ts | 12 + .../types/AzureVaultCredentialParameter.ts | 15 + .../AzureVaultCredentialParameterYaml.ts | 10 + .../types/BitwardenCreditCardDataParameter.ts | 16 + .../BitwardenCreditCardDataParameterYaml.ts | 11 + .../BitwardenLoginCredentialParameter.ts | 17 + .../BitwardenLoginCredentialParameterYaml.ts | 12 + .../BitwardenSensitiveInformationParameter.ts | 17 + ...wardenSensitiveInformationParameterYaml.ts | 12 + skyvern-ts/client/src/api/types/BlockType.ts | 25 + .../src/api/types/BrowserSessionResponse.ts | 41 + skyvern-ts/client/src/api/types/CodeBlock.ts | 13 + .../src/api/types/CodeBlockParametersItem.ts | 62 + .../client/src/api/types/CodeBlockYaml.ts | 9 + .../client/src/api/types/ContextParameter.ts | 14 + .../src/api/types/ContextParameterSource.ts | 62 + .../src/api/types/ContextParameterYaml.ts | 7 + .../src/api/types/CreateScriptResponse.ts | 18 + .../src/api/types/CredentialParameter.ts | 12 + .../src/api/types/CredentialParameterYaml.ts | 7 + .../src/api/types/CredentialResponse.ts | 24 + .../src/api/types/CredentialTypeOutput.ts | 8 + .../api/types/CreditCardCredentialResponse.ts | 11 + .../client/src/api/types/DownloadToS3Block.ts | 12 + .../src/api/types/DownloadToS3BlockYaml.ts | 8 + .../client/src/api/types/ExtractionBlock.ts | 36 + .../types/ExtractionBlockParametersItem.ts | 62 + .../src/api/types/ExtractionBlockYaml.ts | 23 + .../client/src/api/types/FileDownloadBlock.ts | 36 + .../types/FileDownloadBlockParametersItem.ts | 62 + .../src/api/types/FileDownloadBlockYaml.ts | 23 + .../client/src/api/types/FileEncoding.ts | 8 + skyvern-ts/client/src/api/types/FileInfo.ts | 15 + skyvern-ts/client/src/api/types/FileNode.ts | 21 + .../client/src/api/types/FileParserBlock.ts | 14 + .../src/api/types/FileParserBlockYaml.ts | 12 + .../client/src/api/types/FileStorageType.ts | 7 + skyvern-ts/client/src/api/types/FileType.ts | 8 + .../client/src/api/types/FileUploadBlock.ts | 20 + .../src/api/types/FileUploadBlockYaml.ts | 19 + .../client/src/api/types/ForLoopBlock.ts | 15 + .../api/types/ForLoopBlockLoopBlocksItem.ts | 107 + .../src/api/types/ForLoopBlockLoopOver.ts | 62 + .../client/src/api/types/ForLoopBlockYaml.ts | 13 + .../types/ForLoopBlockYamlLoopBlocksItem.ts | 107 + .../client/src/api/types/GetRunResponse.ts | 37 + .../client/src/api/types/HttpRequestBlock.ts | 18 + .../types/HttpRequestBlockParametersItem.ts | 62 + .../src/api/types/HttpRequestBlockYaml.ts | 14 + .../src/api/types/HttpValidationError.ts | 7 + .../src/api/types/InputOrSelectContext.ts | 10 + skyvern-ts/client/src/api/types/LoginBlock.ts | 36 + .../src/api/types/LoginBlockParametersItem.ts | 62 + .../client/src/api/types/LoginBlockYaml.ts | 24 + .../client/src/api/types/NavigationBlock.ts | 36 + .../types/NavigationBlockParametersItem.ts | 62 + .../src/api/types/NavigationBlockYaml.ts | 27 + .../api/types/NonEmptyCreditCardCredential.ts | 19 + .../api/types/NonEmptyPasswordCredential.ts | 17 + .../types/OnePasswordCredentialParameter.ts | 13 + .../OnePasswordCredentialParameterYaml.ts | 8 + skyvern-ts/client/src/api/types/OtpType.ts | 7 + .../client/src/api/types/OutputParameter.ts | 11 + .../src/api/types/OutputParameterYaml.ts | 6 + .../api/types/PasswordCredentialResponse.ts | 13 + .../client/src/api/types/PdfParserBlock.ts | 17 + .../src/api/types/PdfParserBlockYaml.ts | 9 + .../client/src/api/types/ProxyLocation.ts | 30 + skyvern-ts/client/src/api/types/RunEngine.ts | 10 + skyvern-ts/client/src/api/types/RunStatus.ts | 13 + skyvern-ts/client/src/api/types/Script.ts | 20 + .../client/src/api/types/ScriptFileCreate.ts | 17 + .../client/src/api/types/ScriptRunResponse.ts | 5 + .../client/src/api/types/SelectOption.ts | 7 + .../client/src/api/types/SendEmailBlock.ts | 20 + .../src/api/types/SendEmailBlockYaml.ts | 16 + ...orgeSdkSchemasCredentialsCredentialType.ts | 9 + .../SkyvernSchemasRunBlocksCredentialType.ts | 10 + skyvern-ts/client/src/api/types/TaskBlock.ts | 36 + .../src/api/types/TaskBlockParametersItem.ts | 62 + .../client/src/api/types/TaskBlockYaml.ts | 33 + .../client/src/api/types/TaskRunRequest.ts | 95 + .../client/src/api/types/TaskRunResponse.ts | 49 + .../client/src/api/types/TaskV2Block.ts | 17 + .../client/src/api/types/TaskV2BlockYaml.ts | 14 + .../client/src/api/types/TextPromptBlock.ts | 15 + .../types/TextPromptBlockParametersItem.ts | 62 + .../src/api/types/TextPromptBlockYaml.ts | 11 + skyvern-ts/client/src/api/types/Thought.ts | 27 + .../client/src/api/types/ThoughtScenario.ts | 13 + .../client/src/api/types/ThoughtType.ts | 10 + skyvern-ts/client/src/api/types/TotpCode.ts | 32 + skyvern-ts/client/src/api/types/TotpType.ts | 10 + .../client/src/api/types/UploadToS3Block.ts | 12 + .../src/api/types/UploadToS3BlockYaml.ts | 8 + skyvern-ts/client/src/api/types/UrlBlock.ts | 36 + .../src/api/types/UrlBlockParametersItem.ts | 62 + .../client/src/api/types/UrlBlockYaml.ts | 8 + .../client/src/api/types/UserDefinedError.ts | 7 + .../client/src/api/types/ValidationBlock.ts | 36 + .../types/ValidationBlockParametersItem.ts | 62 + .../src/api/types/ValidationBlockYaml.ts | 12 + .../client/src/api/types/ValidationError.ts | 15 + skyvern-ts/client/src/api/types/WaitBlock.ts | 13 + .../src/api/types/WaitBlockParametersItem.ts | 62 + .../client/src/api/types/WaitBlockYaml.ts | 8 + skyvern-ts/client/src/api/types/Workflow.ts | 31 + .../api/types/WorkflowCreateYamlRequest.ts | 24 + .../src/api/types/WorkflowDefinition.ts | 8 + .../api/types/WorkflowDefinitionBlocksItem.ts | 107 + .../types/WorkflowDefinitionParametersItem.ts | 62 + .../src/api/types/WorkflowDefinitionYaml.ts | 8 + .../types/WorkflowDefinitionYamlBlocksItem.ts | 107 + .../WorkflowDefinitionYamlParametersItem.ts | 57 + .../client/src/api/types/WorkflowParameter.ts | 19 + .../src/api/types/WorkflowParameterType.ts | 12 + .../src/api/types/WorkflowParameterYaml.ts | 14 + .../client/src/api/types/WorkflowRequest.ts | 10 + .../client/src/api/types/WorkflowRunBlock.ts | 45 + .../src/api/types/WorkflowRunRequest.ts | 59 + .../src/api/types/WorkflowRunResponse.ts | 53 + .../src/api/types/WorkflowRunTimeline.ts | 12 + .../src/api/types/WorkflowRunTimelineType.ts | 7 + .../client/src/api/types/WorkflowStatus.ts | 8 + skyvern-ts/client/src/api/types/index.ts | 134 + .../client/src/core/fetcher/APIResponse.ts | 23 + .../client/src/core/fetcher/BinaryResponse.ts | 36 + .../src/core/fetcher/EndpointMetadata.ts | 13 + .../src/core/fetcher/EndpointSupplier.ts | 14 + skyvern-ts/client/src/core/fetcher/Fetcher.ts | 165 ++ skyvern-ts/client/src/core/fetcher/Headers.ts | 93 + .../src/core/fetcher/HttpResponsePromise.ts | 116 + .../client/src/core/fetcher/RawResponse.ts | 61 + .../src/core/fetcher/ResponseWithBody.ts | 7 + .../client/src/core/fetcher/Supplier.ts | 11 + .../src/core/fetcher/createRequestUrl.ts | 6 + .../src/core/fetcher/getErrorResponseBody.ts | 33 + .../client/src/core/fetcher/getFetchFn.ts | 3 + .../client/src/core/fetcher/getHeader.ts | 8 + .../client/src/core/fetcher/getRequestBody.ts | 16 + .../src/core/fetcher/getResponseBody.ts | 43 + skyvern-ts/client/src/core/fetcher/index.ts | 11 + .../client/src/core/fetcher/makeRequest.ts | 44 + .../src/core/fetcher/requestWithRetries.ts | 73 + skyvern-ts/client/src/core/fetcher/signals.ts | 38 + skyvern-ts/client/src/core/headers.ts | 33 + skyvern-ts/client/src/core/index.ts | 3 + skyvern-ts/client/src/core/json.ts | 27 + skyvern-ts/client/src/core/runtime/index.ts | 1 + skyvern-ts/client/src/core/runtime/runtime.ts | 133 + .../client/src/core/url/encodePathParam.ts | 18 + skyvern-ts/client/src/core/url/index.ts | 3 + skyvern-ts/client/src/core/url/join.ts | 80 + skyvern-ts/client/src/core/url/qs.ts | 74 + skyvern-ts/client/src/environments.ts | 12 + skyvern-ts/client/src/errors/SkyvernError.ts | 53 + .../client/src/errors/SkyvernTimeoutError.ts | 8 + skyvern-ts/client/src/errors/index.ts | 2 + skyvern-ts/client/src/index.ts | 5 + skyvern-ts/client/src/version.ts | 1 + skyvern-ts/client/tests/custom.test.ts | 13 + .../client/tests/mock-server/MockServer.ts | 29 + .../tests/mock-server/MockServerPool.ts | 106 + .../tests/mock-server/mockEndpointBuilder.ts | 215 ++ .../client/tests/mock-server/randomBaseUrl.ts | 4 + skyvern-ts/client/tests/mock-server/setup.ts | 10 + .../client/tests/mock-server/withHeaders.ts | 70 + .../client/tests/mock-server/withJson.ts | 158 ++ skyvern-ts/client/tests/tsconfig.json | 11 + .../client/tests/unit/fetcher/Fetcher.test.ts | 255 ++ .../unit/fetcher/HttpResponsePromise.test.ts | 143 + .../tests/unit/fetcher/RawResponse.test.ts | 34 + .../unit/fetcher/createRequestUrl.test.ts | 160 ++ .../tests/unit/fetcher/getRequestBody.test.ts | 65 + .../unit/fetcher/getResponseBody.test.ts | 77 + .../tests/unit/fetcher/makeRequest.test.ts | 53 + .../unit/fetcher/requestWithRetries.test.ts | 250 ++ .../client/tests/unit/fetcher/signals.test.ts | 69 + .../client/tests/unit/fetcher/test-file.txt | 1 + skyvern-ts/client/tests/unit/url/join.test.ts | 120 + skyvern-ts/client/tests/unit/url/qs.test.ts | 187 ++ skyvern-ts/client/tests/wire/.gitkeep | 0 skyvern-ts/client/tests/wire/main.test.ts | 2426 +++++++++++++++++ skyvern-ts/client/tests/wire/scripts.test.ts | 44 + skyvern-ts/client/tsconfig.base.json | 18 + skyvern-ts/client/tsconfig.cjs.json | 9 + skyvern-ts/client/tsconfig.esm.json | 10 + skyvern-ts/client/tsconfig.json | 3 + skyvern-ts/client/vitest.config.ts | 27 + 239 files changed, 14550 insertions(+), 3 deletions(-) create mode 100644 fern/.gitignore create mode 100755 scripts/fern_build_python_sdk.sh create mode 100755 scripts/fern_build_ts_sdk.sh create mode 100644 skyvern-ts/client/README.md create mode 100644 skyvern-ts/client/biome.json create mode 100644 skyvern-ts/client/package.json create mode 100644 skyvern-ts/client/pnpm-lock.yaml create mode 100644 skyvern-ts/client/pnpm-workspace.yaml create mode 100644 skyvern-ts/client/reference.md create mode 100644 skyvern-ts/client/scripts/rename-to-esm-files.js create mode 100644 skyvern-ts/client/src/BaseClient.ts create mode 100644 skyvern-ts/client/src/Client.ts create mode 100644 skyvern-ts/client/src/api/client/index.ts create mode 100644 skyvern-ts/client/src/api/client/requests/CreateBrowserSessionRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/CreateCredentialRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/CreateScriptRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/DeployScriptRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/GetCredentialsRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/GetRunArtifactsRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/GetScriptsRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/GetWorkflowsRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/LoginRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/RunTaskRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/RunWorkflowRequest.ts create mode 100644 skyvern-ts/client/src/api/client/requests/TotpCodeCreate.ts create mode 100644 skyvern-ts/client/src/api/client/requests/index.ts create mode 100644 skyvern-ts/client/src/api/errors/BadRequestError.ts create mode 100644 skyvern-ts/client/src/api/errors/ForbiddenError.ts create mode 100644 skyvern-ts/client/src/api/errors/NotFoundError.ts create mode 100644 skyvern-ts/client/src/api/errors/UnprocessableEntityError.ts create mode 100644 skyvern-ts/client/src/api/errors/index.ts create mode 100644 skyvern-ts/client/src/api/index.ts create mode 100644 skyvern-ts/client/src/api/resources/index.ts create mode 100644 skyvern-ts/client/src/api/resources/scripts/client/Client.ts create mode 100644 skyvern-ts/client/src/api/resources/scripts/client/index.ts create mode 100644 skyvern-ts/client/src/api/resources/scripts/index.ts create mode 100644 skyvern-ts/client/src/api/types/Action.ts create mode 100644 skyvern-ts/client/src/api/types/ActionBlock.ts create mode 100644 skyvern-ts/client/src/api/types/ActionBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/ActionBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/ActionStatus.ts create mode 100644 skyvern-ts/client/src/api/types/ActionType.ts create mode 100644 skyvern-ts/client/src/api/types/Artifact.ts create mode 100644 skyvern-ts/client/src/api/types/ArtifactType.ts create mode 100644 skyvern-ts/client/src/api/types/AwsSecretParameter.ts create mode 100644 skyvern-ts/client/src/api/types/AwsSecretParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/AzureSecretParameter.ts create mode 100644 skyvern-ts/client/src/api/types/AzureVaultCredentialParameter.ts create mode 100644 skyvern-ts/client/src/api/types/AzureVaultCredentialParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/BitwardenCreditCardDataParameter.ts create mode 100644 skyvern-ts/client/src/api/types/BitwardenCreditCardDataParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/BitwardenLoginCredentialParameter.ts create mode 100644 skyvern-ts/client/src/api/types/BitwardenLoginCredentialParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/BitwardenSensitiveInformationParameter.ts create mode 100644 skyvern-ts/client/src/api/types/BitwardenSensitiveInformationParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/BlockType.ts create mode 100644 skyvern-ts/client/src/api/types/BrowserSessionResponse.ts create mode 100644 skyvern-ts/client/src/api/types/CodeBlock.ts create mode 100644 skyvern-ts/client/src/api/types/CodeBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/CodeBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/ContextParameter.ts create mode 100644 skyvern-ts/client/src/api/types/ContextParameterSource.ts create mode 100644 skyvern-ts/client/src/api/types/ContextParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/CreateScriptResponse.ts create mode 100644 skyvern-ts/client/src/api/types/CredentialParameter.ts create mode 100644 skyvern-ts/client/src/api/types/CredentialParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/CredentialResponse.ts create mode 100644 skyvern-ts/client/src/api/types/CredentialTypeOutput.ts create mode 100644 skyvern-ts/client/src/api/types/CreditCardCredentialResponse.ts create mode 100644 skyvern-ts/client/src/api/types/DownloadToS3Block.ts create mode 100644 skyvern-ts/client/src/api/types/DownloadToS3BlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/ExtractionBlock.ts create mode 100644 skyvern-ts/client/src/api/types/ExtractionBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/ExtractionBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/FileDownloadBlock.ts create mode 100644 skyvern-ts/client/src/api/types/FileDownloadBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/FileDownloadBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/FileEncoding.ts create mode 100644 skyvern-ts/client/src/api/types/FileInfo.ts create mode 100644 skyvern-ts/client/src/api/types/FileNode.ts create mode 100644 skyvern-ts/client/src/api/types/FileParserBlock.ts create mode 100644 skyvern-ts/client/src/api/types/FileParserBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/FileStorageType.ts create mode 100644 skyvern-ts/client/src/api/types/FileType.ts create mode 100644 skyvern-ts/client/src/api/types/FileUploadBlock.ts create mode 100644 skyvern-ts/client/src/api/types/FileUploadBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/ForLoopBlock.ts create mode 100644 skyvern-ts/client/src/api/types/ForLoopBlockLoopBlocksItem.ts create mode 100644 skyvern-ts/client/src/api/types/ForLoopBlockLoopOver.ts create mode 100644 skyvern-ts/client/src/api/types/ForLoopBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/ForLoopBlockYamlLoopBlocksItem.ts create mode 100644 skyvern-ts/client/src/api/types/GetRunResponse.ts create mode 100644 skyvern-ts/client/src/api/types/HttpRequestBlock.ts create mode 100644 skyvern-ts/client/src/api/types/HttpRequestBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/HttpRequestBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/HttpValidationError.ts create mode 100644 skyvern-ts/client/src/api/types/InputOrSelectContext.ts create mode 100644 skyvern-ts/client/src/api/types/LoginBlock.ts create mode 100644 skyvern-ts/client/src/api/types/LoginBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/LoginBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/NavigationBlock.ts create mode 100644 skyvern-ts/client/src/api/types/NavigationBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/NavigationBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/NonEmptyCreditCardCredential.ts create mode 100644 skyvern-ts/client/src/api/types/NonEmptyPasswordCredential.ts create mode 100644 skyvern-ts/client/src/api/types/OnePasswordCredentialParameter.ts create mode 100644 skyvern-ts/client/src/api/types/OnePasswordCredentialParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/OtpType.ts create mode 100644 skyvern-ts/client/src/api/types/OutputParameter.ts create mode 100644 skyvern-ts/client/src/api/types/OutputParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/PasswordCredentialResponse.ts create mode 100644 skyvern-ts/client/src/api/types/PdfParserBlock.ts create mode 100644 skyvern-ts/client/src/api/types/PdfParserBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/ProxyLocation.ts create mode 100644 skyvern-ts/client/src/api/types/RunEngine.ts create mode 100644 skyvern-ts/client/src/api/types/RunStatus.ts create mode 100644 skyvern-ts/client/src/api/types/Script.ts create mode 100644 skyvern-ts/client/src/api/types/ScriptFileCreate.ts create mode 100644 skyvern-ts/client/src/api/types/ScriptRunResponse.ts create mode 100644 skyvern-ts/client/src/api/types/SelectOption.ts create mode 100644 skyvern-ts/client/src/api/types/SendEmailBlock.ts create mode 100644 skyvern-ts/client/src/api/types/SendEmailBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/SkyvernForgeSdkSchemasCredentialsCredentialType.ts create mode 100644 skyvern-ts/client/src/api/types/SkyvernSchemasRunBlocksCredentialType.ts create mode 100644 skyvern-ts/client/src/api/types/TaskBlock.ts create mode 100644 skyvern-ts/client/src/api/types/TaskBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/TaskBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/TaskRunRequest.ts create mode 100644 skyvern-ts/client/src/api/types/TaskRunResponse.ts create mode 100644 skyvern-ts/client/src/api/types/TaskV2Block.ts create mode 100644 skyvern-ts/client/src/api/types/TaskV2BlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/TextPromptBlock.ts create mode 100644 skyvern-ts/client/src/api/types/TextPromptBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/TextPromptBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/Thought.ts create mode 100644 skyvern-ts/client/src/api/types/ThoughtScenario.ts create mode 100644 skyvern-ts/client/src/api/types/ThoughtType.ts create mode 100644 skyvern-ts/client/src/api/types/TotpCode.ts create mode 100644 skyvern-ts/client/src/api/types/TotpType.ts create mode 100644 skyvern-ts/client/src/api/types/UploadToS3Block.ts create mode 100644 skyvern-ts/client/src/api/types/UploadToS3BlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/UrlBlock.ts create mode 100644 skyvern-ts/client/src/api/types/UrlBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/UrlBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/UserDefinedError.ts create mode 100644 skyvern-ts/client/src/api/types/ValidationBlock.ts create mode 100644 skyvern-ts/client/src/api/types/ValidationBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/ValidationBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/ValidationError.ts create mode 100644 skyvern-ts/client/src/api/types/WaitBlock.ts create mode 100644 skyvern-ts/client/src/api/types/WaitBlockParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/WaitBlockYaml.ts create mode 100644 skyvern-ts/client/src/api/types/Workflow.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowCreateYamlRequest.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowDefinition.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowDefinitionBlocksItem.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowDefinitionParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowDefinitionYaml.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowDefinitionYamlBlocksItem.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowDefinitionYamlParametersItem.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowParameter.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowParameterType.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowParameterYaml.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowRequest.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowRunBlock.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowRunRequest.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowRunResponse.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowRunTimeline.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowRunTimelineType.ts create mode 100644 skyvern-ts/client/src/api/types/WorkflowStatus.ts create mode 100644 skyvern-ts/client/src/api/types/index.ts create mode 100644 skyvern-ts/client/src/core/fetcher/APIResponse.ts create mode 100644 skyvern-ts/client/src/core/fetcher/BinaryResponse.ts create mode 100644 skyvern-ts/client/src/core/fetcher/EndpointMetadata.ts create mode 100644 skyvern-ts/client/src/core/fetcher/EndpointSupplier.ts create mode 100644 skyvern-ts/client/src/core/fetcher/Fetcher.ts create mode 100644 skyvern-ts/client/src/core/fetcher/Headers.ts create mode 100644 skyvern-ts/client/src/core/fetcher/HttpResponsePromise.ts create mode 100644 skyvern-ts/client/src/core/fetcher/RawResponse.ts create mode 100644 skyvern-ts/client/src/core/fetcher/ResponseWithBody.ts create mode 100644 skyvern-ts/client/src/core/fetcher/Supplier.ts create mode 100644 skyvern-ts/client/src/core/fetcher/createRequestUrl.ts create mode 100644 skyvern-ts/client/src/core/fetcher/getErrorResponseBody.ts create mode 100644 skyvern-ts/client/src/core/fetcher/getFetchFn.ts create mode 100644 skyvern-ts/client/src/core/fetcher/getHeader.ts create mode 100644 skyvern-ts/client/src/core/fetcher/getRequestBody.ts create mode 100644 skyvern-ts/client/src/core/fetcher/getResponseBody.ts create mode 100644 skyvern-ts/client/src/core/fetcher/index.ts create mode 100644 skyvern-ts/client/src/core/fetcher/makeRequest.ts create mode 100644 skyvern-ts/client/src/core/fetcher/requestWithRetries.ts create mode 100644 skyvern-ts/client/src/core/fetcher/signals.ts create mode 100644 skyvern-ts/client/src/core/headers.ts create mode 100644 skyvern-ts/client/src/core/index.ts create mode 100644 skyvern-ts/client/src/core/json.ts create mode 100644 skyvern-ts/client/src/core/runtime/index.ts create mode 100644 skyvern-ts/client/src/core/runtime/runtime.ts create mode 100644 skyvern-ts/client/src/core/url/encodePathParam.ts create mode 100644 skyvern-ts/client/src/core/url/index.ts create mode 100644 skyvern-ts/client/src/core/url/join.ts create mode 100644 skyvern-ts/client/src/core/url/qs.ts create mode 100644 skyvern-ts/client/src/environments.ts create mode 100644 skyvern-ts/client/src/errors/SkyvernError.ts create mode 100644 skyvern-ts/client/src/errors/SkyvernTimeoutError.ts create mode 100644 skyvern-ts/client/src/errors/index.ts create mode 100644 skyvern-ts/client/src/index.ts create mode 100644 skyvern-ts/client/src/version.ts create mode 100644 skyvern-ts/client/tests/custom.test.ts create mode 100644 skyvern-ts/client/tests/mock-server/MockServer.ts create mode 100644 skyvern-ts/client/tests/mock-server/MockServerPool.ts create mode 100644 skyvern-ts/client/tests/mock-server/mockEndpointBuilder.ts create mode 100644 skyvern-ts/client/tests/mock-server/randomBaseUrl.ts create mode 100644 skyvern-ts/client/tests/mock-server/setup.ts create mode 100644 skyvern-ts/client/tests/mock-server/withHeaders.ts create mode 100644 skyvern-ts/client/tests/mock-server/withJson.ts create mode 100644 skyvern-ts/client/tests/tsconfig.json create mode 100644 skyvern-ts/client/tests/unit/fetcher/Fetcher.test.ts create mode 100644 skyvern-ts/client/tests/unit/fetcher/HttpResponsePromise.test.ts create mode 100644 skyvern-ts/client/tests/unit/fetcher/RawResponse.test.ts create mode 100644 skyvern-ts/client/tests/unit/fetcher/createRequestUrl.test.ts create mode 100644 skyvern-ts/client/tests/unit/fetcher/getRequestBody.test.ts create mode 100644 skyvern-ts/client/tests/unit/fetcher/getResponseBody.test.ts create mode 100644 skyvern-ts/client/tests/unit/fetcher/makeRequest.test.ts create mode 100644 skyvern-ts/client/tests/unit/fetcher/requestWithRetries.test.ts create mode 100644 skyvern-ts/client/tests/unit/fetcher/signals.test.ts create mode 100644 skyvern-ts/client/tests/unit/fetcher/test-file.txt create mode 100644 skyvern-ts/client/tests/unit/url/join.test.ts create mode 100644 skyvern-ts/client/tests/unit/url/qs.test.ts create mode 100644 skyvern-ts/client/tests/wire/.gitkeep create mode 100644 skyvern-ts/client/tests/wire/main.test.ts create mode 100644 skyvern-ts/client/tests/wire/scripts.test.ts create mode 100644 skyvern-ts/client/tsconfig.base.json create mode 100644 skyvern-ts/client/tsconfig.cjs.json create mode 100644 skyvern-ts/client/tsconfig.esm.json create mode 100644 skyvern-ts/client/tsconfig.json create mode 100644 skyvern-ts/client/vitest.config.ts diff --git a/fern/.gitignore b/fern/.gitignore new file mode 100644 index 00000000..5b898f05 --- /dev/null +++ b/fern/.gitignore @@ -0,0 +1 @@ +.preview \ No newline at end of file diff --git a/fern/credentials/introduction.mdx b/fern/credentials/introduction.mdx index e5b705df..f5c9f44a 100644 --- a/fern/credentials/introduction.mdx +++ b/fern/credentials/introduction.mdx @@ -4,7 +4,7 @@ subtitle: Never send your credentials to LLMs. slug: credentials/introduction --- -Need to give Skyvern access to your credentials? Usernames and passwords, 2FA, credit cards for payments, etc. Skyvern's credential management provides a secure way to manage and use credentials. Agents can then without exposing those credentials to LLMs. +Need to give Skyvern access to your credentials? Usernames and passwords, 2FA, credit cards for payments, etc. Skyvern's credential management provides a secure way to manage and use credentials. Agents can then use them without exposing those credentials to LLMs. ### 2FA Support (TOTP) diff --git a/fern/docs.yml b/fern/docs.yml index 6553e2ef..3e608bb8 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -158,6 +158,7 @@ navigation: - api: API Reference snippets: python: skyvern + typescript: "@skyvern/client" layout: - section: Agent contents: diff --git a/fern/fern.config.json b/fern/fern.config.json index 36ea4c6d..c345567b 100644 --- a/fern/fern.config.json +++ b/fern/fern.config.json @@ -1,4 +1,4 @@ { "organization": "skyvern", - "version": "0.63.26" + "version": "0.94.3" } \ No newline at end of file diff --git a/fern/generators.yml b/fern/generators.yml index 63d14ad9..99f0d96c 100644 --- a/fern/generators.yml +++ b/fern/generators.yml @@ -17,7 +17,7 @@ groups: generators: - name: fernapi/fern-python-sdk smart-casing: true - version: 4.3.17 + version: 4.31.1 output: location: pypi package-name: skyvern @@ -25,3 +25,14 @@ groups: repository: Skyvern-AI/skyvern-python config: client_class_name: Skyvern + ts-sdk: + generators: + - name: fernapi/fern-typescript-sdk + version: 3.11.1 + output: + location: npm + package-name: "@skyvern/client" + github: + repository: Skyvern-AI/skyvern-typescript + config: + namespaceExport: Skyvern diff --git a/scripts/fern_build_python_sdk.sh b/scripts/fern_build_python_sdk.sh new file mode 100755 index 00000000..cc204c2a --- /dev/null +++ b/scripts/fern_build_python_sdk.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +fern generate --group python-sdk --log-level debug --preview +cp -rf fern/.preview/fern-python-sdk/src/skyvern/* skyvern/client/ \ No newline at end of file diff --git a/scripts/fern_build_ts_sdk.sh b/scripts/fern_build_ts_sdk.sh new file mode 100755 index 00000000..698d9bae --- /dev/null +++ b/scripts/fern_build_ts_sdk.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +fern generate --group ts-sdk --log-level debug --preview +cp -rf fern/.preview/fern-typescript-sdk/* skyvern-ts/client/ \ No newline at end of file diff --git a/skyvern-ts/client/README.md b/skyvern-ts/client/README.md new file mode 100644 index 00000000..df2488f1 --- /dev/null +++ b/skyvern-ts/client/README.md @@ -0,0 +1,183 @@ +# Skyvern 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%2FSkyvern-AI%2Fskyvern-typescript) +[![npm shield](https://img.shields.io/npm/v/@skyvern/client)](https://www.npmjs.com/package/@skyvern/client) + +The Skyvern TypeScript library provides convenient access to the Skyvern APIs from TypeScript. + +## Installation + +```sh +npm i -s @skyvern/client +``` + +## Reference + +A full reference for this library is available [here](https://github.com/Skyvern-AI/skyvern-typescript/blob/HEAD/./reference.md). + +## Usage + +Instantiate and use the client with the following: + +```typescript +import { SkyvernClient } from "@skyvern/client"; + +const client = new SkyvernClient({ xApiKey: "YOUR_X_API_KEY", apiKey: "YOUR_API_KEY" }); +await client.runTask({ + "x-user-agent": "x-user-agent", + body: { + prompt: "Find the top 3 posts on Hacker News." + } +}); +``` + +## Request And Response Types + +The SDK exports all request and response types as TypeScript interfaces. Simply import them with the +following namespace: + +```typescript +import { Skyvern } from "@skyvern/client"; + +const request: Skyvern.RunTaskRequest = { + ... +}; +``` + +## Exception Handling + +When the API returns a non-success status code (4xx or 5xx response), a subclass of the following error +will be thrown. + +```typescript +import { SkyvernError } from "@skyvern/client"; + +try { + await client.runTask(...); +} catch (err) { + if (err instanceof SkyvernError) { + console.log(err.statusCode); + console.log(err.message); + console.log(err.body); + console.log(err.rawResponse); + } +} +``` + +## Advanced + +### Additional Headers + +If you would like to send additional headers as part of the request, use the `headers` request option. + +```typescript +const response = await client.runTask(..., { + headers: { + 'X-Custom-Header': 'custom value' + } +}); +``` + +### 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.runTask(..., { + queryParams: { + 'customQueryParamKey': 'custom query param value' + } +}); +``` + +### Retries + +The SDK is instrumented with automatic retries with exponential backoff. A request will be retried as long +as the request is deemed retryable and the number of retry attempts has not grown larger than the configured +retry limit (default: 2). + +A request is deemed retryable when any of the following HTTP status codes is returned: + +- [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout) +- [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests) +- [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors) + +Use the `maxRetries` request option to configure this behavior. + +```typescript +const response = await client.runTask(..., { + maxRetries: 0 // override maxRetries at the request level +}); +``` + +### Timeouts + +The SDK defaults to a 60 second timeout. Use the `timeoutInSeconds` option to configure this behavior. + +```typescript +const response = await client.runTask(..., { + timeoutInSeconds: 30 // override timeout to 30s +}); +``` + +### Aborting Requests + +The SDK allows users to abort requests at any point by passing in an abort signal. + +```typescript +const controller = new AbortController(); +const response = await client.runTask(..., { + abortSignal: controller.signal +}); +controller.abort(); // aborts the request +``` + +### Access Raw Response Data + +The SDK provides access to raw response data, including headers, through the `.withRawResponse()` method. +The `.withRawResponse()` method returns a promise that results to an object with a `data` and a `rawResponse` property. + +```typescript +const { data, rawResponse } = await client.runTask(...).withRawResponse(); + +console.log(data); +console.log(rawResponse.headers['X-My-Header']); +``` + +### Runtime Compatibility + + +The SDK works in the following runtimes: + + + +- Node.js 18+ +- Vercel +- Cloudflare Workers +- Deno v1.25+ +- Bun 1.0+ +- React Native + +### Customizing Fetch Client + +The SDK provides a way for you to customize the underlying HTTP client / Fetch function. If you're running in an +unsupported environment, this provides a way for you to break glass and ensure the SDK works. + +```typescript +import { SkyvernClient } from "@skyvern/client"; + +const client = new SkyvernClient({ + ... + fetcher: // provide your implementation here +}); +``` + +## Contributing + +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! \ No newline at end of file diff --git a/skyvern-ts/client/biome.json b/skyvern-ts/client/biome.json new file mode 100644 index 00000000..b6890dfb --- /dev/null +++ b/skyvern-ts/client/biome.json @@ -0,0 +1,69 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.2.5/schema.json", + "root": true, + "vcs": { + "enabled": false + }, + "files": { + "ignoreUnknown": true, + "includes": [ + "./**", + "!dist", + "!lib", + "!*.tsbuildinfo", + "!_tmp_*", + "!*.tmp", + "!.tmp/", + "!*.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/skyvern-ts/client/package.json b/skyvern-ts/client/package.json new file mode 100644 index 00000000..17839971 --- /dev/null +++ b/skyvern-ts/client/package.json @@ -0,0 +1,65 @@ +{ + "name": "@skyvern/client", + "version": "0.2.18", + "private": false, + "repository": "github:Skyvern-AI/skyvern-typescript", + "type": "commonjs", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.mjs", + "types": "./dist/cjs/index.d.ts", + "exports": { + ".": { + "types": "./dist/cjs/index.d.ts", + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + }, + "default": "./dist/cjs/index.js" + }, + "./package.json": "./package.json" + }, + "files": [ + "dist", + "reference.md", + "README.md", + "LICENSE" + ], + "scripts": { + "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": "vitest", + "test:unit": "vitest --project unit", + "test:wire": "vitest --project wire" + }, + "devDependencies": { + "webpack": "^5.97.1", + "ts-loader": "^9.5.1", + "vitest": "^3.2.4", + "msw": "2.11.2", + "@types/node": "^18.19.70", + "typescript": "~5.7.2", + "@biomejs/biome": "2.2.5" + }, + "browser": { + "fs": false, + "os": false, + "path": false, + "stream": false + }, + "packageManager": "pnpm@10.14.0", + "engines": { + "node": ">=18.0.0" + }, + "sideEffects": false +} diff --git a/skyvern-ts/client/pnpm-lock.yaml b/skyvern-ts/client/pnpm-lock.yaml new file mode 100644 index 00000000..0be5d564 --- /dev/null +++ b/skyvern-ts/client/pnpm-lock.yaml @@ -0,0 +1,1649 @@ +lockfileVersion: '9.0' +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false +importers: + .: + devDependencies: + '@biomejs/biome': + specifier: 2.2.5 + version: 2.2.5 + '@types/node': + specifier: ^18.19.70 + version: 18.19.130 + 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.102.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.44.0) + webpack: + specifier: ^5.97.1 + version: 5.102.1 +packages: + '@biomejs/biome@2.2.5': + resolution: {integrity: sha512-zcIi+163Rc3HtyHbEO7CjeHq8DjQRs40HsGbW6vx2WI0tg8mYQOPouhvHSyEnCBAorfYNnKdR64/IxO7xQ5faw==} + engines: {node: '>=14.21.3'} + hasBin: true + '@biomejs/cli-darwin-arm64@2.2.5': + resolution: {integrity: sha512-MYT+nZ38wEIWVcL5xLyOhYQQ7nlWD0b/4mgATW2c8dvq7R4OQjt/XGXFkXrmtWmQofaIM14L7V8qIz/M+bx5QQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + '@biomejs/cli-darwin-x64@2.2.5': + resolution: {integrity: sha512-FLIEl73fv0R7dI10EnEiZLw+IMz3mWLnF95ASDI0kbx6DDLJjWxE5JxxBfmG+udz1hIDd3fr5wsuP7nwuTRdAg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + '@biomejs/cli-linux-arm64-musl@2.2.5': + resolution: {integrity: sha512-5Ov2wgAFwqDvQiESnu7b9ufD1faRa+40uwrohgBopeY84El2TnBDoMNXx6iuQdreoFGjwW8vH6k68G21EpNERw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + '@biomejs/cli-linux-arm64@2.2.5': + resolution: {integrity: sha512-5DjiiDfHqGgR2MS9D+AZ8kOfrzTGqLKywn8hoXpXXlJXIECGQ32t+gt/uiS2XyGBM2XQhR6ztUvbjZWeccFMoQ==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + '@biomejs/cli-linux-x64-musl@2.2.5': + resolution: {integrity: sha512-AVqLCDb/6K7aPNIcxHaTQj01sl1m989CJIQFQEaiQkGr2EQwyOpaATJ473h+nXDUuAcREhccfRpe/tu+0wu0eQ==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + '@biomejs/cli-linux-x64@2.2.5': + resolution: {integrity: sha512-fq9meKm1AEXeAWan3uCg6XSP5ObA6F/Ovm89TwaMiy1DNIwdgxPkNwxlXJX8iM6oRbFysYeGnT0OG8diCWb9ew==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + '@biomejs/cli-win32-arm64@2.2.5': + resolution: {integrity: sha512-xaOIad4wBambwJa6mdp1FigYSIF9i7PCqRbvBqtIi9y29QtPVQ13sDGtUnsRoe6SjL10auMzQ6YAe+B3RpZXVg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + '@biomejs/cli-win32-x64@2.2.5': + resolution: {integrity: sha512-F/jhuXCssPFAuciMhHKk00xnCAxJRS/pUzVfXYmOMUp//XW7mO6QeCjsjvnm8L4AO/dG2VOB0O+fJPiJ2uXtIw==} + 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.25.11': + resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.25.11': + resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.25.11': + resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.25.11': + resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.25.11': + resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.25.11': + resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.25.11': + resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.11': + resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.25.11': + resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.25.11': + resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.25.11': + resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.25.11': + resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.25.11': + resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.25.11': + resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.25.11': + resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.25.11': + resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.25.11': + resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.11': + resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.11': + resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.11': + resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.11': + resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.11': + resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.25.11': + resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.25.11': + resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.25.11': + resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.25.11': + resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@inquirer/ansi@1.0.1': + resolution: {integrity: sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==} + engines: {node: '>=18'} + '@inquirer/confirm@5.1.19': + resolution: {integrity: sha512-wQNz9cfcxrtEnUyG5PndC8g3gZ7lGDBzmWiXZkX8ot3vfZ+/BLjR8EvyGX4YzQLeVqtAlY/YScZpW7CW8qMoDQ==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/core@10.3.0': + resolution: {integrity: sha512-Uv2aPPPSK5jeCplQmQ9xadnFx2Zhj9b5Dj7bU6ZeCdDNNY11nhYy4btcSdtDguHqCT2h5oNeQTcUNSGGLA7NTA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + '@inquirer/figures@1.0.14': + resolution: {integrity: sha512-DbFgdt+9/OZYFM+19dbpXOSeAstPy884FPy1KjDu4anWwymZeOYhMY1mdFri172htv6mvc/uvIAAi7b7tvjJBQ==} + engines: {node: '>=18'} + '@inquirer/type@3.0.9': + resolution: {integrity: sha512-QPaNt/nmE2bLGQa9b7wwyRJoLZ7pN6rcyXvzU0YCmivmJyq1BVo94G98tStRWkoD1RgDX5C+dPlhhHzNdu/W/w==} + 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.52.5': + resolution: {integrity: sha512-8c1vW4ocv3UOMp9K+gToY5zL2XiiVw3k7f1ksf4yO1FlDFQ1C2u72iACFnSOceJFsWskc2WZNqeRhFRPzv+wtQ==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.52.5': + resolution: {integrity: sha512-mQGfsIEFcu21mvqkEKKu2dYmtuSZOBMmAl5CFlPGLY94Vlcm+zWApK7F/eocsNzp8tKmbeBP8yXyAbx0XHsFNA==} + cpu: [arm64] + os: [android] + '@rollup/rollup-darwin-arm64@4.52.5': + resolution: {integrity: sha512-takF3CR71mCAGA+v794QUZ0b6ZSrgJkArC+gUiG6LB6TQty9T0Mqh3m2ImRBOxS2IeYBo4lKWIieSvnEk2OQWA==} + cpu: [arm64] + os: [darwin] + '@rollup/rollup-darwin-x64@4.52.5': + resolution: {integrity: sha512-W901Pla8Ya95WpxDn//VF9K9u2JbocwV/v75TE0YIHNTbhqUTv9w4VuQ9MaWlNOkkEfFwkdNhXgcLqPSmHy0fA==} + cpu: [x64] + os: [darwin] + '@rollup/rollup-freebsd-arm64@4.52.5': + resolution: {integrity: sha512-QofO7i7JycsYOWxe0GFqhLmF6l1TqBswJMvICnRUjqCx8b47MTo46W8AoeQwiokAx3zVryVnxtBMcGcnX12LvA==} + cpu: [arm64] + os: [freebsd] + '@rollup/rollup-freebsd-x64@4.52.5': + resolution: {integrity: sha512-jr21b/99ew8ujZubPo9skbrItHEIE50WdV86cdSoRkKtmWa+DDr6fu2c/xyRT0F/WazZpam6kk7IHBerSL7LDQ==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + resolution: {integrity: sha512-PsNAbcyv9CcecAUagQefwX8fQn9LQ4nZkpDboBOttmyffnInRy8R8dSg6hxxl2Re5QhHBf6FYIDhIj5v982ATQ==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + resolution: {integrity: sha512-Fw4tysRutyQc/wwkmcyoqFtJhh0u31K+Q6jYjeicsGJJ7bbEq8LwPWV/w0cnzOqR2m694/Af6hpFayLJZkG2VQ==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.52.5': + resolution: {integrity: sha512-a+3wVnAYdQClOTlyapKmyI6BLPAFYs0JM8HRpgYZQO02rMR09ZcV9LbQB+NL6sljzG38869YqThrRnfPMCDtZg==} + cpu: [arm64] + os: [linux] + '@rollup/rollup-linux-arm64-musl@4.52.5': + resolution: {integrity: sha512-AvttBOMwO9Pcuuf7m9PkC1PUIKsfaAJ4AYhy944qeTJgQOqJYJ9oVl2nYgY7Rk0mkbsuOpCAYSs6wLYB2Xiw0Q==} + cpu: [arm64] + os: [linux] + '@rollup/rollup-linux-loong64-gnu@4.52.5': + resolution: {integrity: sha512-DkDk8pmXQV2wVrF6oq5tONK6UHLz/XcEVow4JTTerdeV1uqPeHxwcg7aFsfnSm9L+OO8WJsWotKM2JJPMWrQtA==} + cpu: [loong64] + os: [linux] + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + resolution: {integrity: sha512-W/b9ZN/U9+hPQVvlGwjzi+Wy4xdoH2I8EjaCkMvzpI7wJUs8sWJ03Rq96jRnHkSrcHTpQe8h5Tg3ZzUPGauvAw==} + cpu: [ppc64] + os: [linux] + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + resolution: {integrity: sha512-sjQLr9BW7R/ZiXnQiWPkErNfLMkkWIoCz7YMn27HldKsADEKa5WYdobaa1hmN6slu9oWQbB6/jFpJ+P2IkVrmw==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-riscv64-musl@4.52.5': + resolution: {integrity: sha512-hq3jU/kGyjXWTvAh2awn8oHroCbrPm8JqM7RUpKjalIRWWXE01CQOf/tUNWNHjmbMHg/hmNCwc/Pz3k1T/j/Lg==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.52.5': + resolution: {integrity: sha512-gn8kHOrku8D4NGHMK1Y7NA7INQTRdVOntt1OCYypZPRt6skGbddska44K8iocdpxHTMMNui5oH4elPH4QOLrFQ==} + cpu: [s390x] + os: [linux] + '@rollup/rollup-linux-x64-gnu@4.52.5': + resolution: {integrity: sha512-hXGLYpdhiNElzN770+H2nlx+jRog8TyynpTVzdlc6bndktjKWyZyiCsuDAlpd+j+W+WNqfcyAWz9HxxIGfZm1Q==} + cpu: [x64] + os: [linux] + '@rollup/rollup-linux-x64-musl@4.52.5': + resolution: {integrity: sha512-arCGIcuNKjBoKAXD+y7XomR9gY6Mw7HnFBv5Rw7wQRvwYLR7gBAgV7Mb2QTyjXfTveBNFAtPt46/36vV9STLNg==} + cpu: [x64] + os: [linux] + '@rollup/rollup-openharmony-arm64@4.52.5': + resolution: {integrity: sha512-QoFqB6+/9Rly/RiPjaomPLmR/13cgkIGfA40LHly9zcH1S0bN2HVFYk3a1eAyHQyjs3ZJYlXvIGtcCs5tko9Cw==} + cpu: [arm64] + os: [openharmony] + '@rollup/rollup-win32-arm64-msvc@4.52.5': + resolution: {integrity: sha512-w0cDWVR6MlTstla1cIfOGyl8+qb93FlAVutcor14Gf5Md5ap5ySfQ7R9S/NjNaMLSFdUnKGEasmVnu3lCMqB7w==} + cpu: [arm64] + os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.52.5': + resolution: {integrity: sha512-Aufdpzp7DpOTULJCuvzqcItSGDH73pF3ko/f+ckJhxQyHtp67rHw3HMNxoIdDMUITJESNE6a8uh4Lo4SLouOUg==} + cpu: [ia32] + os: [win32] + '@rollup/rollup-win32-x64-gnu@4.52.5': + resolution: {integrity: sha512-UGBUGPFp1vkj6p8wCRraqNhqwX/4kNQPS57BCFc8wYh0g94iVIW33wJtQAx3G7vrjjNtRaxiMUylM0ktp/TRSQ==} + cpu: [x64] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.52.5': + resolution: {integrity: sha512-TAcgQh2sSkykPRWLrdyy2AiceMckNf5loITqXxFI5VuQjS5tSuw3WlwdN8qv8vzjLAUTvYaH/mVjSFpbkFbpTg==} + 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==} + '@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.8.19: + resolution: {integrity: sha512-zoKGUdu6vb2jd3YOq0nnhEDQVbPcHhco3UImJrv5dSkvxTc2pl2WjOPsjZXDwPDSl5eghIMuY3R6J9NDKF3KcQ==} + hasBin: true + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + browserslist@4.27.0: + resolution: {integrity: sha512-AXVQwdhot1eqLihwasPElhX2tAZiBjWdJ9i/Zcj2S6QYIjkx62OKSfnobkriB81C3l4w0rVy3Nt4jaTBltYEpw==} + 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.30001751: + resolution: {integrity: sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw==} + 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.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + 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.238: + resolution: {integrity: sha512-khBdc+w/Gv+cS8e/Pbnaw/FXcBUeKrRVik9IxfXtgREOWyJhR4tj43n3amkVogJ/yeQUqzkrZcFhtIxIdqmmcQ==} + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + enhanced-resolve@5.18.3: + resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} + engines: {node: '>=10.13.0'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + esbuild@0.25.11: + resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} + 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.2.2: + resolution: {integrity: sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==} + 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.11.0: + resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} + 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.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + 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.26: + resolution: {integrity: sha512-S2M9YimhSjBSvYnlr5/+umAnPHE++ODwt5e2Ij6FoX45HA/s4vHdkDx1eax2pAPeAOqu4s9b7ppahsyEFdVqQA==} + 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.52.5: + resolution: {integrity: sha512-3GuObel8h7Kqdjt0gxkEzaifHTqLVW56Y/bjN7PSQtkKr0w3V/QYSdt6QWYtd7A1xUtYQigtdUfgj1RvWVtorw==} + 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.3: + resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} + 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.14: + resolution: {integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==} + 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.44.0: + resolution: {integrity: sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w==} + 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.17: + resolution: {integrity: sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g==} + tldts@7.0.17: + resolution: {integrity: sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ==} + 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.1.4: + resolution: {integrity: sha512-q0SPT4xyU84saUX+tomz1WLkxUbuaJnR1xWt17M7fJtEJigJeWUNGUqrauFXsHnqev9y9JTRGwk13tFBuKby4A==} + 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.1.11: + resolution: {integrity: sha512-uzcxnSDVjAopEUjljkWh8EIrg6tlzrjFUfMcR1EVsRDGwf/ccef0qQPRyOrROwhrTDaApueq+ja+KLPlzR/zdg==} + 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.4.4: + resolution: {integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==} + engines: {node: '>=10.13.0'} + webpack-sources@3.3.3: + resolution: {integrity: sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==} + engines: {node: '>=10.13.0'} + webpack@5.102.1: + resolution: {integrity: sha512-7h/weGm9d/ywQ6qzJ+Xy+r9n/3qgp/thalBbpOi5i223dPXKi04IBtqPN9nTd+jBc7QKfvDbaBnFipYp4sJAUQ==} + 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'} + 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.2.5': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 2.2.5 + '@biomejs/cli-darwin-x64': 2.2.5 + '@biomejs/cli-linux-arm64': 2.2.5 + '@biomejs/cli-linux-arm64-musl': 2.2.5 + '@biomejs/cli-linux-x64': 2.2.5 + '@biomejs/cli-linux-x64-musl': 2.2.5 + '@biomejs/cli-win32-arm64': 2.2.5 + '@biomejs/cli-win32-x64': 2.2.5 + '@biomejs/cli-darwin-arm64@2.2.5': + optional: true + '@biomejs/cli-darwin-x64@2.2.5': + optional: true + '@biomejs/cli-linux-arm64-musl@2.2.5': + optional: true + '@biomejs/cli-linux-arm64@2.2.5': + optional: true + '@biomejs/cli-linux-x64-musl@2.2.5': + optional: true + '@biomejs/cli-linux-x64@2.2.5': + optional: true + '@biomejs/cli-win32-arm64@2.2.5': + optional: true + '@biomejs/cli-win32-x64@2.2.5': + 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.25.11': + optional: true + '@esbuild/android-arm64@0.25.11': + optional: true + '@esbuild/android-arm@0.25.11': + optional: true + '@esbuild/android-x64@0.25.11': + optional: true + '@esbuild/darwin-arm64@0.25.11': + optional: true + '@esbuild/darwin-x64@0.25.11': + optional: true + '@esbuild/freebsd-arm64@0.25.11': + optional: true + '@esbuild/freebsd-x64@0.25.11': + optional: true + '@esbuild/linux-arm64@0.25.11': + optional: true + '@esbuild/linux-arm@0.25.11': + optional: true + '@esbuild/linux-ia32@0.25.11': + optional: true + '@esbuild/linux-loong64@0.25.11': + optional: true + '@esbuild/linux-mips64el@0.25.11': + optional: true + '@esbuild/linux-ppc64@0.25.11': + optional: true + '@esbuild/linux-riscv64@0.25.11': + optional: true + '@esbuild/linux-s390x@0.25.11': + optional: true + '@esbuild/linux-x64@0.25.11': + optional: true + '@esbuild/netbsd-arm64@0.25.11': + optional: true + '@esbuild/netbsd-x64@0.25.11': + optional: true + '@esbuild/openbsd-arm64@0.25.11': + optional: true + '@esbuild/openbsd-x64@0.25.11': + optional: true + '@esbuild/openharmony-arm64@0.25.11': + optional: true + '@esbuild/sunos-x64@0.25.11': + optional: true + '@esbuild/win32-arm64@0.25.11': + optional: true + '@esbuild/win32-ia32@0.25.11': + optional: true + '@esbuild/win32-x64@0.25.11': + optional: true + '@inquirer/ansi@1.0.1': {} + '@inquirer/confirm@5.1.19(@types/node@18.19.130)': + dependencies: + '@inquirer/core': 10.3.0(@types/node@18.19.130) + '@inquirer/type': 3.0.9(@types/node@18.19.130) + optionalDependencies: + '@types/node': 18.19.130 + '@inquirer/core@10.3.0(@types/node@18.19.130)': + dependencies: + '@inquirer/ansi': 1.0.1 + '@inquirer/figures': 1.0.14 + '@inquirer/type': 3.0.9(@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.14': {} + '@inquirer/type@3.0.9(@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.52.5': + optional: true + '@rollup/rollup-android-arm64@4.52.5': + optional: true + '@rollup/rollup-darwin-arm64@4.52.5': + optional: true + '@rollup/rollup-darwin-x64@4.52.5': + optional: true + '@rollup/rollup-freebsd-arm64@4.52.5': + optional: true + '@rollup/rollup-freebsd-x64@4.52.5': + optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.52.5': + optional: true + '@rollup/rollup-linux-arm-musleabihf@4.52.5': + optional: true + '@rollup/rollup-linux-arm64-gnu@4.52.5': + optional: true + '@rollup/rollup-linux-arm64-musl@4.52.5': + optional: true + '@rollup/rollup-linux-loong64-gnu@4.52.5': + optional: true + '@rollup/rollup-linux-ppc64-gnu@4.52.5': + optional: true + '@rollup/rollup-linux-riscv64-gnu@4.52.5': + optional: true + '@rollup/rollup-linux-riscv64-musl@4.52.5': + optional: true + '@rollup/rollup-linux-s390x-gnu@4.52.5': + optional: true + '@rollup/rollup-linux-x64-gnu@4.52.5': + optional: true + '@rollup/rollup-linux-x64-musl@4.52.5': + optional: true + '@rollup/rollup-openharmony-arm64@4.52.5': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.52.5': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.52.5': + optional: true + '@rollup/rollup-win32-x64-gnu@4.52.5': + optional: true + '@rollup/rollup-win32-x64-msvc@4.52.5': + 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': {} + '@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.1.11(@types/node@18.19.130)(terser@5.44.0))': + dependencies: + '@vitest/spy': 3.2.4 + estree-walker: 3.0.3 + magic-string: 0.30.19 + optionalDependencies: + msw: 2.11.2(@types/node@18.19.130)(typescript@5.7.3) + vite: 7.1.11(@types/node@18.19.130)(terser@5.44.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.19 + 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.8.19: {} + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + browserslist@4.27.0: + dependencies: + baseline-browser-mapping: 2.8.19 + caniuse-lite: 1.0.30001751 + electron-to-chromium: 1.5.238 + node-releases: 2.0.26 + update-browserslist-db: 1.1.4(browserslist@4.27.0) + buffer-from@1.1.2: {} + cac@6.7.14: {} + caniuse-lite@1.0.30001751: {} + chai@5.3.3: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + 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.1: {} + 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.238: {} + emoji-regex@8.0.0: {} + enhanced-resolve@5.18.3: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.0 + es-module-lexer@1.7.0: {} + esbuild@0.25.11: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.11 + '@esbuild/android-arm': 0.25.11 + '@esbuild/android-arm64': 0.25.11 + '@esbuild/android-x64': 0.25.11 + '@esbuild/darwin-arm64': 0.25.11 + '@esbuild/darwin-x64': 0.25.11 + '@esbuild/freebsd-arm64': 0.25.11 + '@esbuild/freebsd-x64': 0.25.11 + '@esbuild/linux-arm': 0.25.11 + '@esbuild/linux-arm64': 0.25.11 + '@esbuild/linux-ia32': 0.25.11 + '@esbuild/linux-loong64': 0.25.11 + '@esbuild/linux-mips64el': 0.25.11 + '@esbuild/linux-ppc64': 0.25.11 + '@esbuild/linux-riscv64': 0.25.11 + '@esbuild/linux-s390x': 0.25.11 + '@esbuild/linux-x64': 0.25.11 + '@esbuild/netbsd-arm64': 0.25.11 + '@esbuild/netbsd-x64': 0.25.11 + '@esbuild/openbsd-arm64': 0.25.11 + '@esbuild/openbsd-x64': 0.25.11 + '@esbuild/openharmony-arm64': 0.25.11 + '@esbuild/sunos-x64': 0.25.11 + '@esbuild/win32-arm64': 0.25.11 + '@esbuild/win32-ia32': 0.25.11 + '@esbuild/win32-x64': 0.25.11 + 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.2.2: {} + 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.11.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.19: + 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.19(@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.11.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.26: {} + 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.52.5: + dependencies: + '@types/estree': 1.0.8 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.52.5 + '@rollup/rollup-android-arm64': 4.52.5 + '@rollup/rollup-darwin-arm64': 4.52.5 + '@rollup/rollup-darwin-x64': 4.52.5 + '@rollup/rollup-freebsd-arm64': 4.52.5 + '@rollup/rollup-freebsd-x64': 4.52.5 + '@rollup/rollup-linux-arm-gnueabihf': 4.52.5 + '@rollup/rollup-linux-arm-musleabihf': 4.52.5 + '@rollup/rollup-linux-arm64-gnu': 4.52.5 + '@rollup/rollup-linux-arm64-musl': 4.52.5 + '@rollup/rollup-linux-loong64-gnu': 4.52.5 + '@rollup/rollup-linux-ppc64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-gnu': 4.52.5 + '@rollup/rollup-linux-riscv64-musl': 4.52.5 + '@rollup/rollup-linux-s390x-gnu': 4.52.5 + '@rollup/rollup-linux-x64-gnu': 4.52.5 + '@rollup/rollup-linux-x64-musl': 4.52.5 + '@rollup/rollup-openharmony-arm64': 4.52.5 + '@rollup/rollup-win32-arm64-msvc': 4.52.5 + '@rollup/rollup-win32-ia32-msvc': 4.52.5 + '@rollup/rollup-win32-x64-gnu': 4.52.5 + '@rollup/rollup-win32-x64-msvc': 4.52.5 + 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.3: {} + 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.14(webpack@5.102.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.44.0 + webpack: 5.102.1 + terser@5.44.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.17: {} + tldts@7.0.17: + dependencies: + tldts-core: 7.0.17 + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + tough-cookie@6.0.0: + dependencies: + tldts: 7.0.17 + ts-loader@9.5.4(typescript@5.7.3)(webpack@5.102.1): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.18.3 + micromatch: 4.0.8 + semver: 7.7.3 + source-map: 0.7.6 + typescript: 5.7.3 + webpack: 5.102.1 + type-fest@4.41.0: {} + typescript@5.7.3: {} + undici-types@5.26.5: {} + update-browserslist-db@1.1.4(browserslist@4.27.0): + dependencies: + browserslist: 4.27.0 + escalade: 3.2.0 + picocolors: 1.1.1 + vite-node@3.2.4(@types/node@18.19.130)(terser@5.44.0): + dependencies: + cac: 6.7.14 + debug: 4.4.3 + es-module-lexer: 1.7.0 + pathe: 2.0.3 + vite: 7.1.11(@types/node@18.19.130)(terser@5.44.0) + transitivePeerDependencies: + - '@types/node' + - jiti + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + - tsx + - yaml + vite@7.1.11(@types/node@18.19.130)(terser@5.44.0): + dependencies: + esbuild: 0.25.11 + fdir: 6.5.0(picomatch@4.0.3) + picomatch: 4.0.3 + postcss: 8.5.6 + rollup: 4.52.5 + tinyglobby: 0.2.15 + optionalDependencies: + '@types/node': 18.19.130 + fsevents: 2.3.3 + terser: 5.44.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.44.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.1.11(@types/node@18.19.130)(terser@5.44.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.2.2 + magic-string: 0.30.19 + 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.1.11(@types/node@18.19.130)(terser@5.44.0) + vite-node: 3.2.4(@types/node@18.19.130)(terser@5.44.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.4.4: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + webpack-sources@3.3.3: {} + webpack@5.102.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.27.0 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.18.3 + es-module-lexer: 1.7.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.14(webpack@5.102.1) + watchpack: 2.4.4 + 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 + 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/skyvern-ts/client/pnpm-workspace.yaml b/skyvern-ts/client/pnpm-workspace.yaml new file mode 100644 index 00000000..3da2847f --- /dev/null +++ b/skyvern-ts/client/pnpm-workspace.yaml @@ -0,0 +1 @@ +packages: ['.'] diff --git a/skyvern-ts/client/reference.md b/skyvern-ts/client/reference.md new file mode 100644 index 00000000..99422970 --- /dev/null +++ b/skyvern-ts/client/reference.md @@ -0,0 +1,141 @@ +# Reference +
client.deployScript(scriptId, { ...params }) -> Skyvern.CreateScriptResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Deploy a script with updated files, creating a new version +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.deployScript("s_abc123", { + files: [{ + path: "src/main.py", + content: "content" + }] +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**scriptId:** `string` — The unique identifier of the script + +
+
+ +
+
+ +**request:** `Skyvern.DeployScriptRequest` + +
+
+ +
+
+ +**requestOptions:** `SkyvernClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## +## Scripts +
client.scripts.runScript(scriptId) -> unknown +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Run a script +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.scripts.runScript("s_abc123"); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**scriptId:** `string` — The unique identifier of the script + +
+
+ +
+
+ +**requestOptions:** `Scripts.RequestOptions` + +
+
+
+
+ + +
+
+
diff --git a/skyvern-ts/client/scripts/rename-to-esm-files.js b/skyvern-ts/client/scripts/rename-to-esm-files.js new file mode 100644 index 00000000..7f330c19 --- /dev/null +++ b/skyvern-ts/client/scripts/rename-to-esm-files.js @@ -0,0 +1,126 @@ +#!/usr/bin/env node + +const fs = require("fs").promises; +const path = require("path"); + +const extensionMap = { + ".js": ".mjs", + ".d.ts": ".d.mts", +}; +const oldExtensions = Object.keys(extensionMap); + +async function findFiles(rootPath) { + const files = []; + + async function scan(directory) { + const entries = await fs.readdir(directory, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(directory, entry.name); + + if (entry.isDirectory()) { + if (entry.name !== "node_modules" && !entry.name.startsWith(".")) { + await scan(fullPath); + } + } else if (entry.isFile()) { + if (oldExtensions.some((ext) => entry.name.endsWith(ext))) { + files.push(fullPath); + } + } + } + } + + await scan(rootPath); + return files; +} + +async function updateFiles(files) { + const updatedFiles = []; + for (const file of files) { + const updated = await updateFileContents(file); + updatedFiles.push(updated); + } + + console.log(`Updated imports in ${updatedFiles.length} files.`); +} + +async function updateFileContents(file) { + const content = await fs.readFile(file, "utf8"); + + let newContent = content; + // Update each extension type defined in the map + for (const [oldExt, newExt] of Object.entries(extensionMap)) { + // Handle static imports/exports + const staticRegex = new RegExp( + `(import|export)(.+from\\s+['"])(\\.\\.?\\/[^'"]+)(\\${oldExt})(['"])`, + "g", + ); + newContent = newContent.replace(staticRegex, `$1$2$3${newExt}$5`); + + // Handle dynamic imports (yield import, await import, regular import()) + const dynamicRegex = new RegExp( + `(yield\\s+import|await\\s+import|import)\\s*\\(\\s*['"](\\.\\.\?\\/[^'"]+)(\\${oldExt})['"]\\s*\\)`, + "g", + ); + newContent = newContent.replace(dynamicRegex, `$1("$2${newExt}")`); + } + + if (content !== newContent) { + await fs.writeFile(file, newContent, "utf8"); + return true; + } + return false; +} + +async function renameFiles(files) { + let counter = 0; + for (const file of files) { + const ext = oldExtensions.find((ext) => file.endsWith(ext)); + const newExt = extensionMap[ext]; + + if (newExt) { + const newPath = file.slice(0, -ext.length) + newExt; + await fs.rename(file, newPath); + counter++; + } + } + + console.log(`Renamed ${counter} files.`); +} + +async function main() { + try { + const targetDir = process.argv[2]; + if (!targetDir) { + console.error("Please provide a target directory"); + process.exit(1); + } + + const targetPath = path.resolve(targetDir); + const targetStats = await fs.stat(targetPath); + + if (!targetStats.isDirectory()) { + console.error("The provided path is not a directory"); + process.exit(1); + } + + console.log(`Scanning directory: ${targetDir}`); + + const files = await findFiles(targetDir); + + if (files.length === 0) { + console.log("No matching files found."); + process.exit(0); + } + + console.log(`Found ${files.length} files.`); + await updateFiles(files); + await renameFiles(files); + console.log("\nDone!"); + } catch (error) { + console.error("An error occurred:", error.message); + process.exit(1); + } +} + +main(); diff --git a/skyvern-ts/client/src/BaseClient.ts b/skyvern-ts/client/src/BaseClient.ts new file mode 100644 index 00000000..f6e0168b --- /dev/null +++ b/skyvern-ts/client/src/BaseClient.ts @@ -0,0 +1,34 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as core from "./core/index.js"; +import type * as environments from "./environments.js"; + +export interface BaseClientOptions { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + xApiKey?: core.Supplier; + /** Override the x-api-key header */ + apiKey?: 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; +} + +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 x-api-key header */ + apiKey?: string | undefined; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; +} diff --git a/skyvern-ts/client/src/Client.ts b/skyvern-ts/client/src/Client.ts new file mode 100644 index 00000000..d981a269 --- /dev/null +++ b/skyvern-ts/client/src/Client.ts @@ -0,0 +1,2284 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as Skyvern from "./api/index.js"; +import { Scripts } from "./api/resources/scripts/client/Client.js"; +import type { BaseClientOptions, BaseRequestOptions } from "./BaseClient.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "./core/headers.js"; +import * as core from "./core/index.js"; +import * as environments from "./environments.js"; +import * as errors from "./errors/index.js"; + +export declare namespace SkyvernClient { + export interface Options extends BaseClientOptions {} + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class SkyvernClient { + protected readonly _options: SkyvernClient.Options; + protected _scripts: Scripts | undefined; + + constructor(_options: SkyvernClient.Options = {}) { + this._options = { + ..._options, + headers: mergeHeaders( + { + "x-api-key": _options?.apiKey, + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@skyvern/client", + "X-Fern-SDK-Version": "0.2.18", + "User-Agent": "@skyvern/client/0.2.18", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + _options?.headers, + ), + }; + } + + public get scripts(): Scripts { + return (this._scripts ??= new Scripts(this._options)); + } + + /** + * Run a task + * + * @param {Skyvern.RunTaskRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.BadRequestError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.runTask({ + * "x-user-agent": "x-user-agent", + * body: { + * prompt: "Find the top 3 posts on Hacker News." + * } + * }) + */ + public runTask( + request: Skyvern.RunTaskRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__runTask(request, requestOptions)); + } + + private async __runTask( + request: Skyvern.RunTaskRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { "x-user-agent": userAgent, body: _body } = request; + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-user-agent": userAgent != null ? userAgent : undefined, + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/run/tasks", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: _body, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.TaskRunResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Skyvern.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/run/tasks."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Run a workflow + * + * @param {Skyvern.RunWorkflowRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.BadRequestError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.runWorkflow({ + * "x-max-steps-override": 1, + * "x-user-agent": "x-user-agent", + * template: true, + * body: { + * workflow_id: "wpid_123" + * } + * }) + */ + public runWorkflow( + request: Skyvern.RunWorkflowRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__runWorkflow(request, requestOptions)); + } + + private async __runWorkflow( + request: Skyvern.RunWorkflowRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { template, "x-max-steps-override": maxStepsOverride, "x-user-agent": userAgent, body: _body } = request; + const _queryParams: Record = {}; + if (template != null) { + _queryParams.template = template.toString(); + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-max-steps-override": maxStepsOverride != null ? maxStepsOverride.toString() : undefined, + "x-user-agent": userAgent != null ? userAgent : undefined, + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/run/workflows", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + requestType: "json", + body: _body, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.WorkflowRunResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Skyvern.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/run/workflows."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get run information (task run, workflow run) + * + * @param {string} runId - The id of the task run or the workflow run. + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getRun("tsk_123") + */ + public getRun( + runId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getRun(runId, requestOptions)); + } + + private async __getRun( + runId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/runs/${core.url.encodePathParam(runId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.GetRunResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/runs/{run_id}."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Cancel a run (task or workflow) + * + * @param {string} runId - The id of the task run or the workflow run to cancel. + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.cancelRun("run_id") + */ + public cancelRun(runId: string, requestOptions?: SkyvernClient.RequestOptions): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__cancelRun(runId, requestOptions)); + } + + private async __cancelRun( + runId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/runs/${core.url.encodePathParam(runId)}/cancel`, + ), + method: "POST", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/runs/{run_id}/cancel."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get all workflows with the latest version for the organization. + * + * Search semantics: + * - If `search_key` is provided, its value is used as a unified search term for both + * `workflows.title` and workflow parameter metadata (key, description, and default_value for + * `WorkflowParameterModel`). + * - Falls back to deprecated `title` (title-only search) if `search_key` is not provided. + * - Parameter metadata search excludes soft-deleted parameter rows across all parameter tables. + * + * @param {Skyvern.GetWorkflowsRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getWorkflows({ + * page: 1, + * page_size: 1, + * only_saved_tasks: true, + * only_workflows: true, + * search_key: "search_key", + * title: "title", + * template: true + * }) + */ + public getWorkflows( + request: Skyvern.GetWorkflowsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getWorkflows(request, requestOptions)); + } + + private async __getWorkflows( + request: Skyvern.GetWorkflowsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { + page, + page_size: pageSize, + only_saved_tasks: onlySavedTasks, + only_workflows: onlyWorkflows, + search_key: searchKey, + title, + template, + } = request; + const _queryParams: Record = {}; + if (page != null) { + _queryParams.page = page.toString(); + } + + if (pageSize != null) { + _queryParams.page_size = pageSize.toString(); + } + + if (onlySavedTasks != null) { + _queryParams.only_saved_tasks = onlySavedTasks.toString(); + } + + if (onlyWorkflows != null) { + _queryParams.only_workflows = onlyWorkflows.toString(); + } + + if (searchKey != null) { + _queryParams.search_key = searchKey; + } + + if (title != null) { + _queryParams.title = title; + } + + if (template != null) { + _queryParams.template = template.toString(); + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/workflows", + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Workflow[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/workflows."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Create a new workflow + * + * @param {Skyvern.WorkflowRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.createWorkflow({}) + */ + public createWorkflow( + request: Skyvern.WorkflowRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__createWorkflow(request, requestOptions)); + } + + private async __createWorkflow( + request: Skyvern.WorkflowRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/workflows", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Workflow, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/workflows."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Update a workflow + * + * @param {string} workflowId - The ID of the workflow to update. Workflow ID starts with `wpid_`. + * @param {Skyvern.WorkflowRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.updateWorkflow("wpid_123", {}) + */ + public updateWorkflow( + workflowId: string, + request: Skyvern.WorkflowRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__updateWorkflow(workflowId, request, requestOptions)); + } + + private async __updateWorkflow( + workflowId: string, + request: Skyvern.WorkflowRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/workflows/${core.url.encodePathParam(workflowId)}`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Workflow, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/workflows/{workflow_id}."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Delete a workflow + * + * @param {string} workflowId - The ID of the workflow to delete. Workflow ID starts with `wpid_`. + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.deleteWorkflow("wpid_123") + */ + public deleteWorkflow( + workflowId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__deleteWorkflow(workflowId, requestOptions)); + } + + private async __deleteWorkflow( + workflowId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/workflows/${core.url.encodePathParam(workflowId)}/delete`, + ), + method: "POST", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling POST /v1/workflows/{workflow_id}/delete.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get an artifact + * + * @param {string} artifactId + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getArtifact("artifact_id") + */ + public getArtifact( + artifactId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getArtifact(artifactId, requestOptions)); + } + + private async __getArtifact( + artifactId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/artifacts/${core.url.encodePathParam(artifactId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Artifact, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/artifacts/{artifact_id}."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get artifacts for a run + * + * @param {string} runId - The id of the task run or the workflow run. + * @param {Skyvern.GetRunArtifactsRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getRunArtifacts("run_id") + */ + public getRunArtifacts( + runId: string, + request: Skyvern.GetRunArtifactsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getRunArtifacts(runId, request, requestOptions)); + } + + private async __getRunArtifacts( + runId: string, + request: Skyvern.GetRunArtifactsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { artifact_type: artifactType } = request; + const _queryParams: Record = {}; + if (artifactType != null) { + if (Array.isArray(artifactType)) { + _queryParams.artifact_type = artifactType.map((item) => item); + } else { + _queryParams.artifact_type = artifactType; + } + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/runs/${core.url.encodePathParam(runId)}/artifacts`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Artifact[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/runs/{run_id}/artifacts."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retry sending the webhook for a run + * + * @param {string} runId - The id of the task run or the workflow run. + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.retryRunWebhook("tsk_123") + */ + public retryRunWebhook( + runId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__retryRunWebhook(runId, requestOptions)); + } + + private async __retryRunWebhook( + runId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/runs/${core.url.encodePathParam(runId)}/retry_webhook`, + ), + method: "POST", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling POST /v1/runs/{run_id}/retry_webhook.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get timeline for a run (workflow run or task_v2 run) + * + * @param {string} runId - The id of the workflow run or task_v2 run. + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.BadRequestError} + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getRunTimeline("wr_123") + */ + public getRunTimeline( + runId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getRunTimeline(runId, requestOptions)); + } + + private async __getRunTimeline( + runId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/runs/${core.url.encodePathParam(runId)}/timeline`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.WorkflowRunTimeline[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Skyvern.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/runs/{run_id}/timeline."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get all active browser sessions for the organization + * + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.ForbiddenError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getBrowserSessions() + */ + public getBrowserSessions( + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getBrowserSessions(requestOptions)); + } + + private async __getBrowserSessions( + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/browser_sessions", + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.BrowserSessionResponse[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 403: + throw new Skyvern.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/browser_sessions."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Create a browser session that persists across multiple runs + * + * @param {Skyvern.CreateBrowserSessionRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.ForbiddenError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.createBrowserSession() + */ + public createBrowserSession( + request: Skyvern.CreateBrowserSessionRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__createBrowserSession(request, requestOptions)); + } + + private async __createBrowserSession( + request: Skyvern.CreateBrowserSessionRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/browser_sessions", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.BrowserSessionResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 403: + throw new Skyvern.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/browser_sessions."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Close a session. Once closed, the session cannot be used again. + * + * @param {string} browserSessionId - The ID of the browser session to close. completed_at will be set when the browser session is closed. browser_session_id starts with `pbs_` + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.ForbiddenError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.closeBrowserSession("pbs_123456") + */ + public closeBrowserSession( + browserSessionId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__closeBrowserSession(browserSessionId, requestOptions)); + } + + private async __closeBrowserSession( + browserSessionId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/browser_sessions/${core.url.encodePathParam(browserSessionId)}/close`, + ), + method: "POST", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 403: + throw new Skyvern.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling POST /v1/browser_sessions/{browser_session_id}/close.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Get details about a specific browser session, including the browser address for cdp connection. + * + * @param {string} browserSessionId - The ID of the browser session. browser_session_id starts with `pbs_` + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.ForbiddenError} + * @throws {@link Skyvern.NotFoundError} + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getBrowserSession("pbs_123456") + */ + public getBrowserSession( + browserSessionId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getBrowserSession(browserSessionId, requestOptions)); + } + + private async __getBrowserSession( + browserSessionId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/browser_sessions/${core.url.encodePathParam(browserSessionId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.BrowserSessionResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 403: + throw new Skyvern.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new Skyvern.NotFoundError(_response.error.body as unknown, _response.rawResponse); + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling GET /v1/browser_sessions/{browser_session_id}.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Forward a TOTP (2FA, MFA) email or sms message containing the code to Skyvern. This endpoint stores the code in database so that Skyvern can use it while running tasks/workflows. + * + * @param {Skyvern.TotpCodeCreate} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.sendTotpCode({ + * totp_identifier: "john.doe@example.com", + * content: "Hello, your verification code is 123456" + * }) + */ + public sendTotpCode( + request: Skyvern.TotpCodeCreate, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__sendTotpCode(request, requestOptions)); + } + + private async __sendTotpCode( + request: Skyvern.TotpCodeCreate, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/credentials/totp", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.TotpCode, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/credentials/totp."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retrieves a paginated list of credentials for the current organization + * + * @param {Skyvern.GetCredentialsRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getCredentials({ + * page: 1, + * page_size: 10 + * }) + */ + public getCredentials( + request: Skyvern.GetCredentialsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getCredentials(request, requestOptions)); + } + + private async __getCredentials( + request: Skyvern.GetCredentialsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { page, page_size: pageSize } = request; + const _queryParams: Record = {}; + if (page != null) { + _queryParams.page = page.toString(); + } + + if (pageSize != null) { + _queryParams.page_size = pageSize.toString(); + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/credentials", + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.CredentialResponse[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/credentials."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Creates a new credential for the current organization + * + * @param {Skyvern.CreateCredentialRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.createCredential({ + * name: "My Credential", + * credential_type: "password", + * credential: { + * password: "securepassword123", + * username: "user@example.com", + * totp: "JBSWY3DPEHPK3PXP" + * } + * }) + */ + public createCredential( + request: Skyvern.CreateCredentialRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__createCredential(request, requestOptions)); + } + + private async __createCredential( + request: Skyvern.CreateCredentialRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/credentials", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.CredentialResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/credentials."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Deletes a specific credential by its ID + * + * @param {string} credentialId - The unique identifier of the credential to delete + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.deleteCredential("cred_1234567890") + */ + public deleteCredential( + credentialId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__deleteCredential(credentialId, requestOptions)); + } + + private async __deleteCredential( + credentialId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/credentials/${core.url.encodePathParam(credentialId)}/delete`, + ), + method: "POST", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: undefined, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling POST /v1/credentials/{credential_id}/delete.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retrieves a specific credential by its ID + * + * @param {string} credentialId - The unique identifier of the credential + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getCredential("cred_1234567890") + */ + public getCredential( + credentialId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getCredential(credentialId, requestOptions)); + } + + private async __getCredential( + credentialId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/credentials/${core.url.encodePathParam(credentialId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.CredentialResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling GET /v1/credentials/{credential_id}.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Log in to a website using either credential stored in Skyvern, Bitwarden, 1Password, or Azure Vault + * + * @param {Skyvern.LoginRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.login({ + * credential_type: "skyvern" + * }) + */ + public login( + request: Skyvern.LoginRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__login(request, requestOptions)); + } + + private async __login( + request: Skyvern.LoginRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/run/tasks/login", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.WorkflowRunResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/run/tasks/login."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retrieves a paginated list of scripts for the current organization + * + * @param {Skyvern.GetScriptsRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getScripts({ + * page: 1, + * page_size: 10 + * }) + */ + public getScripts( + request: Skyvern.GetScriptsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getScripts(request, requestOptions)); + } + + private async __getScripts( + request: Skyvern.GetScriptsRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const { page, page_size: pageSize } = request; + const _queryParams: Record = {}; + if (page != null) { + _queryParams.page = page.toString(); + } + + if (pageSize != null) { + _queryParams.page_size = pageSize.toString(); + } + + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/scripts", + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Script[], rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/scripts."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Create a new script with optional files and metadata + * + * @param {Skyvern.CreateScriptRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.createScript() + */ + public createScript( + request: Skyvern.CreateScriptRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__createScript(request, requestOptions)); + } + + private async __createScript( + request: Skyvern.CreateScriptRequest = {}, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + "v1/scripts", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.CreateScriptResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/scripts."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retrieves a specific script by its ID + * + * @param {string} scriptId - The unique identifier of the script + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.getScript("s_abc123") + */ + public getScript( + scriptId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__getScript(scriptId, requestOptions)); + } + + private async __getScript( + scriptId: string, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/scripts/${core.url.encodePathParam(scriptId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.Script, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling GET /v1/scripts/{script_id}."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Deploy a script with updated files, creating a new version + * + * @param {string} scriptId - The unique identifier of the script + * @param {Skyvern.DeployScriptRequest} request + * @param {SkyvernClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.deployScript("s_abc123", { + * files: [{ + * path: "src/main.py", + * content: "content" + * }] + * }) + */ + public deployScript( + scriptId: string, + request: Skyvern.DeployScriptRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__deployScript(scriptId, request, requestOptions)); + } + + private async __deployScript( + scriptId: string, + request: Skyvern.DeployScriptRequest, + requestOptions?: SkyvernClient.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/scripts/${core.url.encodePathParam(scriptId)}/deploy`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Skyvern.CreateScriptResponse, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError( + "Timeout exceeded when calling POST /v1/scripts/{script_id}/deploy.", + ); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders(): Promise> { + const xApiKeyValue = await core.Supplier.get(this._options.xApiKey); + return { "x-api-key": xApiKeyValue }; + } +} diff --git a/skyvern-ts/client/src/api/client/index.ts b/skyvern-ts/client/src/api/client/index.ts new file mode 100644 index 00000000..195f9aa8 --- /dev/null +++ b/skyvern-ts/client/src/api/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/skyvern-ts/client/src/api/client/requests/CreateBrowserSessionRequest.ts b/skyvern-ts/client/src/api/client/requests/CreateBrowserSessionRequest.ts new file mode 100644 index 00000000..44fcaefa --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/CreateBrowserSessionRequest.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * {} + */ +export interface CreateBrowserSessionRequest { + /** Timeout in minutes for the session. Timeout is applied after the session is started. Must be between 5 and 1440. Defaults to 60. */ + timeout?: number; + /** + * Geographic Proxy location to route the browser traffic through. This is only available in Skyvern Cloud. + * + * Available geotargeting options: + * - RESIDENTIAL: the default value. Skyvern Cloud uses a random US residential proxy. + * - RESIDENTIAL_ES: Spain + * - RESIDENTIAL_IE: Ireland + * - RESIDENTIAL_GB: United Kingdom + * - RESIDENTIAL_IN: India + * - RESIDENTIAL_JP: Japan + * - RESIDENTIAL_FR: France + * - RESIDENTIAL_DE: Germany + * - RESIDENTIAL_NZ: New Zealand + * - RESIDENTIAL_ZA: South Africa + * - RESIDENTIAL_AR: Argentina + * - RESIDENTIAL_AU: Australia + * - RESIDENTIAL_ISP: ISP proxy + * - US-CA: California + * - US-NY: New York + * - US-TX: Texas + * - US-FL: Florida + * - US-WA: Washington + * - NONE: No proxy + */ + proxy_location?: Skyvern.ProxyLocation; +} diff --git a/skyvern-ts/client/src/api/client/requests/CreateCredentialRequest.ts b/skyvern-ts/client/src/api/client/requests/CreateCredentialRequest.ts new file mode 100644 index 00000000..8df2a356 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/CreateCredentialRequest.ts @@ -0,0 +1,31 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * { + * name: "My Credential", + * credential_type: "password", + * credential: { + * password: "securepassword123", + * username: "user@example.com", + * totp: "JBSWY3DPEHPK3PXP" + * } + * } + */ +export interface CreateCredentialRequest { + /** Name of the credential */ + name: string; + /** Type of credential to create */ + credential_type: Skyvern.SkyvernForgeSdkSchemasCredentialsCredentialType; + /** The credential data to store */ + credential: CreateCredentialRequest.Credential; +} + +export namespace CreateCredentialRequest { + /** + * The credential data to store + */ + export type Credential = Skyvern.NonEmptyPasswordCredential | Skyvern.NonEmptyCreditCardCredential; +} diff --git a/skyvern-ts/client/src/api/client/requests/CreateScriptRequest.ts b/skyvern-ts/client/src/api/client/requests/CreateScriptRequest.ts new file mode 100644 index 00000000..990e7843 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/CreateScriptRequest.ts @@ -0,0 +1,16 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * {} + */ +export interface CreateScriptRequest { + /** Associated workflow ID */ + workflow_id?: string; + /** Associated run ID */ + run_id?: string; + /** Array of files to include in the script */ + files?: Skyvern.ScriptFileCreate[]; +} diff --git a/skyvern-ts/client/src/api/client/requests/DeployScriptRequest.ts b/skyvern-ts/client/src/api/client/requests/DeployScriptRequest.ts new file mode 100644 index 00000000..2cf4b6f1 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/DeployScriptRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * { + * files: [{ + * path: "src/main.py", + * content: "content" + * }] + * } + */ +export interface DeployScriptRequest { + /** Array of files to include in the script */ + files: Skyvern.ScriptFileCreate[]; +} diff --git a/skyvern-ts/client/src/api/client/requests/GetCredentialsRequest.ts b/skyvern-ts/client/src/api/client/requests/GetCredentialsRequest.ts new file mode 100644 index 00000000..7cc9d10f --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/GetCredentialsRequest.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * page: 1, + * page_size: 10 + * } + */ +export interface GetCredentialsRequest { + /** Page number for pagination */ + page?: number; + /** Number of items per page */ + page_size?: number; +} diff --git a/skyvern-ts/client/src/api/client/requests/GetRunArtifactsRequest.ts b/skyvern-ts/client/src/api/client/requests/GetRunArtifactsRequest.ts new file mode 100644 index 00000000..15ca03b7 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/GetRunArtifactsRequest.ts @@ -0,0 +1,11 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * {} + */ +export interface GetRunArtifactsRequest { + artifact_type?: Skyvern.ArtifactType | Skyvern.ArtifactType[]; +} diff --git a/skyvern-ts/client/src/api/client/requests/GetScriptsRequest.ts b/skyvern-ts/client/src/api/client/requests/GetScriptsRequest.ts new file mode 100644 index 00000000..3dae7fdb --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/GetScriptsRequest.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * page: 1, + * page_size: 10 + * } + */ +export interface GetScriptsRequest { + /** Page number for pagination */ + page?: number; + /** Number of items per page */ + page_size?: number; +} diff --git a/skyvern-ts/client/src/api/client/requests/GetWorkflowsRequest.ts b/skyvern-ts/client/src/api/client/requests/GetWorkflowsRequest.ts new file mode 100644 index 00000000..42666a97 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/GetWorkflowsRequest.ts @@ -0,0 +1,25 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * page: 1, + * page_size: 1, + * only_saved_tasks: true, + * only_workflows: true, + * search_key: "search_key", + * title: "title", + * template: true + * } + */ +export interface GetWorkflowsRequest { + page?: number; + page_size?: number; + only_saved_tasks?: boolean; + only_workflows?: boolean; + /** Unified search across workflow title and parameter metadata (key, description, default_value). */ + search_key?: string; + /** Deprecated: use search_key instead. */ + title?: string; + template?: boolean; +} diff --git a/skyvern-ts/client/src/api/client/requests/LoginRequest.ts b/skyvern-ts/client/src/api/client/requests/LoginRequest.ts new file mode 100644 index 00000000..5f5ff48e --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/LoginRequest.ts @@ -0,0 +1,52 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * { + * credential_type: "skyvern" + * } + */ +export interface LoginRequest { + /** Where to get the credential from */ + credential_type: Skyvern.SkyvernSchemasRunBlocksCredentialType; + /** Website url */ + url?: string; + /** Login instructions. Skyvern has default prompt/instruction for login if this field is not provided. */ + prompt?: string; + /** Webhook URL to send login status updates */ + webhook_url?: string; + /** Proxy location to use */ + proxy_location?: Skyvern.ProxyLocation; + /** Identifier for TOTP (Time-based One-Time Password) if required */ + totp_identifier?: string; + /** TOTP URL to fetch one-time passwords */ + totp_url?: string; + /** ID of the browser session to use, which is prefixed by `pbs_` e.g. `pbs_123456` */ + browser_session_id?: string; + /** The CDP address for the task. */ + browser_address?: string; + /** Additional HTTP headers to include in requests */ + extra_http_headers?: Record; + /** Maximum number of times to scroll for screenshots */ + max_screenshot_scrolling_times?: number; + /** ID of the Skyvern credential to use for login. */ + credential_id?: string; + /** Bitwarden collection ID. You can find it in the Bitwarden collection URL. e.g. `https://vault.bitwarden.com/vaults/collection_id/items` */ + bitwarden_collection_id?: string; + /** Bitwarden item ID */ + bitwarden_item_id?: string; + /** 1Password vault ID */ + onepassword_vault_id?: string; + /** 1Password item ID */ + onepassword_item_id?: string; + /** Azure Vault Name */ + azure_vault_name?: string; + /** Azure Vault username key */ + azure_vault_username_key?: string; + /** Azure Vault password key */ + azure_vault_password_key?: string; + /** Azure Vault TOTP secret key */ + azure_vault_totp_secret_key?: string; +} diff --git a/skyvern-ts/client/src/api/client/requests/RunTaskRequest.ts b/skyvern-ts/client/src/api/client/requests/RunTaskRequest.ts new file mode 100644 index 00000000..21750ae3 --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/RunTaskRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * { + * "x-user-agent": "x-user-agent", + * body: { + * prompt: "Find the top 3 posts on Hacker News." + * } + * } + */ +export interface RunTaskRequest { + "x-user-agent"?: string; + body: Skyvern.TaskRunRequest; +} diff --git a/skyvern-ts/client/src/api/client/requests/RunWorkflowRequest.ts b/skyvern-ts/client/src/api/client/requests/RunWorkflowRequest.ts new file mode 100644 index 00000000..722d838b --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/RunWorkflowRequest.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../../index.js"; + +/** + * @example + * { + * "x-max-steps-override": 1, + * "x-user-agent": "x-user-agent", + * template: true, + * body: { + * workflow_id: "wpid_123" + * } + * } + */ +export interface RunWorkflowRequest { + template?: boolean; + "x-max-steps-override"?: number; + "x-user-agent"?: string; + body: Skyvern.WorkflowRunRequest; +} diff --git a/skyvern-ts/client/src/api/client/requests/TotpCodeCreate.ts b/skyvern-ts/client/src/api/client/requests/TotpCodeCreate.ts new file mode 100644 index 00000000..a0f18edb --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/TotpCodeCreate.ts @@ -0,0 +1,25 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * totp_identifier: "john.doe@example.com", + * content: "Hello, your verification code is 123456" + * } + */ +export interface TotpCodeCreate { + /** The identifier of the TOTP code. It can be the email address, phone number, or the identifier of the user. */ + totp_identifier: string; + /** The task_id the totp code is for. It can be the task_id of the task that the TOTP code is for. */ + task_id?: string; + /** The workflow ID the TOTP code is for. It can be the workflow ID of the workflow that the TOTP code is for. */ + workflow_id?: string; + /** The workflow run id that the TOTP code is for. It can be the workflow run id of the workflow run that the TOTP code is for. */ + workflow_run_id?: string; + /** An optional field. The source of the TOTP code. e.g. email, sms, etc. */ + source?: string; + /** The content of the TOTP code. It can be the email content that contains the TOTP code, or the sms message that contains the TOTP code. Skyvern will automatically extract the TOTP code from the content. */ + content: string; + /** The timestamp when the TOTP code expires */ + expired_at?: string; +} diff --git a/skyvern-ts/client/src/api/client/requests/index.ts b/skyvern-ts/client/src/api/client/requests/index.ts new file mode 100644 index 00000000..aca2642c --- /dev/null +++ b/skyvern-ts/client/src/api/client/requests/index.ts @@ -0,0 +1,12 @@ +export type { CreateBrowserSessionRequest } from "./CreateBrowserSessionRequest.js"; +export type { CreateCredentialRequest } from "./CreateCredentialRequest.js"; +export type { CreateScriptRequest } from "./CreateScriptRequest.js"; +export type { DeployScriptRequest } from "./DeployScriptRequest.js"; +export type { GetCredentialsRequest } from "./GetCredentialsRequest.js"; +export type { GetRunArtifactsRequest } from "./GetRunArtifactsRequest.js"; +export type { GetScriptsRequest } from "./GetScriptsRequest.js"; +export type { GetWorkflowsRequest } from "./GetWorkflowsRequest.js"; +export type { LoginRequest } from "./LoginRequest.js"; +export type { RunTaskRequest } from "./RunTaskRequest.js"; +export type { RunWorkflowRequest } from "./RunWorkflowRequest.js"; +export type { TotpCodeCreate } from "./TotpCodeCreate.js"; diff --git a/skyvern-ts/client/src/api/errors/BadRequestError.ts b/skyvern-ts/client/src/api/errors/BadRequestError.ts new file mode 100644 index 00000000..6d8bf160 --- /dev/null +++ b/skyvern-ts/client/src/api/errors/BadRequestError.ts @@ -0,0 +1,16 @@ +// 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"; + +export class BadRequestError extends errors.SkyvernError { + constructor(body?: unknown, rawResponse?: core.RawResponse) { + super({ + message: "BadRequestError", + statusCode: 400, + body: body, + rawResponse: rawResponse, + }); + Object.setPrototypeOf(this, BadRequestError.prototype); + } +} diff --git a/skyvern-ts/client/src/api/errors/ForbiddenError.ts b/skyvern-ts/client/src/api/errors/ForbiddenError.ts new file mode 100644 index 00000000..fa4fb7c1 --- /dev/null +++ b/skyvern-ts/client/src/api/errors/ForbiddenError.ts @@ -0,0 +1,16 @@ +// 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"; + +export class ForbiddenError extends errors.SkyvernError { + constructor(body?: unknown, rawResponse?: core.RawResponse) { + super({ + message: "ForbiddenError", + statusCode: 403, + body: body, + rawResponse: rawResponse, + }); + Object.setPrototypeOf(this, ForbiddenError.prototype); + } +} diff --git a/skyvern-ts/client/src/api/errors/NotFoundError.ts b/skyvern-ts/client/src/api/errors/NotFoundError.ts new file mode 100644 index 00000000..c7102612 --- /dev/null +++ b/skyvern-ts/client/src/api/errors/NotFoundError.ts @@ -0,0 +1,16 @@ +// 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"; + +export class NotFoundError extends errors.SkyvernError { + constructor(body?: unknown, rawResponse?: core.RawResponse) { + super({ + message: "NotFoundError", + statusCode: 404, + body: body, + rawResponse: rawResponse, + }); + Object.setPrototypeOf(this, NotFoundError.prototype); + } +} diff --git a/skyvern-ts/client/src/api/errors/UnprocessableEntityError.ts b/skyvern-ts/client/src/api/errors/UnprocessableEntityError.ts new file mode 100644 index 00000000..3fc7eda5 --- /dev/null +++ b/skyvern-ts/client/src/api/errors/UnprocessableEntityError.ts @@ -0,0 +1,16 @@ +// 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"; + +export class UnprocessableEntityError extends errors.SkyvernError { + constructor(body?: unknown, rawResponse?: core.RawResponse) { + super({ + message: "UnprocessableEntityError", + statusCode: 422, + body: body, + rawResponse: rawResponse, + }); + Object.setPrototypeOf(this, UnprocessableEntityError.prototype); + } +} diff --git a/skyvern-ts/client/src/api/errors/index.ts b/skyvern-ts/client/src/api/errors/index.ts new file mode 100644 index 00000000..cfbcfd0f --- /dev/null +++ b/skyvern-ts/client/src/api/errors/index.ts @@ -0,0 +1,4 @@ +export * from "./BadRequestError.js"; +export * from "./ForbiddenError.js"; +export * from "./NotFoundError.js"; +export * from "./UnprocessableEntityError.js"; diff --git a/skyvern-ts/client/src/api/index.ts b/skyvern-ts/client/src/api/index.ts new file mode 100644 index 00000000..d73889d8 --- /dev/null +++ b/skyvern-ts/client/src/api/index.ts @@ -0,0 +1,4 @@ +export * from "./client/index.js"; +export * from "./errors/index.js"; +export * from "./resources/index.js"; +export * from "./types/index.js"; diff --git a/skyvern-ts/client/src/api/resources/index.ts b/skyvern-ts/client/src/api/resources/index.ts new file mode 100644 index 00000000..7c69f0c4 --- /dev/null +++ b/skyvern-ts/client/src/api/resources/index.ts @@ -0,0 +1 @@ +export * as scripts from "./scripts/index.js"; diff --git a/skyvern-ts/client/src/api/resources/scripts/client/Client.ts b/skyvern-ts/client/src/api/resources/scripts/client/Client.ts new file mode 100644 index 00000000..0e73ebe6 --- /dev/null +++ b/skyvern-ts/client/src/api/resources/scripts/client/Client.ts @@ -0,0 +1,102 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; +import * as core from "../../../../core/index.js"; +import * as environments from "../../../../environments.js"; +import * as errors from "../../../../errors/index.js"; +import * as Skyvern from "../../../index.js"; + +export declare namespace Scripts { + export interface Options extends BaseClientOptions {} + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class Scripts { + protected readonly _options: Scripts.Options; + + constructor(_options: Scripts.Options = {}) { + this._options = _options; + } + + /** + * Run a script + * + * @param {string} scriptId - The unique identifier of the script + * @param {Scripts.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Skyvern.UnprocessableEntityError} + * + * @example + * await client.scripts.runScript("s_abc123") + */ + public runScript(scriptId: string, requestOptions?: Scripts.RequestOptions): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__runScript(scriptId, requestOptions)); + } + + private async __runScript( + scriptId: string, + requestOptions?: Scripts.RequestOptions, + ): Promise> { + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ + "x-api-key": requestOptions?.apiKey ?? this._options?.apiKey, + ...(await this._getCustomAuthorizationHeaders()), + }), + 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)) ?? + environments.SkyvernEnvironment.Production, + `v1/scripts/${core.url.encodePathParam(scriptId)}/run`, + ), + method: "POST", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 422: + throw new Skyvern.UnprocessableEntityError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.SkyvernError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.SkyvernTimeoutError("Timeout exceeded when calling POST /v1/scripts/{script_id}/run."); + case "unknown": + throw new errors.SkyvernError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders(): Promise> { + const xApiKeyValue = await core.Supplier.get(this._options.xApiKey); + return { "x-api-key": xApiKeyValue }; + } +} diff --git a/skyvern-ts/client/src/api/resources/scripts/client/index.ts b/skyvern-ts/client/src/api/resources/scripts/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/skyvern-ts/client/src/api/resources/scripts/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/skyvern-ts/client/src/api/resources/scripts/index.ts b/skyvern-ts/client/src/api/resources/scripts/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/skyvern-ts/client/src/api/resources/scripts/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/skyvern-ts/client/src/api/types/Action.ts b/skyvern-ts/client/src/api/types/Action.ts new file mode 100644 index 00000000..bb8099a2 --- /dev/null +++ b/skyvern-ts/client/src/api/types/Action.ts @@ -0,0 +1,41 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface Action { + action_type: Skyvern.ActionType; + status?: Skyvern.ActionStatus; + action_id?: string; + source_action_id?: string; + organization_id?: string; + workflow_run_id?: string; + task_id?: string; + step_id?: string; + step_order?: number; + action_order?: number; + confidence_float?: number; + description?: string; + reasoning?: string; + intention?: string; + response?: string; + element_id?: string; + skyvern_element_hash?: string; + skyvern_element_data?: Record; + tool_call_id?: string; + xpath?: string; + errors?: Skyvern.UserDefinedError[]; + data_extraction_goal?: string; + file_name?: string; + file_url?: string; + download?: boolean; + is_upload_file_tag?: boolean; + text?: string; + input_or_select_context?: Skyvern.InputOrSelectContext; + option?: Skyvern.SelectOption; + is_checked?: boolean; + verified?: boolean; + totp_timing_info?: Record; + created_at?: string; + modified_at?: string; + created_by?: string; +} diff --git a/skyvern-ts/client/src/api/types/ActionBlock.ts b/skyvern-ts/client/src/api/types/ActionBlock.ts new file mode 100644 index 00000000..c3c6b5b2 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ActionBlock.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface ActionBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + task_type?: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + complete_criterion?: string; + terminate_criterion?: string; + navigation_goal?: string; + data_extraction_goal?: string; + data_schema?: ActionBlock.DataSchema; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameters?: Skyvern.ActionBlockParametersItem[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; + download_timeout?: number; +} + +export namespace ActionBlock { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/ActionBlockParametersItem.ts b/skyvern-ts/client/src/api/types/ActionBlockParametersItem.ts new file mode 100644 index 00000000..3b8c4ca6 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ActionBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type ActionBlockParametersItem = + | Skyvern.ActionBlockParametersItem.AwsSecret + | Skyvern.ActionBlockParametersItem.AzureSecret + | Skyvern.ActionBlockParametersItem.AzureVaultCredential + | Skyvern.ActionBlockParametersItem.BitwardenCreditCardData + | Skyvern.ActionBlockParametersItem.BitwardenLoginCredential + | Skyvern.ActionBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.ActionBlockParametersItem.Context + | Skyvern.ActionBlockParametersItem.Credential + | Skyvern.ActionBlockParametersItem.Onepassword + | Skyvern.ActionBlockParametersItem.Output + | Skyvern.ActionBlockParametersItem.Workflow; + +export namespace ActionBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/ActionBlockYaml.ts b/skyvern-ts/client/src/api/types/ActionBlockYaml.ts new file mode 100644 index 00000000..1ffb4ab1 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ActionBlockYaml.ts @@ -0,0 +1,22 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface ActionBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + navigation_goal?: string; + error_code_mapping?: Record; + max_retries?: number; + parameter_keys?: string[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + disable_cache?: boolean; +} diff --git a/skyvern-ts/client/src/api/types/ActionStatus.ts b/skyvern-ts/client/src/api/types/ActionStatus.ts new file mode 100644 index 00000000..16bfe21f --- /dev/null +++ b/skyvern-ts/client/src/api/types/ActionStatus.ts @@ -0,0 +1,9 @@ +// This file was auto-generated by Fern from our API Definition. + +export const ActionStatus = { + Pending: "pending", + Skipped: "skipped", + Failed: "failed", + Completed: "completed", +} as const; +export type ActionStatus = (typeof ActionStatus)[keyof typeof ActionStatus]; diff --git a/skyvern-ts/client/src/api/types/ActionType.ts b/skyvern-ts/client/src/api/types/ActionType.ts new file mode 100644 index 00000000..9861555d --- /dev/null +++ b/skyvern-ts/client/src/api/types/ActionType.ts @@ -0,0 +1,25 @@ +// This file was auto-generated by Fern from our API Definition. + +export const ActionType = { + Click: "click", + InputText: "input_text", + UploadFile: "upload_file", + DownloadFile: "download_file", + SelectOption: "select_option", + Checkbox: "checkbox", + Wait: "wait", + NullAction: "null_action", + SolveCaptcha: "solve_captcha", + Terminate: "terminate", + Complete: "complete", + ReloadPage: "reload_page", + Extract: "extract", + VerificationCode: "verification_code", + GotoUrl: "goto_url", + Scroll: "scroll", + Keypress: "keypress", + Move: "move", + Drag: "drag", + LeftMouse: "left_mouse", +} as const; +export type ActionType = (typeof ActionType)[keyof typeof ActionType]; diff --git a/skyvern-ts/client/src/api/types/Artifact.ts b/skyvern-ts/client/src/api/types/Artifact.ts new file mode 100644 index 00000000..6cf39b77 --- /dev/null +++ b/skyvern-ts/client/src/api/types/Artifact.ts @@ -0,0 +1,22 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface Artifact { + /** The creation datetime of the task. */ + created_at: string; + /** The modification datetime of the task. */ + modified_at: string; + artifact_id: string; + artifact_type: Skyvern.ArtifactType; + uri: string; + task_id?: string; + step_id?: string; + workflow_run_id?: string; + workflow_run_block_id?: string; + observer_cruise_id?: string; + observer_thought_id?: string; + ai_suggestion_id?: string; + signed_url?: string; + organization_id: string; +} diff --git a/skyvern-ts/client/src/api/types/ArtifactType.ts b/skyvern-ts/client/src/api/types/ArtifactType.ts new file mode 100644 index 00000000..60d70d14 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ArtifactType.ts @@ -0,0 +1,31 @@ +// This file was auto-generated by Fern from our API Definition. + +export const ArtifactType = { + Recording: "recording", + BrowserConsoleLog: "browser_console_log", + SkyvernLog: "skyvern_log", + SkyvernLogRaw: "skyvern_log_raw", + Screenshot: "screenshot", + ScreenshotLlm: "screenshot_llm", + ScreenshotAction: "screenshot_action", + ScreenshotFinal: "screenshot_final", + LlmPrompt: "llm_prompt", + LlmRequest: "llm_request", + LlmResponse: "llm_response", + LlmResponseParsed: "llm_response_parsed", + LlmResponseRendered: "llm_response_rendered", + VisibleElementsIdCssMap: "visible_elements_id_css_map", + VisibleElementsIdFrameMap: "visible_elements_id_frame_map", + VisibleElementsTree: "visible_elements_tree", + VisibleElementsTreeTrimmed: "visible_elements_tree_trimmed", + VisibleElementsTreeInPrompt: "visible_elements_tree_in_prompt", + HashedHrefMap: "hashed_href_map", + VisibleElementsIdXpathMap: "visible_elements_id_xpath_map", + Html: "html", + HtmlScrape: "html_scrape", + HtmlAction: "html_action", + Trace: "trace", + Har: "har", + ScriptFile: "script_file", +} as const; +export type ArtifactType = (typeof ArtifactType)[keyof typeof ArtifactType]; diff --git a/skyvern-ts/client/src/api/types/AwsSecretParameter.ts b/skyvern-ts/client/src/api/types/AwsSecretParameter.ts new file mode 100644 index 00000000..bdf20de7 --- /dev/null +++ b/skyvern-ts/client/src/api/types/AwsSecretParameter.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface AwsSecretParameter { + key: string; + description?: string; + aws_secret_parameter_id: string; + workflow_id: string; + aws_key: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/AwsSecretParameterYaml.ts b/skyvern-ts/client/src/api/types/AwsSecretParameterYaml.ts new file mode 100644 index 00000000..d0ebd78d --- /dev/null +++ b/skyvern-ts/client/src/api/types/AwsSecretParameterYaml.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface AwsSecretParameterYaml { + key: string; + description?: string; + aws_key: string; +} diff --git a/skyvern-ts/client/src/api/types/AzureSecretParameter.ts b/skyvern-ts/client/src/api/types/AzureSecretParameter.ts new file mode 100644 index 00000000..19dc33b2 --- /dev/null +++ b/skyvern-ts/client/src/api/types/AzureSecretParameter.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface AzureSecretParameter { + key: string; + description?: string; + azure_secret_parameter_id: string; + workflow_id: string; + azure_key: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/AzureVaultCredentialParameter.ts b/skyvern-ts/client/src/api/types/AzureVaultCredentialParameter.ts new file mode 100644 index 00000000..2ab24cbd --- /dev/null +++ b/skyvern-ts/client/src/api/types/AzureVaultCredentialParameter.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface AzureVaultCredentialParameter { + key: string; + description?: string; + azure_vault_credential_parameter_id: string; + workflow_id: string; + vault_name: string; + username_key: string; + password_key: string; + totp_secret_key?: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/AzureVaultCredentialParameterYaml.ts b/skyvern-ts/client/src/api/types/AzureVaultCredentialParameterYaml.ts new file mode 100644 index 00000000..baf5793a --- /dev/null +++ b/skyvern-ts/client/src/api/types/AzureVaultCredentialParameterYaml.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface AzureVaultCredentialParameterYaml { + key: string; + description?: string; + vault_name: string; + username_key: string; + password_key: string; + totp_secret_key?: string; +} diff --git a/skyvern-ts/client/src/api/types/BitwardenCreditCardDataParameter.ts b/skyvern-ts/client/src/api/types/BitwardenCreditCardDataParameter.ts new file mode 100644 index 00000000..2283c620 --- /dev/null +++ b/skyvern-ts/client/src/api/types/BitwardenCreditCardDataParameter.ts @@ -0,0 +1,16 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface BitwardenCreditCardDataParameter { + key: string; + description?: string; + bitwarden_credit_card_data_parameter_id: string; + workflow_id: string; + bitwarden_client_id_aws_secret_key: string; + bitwarden_client_secret_aws_secret_key: string; + bitwarden_master_password_aws_secret_key: string; + bitwarden_collection_id: string; + bitwarden_item_id: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/BitwardenCreditCardDataParameterYaml.ts b/skyvern-ts/client/src/api/types/BitwardenCreditCardDataParameterYaml.ts new file mode 100644 index 00000000..ba2ea05b --- /dev/null +++ b/skyvern-ts/client/src/api/types/BitwardenCreditCardDataParameterYaml.ts @@ -0,0 +1,11 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface BitwardenCreditCardDataParameterYaml { + key: string; + description?: string; + bitwarden_client_id_aws_secret_key: string; + bitwarden_client_secret_aws_secret_key: string; + bitwarden_master_password_aws_secret_key: string; + bitwarden_collection_id: string; + bitwarden_item_id: string; +} diff --git a/skyvern-ts/client/src/api/types/BitwardenLoginCredentialParameter.ts b/skyvern-ts/client/src/api/types/BitwardenLoginCredentialParameter.ts new file mode 100644 index 00000000..04b7da35 --- /dev/null +++ b/skyvern-ts/client/src/api/types/BitwardenLoginCredentialParameter.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface BitwardenLoginCredentialParameter { + key: string; + description?: string; + bitwarden_login_credential_parameter_id: string; + workflow_id: string; + bitwarden_client_id_aws_secret_key: string; + bitwarden_client_secret_aws_secret_key: string; + bitwarden_master_password_aws_secret_key: string; + url_parameter_key?: string; + bitwarden_collection_id?: string; + bitwarden_item_id?: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/BitwardenLoginCredentialParameterYaml.ts b/skyvern-ts/client/src/api/types/BitwardenLoginCredentialParameterYaml.ts new file mode 100644 index 00000000..c82f9810 --- /dev/null +++ b/skyvern-ts/client/src/api/types/BitwardenLoginCredentialParameterYaml.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface BitwardenLoginCredentialParameterYaml { + key: string; + description?: string; + bitwarden_client_id_aws_secret_key: string; + bitwarden_client_secret_aws_secret_key: string; + bitwarden_master_password_aws_secret_key: string; + url_parameter_key?: string; + bitwarden_collection_id?: string; + bitwarden_item_id?: string; +} diff --git a/skyvern-ts/client/src/api/types/BitwardenSensitiveInformationParameter.ts b/skyvern-ts/client/src/api/types/BitwardenSensitiveInformationParameter.ts new file mode 100644 index 00000000..69d1ed26 --- /dev/null +++ b/skyvern-ts/client/src/api/types/BitwardenSensitiveInformationParameter.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface BitwardenSensitiveInformationParameter { + key: string; + description?: string; + bitwarden_sensitive_information_parameter_id: string; + workflow_id: string; + bitwarden_client_id_aws_secret_key: string; + bitwarden_client_secret_aws_secret_key: string; + bitwarden_master_password_aws_secret_key: string; + bitwarden_collection_id: string; + bitwarden_identity_key: string; + bitwarden_identity_fields: string[]; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/BitwardenSensitiveInformationParameterYaml.ts b/skyvern-ts/client/src/api/types/BitwardenSensitiveInformationParameterYaml.ts new file mode 100644 index 00000000..e8b5f92b --- /dev/null +++ b/skyvern-ts/client/src/api/types/BitwardenSensitiveInformationParameterYaml.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface BitwardenSensitiveInformationParameterYaml { + key: string; + description?: string; + bitwarden_client_id_aws_secret_key: string; + bitwarden_client_secret_aws_secret_key: string; + bitwarden_master_password_aws_secret_key: string; + bitwarden_collection_id: string; + bitwarden_identity_key: string; + bitwarden_identity_fields: string[]; +} diff --git a/skyvern-ts/client/src/api/types/BlockType.ts b/skyvern-ts/client/src/api/types/BlockType.ts new file mode 100644 index 00000000..0c4c658b --- /dev/null +++ b/skyvern-ts/client/src/api/types/BlockType.ts @@ -0,0 +1,25 @@ +// This file was auto-generated by Fern from our API Definition. + +export const BlockType = { + Task: "task", + TaskV2: "task_v2", + ForLoop: "for_loop", + Code: "code", + TextPrompt: "text_prompt", + DownloadToS3: "download_to_s3", + UploadToS3: "upload_to_s3", + FileUpload: "file_upload", + SendEmail: "send_email", + FileUrlParser: "file_url_parser", + Validation: "validation", + Action: "action", + Navigation: "navigation", + Extraction: "extraction", + Login: "login", + Wait: "wait", + FileDownload: "file_download", + GotoUrl: "goto_url", + PdfParser: "pdf_parser", + HttpRequest: "http_request", +} as const; +export type BlockType = (typeof BlockType)[keyof typeof BlockType]; diff --git a/skyvern-ts/client/src/api/types/BrowserSessionResponse.ts b/skyvern-ts/client/src/api/types/BrowserSessionResponse.ts new file mode 100644 index 00000000..5a57293f --- /dev/null +++ b/skyvern-ts/client/src/api/types/BrowserSessionResponse.ts @@ -0,0 +1,41 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +/** + * Response model for browser session information. + */ +export interface BrowserSessionResponse { + /** Unique identifier for the browser session. browser_session_id starts with `pbs_`. */ + browser_session_id: string; + /** ID of the organization that owns this session */ + organization_id: string; + /** Type of the current runnable associated with this session (workflow, task etc) */ + runnable_type?: string; + /** ID of the current runnable */ + runnable_id?: string; + /** Timeout in minutes for the session. Timeout is applied after the session is started. Defaults to 60 minutes. */ + timeout?: number; + /** Url for connecting to the browser */ + browser_address?: string; + /** Url for the browser session page */ + app_url?: string; + /** Whether the browser session supports VNC streaming */ + vnc_streaming_supported?: boolean; + /** The path where the browser session downloads files */ + download_path?: string; + /** The list of files downloaded by the browser session */ + downloaded_files?: Skyvern.FileInfo[]; + /** The list of video recordings from the browser session */ + recordings?: Skyvern.FileInfo[]; + /** Timestamp when the session was started */ + started_at?: string; + /** Timestamp when the session was completed */ + completed_at?: string; + /** Timestamp when the session was created (the timestamp for the initial request) */ + created_at: string; + /** Timestamp when the session was last modified */ + modified_at: string; + /** Timestamp when the session was deleted, if applicable */ + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/CodeBlock.ts b/skyvern-ts/client/src/api/types/CodeBlock.ts new file mode 100644 index 00000000..569cfb12 --- /dev/null +++ b/skyvern-ts/client/src/api/types/CodeBlock.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface CodeBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + code: string; + parameters?: Skyvern.CodeBlockParametersItem[]; +} diff --git a/skyvern-ts/client/src/api/types/CodeBlockParametersItem.ts b/skyvern-ts/client/src/api/types/CodeBlockParametersItem.ts new file mode 100644 index 00000000..00ce0dde --- /dev/null +++ b/skyvern-ts/client/src/api/types/CodeBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type CodeBlockParametersItem = + | Skyvern.CodeBlockParametersItem.AwsSecret + | Skyvern.CodeBlockParametersItem.AzureSecret + | Skyvern.CodeBlockParametersItem.AzureVaultCredential + | Skyvern.CodeBlockParametersItem.BitwardenCreditCardData + | Skyvern.CodeBlockParametersItem.BitwardenLoginCredential + | Skyvern.CodeBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.CodeBlockParametersItem.Context + | Skyvern.CodeBlockParametersItem.Credential + | Skyvern.CodeBlockParametersItem.Onepassword + | Skyvern.CodeBlockParametersItem.Output + | Skyvern.CodeBlockParametersItem.Workflow; + +export namespace CodeBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/CodeBlockYaml.ts b/skyvern-ts/client/src/api/types/CodeBlockYaml.ts new file mode 100644 index 00000000..9e699bb2 --- /dev/null +++ b/skyvern-ts/client/src/api/types/CodeBlockYaml.ts @@ -0,0 +1,9 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface CodeBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + code: string; + parameter_keys?: string[]; +} diff --git a/skyvern-ts/client/src/api/types/ContextParameter.ts b/skyvern-ts/client/src/api/types/ContextParameter.ts new file mode 100644 index 00000000..54c6cacc --- /dev/null +++ b/skyvern-ts/client/src/api/types/ContextParameter.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface ContextParameter { + key: string; + description?: string; + source: Skyvern.ContextParameterSource; + value?: ContextParameter.Value; +} + +export namespace ContextParameter { + export type Value = string | number | number | boolean | Record | unknown[]; +} diff --git a/skyvern-ts/client/src/api/types/ContextParameterSource.ts b/skyvern-ts/client/src/api/types/ContextParameterSource.ts new file mode 100644 index 00000000..4ff60468 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ContextParameterSource.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type ContextParameterSource = + | Skyvern.ContextParameterSource.Workflow + | Skyvern.ContextParameterSource.Context + | Skyvern.ContextParameterSource.AwsSecret + | Skyvern.ContextParameterSource.AzureSecret + | Skyvern.ContextParameterSource.BitwardenLoginCredential + | Skyvern.ContextParameterSource.BitwardenSensitiveInformation + | Skyvern.ContextParameterSource.BitwardenCreditCardData + | Skyvern.ContextParameterSource.Onepassword + | Skyvern.ContextParameterSource.AzureVaultCredential + | Skyvern.ContextParameterSource.Output + | Skyvern.ContextParameterSource.Credential; + +export namespace ContextParameterSource { + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } +} diff --git a/skyvern-ts/client/src/api/types/ContextParameterYaml.ts b/skyvern-ts/client/src/api/types/ContextParameterYaml.ts new file mode 100644 index 00000000..fb8fc69a --- /dev/null +++ b/skyvern-ts/client/src/api/types/ContextParameterYaml.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface ContextParameterYaml { + key: string; + description?: string; + source_parameter_key: string; +} diff --git a/skyvern-ts/client/src/api/types/CreateScriptResponse.ts b/skyvern-ts/client/src/api/types/CreateScriptResponse.ts new file mode 100644 index 00000000..64d1af36 --- /dev/null +++ b/skyvern-ts/client/src/api/types/CreateScriptResponse.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface CreateScriptResponse { + /** Unique script identifier */ + script_id: string; + /** Script version number */ + version: number; + /** ID of the workflow run or task run that generated this script */ + run_id?: string; + /** Total number of files in the script */ + file_count: number; + /** Hierarchical file tree structure */ + file_tree: Record; + /** Timestamp when the script was created */ + created_at: string; +} diff --git a/skyvern-ts/client/src/api/types/CredentialParameter.ts b/skyvern-ts/client/src/api/types/CredentialParameter.ts new file mode 100644 index 00000000..48d66e41 --- /dev/null +++ b/skyvern-ts/client/src/api/types/CredentialParameter.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface CredentialParameter { + key: string; + description?: string; + credential_parameter_id: string; + workflow_id: string; + credential_id: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/CredentialParameterYaml.ts b/skyvern-ts/client/src/api/types/CredentialParameterYaml.ts new file mode 100644 index 00000000..b7087e0d --- /dev/null +++ b/skyvern-ts/client/src/api/types/CredentialParameterYaml.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface CredentialParameterYaml { + key: string; + description?: string; + credential_id: string; +} diff --git a/skyvern-ts/client/src/api/types/CredentialResponse.ts b/skyvern-ts/client/src/api/types/CredentialResponse.ts new file mode 100644 index 00000000..d31e48eb --- /dev/null +++ b/skyvern-ts/client/src/api/types/CredentialResponse.ts @@ -0,0 +1,24 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +/** + * Response model for credential operations. + */ +export interface CredentialResponse { + /** Unique identifier for the credential */ + credential_id: string; + /** The credential data */ + credential: CredentialResponse.Credential; + /** Type of the credential */ + credential_type: Skyvern.CredentialTypeOutput; + /** Name of the credential */ + name: string; +} + +export namespace CredentialResponse { + /** + * The credential data + */ + export type Credential = Skyvern.PasswordCredentialResponse | Skyvern.CreditCardCredentialResponse; +} diff --git a/skyvern-ts/client/src/api/types/CredentialTypeOutput.ts b/skyvern-ts/client/src/api/types/CredentialTypeOutput.ts new file mode 100644 index 00000000..b2abba79 --- /dev/null +++ b/skyvern-ts/client/src/api/types/CredentialTypeOutput.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +/** Type of credential stored in the system. */ +export const CredentialTypeOutput = { + Password: "password", + CreditCard: "credit_card", +} as const; +export type CredentialTypeOutput = (typeof CredentialTypeOutput)[keyof typeof CredentialTypeOutput]; diff --git a/skyvern-ts/client/src/api/types/CreditCardCredentialResponse.ts b/skyvern-ts/client/src/api/types/CreditCardCredentialResponse.ts new file mode 100644 index 00000000..300a228f --- /dev/null +++ b/skyvern-ts/client/src/api/types/CreditCardCredentialResponse.ts @@ -0,0 +1,11 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * Response model for credit card credentials, containing only the last four digits and brand. + */ +export interface CreditCardCredentialResponse { + /** Last four digits of the credit card number */ + last_four: string; + /** Brand of the credit card */ + brand: string; +} diff --git a/skyvern-ts/client/src/api/types/DownloadToS3Block.ts b/skyvern-ts/client/src/api/types/DownloadToS3Block.ts new file mode 100644 index 00000000..8760b67f --- /dev/null +++ b/skyvern-ts/client/src/api/types/DownloadToS3Block.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface DownloadToS3Block { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + url: string; +} diff --git a/skyvern-ts/client/src/api/types/DownloadToS3BlockYaml.ts b/skyvern-ts/client/src/api/types/DownloadToS3BlockYaml.ts new file mode 100644 index 00000000..a2375c32 --- /dev/null +++ b/skyvern-ts/client/src/api/types/DownloadToS3BlockYaml.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DownloadToS3BlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + url: string; +} diff --git a/skyvern-ts/client/src/api/types/ExtractionBlock.ts b/skyvern-ts/client/src/api/types/ExtractionBlock.ts new file mode 100644 index 00000000..ec22ae88 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ExtractionBlock.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface ExtractionBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + task_type?: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + complete_criterion?: string; + terminate_criterion?: string; + navigation_goal?: string; + data_extraction_goal: string; + data_schema?: ExtractionBlock.DataSchema; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameters?: Skyvern.ExtractionBlockParametersItem[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; + download_timeout?: number; +} + +export namespace ExtractionBlock { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/ExtractionBlockParametersItem.ts b/skyvern-ts/client/src/api/types/ExtractionBlockParametersItem.ts new file mode 100644 index 00000000..2cbee11b --- /dev/null +++ b/skyvern-ts/client/src/api/types/ExtractionBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type ExtractionBlockParametersItem = + | Skyvern.ExtractionBlockParametersItem.AwsSecret + | Skyvern.ExtractionBlockParametersItem.AzureSecret + | Skyvern.ExtractionBlockParametersItem.AzureVaultCredential + | Skyvern.ExtractionBlockParametersItem.BitwardenCreditCardData + | Skyvern.ExtractionBlockParametersItem.BitwardenLoginCredential + | Skyvern.ExtractionBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.ExtractionBlockParametersItem.Context + | Skyvern.ExtractionBlockParametersItem.Credential + | Skyvern.ExtractionBlockParametersItem.Onepassword + | Skyvern.ExtractionBlockParametersItem.Output + | Skyvern.ExtractionBlockParametersItem.Workflow; + +export namespace ExtractionBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/ExtractionBlockYaml.ts b/skyvern-ts/client/src/api/types/ExtractionBlockYaml.ts new file mode 100644 index 00000000..39978da5 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ExtractionBlockYaml.ts @@ -0,0 +1,23 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface ExtractionBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + data_extraction_goal: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + data_schema?: ExtractionBlockYaml.DataSchema; + max_retries?: number; + max_steps_per_run?: number; + parameter_keys?: string[]; + cache_actions?: boolean; + disable_cache?: boolean; +} + +export namespace ExtractionBlockYaml { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/FileDownloadBlock.ts b/skyvern-ts/client/src/api/types/FileDownloadBlock.ts new file mode 100644 index 00000000..56f05692 --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileDownloadBlock.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface FileDownloadBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + task_type?: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + complete_criterion?: string; + terminate_criterion?: string; + navigation_goal?: string; + data_extraction_goal?: string; + data_schema?: FileDownloadBlock.DataSchema; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameters?: Skyvern.FileDownloadBlockParametersItem[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; + download_timeout?: number; +} + +export namespace FileDownloadBlock { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/FileDownloadBlockParametersItem.ts b/skyvern-ts/client/src/api/types/FileDownloadBlockParametersItem.ts new file mode 100644 index 00000000..0bf287ca --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileDownloadBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type FileDownloadBlockParametersItem = + | Skyvern.FileDownloadBlockParametersItem.AwsSecret + | Skyvern.FileDownloadBlockParametersItem.AzureSecret + | Skyvern.FileDownloadBlockParametersItem.AzureVaultCredential + | Skyvern.FileDownloadBlockParametersItem.BitwardenCreditCardData + | Skyvern.FileDownloadBlockParametersItem.BitwardenLoginCredential + | Skyvern.FileDownloadBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.FileDownloadBlockParametersItem.Context + | Skyvern.FileDownloadBlockParametersItem.Credential + | Skyvern.FileDownloadBlockParametersItem.Onepassword + | Skyvern.FileDownloadBlockParametersItem.Output + | Skyvern.FileDownloadBlockParametersItem.Workflow; + +export namespace FileDownloadBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/FileDownloadBlockYaml.ts b/skyvern-ts/client/src/api/types/FileDownloadBlockYaml.ts new file mode 100644 index 00000000..f373d141 --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileDownloadBlockYaml.ts @@ -0,0 +1,23 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface FileDownloadBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + navigation_goal: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameter_keys?: string[]; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + disable_cache?: boolean; + download_timeout?: number; +} diff --git a/skyvern-ts/client/src/api/types/FileEncoding.ts b/skyvern-ts/client/src/api/types/FileEncoding.ts new file mode 100644 index 00000000..f573d49c --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileEncoding.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +/** Supported file content encodings. */ +export const FileEncoding = { + Base64: "base64", + Utf8: "utf-8", +} as const; +export type FileEncoding = (typeof FileEncoding)[keyof typeof FileEncoding]; diff --git a/skyvern-ts/client/src/api/types/FileInfo.ts b/skyvern-ts/client/src/api/types/FileInfo.ts new file mode 100644 index 00000000..64260946 --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileInfo.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * Information about a downloaded file, including URL and checksum. + */ +export interface FileInfo { + /** URL to access the file */ + url: string; + /** SHA-256 checksum of the file */ + checksum?: string; + /** Original filename */ + filename?: string; + /** Modified time of the file */ + modified_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/FileNode.ts b/skyvern-ts/client/src/api/types/FileNode.ts new file mode 100644 index 00000000..db7965ca --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileNode.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +/** + * Model representing a file or directory in the file tree. + */ +export interface FileNode { + /** Type of node: 'file' or 'directory' */ + type: string; + /** File size in bytes */ + size?: number; + /** MIME type of the file */ + mime_type?: string; + /** SHA256 hash of file content */ + content_hash?: string; + /** Timestamp when the file was created */ + created_at: string; + /** Child nodes for directories */ + children?: Record; +} diff --git a/skyvern-ts/client/src/api/types/FileParserBlock.ts b/skyvern-ts/client/src/api/types/FileParserBlock.ts new file mode 100644 index 00000000..bb71c77f --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileParserBlock.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface FileParserBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + file_url: string; + file_type: Skyvern.FileType; + json_schema?: Record; +} diff --git a/skyvern-ts/client/src/api/types/FileParserBlockYaml.ts b/skyvern-ts/client/src/api/types/FileParserBlockYaml.ts new file mode 100644 index 00000000..c801fffe --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileParserBlockYaml.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface FileParserBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + file_url: string; + file_type: Skyvern.FileType; + json_schema?: Record; +} diff --git a/skyvern-ts/client/src/api/types/FileStorageType.ts b/skyvern-ts/client/src/api/types/FileStorageType.ts new file mode 100644 index 00000000..18d06bec --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileStorageType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const FileStorageType = { + S3: "s3", + Azure: "azure", +} as const; +export type FileStorageType = (typeof FileStorageType)[keyof typeof FileStorageType]; diff --git a/skyvern-ts/client/src/api/types/FileType.ts b/skyvern-ts/client/src/api/types/FileType.ts new file mode 100644 index 00000000..af4d7542 --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileType.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export const FileType = { + Csv: "csv", + Excel: "excel", + Pdf: "pdf", +} as const; +export type FileType = (typeof FileType)[keyof typeof FileType]; diff --git a/skyvern-ts/client/src/api/types/FileUploadBlock.ts b/skyvern-ts/client/src/api/types/FileUploadBlock.ts new file mode 100644 index 00000000..54141577 --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileUploadBlock.ts @@ -0,0 +1,20 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface FileUploadBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + storage_type?: Skyvern.FileStorageType; + s3_bucket?: string; + aws_access_key_id?: string; + aws_secret_access_key?: string; + region_name?: string; + azure_storage_account_name?: string; + azure_storage_account_key?: string; + azure_blob_container_name?: string; + path?: string; +} diff --git a/skyvern-ts/client/src/api/types/FileUploadBlockYaml.ts b/skyvern-ts/client/src/api/types/FileUploadBlockYaml.ts new file mode 100644 index 00000000..ead7990e --- /dev/null +++ b/skyvern-ts/client/src/api/types/FileUploadBlockYaml.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface FileUploadBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + storage_type?: Skyvern.FileStorageType; + s3_bucket?: string; + aws_access_key_id?: string; + aws_secret_access_key?: string; + region_name?: string; + azure_storage_account_name?: string; + azure_storage_account_key?: string; + azure_blob_container_name?: string; + azure_folder_path?: string; + path?: string; +} diff --git a/skyvern-ts/client/src/api/types/ForLoopBlock.ts b/skyvern-ts/client/src/api/types/ForLoopBlock.ts new file mode 100644 index 00000000..eda1f037 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ForLoopBlock.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface ForLoopBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + loop_blocks: Skyvern.ForLoopBlockLoopBlocksItem[]; + loop_over?: Skyvern.ForLoopBlockLoopOver; + loop_variable_reference?: string; + complete_if_empty?: boolean; +} diff --git a/skyvern-ts/client/src/api/types/ForLoopBlockLoopBlocksItem.ts b/skyvern-ts/client/src/api/types/ForLoopBlockLoopBlocksItem.ts new file mode 100644 index 00000000..e3952f67 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ForLoopBlockLoopBlocksItem.ts @@ -0,0 +1,107 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type ForLoopBlockLoopBlocksItem = + | Skyvern.ForLoopBlockLoopBlocksItem.Action + | Skyvern.ForLoopBlockLoopBlocksItem.Code + | Skyvern.ForLoopBlockLoopBlocksItem.DownloadToS3 + | Skyvern.ForLoopBlockLoopBlocksItem.Extraction + | Skyvern.ForLoopBlockLoopBlocksItem.FileDownload + | Skyvern.ForLoopBlockLoopBlocksItem.FileUpload + | Skyvern.ForLoopBlockLoopBlocksItem.FileUrlParser + | Skyvern.ForLoopBlockLoopBlocksItem.ForLoop + | Skyvern.ForLoopBlockLoopBlocksItem.GotoUrl + | Skyvern.ForLoopBlockLoopBlocksItem.HttpRequest + | Skyvern.ForLoopBlockLoopBlocksItem.Login + | Skyvern.ForLoopBlockLoopBlocksItem.Navigation + | Skyvern.ForLoopBlockLoopBlocksItem.PdfParser + | Skyvern.ForLoopBlockLoopBlocksItem.SendEmail + | Skyvern.ForLoopBlockLoopBlocksItem.Task + | Skyvern.ForLoopBlockLoopBlocksItem.TaskV2 + | Skyvern.ForLoopBlockLoopBlocksItem.TextPrompt + | Skyvern.ForLoopBlockLoopBlocksItem.UploadToS3 + | Skyvern.ForLoopBlockLoopBlocksItem.Validation + | Skyvern.ForLoopBlockLoopBlocksItem.Wait; + +export namespace ForLoopBlockLoopBlocksItem { + export interface Action extends Skyvern.ActionBlock { + block_type: "action"; + } + + export interface Code extends Skyvern.CodeBlock { + block_type: "code"; + } + + export interface DownloadToS3 extends Skyvern.DownloadToS3Block { + block_type: "download_to_s3"; + } + + export interface Extraction extends Skyvern.ExtractionBlock { + block_type: "extraction"; + } + + export interface FileDownload extends Skyvern.FileDownloadBlock { + block_type: "file_download"; + } + + export interface FileUpload extends Skyvern.FileUploadBlock { + block_type: "file_upload"; + } + + export interface FileUrlParser extends Skyvern.FileParserBlock { + block_type: "file_url_parser"; + } + + export interface ForLoop extends Skyvern.ForLoopBlock { + block_type: "for_loop"; + } + + export interface GotoUrl extends Skyvern.UrlBlock { + block_type: "goto_url"; + } + + export interface HttpRequest extends Skyvern.HttpRequestBlock { + block_type: "http_request"; + } + + export interface Login extends Skyvern.LoginBlock { + block_type: "login"; + } + + export interface Navigation extends Skyvern.NavigationBlock { + block_type: "navigation"; + } + + export interface PdfParser extends Skyvern.PdfParserBlock { + block_type: "pdf_parser"; + } + + export interface SendEmail extends Skyvern.SendEmailBlock { + block_type: "send_email"; + } + + export interface Task extends Skyvern.TaskBlock { + block_type: "task"; + } + + export interface TaskV2 extends Skyvern.TaskV2Block { + block_type: "task_v2"; + } + + export interface TextPrompt extends Skyvern.TextPromptBlock { + block_type: "text_prompt"; + } + + export interface UploadToS3 extends Skyvern.UploadToS3Block { + block_type: "upload_to_s3"; + } + + export interface Validation extends Skyvern.ValidationBlock { + block_type: "validation"; + } + + export interface Wait extends Skyvern.WaitBlock { + block_type: "wait"; + } +} diff --git a/skyvern-ts/client/src/api/types/ForLoopBlockLoopOver.ts b/skyvern-ts/client/src/api/types/ForLoopBlockLoopOver.ts new file mode 100644 index 00000000..64f8cdc7 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ForLoopBlockLoopOver.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type ForLoopBlockLoopOver = + | Skyvern.ForLoopBlockLoopOver.AwsSecret + | Skyvern.ForLoopBlockLoopOver.AzureSecret + | Skyvern.ForLoopBlockLoopOver.AzureVaultCredential + | Skyvern.ForLoopBlockLoopOver.BitwardenCreditCardData + | Skyvern.ForLoopBlockLoopOver.BitwardenLoginCredential + | Skyvern.ForLoopBlockLoopOver.BitwardenSensitiveInformation + | Skyvern.ForLoopBlockLoopOver.Context + | Skyvern.ForLoopBlockLoopOver.Credential + | Skyvern.ForLoopBlockLoopOver.Onepassword + | Skyvern.ForLoopBlockLoopOver.Output + | Skyvern.ForLoopBlockLoopOver.Workflow; + +export namespace ForLoopBlockLoopOver { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/ForLoopBlockYaml.ts b/skyvern-ts/client/src/api/types/ForLoopBlockYaml.ts new file mode 100644 index 00000000..be5f876a --- /dev/null +++ b/skyvern-ts/client/src/api/types/ForLoopBlockYaml.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface ForLoopBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + loop_blocks: Skyvern.ForLoopBlockYamlLoopBlocksItem[]; + loop_over_parameter_key?: string; + loop_variable_reference?: string; + complete_if_empty?: boolean; +} diff --git a/skyvern-ts/client/src/api/types/ForLoopBlockYamlLoopBlocksItem.ts b/skyvern-ts/client/src/api/types/ForLoopBlockYamlLoopBlocksItem.ts new file mode 100644 index 00000000..9c0f417f --- /dev/null +++ b/skyvern-ts/client/src/api/types/ForLoopBlockYamlLoopBlocksItem.ts @@ -0,0 +1,107 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type ForLoopBlockYamlLoopBlocksItem = + | Skyvern.ForLoopBlockYamlLoopBlocksItem.Task + | Skyvern.ForLoopBlockYamlLoopBlocksItem.ForLoop + | Skyvern.ForLoopBlockYamlLoopBlocksItem.Code + | Skyvern.ForLoopBlockYamlLoopBlocksItem.TextPrompt + | Skyvern.ForLoopBlockYamlLoopBlocksItem.DownloadToS3 + | Skyvern.ForLoopBlockYamlLoopBlocksItem.UploadToS3 + | Skyvern.ForLoopBlockYamlLoopBlocksItem.FileUpload + | Skyvern.ForLoopBlockYamlLoopBlocksItem.SendEmail + | Skyvern.ForLoopBlockYamlLoopBlocksItem.FileUrlParser + | Skyvern.ForLoopBlockYamlLoopBlocksItem.Validation + | Skyvern.ForLoopBlockYamlLoopBlocksItem.Action + | Skyvern.ForLoopBlockYamlLoopBlocksItem.Navigation + | Skyvern.ForLoopBlockYamlLoopBlocksItem.Extraction + | Skyvern.ForLoopBlockYamlLoopBlocksItem.Login + | Skyvern.ForLoopBlockYamlLoopBlocksItem.Wait + | Skyvern.ForLoopBlockYamlLoopBlocksItem.FileDownload + | Skyvern.ForLoopBlockYamlLoopBlocksItem.GotoUrl + | Skyvern.ForLoopBlockYamlLoopBlocksItem.PdfParser + | Skyvern.ForLoopBlockYamlLoopBlocksItem.TaskV2 + | Skyvern.ForLoopBlockYamlLoopBlocksItem.HttpRequest; + +export namespace ForLoopBlockYamlLoopBlocksItem { + export interface Task extends Skyvern.TaskBlockYaml { + block_type: "task"; + } + + export interface ForLoop extends Skyvern.ForLoopBlockYaml { + block_type: "for_loop"; + } + + export interface Code extends Skyvern.CodeBlockYaml { + block_type: "code"; + } + + export interface TextPrompt extends Skyvern.TextPromptBlockYaml { + block_type: "text_prompt"; + } + + export interface DownloadToS3 extends Skyvern.DownloadToS3BlockYaml { + block_type: "download_to_s3"; + } + + export interface UploadToS3 extends Skyvern.UploadToS3BlockYaml { + block_type: "upload_to_s3"; + } + + export interface FileUpload extends Skyvern.FileUploadBlockYaml { + block_type: "file_upload"; + } + + export interface SendEmail extends Skyvern.SendEmailBlockYaml { + block_type: "send_email"; + } + + export interface FileUrlParser extends Skyvern.FileParserBlockYaml { + block_type: "file_url_parser"; + } + + export interface Validation extends Skyvern.ValidationBlockYaml { + block_type: "validation"; + } + + export interface Action extends Skyvern.ActionBlockYaml { + block_type: "action"; + } + + export interface Navigation extends Skyvern.NavigationBlockYaml { + block_type: "navigation"; + } + + export interface Extraction extends Skyvern.ExtractionBlockYaml { + block_type: "extraction"; + } + + export interface Login extends Skyvern.LoginBlockYaml { + block_type: "login"; + } + + export interface Wait extends Skyvern.WaitBlockYaml { + block_type: "wait"; + } + + export interface FileDownload extends Skyvern.FileDownloadBlockYaml { + block_type: "file_download"; + } + + export interface GotoUrl extends Skyvern.UrlBlockYaml { + block_type: "goto_url"; + } + + export interface PdfParser extends Skyvern.PdfParserBlockYaml { + block_type: "pdf_parser"; + } + + export interface TaskV2 extends Skyvern.TaskV2BlockYaml { + block_type: "task_v2"; + } + + export interface HttpRequest extends Skyvern.HttpRequestBlockYaml { + block_type: "http_request"; + } +} diff --git a/skyvern-ts/client/src/api/types/GetRunResponse.ts b/skyvern-ts/client/src/api/types/GetRunResponse.ts new file mode 100644 index 00000000..1b24fc4e --- /dev/null +++ b/skyvern-ts/client/src/api/types/GetRunResponse.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type GetRunResponse = + | Skyvern.GetRunResponse.TaskV1 + | Skyvern.GetRunResponse.TaskV2 + | Skyvern.GetRunResponse.OpenaiCua + | Skyvern.GetRunResponse.AnthropicCua + | Skyvern.GetRunResponse.UiTars + | Skyvern.GetRunResponse.WorkflowRun; + +export namespace GetRunResponse { + export interface TaskV1 extends Skyvern.TaskRunResponse { + run_type: "task_v1"; + } + + export interface TaskV2 extends Skyvern.TaskRunResponse { + run_type: "task_v2"; + } + + export interface OpenaiCua extends Skyvern.TaskRunResponse { + run_type: "openai_cua"; + } + + export interface AnthropicCua extends Skyvern.TaskRunResponse { + run_type: "anthropic_cua"; + } + + export interface UiTars extends Skyvern.TaskRunResponse { + run_type: "ui_tars"; + } + + export interface WorkflowRun extends Skyvern.WorkflowRunResponse { + run_type: "workflow_run"; + } +} diff --git a/skyvern-ts/client/src/api/types/HttpRequestBlock.ts b/skyvern-ts/client/src/api/types/HttpRequestBlock.ts new file mode 100644 index 00000000..2072cb34 --- /dev/null +++ b/skyvern-ts/client/src/api/types/HttpRequestBlock.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface HttpRequestBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + method?: string; + url?: string; + headers?: Record; + body?: Record; + timeout?: number; + follow_redirects?: boolean; + parameters?: Skyvern.HttpRequestBlockParametersItem[]; +} diff --git a/skyvern-ts/client/src/api/types/HttpRequestBlockParametersItem.ts b/skyvern-ts/client/src/api/types/HttpRequestBlockParametersItem.ts new file mode 100644 index 00000000..f17785c2 --- /dev/null +++ b/skyvern-ts/client/src/api/types/HttpRequestBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type HttpRequestBlockParametersItem = + | Skyvern.HttpRequestBlockParametersItem.AwsSecret + | Skyvern.HttpRequestBlockParametersItem.AzureSecret + | Skyvern.HttpRequestBlockParametersItem.AzureVaultCredential + | Skyvern.HttpRequestBlockParametersItem.BitwardenCreditCardData + | Skyvern.HttpRequestBlockParametersItem.BitwardenLoginCredential + | Skyvern.HttpRequestBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.HttpRequestBlockParametersItem.Context + | Skyvern.HttpRequestBlockParametersItem.Credential + | Skyvern.HttpRequestBlockParametersItem.Onepassword + | Skyvern.HttpRequestBlockParametersItem.Output + | Skyvern.HttpRequestBlockParametersItem.Workflow; + +export namespace HttpRequestBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/HttpRequestBlockYaml.ts b/skyvern-ts/client/src/api/types/HttpRequestBlockYaml.ts new file mode 100644 index 00000000..5bb06eb2 --- /dev/null +++ b/skyvern-ts/client/src/api/types/HttpRequestBlockYaml.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface HttpRequestBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + method?: string; + url?: string; + headers?: Record; + body?: Record; + timeout?: number; + follow_redirects?: boolean; + parameter_keys?: string[]; +} diff --git a/skyvern-ts/client/src/api/types/HttpValidationError.ts b/skyvern-ts/client/src/api/types/HttpValidationError.ts new file mode 100644 index 00000000..fab95797 --- /dev/null +++ b/skyvern-ts/client/src/api/types/HttpValidationError.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface HttpValidationError { + detail?: Skyvern.ValidationError[]; +} diff --git a/skyvern-ts/client/src/api/types/InputOrSelectContext.ts b/skyvern-ts/client/src/api/types/InputOrSelectContext.ts new file mode 100644 index 00000000..120d872f --- /dev/null +++ b/skyvern-ts/client/src/api/types/InputOrSelectContext.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface InputOrSelectContext { + intention?: string; + field?: string; + is_required?: boolean; + is_search_bar?: boolean; + is_location_input?: boolean; + is_date_related?: boolean; +} diff --git a/skyvern-ts/client/src/api/types/LoginBlock.ts b/skyvern-ts/client/src/api/types/LoginBlock.ts new file mode 100644 index 00000000..849ee707 --- /dev/null +++ b/skyvern-ts/client/src/api/types/LoginBlock.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface LoginBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + task_type?: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + complete_criterion?: string; + terminate_criterion?: string; + navigation_goal?: string; + data_extraction_goal?: string; + data_schema?: LoginBlock.DataSchema; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameters?: Skyvern.LoginBlockParametersItem[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; + download_timeout?: number; +} + +export namespace LoginBlock { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/LoginBlockParametersItem.ts b/skyvern-ts/client/src/api/types/LoginBlockParametersItem.ts new file mode 100644 index 00000000..1fdf014b --- /dev/null +++ b/skyvern-ts/client/src/api/types/LoginBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type LoginBlockParametersItem = + | Skyvern.LoginBlockParametersItem.AwsSecret + | Skyvern.LoginBlockParametersItem.AzureSecret + | Skyvern.LoginBlockParametersItem.AzureVaultCredential + | Skyvern.LoginBlockParametersItem.BitwardenCreditCardData + | Skyvern.LoginBlockParametersItem.BitwardenLoginCredential + | Skyvern.LoginBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.LoginBlockParametersItem.Context + | Skyvern.LoginBlockParametersItem.Credential + | Skyvern.LoginBlockParametersItem.Onepassword + | Skyvern.LoginBlockParametersItem.Output + | Skyvern.LoginBlockParametersItem.Workflow; + +export namespace LoginBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/LoginBlockYaml.ts b/skyvern-ts/client/src/api/types/LoginBlockYaml.ts new file mode 100644 index 00000000..bb05d694 --- /dev/null +++ b/skyvern-ts/client/src/api/types/LoginBlockYaml.ts @@ -0,0 +1,24 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface LoginBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + navigation_goal?: string; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameter_keys?: string[]; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + disable_cache?: boolean; + complete_criterion?: string; + terminate_criterion?: string; + complete_verification?: boolean; +} diff --git a/skyvern-ts/client/src/api/types/NavigationBlock.ts b/skyvern-ts/client/src/api/types/NavigationBlock.ts new file mode 100644 index 00000000..bb89f117 --- /dev/null +++ b/skyvern-ts/client/src/api/types/NavigationBlock.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface NavigationBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + task_type?: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + complete_criterion?: string; + terminate_criterion?: string; + navigation_goal: string; + data_extraction_goal?: string; + data_schema?: NavigationBlock.DataSchema; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameters?: Skyvern.NavigationBlockParametersItem[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; + download_timeout?: number; +} + +export namespace NavigationBlock { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/NavigationBlockParametersItem.ts b/skyvern-ts/client/src/api/types/NavigationBlockParametersItem.ts new file mode 100644 index 00000000..56776c47 --- /dev/null +++ b/skyvern-ts/client/src/api/types/NavigationBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type NavigationBlockParametersItem = + | Skyvern.NavigationBlockParametersItem.AwsSecret + | Skyvern.NavigationBlockParametersItem.AzureSecret + | Skyvern.NavigationBlockParametersItem.AzureVaultCredential + | Skyvern.NavigationBlockParametersItem.BitwardenCreditCardData + | Skyvern.NavigationBlockParametersItem.BitwardenLoginCredential + | Skyvern.NavigationBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.NavigationBlockParametersItem.Context + | Skyvern.NavigationBlockParametersItem.Credential + | Skyvern.NavigationBlockParametersItem.Onepassword + | Skyvern.NavigationBlockParametersItem.Output + | Skyvern.NavigationBlockParametersItem.Workflow; + +export namespace NavigationBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/NavigationBlockYaml.ts b/skyvern-ts/client/src/api/types/NavigationBlockYaml.ts new file mode 100644 index 00000000..5c1b11bc --- /dev/null +++ b/skyvern-ts/client/src/api/types/NavigationBlockYaml.ts @@ -0,0 +1,27 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface NavigationBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + navigation_goal: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameter_keys?: string[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + disable_cache?: boolean; + complete_criterion?: string; + terminate_criterion?: string; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; +} diff --git a/skyvern-ts/client/src/api/types/NonEmptyCreditCardCredential.ts b/skyvern-ts/client/src/api/types/NonEmptyCreditCardCredential.ts new file mode 100644 index 00000000..5acebb51 --- /dev/null +++ b/skyvern-ts/client/src/api/types/NonEmptyCreditCardCredential.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * Credit card credential model that requires non-empty values. + */ +export interface NonEmptyCreditCardCredential { + /** The full credit card number (must not be empty) */ + card_number: string; + /** The card's CVV (must not be empty) */ + card_cvv: string; + /** The card's expiration month (must not be empty) */ + card_exp_month: string; + /** The card's expiration year (must not be empty) */ + card_exp_year: string; + /** The card's brand (must not be empty) */ + card_brand: string; + /** The name of the card holder (must not be empty) */ + card_holder_name: string; +} diff --git a/skyvern-ts/client/src/api/types/NonEmptyPasswordCredential.ts b/skyvern-ts/client/src/api/types/NonEmptyPasswordCredential.ts new file mode 100644 index 00000000..055de72d --- /dev/null +++ b/skyvern-ts/client/src/api/types/NonEmptyPasswordCredential.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +/** + * Password credential model that requires non-empty values. + */ +export interface NonEmptyPasswordCredential { + /** The password value (must not be empty) */ + password: string; + /** The username associated with the credential (must not be empty) */ + username: string; + /** Optional TOTP (Time-based One-Time Password) string used to generate 2FA codes */ + totp?: string; + /** Type of 2FA method used for this credential */ + totp_type?: Skyvern.TotpType; +} diff --git a/skyvern-ts/client/src/api/types/OnePasswordCredentialParameter.ts b/skyvern-ts/client/src/api/types/OnePasswordCredentialParameter.ts new file mode 100644 index 00000000..1fa95717 --- /dev/null +++ b/skyvern-ts/client/src/api/types/OnePasswordCredentialParameter.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface OnePasswordCredentialParameter { + key: string; + description?: string; + onepassword_credential_parameter_id: string; + workflow_id: string; + vault_id: string; + item_id: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/OnePasswordCredentialParameterYaml.ts b/skyvern-ts/client/src/api/types/OnePasswordCredentialParameterYaml.ts new file mode 100644 index 00000000..1b902897 --- /dev/null +++ b/skyvern-ts/client/src/api/types/OnePasswordCredentialParameterYaml.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface OnePasswordCredentialParameterYaml { + key: string; + description?: string; + vault_id: string; + item_id: string; +} diff --git a/skyvern-ts/client/src/api/types/OtpType.ts b/skyvern-ts/client/src/api/types/OtpType.ts new file mode 100644 index 00000000..e4a72c3a --- /dev/null +++ b/skyvern-ts/client/src/api/types/OtpType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const OtpType = { + Totp: "totp", + MagicLink: "magic_link", +} as const; +export type OtpType = (typeof OtpType)[keyof typeof OtpType]; diff --git a/skyvern-ts/client/src/api/types/OutputParameter.ts b/skyvern-ts/client/src/api/types/OutputParameter.ts new file mode 100644 index 00000000..11ea2821 --- /dev/null +++ b/skyvern-ts/client/src/api/types/OutputParameter.ts @@ -0,0 +1,11 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface OutputParameter { + key: string; + description?: string; + output_parameter_id: string; + workflow_id: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/OutputParameterYaml.ts b/skyvern-ts/client/src/api/types/OutputParameterYaml.ts new file mode 100644 index 00000000..d707982d --- /dev/null +++ b/skyvern-ts/client/src/api/types/OutputParameterYaml.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface OutputParameterYaml { + key: string; + description?: string; +} diff --git a/skyvern-ts/client/src/api/types/PasswordCredentialResponse.ts b/skyvern-ts/client/src/api/types/PasswordCredentialResponse.ts new file mode 100644 index 00000000..717e1f2d --- /dev/null +++ b/skyvern-ts/client/src/api/types/PasswordCredentialResponse.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +/** + * Response model for password credentials, containing only the username. + */ +export interface PasswordCredentialResponse { + /** The username associated with the credential */ + username: string; + /** Type of 2FA method used for this credential */ + totp_type?: Skyvern.TotpType; +} diff --git a/skyvern-ts/client/src/api/types/PdfParserBlock.ts b/skyvern-ts/client/src/api/types/PdfParserBlock.ts new file mode 100644 index 00000000..956a73e3 --- /dev/null +++ b/skyvern-ts/client/src/api/types/PdfParserBlock.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +/** + * DEPRECATED: Use FileParserBlock with file_type=FileType.PDF instead. + * This block will be removed in a future version. + */ +export interface PdfParserBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + file_url: string; + json_schema?: Record; +} diff --git a/skyvern-ts/client/src/api/types/PdfParserBlockYaml.ts b/skyvern-ts/client/src/api/types/PdfParserBlockYaml.ts new file mode 100644 index 00000000..051ea76e --- /dev/null +++ b/skyvern-ts/client/src/api/types/PdfParserBlockYaml.ts @@ -0,0 +1,9 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface PdfParserBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + file_url: string; + json_schema?: Record; +} diff --git a/skyvern-ts/client/src/api/types/ProxyLocation.ts b/skyvern-ts/client/src/api/types/ProxyLocation.ts new file mode 100644 index 00000000..5af753ec --- /dev/null +++ b/skyvern-ts/client/src/api/types/ProxyLocation.ts @@ -0,0 +1,30 @@ +// This file was auto-generated by Fern from our API Definition. + +export const ProxyLocation = { + Residential: "RESIDENTIAL", + UsCa: "US-CA", + UsNy: "US-NY", + UsTx: "US-TX", + UsFl: "US-FL", + UsWa: "US-WA", + ResidentialEs: "RESIDENTIAL_ES", + ResidentialIe: "RESIDENTIAL_IE", + ResidentialGb: "RESIDENTIAL_GB", + ResidentialIn: "RESIDENTIAL_IN", + ResidentialJp: "RESIDENTIAL_JP", + ResidentialFr: "RESIDENTIAL_FR", + ResidentialDe: "RESIDENTIAL_DE", + ResidentialNz: "RESIDENTIAL_NZ", + ResidentialZa: "RESIDENTIAL_ZA", + ResidentialAr: "RESIDENTIAL_AR", + ResidentialAu: "RESIDENTIAL_AU", + ResidentialBr: "RESIDENTIAL_BR", + ResidentialTr: "RESIDENTIAL_TR", + ResidentialCa: "RESIDENTIAL_CA", + ResidentialMx: "RESIDENTIAL_MX", + ResidentialIt: "RESIDENTIAL_IT", + ResidentialNl: "RESIDENTIAL_NL", + ResidentialIsp: "RESIDENTIAL_ISP", + None: "NONE", +} as const; +export type ProxyLocation = (typeof ProxyLocation)[keyof typeof ProxyLocation]; diff --git a/skyvern-ts/client/src/api/types/RunEngine.ts b/skyvern-ts/client/src/api/types/RunEngine.ts new file mode 100644 index 00000000..4ce84505 --- /dev/null +++ b/skyvern-ts/client/src/api/types/RunEngine.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +export const RunEngine = { + Skyvern10: "skyvern-1.0", + Skyvern20: "skyvern-2.0", + OpenaiCua: "openai-cua", + AnthropicCua: "anthropic-cua", + UiTars: "ui-tars", +} as const; +export type RunEngine = (typeof RunEngine)[keyof typeof RunEngine]; diff --git a/skyvern-ts/client/src/api/types/RunStatus.ts b/skyvern-ts/client/src/api/types/RunStatus.ts new file mode 100644 index 00000000..3f7d5d0e --- /dev/null +++ b/skyvern-ts/client/src/api/types/RunStatus.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +export const RunStatus = { + Created: "created", + Queued: "queued", + Running: "running", + TimedOut: "timed_out", + Failed: "failed", + Terminated: "terminated", + Completed: "completed", + Canceled: "canceled", +} as const; +export type RunStatus = (typeof RunStatus)[keyof typeof RunStatus]; diff --git a/skyvern-ts/client/src/api/types/Script.ts b/skyvern-ts/client/src/api/types/Script.ts new file mode 100644 index 00000000..00556f08 --- /dev/null +++ b/skyvern-ts/client/src/api/types/Script.ts @@ -0,0 +1,20 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface Script { + /** Unique identifier for this specific script revision */ + script_revision_id: string; + /** User-facing script identifier, consistent across versions */ + script_id: string; + /** ID of the organization that owns this script */ + organization_id: string; + /** ID of the workflow run or task run that generated this script */ + run_id?: string; + /** Version number of the script */ + version: number; + /** Timestamp when the script was created */ + created_at: string; + /** Timestamp when the script was last modified */ + modified_at: string; + /** Timestamp when the script was soft deleted */ + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/ScriptFileCreate.ts b/skyvern-ts/client/src/api/types/ScriptFileCreate.ts new file mode 100644 index 00000000..9fc62256 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ScriptFileCreate.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +/** + * Model representing a file in a script. + */ +export interface ScriptFileCreate { + /** File path relative to script root */ + path: string; + /** Base64 encoded file content */ + content: string; + /** Content encoding */ + encoding?: Skyvern.FileEncoding; + /** MIME type (auto-detected if not provided) */ + mime_type?: string; +} diff --git a/skyvern-ts/client/src/api/types/ScriptRunResponse.ts b/skyvern-ts/client/src/api/types/ScriptRunResponse.ts new file mode 100644 index 00000000..b2a78983 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ScriptRunResponse.ts @@ -0,0 +1,5 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface ScriptRunResponse { + ai_fallback_triggered?: boolean; +} diff --git a/skyvern-ts/client/src/api/types/SelectOption.ts b/skyvern-ts/client/src/api/types/SelectOption.ts new file mode 100644 index 00000000..6ecfbf30 --- /dev/null +++ b/skyvern-ts/client/src/api/types/SelectOption.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface SelectOption { + label?: string; + value?: string; + index?: number; +} diff --git a/skyvern-ts/client/src/api/types/SendEmailBlock.ts b/skyvern-ts/client/src/api/types/SendEmailBlock.ts new file mode 100644 index 00000000..be2315cc --- /dev/null +++ b/skyvern-ts/client/src/api/types/SendEmailBlock.ts @@ -0,0 +1,20 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface SendEmailBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + smtp_host: Skyvern.AwsSecretParameter; + smtp_port: Skyvern.AwsSecretParameter; + smtp_username: Skyvern.AwsSecretParameter; + smtp_password: Skyvern.AwsSecretParameter; + sender: string; + recipients: string[]; + subject: string; + body: string; + file_attachments?: string[]; +} diff --git a/skyvern-ts/client/src/api/types/SendEmailBlockYaml.ts b/skyvern-ts/client/src/api/types/SendEmailBlockYaml.ts new file mode 100644 index 00000000..d860d20e --- /dev/null +++ b/skyvern-ts/client/src/api/types/SendEmailBlockYaml.ts @@ -0,0 +1,16 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface SendEmailBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + smtp_host_secret_parameter_key: string; + smtp_port_secret_parameter_key: string; + smtp_username_secret_parameter_key: string; + smtp_password_secret_parameter_key: string; + sender: string; + recipients: string[]; + subject: string; + body: string; + file_attachments?: string[]; +} diff --git a/skyvern-ts/client/src/api/types/SkyvernForgeSdkSchemasCredentialsCredentialType.ts b/skyvern-ts/client/src/api/types/SkyvernForgeSdkSchemasCredentialsCredentialType.ts new file mode 100644 index 00000000..bc1f52a3 --- /dev/null +++ b/skyvern-ts/client/src/api/types/SkyvernForgeSdkSchemasCredentialsCredentialType.ts @@ -0,0 +1,9 @@ +// This file was auto-generated by Fern from our API Definition. + +/** Type of credential stored in the system. */ +export const SkyvernForgeSdkSchemasCredentialsCredentialType = { + Password: "password", + CreditCard: "credit_card", +} as const; +export type SkyvernForgeSdkSchemasCredentialsCredentialType = + (typeof SkyvernForgeSdkSchemasCredentialsCredentialType)[keyof typeof SkyvernForgeSdkSchemasCredentialsCredentialType]; diff --git a/skyvern-ts/client/src/api/types/SkyvernSchemasRunBlocksCredentialType.ts b/skyvern-ts/client/src/api/types/SkyvernSchemasRunBlocksCredentialType.ts new file mode 100644 index 00000000..972e6a83 --- /dev/null +++ b/skyvern-ts/client/src/api/types/SkyvernSchemasRunBlocksCredentialType.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +export const SkyvernSchemasRunBlocksCredentialType = { + Skyvern: "skyvern", + Bitwarden: "bitwarden", + OnePassword: "1password", + AzureVault: "azure_vault", +} as const; +export type SkyvernSchemasRunBlocksCredentialType = + (typeof SkyvernSchemasRunBlocksCredentialType)[keyof typeof SkyvernSchemasRunBlocksCredentialType]; diff --git a/skyvern-ts/client/src/api/types/TaskBlock.ts b/skyvern-ts/client/src/api/types/TaskBlock.ts new file mode 100644 index 00000000..96d49826 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TaskBlock.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface TaskBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + task_type?: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + complete_criterion?: string; + terminate_criterion?: string; + navigation_goal?: string; + data_extraction_goal?: string; + data_schema?: TaskBlock.DataSchema; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameters?: Skyvern.TaskBlockParametersItem[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; + download_timeout?: number; +} + +export namespace TaskBlock { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/TaskBlockParametersItem.ts b/skyvern-ts/client/src/api/types/TaskBlockParametersItem.ts new file mode 100644 index 00000000..110ba52c --- /dev/null +++ b/skyvern-ts/client/src/api/types/TaskBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type TaskBlockParametersItem = + | Skyvern.TaskBlockParametersItem.AwsSecret + | Skyvern.TaskBlockParametersItem.AzureSecret + | Skyvern.TaskBlockParametersItem.AzureVaultCredential + | Skyvern.TaskBlockParametersItem.BitwardenCreditCardData + | Skyvern.TaskBlockParametersItem.BitwardenLoginCredential + | Skyvern.TaskBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.TaskBlockParametersItem.Context + | Skyvern.TaskBlockParametersItem.Credential + | Skyvern.TaskBlockParametersItem.Onepassword + | Skyvern.TaskBlockParametersItem.Output + | Skyvern.TaskBlockParametersItem.Workflow; + +export namespace TaskBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/TaskBlockYaml.ts b/skyvern-ts/client/src/api/types/TaskBlockYaml.ts new file mode 100644 index 00000000..b3a8e916 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TaskBlockYaml.ts @@ -0,0 +1,33 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface TaskBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + navigation_goal?: string; + data_extraction_goal?: string; + data_schema?: TaskBlockYaml.DataSchema; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameter_keys?: string[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + disable_cache?: boolean; + complete_criterion?: string; + terminate_criterion?: string; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; +} + +export namespace TaskBlockYaml { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/TaskRunRequest.ts b/skyvern-ts/client/src/api/types/TaskRunRequest.ts new file mode 100644 index 00000000..db238e2f --- /dev/null +++ b/skyvern-ts/client/src/api/types/TaskRunRequest.ts @@ -0,0 +1,95 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface TaskRunRequest { + /** + * The goal or task description for Skyvern to accomplish + */ + prompt: string; + /** + * The starting URL for the task. If not provided, Skyvern will attempt to determine an appropriate URL + */ + url?: string; + /** + * The engine that powers the agent task. The default value is `skyvern-2.0`, the latest Skyvern agent that performs pretty well with complex and multi-step tasks. `skyvern-1.0` is good for simple tasks like filling a form, or searching for information on Google. The `openai-cua` engine uses OpenAI's CUA model. The `anthropic-cua` uses Anthropic's Claude Sonnet 3.7 model with the computer use tool. + */ + engine?: Skyvern.RunEngine; + /** The title for the task */ + title?: string; + /** + * Geographic Proxy location to route the browser traffic through. This is only available in Skyvern Cloud. + * + * Available geotargeting options: + * - RESIDENTIAL: the default value. Skyvern Cloud uses a random US residential proxy. + * - RESIDENTIAL_ES: Spain + * - RESIDENTIAL_IE: Ireland + * - RESIDENTIAL_GB: United Kingdom + * - RESIDENTIAL_IN: India + * - RESIDENTIAL_JP: Japan + * - RESIDENTIAL_FR: France + * - RESIDENTIAL_DE: Germany + * - RESIDENTIAL_NZ: New Zealand + * - RESIDENTIAL_ZA: South Africa + * - RESIDENTIAL_AR: Argentina + * - RESIDENTIAL_AU: Australia + * - RESIDENTIAL_ISP: ISP proxy + * - US-CA: California + * - US-NY: New York + * - US-TX: Texas + * - US-FL: Florida + * - US-WA: Washington + * - NONE: No proxy + */ + proxy_location?: Skyvern.ProxyLocation; + /** + * The schema for data to be extracted from the webpage. If you're looking for consistent data schema being returned by the agent, it's highly recommended to use https://json-schema.org/. + */ + data_extraction_schema?: TaskRunRequest.DataExtractionSchema; + /** + * Custom mapping of error codes to error messages if Skyvern encounters an error. + */ + error_code_mapping?: Record; + /** + * Maximum number of steps the task can take. Task will fail if it exceeds this number. Cautions: you are charged per step so please set this number to a reasonable value. Contact sales@skyvern.com for custom pricing. + */ + max_steps?: number; + /** + * After a run is finished, send an update to this URL. Refer to https://www.skyvern.com/docs/running-tasks/webhooks-faq for more details. + */ + webhook_url?: string; + /** + * Identifier for the TOTP/2FA/MFA code when the code is pushed to Skyvern. Refer to https://www.skyvern.com/docs/credentials/totp#option-3-push-code-to-skyvern for more details. + */ + totp_identifier?: string; + /** + * URL that serves TOTP/2FA/MFA codes for Skyvern to use during the workflow run. Refer to https://www.skyvern.com/docs/credentials/totp#option-2-get-code-from-your-endpoint for more details. + */ + totp_url?: string; + /** + * Run the task or workflow in the specific Skyvern browser session. Having a browser session can persist the real-time state of the browser, so that the next run can continue from where the previous run left off. + */ + browser_session_id?: string; + /** + * Optional model configuration. + */ + model?: Record; + /** The extra HTTP headers for the requests in browser. */ + extra_http_headers?: Record; + /** Whether to publish this task as a reusable workflow. Only available for skyvern-2.0. */ + publish_workflow?: boolean; + /** Whether to include action history when verifying that the task is complete */ + include_action_history_in_verification?: boolean; + /** The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot. */ + max_screenshot_scrolls?: number; + /** The CDP address for the task. */ + browser_address?: string; +} + +export namespace TaskRunRequest { + /** + * + * The schema for data to be extracted from the webpage. If you're looking for consistent data schema being returned by the agent, it's highly recommended to use https://json-schema.org/. + */ + export type DataExtractionSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/TaskRunResponse.ts b/skyvern-ts/client/src/api/types/TaskRunResponse.ts new file mode 100644 index 00000000..eed4dda6 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TaskRunResponse.ts @@ -0,0 +1,49 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface TaskRunResponse { + /** Unique identifier for this run. Run ID starts with `tsk_` for task runs and `wr_` for workflow runs. */ + run_id: string; + /** Current status of the run */ + status: Skyvern.RunStatus; + /** Output data from the run, if any. Format/schema depends on the data extracted by the run. */ + output?: TaskRunResponse.Output; + /** List of files downloaded during the run */ + downloaded_files?: Skyvern.FileInfo[]; + /** URL to the recording of the run */ + recording_url?: string; + /** List of last n screenshot URLs in reverse chronological order - the first one the list is the latest screenshot. */ + screenshot_urls?: string[]; + /** Reason for failure if the run failed or terminated */ + failure_reason?: string; + /** Timestamp when this run was created */ + created_at: string; + /** Timestamp when this run was last modified */ + modified_at: string; + /** Timestamp when this run was queued */ + queued_at?: string; + /** Timestamp when this run started execution */ + started_at?: string; + /** Timestamp when this run finished */ + finished_at?: string; + /** URL to the application UI where the run can be viewed */ + app_url?: string; + /** ID of the Skyvern persistent browser session used for this run */ + browser_session_id?: string; + /** The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot */ + max_screenshot_scrolls?: number; + /** The script run result */ + script_run?: Skyvern.ScriptRunResponse; + /** The errors for the run */ + errors?: Record[]; + /** The original request parameters used to start this task run */ + run_request?: Skyvern.TaskRunRequest; +} + +export namespace TaskRunResponse { + /** + * Output data from the run, if any. Format/schema depends on the data extracted by the run. + */ + export type Output = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/TaskV2Block.ts b/skyvern-ts/client/src/api/types/TaskV2Block.ts new file mode 100644 index 00000000..ab8b8272 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TaskV2Block.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface TaskV2Block { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + prompt: string; + url?: string; + totp_verification_url?: string; + totp_identifier?: string; + max_iterations?: number; + max_steps?: number; +} diff --git a/skyvern-ts/client/src/api/types/TaskV2BlockYaml.ts b/skyvern-ts/client/src/api/types/TaskV2BlockYaml.ts new file mode 100644 index 00000000..88ff13f5 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TaskV2BlockYaml.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TaskV2BlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + prompt: string; + url?: string; + totp_verification_url?: string; + totp_identifier?: string; + max_iterations?: number; + max_steps?: number; + disable_cache?: boolean; +} diff --git a/skyvern-ts/client/src/api/types/TextPromptBlock.ts b/skyvern-ts/client/src/api/types/TextPromptBlock.ts new file mode 100644 index 00000000..d986229d --- /dev/null +++ b/skyvern-ts/client/src/api/types/TextPromptBlock.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface TextPromptBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + llm_key?: string; + prompt: string; + parameters?: Skyvern.TextPromptBlockParametersItem[]; + json_schema?: Record; +} diff --git a/skyvern-ts/client/src/api/types/TextPromptBlockParametersItem.ts b/skyvern-ts/client/src/api/types/TextPromptBlockParametersItem.ts new file mode 100644 index 00000000..8c9a5b4f --- /dev/null +++ b/skyvern-ts/client/src/api/types/TextPromptBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type TextPromptBlockParametersItem = + | Skyvern.TextPromptBlockParametersItem.AwsSecret + | Skyvern.TextPromptBlockParametersItem.AzureSecret + | Skyvern.TextPromptBlockParametersItem.AzureVaultCredential + | Skyvern.TextPromptBlockParametersItem.BitwardenCreditCardData + | Skyvern.TextPromptBlockParametersItem.BitwardenLoginCredential + | Skyvern.TextPromptBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.TextPromptBlockParametersItem.Context + | Skyvern.TextPromptBlockParametersItem.Credential + | Skyvern.TextPromptBlockParametersItem.Onepassword + | Skyvern.TextPromptBlockParametersItem.Output + | Skyvern.TextPromptBlockParametersItem.Workflow; + +export namespace TextPromptBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/TextPromptBlockYaml.ts b/skyvern-ts/client/src/api/types/TextPromptBlockYaml.ts new file mode 100644 index 00000000..cead5374 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TextPromptBlockYaml.ts @@ -0,0 +1,11 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TextPromptBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + llm_key?: string; + prompt: string; + parameter_keys?: string[]; + json_schema?: Record; +} diff --git a/skyvern-ts/client/src/api/types/Thought.ts b/skyvern-ts/client/src/api/types/Thought.ts new file mode 100644 index 00000000..c4c37459 --- /dev/null +++ b/skyvern-ts/client/src/api/types/Thought.ts @@ -0,0 +1,27 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface Thought { + thought_id: string; + task_id: string; + organization_id: string; + workflow_run_id?: string; + workflow_run_block_id?: string; + workflow_id?: string; + workflow_permanent_id?: string; + user_input?: string; + observation?: string; + thought?: string; + answer?: string; + thought_type?: Skyvern.ThoughtType; + thought_scenario?: Skyvern.ThoughtScenario; + output?: Record; + input_token_count?: number; + output_token_count?: number; + reasoning_token_count?: number; + cached_token_count?: number; + thought_cost?: number; + created_at: string; + modified_at: string; +} diff --git a/skyvern-ts/client/src/api/types/ThoughtScenario.ts b/skyvern-ts/client/src/api/types/ThoughtScenario.ts new file mode 100644 index 00000000..871c252b --- /dev/null +++ b/skyvern-ts/client/src/api/types/ThoughtScenario.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +export const ThoughtScenario = { + GeneratePlan: "generate_plan", + UserGoalCheck: "user_goal_check", + FailureDescribe: "failure_describe", + Summarization: "summarization", + GenerateMetadata: "generate_metadata", + ExtractLoopValues: "extract_loop_values", + GenerateTaskInLoop: "generate_task_in_loop", + GenerateGeneralTask: "generate_general_task", +} as const; +export type ThoughtScenario = (typeof ThoughtScenario)[keyof typeof ThoughtScenario]; diff --git a/skyvern-ts/client/src/api/types/ThoughtType.ts b/skyvern-ts/client/src/api/types/ThoughtType.ts new file mode 100644 index 00000000..b307cb55 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ThoughtType.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +export const ThoughtType = { + Plan: "plan", + Metadata: "metadata", + UserGoalCheck: "user_goal_check", + InternalPlan: "internal_plan", + FailureDescribe: "failure_describe", +} as const; +export type ThoughtType = (typeof ThoughtType)[keyof typeof ThoughtType]; diff --git a/skyvern-ts/client/src/api/types/TotpCode.ts b/skyvern-ts/client/src/api/types/TotpCode.ts new file mode 100644 index 00000000..0def1889 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TotpCode.ts @@ -0,0 +1,32 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface TotpCode { + /** The identifier of the TOTP code. It can be the email address, phone number, or the identifier of the user. */ + totp_identifier: string; + /** The task_id the totp code is for. It can be the task_id of the task that the TOTP code is for. */ + task_id?: string; + /** The workflow ID the TOTP code is for. It can be the workflow ID of the workflow that the TOTP code is for. */ + workflow_id?: string; + /** The workflow run id that the TOTP code is for. It can be the workflow run id of the workflow run that the TOTP code is for. */ + workflow_run_id?: string; + /** An optional field. The source of the TOTP code. e.g. email, sms, etc. */ + source?: string; + /** The content of the TOTP code. It can be the email content that contains the TOTP code, or the sms message that contains the TOTP code. Skyvern will automatically extract the TOTP code from the content. */ + content: string; + /** The timestamp when the TOTP code expires */ + expired_at?: string; + /** The skyvern ID of the TOTP code. */ + totp_code_id: string; + /** The TOTP code extracted from the content. */ + code: string; + /** The ID of the organization that the TOTP code is for. */ + organization_id: string; + /** The timestamp when the TOTP code was created. */ + created_at: string; + /** The timestamp when the TOTP code was modified. */ + modified_at: string; + /** The type of the OTP code. */ + otp_type?: Skyvern.OtpType; +} diff --git a/skyvern-ts/client/src/api/types/TotpType.ts b/skyvern-ts/client/src/api/types/TotpType.ts new file mode 100644 index 00000000..4d5ed3c1 --- /dev/null +++ b/skyvern-ts/client/src/api/types/TotpType.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +/** Type of 2FA/TOTP method used. */ +export const TotpType = { + Authenticator: "authenticator", + Email: "email", + Text: "text", + None: "none", +} as const; +export type TotpType = (typeof TotpType)[keyof typeof TotpType]; diff --git a/skyvern-ts/client/src/api/types/UploadToS3Block.ts b/skyvern-ts/client/src/api/types/UploadToS3Block.ts new file mode 100644 index 00000000..b3f3b775 --- /dev/null +++ b/skyvern-ts/client/src/api/types/UploadToS3Block.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface UploadToS3Block { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + path?: string; +} diff --git a/skyvern-ts/client/src/api/types/UploadToS3BlockYaml.ts b/skyvern-ts/client/src/api/types/UploadToS3BlockYaml.ts new file mode 100644 index 00000000..387f81a8 --- /dev/null +++ b/skyvern-ts/client/src/api/types/UploadToS3BlockYaml.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface UploadToS3BlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + path?: string; +} diff --git a/skyvern-ts/client/src/api/types/UrlBlock.ts b/skyvern-ts/client/src/api/types/UrlBlock.ts new file mode 100644 index 00000000..83b90d49 --- /dev/null +++ b/skyvern-ts/client/src/api/types/UrlBlock.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface UrlBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + task_type?: string; + url: string; + title?: string; + engine?: Skyvern.RunEngine; + complete_criterion?: string; + terminate_criterion?: string; + navigation_goal?: string; + data_extraction_goal?: string; + data_schema?: UrlBlock.DataSchema; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameters?: Skyvern.UrlBlockParametersItem[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; + download_timeout?: number; +} + +export namespace UrlBlock { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/UrlBlockParametersItem.ts b/skyvern-ts/client/src/api/types/UrlBlockParametersItem.ts new file mode 100644 index 00000000..7800fa36 --- /dev/null +++ b/skyvern-ts/client/src/api/types/UrlBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type UrlBlockParametersItem = + | Skyvern.UrlBlockParametersItem.AwsSecret + | Skyvern.UrlBlockParametersItem.AzureSecret + | Skyvern.UrlBlockParametersItem.AzureVaultCredential + | Skyvern.UrlBlockParametersItem.BitwardenCreditCardData + | Skyvern.UrlBlockParametersItem.BitwardenLoginCredential + | Skyvern.UrlBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.UrlBlockParametersItem.Context + | Skyvern.UrlBlockParametersItem.Credential + | Skyvern.UrlBlockParametersItem.Onepassword + | Skyvern.UrlBlockParametersItem.Output + | Skyvern.UrlBlockParametersItem.Workflow; + +export namespace UrlBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/UrlBlockYaml.ts b/skyvern-ts/client/src/api/types/UrlBlockYaml.ts new file mode 100644 index 00000000..cbc47204 --- /dev/null +++ b/skyvern-ts/client/src/api/types/UrlBlockYaml.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface UrlBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + url: string; +} diff --git a/skyvern-ts/client/src/api/types/UserDefinedError.ts b/skyvern-ts/client/src/api/types/UserDefinedError.ts new file mode 100644 index 00000000..619c2b7e --- /dev/null +++ b/skyvern-ts/client/src/api/types/UserDefinedError.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface UserDefinedError { + error_code: string; + reasoning: string; + confidence_float: number; +} diff --git a/skyvern-ts/client/src/api/types/ValidationBlock.ts b/skyvern-ts/client/src/api/types/ValidationBlock.ts new file mode 100644 index 00000000..602c5f46 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ValidationBlock.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface ValidationBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + task_type?: string; + url?: string; + title?: string; + engine?: Skyvern.RunEngine; + complete_criterion?: string; + terminate_criterion?: string; + navigation_goal?: string; + data_extraction_goal?: string; + data_schema?: ValidationBlock.DataSchema; + error_code_mapping?: Record; + max_retries?: number; + max_steps_per_run?: number; + parameters?: Skyvern.ValidationBlockParametersItem[]; + complete_on_download?: boolean; + download_suffix?: string; + totp_verification_url?: string; + totp_identifier?: string; + cache_actions?: boolean; + complete_verification?: boolean; + include_action_history_in_verification?: boolean; + download_timeout?: number; +} + +export namespace ValidationBlock { + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/ValidationBlockParametersItem.ts b/skyvern-ts/client/src/api/types/ValidationBlockParametersItem.ts new file mode 100644 index 00000000..d0d48260 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ValidationBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type ValidationBlockParametersItem = + | Skyvern.ValidationBlockParametersItem.AwsSecret + | Skyvern.ValidationBlockParametersItem.AzureSecret + | Skyvern.ValidationBlockParametersItem.AzureVaultCredential + | Skyvern.ValidationBlockParametersItem.BitwardenCreditCardData + | Skyvern.ValidationBlockParametersItem.BitwardenLoginCredential + | Skyvern.ValidationBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.ValidationBlockParametersItem.Context + | Skyvern.ValidationBlockParametersItem.Credential + | Skyvern.ValidationBlockParametersItem.Onepassword + | Skyvern.ValidationBlockParametersItem.Output + | Skyvern.ValidationBlockParametersItem.Workflow; + +export namespace ValidationBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/ValidationBlockYaml.ts b/skyvern-ts/client/src/api/types/ValidationBlockYaml.ts new file mode 100644 index 00000000..bf20f1ee --- /dev/null +++ b/skyvern-ts/client/src/api/types/ValidationBlockYaml.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface ValidationBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + complete_criterion?: string; + terminate_criterion?: string; + error_code_mapping?: Record; + parameter_keys?: string[]; + disable_cache?: boolean; +} diff --git a/skyvern-ts/client/src/api/types/ValidationError.ts b/skyvern-ts/client/src/api/types/ValidationError.ts new file mode 100644 index 00000000..211953b6 --- /dev/null +++ b/skyvern-ts/client/src/api/types/ValidationError.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface ValidationError { + loc: ValidationError.Loc.Item[]; + msg: string; + type: string; +} + +export namespace ValidationError { + export type Loc = Loc.Item[]; + + export namespace Loc { + export type Item = string | number; + } +} diff --git a/skyvern-ts/client/src/api/types/WaitBlock.ts b/skyvern-ts/client/src/api/types/WaitBlock.ts new file mode 100644 index 00000000..f7343f72 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WaitBlock.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WaitBlock { + label: string; + output_parameter: Skyvern.OutputParameter; + continue_on_failure?: boolean; + model?: Record; + disable_cache?: boolean; + wait_sec: number; + parameters?: Skyvern.WaitBlockParametersItem[]; +} diff --git a/skyvern-ts/client/src/api/types/WaitBlockParametersItem.ts b/skyvern-ts/client/src/api/types/WaitBlockParametersItem.ts new file mode 100644 index 00000000..3e4d5dc8 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WaitBlockParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type WaitBlockParametersItem = + | Skyvern.WaitBlockParametersItem.AwsSecret + | Skyvern.WaitBlockParametersItem.AzureSecret + | Skyvern.WaitBlockParametersItem.AzureVaultCredential + | Skyvern.WaitBlockParametersItem.BitwardenCreditCardData + | Skyvern.WaitBlockParametersItem.BitwardenLoginCredential + | Skyvern.WaitBlockParametersItem.BitwardenSensitiveInformation + | Skyvern.WaitBlockParametersItem.Context + | Skyvern.WaitBlockParametersItem.Credential + | Skyvern.WaitBlockParametersItem.Onepassword + | Skyvern.WaitBlockParametersItem.Output + | Skyvern.WaitBlockParametersItem.Workflow; + +export namespace WaitBlockParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/WaitBlockYaml.ts b/skyvern-ts/client/src/api/types/WaitBlockYaml.ts new file mode 100644 index 00000000..5a6ffd12 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WaitBlockYaml.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface WaitBlockYaml { + label: string; + continue_on_failure?: boolean; + model?: Record; + wait_sec?: number; +} diff --git a/skyvern-ts/client/src/api/types/Workflow.ts b/skyvern-ts/client/src/api/types/Workflow.ts new file mode 100644 index 00000000..2d71599c --- /dev/null +++ b/skyvern-ts/client/src/api/types/Workflow.ts @@ -0,0 +1,31 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface Workflow { + workflow_id: string; + organization_id: string; + title: string; + workflow_permanent_id: string; + version: number; + is_saved_task: boolean; + description?: string; + workflow_definition: Skyvern.WorkflowDefinition; + proxy_location?: Skyvern.ProxyLocation; + webhook_callback_url?: string; + totp_verification_url?: string; + totp_identifier?: string; + persist_browser_session?: boolean; + model?: Record; + status?: Skyvern.WorkflowStatus; + max_screenshot_scrolls?: number; + extra_http_headers?: Record; + run_with?: string; + ai_fallback?: boolean; + cache_key?: string; + run_sequentially?: boolean; + sequential_key?: string; + created_at: string; + modified_at: string; + deleted_at?: string; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowCreateYamlRequest.ts b/skyvern-ts/client/src/api/types/WorkflowCreateYamlRequest.ts new file mode 100644 index 00000000..8d9c2745 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowCreateYamlRequest.ts @@ -0,0 +1,24 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowCreateYamlRequest { + title: string; + description?: string; + proxy_location?: Skyvern.ProxyLocation; + webhook_callback_url?: string; + totp_verification_url?: string; + totp_identifier?: string; + persist_browser_session?: boolean; + model?: Record; + workflow_definition: Skyvern.WorkflowDefinitionYaml; + is_saved_task?: boolean; + max_screenshot_scrolls?: number; + extra_http_headers?: Record; + status?: Skyvern.WorkflowStatus; + run_with?: string; + ai_fallback?: boolean; + cache_key?: string; + run_sequentially?: boolean; + sequential_key?: string; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowDefinition.ts b/skyvern-ts/client/src/api/types/WorkflowDefinition.ts new file mode 100644 index 00000000..da5dfa41 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowDefinition.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowDefinition { + parameters: Skyvern.WorkflowDefinitionParametersItem[]; + blocks: Skyvern.WorkflowDefinitionBlocksItem[]; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowDefinitionBlocksItem.ts b/skyvern-ts/client/src/api/types/WorkflowDefinitionBlocksItem.ts new file mode 100644 index 00000000..5477f27f --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowDefinitionBlocksItem.ts @@ -0,0 +1,107 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type WorkflowDefinitionBlocksItem = + | Skyvern.WorkflowDefinitionBlocksItem.Action + | Skyvern.WorkflowDefinitionBlocksItem.Code + | Skyvern.WorkflowDefinitionBlocksItem.DownloadToS3 + | Skyvern.WorkflowDefinitionBlocksItem.Extraction + | Skyvern.WorkflowDefinitionBlocksItem.FileDownload + | Skyvern.WorkflowDefinitionBlocksItem.FileUpload + | Skyvern.WorkflowDefinitionBlocksItem.FileUrlParser + | Skyvern.WorkflowDefinitionBlocksItem.ForLoop + | Skyvern.WorkflowDefinitionBlocksItem.GotoUrl + | Skyvern.WorkflowDefinitionBlocksItem.HttpRequest + | Skyvern.WorkflowDefinitionBlocksItem.Login + | Skyvern.WorkflowDefinitionBlocksItem.Navigation + | Skyvern.WorkflowDefinitionBlocksItem.PdfParser + | Skyvern.WorkflowDefinitionBlocksItem.SendEmail + | Skyvern.WorkflowDefinitionBlocksItem.Task + | Skyvern.WorkflowDefinitionBlocksItem.TaskV2 + | Skyvern.WorkflowDefinitionBlocksItem.TextPrompt + | Skyvern.WorkflowDefinitionBlocksItem.UploadToS3 + | Skyvern.WorkflowDefinitionBlocksItem.Validation + | Skyvern.WorkflowDefinitionBlocksItem.Wait; + +export namespace WorkflowDefinitionBlocksItem { + export interface Action extends Skyvern.ActionBlock { + block_type: "action"; + } + + export interface Code extends Skyvern.CodeBlock { + block_type: "code"; + } + + export interface DownloadToS3 extends Skyvern.DownloadToS3Block { + block_type: "download_to_s3"; + } + + export interface Extraction extends Skyvern.ExtractionBlock { + block_type: "extraction"; + } + + export interface FileDownload extends Skyvern.FileDownloadBlock { + block_type: "file_download"; + } + + export interface FileUpload extends Skyvern.FileUploadBlock { + block_type: "file_upload"; + } + + export interface FileUrlParser extends Skyvern.FileParserBlock { + block_type: "file_url_parser"; + } + + export interface ForLoop extends Skyvern.ForLoopBlock { + block_type: "for_loop"; + } + + export interface GotoUrl extends Skyvern.UrlBlock { + block_type: "goto_url"; + } + + export interface HttpRequest extends Skyvern.HttpRequestBlock { + block_type: "http_request"; + } + + export interface Login extends Skyvern.LoginBlock { + block_type: "login"; + } + + export interface Navigation extends Skyvern.NavigationBlock { + block_type: "navigation"; + } + + export interface PdfParser extends Skyvern.PdfParserBlock { + block_type: "pdf_parser"; + } + + export interface SendEmail extends Skyvern.SendEmailBlock { + block_type: "send_email"; + } + + export interface Task extends Skyvern.TaskBlock { + block_type: "task"; + } + + export interface TaskV2 extends Skyvern.TaskV2Block { + block_type: "task_v2"; + } + + export interface TextPrompt extends Skyvern.TextPromptBlock { + block_type: "text_prompt"; + } + + export interface UploadToS3 extends Skyvern.UploadToS3Block { + block_type: "upload_to_s3"; + } + + export interface Validation extends Skyvern.ValidationBlock { + block_type: "validation"; + } + + export interface Wait extends Skyvern.WaitBlock { + block_type: "wait"; + } +} diff --git a/skyvern-ts/client/src/api/types/WorkflowDefinitionParametersItem.ts b/skyvern-ts/client/src/api/types/WorkflowDefinitionParametersItem.ts new file mode 100644 index 00000000..b97b117d --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowDefinitionParametersItem.ts @@ -0,0 +1,62 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type WorkflowDefinitionParametersItem = + | Skyvern.WorkflowDefinitionParametersItem.AwsSecret + | Skyvern.WorkflowDefinitionParametersItem.AzureSecret + | Skyvern.WorkflowDefinitionParametersItem.AzureVaultCredential + | Skyvern.WorkflowDefinitionParametersItem.BitwardenCreditCardData + | Skyvern.WorkflowDefinitionParametersItem.BitwardenLoginCredential + | Skyvern.WorkflowDefinitionParametersItem.BitwardenSensitiveInformation + | Skyvern.WorkflowDefinitionParametersItem.Context + | Skyvern.WorkflowDefinitionParametersItem.Credential + | Skyvern.WorkflowDefinitionParametersItem.Onepassword + | Skyvern.WorkflowDefinitionParametersItem.Output + | Skyvern.WorkflowDefinitionParametersItem.Workflow; + +export namespace WorkflowDefinitionParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameter { + parameter_type: "aws_secret"; + } + + export interface AzureSecret extends Skyvern.AzureSecretParameter { + parameter_type: "azure_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameter { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameter { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameter { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameter { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameter { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameter { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameter { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameter { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameter { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/WorkflowDefinitionYaml.ts b/skyvern-ts/client/src/api/types/WorkflowDefinitionYaml.ts new file mode 100644 index 00000000..4796c5d2 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowDefinitionYaml.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowDefinitionYaml { + parameters: Skyvern.WorkflowDefinitionYamlParametersItem[]; + blocks: Skyvern.WorkflowDefinitionYamlBlocksItem[]; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowDefinitionYamlBlocksItem.ts b/skyvern-ts/client/src/api/types/WorkflowDefinitionYamlBlocksItem.ts new file mode 100644 index 00000000..d424f238 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowDefinitionYamlBlocksItem.ts @@ -0,0 +1,107 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type WorkflowDefinitionYamlBlocksItem = + | Skyvern.WorkflowDefinitionYamlBlocksItem.Action + | Skyvern.WorkflowDefinitionYamlBlocksItem.Code + | Skyvern.WorkflowDefinitionYamlBlocksItem.DownloadToS3 + | Skyvern.WorkflowDefinitionYamlBlocksItem.Extraction + | Skyvern.WorkflowDefinitionYamlBlocksItem.FileDownload + | Skyvern.WorkflowDefinitionYamlBlocksItem.FileUpload + | Skyvern.WorkflowDefinitionYamlBlocksItem.FileUrlParser + | Skyvern.WorkflowDefinitionYamlBlocksItem.ForLoop + | Skyvern.WorkflowDefinitionYamlBlocksItem.GotoUrl + | Skyvern.WorkflowDefinitionYamlBlocksItem.HttpRequest + | Skyvern.WorkflowDefinitionYamlBlocksItem.Login + | Skyvern.WorkflowDefinitionYamlBlocksItem.Navigation + | Skyvern.WorkflowDefinitionYamlBlocksItem.PdfParser + | Skyvern.WorkflowDefinitionYamlBlocksItem.SendEmail + | Skyvern.WorkflowDefinitionYamlBlocksItem.Task + | Skyvern.WorkflowDefinitionYamlBlocksItem.TaskV2 + | Skyvern.WorkflowDefinitionYamlBlocksItem.TextPrompt + | Skyvern.WorkflowDefinitionYamlBlocksItem.UploadToS3 + | Skyvern.WorkflowDefinitionYamlBlocksItem.Validation + | Skyvern.WorkflowDefinitionYamlBlocksItem.Wait; + +export namespace WorkflowDefinitionYamlBlocksItem { + export interface Action extends Skyvern.ActionBlockYaml { + block_type: "action"; + } + + export interface Code extends Skyvern.CodeBlockYaml { + block_type: "code"; + } + + export interface DownloadToS3 extends Skyvern.DownloadToS3BlockYaml { + block_type: "download_to_s3"; + } + + export interface Extraction extends Skyvern.ExtractionBlockYaml { + block_type: "extraction"; + } + + export interface FileDownload extends Skyvern.FileDownloadBlockYaml { + block_type: "file_download"; + } + + export interface FileUpload extends Skyvern.FileUploadBlockYaml { + block_type: "file_upload"; + } + + export interface FileUrlParser extends Skyvern.FileParserBlockYaml { + block_type: "file_url_parser"; + } + + export interface ForLoop extends Skyvern.ForLoopBlockYaml { + block_type: "for_loop"; + } + + export interface GotoUrl extends Skyvern.UrlBlockYaml { + block_type: "goto_url"; + } + + export interface HttpRequest extends Skyvern.HttpRequestBlockYaml { + block_type: "http_request"; + } + + export interface Login extends Skyvern.LoginBlockYaml { + block_type: "login"; + } + + export interface Navigation extends Skyvern.NavigationBlockYaml { + block_type: "navigation"; + } + + export interface PdfParser extends Skyvern.PdfParserBlockYaml { + block_type: "pdf_parser"; + } + + export interface SendEmail extends Skyvern.SendEmailBlockYaml { + block_type: "send_email"; + } + + export interface Task extends Skyvern.TaskBlockYaml { + block_type: "task"; + } + + export interface TaskV2 extends Skyvern.TaskV2BlockYaml { + block_type: "task_v2"; + } + + export interface TextPrompt extends Skyvern.TextPromptBlockYaml { + block_type: "text_prompt"; + } + + export interface UploadToS3 extends Skyvern.UploadToS3BlockYaml { + block_type: "upload_to_s3"; + } + + export interface Validation extends Skyvern.ValidationBlockYaml { + block_type: "validation"; + } + + export interface Wait extends Skyvern.WaitBlockYaml { + block_type: "wait"; + } +} diff --git a/skyvern-ts/client/src/api/types/WorkflowDefinitionYamlParametersItem.ts b/skyvern-ts/client/src/api/types/WorkflowDefinitionYamlParametersItem.ts new file mode 100644 index 00000000..794ba7d3 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowDefinitionYamlParametersItem.ts @@ -0,0 +1,57 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export type WorkflowDefinitionYamlParametersItem = + | Skyvern.WorkflowDefinitionYamlParametersItem.AwsSecret + | Skyvern.WorkflowDefinitionYamlParametersItem.AzureVaultCredential + | Skyvern.WorkflowDefinitionYamlParametersItem.BitwardenCreditCardData + | Skyvern.WorkflowDefinitionYamlParametersItem.BitwardenLoginCredential + | Skyvern.WorkflowDefinitionYamlParametersItem.BitwardenSensitiveInformation + | Skyvern.WorkflowDefinitionYamlParametersItem.Context + | Skyvern.WorkflowDefinitionYamlParametersItem.Credential + | Skyvern.WorkflowDefinitionYamlParametersItem.Onepassword + | Skyvern.WorkflowDefinitionYamlParametersItem.Output + | Skyvern.WorkflowDefinitionYamlParametersItem.Workflow; + +export namespace WorkflowDefinitionYamlParametersItem { + export interface AwsSecret extends Skyvern.AwsSecretParameterYaml { + parameter_type: "aws_secret"; + } + + export interface AzureVaultCredential extends Skyvern.AzureVaultCredentialParameterYaml { + parameter_type: "azure_vault_credential"; + } + + export interface BitwardenCreditCardData extends Skyvern.BitwardenCreditCardDataParameterYaml { + parameter_type: "bitwarden_credit_card_data"; + } + + export interface BitwardenLoginCredential extends Skyvern.BitwardenLoginCredentialParameterYaml { + parameter_type: "bitwarden_login_credential"; + } + + export interface BitwardenSensitiveInformation extends Skyvern.BitwardenSensitiveInformationParameterYaml { + parameter_type: "bitwarden_sensitive_information"; + } + + export interface Context extends Skyvern.ContextParameterYaml { + parameter_type: "context"; + } + + export interface Credential extends Skyvern.CredentialParameterYaml { + parameter_type: "credential"; + } + + export interface Onepassword extends Skyvern.OnePasswordCredentialParameterYaml { + parameter_type: "onepassword"; + } + + export interface Output extends Skyvern.OutputParameterYaml { + parameter_type: "output"; + } + + export interface Workflow extends Skyvern.WorkflowParameterYaml { + parameter_type: "workflow"; + } +} diff --git a/skyvern-ts/client/src/api/types/WorkflowParameter.ts b/skyvern-ts/client/src/api/types/WorkflowParameter.ts new file mode 100644 index 00000000..74f9bd91 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowParameter.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowParameter { + key: string; + description?: string; + workflow_parameter_id: string; + workflow_parameter_type: Skyvern.WorkflowParameterType; + workflow_id: string; + default_value?: WorkflowParameter.DefaultValue; + created_at: string; + modified_at: string; + deleted_at?: string; +} + +export namespace WorkflowParameter { + export type DefaultValue = string | number | number | boolean | Record | unknown[]; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowParameterType.ts b/skyvern-ts/client/src/api/types/WorkflowParameterType.ts new file mode 100644 index 00000000..ba03a573 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowParameterType.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export const WorkflowParameterType = { + String: "string", + Integer: "integer", + Float: "float", + Boolean: "boolean", + Json: "json", + FileUrl: "file_url", + CredentialId: "credential_id", +} as const; +export type WorkflowParameterType = (typeof WorkflowParameterType)[keyof typeof WorkflowParameterType]; diff --git a/skyvern-ts/client/src/api/types/WorkflowParameterYaml.ts b/skyvern-ts/client/src/api/types/WorkflowParameterYaml.ts new file mode 100644 index 00000000..b32df407 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowParameterYaml.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowParameterYaml { + key: string; + description?: string; + workflow_parameter_type: Skyvern.WorkflowParameterType; + default_value?: WorkflowParameterYaml.DefaultValue; +} + +export namespace WorkflowParameterYaml { + export type DefaultValue = string | number | number | boolean | Record | unknown[]; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowRequest.ts b/skyvern-ts/client/src/api/types/WorkflowRequest.ts new file mode 100644 index 00000000..3c94ce56 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowRequest.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowRequest { + /** Workflow definition in JSON format */ + json_definition?: Skyvern.WorkflowCreateYamlRequest; + /** Workflow definition in YAML format */ + yaml_definition?: string; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowRunBlock.ts b/skyvern-ts/client/src/api/types/WorkflowRunBlock.ts new file mode 100644 index 00000000..26811d33 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowRunBlock.ts @@ -0,0 +1,45 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowRunBlock { + workflow_run_block_id: string; + block_workflow_run_id?: string; + workflow_run_id: string; + organization_id: string; + description?: string; + parent_workflow_run_block_id?: string; + block_type: Skyvern.BlockType; + label?: string; + status?: string; + output?: WorkflowRunBlock.Output; + continue_on_failure?: boolean; + failure_reason?: string; + engine?: Skyvern.RunEngine; + task_id?: string; + url?: string; + navigation_goal?: string; + navigation_payload?: WorkflowRunBlock.NavigationPayload; + data_extraction_goal?: string; + data_schema?: WorkflowRunBlock.DataSchema; + terminate_criterion?: string; + complete_criterion?: string; + actions?: Skyvern.Action[]; + created_at: string; + modified_at: string; + include_action_history_in_verification?: boolean; + duration?: number; + loop_values?: unknown[]; + current_value?: string; + current_index?: number; + recipients?: string[]; + attachments?: string[]; + subject?: string; + body?: string; +} + +export namespace WorkflowRunBlock { + export type Output = Record | unknown[] | string; + export type NavigationPayload = Record | unknown[] | string; + export type DataSchema = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowRunRequest.ts b/skyvern-ts/client/src/api/types/WorkflowRunRequest.ts new file mode 100644 index 00000000..8198f10d --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowRunRequest.ts @@ -0,0 +1,59 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowRunRequest { + /** ID of the workflow to run. Workflow ID starts with `wpid_`. */ + workflow_id: string; + /** Parameters to pass to the workflow */ + parameters?: Record; + /** The title for this workflow run */ + title?: string; + /** + * Geographic Proxy location to route the browser traffic through. This is only available in Skyvern Cloud. + * + * Available geotargeting options: + * - RESIDENTIAL: the default value. Skyvern Cloud uses a random US residential proxy. + * - RESIDENTIAL_ES: Spain + * - RESIDENTIAL_IE: Ireland + * - RESIDENTIAL_GB: United Kingdom + * - RESIDENTIAL_IN: India + * - RESIDENTIAL_JP: Japan + * - RESIDENTIAL_FR: France + * - RESIDENTIAL_DE: Germany + * - RESIDENTIAL_NZ: New Zealand + * - RESIDENTIAL_ZA: South Africa + * - RESIDENTIAL_AR: Argentina + * - RESIDENTIAL_AU: Australia + * - RESIDENTIAL_ISP: ISP proxy + * - US-CA: California + * - US-NY: New York + * - US-TX: Texas + * - US-FL: Florida + * - US-WA: Washington + * - NONE: No proxy + */ + proxy_location?: Skyvern.ProxyLocation; + /** URL to send workflow status updates to after a run is finished. Refer to https://www.skyvern.com/docs/running-tasks/webhooks-faq for webhook questions. */ + webhook_url?: string; + /** + * URL that serves TOTP/2FA/MFA codes for Skyvern to use during the workflow run. Refer to https://www.skyvern.com/docs/credentials/totp#option-2-get-code-from-your-endpoint for more details. + */ + totp_url?: string; + /** + * Identifier for the TOTP/2FA/MFA code when the code is pushed to Skyvern. Refer to https://www.skyvern.com/docs/credentials/totp#option-3-push-code-to-skyvern for more details. + */ + totp_identifier?: string; + /** ID of a Skyvern browser session to reuse, having it continue from the current screen state */ + browser_session_id?: string; + /** The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot. */ + max_screenshot_scrolls?: number; + /** The extra HTTP headers for the requests in browser. */ + extra_http_headers?: Record; + /** The CDP address for the workflow run. */ + browser_address?: string; + /** Whether to fallback to AI if the workflow run fails. */ + ai_fallback?: boolean; + /** Whether to run the workflow with agent or code. */ + run_with?: string; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowRunResponse.ts b/skyvern-ts/client/src/api/types/WorkflowRunResponse.ts new file mode 100644 index 00000000..77d08e37 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowRunResponse.ts @@ -0,0 +1,53 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowRunResponse { + /** Unique identifier for this run. Run ID starts with `tsk_` for task runs and `wr_` for workflow runs. */ + run_id: string; + /** Current status of the run */ + status: Skyvern.RunStatus; + /** Output data from the run, if any. Format/schema depends on the data extracted by the run. */ + output?: WorkflowRunResponse.Output; + /** List of files downloaded during the run */ + downloaded_files?: Skyvern.FileInfo[]; + /** URL to the recording of the run */ + recording_url?: string; + /** List of last n screenshot URLs in reverse chronological order - the first one the list is the latest screenshot. */ + screenshot_urls?: string[]; + /** Reason for failure if the run failed or terminated */ + failure_reason?: string; + /** Timestamp when this run was created */ + created_at: string; + /** Timestamp when this run was last modified */ + modified_at: string; + /** Timestamp when this run was queued */ + queued_at?: string; + /** Timestamp when this run started execution */ + started_at?: string; + /** Timestamp when this run finished */ + finished_at?: string; + /** URL to the application UI where the run can be viewed */ + app_url?: string; + /** ID of the Skyvern persistent browser session used for this run */ + browser_session_id?: string; + /** The maximum number of scrolls for the post action screenshot. When it's None or 0, it takes the current viewpoint screenshot */ + max_screenshot_scrolls?: number; + /** The script run result */ + script_run?: Skyvern.ScriptRunResponse; + /** The errors for the run */ + errors?: Record[]; + /** Whether the workflow run was executed with agent or code */ + run_with?: string; + /** Whether to fallback to AI if code run fails. */ + ai_fallback?: boolean; + /** The original request parameters used to start this workflow run */ + run_request?: Skyvern.WorkflowRunRequest; +} + +export namespace WorkflowRunResponse { + /** + * Output data from the run, if any. Format/schema depends on the data extracted by the run. + */ + export type Output = Record | unknown[] | string; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowRunTimeline.ts b/skyvern-ts/client/src/api/types/WorkflowRunTimeline.ts new file mode 100644 index 00000000..14120404 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowRunTimeline.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as Skyvern from "../index.js"; + +export interface WorkflowRunTimeline { + type: Skyvern.WorkflowRunTimelineType; + block?: Skyvern.WorkflowRunBlock; + thought?: Skyvern.Thought; + children?: Skyvern.WorkflowRunTimeline[]; + created_at: string; + modified_at: string; +} diff --git a/skyvern-ts/client/src/api/types/WorkflowRunTimelineType.ts b/skyvern-ts/client/src/api/types/WorkflowRunTimelineType.ts new file mode 100644 index 00000000..59cdaa61 --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowRunTimelineType.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export const WorkflowRunTimelineType = { + Thought: "thought", + Block: "block", +} as const; +export type WorkflowRunTimelineType = (typeof WorkflowRunTimelineType)[keyof typeof WorkflowRunTimelineType]; diff --git a/skyvern-ts/client/src/api/types/WorkflowStatus.ts b/skyvern-ts/client/src/api/types/WorkflowStatus.ts new file mode 100644 index 00000000..3a98927d --- /dev/null +++ b/skyvern-ts/client/src/api/types/WorkflowStatus.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export const WorkflowStatus = { + Published: "published", + Draft: "draft", + AutoGenerated: "auto_generated", +} as const; +export type WorkflowStatus = (typeof WorkflowStatus)[keyof typeof WorkflowStatus]; diff --git a/skyvern-ts/client/src/api/types/index.ts b/skyvern-ts/client/src/api/types/index.ts new file mode 100644 index 00000000..77105f65 --- /dev/null +++ b/skyvern-ts/client/src/api/types/index.ts @@ -0,0 +1,134 @@ +export * from "./Action.js"; +export * from "./ActionBlock.js"; +export * from "./ActionBlockParametersItem.js"; +export * from "./ActionBlockYaml.js"; +export * from "./ActionStatus.js"; +export * from "./ActionType.js"; +export * from "./Artifact.js"; +export * from "./ArtifactType.js"; +export * from "./AwsSecretParameter.js"; +export * from "./AwsSecretParameterYaml.js"; +export * from "./AzureSecretParameter.js"; +export * from "./AzureVaultCredentialParameter.js"; +export * from "./AzureVaultCredentialParameterYaml.js"; +export * from "./BitwardenCreditCardDataParameter.js"; +export * from "./BitwardenCreditCardDataParameterYaml.js"; +export * from "./BitwardenLoginCredentialParameter.js"; +export * from "./BitwardenLoginCredentialParameterYaml.js"; +export * from "./BitwardenSensitiveInformationParameter.js"; +export * from "./BitwardenSensitiveInformationParameterYaml.js"; +export * from "./BlockType.js"; +export * from "./BrowserSessionResponse.js"; +export * from "./CodeBlock.js"; +export * from "./CodeBlockParametersItem.js"; +export * from "./CodeBlockYaml.js"; +export * from "./ContextParameter.js"; +export * from "./ContextParameterSource.js"; +export * from "./ContextParameterYaml.js"; +export * from "./CreateScriptResponse.js"; +export * from "./CredentialParameter.js"; +export * from "./CredentialParameterYaml.js"; +export * from "./CredentialResponse.js"; +export * from "./CredentialTypeOutput.js"; +export * from "./CreditCardCredentialResponse.js"; +export * from "./DownloadToS3Block.js"; +export * from "./DownloadToS3BlockYaml.js"; +export * from "./ExtractionBlock.js"; +export * from "./ExtractionBlockParametersItem.js"; +export * from "./ExtractionBlockYaml.js"; +export * from "./FileDownloadBlock.js"; +export * from "./FileDownloadBlockParametersItem.js"; +export * from "./FileDownloadBlockYaml.js"; +export * from "./FileEncoding.js"; +export * from "./FileInfo.js"; +export * from "./FileNode.js"; +export * from "./FileParserBlock.js"; +export * from "./FileParserBlockYaml.js"; +export * from "./FileStorageType.js"; +export * from "./FileType.js"; +export * from "./FileUploadBlock.js"; +export * from "./FileUploadBlockYaml.js"; +export * from "./ForLoopBlock.js"; +export * from "./ForLoopBlockLoopBlocksItem.js"; +export * from "./ForLoopBlockLoopOver.js"; +export * from "./ForLoopBlockYaml.js"; +export * from "./ForLoopBlockYamlLoopBlocksItem.js"; +export * from "./GetRunResponse.js"; +export * from "./HttpRequestBlock.js"; +export * from "./HttpRequestBlockParametersItem.js"; +export * from "./HttpRequestBlockYaml.js"; +export * from "./HttpValidationError.js"; +export * from "./InputOrSelectContext.js"; +export * from "./LoginBlock.js"; +export * from "./LoginBlockParametersItem.js"; +export * from "./LoginBlockYaml.js"; +export * from "./NavigationBlock.js"; +export * from "./NavigationBlockParametersItem.js"; +export * from "./NavigationBlockYaml.js"; +export * from "./NonEmptyCreditCardCredential.js"; +export * from "./NonEmptyPasswordCredential.js"; +export * from "./OnePasswordCredentialParameter.js"; +export * from "./OnePasswordCredentialParameterYaml.js"; +export * from "./OtpType.js"; +export * from "./OutputParameter.js"; +export * from "./OutputParameterYaml.js"; +export * from "./PasswordCredentialResponse.js"; +export * from "./PdfParserBlock.js"; +export * from "./PdfParserBlockYaml.js"; +export * from "./ProxyLocation.js"; +export * from "./RunEngine.js"; +export * from "./RunStatus.js"; +export * from "./Script.js"; +export * from "./ScriptFileCreate.js"; +export * from "./ScriptRunResponse.js"; +export * from "./SelectOption.js"; +export * from "./SendEmailBlock.js"; +export * from "./SendEmailBlockYaml.js"; +export * from "./SkyvernForgeSdkSchemasCredentialsCredentialType.js"; +export * from "./SkyvernSchemasRunBlocksCredentialType.js"; +export * from "./TaskBlock.js"; +export * from "./TaskBlockParametersItem.js"; +export * from "./TaskBlockYaml.js"; +export * from "./TaskRunRequest.js"; +export * from "./TaskRunResponse.js"; +export * from "./TaskV2Block.js"; +export * from "./TaskV2BlockYaml.js"; +export * from "./TextPromptBlock.js"; +export * from "./TextPromptBlockParametersItem.js"; +export * from "./TextPromptBlockYaml.js"; +export * from "./Thought.js"; +export * from "./ThoughtScenario.js"; +export * from "./ThoughtType.js"; +export * from "./TotpCode.js"; +export * from "./TotpType.js"; +export * from "./UploadToS3Block.js"; +export * from "./UploadToS3BlockYaml.js"; +export * from "./UrlBlock.js"; +export * from "./UrlBlockParametersItem.js"; +export * from "./UrlBlockYaml.js"; +export * from "./UserDefinedError.js"; +export * from "./ValidationBlock.js"; +export * from "./ValidationBlockParametersItem.js"; +export * from "./ValidationBlockYaml.js"; +export * from "./ValidationError.js"; +export * from "./WaitBlock.js"; +export * from "./WaitBlockParametersItem.js"; +export * from "./WaitBlockYaml.js"; +export * from "./Workflow.js"; +export * from "./WorkflowCreateYamlRequest.js"; +export * from "./WorkflowDefinition.js"; +export * from "./WorkflowDefinitionBlocksItem.js"; +export * from "./WorkflowDefinitionParametersItem.js"; +export * from "./WorkflowDefinitionYaml.js"; +export * from "./WorkflowDefinitionYamlBlocksItem.js"; +export * from "./WorkflowDefinitionYamlParametersItem.js"; +export * from "./WorkflowParameter.js"; +export * from "./WorkflowParameterType.js"; +export * from "./WorkflowParameterYaml.js"; +export * from "./WorkflowRequest.js"; +export * from "./WorkflowRunBlock.js"; +export * from "./WorkflowRunRequest.js"; +export * from "./WorkflowRunResponse.js"; +export * from "./WorkflowRunTimeline.js"; +export * from "./WorkflowRunTimelineType.js"; +export * from "./WorkflowStatus.js"; diff --git a/skyvern-ts/client/src/core/fetcher/APIResponse.ts b/skyvern-ts/client/src/core/fetcher/APIResponse.ts new file mode 100644 index 00000000..97ab83c2 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/APIResponse.ts @@ -0,0 +1,23 @@ +import type { RawResponse } from "./RawResponse.js"; + +/** + * The response of an API call. + * It is a successful response or a failed response. + */ +export type APIResponse = SuccessfulResponse | FailedResponse; + +export interface SuccessfulResponse { + ok: true; + body: T; + /** + * @deprecated Use `rawResponse` instead + */ + headers?: Record; + rawResponse: RawResponse; +} + +export interface FailedResponse { + ok: false; + error: T; + rawResponse: RawResponse; +} diff --git a/skyvern-ts/client/src/core/fetcher/BinaryResponse.ts b/skyvern-ts/client/src/core/fetcher/BinaryResponse.ts new file mode 100644 index 00000000..4b4d0e89 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/BinaryResponse.ts @@ -0,0 +1,36 @@ +import type { ResponseWithBody } from "./ResponseWithBody.js"; + +export type BinaryResponse = { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bodyUsed) */ + bodyUsed: boolean; + /** + * Returns a ReadableStream of the response body. + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/body) + */ + stream: () => ReadableStream; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/arrayBuffer) */ + arrayBuffer: () => Promise; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/blob) */ + blob: () => Promise; + /** + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bytes) + * Some versions of the Fetch API may not support this method. + */ + bytes?(): Promise; +}; + +export function getBinaryResponse(response: ResponseWithBody): BinaryResponse { + const binaryResponse: BinaryResponse = { + get bodyUsed() { + return response.bodyUsed; + }, + stream: () => response.body, + arrayBuffer: response.arrayBuffer.bind(response), + blob: response.blob.bind(response), + }; + if ("bytes" in response && typeof response.bytes === "function") { + binaryResponse.bytes = response.bytes.bind(response); + } + + return binaryResponse; +} diff --git a/skyvern-ts/client/src/core/fetcher/EndpointMetadata.ts b/skyvern-ts/client/src/core/fetcher/EndpointMetadata.ts new file mode 100644 index 00000000..998d68f5 --- /dev/null +++ b/skyvern-ts/client/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/skyvern-ts/client/src/core/fetcher/EndpointSupplier.ts b/skyvern-ts/client/src/core/fetcher/EndpointSupplier.ts new file mode 100644 index 00000000..8079841c --- /dev/null +++ b/skyvern-ts/client/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/skyvern-ts/client/src/core/fetcher/Fetcher.ts b/skyvern-ts/client/src/core/fetcher/Fetcher.ts new file mode 100644 index 00000000..202e134f --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/Fetcher.ts @@ -0,0 +1,165 @@ +import { toJson } from "../json.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 { makeRequest } from "./makeRequest.js"; +import { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; +import { requestWithRetries } from "./requestWithRetries.js"; + +export type FetchFunction = (args: Fetcher.Args) => Promise>; + +export declare namespace Fetcher { + export interface Args { + url: string; + method: string; + contentType?: string; + headers?: Record | null | undefined>; + queryParameters?: Record; + body?: unknown; + timeoutMs?: number; + maxRetries?: number; + withCredentials?: boolean; + abortSignal?: AbortSignal; + requestType?: "json" | "file" | "bytes"; + responseType?: "json" | "blob" | "sse" | "streaming" | "text" | "arrayBuffer" | "binary-response"; + duplex?: "half"; + endpointMetadata?: EndpointMetadata; + } + + export type Error = FailedStatusCodeError | NonJsonError | TimeoutError | UnknownError; + + export interface FailedStatusCodeError { + reason: "status-code"; + statusCode: number; + body: unknown; + } + + export interface NonJsonError { + reason: "non-json"; + statusCode: number; + rawBody: string; + } + + export interface TimeoutError { + reason: "timeout"; + } + + export interface UnknownError { + reason: "unknown"; + errorMessage: string; + } +} + +async function getHeaders(args: Fetcher.Args): Promise> { + const newHeaders: Record = {}; + if (args.body !== undefined && args.contentType != null) { + newHeaders["Content-Type"] = args.contentType; + } + + if (args.headers == null) { + return newHeaders; + } + + for (const [key, value] of Object.entries(args.headers)) { + const result = await EndpointSupplier.get(value, { endpointMetadata: args.endpointMetadata ?? {} }); + if (typeof result === "string") { + newHeaders[key] = result; + continue; + } + if (result == null) { + continue; + } + newHeaders[key] = `${result}`; + } + return newHeaders; +} + +export async function fetcherImpl(args: Fetcher.Args): Promise> { + const url = createRequestUrl(args.url, args.queryParameters); + const requestBody: BodyInit | undefined = await getRequestBody({ + body: args.body, + type: args.requestType === "json" ? "json" : "other", + }); + const fetchFn = await getFetchFn(); + + try { + const response = await requestWithRetries( + async () => + makeRequest( + fetchFn, + url, + args.method, + await getHeaders(args), + requestBody, + args.timeoutMs, + args.abortSignal, + args.withCredentials, + args.duplex, + ), + args.maxRetries, + ); + + if (response.status >= 200 && response.status < 400) { + return { + ok: true, + body: (await getResponseBody(response, args.responseType)) as R, + headers: response.headers, + rawResponse: toRawResponse(response), + }; + } else { + return { + ok: false, + error: { + reason: "status-code", + statusCode: response.status, + body: await getErrorResponseBody(response), + }, + rawResponse: toRawResponse(response), + }; + } + } catch (error) { + if (args.abortSignal?.aborted) { + return { + ok: false, + error: { + reason: "unknown", + errorMessage: "The user aborted a request", + }, + rawResponse: abortRawResponse, + }; + } else if (error instanceof Error && error.name === "AbortError") { + return { + ok: false, + error: { + reason: "timeout", + }, + rawResponse: abortRawResponse, + }; + } else if (error instanceof Error) { + return { + ok: false, + error: { + reason: "unknown", + errorMessage: error.message, + }, + rawResponse: unknownRawResponse, + }; + } + + return { + ok: false, + error: { + reason: "unknown", + errorMessage: toJson(error), + }, + rawResponse: unknownRawResponse, + }; + } +} + +export const fetcher: FetchFunction = fetcherImpl; diff --git a/skyvern-ts/client/src/core/fetcher/Headers.ts b/skyvern-ts/client/src/core/fetcher/Headers.ts new file mode 100644 index 00000000..af841aa2 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/Headers.ts @@ -0,0 +1,93 @@ +let Headers: typeof globalThis.Headers; + +if (typeof globalThis.Headers !== "undefined") { + Headers = globalThis.Headers; +} else { + Headers = class Headers implements Headers { + private headers: Map; + + constructor(init?: HeadersInit) { + this.headers = new Map(); + + if (init) { + if (init instanceof Headers) { + init.forEach((value, key) => this.append(key, value)); + } else if (Array.isArray(init)) { + for (const [key, value] of init) { + if (typeof key === "string" && typeof value === "string") { + this.append(key, value); + } else { + throw new TypeError("Each header entry must be a [string, string] tuple"); + } + } + } else { + for (const [key, value] of Object.entries(init)) { + if (typeof value === "string") { + this.append(key, value); + } else { + throw new TypeError("Header values must be strings"); + } + } + } + } + } + + append(name: string, value: string): void { + const key = name.toLowerCase(); + const existing = this.headers.get(key) || []; + this.headers.set(key, [...existing, value]); + } + + delete(name: string): void { + const key = name.toLowerCase(); + this.headers.delete(key); + } + + get(name: string): string | null { + const key = name.toLowerCase(); + const values = this.headers.get(key); + return values ? values.join(", ") : null; + } + + has(name: string): boolean { + const key = name.toLowerCase(); + return this.headers.has(key); + } + + set(name: string, value: string): void { + const key = name.toLowerCase(); + this.headers.set(key, [value]); + } + + forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: unknown): void { + const boundCallback = thisArg ? callbackfn.bind(thisArg) : callbackfn; + this.headers.forEach((values, key) => boundCallback(values.join(", "), key, this)); + } + + getSetCookie(): string[] { + return this.headers.get("set-cookie") || []; + } + + *entries(): HeadersIterator<[string, string]> { + for (const [key, values] of this.headers.entries()) { + yield [key, values.join(", ")]; + } + } + + *keys(): HeadersIterator { + yield* this.headers.keys(); + } + + *values(): HeadersIterator { + for (const values of this.headers.values()) { + yield values.join(", "); + } + } + + [Symbol.iterator](): HeadersIterator<[string, string]> { + return this.entries(); + } + }; +} + +export { Headers }; diff --git a/skyvern-ts/client/src/core/fetcher/HttpResponsePromise.ts b/skyvern-ts/client/src/core/fetcher/HttpResponsePromise.ts new file mode 100644 index 00000000..692ca7d7 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/HttpResponsePromise.ts @@ -0,0 +1,116 @@ +import type { WithRawResponse } from "./RawResponse.js"; + +/** + * A promise that returns the parsed response and lets you retrieve the raw response too. + */ +export class HttpResponsePromise extends Promise { + private innerPromise: Promise>; + private unwrappedPromise: Promise | undefined; + + private constructor(promise: Promise>) { + // Initialize with a no-op to avoid premature parsing + super((resolve) => { + resolve(undefined as unknown as T); + }); + this.innerPromise = promise; + } + + /** + * Creates an `HttpResponsePromise` from a function that returns a promise. + * + * @param fn - A function that returns a promise resolving to a `WithRawResponse` object. + * @param args - Arguments to pass to the function. + * @returns An `HttpResponsePromise` instance. + */ + public static fromFunction Promise>, T>( + fn: F, + ...args: Parameters + ): HttpResponsePromise { + return new HttpResponsePromise(fn(...args)); + } + + /** + * Creates a function that returns an `HttpResponsePromise` from a function that returns a promise. + * + * @param fn - A function that returns a promise resolving to a `WithRawResponse` object. + * @returns A function that returns an `HttpResponsePromise` instance. + */ + public static interceptFunction< + F extends (...args: never[]) => Promise>, + T = Awaited>["data"], + >(fn: F): (...args: Parameters) => HttpResponsePromise { + return (...args: Parameters): HttpResponsePromise => { + return HttpResponsePromise.fromPromise(fn(...args)); + }; + } + + /** + * Creates an `HttpResponsePromise` from an existing promise. + * + * @param promise - A promise resolving to a `WithRawResponse` object. + * @returns An `HttpResponsePromise` instance. + */ + public static fromPromise(promise: Promise>): HttpResponsePromise { + return new HttpResponsePromise(promise); + } + + /** + * Creates an `HttpResponsePromise` from an executor function. + * + * @param executor - A function that takes resolve and reject callbacks to create a promise. + * @returns An `HttpResponsePromise` instance. + */ + public static fromExecutor( + executor: (resolve: (value: WithRawResponse) => void, reject: (reason?: unknown) => void) => void, + ): HttpResponsePromise { + const promise = new Promise>(executor); + return new HttpResponsePromise(promise); + } + + /** + * Creates an `HttpResponsePromise` from a resolved result. + * + * @param result - A `WithRawResponse` object to resolve immediately. + * @returns An `HttpResponsePromise` instance. + */ + public static fromResult(result: WithRawResponse): HttpResponsePromise { + const promise = Promise.resolve(result); + return new HttpResponsePromise(promise); + } + + private unwrap(): Promise { + if (!this.unwrappedPromise) { + this.unwrappedPromise = this.innerPromise.then(({ data }) => data); + } + return this.unwrappedPromise; + } + + /** @inheritdoc */ + public override then( + onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, + onrejected?: ((reason: unknown) => TResult2 | PromiseLike) | null, + ): Promise { + return this.unwrap().then(onfulfilled, onrejected); + } + + /** @inheritdoc */ + public override catch( + onrejected?: ((reason: unknown) => TResult | PromiseLike) | null, + ): Promise { + return this.unwrap().catch(onrejected); + } + + /** @inheritdoc */ + public override finally(onfinally?: (() => void) | null): Promise { + return this.unwrap().finally(onfinally); + } + + /** + * Retrieves the data and raw response. + * + * @returns A promise resolving to a `WithRawResponse` object. + */ + public async withRawResponse(): Promise> { + return await this.innerPromise; + } +} diff --git a/skyvern-ts/client/src/core/fetcher/RawResponse.ts b/skyvern-ts/client/src/core/fetcher/RawResponse.ts new file mode 100644 index 00000000..37fb44e2 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/RawResponse.ts @@ -0,0 +1,61 @@ +import { Headers } from "./Headers.js"; + +/** + * The raw response from the fetch call excluding the body. + */ +export type RawResponse = Omit< + { + [K in keyof Response as Response[K] extends Function ? never : K]: Response[K]; // strips out functions + }, + "ok" | "body" | "bodyUsed" +>; // strips out body and bodyUsed + +/** + * A raw response indicating that the request was aborted. + */ +export const abortRawResponse: RawResponse = { + headers: new Headers(), + redirected: false, + status: 499, + statusText: "Client Closed Request", + type: "error", + url: "", +} as const; + +/** + * A raw response indicating an unknown error. + */ +export const unknownRawResponse: RawResponse = { + headers: new Headers(), + redirected: false, + status: 0, + statusText: "Unknown Error", + type: "error", + url: "", +} as const; + +/** + * Converts a `RawResponse` object into a `RawResponse` by extracting its properties, + * excluding the `body` and `bodyUsed` fields. + * + * @param response - The `RawResponse` object to convert. + * @returns A `RawResponse` object containing the extracted properties of the input response. + */ +export function toRawResponse(response: Response): RawResponse { + return { + headers: response.headers, + redirected: response.redirected, + status: response.status, + statusText: response.statusText, + type: response.type, + url: response.url, + }; +} + +/** + * Creates a `RawResponse` from a standard `Response` object. + */ +export interface WithRawResponse { + readonly data: T; + readonly rawResponse: RawResponse; +} diff --git a/skyvern-ts/client/src/core/fetcher/ResponseWithBody.ts b/skyvern-ts/client/src/core/fetcher/ResponseWithBody.ts new file mode 100644 index 00000000..445d40f8 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/ResponseWithBody.ts @@ -0,0 +1,7 @@ +export type ResponseWithBody = Response & { + body: ReadableStream; +}; + +export function isResponseWithBody(response: Response): response is ResponseWithBody { + return (response as ResponseWithBody).body != null; +} diff --git a/skyvern-ts/client/src/core/fetcher/Supplier.ts b/skyvern-ts/client/src/core/fetcher/Supplier.ts new file mode 100644 index 00000000..867c931c --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/Supplier.ts @@ -0,0 +1,11 @@ +export type Supplier = T | Promise | (() => T | Promise); + +export const Supplier = { + get: async (supplier: Supplier): Promise => { + if (typeof supplier === "function") { + return (supplier as () => T)(); + } else { + return supplier; + } + }, +}; diff --git a/skyvern-ts/client/src/core/fetcher/createRequestUrl.ts b/skyvern-ts/client/src/core/fetcher/createRequestUrl.ts new file mode 100644 index 00000000..88e13265 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/createRequestUrl.ts @@ -0,0 +1,6 @@ +import { toQueryString } from "../url/qs.js"; + +export function createRequestUrl(baseUrl: string, queryParameters?: Record): string { + const queryString = toQueryString(queryParameters, { arrayFormat: "repeat" }); + return queryString ? `${baseUrl}?${queryString}` : baseUrl; +} diff --git a/skyvern-ts/client/src/core/fetcher/getErrorResponseBody.ts b/skyvern-ts/client/src/core/fetcher/getErrorResponseBody.ts new file mode 100644 index 00000000..7cf4e623 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/getErrorResponseBody.ts @@ -0,0 +1,33 @@ +import { fromJson } from "../json.js"; +import { getResponseBody } from "./getResponseBody.js"; + +export async function getErrorResponseBody(response: Response): Promise { + let contentType = response.headers.get("Content-Type")?.toLowerCase(); + if (contentType == null || contentType.length === 0) { + return getResponseBody(response); + } + + if (contentType.indexOf(";") !== -1) { + contentType = contentType.split(";")[0]?.trim() ?? ""; + } + switch (contentType) { + case "application/hal+json": + case "application/json": + case "application/ld+json": + case "application/problem+json": + case "application/vnd.api+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(); + return text.length > 0 ? fromJson(text) : undefined; + } + + // Fallback to plain text if content type is not recognized + // Even if no body is present, the response will be an empty string + return await response.text(); + } +} diff --git a/skyvern-ts/client/src/core/fetcher/getFetchFn.ts b/skyvern-ts/client/src/core/fetcher/getFetchFn.ts new file mode 100644 index 00000000..9f845b95 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/getFetchFn.ts @@ -0,0 +1,3 @@ +export async function getFetchFn(): Promise { + return fetch; +} diff --git a/skyvern-ts/client/src/core/fetcher/getHeader.ts b/skyvern-ts/client/src/core/fetcher/getHeader.ts new file mode 100644 index 00000000..50f922b0 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/getHeader.ts @@ -0,0 +1,8 @@ +export function getHeader(headers: Record, header: string): string | undefined { + for (const [headerKey, headerValue] of Object.entries(headers)) { + if (headerKey.toLowerCase() === header.toLowerCase()) { + return headerValue; + } + } + return undefined; +} diff --git a/skyvern-ts/client/src/core/fetcher/getRequestBody.ts b/skyvern-ts/client/src/core/fetcher/getRequestBody.ts new file mode 100644 index 00000000..e38457c5 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/getRequestBody.ts @@ -0,0 +1,16 @@ +import { toJson } from "../json.js"; + +export declare namespace GetRequestBody { + interface Args { + body: unknown; + type: "json" | "file" | "bytes" | "other"; + } +} + +export async function getRequestBody({ body, type }: GetRequestBody.Args): Promise { + if (type.includes("json")) { + return toJson(body); + } else { + return body as BodyInit; + } +} diff --git a/skyvern-ts/client/src/core/fetcher/getResponseBody.ts b/skyvern-ts/client/src/core/fetcher/getResponseBody.ts new file mode 100644 index 00000000..0f24de17 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/getResponseBody.ts @@ -0,0 +1,43 @@ +import { fromJson } from "../json.js"; +import { getBinaryResponse } from "./BinaryResponse.js"; +import { isResponseWithBody } from "./ResponseWithBody.js"; + +export async function getResponseBody(response: Response, responseType?: string): Promise { + if (!isResponseWithBody(response)) { + return undefined; + } + switch (responseType) { + case "binary-response": + return getBinaryResponse(response); + case "blob": + return await response.blob(); + case "arrayBuffer": + return await response.arrayBuffer(); + case "sse": + return response.body; + case "streaming": + return response.body; + + case "text": + return await response.text(); + } + + // if responseType is "json" or not specified, try to parse as JSON + const text = await response.text(); + if (text.length > 0) { + try { + const responseBody = fromJson(text); + return responseBody; + } catch (_err) { + return { + ok: false, + error: { + reason: "non-json", + statusCode: response.status, + rawBody: text, + }, + }; + } + } + return undefined; +} diff --git a/skyvern-ts/client/src/core/fetcher/index.ts b/skyvern-ts/client/src/core/fetcher/index.ts new file mode 100644 index 00000000..c3bc6da2 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/index.ts @@ -0,0 +1,11 @@ +export type { APIResponse } from "./APIResponse.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 { HttpResponsePromise } from "./HttpResponsePromise.js"; +export type { RawResponse, WithRawResponse } from "./RawResponse.js"; +export { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; +export { Supplier } from "./Supplier.js"; diff --git a/skyvern-ts/client/src/core/fetcher/makeRequest.ts b/skyvern-ts/client/src/core/fetcher/makeRequest.ts new file mode 100644 index 00000000..5edce698 --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/makeRequest.ts @@ -0,0 +1,44 @@ +import { anySignal, getTimeoutSignal } from "./signals.js"; + +export const makeRequest = async ( + fetchFn: (url: string, init: RequestInit) => Promise, + url: string, + method: string, + headers: Record, + requestBody: BodyInit | undefined, + timeoutMs?: number, + abortSignal?: AbortSignal, + withCredentials?: boolean, + duplex?: "half", +): Promise => { + const signals: AbortSignal[] = []; + + // Add timeout signal + let timeoutAbortId: NodeJS.Timeout | undefined; + if (timeoutMs != null) { + const { signal, abortId } = getTimeoutSignal(timeoutMs); + timeoutAbortId = abortId; + signals.push(signal); + } + + // Add arbitrary signal + if (abortSignal != null) { + signals.push(abortSignal); + } + const newSignals = anySignal(signals); + const response = await fetchFn(url, { + method: method, + headers, + body: requestBody, + signal: newSignals, + credentials: withCredentials ? "include" : undefined, + // @ts-ignore + duplex, + }); + + if (timeoutAbortId != null) { + clearTimeout(timeoutAbortId); + } + + return response; +}; diff --git a/skyvern-ts/client/src/core/fetcher/requestWithRetries.ts b/skyvern-ts/client/src/core/fetcher/requestWithRetries.ts new file mode 100644 index 00000000..3d30bd1c --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/requestWithRetries.ts @@ -0,0 +1,73 @@ +const INITIAL_RETRY_DELAY = 1000; // in milliseconds +const MAX_RETRY_DELAY = 60000; // in milliseconds +const DEFAULT_MAX_RETRIES = 2; +const JITTER_FACTOR = 0.2; // 20% random jitter + +function addPositiveJitter(delay: number): number { + // Generate a random value between 0 and +JITTER_FACTOR + const jitterMultiplier = 1 + Math.random() * JITTER_FACTOR; + return delay * jitterMultiplier; +} + +function addSymmetricJitter(delay: number): number { + // Generate a random value in a JITTER_FACTOR-sized percentage range around delay + const jitterMultiplier = 1 + (Math.random() - 0.5) * JITTER_FACTOR; + return delay * jitterMultiplier; +} + +function getRetryDelayFromHeaders(response: Response, retryAttempt: number): number { + // Check for Retry-After header first (RFC 7231), with no jitter + const retryAfter = response.headers.get("Retry-After"); + if (retryAfter) { + // Parse as number of seconds... + const retryAfterSeconds = parseInt(retryAfter, 10); + if (!Number.isNaN(retryAfterSeconds) && retryAfterSeconds > 0) { + return Math.min(retryAfterSeconds * 1000, MAX_RETRY_DELAY); + } + + // ...or as an HTTP date; both are valid + 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); + } + } + } + + // Then check for industry-standard X-RateLimit-Reset header, with positive jitter + const rateLimitReset = response.headers.get("X-RateLimit-Reset"); + if (rateLimitReset) { + const resetTime = parseInt(rateLimitReset, 10); + if (!Number.isNaN(resetTime)) { + // Assume Unix timestamp in epoch seconds + const delay = resetTime * 1000 - Date.now(); + if (delay > 0) { + return addPositiveJitter(Math.min(delay, MAX_RETRY_DELAY)); + } + } + } + + // Fall back to exponential backoff, with symmetric jitter + return addSymmetricJitter(Math.min(INITIAL_RETRY_DELAY * 2 ** retryAttempt, MAX_RETRY_DELAY)); +} + +export async function requestWithRetries( + requestFn: () => Promise, + maxRetries: number = DEFAULT_MAX_RETRIES, +): Promise { + let response: Response = await requestFn(); + + for (let i = 0; i < maxRetries; ++i) { + if ([408, 429].includes(response.status) || response.status >= 500) { + // Get delay with appropriate jitter applied + const delay = getRetryDelayFromHeaders(response, i); + + await new Promise((resolve) => setTimeout(resolve, delay)); + response = await requestFn(); + } else { + break; + } + } + return response!; +} diff --git a/skyvern-ts/client/src/core/fetcher/signals.ts b/skyvern-ts/client/src/core/fetcher/signals.ts new file mode 100644 index 00000000..a8d32a2e --- /dev/null +++ b/skyvern-ts/client/src/core/fetcher/signals.ts @@ -0,0 +1,38 @@ +const TIMEOUT = "timeout"; + +export function getTimeoutSignal(timeoutMs: number): { signal: AbortSignal; abortId: NodeJS.Timeout } { + 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, + }); + } + + return controller.signal; +} diff --git a/skyvern-ts/client/src/core/headers.ts b/skyvern-ts/client/src/core/headers.ts new file mode 100644 index 00000000..a723d228 --- /dev/null +++ b/skyvern-ts/client/src/core/headers.ts @@ -0,0 +1,33 @@ +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))) { + if (value != null) { + result[key] = value; + } else if (key in result) { + delete result[key]; + } + } + + return result; +} + +export function mergeOnlyDefinedHeaders( + ...headersArray: (Record | null | undefined)[] +): Record { + const result: Record = {}; + + for (const [key, value] of headersArray + .filter((headers) => headers != null) + .flatMap((headers) => Object.entries(headers))) { + if (value != null) { + result[key] = value; + } + } + + return result; +} diff --git a/skyvern-ts/client/src/core/index.ts b/skyvern-ts/client/src/core/index.ts new file mode 100644 index 00000000..bbb640d1 --- /dev/null +++ b/skyvern-ts/client/src/core/index.ts @@ -0,0 +1,3 @@ +export * from "./fetcher/index.js"; +export * from "./runtime/index.js"; +export * as url from "./url/index.js"; diff --git a/skyvern-ts/client/src/core/json.ts b/skyvern-ts/client/src/core/json.ts new file mode 100644 index 00000000..c052f324 --- /dev/null +++ b/skyvern-ts/client/src/core/json.ts @@ -0,0 +1,27 @@ +/** + * Serialize a value to JSON + * @param value A JavaScript value, usually an object or array, to be converted. + * @param replacer A function that transforms the results. + * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. + * @returns JSON string + */ +export const toJson = ( + value: unknown, + replacer?: (this: unknown, key: string, value: unknown) => unknown, + space?: string | number, +): string => { + return JSON.stringify(value, replacer, space); +}; + +/** + * Parse JSON string to object, array, or other type + * @param text A valid JSON string. + * @param reviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is. + * @returns Parsed object, array, or other type + */ +export function fromJson( + text: string, + reviver?: (this: unknown, key: string, value: unknown) => unknown, +): T { + return JSON.parse(text, reviver); +} diff --git a/skyvern-ts/client/src/core/runtime/index.ts b/skyvern-ts/client/src/core/runtime/index.ts new file mode 100644 index 00000000..cfab23f9 --- /dev/null +++ b/skyvern-ts/client/src/core/runtime/index.ts @@ -0,0 +1 @@ +export { RUNTIME } from "./runtime.js"; diff --git a/skyvern-ts/client/src/core/runtime/runtime.ts b/skyvern-ts/client/src/core/runtime/runtime.ts new file mode 100644 index 00000000..08fd2563 --- /dev/null +++ b/skyvern-ts/client/src/core/runtime/runtime.ts @@ -0,0 +1,133 @@ +interface DenoGlobal { + version: { + deno: string; + }; +} + +interface BunGlobal { + version: string; +} + +declare const Deno: DenoGlobal | undefined; +declare const Bun: BunGlobal | undefined; +declare const EdgeRuntime: string | undefined; +declare const self: typeof globalThis.self & { + importScripts?: unknown; +}; + +/** + * A constant that indicates which environment and version the SDK is running in. + */ +export const RUNTIME: Runtime = evaluateRuntime(); + +export interface Runtime { + type: "browser" | "web-worker" | "deno" | "bun" | "node" | "react-native" | "unknown" | "workerd" | "edge-runtime"; + version?: string; + parsedVersion?: number; +} + +function evaluateRuntime(): Runtime { + /** + * A constant that indicates whether the environment the code is running is a Web Browser. + */ + const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined"; + if (isBrowser) { + return { + type: "browser", + version: window.navigator.userAgent, + }; + } + + /** + * A constant that indicates whether the environment the code is running is Cloudflare. + * https://developers.cloudflare.com/workers/runtime-apis/web-standards/#navigatoruseragent + */ + const isCloudflare = typeof globalThis !== "undefined" && globalThis?.navigator?.userAgent === "Cloudflare-Workers"; + if (isCloudflare) { + return { + type: "workerd", + }; + } + + /** + * A constant that indicates whether the environment the code is running is Edge Runtime. + * https://vercel.com/docs/functions/runtimes/edge-runtime#check-if-you're-running-on-the-edge-runtime + */ + const isEdgeRuntime = typeof EdgeRuntime === "string"; + if (isEdgeRuntime) { + return { + type: "edge-runtime", + }; + } + + /** + * A constant that indicates whether the environment the code is running is a Web Worker. + */ + const isWebWorker = + typeof self === "object" && + typeof self?.importScripts === "function" && + (self.constructor?.name === "DedicatedWorkerGlobalScope" || + self.constructor?.name === "ServiceWorkerGlobalScope" || + self.constructor?.name === "SharedWorkerGlobalScope"); + if (isWebWorker) { + return { + type: "web-worker", + }; + } + + /** + * A constant that indicates whether the environment the code is running is Deno. + * FYI Deno spoofs process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions + */ + const isDeno = + typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined"; + if (isDeno) { + return { + type: "deno", + version: Deno.version.deno, + }; + } + + /** + * A constant that indicates whether the environment the code is running is Bun.sh. + */ + const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undefined"; + if (isBun) { + return { + type: "bun", + version: Bun.version, + }; + } + + /** + * A constant that indicates whether the environment the code is running is Node.JS. + */ + const isNode = + typeof process !== "undefined" && + "version" in process && + !!process.version && + "versions" in process && + !!process.versions?.node; + if (isNode) { + return { + type: "node", + version: process.versions.node, + parsedVersion: Number(process.versions.node.split(".")[0]), + }; + } + + /** + * 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/skyvern-ts/client/src/core/url/encodePathParam.ts b/skyvern-ts/client/src/core/url/encodePathParam.ts new file mode 100644 index 00000000..19b90124 --- /dev/null +++ b/skyvern-ts/client/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/skyvern-ts/client/src/core/url/index.ts b/skyvern-ts/client/src/core/url/index.ts new file mode 100644 index 00000000..f2e0fa2d --- /dev/null +++ b/skyvern-ts/client/src/core/url/index.ts @@ -0,0 +1,3 @@ +export { encodePathParam } from "./encodePathParam.js"; +export { join } from "./join.js"; +export { toQueryString } from "./qs.js"; diff --git a/skyvern-ts/client/src/core/url/join.ts b/skyvern-ts/client/src/core/url/join.ts new file mode 100644 index 00000000..b872a90a --- /dev/null +++ b/skyvern-ts/client/src/core/url/join.ts @@ -0,0 +1,80 @@ +export function join(base: string, ...segments: string[]): string { + if (!base) { + return ""; + } + + if (segments.length === 0) { + return base; + } + + if (base.includes("://")) { + let url: URL; + 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?.endsWith("/"); + + for (const segment of segments) { + const cleanSegment = trimSlashes(segment); + if (cleanSegment) { + url.pathname = joinPathSegments(url.pathname, cleanSegment); + } + } + + if (shouldPreserveTrailingSlash && !url.pathname.endsWith("/")) { + url.pathname += "/"; + } + + return url.toString(); + } + + return joinPath(base, ...segments); +} + +function joinPath(base: string, ...segments: string[]): string { + if (segments.length === 0) { + return base; + } + + let result = base; + + const lastSegment = segments[segments.length - 1]; + const shouldPreserveTrailingSlash = lastSegment?.endsWith("/"); + + for (const segment of segments) { + const cleanSegment = trimSlashes(segment); + if (cleanSegment) { + result = joinPathSegments(result, cleanSegment); + } + } + + if (shouldPreserveTrailingSlash && !result.endsWith("/")) { + result += "/"; + } + + return result; +} + +function joinPathSegments(left: string, right: string): string { + if (left.endsWith("/")) { + return left + right; + } + return `${left}/${right}`; +} + +function trimSlashes(str: string): string { + if (!str) return str; + + let start = 0; + let end = str.length; + + if (str.startsWith("/")) start = 1; + if (str.endsWith("/")) end = str.length - 1; + + return start === 0 && end === str.length ? str : str.slice(start, end); +} diff --git a/skyvern-ts/client/src/core/url/qs.ts b/skyvern-ts/client/src/core/url/qs.ts new file mode 100644 index 00000000..13e89be9 --- /dev/null +++ b/skyvern-ts/client/src/core/url/qs.ts @@ -0,0 +1,74 @@ +interface QueryStringOptions { + arrayFormat?: "indices" | "repeat"; + encode?: boolean; +} + +const defaultQsOptions: Required = { + arrayFormat: "indices", + encode: true, +} as const; + +function encodeValue(value: unknown, shouldEncode: boolean): string { + if (value === undefined) { + return ""; + } + if (value === null) { + return ""; + } + const stringValue = String(value); + return shouldEncode ? encodeURIComponent(stringValue) : stringValue; +} + +function stringifyObject(obj: Record, prefix = "", options: Required): string[] { + const parts: string[] = []; + + for (const [key, value] of Object.entries(obj)) { + const fullKey = prefix ? `${prefix}[${key}]` : key; + + if (value === undefined) { + continue; + } + + if (Array.isArray(value)) { + if (value.length === 0) { + continue; + } + for (let i = 0; i < value.length; i++) { + const item = value[i]; + if (item === undefined) { + continue; + } + if (typeof item === "object" && !Array.isArray(item) && item !== null) { + const arrayKey = options.arrayFormat === "indices" ? `${fullKey}[${i}]` : fullKey; + parts.push(...stringifyObject(item as Record, arrayKey, options)); + } else { + const arrayKey = options.arrayFormat === "indices" ? `${fullKey}[${i}]` : fullKey; + const encodedKey = options.encode ? encodeURIComponent(arrayKey) : arrayKey; + parts.push(`${encodedKey}=${encodeValue(item, options.encode)}`); + } + } + } else if (typeof value === "object" && value !== null) { + if (Object.keys(value as Record).length === 0) { + continue; + } + parts.push(...stringifyObject(value as Record, fullKey, options)); + } else { + const encodedKey = options.encode ? encodeURIComponent(fullKey) : fullKey; + parts.push(`${encodedKey}=${encodeValue(value, options.encode)}`); + } + } + + return parts; +} + +export function toQueryString(obj: unknown, options?: QueryStringOptions): string { + if (obj == null || typeof obj !== "object") { + return ""; + } + + const parts = stringifyObject(obj as Record, "", { + ...defaultQsOptions, + ...options, + }); + return parts.join("&"); +} diff --git a/skyvern-ts/client/src/environments.ts b/skyvern-ts/client/src/environments.ts new file mode 100644 index 00000000..49d25bdf --- /dev/null +++ b/skyvern-ts/client/src/environments.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export const SkyvernEnvironment = { + Production: "https://api.skyvern.com", + Staging: "https://api-staging.skyvern.com", + Development: "http://localhost:8000", +} as const; + +export type SkyvernEnvironment = + | typeof SkyvernEnvironment.Production + | typeof SkyvernEnvironment.Staging + | typeof SkyvernEnvironment.Development; diff --git a/skyvern-ts/client/src/errors/SkyvernError.ts b/skyvern-ts/client/src/errors/SkyvernError.ts new file mode 100644 index 00000000..d4e400a4 --- /dev/null +++ b/skyvern-ts/client/src/errors/SkyvernError.ts @@ -0,0 +1,53 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as core from "../core/index.js"; +import { toJson } from "../core/json.js"; + +export class SkyvernError extends Error { + public readonly statusCode?: number; + public readonly body?: unknown; + public readonly rawResponse?: core.RawResponse; + + constructor({ + message, + statusCode, + body, + rawResponse, + }: { + message?: string; + statusCode?: number; + body?: unknown; + rawResponse?: core.RawResponse; + }) { + super(buildMessage({ message, statusCode, body })); + Object.setPrototypeOf(this, SkyvernError.prototype); + this.statusCode = statusCode; + this.body = body; + this.rawResponse = rawResponse; + } +} + +function buildMessage({ + message, + statusCode, + body, +}: { + message: string | undefined; + statusCode: number | undefined; + body: unknown | undefined; +}): string { + const lines: string[] = []; + if (message != null) { + lines.push(message); + } + + if (statusCode != null) { + lines.push(`Status code: ${statusCode.toString()}`); + } + + if (body != null) { + lines.push(`Body: ${toJson(body, undefined, 2)}`); + } + + return lines.join("\n"); +} diff --git a/skyvern-ts/client/src/errors/SkyvernTimeoutError.ts b/skyvern-ts/client/src/errors/SkyvernTimeoutError.ts new file mode 100644 index 00000000..c8528cd2 --- /dev/null +++ b/skyvern-ts/client/src/errors/SkyvernTimeoutError.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export class SkyvernTimeoutError extends Error { + constructor(message: string) { + super(message); + Object.setPrototypeOf(this, SkyvernTimeoutError.prototype); + } +} diff --git a/skyvern-ts/client/src/errors/index.ts b/skyvern-ts/client/src/errors/index.ts new file mode 100644 index 00000000..3af29e21 --- /dev/null +++ b/skyvern-ts/client/src/errors/index.ts @@ -0,0 +1,2 @@ +export { SkyvernError } from "./SkyvernError.js"; +export { SkyvernTimeoutError } from "./SkyvernTimeoutError.js"; diff --git a/skyvern-ts/client/src/index.ts b/skyvern-ts/client/src/index.ts new file mode 100644 index 00000000..101bd60e --- /dev/null +++ b/skyvern-ts/client/src/index.ts @@ -0,0 +1,5 @@ +export * as Skyvern from "./api/index.js"; +export type { BaseClientOptions, BaseRequestOptions } from "./BaseClient.js"; +export { SkyvernClient } from "./Client.js"; +export { SkyvernEnvironment } from "./environments.js"; +export { SkyvernError, SkyvernTimeoutError } from "./errors/index.js"; diff --git a/skyvern-ts/client/src/version.ts b/skyvern-ts/client/src/version.ts new file mode 100644 index 00000000..1d8e2cab --- /dev/null +++ b/skyvern-ts/client/src/version.ts @@ -0,0 +1 @@ +export const SDK_VERSION = "0.2.18"; diff --git a/skyvern-ts/client/tests/custom.test.ts b/skyvern-ts/client/tests/custom.test.ts new file mode 100644 index 00000000..7f5e031c --- /dev/null +++ b/skyvern-ts/client/tests/custom.test.ts @@ -0,0 +1,13 @@ +/** + * This is a custom test file, if you wish to add more tests + * to your SDK. + * Be sure to mark this file in `.fernignore`. + * + * If you include example requests/responses in your fern definition, + * you will have tests automatically generated for you. + */ +describe("test", () => { + it("default", () => { + expect(true).toBe(true); + }); +}); diff --git a/skyvern-ts/client/tests/mock-server/MockServer.ts b/skyvern-ts/client/tests/mock-server/MockServer.ts new file mode 100644 index 00000000..5b30fe7c --- /dev/null +++ b/skyvern-ts/client/tests/mock-server/MockServer.ts @@ -0,0 +1,29 @@ +import type { RequestHandlerOptions } from "msw"; +import type { SetupServer } from "msw/node"; + +import { mockEndpointBuilder } from "./mockEndpointBuilder"; + +export interface MockServerOptions { + baseUrl: string; + server: SetupServer; +} + +export class MockServer { + private readonly server: SetupServer; + public readonly baseUrl: string; + + constructor({ baseUrl, server }: MockServerOptions) { + this.baseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl; + this.server = server; + } + + public mockEndpoint(options?: RequestHandlerOptions): ReturnType { + const builder = mockEndpointBuilder({ + once: options?.once, + onBuild: (handler) => { + this.server.use(handler); + }, + }).baseUrl(this.baseUrl); + return builder; + } +} diff --git a/skyvern-ts/client/tests/mock-server/MockServerPool.ts b/skyvern-ts/client/tests/mock-server/MockServerPool.ts new file mode 100644 index 00000000..e1a90f7f --- /dev/null +++ b/skyvern-ts/client/tests/mock-server/MockServerPool.ts @@ -0,0 +1,106 @@ +import { setupServer } from "msw/node"; + +import { fromJson, toJson } from "../../src/core/json"; +import { MockServer } from "./MockServer"; +import { randomBaseUrl } from "./randomBaseUrl"; + +const mswServer = setupServer(); +interface MockServerOptions { + baseUrl?: string; +} + +async function formatHttpRequest(request: Request, id?: string): Promise { + try { + const clone = request.clone(); + const headers = [...clone.headers.entries()].map(([k, v]) => `${k}: ${v}`).join("\n"); + + let body = ""; + try { + const contentType = clone.headers.get("content-type"); + if (contentType?.includes("application/json")) { + body = toJson(fromJson(await clone.text()), undefined, 2); + } else if (clone.body) { + body = await clone.text(); + } + } catch (_e) { + body = "(unable to parse body)"; + } + + const title = id ? `### Request ${id} ###\n` : ""; + const firstLine = `${title}${request.method} ${request.url.toString()} HTTP/1.1`; + + return `\n${firstLine}\n${headers}\n\n${body || "(no body)"}\n`; + } catch (e) { + return `Error formatting request: ${e}`; + } +} + +async function formatHttpResponse(response: Response, id?: string): Promise { + try { + const clone = response.clone(); + const headers = [...clone.headers.entries()].map(([k, v]) => `${k}: ${v}`).join("\n"); + + let body = ""; + try { + const contentType = clone.headers.get("content-type"); + if (contentType?.includes("application/json")) { + body = toJson(fromJson(await clone.text()), undefined, 2); + } else if (clone.body) { + body = await clone.text(); + } + } catch (_e) { + body = "(unable to parse body)"; + } + + const title = id ? `### Response for ${id} ###\n` : ""; + const firstLine = `${title}HTTP/1.1 ${response.status} ${response.statusText}`; + + return `\n${firstLine}\n${headers}\n\n${body || "(no body)"}\n`; + } catch (e) { + return `Error formatting response: ${e}`; + } +} + +class MockServerPool { + private servers: MockServer[] = []; + + public createServer(options?: Partial): MockServer { + const baseUrl = options?.baseUrl || randomBaseUrl(); + const server = new MockServer({ baseUrl, server: mswServer }); + this.servers.push(server); + return server; + } + + public getServers(): MockServer[] { + return [...this.servers]; + } + + public listen(): void { + const onUnhandledRequest = process.env.LOG_LEVEL === "debug" ? "warn" : "bypass"; + mswServer.listen({ onUnhandledRequest }); + + if (process.env.LOG_LEVEL === "debug") { + mswServer.events.on("request:start", async ({ request, requestId }) => { + const formattedRequest = await formatHttpRequest(request, requestId); + console.debug(`request:start\n${formattedRequest}`); + }); + + mswServer.events.on("request:unhandled", async ({ request, requestId }) => { + const formattedRequest = await formatHttpRequest(request, requestId); + console.debug(`request:unhandled\n${formattedRequest}`); + }); + + mswServer.events.on("response:mocked", async ({ request, response, requestId }) => { + const formattedResponse = await formatHttpResponse(response, requestId); + console.debug(`response:mocked\n${formattedResponse}`); + }); + } + } + + public close(): void { + this.servers = []; + mswServer.close(); + } +} + +export const mockServerPool = new MockServerPool(); diff --git a/skyvern-ts/client/tests/mock-server/mockEndpointBuilder.ts b/skyvern-ts/client/tests/mock-server/mockEndpointBuilder.ts new file mode 100644 index 00000000..18557ec1 --- /dev/null +++ b/skyvern-ts/client/tests/mock-server/mockEndpointBuilder.ts @@ -0,0 +1,215 @@ +import { type DefaultBodyType, type HttpHandler, HttpResponse, type HttpResponseResolver, http } from "msw"; + +import { url } from "../../src/core"; +import { toJson } from "../../src/core/json"; +import { withHeaders } from "./withHeaders"; +import { withJson } from "./withJson"; + +type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head"; + +interface MethodStage { + baseUrl(baseUrl: string): MethodStage; + all(path: string): RequestHeadersStage; + get(path: string): RequestHeadersStage; + post(path: string): RequestHeadersStage; + put(path: string): RequestHeadersStage; + delete(path: string): RequestHeadersStage; + patch(path: string): RequestHeadersStage; + options(path: string): RequestHeadersStage; + head(path: string): RequestHeadersStage; +} + +interface RequestHeadersStage extends RequestBodyStage, ResponseStage { + header(name: string, value: string): RequestHeadersStage; + headers(headers: Record): RequestBodyStage; +} + +interface RequestBodyStage extends ResponseStage { + jsonBody(body: unknown): ResponseStage; +} + +interface ResponseStage { + respondWith(): ResponseStatusStage; +} +interface ResponseStatusStage { + statusCode(statusCode: number): ResponseHeaderStage; +} + +interface ResponseHeaderStage extends ResponseBodyStage, BuildStage { + header(name: string, value: string): ResponseHeaderStage; + headers(headers: Record): ResponseHeaderStage; +} + +interface ResponseBodyStage { + jsonBody(body: unknown): BuildStage; +} + +interface BuildStage { + build(): HttpHandler; +} + +export interface HttpHandlerBuilderOptions { + onBuild?: (handler: HttpHandler) => void; + once?: boolean; +} + +class RequestBuilder implements MethodStage, RequestHeadersStage, RequestBodyStage, ResponseStage { + private method: HttpMethod = "get"; + private _baseUrl: string = ""; + private path: string = "/"; + private readonly predicates: ((resolver: HttpResponseResolver) => HttpResponseResolver)[] = []; + private readonly handlerOptions?: HttpHandlerBuilderOptions; + + constructor(options?: HttpHandlerBuilderOptions) { + this.handlerOptions = options; + } + + baseUrl(baseUrl: string): MethodStage { + this._baseUrl = baseUrl; + return this; + } + + all(path: string): RequestHeadersStage { + this.method = "all"; + this.path = path; + return this; + } + + get(path: string): RequestHeadersStage { + this.method = "get"; + this.path = path; + return this; + } + + post(path: string): RequestHeadersStage { + this.method = "post"; + this.path = path; + return this; + } + + put(path: string): RequestHeadersStage { + this.method = "put"; + this.path = path; + return this; + } + + delete(path: string): RequestHeadersStage { + this.method = "delete"; + this.path = path; + return this; + } + + patch(path: string): RequestHeadersStage { + this.method = "patch"; + this.path = path; + return this; + } + + options(path: string): RequestHeadersStage { + this.method = "options"; + this.path = path; + return this; + } + + head(path: string): RequestHeadersStage { + this.method = "head"; + this.path = path; + return this; + } + + header(name: string, value: string): RequestHeadersStage { + this.predicates.push((resolver) => withHeaders({ [name]: value }, resolver)); + return this; + } + + headers(headers: Record): RequestBodyStage { + this.predicates.push((resolver) => withHeaders(headers, resolver)); + return this; + } + + jsonBody(body: unknown): ResponseStage { + if (body === undefined) { + throw new Error("Undefined is not valid JSON. Do not call jsonBody if you want an empty body."); + } + this.predicates.push((resolver) => withJson(body, resolver)); + return this; + } + + respondWith(): ResponseStatusStage { + return new ResponseBuilder(this.method, this.buildUrl(), this.predicates, this.handlerOptions); + } + + private buildUrl(): string { + return url.join(this._baseUrl, this.path); + } +} + +class ResponseBuilder implements ResponseStatusStage, ResponseHeaderStage, ResponseBodyStage, BuildStage { + private readonly method: HttpMethod; + private readonly url: string; + private readonly requestPredicates: ((resolver: HttpResponseResolver) => HttpResponseResolver)[]; + private readonly handlerOptions?: HttpHandlerBuilderOptions; + + private responseStatusCode: number = 200; + private responseHeaders: Record = {}; + private responseBody: DefaultBodyType = undefined; + + constructor( + method: HttpMethod, + url: string, + requestPredicates: ((resolver: HttpResponseResolver) => HttpResponseResolver)[], + options?: HttpHandlerBuilderOptions, + ) { + this.method = method; + this.url = url; + this.requestPredicates = requestPredicates; + this.handlerOptions = options; + } + + public statusCode(code: number): ResponseHeaderStage { + this.responseStatusCode = code; + return this; + } + + public header(name: string, value: string): ResponseHeaderStage { + this.responseHeaders[name] = value; + return this; + } + + public headers(headers: Record): ResponseHeaderStage { + this.responseHeaders = { ...this.responseHeaders, ...headers }; + return this; + } + + public jsonBody(body: unknown): BuildStage { + if (body === undefined) { + throw new Error("Undefined is not valid JSON. Do not call jsonBody if you expect an empty body."); + } + this.responseBody = toJson(body); + return this; + } + + public build(): HttpHandler { + const responseResolver: HttpResponseResolver = () => { + const response = new HttpResponse(this.responseBody, { + status: this.responseStatusCode, + headers: this.responseHeaders, + }); + // if no Content-Type header is set, delete the default text content type that is set + if (Object.keys(this.responseHeaders).some((key) => key.toLowerCase() === "content-type") === false) { + response.headers.delete("Content-Type"); + } + return response; + }; + + const finalResolver = this.requestPredicates.reduceRight((acc, predicate) => predicate(acc), responseResolver); + + const handler = http[this.method](this.url, finalResolver, this.handlerOptions); + this.handlerOptions?.onBuild?.(handler); + return handler; + } +} + +export function mockEndpointBuilder(options?: HttpHandlerBuilderOptions): MethodStage { + return new RequestBuilder(options); +} diff --git a/skyvern-ts/client/tests/mock-server/randomBaseUrl.ts b/skyvern-ts/client/tests/mock-server/randomBaseUrl.ts new file mode 100644 index 00000000..031aa640 --- /dev/null +++ b/skyvern-ts/client/tests/mock-server/randomBaseUrl.ts @@ -0,0 +1,4 @@ +export function randomBaseUrl(): string { + const randomString = Math.random().toString(36).substring(2, 15); + return `http://${randomString}.localhost`; +} diff --git a/skyvern-ts/client/tests/mock-server/setup.ts b/skyvern-ts/client/tests/mock-server/setup.ts new file mode 100644 index 00000000..aeb3a95a --- /dev/null +++ b/skyvern-ts/client/tests/mock-server/setup.ts @@ -0,0 +1,10 @@ +import { afterAll, beforeAll } from "vitest"; + +import { mockServerPool } from "./MockServerPool"; + +beforeAll(() => { + mockServerPool.listen(); +}); +afterAll(() => { + mockServerPool.close(); +}); diff --git a/skyvern-ts/client/tests/mock-server/withHeaders.ts b/skyvern-ts/client/tests/mock-server/withHeaders.ts new file mode 100644 index 00000000..6599d2b4 --- /dev/null +++ b/skyvern-ts/client/tests/mock-server/withHeaders.ts @@ -0,0 +1,70 @@ +import { type HttpResponseResolver, passthrough } from "msw"; + +/** + * Creates a request matcher that validates if request headers match specified criteria + * @param expectedHeaders - Headers to match against + * @param resolver - Response resolver to execute if headers match + */ +export function withHeaders( + expectedHeaders: Record boolean)>, + resolver: HttpResponseResolver, +): HttpResponseResolver { + return (args) => { + const { request } = args; + const { headers } = request; + + const mismatches: Record< + string, + { actual: string | null; expected: string | RegExp | ((value: string) => boolean) } + > = {}; + + for (const [key, expectedValue] of Object.entries(expectedHeaders)) { + const actualValue = headers.get(key); + + if (actualValue === null) { + mismatches[key] = { actual: null, expected: expectedValue }; + continue; + } + + if (typeof expectedValue === "function") { + if (!expectedValue(actualValue)) { + mismatches[key] = { actual: actualValue, expected: expectedValue }; + } + } else if (expectedValue instanceof RegExp) { + if (!expectedValue.test(actualValue)) { + mismatches[key] = { actual: actualValue, expected: expectedValue }; + } + } else if (expectedValue !== actualValue) { + mismatches[key] = { actual: actualValue, expected: expectedValue }; + } + } + + if (Object.keys(mismatches).length > 0) { + const formattedMismatches = formatHeaderMismatches(mismatches); + console.error("Header mismatch:", formattedMismatches); + return passthrough(); + } + + return resolver(args); + }; +} + +function formatHeaderMismatches( + mismatches: Record boolean) }>, +): Record { + const formatted: Record = {}; + + for (const [key, { actual, expected }] of Object.entries(mismatches)) { + formatted[key] = { + actual, + expected: + expected instanceof RegExp + ? expected.toString() + : typeof expected === "function" + ? "[Function]" + : expected, + }; + } + + return formatted; +} diff --git a/skyvern-ts/client/tests/mock-server/withJson.ts b/skyvern-ts/client/tests/mock-server/withJson.ts new file mode 100644 index 00000000..b627638b --- /dev/null +++ b/skyvern-ts/client/tests/mock-server/withJson.ts @@ -0,0 +1,158 @@ +import { type HttpResponseResolver, passthrough } from "msw"; + +import { fromJson, toJson } from "../../src/core/json"; + +/** + * Creates a request matcher that validates if the request JSON body exactly matches the expected object + * @param expectedBody - The exact body object to match against + * @param resolver - Response resolver to execute if body matches + */ +export function withJson(expectedBody: unknown, resolver: HttpResponseResolver): HttpResponseResolver { + return async (args) => { + const { request } = args; + + let clonedRequest: Request; + let bodyText: string | undefined; + let actualBody: unknown; + try { + clonedRequest = request.clone(); + bodyText = await clonedRequest.text(); + if (bodyText === "") { + console.error("Request body is empty, expected a JSON object."); + return passthrough(); + } + actualBody = fromJson(bodyText); + } catch (error) { + console.error(`Error processing request body:\n\tError: ${error}\n\tBody: ${bodyText}`); + return passthrough(); + } + + const mismatches = findMismatches(actualBody, expectedBody); + if (Object.keys(mismatches).filter((key) => !key.startsWith("pagination.")).length > 0) { + console.error("JSON body mismatch:", toJson(mismatches, undefined, 2)); + return passthrough(); + } + + return resolver(args); + }; +} + +function findMismatches(actual: any, expected: any): Record { + const mismatches: Record = {}; + + if (typeof actual !== typeof expected) { + if (areEquivalent(actual, expected)) { + return {}; + } + return { value: { actual, expected } }; + } + + if (typeof actual !== "object" || actual === null || expected === null) { + if (actual !== expected) { + if (areEquivalent(actual, expected)) { + return {}; + } + return { value: { actual, expected } }; + } + return {}; + } + + if (Array.isArray(actual) && Array.isArray(expected)) { + if (actual.length !== expected.length) { + return { length: { actual: actual.length, expected: expected.length } }; + } + + const arrayMismatches: Record = {}; + for (let i = 0; i < actual.length; i++) { + const itemMismatches = findMismatches(actual[i], expected[i]); + if (Object.keys(itemMismatches).length > 0) { + for (const [mismatchKey, mismatchValue] of Object.entries(itemMismatches)) { + arrayMismatches[`[${i}]${mismatchKey === "value" ? "" : `.${mismatchKey}`}`] = mismatchValue; + } + } + } + return arrayMismatches; + } + + const actualKeys = Object.keys(actual); + const expectedKeys = Object.keys(expected); + + const allKeys = new Set([...actualKeys, ...expectedKeys]); + + for (const key of allKeys) { + if (!expectedKeys.includes(key)) { + if (actual[key] === undefined) { + continue; // Skip undefined values in actual + } + mismatches[key] = { actual: actual[key], expected: undefined }; + } else if (!actualKeys.includes(key)) { + if (expected[key] === undefined) { + continue; // Skip undefined values in expected + } + mismatches[key] = { actual: undefined, expected: expected[key] }; + } else if ( + typeof actual[key] === "object" && + actual[key] !== null && + typeof expected[key] === "object" && + expected[key] !== null + ) { + const nestedMismatches = findMismatches(actual[key], expected[key]); + if (Object.keys(nestedMismatches).length > 0) { + for (const [nestedKey, nestedValue] of Object.entries(nestedMismatches)) { + mismatches[`${key}${nestedKey === "value" ? "" : `.${nestedKey}`}`] = nestedValue; + } + } + } else if (actual[key] !== expected[key]) { + if (areEquivalent(actual[key], expected[key])) { + continue; + } + mismatches[key] = { actual: actual[key], expected: expected[key] }; + } + } + + return mismatches; +} + +function areEquivalent(actual: unknown, expected: unknown): boolean { + if (actual === expected) { + return true; + } + if (isEquivalentBigInt(actual, expected)) { + return true; + } + if (isEquivalentDatetime(actual, expected)) { + return true; + } + return false; +} + +function isEquivalentBigInt(actual: unknown, expected: unknown) { + if (typeof actual === "number") { + actual = BigInt(actual); + } + if (typeof expected === "number") { + expected = BigInt(expected); + } + if (typeof actual === "bigint" && typeof expected === "bigint") { + return actual === expected; + } + return false; +} + +function isEquivalentDatetime(str1: unknown, str2: unknown): boolean { + if (typeof str1 !== "string" || typeof str2 !== "string") { + return false; + } + const isoDatePattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/; + if (!isoDatePattern.test(str1) || !isoDatePattern.test(str2)) { + return false; + } + + try { + const date1 = new Date(str1).getTime(); + const date2 = new Date(str2).getTime(); + return date1 === date2; + } catch { + return false; + } +} diff --git a/skyvern-ts/client/tests/tsconfig.json b/skyvern-ts/client/tests/tsconfig.json new file mode 100644 index 00000000..a477df47 --- /dev/null +++ b/skyvern-ts/client/tests/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": null, + "rootDir": "..", + "baseUrl": "..", + "types": ["vitest/globals"] + }, + "include": ["../src", "../tests"], + "exclude": [] +} diff --git a/skyvern-ts/client/tests/unit/fetcher/Fetcher.test.ts b/skyvern-ts/client/tests/unit/fetcher/Fetcher.test.ts new file mode 100644 index 00000000..bfc64294 --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/Fetcher.test.ts @@ -0,0 +1,255 @@ +import fs from "fs"; +import { join } from "path"; +import stream from "stream"; +import type { BinaryResponse } from "../../../src/core"; +import { type Fetcher, fetcherImpl } from "../../../src/core/fetcher/Fetcher"; + +describe("Test fetcherImpl", () => { + it("should handle successful request", async () => { + const mockArgs: Fetcher.Args = { + url: "https://httpbin.org/post", + method: "POST", + headers: { "X-Test": "x-test-header" }, + body: { data: "test" }, + contentType: "application/json", + requestType: "json", + responseType: "json", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ data: "test" }), { + status: 200, + statusText: "OK", + }), + ); + + const result = await fetcherImpl(mockArgs); + expect(result.ok).toBe(true); + if (result.ok) { + expect(result.body).toEqual({ data: "test" }); + } + + expect(global.fetch).toHaveBeenCalledWith( + "https://httpbin.org/post", + expect.objectContaining({ + method: "POST", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + body: JSON.stringify({ data: "test" }), + }), + ); + }); + + it("should send octet stream", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "POST", + headers: { "X-Test": "x-test-header" }, + contentType: "application/octet-stream", + requestType: "bytes", + responseType: "json", + body: fs.createReadStream(join(__dirname, "test-file.txt")), + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ data: "test" }), { + status: 200, + statusText: "OK", + }), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "POST", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + body: expect.any(fs.ReadStream), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + expect(result.body).toEqual({ data: "test" }); + } + }); + + it("should receive file as stream", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + responseType: "binary-response", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.stream).toBe("function"); + const stream = body.stream(); + expect(stream).toBeInstanceOf(ReadableStream); + const reader = stream.getReader(); + const { value } = await reader.read(); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(value); + expect(streamContent).toBe("This is a test file!\n"); + expect(body.bodyUsed).toBe(true); + } + }); + + it("should receive file as blob", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + responseType: "binary-response", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.blob).toBe("function"); + const blob = await body.blob(); + expect(blob).toBeInstanceOf(Blob); + const reader = blob.stream().getReader(); + const { value } = await reader.read(); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(value); + expect(streamContent).toBe("This is a test file!\n"); + expect(body.bodyUsed).toBe(true); + } + }); + + it("should receive file as arraybuffer", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + responseType: "binary-response", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.arrayBuffer).toBe("function"); + const arrayBuffer = await body.arrayBuffer(); + expect(arrayBuffer).toBeInstanceOf(ArrayBuffer); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(new Uint8Array(arrayBuffer)); + expect(streamContent).toBe("This is a test file!\n"); + expect(body.bodyUsed).toBe(true); + } + }); + + it("should receive file as bytes", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + responseType: "binary-response", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.bytes).toBe("function"); + if (!body.bytes) { + return; + } + const bytes = await body.bytes(); + expect(bytes).toBeInstanceOf(Uint8Array); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(bytes); + expect(streamContent).toBe("This is a test file!\n"); + expect(body.bodyUsed).toBe(true); + } + }); +}); diff --git a/skyvern-ts/client/tests/unit/fetcher/HttpResponsePromise.test.ts b/skyvern-ts/client/tests/unit/fetcher/HttpResponsePromise.test.ts new file mode 100644 index 00000000..2ec008e5 --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/HttpResponsePromise.test.ts @@ -0,0 +1,143 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { HttpResponsePromise } from "../../../src/core/fetcher/HttpResponsePromise"; +import type { RawResponse, WithRawResponse } from "../../../src/core/fetcher/RawResponse"; + +describe("HttpResponsePromise", () => { + const mockRawResponse: RawResponse = { + headers: new Headers(), + redirected: false, + status: 200, + statusText: "OK", + type: "basic" as ResponseType, + url: "https://example.com", + }; + const mockData = { id: "123", name: "test" }; + const mockWithRawResponse: WithRawResponse = { + data: mockData, + rawResponse: mockRawResponse, + }; + + describe("fromFunction", () => { + it("should create an HttpResponsePromise from a function", async () => { + const mockFn = vi + .fn<(arg1: string, arg2: string) => Promise>>() + .mockResolvedValue(mockWithRawResponse); + + const responsePromise = HttpResponsePromise.fromFunction(mockFn, "arg1", "arg2"); + + const result = await responsePromise; + expect(result).toEqual(mockData); + expect(mockFn).toHaveBeenCalledWith("arg1", "arg2"); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("fromPromise", () => { + it("should create an HttpResponsePromise from a promise", async () => { + const promise = Promise.resolve(mockWithRawResponse); + + const responsePromise = HttpResponsePromise.fromPromise(promise); + + const result = await responsePromise; + expect(result).toEqual(mockData); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("fromExecutor", () => { + it("should create an HttpResponsePromise from an executor function", async () => { + const responsePromise = HttpResponsePromise.fromExecutor((resolve) => { + resolve(mockWithRawResponse); + }); + + const result = await responsePromise; + expect(result).toEqual(mockData); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("fromResult", () => { + it("should create an HttpResponsePromise from a result", async () => { + const responsePromise = HttpResponsePromise.fromResult(mockWithRawResponse); + + const result = await responsePromise; + expect(result).toEqual(mockData); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("Promise methods", () => { + let responsePromise: HttpResponsePromise; + + beforeEach(() => { + responsePromise = HttpResponsePromise.fromResult(mockWithRawResponse); + }); + + it("should support then() method", async () => { + const result = await responsePromise.then((data) => ({ + ...data, + modified: true, + })); + + expect(result).toEqual({ + ...mockData, + modified: true, + }); + }); + + it("should support catch() method", async () => { + const errorResponsePromise = HttpResponsePromise.fromExecutor((_, reject) => { + reject(new Error("Test error")); + }); + + const catchSpy = vi.fn(); + await errorResponsePromise.catch(catchSpy); + + expect(catchSpy).toHaveBeenCalled(); + const error = catchSpy.mock.calls[0]?.[0]; + expect(error).toBeInstanceOf(Error); + expect((error as Error).message).toBe("Test error"); + }); + + it("should support finally() method", async () => { + const finallySpy = vi.fn(); + await responsePromise.finally(finallySpy); + + expect(finallySpy).toHaveBeenCalled(); + }); + }); + + describe("withRawResponse", () => { + it("should return both data and raw response", async () => { + const responsePromise = HttpResponsePromise.fromResult(mockWithRawResponse); + + const result = await responsePromise.withRawResponse(); + + expect(result).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); +}); diff --git a/skyvern-ts/client/tests/unit/fetcher/RawResponse.test.ts b/skyvern-ts/client/tests/unit/fetcher/RawResponse.test.ts new file mode 100644 index 00000000..375ee3f3 --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/RawResponse.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; + +import { toRawResponse } from "../../../src/core/fetcher/RawResponse"; + +describe("RawResponse", () => { + describe("toRawResponse", () => { + it("should convert Response to RawResponse by removing body, bodyUsed, and ok properties", () => { + const mockHeaders = new Headers({ "content-type": "application/json" }); + const mockResponse = { + body: "test body", + bodyUsed: false, + ok: true, + headers: mockHeaders, + redirected: false, + status: 200, + statusText: "OK", + type: "basic" as ResponseType, + url: "https://example.com", + }; + + const result = toRawResponse(mockResponse as unknown as Response); + + expect("body" in result).toBe(false); + expect("bodyUsed" in result).toBe(false); + expect("ok" in result).toBe(false); + expect(result.headers).toBe(mockHeaders); + expect(result.redirected).toBe(false); + expect(result.status).toBe(200); + expect(result.statusText).toBe("OK"); + expect(result.type).toBe("basic"); + expect(result.url).toBe("https://example.com"); + }); + }); +}); diff --git a/skyvern-ts/client/tests/unit/fetcher/createRequestUrl.test.ts b/skyvern-ts/client/tests/unit/fetcher/createRequestUrl.test.ts new file mode 100644 index 00000000..06e03b2c --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/createRequestUrl.test.ts @@ -0,0 +1,160 @@ +import { createRequestUrl } from "../../../src/core/fetcher/createRequestUrl"; + +describe("Test createRequestUrl", () => { + it("should return the base URL when no query parameters are provided", () => { + const baseUrl = "https://api.example.com"; + expect(createRequestUrl(baseUrl)).toBe(baseUrl); + }); + + it("should append simple query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { key: "value", another: "param" }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?key=value&another=param"); + }); + + it("should handle array query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { items: ["a", "b", "c"] }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?items=a&items=b&items=c"); + }); + + it("should handle object query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { filter: { name: "John", age: 30 } }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?filter%5Bname%5D=John&filter%5Bage%5D=30", + ); + }); + + it("should handle mixed types of query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + simple: "value", + array: ["x", "y"], + object: { key: "value" }, + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?simple=value&array=x&array=y&object%5Bkey%5D=value", + ); + }); + + it("should handle empty query parameters object", () => { + const baseUrl = "https://api.example.com"; + expect(createRequestUrl(baseUrl, {})).toBe(baseUrl); + }); + + it("should encode special characters in query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { special: "a&b=c d" }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?special=a%26b%3Dc%20d"); + }); + + // Additional tests for edge cases and different value types + it("should handle numeric values", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { count: 42, price: 19.99, active: 1, inactive: 0 }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?count=42&price=19.99&active=1&inactive=0", + ); + }); + + it("should handle boolean values", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { enabled: true, disabled: false }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?enabled=true&disabled=false"); + }); + + it("should handle null and undefined values", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + valid: "value", + nullValue: null, + undefinedValue: undefined, + emptyString: "", + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?valid=value&nullValue=&emptyString=", + ); + }); + + it("should handle deeply nested objects", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + user: { + profile: { + name: "John", + settings: { theme: "dark" }, + }, + }, + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?user%5Bprofile%5D%5Bname%5D=John&user%5Bprofile%5D%5Bsettings%5D%5Btheme%5D=dark", + ); + }); + + it("should handle arrays of objects", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + users: [ + { name: "John", age: 30 }, + { name: "Jane", age: 25 }, + ], + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?users%5Bname%5D=John&users%5Bage%5D=30&users%5Bname%5D=Jane&users%5Bage%5D=25", + ); + }); + + it("should handle mixed arrays", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + mixed: ["string", 42, true, { key: "value" }], + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?mixed=string&mixed=42&mixed=true&mixed%5Bkey%5D=value", + ); + }); + + it("should handle empty arrays", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { emptyArray: [] }; + expect(createRequestUrl(baseUrl, queryParams)).toBe(baseUrl); + }); + + it("should handle empty objects", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { emptyObject: {} }; + expect(createRequestUrl(baseUrl, queryParams)).toBe(baseUrl); + }); + + it("should handle special characters in keys", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { "key with spaces": "value", "key[with]brackets": "value" }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?key%20with%20spaces=value&key%5Bwith%5Dbrackets=value", + ); + }); + + it("should handle URL with existing query parameters", () => { + const baseUrl = "https://api.example.com?existing=param"; + const queryParams = { new: "value" }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?existing=param?new=value"); + }); + + it("should handle complex nested structures", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + filters: { + status: ["active", "pending"], + category: { + type: "electronics", + subcategories: ["phones", "laptops"], + }, + }, + sort: { field: "name", direction: "asc" }, + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?filters%5Bstatus%5D=active&filters%5Bstatus%5D=pending&filters%5Bcategory%5D%5Btype%5D=electronics&filters%5Bcategory%5D%5Bsubcategories%5D=phones&filters%5Bcategory%5D%5Bsubcategories%5D=laptops&sort%5Bfield%5D=name&sort%5Bdirection%5D=asc", + ); + }); +}); diff --git a/skyvern-ts/client/tests/unit/fetcher/getRequestBody.test.ts b/skyvern-ts/client/tests/unit/fetcher/getRequestBody.test.ts new file mode 100644 index 00000000..e864c8b5 --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/getRequestBody.test.ts @@ -0,0 +1,65 @@ +import { getRequestBody } from "../../../src/core/fetcher/getRequestBody"; +import { RUNTIME } from "../../../src/core/runtime"; + +describe("Test getRequestBody", () => { + it("should stringify body if not FormData in Node environment", async () => { + if (RUNTIME.type === "node") { + const body = { key: "value" }; + const result = await getRequestBody({ + body, + type: "json", + }); + expect(result).toBe('{"key":"value"}'); + } + }); + + it("should return FormData in browser environment", async () => { + if (RUNTIME.type === "browser") { + const formData = new FormData(); + formData.append("key", "value"); + const result = await getRequestBody({ + body: formData, + type: "file", + }); + expect(result).toBe(formData); + } + }); + + it("should stringify body if not FormData in browser environment", async () => { + if (RUNTIME.type === "browser") { + const body = { key: "value" }; + const result = await getRequestBody({ + body, + type: "json", + }); + expect(result).toBe('{"key":"value"}'); + } + }); + + it("should return the Uint8Array", async () => { + const input = new Uint8Array([1, 2, 3]); + const result = await getRequestBody({ + body: input, + type: "bytes", + }); + expect(result).toBe(input); + }); + + it("should return the input for content-type 'application/x-www-form-urlencoded'", async () => { + const input = "key=value&another=param"; + const result = await getRequestBody({ + body: input, + type: "other", + }); + expect(result).toBe(input); + }); + + it("should JSON stringify objects", async () => { + const input = { key: "value" }; + const result = await getRequestBody({ + body: input, + type: "json", + }); + expect(result).toBe('{"key":"value"}'); + }); +}); diff --git a/skyvern-ts/client/tests/unit/fetcher/getResponseBody.test.ts b/skyvern-ts/client/tests/unit/fetcher/getResponseBody.test.ts new file mode 100644 index 00000000..151843ae --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/getResponseBody.test.ts @@ -0,0 +1,77 @@ +import { getResponseBody } from "../../../src/core/fetcher/getResponseBody"; +import { RUNTIME } from "../../../src/core/runtime"; + +describe("Test getResponseBody", () => { + it("should handle blob response type", async () => { + const mockBlob = new Blob(["test"], { type: "text/plain" }); + const mockResponse = new Response(mockBlob); + const result = await getResponseBody(mockResponse, "blob"); + // @ts-expect-error + expect(result.constructor.name).toBe("Blob"); + }); + + it("should handle sse response type", async () => { + if (RUNTIME.type === "node") { + const mockStream = new ReadableStream(); + const mockResponse = new Response(mockStream); + const result = await getResponseBody(mockResponse, "sse"); + expect(result).toBe(mockStream); + } + }); + + it("should handle streaming response type", async () => { + // Create a ReadableStream with some test data + const encoder = new TextEncoder(); + const testData = "test stream data"; + const mockStream = new ReadableStream({ + start(controller) { + controller.enqueue(encoder.encode(testData)); + controller.close(); + }, + }); + + const mockResponse = new Response(mockStream); + const result = (await getResponseBody(mockResponse, "streaming")) as ReadableStream; + + expect(result).toBeInstanceOf(ReadableStream); + + // Read and verify the stream content + const reader = result.getReader(); + const decoder = new TextDecoder(); + const { value } = await reader.read(); + const streamContent = decoder.decode(value); + expect(streamContent).toBe(testData); + }); + + it("should handle text response type", async () => { + const mockResponse = new Response("test text"); + const result = await getResponseBody(mockResponse, "text"); + expect(result).toBe("test text"); + }); + + it("should handle JSON response", async () => { + const mockJson = { key: "value" }; + const mockResponse = new Response(JSON.stringify(mockJson)); + const result = await getResponseBody(mockResponse); + expect(result).toEqual(mockJson); + }); + + it("should handle empty response", async () => { + const mockResponse = new Response(""); + const result = await getResponseBody(mockResponse); + expect(result).toBeUndefined(); + }); + + it("should handle non-JSON response", async () => { + const mockResponse = new Response("invalid json"); + const result = await getResponseBody(mockResponse); + expect(result).toEqual({ + ok: false, + error: { + reason: "non-json", + statusCode: 200, + rawBody: "invalid json", + }, + }); + }); +}); diff --git a/skyvern-ts/client/tests/unit/fetcher/makeRequest.test.ts b/skyvern-ts/client/tests/unit/fetcher/makeRequest.test.ts new file mode 100644 index 00000000..f6203cdc --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/makeRequest.test.ts @@ -0,0 +1,53 @@ +import { makeRequest } from "../../../src/core/fetcher/makeRequest"; + +describe("Test makeRequest", () => { + const mockPostUrl = "https://httpbin.org/post"; + const mockGetUrl = "https://httpbin.org/get"; + const mockHeaders = { "Content-Type": "application/json" }; + const mockBody = JSON.stringify({ key: "value" }); + + let mockFetch: import("vitest").Mock; + + beforeEach(() => { + mockFetch = vi.fn(); + mockFetch.mockResolvedValue(new Response(JSON.stringify({ test: "successful" }), { status: 200 })); + }); + + it("should handle POST request correctly", async () => { + const response = await makeRequest(mockFetch, mockPostUrl, "POST", mockHeaders, mockBody); + const responseBody = await response.json(); + expect(responseBody).toEqual({ test: "successful" }); + expect(mockFetch).toHaveBeenCalledTimes(1); + const [calledUrl, calledOptions] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe(mockPostUrl); + expect(calledOptions).toEqual( + expect.objectContaining({ + method: "POST", + headers: mockHeaders, + body: mockBody, + credentials: undefined, + }), + ); + expect(calledOptions.signal).toBeDefined(); + expect(calledOptions.signal).toBeInstanceOf(AbortSignal); + }); + + it("should handle GET request correctly", async () => { + const response = await makeRequest(mockFetch, mockGetUrl, "GET", mockHeaders, undefined); + const responseBody = await response.json(); + expect(responseBody).toEqual({ test: "successful" }); + expect(mockFetch).toHaveBeenCalledTimes(1); + const [calledUrl, calledOptions] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe(mockGetUrl); + expect(calledOptions).toEqual( + expect.objectContaining({ + method: "GET", + headers: mockHeaders, + body: undefined, + credentials: undefined, + }), + ); + expect(calledOptions.signal).toBeDefined(); + expect(calledOptions.signal).toBeInstanceOf(AbortSignal); + }); +}); diff --git a/skyvern-ts/client/tests/unit/fetcher/requestWithRetries.test.ts b/skyvern-ts/client/tests/unit/fetcher/requestWithRetries.test.ts new file mode 100644 index 00000000..7d46082d --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/requestWithRetries.test.ts @@ -0,0 +1,250 @@ +import { requestWithRetries } from "../../../src/core/fetcher/requestWithRetries"; + +describe("requestWithRetries", () => { + let mockFetch: import("vitest").Mock; + let originalMathRandom: typeof Math.random; + let setTimeoutSpy: import("vitest").MockInstance; + + beforeEach(() => { + mockFetch = vi.fn(); + originalMathRandom = Math.random; + + // Mock Math.random for consistent jitter + Math.random = vi.fn(() => 0.5); + + vi.useFakeTimers({ + toFake: [ + "setTimeout", + "clearTimeout", + "setInterval", + "clearInterval", + "setImmediate", + "clearImmediate", + "Date", + "performance", + "requestAnimationFrame", + "cancelAnimationFrame", + "requestIdleCallback", + "cancelIdleCallback", + ], + }); + }); + + afterEach(() => { + Math.random = originalMathRandom; + vi.clearAllMocks(); + vi.clearAllTimers(); + }); + + it("should retry on retryable status codes", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const retryableStatuses = [408, 429, 500, 502]; + let callCount = 0; + + mockFetch.mockImplementation(async () => { + if (callCount < retryableStatuses.length) { + return new Response("", { status: retryableStatuses[callCount++] }); + } + return new Response("", { status: 200 }); + }); + + const responsePromise = requestWithRetries(() => mockFetch(), retryableStatuses.length); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(retryableStatuses.length + 1); + expect(response.status).toBe(200); + }); + + it("should respect maxRetries limit", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const maxRetries = 2; + mockFetch.mockResolvedValue(new Response("", { status: 500 })); + + const responsePromise = requestWithRetries(() => mockFetch(), maxRetries); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(maxRetries + 1); + expect(response.status).toBe(500); + }); + + it("should not retry on success status codes", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const successStatuses = [200, 201, 202]; + + for (const status of successStatuses) { + mockFetch.mockReset(); + setTimeoutSpy.mockClear(); + mockFetch.mockResolvedValueOnce(new Response("", { status })); + + const responsePromise = requestWithRetries(() => mockFetch(), 3); + await vi.runAllTimersAsync(); + await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(1); + expect(setTimeoutSpy).not.toHaveBeenCalled(); + } + }); + + it("should apply correct exponential backoff with jitter", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch.mockResolvedValue(new Response("", { status: 500 })); + const maxRetries = 3; + const expectedDelays = [1000, 2000, 4000]; + + const responsePromise = requestWithRetries(() => mockFetch(), maxRetries); + await vi.runAllTimersAsync(); + await responsePromise; + + // Verify setTimeout calls + expect(setTimeoutSpy).toHaveBeenCalledTimes(expectedDelays.length); + + expectedDelays.forEach((delay, index) => { + expect(setTimeoutSpy).toHaveBeenNthCalledWith(index + 1, expect.any(Function), delay); + }); + + expect(mockFetch).toHaveBeenCalledTimes(maxRetries + 1); + }); + + it("should handle concurrent retries independently", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce(new Response("", { status: 500 })) + .mockResolvedValueOnce(new Response("", { status: 500 })) + .mockResolvedValueOnce(new Response("", { status: 200 })) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const promise1 = requestWithRetries(() => mockFetch(), 1); + const promise2 = requestWithRetries(() => mockFetch(), 1); + + await vi.runAllTimersAsync(); + const [response1, response2] = await Promise.all([promise1, promise2]); + + expect(response1.status).toBe(200); + expect(response2.status).toBe(200); + }); + + it("should respect retry-after header with seconds value", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ "retry-after": "5" }), + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 5000); // 5 seconds = 5000ms + expect(response.status).toBe(200); + }); + + it("should respect retry-after header with HTTP date value", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const futureDate = new Date(Date.now() + 3000); // 3 seconds from now + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ "retry-after": futureDate.toUTCString() }), + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + // Should use the date-based delay (approximately 3000ms, but with jitter) + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), expect.any(Number)); + const actualDelay = setTimeoutSpy.mock.calls[0][1]; + expect(actualDelay).toBeGreaterThan(2000); + expect(actualDelay).toBeLessThan(4000); + expect(response.status).toBe(200); + }); + + it("should respect x-ratelimit-reset header", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const resetTime = Math.floor((Date.now() + 4000) / 1000); // 4 seconds from now in Unix timestamp + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ "x-ratelimit-reset": resetTime.toString() }), + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + // Should use the x-ratelimit-reset delay (approximately 4000ms, but with positive jitter) + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), expect.any(Number)); + const actualDelay = setTimeoutSpy.mock.calls[0][1]; + expect(actualDelay).toBeGreaterThan(3000); + expect(actualDelay).toBeLessThan(6000); + expect(response.status).toBe(200); + }); + + it("should cap delay at MAX_RETRY_DELAY for large header values", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ "retry-after": "120" }), // 120 seconds = 120000ms > MAX_RETRY_DELAY (60000ms) + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + // Should be capped at MAX_RETRY_DELAY (60000ms) with jitter applied + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 60000); // Exactly MAX_RETRY_DELAY since jitter with 0.5 random keeps it at 60000 + expect(response.status).toBe(200); + }); +}); diff --git a/skyvern-ts/client/tests/unit/fetcher/signals.test.ts b/skyvern-ts/client/tests/unit/fetcher/signals.test.ts new file mode 100644 index 00000000..d7b6d1e6 --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/signals.test.ts @@ -0,0 +1,69 @@ +import { anySignal, getTimeoutSignal } from "../../../src/core/fetcher/signals"; + +describe("Test getTimeoutSignal", () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("should return an object with signal and abortId", () => { + const { signal, abortId } = getTimeoutSignal(1000); + + expect(signal).toBeDefined(); + expect(abortId).toBeDefined(); + expect(signal).toBeInstanceOf(AbortSignal); + expect(signal.aborted).toBe(false); + }); + + it("should create a signal that aborts after the specified timeout", () => { + const timeoutMs = 5000; + const { signal } = getTimeoutSignal(timeoutMs); + + expect(signal.aborted).toBe(false); + + vi.advanceTimersByTime(timeoutMs - 1); + expect(signal.aborted).toBe(false); + + vi.advanceTimersByTime(1); + expect(signal.aborted).toBe(true); + }); +}); + +describe("Test anySignal", () => { + it("should return an AbortSignal", () => { + const signal = anySignal(new AbortController().signal); + expect(signal).toBeInstanceOf(AbortSignal); + }); + + it("should abort when any of the input signals is aborted", () => { + const controller1 = new AbortController(); + const controller2 = new AbortController(); + const signal = anySignal(controller1.signal, controller2.signal); + + expect(signal.aborted).toBe(false); + controller1.abort(); + expect(signal.aborted).toBe(true); + }); + + it("should handle an array of signals", () => { + const controller1 = new AbortController(); + const controller2 = new AbortController(); + const signal = anySignal([controller1.signal, controller2.signal]); + + expect(signal.aborted).toBe(false); + controller2.abort(); + expect(signal.aborted).toBe(true); + }); + + it("should abort immediately if one of the input signals is already aborted", () => { + const controller1 = new AbortController(); + const controller2 = new AbortController(); + controller1.abort(); + + const signal = anySignal(controller1.signal, controller2.signal); + expect(signal.aborted).toBe(true); + }); +}); diff --git a/skyvern-ts/client/tests/unit/fetcher/test-file.txt b/skyvern-ts/client/tests/unit/fetcher/test-file.txt new file mode 100644 index 00000000..c66d471e --- /dev/null +++ b/skyvern-ts/client/tests/unit/fetcher/test-file.txt @@ -0,0 +1 @@ +This is a test file! diff --git a/skyvern-ts/client/tests/unit/url/join.test.ts b/skyvern-ts/client/tests/unit/url/join.test.ts new file mode 100644 index 00000000..1956a8c0 --- /dev/null +++ b/skyvern-ts/client/tests/unit/url/join.test.ts @@ -0,0 +1,120 @@ +import { join } from "../../../src/core/url/index"; + +describe("join", () => { + describe("basic functionality", () => { + it("should return empty string for empty base", () => { + expect(join("")).toBe(""); + expect(join("", "path")).toBe(""); + }); + + it("should handle single segment", () => { + expect(join("base", "segment")).toBe("base/segment"); + expect(join("base/", "segment")).toBe("base/segment"); + expect(join("base", "/segment")).toBe("base/segment"); + expect(join("base/", "/segment")).toBe("base/segment"); + }); + + it("should handle multiple segments", () => { + expect(join("base", "path1", "path2", "path3")).toBe("base/path1/path2/path3"); + expect(join("base/", "/path1/", "/path2/", "/path3/")).toBe("base/path1/path2/path3/"); + }); + }); + + describe("URL handling", () => { + it("should handle absolute URLs", () => { + expect(join("https://example.com", "api", "v1")).toBe("https://example.com/api/v1"); + expect(join("https://example.com/", "/api/", "/v1/")).toBe("https://example.com/api/v1/"); + expect(join("https://example.com/base", "api", "v1")).toBe("https://example.com/base/api/v1"); + }); + + it("should preserve URL query parameters and fragments", () => { + expect(join("https://example.com?query=1", "api")).toBe("https://example.com/api?query=1"); + expect(join("https://example.com#fragment", "api")).toBe("https://example.com/api#fragment"); + expect(join("https://example.com?query=1#fragment", "api")).toBe( + "https://example.com/api?query=1#fragment", + ); + }); + + it("should handle different protocols", () => { + expect(join("http://example.com", "api")).toBe("http://example.com/api"); + expect(join("ftp://example.com", "files")).toBe("ftp://example.com/files"); + expect(join("ws://example.com", "socket")).toBe("ws://example.com/socket"); + }); + + it("should fallback to path joining for malformed URLs", () => { + expect(join("not-a-url://", "path")).toBe("not-a-url:///path"); + }); + }); + + describe("edge cases", () => { + it("should handle empty segments", () => { + expect(join("base", "", "path")).toBe("base/path"); + expect(join("base", null as any, "path")).toBe("base/path"); + expect(join("base", undefined as any, "path")).toBe("base/path"); + }); + + it("should handle segments with only slashes", () => { + expect(join("base", "/", "path")).toBe("base/path"); + expect(join("base", "//", "path")).toBe("base/path"); + }); + + it("should handle base paths with trailing slashes", () => { + expect(join("base/", "path")).toBe("base/path"); + }); + + it("should handle complex nested paths", () => { + expect(join("api/v1/", "/users/", "/123/", "/profile")).toBe("api/v1/users/123/profile"); + }); + }); + + describe("real-world scenarios", () => { + it("should handle API endpoint construction", () => { + const baseUrl = "https://api.example.com/v1"; + expect(join(baseUrl, "users", "123", "posts")).toBe("https://api.example.com/v1/users/123/posts"); + }); + + it("should handle file path construction", () => { + expect(join("/var/www", "html", "assets", "images")).toBe("/var/www/html/assets/images"); + }); + + it("should handle relative path construction", () => { + expect(join("../parent", "child", "grandchild")).toBe("../parent/child/grandchild"); + }); + + it("should handle Windows-style paths", () => { + expect(join("C:\\Users", "Documents", "file.txt")).toBe("C:\\Users/Documents/file.txt"); + }); + }); + + describe("performance scenarios", () => { + it("should handle many segments efficiently", () => { + const segments = Array(100).fill("segment"); + const result = join("base", ...segments); + expect(result).toBe(`base/${segments.join("/")}`); + }); + + it("should handle long URLs", () => { + const longPath = "a".repeat(1000); + expect(join("https://example.com", longPath)).toBe(`https://example.com/${longPath}`); + }); + }); + + describe("trailing slash preservation", () => { + it("should preserve trailing slash on final result when base has trailing slash and no segments", () => { + expect(join("https://api.example.com/")).toBe("https://api.example.com/"); + expect(join("https://api.example.com/v1/")).toBe("https://api.example.com/v1/"); + }); + + it("should preserve trailing slash when last segment has trailing slash", () => { + expect(join("https://api.example.com", "users/")).toBe("https://api.example.com/users/"); + expect(join("api/v1", "users/")).toBe("api/v1/users/"); + }); + + it("should preserve trailing slash with multiple segments where last has trailing slash", () => { + expect(join("https://api.example.com", "v1", "collections/")).toBe( + "https://api.example.com/v1/collections/", + ); + expect(join("base", "path1", "path2/")).toBe("base/path1/path2/"); + }); + }); +}); diff --git a/skyvern-ts/client/tests/unit/url/qs.test.ts b/skyvern-ts/client/tests/unit/url/qs.test.ts new file mode 100644 index 00000000..80e7e044 --- /dev/null +++ b/skyvern-ts/client/tests/unit/url/qs.test.ts @@ -0,0 +1,187 @@ +import { toQueryString } from "../../../src/core/url/index"; + +describe("Test qs toQueryString", () => { + describe("Basic functionality", () => { + it("should return empty string for null/undefined", () => { + expect(toQueryString(null)).toBe(""); + expect(toQueryString(undefined)).toBe(""); + }); + + it("should return empty string for primitive values", () => { + expect(toQueryString("hello")).toBe(""); + expect(toQueryString(42)).toBe(""); + expect(toQueryString(true)).toBe(""); + expect(toQueryString(false)).toBe(""); + }); + + it("should handle empty objects", () => { + expect(toQueryString({})).toBe(""); + }); + + it("should handle simple key-value pairs", () => { + const obj = { name: "John", age: 30 }; + expect(toQueryString(obj)).toBe("name=John&age=30"); + }); + }); + + describe("Array handling", () => { + it("should handle arrays with indices format (default)", () => { + const obj = { items: ["a", "b", "c"] }; + expect(toQueryString(obj)).toBe("items%5B0%5D=a&items%5B1%5D=b&items%5B2%5D=c"); + }); + + it("should handle arrays with repeat format", () => { + const obj = { items: ["a", "b", "c"] }; + expect(toQueryString(obj, { arrayFormat: "repeat" })).toBe("items=a&items=b&items=c"); + }); + + it("should handle empty arrays", () => { + const obj = { items: [] }; + expect(toQueryString(obj)).toBe(""); + }); + + it("should handle arrays with mixed types", () => { + const obj = { mixed: ["string", 42, true, false] }; + expect(toQueryString(obj)).toBe("mixed%5B0%5D=string&mixed%5B1%5D=42&mixed%5B2%5D=true&mixed%5B3%5D=false"); + }); + + it("should handle arrays with objects", () => { + const obj = { users: [{ name: "John" }, { name: "Jane" }] }; + expect(toQueryString(obj)).toBe("users%5B0%5D%5Bname%5D=John&users%5B1%5D%5Bname%5D=Jane"); + }); + + it("should handle arrays with objects in repeat format", () => { + const obj = { users: [{ name: "John" }, { name: "Jane" }] }; + expect(toQueryString(obj, { arrayFormat: "repeat" })).toBe("users%5Bname%5D=John&users%5Bname%5D=Jane"); + }); + }); + + describe("Nested objects", () => { + it("should handle nested objects", () => { + const obj = { user: { name: "John", age: 30 } }; + expect(toQueryString(obj)).toBe("user%5Bname%5D=John&user%5Bage%5D=30"); + }); + + it("should handle deeply nested objects", () => { + const obj = { user: { profile: { name: "John", settings: { theme: "dark" } } } }; + expect(toQueryString(obj)).toBe( + "user%5Bprofile%5D%5Bname%5D=John&user%5Bprofile%5D%5Bsettings%5D%5Btheme%5D=dark", + ); + }); + + it("should handle empty nested objects", () => { + const obj = { user: {} }; + expect(toQueryString(obj)).toBe(""); + }); + }); + + describe("Encoding", () => { + it("should encode by default", () => { + const obj = { name: "John Doe", email: "john@example.com" }; + expect(toQueryString(obj)).toBe("name=John%20Doe&email=john%40example.com"); + }); + + it("should not encode when encode is false", () => { + const obj = { name: "John Doe", email: "john@example.com" }; + expect(toQueryString(obj, { encode: false })).toBe("name=John Doe&email=john@example.com"); + }); + + it("should encode special characters in keys", () => { + const obj = { "user name": "John", "email[primary]": "john@example.com" }; + expect(toQueryString(obj)).toBe("user%20name=John&email%5Bprimary%5D=john%40example.com"); + }); + + it("should not encode special characters in keys when encode is false", () => { + const obj = { "user name": "John", "email[primary]": "john@example.com" }; + expect(toQueryString(obj, { encode: false })).toBe("user name=John&email[primary]=john@example.com"); + }); + }); + + describe("Mixed scenarios", () => { + it("should handle complex nested structures", () => { + const obj = { + filters: { + status: ["active", "pending"], + category: { + type: "electronics", + subcategories: ["phones", "laptops"], + }, + }, + sort: { field: "name", direction: "asc" }, + }; + expect(toQueryString(obj)).toBe( + "filters%5Bstatus%5D%5B0%5D=active&filters%5Bstatus%5D%5B1%5D=pending&filters%5Bcategory%5D%5Btype%5D=electronics&filters%5Bcategory%5D%5Bsubcategories%5D%5B0%5D=phones&filters%5Bcategory%5D%5Bsubcategories%5D%5B1%5D=laptops&sort%5Bfield%5D=name&sort%5Bdirection%5D=asc", + ); + }); + + it("should handle complex nested structures with repeat format", () => { + const obj = { + filters: { + status: ["active", "pending"], + category: { + type: "electronics", + subcategories: ["phones", "laptops"], + }, + }, + sort: { field: "name", direction: "asc" }, + }; + expect(toQueryString(obj, { arrayFormat: "repeat" })).toBe( + "filters%5Bstatus%5D=active&filters%5Bstatus%5D=pending&filters%5Bcategory%5D%5Btype%5D=electronics&filters%5Bcategory%5D%5Bsubcategories%5D=phones&filters%5Bcategory%5D%5Bsubcategories%5D=laptops&sort%5Bfield%5D=name&sort%5Bdirection%5D=asc", + ); + }); + + it("should handle arrays with null/undefined values", () => { + const obj = { items: ["a", null, "c", undefined, "e"] }; + expect(toQueryString(obj)).toBe("items%5B0%5D=a&items%5B1%5D=&items%5B2%5D=c&items%5B4%5D=e"); + }); + + it("should handle objects with null/undefined values", () => { + const obj = { name: "John", age: null, email: undefined, active: true }; + expect(toQueryString(obj)).toBe("name=John&age=&active=true"); + }); + }); + + describe("Edge cases", () => { + it("should handle numeric keys", () => { + const obj = { "0": "zero", "1": "one" }; + expect(toQueryString(obj)).toBe("0=zero&1=one"); + }); + + it("should handle boolean values in objects", () => { + const obj = { enabled: true, disabled: false }; + expect(toQueryString(obj)).toBe("enabled=true&disabled=false"); + }); + + it("should handle empty strings", () => { + const obj = { name: "", description: "test" }; + expect(toQueryString(obj)).toBe("name=&description=test"); + }); + + it("should handle zero values", () => { + const obj = { count: 0, price: 0.0 }; + expect(toQueryString(obj)).toBe("count=0&price=0"); + }); + + it("should handle arrays with empty strings", () => { + const obj = { items: ["a", "", "c"] }; + expect(toQueryString(obj)).toBe("items%5B0%5D=a&items%5B1%5D=&items%5B2%5D=c"); + }); + }); + + describe("Options combinations", () => { + it("should respect both arrayFormat and encode options", () => { + const obj = { items: ["a & b", "c & d"] }; + expect(toQueryString(obj, { arrayFormat: "repeat", encode: false })).toBe("items=a & b&items=c & d"); + }); + + it("should use default options when none provided", () => { + const obj = { items: ["a", "b"] }; + expect(toQueryString(obj)).toBe("items%5B0%5D=a&items%5B1%5D=b"); + }); + + it("should merge provided options with defaults", () => { + const obj = { items: ["a", "b"], name: "John Doe" }; + expect(toQueryString(obj, { encode: false })).toBe("items[0]=a&items[1]=b&name=John Doe"); + }); + }); +}); diff --git a/skyvern-ts/client/tests/wire/.gitkeep b/skyvern-ts/client/tests/wire/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/skyvern-ts/client/tests/wire/main.test.ts b/skyvern-ts/client/tests/wire/main.test.ts new file mode 100644 index 00000000..c773ade7 --- /dev/null +++ b/skyvern-ts/client/tests/wire/main.test.ts @@ -0,0 +1,2426 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as Skyvern from "../../src/api/index"; +import { SkyvernClient } from "../../src/Client"; +import { mockServerPool } from "../mock-server/MockServerPool"; + +describe("SkyvernClient", () => { + test("run_task (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { prompt: "Find the top 3 posts on Hacker News." }; + const rawResponseBody = { + run_id: "tsk_123", + status: "created", + output: { key: "value" }, + downloaded_files: [ + { url: "url", checksum: "checksum", filename: "filename", modified_at: "2024-01-15T09:30:00Z" }, + ], + recording_url: "recording_url", + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + script_run: { ai_fallback_triggered: true }, + errors: [{ key: "value" }], + run_request: { + prompt: "Find the top 3 posts on Hacker News.", + url: "url", + engine: "skyvern-1.0", + title: "title", + proxy_location: "RESIDENTIAL", + data_extraction_schema: { key: "value" }, + error_code_mapping: { key: "value" }, + max_steps: 1, + webhook_url: "webhook_url", + totp_identifier: "totp_identifier", + totp_url: "totp_url", + browser_session_id: "browser_session_id", + model: { key: "value" }, + extra_http_headers: { key: "value" }, + publish_workflow: true, + include_action_history_in_verification: true, + max_screenshot_scrolls: 1, + browser_address: "browser_address", + }, + }; + server + .mockEndpoint() + .post("/v1/run/tasks") + .header("x-user-agent", "x-user-agent") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.runTask({ + "x-user-agent": "x-user-agent", + body: { + prompt: "Find the top 3 posts on Hacker News.", + }, + }); + expect(response).toEqual({ + run_id: "tsk_123", + status: "created", + output: { + key: "value", + }, + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + recording_url: "recording_url", + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + script_run: { + ai_fallback_triggered: true, + }, + errors: [ + { + key: "value", + }, + ], + run_request: { + prompt: "Find the top 3 posts on Hacker News.", + url: "url", + engine: "skyvern-1.0", + title: "title", + proxy_location: "RESIDENTIAL", + data_extraction_schema: { + key: "value", + }, + error_code_mapping: { + key: "value", + }, + max_steps: 1, + webhook_url: "webhook_url", + totp_identifier: "totp_identifier", + totp_url: "totp_url", + browser_session_id: "browser_session_id", + model: { + key: "value", + }, + extra_http_headers: { + key: "value", + }, + publish_workflow: true, + include_action_history_in_verification: true, + max_screenshot_scrolls: 1, + browser_address: "browser_address", + }, + }); + }); + + test("run_task (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { prompt: "prompt" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/run/tasks") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.runTask({ + body: { + prompt: "prompt", + }, + }); + }).rejects.toThrow(Skyvern.BadRequestError); + }); + + test("run_task (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { prompt: "prompt" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/run/tasks") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.runTask({ + body: { + prompt: "prompt", + }, + }); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("run_workflow (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { workflow_id: "wpid_123" }; + const rawResponseBody = { + run_id: "tsk_123", + status: "created", + output: { key: "value" }, + downloaded_files: [ + { url: "url", checksum: "checksum", filename: "filename", modified_at: "2024-01-15T09:30:00Z" }, + ], + recording_url: "recording_url", + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + script_run: { ai_fallback_triggered: true }, + errors: [{ key: "value" }], + run_with: "run_with", + ai_fallback: true, + run_request: { + workflow_id: "wpid_123", + parameters: { key: "value" }, + title: "title", + proxy_location: "RESIDENTIAL", + webhook_url: "webhook_url", + totp_url: "totp_url", + totp_identifier: "totp_identifier", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + extra_http_headers: { key: "value" }, + browser_address: "browser_address", + ai_fallback: true, + run_with: "run_with", + }, + }; + server + .mockEndpoint() + .post("/v1/run/workflows") + .header("x-max-steps-override", "1") + .header("x-user-agent", "x-user-agent") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.runWorkflow({ + "x-max-steps-override": 1, + "x-user-agent": "x-user-agent", + template: true, + body: { + workflow_id: "wpid_123", + }, + }); + expect(response).toEqual({ + run_id: "tsk_123", + status: "created", + output: { + key: "value", + }, + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + recording_url: "recording_url", + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + script_run: { + ai_fallback_triggered: true, + }, + errors: [ + { + key: "value", + }, + ], + run_with: "run_with", + ai_fallback: true, + run_request: { + workflow_id: "wpid_123", + parameters: { + key: "value", + }, + title: "title", + proxy_location: "RESIDENTIAL", + webhook_url: "webhook_url", + totp_url: "totp_url", + totp_identifier: "totp_identifier", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + extra_http_headers: { + key: "value", + }, + browser_address: "browser_address", + ai_fallback: true, + run_with: "run_with", + }, + }); + }); + + test("run_workflow (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { workflow_id: "workflow_id" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/run/workflows") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.runWorkflow({ + body: { + workflow_id: "workflow_id", + }, + }); + }).rejects.toThrow(Skyvern.BadRequestError); + }); + + test("run_workflow (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { workflow_id: "workflow_id" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/run/workflows") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.runWorkflow({ + body: { + workflow_id: "workflow_id", + }, + }); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_run (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + run_type: "task_v1", + run_id: "tsk_123", + status: "created", + output: { key: "value" }, + downloaded_files: [ + { url: "url", checksum: "checksum", filename: "filename", modified_at: "2024-01-15T09:30:00Z" }, + ], + recording_url: "recording_url", + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + script_run: { ai_fallback_triggered: true }, + errors: [{ key: "value" }], + run_request: { + prompt: "Find the top 3 posts on Hacker News.", + url: "url", + engine: "skyvern-1.0", + title: "title", + proxy_location: "RESIDENTIAL", + data_extraction_schema: { key: "value" }, + error_code_mapping: { key: "value" }, + max_steps: 1, + webhook_url: "webhook_url", + totp_identifier: "totp_identifier", + totp_url: "totp_url", + browser_session_id: "browser_session_id", + model: { key: "value" }, + extra_http_headers: { key: "value" }, + publish_workflow: true, + include_action_history_in_verification: true, + max_screenshot_scrolls: 1, + browser_address: "browser_address", + }, + }; + server.mockEndpoint().get("/v1/runs/tsk_123").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.getRun("tsk_123"); + expect(response).toEqual({ + run_type: "task_v1", + run_id: "tsk_123", + status: "created", + output: { + key: "value", + }, + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + recording_url: "recording_url", + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + script_run: { + ai_fallback_triggered: true, + }, + errors: [ + { + key: "value", + }, + ], + run_request: { + prompt: "Find the top 3 posts on Hacker News.", + url: "url", + engine: "skyvern-1.0", + title: "title", + proxy_location: "RESIDENTIAL", + data_extraction_schema: { + key: "value", + }, + error_code_mapping: { + key: "value", + }, + max_steps: 1, + webhook_url: "webhook_url", + totp_identifier: "totp_identifier", + totp_url: "totp_url", + browser_session_id: "browser_session_id", + model: { + key: "value", + }, + extra_http_headers: { + key: "value", + }, + publish_workflow: true, + include_action_history_in_verification: true, + max_screenshot_scrolls: 1, + browser_address: "browser_address", + }, + }); + }); + + test("get_run (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/runs/run_id").respondWith().statusCode(404).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.getRun("run_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("get_run (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/runs/run_id").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.getRun("run_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("cancel_run (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/runs/run_id/cancel") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.cancelRun("run_id"); + expect(response).toEqual({ + key: "value", + }); + }); + + test("cancel_run (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/runs/run_id/cancel") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.cancelRun("run_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_workflows (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + description: "description", + workflow_definition: { + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + model: { key: "value" }, + status: "published", + max_screenshot_scrolls: 1, + extra_http_headers: { key: "value" }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + run_sequentially: true, + sequential_key: "sequential_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }, + ]; + server.mockEndpoint().get("/v1/workflows").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.getWorkflows({ + page: 1, + page_size: 1, + only_saved_tasks: true, + only_workflows: true, + search_key: "search_key", + title: "title", + template: true, + }); + expect(response).toEqual([ + { + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + description: "description", + workflow_definition: { + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + model: { + key: "value", + }, + status: "published", + max_screenshot_scrolls: 1, + extra_http_headers: { + key: "value", + }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + run_sequentially: true, + sequential_key: "sequential_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }, + ]); + }); + + test("get_workflows (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/workflows").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.getWorkflows(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("create_workflow (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + description: "description", + workflow_definition: { + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + model: { key: "value" }, + status: "published", + max_screenshot_scrolls: 1, + extra_http_headers: { key: "value" }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + run_sequentially: true, + sequential_key: "sequential_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .post("/v1/workflows") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.createWorkflow({}); + expect(response).toEqual({ + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + description: "description", + workflow_definition: { + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + model: { + key: "value", + }, + status: "published", + max_screenshot_scrolls: 1, + extra_http_headers: { + key: "value", + }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + run_sequentially: true, + sequential_key: "sequential_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }); + }); + + test("create_workflow (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/workflows") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.createWorkflow({}); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("update_workflow (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + description: "description", + workflow_definition: { + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + model: { key: "value" }, + status: "published", + max_screenshot_scrolls: 1, + extra_http_headers: { key: "value" }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + run_sequentially: true, + sequential_key: "sequential_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .post("/v1/workflows/wpid_123") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.updateWorkflow("wpid_123", {}); + expect(response).toEqual({ + workflow_id: "workflow_id", + organization_id: "organization_id", + title: "title", + workflow_permanent_id: "workflow_permanent_id", + version: 1, + is_saved_task: true, + description: "description", + workflow_definition: { + parameters: [ + { + parameter_type: "aws_secret", + key: "key", + aws_secret_parameter_id: "aws_secret_parameter_id", + workflow_id: "workflow_id", + aws_key: "aws_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + blocks: [ + { + block_type: "action", + label: "label", + output_parameter: { + key: "key", + output_parameter_id: "output_parameter_id", + workflow_id: "workflow_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + }, + ], + }, + proxy_location: "RESIDENTIAL", + webhook_callback_url: "webhook_callback_url", + totp_verification_url: "totp_verification_url", + totp_identifier: "totp_identifier", + persist_browser_session: true, + model: { + key: "value", + }, + status: "published", + max_screenshot_scrolls: 1, + extra_http_headers: { + key: "value", + }, + run_with: "run_with", + ai_fallback: true, + cache_key: "cache_key", + run_sequentially: true, + sequential_key: "sequential_key", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }); + }); + + test("update_workflow (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/workflows/workflow_id") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.updateWorkflow("workflow_id", {}); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("delete_workflow (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/workflows/wpid_123/delete") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.deleteWorkflow("wpid_123"); + expect(response).toEqual({ + key: "value", + }); + }); + + test("delete_workflow (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/workflows/workflow_id/delete") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.deleteWorkflow("workflow_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_artifact (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + created_at: "2023-01-01T00:00:00Z", + modified_at: "2023-01-01T00:00:00Z", + artifact_id: "artifact_id", + artifact_type: "recording", + uri: "uri", + task_id: "task_id", + step_id: "step_id", + workflow_run_id: "workflow_run_id", + workflow_run_block_id: "workflow_run_block_id", + observer_cruise_id: "observer_cruise_id", + observer_thought_id: "observer_thought_id", + ai_suggestion_id: "ai_suggestion_id", + signed_url: "signed_url", + organization_id: "organization_id", + }; + server + .mockEndpoint() + .get("/v1/artifacts/artifact_id") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getArtifact("artifact_id"); + expect(response).toEqual({ + created_at: "2023-01-01T00:00:00Z", + modified_at: "2023-01-01T00:00:00Z", + artifact_id: "artifact_id", + artifact_type: "recording", + uri: "uri", + task_id: "task_id", + step_id: "step_id", + workflow_run_id: "workflow_run_id", + workflow_run_block_id: "workflow_run_block_id", + observer_cruise_id: "observer_cruise_id", + observer_thought_id: "observer_thought_id", + ai_suggestion_id: "ai_suggestion_id", + signed_url: "signed_url", + organization_id: "organization_id", + }); + }); + + test("get_artifact (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/artifacts/artifact_id") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getArtifact("artifact_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("get_artifact (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/artifacts/artifact_id") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getArtifact("artifact_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_run_artifacts (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + created_at: "2023-01-01T00:00:00Z", + modified_at: "2023-01-01T00:00:00Z", + artifact_id: "artifact_id", + artifact_type: "recording", + uri: "uri", + task_id: "task_id", + step_id: "step_id", + workflow_run_id: "workflow_run_id", + workflow_run_block_id: "workflow_run_block_id", + observer_cruise_id: "observer_cruise_id", + observer_thought_id: "observer_thought_id", + ai_suggestion_id: "ai_suggestion_id", + signed_url: "signed_url", + organization_id: "organization_id", + }, + ]; + server + .mockEndpoint() + .get("/v1/runs/run_id/artifacts") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getRunArtifacts("run_id"); + expect(response).toEqual([ + { + created_at: "2023-01-01T00:00:00Z", + modified_at: "2023-01-01T00:00:00Z", + artifact_id: "artifact_id", + artifact_type: "recording", + uri: "uri", + task_id: "task_id", + step_id: "step_id", + workflow_run_id: "workflow_run_id", + workflow_run_block_id: "workflow_run_block_id", + observer_cruise_id: "observer_cruise_id", + observer_thought_id: "observer_thought_id", + ai_suggestion_id: "ai_suggestion_id", + signed_url: "signed_url", + organization_id: "organization_id", + }, + ]); + }); + + test("get_run_artifacts (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/runs/run_id/artifacts") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getRunArtifacts("run_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("retry_run_webhook (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/runs/tsk_123/retry_webhook") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.retryRunWebhook("tsk_123"); + expect(response).toEqual({ + key: "value", + }); + }); + + test("retry_run_webhook (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/runs/run_id/retry_webhook") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.retryRunWebhook("run_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_run_timeline (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + type: "thought", + block: { + workflow_run_block_id: "workflow_run_block_id", + block_workflow_run_id: "block_workflow_run_id", + workflow_run_id: "workflow_run_id", + organization_id: "organization_id", + description: "description", + parent_workflow_run_block_id: "parent_workflow_run_block_id", + block_type: "task", + label: "label", + status: "status", + output: { key: "value" }, + continue_on_failure: true, + failure_reason: "failure_reason", + engine: "skyvern-1.0", + task_id: "task_id", + url: "url", + navigation_goal: "navigation_goal", + navigation_payload: { key: "value" }, + data_extraction_goal: "data_extraction_goal", + data_schema: { key: "value" }, + terminate_criterion: "terminate_criterion", + complete_criterion: "complete_criterion", + actions: [{ action_type: "click" }], + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + include_action_history_in_verification: true, + duration: 1.1, + loop_values: [], + current_value: "current_value", + current_index: 1, + recipients: ["recipients"], + attachments: ["attachments"], + subject: "subject", + body: "body", + }, + thought: { + thought_id: "thought_id", + task_id: "task_id", + organization_id: "organization_id", + workflow_run_id: "workflow_run_id", + workflow_run_block_id: "workflow_run_block_id", + workflow_id: "workflow_id", + workflow_permanent_id: "workflow_permanent_id", + user_input: "user_input", + observation: "observation", + thought: "thought", + answer: "answer", + thought_type: "plan", + thought_scenario: "generate_plan", + output: { key: "value" }, + input_token_count: 1, + output_token_count: 1, + reasoning_token_count: 1, + cached_token_count: 1, + thought_cost: 1.1, + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ]; + server + .mockEndpoint() + .get("/v1/runs/wr_123/timeline") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getRunTimeline("wr_123"); + expect(response).toEqual([ + { + type: "thought", + block: { + workflow_run_block_id: "workflow_run_block_id", + block_workflow_run_id: "block_workflow_run_id", + workflow_run_id: "workflow_run_id", + organization_id: "organization_id", + description: "description", + parent_workflow_run_block_id: "parent_workflow_run_block_id", + block_type: "task", + label: "label", + status: "status", + output: { + key: "value", + }, + continue_on_failure: true, + failure_reason: "failure_reason", + engine: "skyvern-1.0", + task_id: "task_id", + url: "url", + navigation_goal: "navigation_goal", + navigation_payload: { + key: "value", + }, + data_extraction_goal: "data_extraction_goal", + data_schema: { + key: "value", + }, + terminate_criterion: "terminate_criterion", + complete_criterion: "complete_criterion", + actions: [ + { + action_type: "click", + }, + ], + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + include_action_history_in_verification: true, + duration: 1.1, + loop_values: [], + current_value: "current_value", + current_index: 1, + recipients: ["recipients"], + attachments: ["attachments"], + subject: "subject", + body: "body", + }, + thought: { + thought_id: "thought_id", + task_id: "task_id", + organization_id: "organization_id", + workflow_run_id: "workflow_run_id", + workflow_run_block_id: "workflow_run_block_id", + workflow_id: "workflow_id", + workflow_permanent_id: "workflow_permanent_id", + user_input: "user_input", + observation: "observation", + thought: "thought", + answer: "answer", + thought_type: "plan", + thought_scenario: "generate_plan", + output: { + key: "value", + }, + input_token_count: 1, + output_token_count: 1, + reasoning_token_count: 1, + cached_token_count: 1, + thought_cost: 1.1, + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + }, + ]); + }); + + test("get_run_timeline (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/runs/run_id/timeline") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getRunTimeline("run_id"); + }).rejects.toThrow(Skyvern.BadRequestError); + }); + + test("get_run_timeline (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/runs/run_id/timeline") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getRunTimeline("run_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("get_run_timeline (4)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/runs/run_id/timeline") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getRunTimeline("run_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_browser_sessions (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + browser_session_id: "pbs_123456", + organization_id: "organization_id", + runnable_type: "runnable_type", + runnable_id: "runnable_id", + timeout: 1, + browser_address: "browser_address", + app_url: "app_url", + vnc_streaming_supported: true, + download_path: "download_path", + downloaded_files: [{ url: "url" }], + recordings: [{ url: "url" }], + started_at: "2024-01-15T09:30:00Z", + completed_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }, + ]; + server + .mockEndpoint() + .get("/v1/browser_sessions") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getBrowserSessions(); + expect(response).toEqual([ + { + browser_session_id: "pbs_123456", + organization_id: "organization_id", + runnable_type: "runnable_type", + runnable_id: "runnable_id", + timeout: 1, + browser_address: "browser_address", + app_url: "app_url", + vnc_streaming_supported: true, + download_path: "download_path", + downloaded_files: [ + { + url: "url", + }, + ], + recordings: [ + { + url: "url", + }, + ], + started_at: "2024-01-15T09:30:00Z", + completed_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }, + ]); + }); + + test("get_browser_sessions (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/browser_sessions") + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getBrowserSessions(); + }).rejects.toThrow(Skyvern.ForbiddenError); + }); + + test("get_browser_sessions (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/browser_sessions") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getBrowserSessions(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("create_browser_session (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { + browser_session_id: "pbs_123456", + organization_id: "organization_id", + runnable_type: "runnable_type", + runnable_id: "runnable_id", + timeout: 1, + browser_address: "browser_address", + app_url: "app_url", + vnc_streaming_supported: true, + download_path: "download_path", + downloaded_files: [ + { url: "url", checksum: "checksum", filename: "filename", modified_at: "2024-01-15T09:30:00Z" }, + ], + recordings: [ + { url: "url", checksum: "checksum", filename: "filename", modified_at: "2024-01-15T09:30:00Z" }, + ], + started_at: "2024-01-15T09:30:00Z", + completed_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .post("/v1/browser_sessions") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.createBrowserSession(); + expect(response).toEqual({ + browser_session_id: "pbs_123456", + organization_id: "organization_id", + runnable_type: "runnable_type", + runnable_id: "runnable_id", + timeout: 1, + browser_address: "browser_address", + app_url: "app_url", + vnc_streaming_supported: true, + download_path: "download_path", + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + recordings: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + started_at: "2024-01-15T09:30:00Z", + completed_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }); + }); + + test("create_browser_session (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/browser_sessions") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.createBrowserSession(); + }).rejects.toThrow(Skyvern.ForbiddenError); + }); + + test("create_browser_session (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/browser_sessions") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.createBrowserSession(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("close_browser_session (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/browser_sessions/pbs_123456/close") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.closeBrowserSession("pbs_123456"); + expect(response).toEqual({ + key: "value", + }); + }); + + test("close_browser_session (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/browser_sessions/browser_session_id/close") + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.closeBrowserSession("browser_session_id"); + }).rejects.toThrow(Skyvern.ForbiddenError); + }); + + test("close_browser_session (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/browser_sessions/browser_session_id/close") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.closeBrowserSession("browser_session_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_browser_session (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + browser_session_id: "pbs_123456", + organization_id: "organization_id", + runnable_type: "runnable_type", + runnable_id: "runnable_id", + timeout: 1, + browser_address: "browser_address", + app_url: "app_url", + vnc_streaming_supported: true, + download_path: "download_path", + downloaded_files: [ + { url: "url", checksum: "checksum", filename: "filename", modified_at: "2024-01-15T09:30:00Z" }, + ], + recordings: [ + { url: "url", checksum: "checksum", filename: "filename", modified_at: "2024-01-15T09:30:00Z" }, + ], + started_at: "2024-01-15T09:30:00Z", + completed_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .get("/v1/browser_sessions/pbs_123456") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getBrowserSession("pbs_123456"); + expect(response).toEqual({ + browser_session_id: "pbs_123456", + organization_id: "organization_id", + runnable_type: "runnable_type", + runnable_id: "runnable_id", + timeout: 1, + browser_address: "browser_address", + app_url: "app_url", + vnc_streaming_supported: true, + download_path: "download_path", + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + recordings: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + started_at: "2024-01-15T09:30:00Z", + completed_at: "2024-01-15T09:30:00Z", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }); + }); + + test("get_browser_session (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/browser_sessions/browser_session_id") + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getBrowserSession("browser_session_id"); + }).rejects.toThrow(Skyvern.ForbiddenError); + }); + + test("get_browser_session (3)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/browser_sessions/browser_session_id") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getBrowserSession("browser_session_id"); + }).rejects.toThrow(Skyvern.NotFoundError); + }); + + test("get_browser_session (4)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/browser_sessions/browser_session_id") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getBrowserSession("browser_session_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("send_totp_code (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { + totp_identifier: "john.doe@example.com", + content: "Hello, your verification code is 123456", + }; + const rawResponseBody = { + totp_identifier: "john.doe@example.com", + task_id: "task_id", + workflow_id: "workflow_id", + workflow_run_id: "workflow_run_id", + source: "source", + content: "Hello, your verification code is 123456", + expired_at: "2024-01-15T09:30:00Z", + totp_code_id: "totp_code_id", + code: "code", + organization_id: "organization_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + otp_type: "totp", + }; + server + .mockEndpoint() + .post("/v1/credentials/totp") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.sendTotpCode({ + totp_identifier: "john.doe@example.com", + content: "Hello, your verification code is 123456", + }); + expect(response).toEqual({ + totp_identifier: "john.doe@example.com", + task_id: "task_id", + workflow_id: "workflow_id", + workflow_run_id: "workflow_run_id", + source: "source", + content: "Hello, your verification code is 123456", + expired_at: "2024-01-15T09:30:00Z", + totp_code_id: "totp_code_id", + code: "code", + organization_id: "organization_id", + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + otp_type: "totp", + }); + }); + + test("send_totp_code (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { totp_identifier: "totp_identifier", content: "content" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/credentials/totp") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.sendTotpCode({ + totp_identifier: "totp_identifier", + content: "content", + }); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_credentials (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + credential_id: "cred_1234567890", + credential: { username: "user@example.com", totp_type: "authenticator" }, + credential_type: "password", + name: "Amazon Login", + }, + ]; + server.mockEndpoint().get("/v1/credentials").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.getCredentials({ + page: 1, + page_size: 10, + }); + expect(response).toEqual([ + { + credential_id: "cred_1234567890", + credential: { + username: "user@example.com", + totp_type: "authenticator", + }, + credential_type: "password", + name: "Amazon Login", + }, + ]); + }); + + test("get_credentials (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/credentials").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.getCredentials(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("create_credential (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { + name: "My Credential", + credential_type: "password", + credential: { password: "securepassword123", username: "user@example.com", totp: "JBSWY3DPEHPK3PXP" }, + }; + const rawResponseBody = { + credential_id: "cred_1234567890", + credential: { username: "user@example.com", totp_type: "authenticator" }, + credential_type: "password", + name: "Amazon Login", + }; + server + .mockEndpoint() + .post("/v1/credentials") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.createCredential({ + name: "My Credential", + credential_type: "password", + credential: { + password: "securepassword123", + username: "user@example.com", + totp: "JBSWY3DPEHPK3PXP", + }, + }); + expect(response).toEqual({ + credential_id: "cred_1234567890", + credential: { + username: "user@example.com", + totp_type: "authenticator", + }, + credential_type: "password", + name: "Amazon Login", + }); + }); + + test("create_credential (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { + name: "name", + credential_type: "password", + credential: { password: "x", username: "x" }, + }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/credentials") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.createCredential({ + name: "name", + credential_type: "password", + credential: { + password: "x", + username: "x", + }, + }); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("delete_credential (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + server.mockEndpoint().post("/v1/credentials/cred_1234567890/delete").respondWith().statusCode(200).build(); + + const response = await client.deleteCredential("cred_1234567890"); + expect(response).toEqual(undefined); + }); + + test("delete_credential (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/credentials/credential_id/delete") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.deleteCredential("credential_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_credential (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + credential_id: "cred_1234567890", + credential: { username: "user@example.com", totp_type: "authenticator" }, + credential_type: "password", + name: "Amazon Login", + }; + server + .mockEndpoint() + .get("/v1/credentials/cred_1234567890") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getCredential("cred_1234567890"); + expect(response).toEqual({ + credential_id: "cred_1234567890", + credential: { + username: "user@example.com", + totp_type: "authenticator", + }, + credential_type: "password", + name: "Amazon Login", + }); + }); + + test("get_credential (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/credentials/credential_id") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getCredential("credential_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("login (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { credential_type: "skyvern" }; + const rawResponseBody = { + run_id: "tsk_123", + status: "created", + output: { key: "value" }, + downloaded_files: [ + { url: "url", checksum: "checksum", filename: "filename", modified_at: "2024-01-15T09:30:00Z" }, + ], + recording_url: "recording_url", + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + script_run: { ai_fallback_triggered: true }, + errors: [{ key: "value" }], + run_with: "run_with", + ai_fallback: true, + run_request: { + workflow_id: "wpid_123", + parameters: { key: "value" }, + title: "title", + proxy_location: "RESIDENTIAL", + webhook_url: "webhook_url", + totp_url: "totp_url", + totp_identifier: "totp_identifier", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + extra_http_headers: { key: "value" }, + browser_address: "browser_address", + ai_fallback: true, + run_with: "run_with", + }, + }; + server + .mockEndpoint() + .post("/v1/run/tasks/login") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.login({ + credential_type: "skyvern", + }); + expect(response).toEqual({ + run_id: "tsk_123", + status: "created", + output: { + key: "value", + }, + downloaded_files: [ + { + url: "url", + checksum: "checksum", + filename: "filename", + modified_at: "2024-01-15T09:30:00Z", + }, + ], + recording_url: "recording_url", + screenshot_urls: ["screenshot_urls"], + failure_reason: "failure_reason", + created_at: "2025-01-01T00:00:00Z", + modified_at: "2025-01-01T00:05:00Z", + queued_at: "2024-01-15T09:30:00Z", + started_at: "2024-01-15T09:30:00Z", + finished_at: "2024-01-15T09:30:00Z", + app_url: "app_url", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + script_run: { + ai_fallback_triggered: true, + }, + errors: [ + { + key: "value", + }, + ], + run_with: "run_with", + ai_fallback: true, + run_request: { + workflow_id: "wpid_123", + parameters: { + key: "value", + }, + title: "title", + proxy_location: "RESIDENTIAL", + webhook_url: "webhook_url", + totp_url: "totp_url", + totp_identifier: "totp_identifier", + browser_session_id: "browser_session_id", + max_screenshot_scrolls: 1, + extra_http_headers: { + key: "value", + }, + browser_address: "browser_address", + ai_fallback: true, + run_with: "run_with", + }, + }); + }); + + test("login (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { credential_type: "skyvern" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/run/tasks/login") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.login({ + credential_type: "skyvern", + }); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_scripts (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = [ + { + script_revision_id: "script_revision_id", + script_id: "script_id", + organization_id: "organization_id", + run_id: "run_id", + version: 1, + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }, + ]; + server.mockEndpoint().get("/v1/scripts").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.getScripts({ + page: 1, + page_size: 10, + }); + expect(response).toEqual([ + { + script_revision_id: "script_revision_id", + script_id: "script_id", + organization_id: "organization_id", + run_id: "run_id", + version: 1, + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }, + ]); + }); + + test("get_scripts (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/scripts").respondWith().statusCode(422).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.getScripts(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("create_script (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { + script_id: "s_abc123", + version: 1, + run_id: "run_id", + file_count: 1, + file_tree: { + key: { + type: "type", + size: 1, + mime_type: "mime_type", + content_hash: "content_hash", + created_at: "2024-01-15T09:30:00Z", + children: {}, + }, + }, + created_at: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .post("/v1/scripts") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.createScript(); + expect(response).toEqual({ + script_id: "s_abc123", + version: 1, + run_id: "run_id", + file_count: 1, + file_tree: { + key: { + type: "type", + size: 1, + mime_type: "mime_type", + content_hash: "content_hash", + created_at: "2024-01-15T09:30:00Z", + children: {}, + }, + }, + created_at: "2024-01-15T09:30:00Z", + }); + }); + + test("create_script (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/scripts") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.createScript(); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("get_script (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { + script_revision_id: "script_revision_id", + script_id: "script_id", + organization_id: "organization_id", + run_id: "run_id", + version: 1, + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .get("/v1/scripts/s_abc123") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.getScript("s_abc123"); + expect(response).toEqual({ + script_revision_id: "script_revision_id", + script_id: "script_id", + organization_id: "organization_id", + run_id: "run_id", + version: 1, + created_at: "2024-01-15T09:30:00Z", + modified_at: "2024-01-15T09:30:00Z", + deleted_at: "2024-01-15T09:30:00Z", + }); + }); + + test("get_script (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/scripts/script_id") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.getScript("script_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); + + test("deploy_script (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { files: [{ path: "src/main.py", content: "content" }] }; + const rawResponseBody = { + script_id: "s_abc123", + version: 1, + run_id: "run_id", + file_count: 1, + file_tree: { + key: { + type: "type", + size: 1, + mime_type: "mime_type", + content_hash: "content_hash", + created_at: "2024-01-15T09:30:00Z", + children: {}, + }, + }, + created_at: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .post("/v1/scripts/s_abc123/deploy") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.deployScript("s_abc123", { + files: [ + { + path: "src/main.py", + content: "content", + }, + ], + }); + expect(response).toEqual({ + script_id: "s_abc123", + version: 1, + run_id: "run_id", + file_count: 1, + file_tree: { + key: { + type: "type", + size: 1, + mime_type: "mime_type", + content_hash: "content_hash", + created_at: "2024-01-15T09:30:00Z", + children: {}, + }, + }, + created_at: "2024-01-15T09:30:00Z", + }); + }); + + test("deploy_script (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + const rawRequestBody = { + files: [ + { path: "path", content: "content" }, + { path: "path", content: "content" }, + ], + }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/scripts/script_id/deploy") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.deployScript("script_id", { + files: [ + { + path: "path", + content: "content", + }, + { + path: "path", + content: "content", + }, + ], + }); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); +}); diff --git a/skyvern-ts/client/tests/wire/scripts.test.ts b/skyvern-ts/client/tests/wire/scripts.test.ts new file mode 100644 index 00000000..3a8fb352 --- /dev/null +++ b/skyvern-ts/client/tests/wire/scripts.test.ts @@ -0,0 +1,44 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as Skyvern from "../../src/api/index"; +import { SkyvernClient } from "../../src/Client"; +import { mockServerPool } from "../mock-server/MockServerPool"; + +describe("Scripts", () => { + test("runScript (1)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/scripts/s_abc123/run") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.scripts.runScript("s_abc123"); + expect(response).toEqual({ + key: "value", + }); + }); + + test("runScript (2)", async () => { + const server = mockServerPool.createServer(); + const client = new SkyvernClient({ xApiKey: "test", apiKey: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/scripts/script_id/run") + .respondWith() + .statusCode(422) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.scripts.runScript("script_id"); + }).rejects.toThrow(Skyvern.UnprocessableEntityError); + }); +}); diff --git a/skyvern-ts/client/tsconfig.base.json b/skyvern-ts/client/tsconfig.base.json new file mode 100644 index 00000000..d7627675 --- /dev/null +++ b/skyvern-ts/client/tsconfig.base.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "extendedDiagnostics": true, + "strict": true, + "target": "ES6", + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "declaration": true, + "outDir": "dist", + "rootDir": "src", + "baseUrl": "src", + "isolatedModules": true, + "isolatedDeclarations": true + }, + "include": ["src"], + "exclude": [] +} diff --git a/skyvern-ts/client/tsconfig.cjs.json b/skyvern-ts/client/tsconfig.cjs.json new file mode 100644 index 00000000..5c11446f --- /dev/null +++ b/skyvern-ts/client/tsconfig.cjs.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "CommonJS", + "outDir": "dist/cjs" + }, + "include": ["src"], + "exclude": [] +} diff --git a/skyvern-ts/client/tsconfig.esm.json b/skyvern-ts/client/tsconfig.esm.json new file mode 100644 index 00000000..6ce90974 --- /dev/null +++ b/skyvern-ts/client/tsconfig.esm.json @@ -0,0 +1,10 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "esnext", + "outDir": "dist/esm", + "verbatimModuleSyntax": true + }, + "include": ["src"], + "exclude": [] +} diff --git a/skyvern-ts/client/tsconfig.json b/skyvern-ts/client/tsconfig.json new file mode 100644 index 00000000..d77fdf00 --- /dev/null +++ b/skyvern-ts/client/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./tsconfig.cjs.json" +} diff --git a/skyvern-ts/client/vitest.config.ts b/skyvern-ts/client/vitest.config.ts new file mode 100644 index 00000000..677c5855 --- /dev/null +++ b/skyvern-ts/client/vitest.config.ts @@ -0,0 +1,27 @@ +import { defineConfig } from "vitest/config"; +export default defineConfig({ + test: { + projects: [ + { + test: { + globals: true, + name: "unit", + environment: "node", + root: "./tests", + include: ["**/*.test.{js,ts,jsx,tsx}"], + exclude: ["wire/**"], + }, + }, + { + test: { + globals: true, + name: "wire", + environment: "node", + root: "./tests/wire", + setupFiles: ["../mock-server/setup.ts"], + }, + }, + ], + passWithNoTests: true, + }, +});