diff --git a/.genignore b/.genignore new file mode 100644 index 0000000..32c837e --- /dev/null +++ b/.genignore @@ -0,0 +1,3 @@ +# Manually maintained test files - excluded from Speakeasy generation +src/__tests__/** + diff --git a/.github/workflows/sdk_test.yaml b/.github/workflows/sdk_test.yaml new file mode 100644 index 0000000..08d7b35 --- /dev/null +++ b/.github/workflows/sdk_test.yaml @@ -0,0 +1,21 @@ +name: Test +permissions: + checks: write + contents: write + pull-requests: write + statuses: write + id-token: write +"on": + workflow_dispatch: + inputs: + target: + description: Provided SDK target to run tests for, (all) is valid + type: string +jobs: + test: + uses: speakeasy-api/sdk-generation-action/.github/workflows/sdk-test.yaml@v15 + with: + target: ${{ github.event.inputs.target || 'dwolla' }} + secrets: + github_access_token: ${{ secrets.GITHUB_TOKEN }} + speakeasy_api_key: ${{ secrets.SPEAKEASY_API_KEY }} diff --git a/.speakeasy/gen.lock b/.speakeasy/gen.lock index 58b5dcc..934ef09 100644 --- a/.speakeasy/gen.lock +++ b/.speakeasy/gen.lock @@ -1,12 +1,12 @@ lockVersion: 2.0.0 id: 53ac026a-ff11-435d-914b-31df5268afb0 management: - docChecksum: 42cfc58c3eb68a6a4de4b47956c205b9 + docChecksum: 9fd1bbc68b879020d3e55ac2a43fc6b5 docVersion: "2.0" - speakeasyVersion: 1.658.2 - generationVersion: 2.755.9 - releaseVersion: 0.0.1-beta.13 - configChecksum: 0fc627c25b27407851e489453baa2bf5 + speakeasyVersion: 1.667.0 + generationVersion: 2.769.1 + releaseVersion: 0.0.1-beta.14 + configChecksum: 9dac73ad419b87dc5e478f4041e6ee4b repoURL: https://github.com/Dwolla/dwolla-typescript.git installationURL: https://github.com/Dwolla/dwolla-typescript published: true @@ -14,7 +14,7 @@ features: typescript: additionalDependencies: 0.1.0 constsAndDefaults: 0.1.12 - core: 3.26.7 + core: 3.26.14 defaultEnabledRetries: 0.1.0 devContainers: 2.90.1 enumUnions: 0.1.0 @@ -24,13 +24,15 @@ features: globalSecurityCallbacks: 0.1.0 globalServerURLs: 2.83.0 groups: 2.81.3 + methodSecurity: 2.82.6 nameOverrides: 2.81.2 oauth2ClientCredentials: 1.1.0 responseFormat: 0.2.3 retries: 2.83.0 - sdkHooks: 0.3.0 + sdkHooks: 0.4.0 serverIDs: 2.81.2 - unions: 2.86.0 + tests: 0.17.3 + unions: 2.86.3 uploadStreams: 0.1.0 generatedFiles: - .devcontainer/README.md @@ -517,6 +519,7 @@ generatedFiles: - docs/models/operations/createaccountexchangeresponsebody.md - docs/models/operations/createapplicationaccesstokenrequest.md - docs/models/operations/createapplicationaccesstokenresponse.md + - docs/models/operations/createapplicationaccesstokensecurity.md - docs/models/operations/createbeneficialownerdocumentdocumenttype.md - docs/models/operations/createbeneficialownerdocumentfile.md - docs/models/operations/createbeneficialownerdocumentrequest.md @@ -700,7 +703,6 @@ generatedFiles: - docs/models/operations/simulatebanktransferprocessingrequest.md - docs/models/operations/simulatebanktransferprocessingresponse.md - docs/models/operations/to.md - - docs/models/operations/tokentype.md - docs/models/operations/toledgerentry.md - docs/models/operations/total.md - docs/models/operations/transaction.md @@ -1467,8 +1469,9 @@ generatedFiles: - src/types/index.ts - src/types/operations.ts - src/types/rfcdate.ts + - src/types/smartUnion.ts - src/types/streams.ts - - src/types/union.ts + - src/types/unrecognized.ts - tsconfig.json examples: createApplicationAccessToken: @@ -1477,7 +1480,7 @@ examples: application/x-www-form-urlencoded: {"grant_type": "client_credentials"} responses: "200": - application/json: {"access_token": "gTm0p62yYXFiB1rOdhV0TsNOinC2V2P1CMaAtojkO9JEGbv3i5", "token_type": "bearer", "expires_in": 3599} + application/json: {"access_token": "gTm0p62yYXFiB1rOdhV0TsNOinC2V2P1CMaAtojkO9JEGbv3i5", "token_type": "Bearer", "expires_in": 3599} "401": application/json: {"error": "invalid_client"} root: @@ -1551,7 +1554,7 @@ examples: speakeasy-default-list-and-search-customers: responses: "200": - application/vnd.dwolla.v1.hal+json: {"_links": {"key": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}, "key1": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}}, "_embedded": {"customers": [{"_links": {"key": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}, "key1": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}, "key2": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}}, "id": "c41125c5-99c4-4303-a9f6-d066d28a61e3", "firstName": "Jane", "lastName": "Doe", "email": "janedoe@mail.com", "correlationId": "CID-abe2bb3d-d2ff-433b-95a3-0debd960ed25", "created": "2022-10-07T16:46:13.023Z", "type": "personal", "status": "verified", "address1": "123 Main Street", "address2": "Ste 123", "city": "Des Moines", "state": "IA", "postalCode": "50309"}]}} + application/vnd.dwolla.v1.hal+json: {"_links": {"key": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}, "key1": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}}, "_embedded": {"customers": [{"_links": {"key": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}, "key1": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}, "key2": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}}, "id": "c41125c5-99c4-4303-a9f6-d066d28a61e3", "firstName": "Jane", "lastName": "Doe", "email": "janedoe@mail.com", "correlationId": "CID-abe2bb3d-d2ff-433b-95a3-0debd960ed25", "created": "2022-10-07T16:46:13.023Z", "type": "personal", "status": "verified", "address1": "123 Main Street", "address2": "Ste 123", "city": "Des Moines", "state": "IA", "postalCode": "50309"}]}, "total": 2} "403": application/vnd.dwolla.v1.hal+json: {"code": "Forbidden", "message": "The supplied credentials are not authorized for this resource."} createCustomer: @@ -1976,7 +1979,7 @@ examples: id: "" responses: "200": - application/vnd.dwolla.v1.hal+json: {"transactions": [{"_links": {"key": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}, "key1": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}}, "id": "416a2857-c887-4cca-bd02-8c3f75c4bb0e", "status": "pending", "amount": {"value": "2.00", "currency": "USD"}, "created": "2016-02-22T20:46:38.777Z"}], "total": "1"} + application/vnd.dwolla.v1.hal+json: {"transactions": [{"_links": {"key": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}, "key1": {"href": "https://api.dwolla.com", "type": "application/vnd.dwolla.v1.hal+json", "resource-type": "resource-type"}}, "id": "416a2857-c887-4cca-bd02-8c3f75c4bb0e", "status": "pending", "amount": {"value": "2.00", "currency": "USD"}, "created": "2016-02-22T20:46:38.777Z"}], "total": 1} "404": application/vnd.dwolla.v1.hal+json: {"code": "NotFound", "message": "The requested resource was not found."} getTransferFailureReason: @@ -2526,6 +2529,7 @@ examples: responses: "200": application/json: {"token": "4adF858jPeQ9RnojMHdqSD2KwsvmhO7Ti7cI5woOiBGCpH5krY"} + application/vnd.dwolla.v1.hal+json: {"token": "4adF858jPeQ9RnojMHdqSD2KwsvmhO7Ti7cI5woOiBGCpH5krY"} "400": application/vnd.dwolla.v1.hal+json: {"code": "BadRequest", "message": "The request body contains bad syntax or is incomplete."} "403": @@ -2632,4 +2636,69 @@ examples: "403": application/vnd.dwolla.v1.hal+json: {"code": "forbidden", "message": "Not authorized to simulate transfer processing."} examplesVersion: 1.0.2 -generatedTests: {} +generatedTests: + createApplicationAccessToken: "2025-11-24T10:10:12-06:00" + getRoot: "2025-11-24T10:10:12-06:00" + getAccount: "2025-11-24T10:10:12-06:00" + listFundingSources: "2025-11-24T10:10:12-06:00" + listAndSearchTransfers: "2025-11-24T10:10:12-06:00" + listMassPayments: "2025-11-24T10:10:12-06:00" + listAccountExchanges: "2025-11-24T10:10:12-06:00" + createAccountExchange: "2025-11-24T10:10:12-06:00" + listAndSearchCustomers: "2025-11-24T10:10:12-06:00" + getCustomer: "2025-11-24T10:10:12-06:00" + update: "2025-11-24T10:10:12-06:00" + listAvailableExchangeConnections: "2025-11-24T10:10:12-06:00" + listBeneficialOwnersForCustomer: "2025-11-24T10:10:12-06:00" + getBeneficialOwnershipStatusForCustomer: "2025-11-24T10:10:12-06:00" + certifyBeneficialOwnershipForCustomer: "2025-11-24T10:10:12-06:00" + listCustomerDocuments: "2025-11-24T10:10:12-06:00" + listCustomerFundingSources: "2025-11-24T10:10:12-06:00" + listCustomerTransfers: "2025-11-24T10:10:12-06:00" + listCustomerMassPayments: "2025-11-24T10:10:12-06:00" + listCustomerLabels: "2025-11-24T10:10:12-06:00" + listCustomerExchanges: "2025-11-24T10:10:12-06:00" + listBusinessClassifications: "2025-11-24T10:10:12-06:00" + retrieveBusinessClassification: "2025-11-24T10:10:12-06:00" + retrieveBeneficialOwner: "2025-11-24T10:10:12-06:00" + updateBeneficialOwner: "2025-11-24T10:10:12-06:00" + deleteBeneficialOwner: "2025-11-24T10:10:12-06:00" + listBeneficialOwnerDocuments: "2025-11-24T10:10:12-06:00" + retrieveDocument: "2025-11-24T10:10:12-06:00" + getKbaQuestions: "2025-11-24T10:10:12-06:00" + verifyKbaQuestions: "2025-11-24T10:10:12-06:00" + getFundingSource: "2025-11-24T10:10:12-06:00" + updateOrRemoveFundingSource: "2025-11-24T10:10:12-06:00" + getVanRouting: "2025-11-24T10:10:12-06:00" + getMicroDeposits: "2025-11-24T10:10:12-06:00" + verifyMicroDeposits: "2025-11-24T10:10:12-06:00" + getFundingSourceBalance: "2025-11-24T10:10:12-06:00" + createOnDemandTransferAuthorization: "2025-11-24T10:10:12-06:00" + getTransfer: "2025-11-24T10:10:12-06:00" + cancelTransfer: "2025-11-24T10:10:12-06:00" + listTransferFees: "2025-11-24T10:10:12-06:00" + getTransferFailureReason: "2025-11-24T10:10:12-06:00" + getMassPayment: "2025-11-24T10:10:12-06:00" + updateMassPayment: "2025-11-24T10:10:12-06:00" + listMassPaymentItems: "2025-11-24T10:10:12-06:00" + getMassPaymentItem: "2025-11-24T10:10:12-06:00" + getLabel: "2025-11-24T10:10:12-06:00" + removeLabel: "2025-11-24T10:10:12-06:00" + listLabelLedgerEntries: "2025-11-24T10:10:12-06:00" + getLabelLedgerEntry: "2025-11-24T10:10:12-06:00" + retrieveLabelReallocation: "2025-11-24T10:10:12-06:00" + listEvents: "2025-11-24T10:10:12-06:00" + getEvent: "2025-11-24T10:10:12-06:00" + listWebhookSubscriptions: "2025-11-24T10:10:12-06:00" + getWebhookSubscription: "2025-11-24T10:10:12-06:00" + updateWebhookSubscription: "2025-11-24T10:10:12-06:00" + delete: "2025-11-24T10:10:12-06:00" + listWebhooks: "2025-11-24T10:10:12-06:00" + getWebhook: "2025-11-24T10:10:12-06:00" + listWebhookRetries: "2025-11-24T10:10:12-06:00" + simulateBankTransferProcessing: "2025-11-24T10:10:12-06:00" + listExchangePartners: "2025-11-24T10:10:12-06:00" + getExchangePartner: "2025-11-24T10:10:12-06:00" + getExchange: "2025-11-24T10:10:12-06:00" + retrieveCustomerExchangeSession: "2025-11-24T10:10:12-06:00" + createClientToken: "2025-11-24T10:10:12-06:00" diff --git a/.speakeasy/gen.yaml b/.speakeasy/gen.yaml index e134797..40eca27 100644 --- a/.speakeasy/gen.yaml +++ b/.speakeasy/gen.yaml @@ -26,10 +26,10 @@ generation: requestBodyFieldName: "" tests: generateTests: true - generateNewTests: false + generateNewTests: true skipResponseBodyAssertions: false typescript: - version: 0.0.1-beta.13 + version: 0.0.1-beta.14 acceptHeaderEnum: true additionalDependencies: dependencies: {} @@ -42,7 +42,7 @@ typescript: author: Speakeasy baseErrorName: DwollaError clientServerStatusCodesAsErrors: true - constFieldsAlwaysOptional: true + constFieldsAlwaysOptional: false defaultErrorName: APIError enableCustomCodeRegions: false enableMCPServer: false @@ -52,6 +52,9 @@ typescript: exportZodModelNamespace: false flattenGlobalSecurity: true flatteningOrder: parameters-first + formStringArrayEncodeMode: encoded-string + forwardCompatibleEnumsByDefault: false + forwardCompatibleUnionsByDefault: "false" generateExamples: true imports: option: openapi @@ -61,14 +64,18 @@ typescript: operations: models/operations shared: models webhooks: models/webhooks + inferUnionDiscriminators: true inputModelSuffix: input jsonpath: rfc9535 + laxMode: strict maxMethodParams: 0 methodArguments: require-security-and-request modelPropertyCasing: camel moduleFormat: dual + multipartArrayFormat: legacy outputModelSuffix: output packageName: dwolla + preApplyUnionDiscriminators: true responseFormat: flat sseFlatResponse: false templateVersion: v2 diff --git a/.speakeasy/testfiles/example.file b/.speakeasy/testfiles/example.file new file mode 100644 index 0000000..3b18e51 --- /dev/null +++ b/.speakeasy/testfiles/example.file @@ -0,0 +1 @@ +hello world diff --git a/.speakeasy/tests.arazzo.yaml b/.speakeasy/tests.arazzo.yaml new file mode 100644 index 0000000..2ae48aa --- /dev/null +++ b/.speakeasy/tests.arazzo.yaml @@ -0,0 +1,1143 @@ +arazzo: 1.0.1 +info: + title: Dwolla TypeScript SDK Test Suite + summary: Integration tests for the Dwolla TypeScript SDK + version: 0.0.1 +sourceDescriptions: + - name: dwolla-openapi + url: https://raw.githubusercontent.com/Dwolla/dwolla-openapi/main/openapi.yml + type: openapi +x-speakeasy-test-server: + baseUrl: https://api-sandbox.dwolla.com +x-speakeasy-test-rebuild: false +workflows: + - workflowId: createApplicationAccessToken + steps: + - stepId: test + operationId: createApplicationAccessToken + requestBody: + contentType: application/x-www-form-urlencoded + payload: + grant_type: client_credentials + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + {"access_token":"gTm0p62yYXFiB1rOdhV0TsNOinC2V2P1CMaAtojkO9JEGbv3i5","token_type":"bearer","expires_in":3599} + type: simple + x-speakeasy-test-group: tokens + x-speakeasy-test-rebuild: false + - workflowId: getRoot + steps: + - stepId: test + operationId: getRoot + x-speakeasy-test-group: root + x-speakeasy-test-rebuild: false + - workflowId: getAccount + steps: + - stepId: test + operationId: getAccount + parameters: + - name: id + in: path + value: 5e7cd80f-3a4a-451e-9cd6-a86fc571741f + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"2e21f010-3023-4891-aced-ed726d7cd5e1","name":"Self Employed","authorizedRep":"Jane Doe","timezoneOffset":-6,"email":"janedoe@mail.com","phone":"5555552368","address":{"address1":"462 Main Street","address2":"Suite 124","city":"Des Moines","postalCode":"50309","state":"IA","country":"US"},"verificationStatus":"Verified","ownershipStatus":"Exempt","ownershipCertificationStatus":"Exempt","type":"Commercial","created":"2021-10-25T00:39:38.283Z"} + type: simple + x-speakeasy-test-group: accounts + x-speakeasy-test-rebuild: false + - workflowId: listFundingSources + steps: + - stepId: test + operationId: listFundingSources + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"funding-sources":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","status":"unverified","type":"bank","bankAccountType":"checking","name":"My bank","created":"2022-07-23T00:18:21.419Z","removed":true,"channels":["ach"],"bankName":"SANDBOX TEST BANK","fingerprint":"5012989b55af15400e8102f95d2ec5e7ce3aef45c01613280d80a236dd8d6c"}]},"total":3} + type: simple + x-speakeasy-test-group: accounts_fundingSources + x-speakeasy-test-rebuild: false + - workflowId: listAndSearchTransfers + steps: + - stepId: test + operationId: listAndSearchTransfers + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"transfers":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"15c6bcce-46f7-e811-8112-e8dd3bececa8","status":"pending","amount":{"value":"42.00","currency":"USD"},"created":"2018-12-03T22:00:22.970Z","clearing":{"source":"standard","destination":"same-day"},"metadata":{"paymentId":"12345678","note":"Payment for completed work Dec. 1"},"achDetails":{"source":{"addenda":{"values":["ABC123_AddendaValue"]}},"destination":{"addenda":{"values":["ZYX987_AddendaValue"]}}},"rtpDetails":{"destination":{"remittanceData":"ABC_123 Remittance Data"}},"correlationId":"8a2cdc8d-629d-4a24-98ac-40b735229fe2","processingChannel":{"destination":"real-time-payments"}}]},"total":100} + type: simple + x-speakeasy-test-group: accounts_transfers + x-speakeasy-test-rebuild: false + - workflowId: listMassPayments + steps: + - stepId: test + operationId: listMassPayments + parameters: + - name: id + in: path + value: + - name: limit + in: query + value: 25 + - name: offset + in: query + value: 0 + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"mass-payments":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"11ac4051-7b76-44fc-87ab-ae23012393f0","status":"complete","created":"2022-01-20T17:41:41.000Z","total":{"value":"5.00","currency":"USD"},"totalFees":{"value":"5.00","currency":"USD"},"correlationId":"CID-8a2cdc8d-629d-4a24-98ac-40b735229fe2"}]},"total":100} + type: simple + x-speakeasy-test-group: accounts_massPayments + x-speakeasy-test-rebuild: false + - workflowId: listAccountExchanges + steps: + - stepId: test + operationId: listAccountExchanges + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"exchanges":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","status":"deactivated","created":"2022-07-23T00:18:21.419Z"}, {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","status":"deactivated","created":"2022-07-23T00:18:21.419Z"}]},"total":3} + type: simple + x-speakeasy-test-group: accounts_exchanges + x-speakeasy-test-rebuild: false + - workflowId: createAccountExchange + steps: + - stepId: test + operationId: createAccountExchange + requestBody: + contentType: application/json + payload: + _links: + exchange-partner: + href: https://api.dwolla.com/exchange-partners/292317ec-e252-47d8-93c3-2d128e037aa4 + token: someMXProcessorToken + successCriteria: + - condition: $statusCode == 201 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {} + type: simple + x-speakeasy-test-group: accounts_exchanges + x-speakeasy-test-rebuild: false + - workflowId: listAndSearchCustomers + steps: + - stepId: test + operationId: listAndSearchCustomers + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"customers":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"c41125c5-99c4-4303-a9f6-d066d28a61e3","firstName":"Jane","lastName":"Doe","email":"janedoe@mail.com","correlationId":"CID-abe2bb3d-d2ff-433b-95a3-0debd960ed25","created":"2022-10-07T16:46:13.023Z","type":"personal","status":"verified","address1":"123 Main Street","address2":"Ste 123","city":"Des Moines","state":"IA","postalCode":"50309"}]}} + type: simple + x-speakeasy-test-group: customers + x-speakeasy-test-rebuild: false + - workflowId: getCustomer + steps: + - stepId: test + operationId: getCustomer + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"c41125c5-99c4-4303-a9f6-d066d28a61e3","firstName":"Jane","lastName":"Doe","email":"janedoe@mail.com","correlationId":"CID-abe2bb3d-d2ff-433b-95a3-0debd960ed25","created":"2022-10-07T16:46:13.023Z","type":"unverified","status":"unverified"} + type: simple + x-speakeasy-test-group: customers + x-speakeasy-test-rebuild: false + - workflowId: update + steps: + - stepId: test + operationId: update + parameters: + - name: id + in: path + value: + requestBody: + contentType: application/json + payload: + address1: 99-99 33rd St + businessClassification: 9ed3f670-7d6f-11e3-b1ce-5404a6144203 + businessName: Jane Corp + businessType: soleProprietorship + city: Some City + dateOfBirth: "1980-01-31" + ein: 00-0000000 + email: solePropBusiness@email.com + firstName: Business + lastName: Owner + operationType: upgradeToVerifiedSoleProp + postalCode: "11101" + ssn: "6789" + state: NY + type: business + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"c41125c5-99c4-4303-a9f6-d066d28a61e3","firstName":"Jane","lastName":"Doe","email":"janedoe@mail.com","correlationId":"CID-abe2bb3d-d2ff-433b-95a3-0debd960ed25","created":"2022-10-07T16:46:13.023Z","type":"receive-only","status":"unverified","businessName":"Jane Corp llc"} + type: simple + x-speakeasy-test-group: customers + x-speakeasy-test-rebuild: false + - workflowId: listAvailableExchangeConnections + steps: + - stepId: test + operationId: listAvailableExchangeConnections + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/customers/1b54c81a-261f-4779-bb57-9405e6e00694/available-exchange-connections","type":"application/vnd.dwolla.v1.hal+json","resource-type":"customer"},"customers":{"href":"https://api.dwolla.com/customers/1b54c81a-261f-4779-bb57-9405e6e00694","type":"application/vnd.dwolla.v1.hal+json","resource-type":"customer"}},"_embedded":{"available-exchange-connections":[]}} + type: simple + x-speakeasy-test-group: customers + x-speakeasy-test-rebuild: false + - workflowId: listBeneficialOwnersForCustomer + steps: + - stepId: test + operationId: listBeneficialOwnersForCustomer + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"beneficial-owners":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","firstName":"John","lastName":"Doe","address":{"address1":"462 Main Street","address2":"Suite 123","address3":"Unit 123","city":"Des Moines","postalCode":"50309","country":"USA","stateProvinceRegion":"IA"},"verificationStatus":"verified","created":"2022-07-23T00:18:21.419Z"}, {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","firstName":"John","lastName":"Doe","address":{"address1":"462 Main Street","address2":"Suite 123","address3":"Unit 123","city":"Des Moines","postalCode":"50309","country":"USA","stateProvinceRegion":"IA"},"verificationStatus":"verified","created":"2022-07-23T00:18:21.419Z"}]}} + type: simple + x-speakeasy-test-group: customers_beneficialOwners + x-speakeasy-test-rebuild: false + - workflowId: getBeneficialOwnershipStatusForCustomer + steps: + - stepId: test + operationId: getBeneficialOwnershipStatusForCustomer + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"status":"uncertified"} + type: simple + x-speakeasy-test-group: beneficialOwnership + x-speakeasy-test-rebuild: false + - workflowId: certifyBeneficialOwnershipForCustomer + steps: + - stepId: test + operationId: certifyBeneficialOwnershipForCustomer + parameters: + - name: id + in: path + value: + requestBody: + contentType: application/json + payload: + status: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"status":"uncertified"} + type: simple + x-speakeasy-test-group: beneficialOwnership + x-speakeasy-test-rebuild: false + - workflowId: listCustomerDocuments + steps: + - stepId: test + operationId: listCustomerDocuments + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"documents":[{"_links":{"self":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"56502f7a-fa59-4a2f-8579-0f8bc9d7b9cc","status":"reviewed","type":"passport","created":"2015-09-29T21:42:16.000Z","documentVerificationStatus":"rejected","failureReason":"ScanDobMismatch","allFailureReasons":[{"reason":"ScanDobMismatch","description":"Scan DOB does not match DOB on account"}, {"reason":"ScanDobMismatch","description":"Scan DOB does not match DOB on account"}]}]},"total":2} + type: simple + x-speakeasy-test-group: customers_documents + x-speakeasy-test-rebuild: false + - workflowId: listCustomerFundingSources + steps: + - stepId: test + operationId: listCustomerFundingSources + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"funding-sources":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","status":"unverified","type":"bank","bankAccountType":"checking","name":"My bank","created":"2022-07-23T00:18:21.419Z","removed":true,"channels":["ach"],"bankName":"SANDBOX TEST BANK","fingerprint":"5012989b55af15400e8102f95d2ec5e7ce3aef45c01613280d80a236dd8d6c"}]},"total":3} + type: simple + x-speakeasy-test-group: customers_fundingSources + x-speakeasy-test-rebuild: false + - workflowId: listCustomerTransfers + steps: + - stepId: test + operationId: listCustomerTransfers + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"transfers":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"15c6bcce-46f7-e811-8112-e8dd3bececa8","status":"pending","amount":{"value":"42.00","currency":"USD"},"created":"2018-12-03T22:00:22.970Z","clearing":{"source":"standard","destination":"same-day"},"metadata":{"paymentId":"12345678","note":"Payment for completed work Dec. 1"},"achDetails":{"source":{"addenda":{"values":["ABC123_AddendaValue"]}},"destination":{"addenda":{"values":["ZYX987_AddendaValue"]}}},"rtpDetails":{"destination":{"remittanceData":"ABC_123 Remittance Data"}},"correlationId":"8a2cdc8d-629d-4a24-98ac-40b735229fe2","processingChannel":{"destination":"real-time-payments"}}, {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"15c6bcce-46f7-e811-8112-e8dd3bececa8","status":"pending","amount":{"value":"42.00","currency":"USD"},"created":"2018-12-03T22:00:22.970Z","clearing":{"source":"standard","destination":"same-day"},"metadata":{"paymentId":"12345678","note":"Payment for completed work Dec. 1"},"achDetails":{"source":{"addenda":{"values":["ABC123_AddendaValue"]}},"destination":{"addenda":{"values":["ZYX987_AddendaValue"]}}},"rtpDetails":{"destination":{"remittanceData":"ABC_123 Remittance Data"}},"correlationId":"8a2cdc8d-629d-4a24-98ac-40b735229fe2","processingChannel":{"destination":"real-time-payments"}}, {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"15c6bcce-46f7-e811-8112-e8dd3bececa8","status":"pending","amount":{"value":"42.00","currency":"USD"},"created":"2018-12-03T22:00:22.970Z","clearing":{"source":"standard","destination":"same-day"},"metadata":{"paymentId":"12345678","note":"Payment for completed work Dec. 1"},"achDetails":{"source":{"addenda":{"values":["ABC123_AddendaValue"]}},"destination":{"addenda":{"values":["ZYX987_AddendaValue"]}}},"rtpDetails":{"destination":{"remittanceData":"ABC_123 Remittance Data"}},"correlationId":"8a2cdc8d-629d-4a24-98ac-40b735229fe2","processingChannel":{"destination":"real-time-payments"}}]},"total":100} + type: simple + x-speakeasy-test-group: customers_transfers + x-speakeasy-test-rebuild: false + - workflowId: listCustomerMassPayments + steps: + - stepId: test + operationId: listCustomerMassPayments + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"mass-payments":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"11ac4051-7b76-44fc-87ab-ae23012393f0","status":"complete","created":"2022-01-20T17:41:41.000Z","total":{"value":"5.00","currency":"USD"},"totalFees":{"value":"5.00","currency":"USD"},"correlationId":"CID-8a2cdc8d-629d-4a24-98ac-40b735229fe2"}]},"total":100} + type: simple + x-speakeasy-test-group: customers_massPayments + x-speakeasy-test-rebuild: false + - workflowId: listCustomerLabels + steps: + - stepId: test + operationId: listCustomerLabels + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"labels":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"7e042ffe-e25e-40d2-b86e-748b98845ecc","created":"2022-05-15T22:19:09.635Z","amount":{"value":"10","currency":"USD"}}]},"total":100} + type: simple + x-speakeasy-test-group: customers_labels + x-speakeasy-test-rebuild: false + - workflowId: listCustomerExchanges + steps: + - stepId: test + operationId: listCustomerExchanges + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"exchanges":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","status":"deactivated","created":"2022-07-23T00:18:21.419Z"}]},"total":3} + type: simple + x-speakeasy-test-group: customers_exchanges + x-speakeasy-test-rebuild: false + - workflowId: listBusinessClassifications + steps: + - stepId: test + operationId: listBusinessClassifications + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"business-classifications":[{"_links":{},"_embedded":{}}, {"_links":{},"_embedded":{}}]},"total":3} + type: simple + x-speakeasy-test-group: businessClassifications + x-speakeasy-test-rebuild: false + - workflowId: retrieveBusinessClassification + steps: + - stepId: test + operationId: retrieveBusinessClassification + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"industry-classifications":[{"id":"9ed3f66b-7d6f-11e3-95ac-5404a6144203","name":"Wineries"}, {"id":"9ed3f66b-7d6f-11e3-95ac-5404a6144203","name":"Wineries"}]},"id":"9ed3f669-7d6f-11e3-b545-5404a6144203","name":"Food retail and service"} + type: simple + x-speakeasy-test-group: businessClassifications + x-speakeasy-test-rebuild: false + - workflowId: retrieveBeneficialOwner + steps: + - stepId: test + operationId: retrieveBeneficialOwner + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","firstName":"John","lastName":"Doe","address":{"address1":"462 Main Street","address2":"Suite 123","address3":"Unit 123","city":"Des Moines","postalCode":"50309","country":"USA","stateProvinceRegion":"IA"},"verificationStatus":"verified","created":"2022-07-23T00:18:21.419Z"} + type: simple + x-speakeasy-test-group: beneficialOwners + x-speakeasy-test-rebuild: false + - workflowId: updateBeneficialOwner + steps: + - stepId: test + operationId: updateBeneficialOwner + parameters: + - name: id + in: path + value: + requestBody: + contentType: application/json + payload: + address: + address1: 462 Main Street + address2: Suite 123 + address3: Unit 123 + city: Des Moines + country: USA + postalCode: "50309" + stateProvinceRegion: IA + dateOfBirth: "2005-10-23" + firstName: Lauryn + lastName: D'Amore + passport: + country: Suriname + number: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","firstName":"John","lastName":"Doe","address":{"address1":"462 Main Street","address2":"Suite 123","address3":"Unit 123","city":"Des Moines","postalCode":"50309","country":"USA","stateProvinceRegion":"IA"},"verificationStatus":"verified","created":"2022-07-23T00:18:21.419Z"} + type: simple + x-speakeasy-test-group: beneficialOwners + x-speakeasy-test-rebuild: false + - workflowId: deleteBeneficialOwner + steps: + - stepId: test + operationId: deleteBeneficialOwner + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {} + type: simple + x-speakeasy-test-group: beneficialOwners + x-speakeasy-test-rebuild: false + - workflowId: listBeneficialOwnerDocuments + steps: + - stepId: test + operationId: listBeneficialOwnerDocuments + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"documents":[{"_links":{"self":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"56502f7a-fa59-4a2f-8579-0f8bc9d7b9cc","status":"reviewed","type":"passport","created":"2015-09-29T21:42:16.000Z","documentVerificationStatus":"rejected","failureReason":"ScanDobMismatch","allFailureReasons":[{"reason":"ScanDobMismatch","description":"Scan DOB does not match DOB on account"}, {"reason":"ScanDobMismatch","description":"Scan DOB does not match DOB on account"}]}]},"total":2} + type: simple + x-speakeasy-test-group: beneficialOwners_documents + x-speakeasy-test-rebuild: false + - workflowId: retrieveDocument + steps: + - stepId: test + operationId: retrieveDocument + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"56502f7a-fa59-4a2f-8579-0f8bc9d7b9cc","status":"reviewed","type":"passport","created":"2015-09-29T21:42:16.000Z","documentVerificationStatus":"rejected","failureReason":"ScanDobMismatch","allFailureReasons":[{"reason":"ScanDobMismatch","description":"Scan DOB does not match DOB on account"}]} + type: simple + x-speakeasy-test-group: documents + x-speakeasy-test-rebuild: false + - workflowId: getKbaQuestions + steps: + - stepId: test + operationId: getKbaQuestions + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"answer":{"href":"https://api.dwolla.com/kba/62dac6f3-bf8f-4961-9af8-428de8ecd9a4","type":"application/vnd.dwolla.v1.hal+json","resource-type":"kba"}},"id":"62dac6f3-bf8f-4961-9af8-428de8ecd9a4","questions":[{"id":"2355953375","text":"In what county do you currently live?","answers":[{"id":"2687969295","text":"Pulaski"}, {"id":"2687969295","text":"Pulaski"}]}, {"id":"2355953375","text":"In what county do you currently live?","answers":[{"id":"2687969295","text":"Pulaski"}, {"id":"2687969295","text":"Pulaski"}]}, {"id":"2355953375","text":"In what county do you currently live?","answers":[{"id":"2687969295","text":"Pulaski"}, {"id":"2687969295","text":"Pulaski"}]}]} + type: simple + x-speakeasy-test-group: kba + x-speakeasy-test-rebuild: false + - workflowId: verifyKbaQuestions + steps: + - stepId: test + operationId: verifyKbaQuestions + parameters: + - name: id + in: path + value: + requestBody: + contentType: application/json + payload: + answers: + - answerId: "2687969335" + questionId: "2355953375" + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"customer":{"href":"https://api.dwolla.com/customers/b5fd802d-d8c7-43ce-94a8-7c14485b7042","type":"application/vnd.dwolla.v1.hal+json","resource-type":"customer"}},"verificationStatus":"verified"} + type: simple + x-speakeasy-test-group: kba + x-speakeasy-test-rebuild: false + - workflowId: getFundingSource + steps: + - stepId: test + operationId: getFundingSource + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","status":"unverified","type":"bank","bankAccountType":"checking","name":"My bank","created":"2022-07-23T00:18:21.419Z","removed":true,"channels":["ach"],"bankName":"SANDBOX TEST BANK","fingerprint":"5012989b55af15400e8102f95d2ec5e7ce3aef45c01613280d80a236dd8d6c"} + type: simple + x-speakeasy-test-group: fundingSources + x-speakeasy-test-rebuild: false + - workflowId: updateOrRemoveFundingSource + steps: + - stepId: test + operationId: updateOrRemoveFundingSource + parameters: + - name: id + in: path + value: + requestBody: + contentType: application/json + payload: + removed: true + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {} + type: simple + x-speakeasy-test-group: fundingSources + x-speakeasy-test-rebuild: false + - workflowId: getVanRouting + steps: + - stepId: test + operationId: getVanRouting + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"accountNumber":"9619991490430833","routingNumber":"084106768"} + type: simple + x-speakeasy-test-group: fundingSources + x-speakeasy-test-rebuild: false + - workflowId: getMicroDeposits + steps: + - stepId: test + operationId: getMicroDeposits + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"created":"2022-12-30T20:56:53.000Z","status":"failed","failure":{"code":"R03","description":"No Account/Unable to locate account"}} + type: simple + x-speakeasy-test-group: microDeposits + x-speakeasy-test-rebuild: false + - workflowId: verifyMicroDeposits + steps: + - stepId: test + operationId: verifyMicroDeposits + parameters: + - name: id + in: path + value: + requestBody: + contentType: application/vnd.dwolla.v1.hal+json + payload: + amount1: + currency: USD + value: "0.02" + amount2: + currency: USD + value: "0.03" + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api-sandbox.dwolla.com/funding-sources/2e446d1b-fb3c-42a0-9691-5d1d6a4dbbf0/micro-deposits","type":"application/vnd.dwolla.v1.hal+json","resource-type":"micro-deposits"}}} + type: simple + x-speakeasy-test-group: microDeposits + x-speakeasy-test-rebuild: false + - workflowId: getFundingSourceBalance + steps: + - stepId: test + operationId: getFundingSourceBalance + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"balance":{"value":"4616.87","currency":"USD"},"total":{"value":"4616.87","currency":"USD"},"lastUpdated":"2017-04-18T15:20:25.880Z"} + type: simple + x-speakeasy-test-group: balance + x-speakeasy-test-rebuild: false + - workflowId: createOnDemandTransferAuthorization + steps: + - stepId: test + operationId: createOnDemandTransferAuthorization + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/on-demand-authorizations/30e7c028-0bdf-e511-80de-0aa34a9b2388"}},"bodyText":"I agree that future payments to Company ABC inc. will be processed by the Dwolla payment system from the selected account above. In order to cancel this authorization, I will change my payment settings within my Company ABC inc. account.","buttonText":"Agree & Continue"} + type: simple + x-speakeasy-test-group: onDemandTransferAuthorizations + x-speakeasy-test-rebuild: false + - workflowId: getTransfer + steps: + - stepId: test + operationId: getTransfer + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"15c6bcce-46f7-e811-8112-e8dd3bececa8","status":"pending","amount":{"value":"42.00","currency":"USD"},"created":"2018-12-03T22:00:22.970Z","clearing":{"source":"standard","destination":"same-day"},"metadata":{"paymentId":"12345678","note":"Payment for completed work Dec. 1"},"achDetails":{"source":{"addenda":{"values":["ABC123_AddendaValue"]},"beneficiaryName":"John Doe","companyEntryDescription":"PAYMENT","companyId":"1234567890","companyName":"Acme Corporation","effectiveDate":"2021-12-01","postingData":"Acme Corporation:Payment Reference:John Doe","routingNumber":"222222226","traceId":"222222225926346"},"destination":{"addenda":{"values":["ZYX987_AddendaValue"]},"beneficiaryName":"Jane Smith","companyEntryDescription":"PAYMENT","companyId":"1234567890","companyName":"Acme Corporation","effectiveDate":"2021-12-01","postingData":"Acme Corporation:Payment Reference:Jane Smith","routingNumber":"222222226","traceId":"222222225926346"}},"rtpDetails":{"destination":{"remittanceData":"ABC_123 Remittance Data","networkId":"20210617021214273T1BG27487110796028","endToEndReferenceId":"E2E-RTP-20210617-001"}},"fedNowDetails":{"destination":{"remittanceData":"ABC_123 Remittance Data","networkId":"20240115123456789FEDNOW123456","endToEndReferenceId":"E2E-FEDNOW-20240115-001"}},"correlationId":"8a2cdc8d-629d-4a24-98ac-40b735229fe2","processingChannel":{"destination":"real-time-payments"}} + type: simple + x-speakeasy-test-group: transfers + x-speakeasy-test-rebuild: false + - workflowId: cancelTransfer + steps: + - stepId: test + operationId: cancelTransfer + parameters: + - name: id + in: path + value: + requestBody: + contentType: application/json + payload: + status: cancelled + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {} + type: simple + x-speakeasy-test-group: transfers + x-speakeasy-test-rebuild: false + - workflowId: listTransferFees + steps: + - stepId: test + operationId: listTransferFees + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"transactions":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"416a2857-c887-4cca-bd02-8c3f75c4bb0e","status":"pending","amount":{"value":"2.00","currency":"USD"},"created":"2016-02-22T20:46:38.777Z"}],"total":"1"} + type: simple + x-speakeasy-test-group: fees + x-speakeasy-test-rebuild: false + - workflowId: getTransferFailureReason + steps: + - stepId: test + operationId: getTransferFailureReason + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"code":"R03","description":"No Account/Unable to Locate Account","explanation":"The account number does not correspond to the individual identified in the entry or a valid account."} + type: simple + x-speakeasy-test-group: failure + x-speakeasy-test-rebuild: false + - workflowId: getMassPayment + steps: + - stepId: test + operationId: getMassPayment + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"11ac4051-7b76-44fc-87ab-ae23012393f0","status":"complete","created":"2022-01-20T17:41:41.000Z","total":{"value":"5.00","currency":"USD"},"totalFees":{"value":"5.00","currency":"USD"},"correlationId":"CID-8a2cdc8d-629d-4a24-98ac-40b735229fe2"} + type: simple + x-speakeasy-test-group: massPayments + x-speakeasy-test-rebuild: false + - workflowId: updateMassPayment + steps: + - stepId: test + operationId: updateMassPayment + parameters: + - name: id + in: path + value: + requestBody: + contentType: application/json + payload: + status: pending + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"11ac4051-7b76-44fc-87ab-ae23012393f0","status":"complete","created":"2022-01-20T17:41:41.000Z","total":{"value":"5.00","currency":"USD"},"totalFees":{"value":"5.00","currency":"USD"},"correlationId":"CID-8a2cdc8d-629d-4a24-98ac-40b735229fe2"} + type: simple + x-speakeasy-test-group: massPayments + x-speakeasy-test-rebuild: false + - workflowId: listMassPaymentItems + steps: + - stepId: test + operationId: listMassPaymentItems + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563/items"},"first":{"href":"https://api.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563/items?limit=25&offset=0"},"last":{"href":"https://api.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563/items?limit=25&offset=0"}},"_embedded":{"items":[{"_links":{"self":{"href":"https://api.dwolla.com/mass-payment-items/c1c7d293-63ec-e511-80df-0aa34a9b2388"},"mass-payment":{"href":"https://api.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563"},"destination":{"href":"https://api.dwolla.com/funding-sources/b442c936-1f87-465d-a4e2-a982164b26bd"},"transfer":{"href":"https://api.dwolla.com/transfers/fa3999db-41ed-e511-80df-0aa34a9b2388"}},"id":"2f845bc9-41ed-e511-80df-0aa34a9b2388","status":"success","amount":{"value":"1","currency":"USD"},"metadata":{"item1":"item1"},"processingChannel":{"destination":"real-time-payments"}}, {"_links":{"self":{"href":"https://api.dwolla.com/mass-payment-items/c1c7d293-63ec-e511-80df-0aa34a9b2388"},"mass-payment":{"href":"https://api.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563"},"destination":{"href":"https://api.dwolla.com/funding-sources/b442c936-1f87-465d-a4e2-a982164b26bd"},"transfer":{"href":"https://api.dwolla.com/transfers/fa3999db-41ed-e511-80df-0aa34a9b2388"}},"id":"2f845bc9-41ed-e511-80df-0aa34a9b2388","status":"success","amount":{"value":"1","currency":"USD"},"metadata":{"item1":"item1"},"processingChannel":{"destination":"real-time-payments"}}]},"total":3} + type: simple + x-speakeasy-test-group: items + x-speakeasy-test-rebuild: false + - workflowId: getMassPaymentItem + steps: + - stepId: test + operationId: getMassPaymentItem + parameters: + - name: itemId + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/mass-payment-items/c1c7d293-63ec-e511-80df-0aa34a9b2388"},"mass-payment":{"href":"https://api.dwolla.com/mass-payments/eb467252-808c-4bc0-b86f-a5cd01454563"},"destination":{"href":"https://api.dwolla.com/funding-sources/b442c936-1f87-465d-a4e2-a982164b26bd"},"transfer":{"href":"https://api.dwolla.com/transfers/fa3999db-41ed-e511-80df-0aa34a9b2388"}},"id":"2f845bc9-41ed-e511-80df-0aa34a9b2388","status":"success","amount":{"value":"1.00","currency":"USD"},"metadata":{"item1":"item1"},"processingChannel":{"destination":"real-time-payments"}} + type: simple + x-speakeasy-test-group: items + x-speakeasy-test-rebuild: false + - workflowId: getLabel + steps: + - stepId: test + operationId: getLabel + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"7e042ffe-e25e-40d2-b86e-748b98845ecc","created":"2022-05-15T22:19:09.635Z","amount":{"value":"10.00","currency":"USD"}} + type: simple + x-speakeasy-test-group: labels + x-speakeasy-test-rebuild: false + - workflowId: removeLabel + steps: + - stepId: test + operationId: removeLabel + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"7e042ffe-e25e-40d2-b86e-748b98845ecc","created":"2022-05-15T22:19:09.635Z","amount":{"value":"10.00","currency":"USD"}} + type: simple + x-speakeasy-test-group: labels + x-speakeasy-test-rebuild: false + - workflowId: listLabelLedgerEntries + steps: + - stepId: test + operationId: listLabelLedgerEntries + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"ledger-entries":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"32d68709-62dd-43d6-a6df-562f4baec526","amount":{"value":"-5","currency":"USD"},"created":"2019-05-16T01:54:58.062Z"}, {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"32d68709-62dd-43d6-a6df-562f4baec526","amount":{"value":"-5","currency":"USD"},"created":"2019-05-16T01:54:58.062Z"}]},"total":100} + type: simple + x-speakeasy-test-group: ledgerEntries + x-speakeasy-test-rebuild: false + - workflowId: getLabelLedgerEntry + steps: + - stepId: test + operationId: getLabelLedgerEntry + parameters: + - name: ledgerEntryId + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"32d68709-62dd-43d6-a6df-562f4baec526","amount":{"value":"-5.00","currency":"USD"},"created":"2019-05-16T01:54:58.062Z"} + type: simple + x-speakeasy-test-group: ledgerEntries + x-speakeasy-test-rebuild: false + - workflowId: retrieveLabelReallocation + steps: + - stepId: test + operationId: retrieveLabelReallocation + parameters: + - name: reallocationId + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/label-reallocations/fd36b78c-42f3-4e21-8efb-09196fccbd21","type":"application/vnd.dwolla.v1.hal+json","resource-type":"label-reallocation"},"to-ledger-entry":{"href":"https://api.dwolla.com/ledger-entries/d8a4bf7a-3fa0-48b9-873c-765d7375c59f","type":"application/vnd.dwolla.v1.hal+json","resource-type":"ledger-entry"},"from-ledger-entry":{"href":"https://api.dwolla.com/ledger-entries/f6a44994-b4da-48e3-bd10-d3a168e6a77d","type":"application/vnd.dwolla.v1.hal+json","resource-type":"ledger-entry"}},"created":"2022-05-16T13:41:31.036Z"} + type: simple + x-speakeasy-test-group: reallocations + x-speakeasy-test-rebuild: false + - workflowId: listEvents + steps: + - stepId: test + operationId: listEvents + x-speakeasy-test-group: events + x-speakeasy-test-rebuild: false + - workflowId: getEvent + steps: + - stepId: test + operationId: getEvent + parameters: + - name: id + in: path + value: + x-speakeasy-test-group: events + x-speakeasy-test-rebuild: false + - workflowId: listWebhookSubscriptions + steps: + - stepId: test + operationId: listWebhookSubscriptions + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/webhook-subscriptions"}},"_embedded":{"webhook-subscriptions":[{"_links":{"self":{"href":"https://api.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589"},"webhooks":{"href":"https://api.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589/webhooks"}},"id":"077dfffb-4852-412f-96b6-0fe668066589","url":"http://myapplication.com/webhooks","paused":true,"created":"2022-10-28T16:20:47+00:00"}]},"total":1} + type: simple + x-speakeasy-test-group: webhookSubscriptions + x-speakeasy-test-rebuild: false + - workflowId: getWebhookSubscription + steps: + - stepId: test + operationId: getWebhookSubscription + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589"},"webhooks":{"href":"https://api.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589/webhooks"}},"id":"077dfffb-4852-412f-96b6-0fe668066589","url":"http://myapplication.com/webhooks","paused":true,"created":"2022-10-28T16:20:47+00:00"} + type: simple + x-speakeasy-test-group: webhookSubscriptions + x-speakeasy-test-rebuild: false + - workflowId: updateWebhookSubscription + steps: + - stepId: test + operationId: updateWebhookSubscription + parameters: + - name: id + in: path + value: + requestBody: + contentType: application/json + payload: + paused: true + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589"},"webhooks":{"href":"https://api.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589/webhooks"}},"id":"077dfffb-4852-412f-96b6-0fe668066589","url":"http://myapplication.com/webhooks","paused":true,"created":"2022-10-28T16:20:47+00:00"} + type: simple + x-speakeasy-test-group: webhookSubscriptions + x-speakeasy-test-rebuild: false + - workflowId: delete + steps: + - stepId: test + operationId: delete + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589"},"webhooks":{"href":"https://api.dwolla.com/webhook-subscriptions/077dfffb-4852-412f-96b6-0fe668066589/webhooks"}},"id":"077dfffb-4852-412f-96b6-0fe668066589","url":"http://myapplication.com/webhooks","paused":true,"created":"2022-10-28T16:20:47+00:00"} + type: simple + x-speakeasy-test-group: webhookSubscriptions + x-speakeasy-test-rebuild: false + - workflowId: listWebhooks + steps: + - stepId: test + operationId: listWebhooks + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/webhook-subscriptions/a0943041-7a5c-4e8f-92de-b55711ef3a83/webhooks"},"first":{"href":"https://api.dwolla.com/webhook-subscriptions/a0943041-7a5c-4e8f-92de-b55711ef3a83/webhooks?limit=25&offset=0"},"last":{"href":"https://api.dwolla.com/webhook-subscriptions/a0943041-7a5c-4e8f-92de-b55711ef3a83/webhooks?limit=25&offset=150"},"next":{"href":"https://api.dwolla.com/webhook-subscriptions/a0943041-7a5c-4e8f-92de-b55711ef3a83/webhooks?limit=25&offset=25"}},"_embedded":{"webhooks":[{"_links":{"self":{"href":"https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8"},"subscription":{"href":"https://api.dwolla.com/webhook-subscriptions/a0943041-7a5c-4e8f-92de-b55711ef3a83"},"retry":{"href":"https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries"},"event":{"href":"https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50"}},"id":"9ece9660-aa34-41eb-80d7-0125d53b45e8","topic":"transfer_created","accountId":"ca32853c-48fa-40be-ae75-77b37504581b","eventId":"03c7e14c-7f15-44a2-bcf7-83f2f7e95d50","subscriptionId":"a0943041-7a5c-4e8f-92de-b55711ef3a83","attempts":[{"id":"d4d16621-c6b0-40cb-8dc3-0469fa9dc4e8","request":{"timestamp":"2022-10-27T17:07:34.304Z","url":"https://myapp.runscope.net","headers":[{"name":"X-Dwolla-Topic","value":"transfer_created"}],"body":"id:03c7e14c-7f15-44a2-bcf7-83f2f7e95d50resourceId:81BA6F36-CD7C-E511-80DB-0AA34A9B2388topic:transfer_createdtimestamp:2022-10-27T17:07:34.207Z_links:self:href:https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50account:href:https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581bresource:href:https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388"},"response":{"timestamp":"2022-10-27T17:07:34.308Z","headers":[{"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}],"statusCode":200,"body":"body:id:03c7e14c-7f15-44a2-bcf7-83f2f7e95d50resourceId:81BA6F36-CD7C-E511-80DB-0AA34A9B2388topic:transfer_createdtimestamp:2022-10-27T17:07:34.207Z_links:self:href:https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50account:href:https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581bresource:href:https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388files:[]form:fragment:headers:Connection:[close]Content-Length:[453]Content-Type:[application/json; charset=UTF-8]Host:[myapp.runscope.net]User-Agent:[dwolla-webhooks/1.0]X-Dwolla-Topic:[transfer_created]X-Request-Signature:[bd93780bd7e1ad77ab821094aaa0f9e3dece5ee3]host:myapp.runscope.netmethod:POSTparams:path:/region:us5runscope_host:prod078.runscope.inscheme:httpssource:capturesource_ip:52.24.10.184timestamp:1.4459656543078682e+09url:https://myapp.runscope.net/"}}]}]},"total":1} + type: simple + x-speakeasy-test-group: webhookSubscriptions_webhooks + x-speakeasy-test-rebuild: false + - workflowId: getWebhook + steps: + - stepId: test + operationId: getWebhook + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8"},"subscription":{"href":"https://api.dwolla.com/webhook-subscriptions/a0943041-7a5c-4e8f-92de-b55711ef3a83"},"retry":{"href":"https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries"},"event":{"href":"https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50"}},"id":"9ece9660-aa34-41eb-80d7-0125d53b45e8","topic":"transfer_created","accountId":"ca32853c-48fa-40be-ae75-77b37504581b","eventId":"03c7e14c-7f15-44a2-bcf7-83f2f7e95d50","subscriptionId":"a0943041-7a5c-4e8f-92de-b55711ef3a83","attempts":[{"id":"d4d16621-c6b0-40cb-8dc3-0469fa9dc4e8","request":{"timestamp":"2022-10-27T17:07:34.304Z","url":"https://myapp.runscope.net","headers":[{"name":"X-Dwolla-Topic","value":"transfer_created"}, {"name":"X-Dwolla-Topic","value":"transfer_created"}, {"name":"X-Dwolla-Topic","value":"transfer_created"}],"body":"id:03c7e14c-7f15-44a2-bcf7-83f2f7e95d50resourceId:81BA6F36-CD7C-E511-80DB-0AA34A9B2388topic:transfer_createdtimestamp:2022-10-27T17:07:34.207Z_links:self:href:https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50account:href:https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581bresource:href:https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388"},"response":{"timestamp":"2022-10-27T17:07:34.308Z","headers":[{"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}, {"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}, {"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}],"statusCode":200,"body":"body:id:03c7e14c-7f15-44a2-bcf7-83f2f7e95d50resourceId:81BA6F36-CD7C-E511-80DB-0AA34A9B2388topic:transfer_createdtimestamp:2022-10-27T17:07:34.207Z_links:self:href:https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50account:href:https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581bresource:href:https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388files:[]form:fragment:headers:Connection:[close]Content-Length:[453]Content-Type:[application/json; charset=UTF-8]Host:[myapp.runscope.net]User-Agent:[dwolla-webhooks/1.0]X-Dwolla-Topic:[transfer_created]X-Request-Signature:[bd93780bd7e1ad77ab821094aaa0f9e3dece5ee3]host:myapp.runscope.netmethod:POSTparams:path:/region:us5runscope_host:prod078.runscope.inscheme:httpssource:capturesource_ip:52.24.10.184timestamp:1.4459656543078682e+09url:https://myapp.runscope.net/"}}, {"id":"d4d16621-c6b0-40cb-8dc3-0469fa9dc4e8","request":{"timestamp":"2022-10-27T17:07:34.304Z","url":"https://myapp.runscope.net","headers":[{"name":"X-Dwolla-Topic","value":"transfer_created"}, {"name":"X-Dwolla-Topic","value":"transfer_created"}, {"name":"X-Dwolla-Topic","value":"transfer_created"}],"body":"id:03c7e14c-7f15-44a2-bcf7-83f2f7e95d50resourceId:81BA6F36-CD7C-E511-80DB-0AA34A9B2388topic:transfer_createdtimestamp:2022-10-27T17:07:34.207Z_links:self:href:https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50account:href:https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581bresource:href:https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388"},"response":{"timestamp":"2022-10-27T17:07:34.308Z","headers":[{"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}, {"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}, {"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}],"statusCode":200,"body":"body:id:03c7e14c-7f15-44a2-bcf7-83f2f7e95d50resourceId:81BA6F36-CD7C-E511-80DB-0AA34A9B2388topic:transfer_createdtimestamp:2022-10-27T17:07:34.207Z_links:self:href:https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50account:href:https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581bresource:href:https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388files:[]form:fragment:headers:Connection:[close]Content-Length:[453]Content-Type:[application/json; charset=UTF-8]Host:[myapp.runscope.net]User-Agent:[dwolla-webhooks/1.0]X-Dwolla-Topic:[transfer_created]X-Request-Signature:[bd93780bd7e1ad77ab821094aaa0f9e3dece5ee3]host:myapp.runscope.netmethod:POSTparams:path:/region:us5runscope_host:prod078.runscope.inscheme:httpssource:capturesource_ip:52.24.10.184timestamp:1.4459656543078682e+09url:https://myapp.runscope.net/"}}, {"id":"d4d16621-c6b0-40cb-8dc3-0469fa9dc4e8","request":{"timestamp":"2022-10-27T17:07:34.304Z","url":"https://myapp.runscope.net","headers":[{"name":"X-Dwolla-Topic","value":"transfer_created"}, {"name":"X-Dwolla-Topic","value":"transfer_created"}, {"name":"X-Dwolla-Topic","value":"transfer_created"}],"body":"id:03c7e14c-7f15-44a2-bcf7-83f2f7e95d50resourceId:81BA6F36-CD7C-E511-80DB-0AA34A9B2388topic:transfer_createdtimestamp:2022-10-27T17:07:34.207Z_links:self:href:https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50account:href:https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581bresource:href:https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388"},"response":{"timestamp":"2022-10-27T17:07:34.308Z","headers":[{"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}, {"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}, {"name":"Date","value":"Tue 27 Oct 2022 17:07:34 GMT"}],"statusCode":200,"body":"body:id:03c7e14c-7f15-44a2-bcf7-83f2f7e95d50resourceId:81BA6F36-CD7C-E511-80DB-0AA34A9B2388topic:transfer_createdtimestamp:2022-10-27T17:07:34.207Z_links:self:href:https://api.dwolla.com/events/03c7e14c-7f15-44a2-bcf7-83f2f7e95d50account:href:https://api.dwolla.com/accounts/ca32853c-48fa-40be-ae75-77b37504581bresource:href:https://api.dwolla.com/transfers/81BA6F36-CD7C-E511-80DB-0AA34A9B2388files:[]form:fragment:headers:Connection:[close]Content-Length:[453]Content-Type:[application/json; charset=UTF-8]Host:[myapp.runscope.net]User-Agent:[dwolla-webhooks/1.0]X-Dwolla-Topic:[transfer_created]X-Request-Signature:[bd93780bd7e1ad77ab821094aaa0f9e3dece5ee3]host:myapp.runscope.netmethod:POSTparams:path:/region:us5runscope_host:prod078.runscope.inscheme:httpssource:capturesource_ip:52.24.10.184timestamp:1.4459656543078682e+09url:https://myapp.runscope.net/"}}]} + type: simple + x-speakeasy-test-group: webhooks + x-speakeasy-test-rebuild: false + - workflowId: listWebhookRetries + steps: + - stepId: test + operationId: listWebhookRetries + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"self":{"href":"https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries"}},"_embedded":{"retries":[{"_links":{"self":{"href":"https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries/5aa27a0f-cf99-418d-a3ee-67c0ff99a494"},"webhook":{"href":"https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8"}},"id":"5aa27a0f-cf99-418d-a3ee-67c0ff99a494","timestamp":"2022-11-02T17:43:26.000Z"}, {"_links":{"self":{"href":"https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8/retries/5aa27a0f-cf99-418d-a3ee-67c0ff99a494"},"webhook":{"href":"https://api.dwolla.com/webhooks/9ece9660-aa34-41eb-80d7-0125d53b45e8"}},"id":"5aa27a0f-cf99-418d-a3ee-67c0ff99a494","timestamp":"2022-11-02T17:43:26.000Z"}]},"total":1} + type: simple + x-speakeasy-test-group: retries + x-speakeasy-test-rebuild: false + - workflowId: simulateBankTransferProcessing + steps: + - stepId: test + operationId: simulateBankTransferProcessing + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {} + type: simple + x-speakeasy-test-group: sandbox simulations + x-speakeasy-test-rebuild: false + - workflowId: listExchangePartners + steps: + - stepId: test + operationId: listExchangePartners + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"_embedded":{"exchange-partners":[{"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","name":"Plaid","status":"active","created":"2022-07-23T00:18:21.419Z"}, {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","name":"Plaid","status":"active","created":"2022-07-23T00:18:21.419Z"}, {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","name":"Plaid","status":"active","created":"2022-07-23T00:18:21.419Z"}]},"total":3} + type: simple + x-speakeasy-test-group: exchangePartners + x-speakeasy-test-rebuild: false + - workflowId: getExchangePartner + steps: + - stepId: test + operationId: getExchangePartner + parameters: + - name: id + in: path + value: 292317ec-e252-47d8-93c3-2d128e037aa4 + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","name":"Plaid","status":"active","created":"2022-07-23T00:18:21.419Z"} + type: simple + x-speakeasy-test-group: exchangePartners + x-speakeasy-test-rebuild: false + - workflowId: getExchange + steps: + - stepId: test + operationId: getExchange + parameters: + - name: id + in: path + value: e5e9f2d3-a96c-4abd-a097-8ec7ae28aa8a + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"_links":{"key":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key1":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"},"key2":{"href":"https://api.dwolla.com","type":"application/vnd.dwolla.v1.hal+json","resource-type":"resource-type"}},"id":"d3d6b41e-5567-4bc6-9c6e-0efd0a3e647e","status":"active","created":"2022-07-23T00:18:21.419Z"} + type: simple + x-speakeasy-test-group: exchanges + x-speakeasy-test-rebuild: false + - workflowId: retrieveCustomerExchangeSession + steps: + - stepId: test + operationId: retrieveCustomerExchangeSession + parameters: + - name: id + in: path + value: + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/vnd.dwolla.v1.hal+json + - context: $response.body + condition: | + {"created":"2024-03-25T17:13:38.430Z","_links":{"self":{"href":"https://api.dwolla.com/exchange-sessions/9b7fb629-0fad-44f4-8c5e-44c25a0bfa8e","type":"application/vnd.dwolla.v1.hal+json","resource-type":"exchange-sessions"},"exchange-partner":{"href":"https://api.dwolla.com/exchange-partners/bca8d065-49a5-475b-a6b4-509bc8504d22","type":"application/vnd.dwolla.v1.hal+json","resource-type":"exchange-partner"},"external-provider-session":{"href":"https://www.mx.com/connect/lAfkc7m897s3t1ks9mmwyj4ry7Zq0xql4grzAg1kz77x7c9jrwls1t22w6xt8d2lsxx9zpqv30js3wswfdwcrpAsqgbAfkqwpksp7c2chsx167xy90Asfc67dkj9y48y8p142xw3yp4x5l9t9gkk6m3yk5vwsvyq2qq7w9trszxwdl14lmkg7l6949bn5n41chdkbnxycy40n9b6fkbdwl6qt5wl107k1x8srvlkpz325p412x9tkyA5clf39109lsfrgz2lkgsvntqf7l0zzwb5hl658gdjbxwhb52krwybnbdAqfq69cdy54l05jkvfwyf01q89x48jtgtx290lzjdfcty1lwb8d648wns/eyJ1aV9tZXNzYWdlX3ZlcnNpb24iOjQsInVpX21lc3NhZ2Vfd2Vidmlld191cmxfc2NoZW1lIjoibXgiLCJtb2RlIjoidmVyaWZpY2F0aW9uIn0%3D","type":"application/vnd.dwolla.v1.hal+json","resource-type":"text/html"}},"externalProviderSessionToken":"link-production-b41e8ed3-0874-4c64-b07d-a77088979d5f"} + type: simple + x-speakeasy-test-group: exchangeSessions + x-speakeasy-test-rebuild: false + - workflowId: createClientToken + steps: + - stepId: test + operationId: createClientToken + requestBody: + contentType: application/json + payload: + _links: + customer: + href: https://api-sandbox.dwolla.com/customers/707177c3-bf15-4e7e-b37c-55c3898d9bf4 + action: customer.update + successCriteria: + - condition: $statusCode == 200 + - condition: $response.header.Content-Type == application/json + - context: $response.body + condition: | + {"token":"4adF858jPeQ9RnojMHdqSD2KwsvmhO7Ti7cI5woOiBGCpH5krY"} + type: simple + x-speakeasy-test-group: clientTokens + x-speakeasy-test-rebuild: false diff --git a/.speakeasy/workflow.lock b/.speakeasy/workflow.lock index f360cc1..c2c7fde 100644 --- a/.speakeasy/workflow.lock +++ b/.speakeasy/workflow.lock @@ -1,9 +1,9 @@ -speakeasyVersion: 1.658.2 +speakeasyVersion: 1.667.0 sources: Dwolla API: sourceNamespace: dwolla-api - sourceRevisionDigest: sha256:8560f130650477e719c332a5dd7de3491ac607dfacadedf856b431398fe90b54 - sourceBlobDigest: sha256:2bcc871656f1bc33551ec6f2d0d26e2a8dbd69adc88c9b10e52c2bf44bf28f11 + sourceRevisionDigest: sha256:8cb2abe41e95d73817dac1f48cc94e1731ab7ffab4ac9f4cd244fd41bd551d6e + sourceBlobDigest: sha256:85a12398d13f5d9a11c6d9382157f30fdd58d89b3f5b14d043b2ae4cdb8fc5b6 tags: - latest - "2.0" @@ -11,10 +11,10 @@ targets: dwolla: source: Dwolla API sourceNamespace: dwolla-api - sourceRevisionDigest: sha256:8560f130650477e719c332a5dd7de3491ac607dfacadedf856b431398fe90b54 - sourceBlobDigest: sha256:2bcc871656f1bc33551ec6f2d0d26e2a8dbd69adc88c9b10e52c2bf44bf28f11 + sourceRevisionDigest: sha256:8cb2abe41e95d73817dac1f48cc94e1731ab7ffab4ac9f4cd244fd41bd551d6e + sourceBlobDigest: sha256:85a12398d13f5d9a11c6d9382157f30fdd58d89b3f5b14d043b2ae4cdb8fc5b6 codeSamplesNamespace: dwolla-api-typescript-code-samples - codeSamplesRevisionDigest: sha256:c469e70e3f1bec2c0149f3513e457a6de5dafba0b044f58334f2560f87df8ada + codeSamplesRevisionDigest: sha256:fb7ceb12123821f6441823d3404f0f0bcda81618af11a012fa91eba387766f71 workflow: workflowVersion: 1.0.0 speakeasyVersion: latest @@ -40,3 +40,5 @@ workflow: labelOverride: fixedValue: Typescript (SDK) blocking: false + testing: + enabled: false diff --git a/.speakeasy/workflow.yaml b/.speakeasy/workflow.yaml index cf9f76b..870405d 100644 --- a/.speakeasy/workflow.yaml +++ b/.speakeasy/workflow.yaml @@ -22,3 +22,5 @@ targets: labelOverride: fixedValue: Typescript (SDK) blocking: false + testing: + enabled: false diff --git a/FUNCTIONS.md b/FUNCTIONS.md index 1503a00..222418e 100644 --- a/FUNCTIONS.md +++ b/FUNCTIONS.md @@ -24,15 +24,12 @@ import { tokensCreate } from "dwolla/funcs/tokensCreate.js"; // Use `DwollaCore` for best tree-shaking performance. // You can create one instance of it to use across an application. -const dwolla = new DwollaCore({ - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, -}); +const dwolla = new DwollaCore(); async function run() { const res = await tokensCreate(dwolla, { + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); if (res.ok) { diff --git a/README.md b/README.md index 932d42a..fbc3962 100644 --- a/README.md +++ b/README.md @@ -90,15 +90,12 @@ For supported JavaScript runtimes, please consult [RUNTIMES.md](RUNTIMES.md). ```typescript import { Dwolla } from "dwolla"; -const dwolla = new Dwolla({ - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, -}); +const dwolla = new Dwolla(); async function run() { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); @@ -132,8 +129,28 @@ const dwolla = new Dwolla({ }, }); +async function run() { + const result = await dwolla.root.get(); + + console.log(result); +} + +run(); + +``` + +### Per-Operation Security Schemes + +Some operations in this SDK require the security scheme to be specified at the request level. For example: +```typescript +import { Dwolla } from "dwolla"; + +const dwolla = new Dwolla(); + async function run() { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); @@ -528,15 +545,12 @@ To change the default retry strategy for a single API call, simply provide a ret ```typescript import { Dwolla } from "dwolla"; -const dwolla = new Dwolla({ - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, -}); +const dwolla = new Dwolla(); async function run() { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }, { retries: { @@ -573,14 +587,12 @@ const dwolla = new Dwolla({ }, retryConnectionErrors: false, }, - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, }); async function run() { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); @@ -611,16 +623,13 @@ run(); import { Dwolla } from "dwolla"; import * as errors from "dwolla/models/errors"; -const dwolla = new Dwolla({ - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, -}); +const dwolla = new Dwolla(); async function run() { try { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); @@ -860,14 +869,12 @@ import { Dwolla } from "dwolla"; const dwolla = new Dwolla({ server: "prod", - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, }); async function run() { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); @@ -886,14 +893,12 @@ import { Dwolla } from "dwolla"; const dwolla = new Dwolla({ serverURL: "https://api.dwolla.com", - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, }); async function run() { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); diff --git a/USAGE.md b/USAGE.md index d6808b2..fb01be2 100644 --- a/USAGE.md +++ b/USAGE.md @@ -2,15 +2,12 @@ ```typescript import { Dwolla } from "dwolla"; -const dwolla = new Dwolla({ - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, -}); +const dwolla = new Dwolla(); async function run() { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); diff --git a/docs/models/createreceiveonlyuser.md b/docs/models/createreceiveonlyuser.md index 2fffee4..baa4cca 100644 --- a/docs/models/createreceiveonlyuser.md +++ b/docs/models/createreceiveonlyuser.md @@ -11,6 +11,7 @@ let value: CreateReceiveOnlyUser = { firstName: "Account", lastName: "Admin", email: "accountAdmin@email.com", + type: "receive-only", ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", @@ -25,7 +26,7 @@ let value: CreateReceiveOnlyUser = { | `firstName` | *string* | :heavy_check_mark: | N/A | Account | | `lastName` | *string* | :heavy_check_mark: | N/A | Admin | | `email` | *string* | :heavy_check_mark: | N/A | accountAdmin@email.com | -| `type` | *string* | :heavy_check_mark: | N/A | | +| `type` | *"receive-only"* | :heavy_check_mark: | N/A | | | `ipAddress` | *string* | :heavy_minus_sign: | N/A | 143.156.7.8 | | `phone` | *string* | :heavy_minus_sign: | N/A | 5555555555 | | `correlationId` | *string* | :heavy_minus_sign: | N/A | fc451a7a-ae30-4404-aB95-e3553fcd733 | diff --git a/docs/models/createunverifiedcustomer.md b/docs/models/createunverifiedcustomer.md index e0e57b4..9ff0455 100644 --- a/docs/models/createunverifiedcustomer.md +++ b/docs/models/createunverifiedcustomer.md @@ -11,6 +11,7 @@ let value: CreateUnverifiedCustomer = { firstName: "Account", lastName: "Admin", email: "accountAdmin@email.com", + type: "unverified", ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", @@ -25,7 +26,7 @@ let value: CreateUnverifiedCustomer = { | `firstName` | *string* | :heavy_check_mark: | N/A | Account | | `lastName` | *string* | :heavy_check_mark: | N/A | Admin | | `email` | *string* | :heavy_check_mark: | N/A | accountAdmin@email.com | -| `type` | *string* | :heavy_check_mark: | N/A | | +| `type` | *"unverified"* | :heavy_check_mark: | N/A | | | `ipAddress` | *string* | :heavy_minus_sign: | N/A | 143.156.7.8 | | `phone` | *string* | :heavy_minus_sign: | N/A | 5555555555 | | `correlationId` | *string* | :heavy_minus_sign: | N/A | fc451a7a-ae30-4404-aB95-e3553fcd733 | diff --git a/docs/models/createverifiedbusinesscustomerwithcontroller.md b/docs/models/createverifiedbusinesscustomerwithcontroller.md index 4ed5db0..4015cd9 100644 --- a/docs/models/createverifiedbusinesscustomerwithcontroller.md +++ b/docs/models/createverifiedbusinesscustomerwithcontroller.md @@ -14,6 +14,7 @@ let value: CreateVerifiedBusinessCustomerWithController = { ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", + type: "business", address1: "99-99 33rd St", address2: "99-99 33rd St", city: "Some City", @@ -54,7 +55,7 @@ let value: CreateVerifiedBusinessCustomerWithController = { | `ipAddress` | *string* | :heavy_minus_sign: | N/A | 143.156.7.8 | | `phone` | *string* | :heavy_minus_sign: | N/A | 5555555555 | | `correlationId` | *string* | :heavy_minus_sign: | N/A | fc451a7a-ae30-4404-aB95-e3553fcd733 | -| `type` | *string* | :heavy_check_mark: | N/A | | +| `type` | *"business"* | :heavy_check_mark: | N/A | | | `address1` | *string* | :heavy_check_mark: | N/A | 99-99 33rd St | | `address2` | *string* | :heavy_minus_sign: | N/A | 99-99 33rd St | | `city` | *string* | :heavy_check_mark: | N/A | Some City | diff --git a/docs/models/createverifiedbusinesscustomerwithinternationalcontroller.md b/docs/models/createverifiedbusinesscustomerwithinternationalcontroller.md index d8e9b3c..982104d 100644 --- a/docs/models/createverifiedbusinesscustomerwithinternationalcontroller.md +++ b/docs/models/createverifiedbusinesscustomerwithinternationalcontroller.md @@ -14,6 +14,7 @@ let value: CreateVerifiedBusinessCustomerWithInternationalController = { ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", + type: "business", address1: "99-99 33rd St", address2: "99-99 33rd St", city: "Some City", @@ -57,7 +58,7 @@ let value: CreateVerifiedBusinessCustomerWithInternationalController = { | `ipAddress` | *string* | :heavy_minus_sign: | N/A | 143.156.7.8 | | `phone` | *string* | :heavy_minus_sign: | N/A | 5555555555 | | `correlationId` | *string* | :heavy_minus_sign: | N/A | fc451a7a-ae30-4404-aB95-e3553fcd733 | -| `type` | *string* | :heavy_check_mark: | N/A | | +| `type` | *"business"* | :heavy_check_mark: | N/A | | | `address1` | *string* | :heavy_check_mark: | N/A | 99-99 33rd St | | `address2` | *string* | :heavy_minus_sign: | N/A | 99-99 33rd St | | `city` | *string* | :heavy_check_mark: | N/A | Some City | diff --git a/docs/models/createverifiedpersonalcustomer.md b/docs/models/createverifiedpersonalcustomer.md index 0b17e4a..9dd8ad5 100644 --- a/docs/models/createverifiedpersonalcustomer.md +++ b/docs/models/createverifiedpersonalcustomer.md @@ -14,6 +14,7 @@ let value: CreateVerifiedPersonalCustomer = { ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", + type: "personal", address1: "99-99 33rd St", address2: "99-99 33rd St", city: "Some City", @@ -34,7 +35,7 @@ let value: CreateVerifiedPersonalCustomer = { | `ipAddress` | *string* | :heavy_minus_sign: | N/A | 143.156.7.8 | | `phone` | *string* | :heavy_minus_sign: | N/A | 5555555555 | | `correlationId` | *string* | :heavy_minus_sign: | N/A | fc451a7a-ae30-4404-aB95-e3553fcd733 | -| `type` | *string* | :heavy_check_mark: | N/A | | +| `type` | *"personal"* | :heavy_check_mark: | N/A | | | `address1` | *string* | :heavy_check_mark: | N/A | 99-99 33rd St | | `address2` | *string* | :heavy_minus_sign: | N/A | 99-99 33rd St | | `city` | *string* | :heavy_check_mark: | N/A | Some City | diff --git a/docs/models/createverifiedsolepropcustomer.md b/docs/models/createverifiedsolepropcustomer.md index 8a9daed..0953018 100644 --- a/docs/models/createverifiedsolepropcustomer.md +++ b/docs/models/createverifiedsolepropcustomer.md @@ -14,6 +14,7 @@ let value: CreateVerifiedSolePropCustomer = { ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", + type: "business", address1: "99-99 33rd St", address2: "99-99 33rd St", city: "Some City", @@ -26,6 +27,7 @@ let value: CreateVerifiedSolePropCustomer = { doingBusinessAs: "Jane's Electronics", ein: "00-0000000", website: "https://www.domain.com", + businessType: "soleProprietorship", }; ``` @@ -39,7 +41,7 @@ let value: CreateVerifiedSolePropCustomer = { | `ipAddress` | *string* | :heavy_minus_sign: | N/A | 143.156.7.8 | | `phone` | *string* | :heavy_minus_sign: | N/A | 5555555555 | | `correlationId` | *string* | :heavy_minus_sign: | N/A | fc451a7a-ae30-4404-aB95-e3553fcd733 | -| `type` | *string* | :heavy_check_mark: | N/A | | +| `type` | *"business"* | :heavy_check_mark: | N/A | | | `address1` | *string* | :heavy_check_mark: | N/A | 99-99 33rd St | | `address2` | *string* | :heavy_minus_sign: | N/A | 99-99 33rd St | | `city` | *string* | :heavy_check_mark: | N/A | Some City | @@ -52,4 +54,4 @@ let value: CreateVerifiedSolePropCustomer = { | `doingBusinessAs` | *string* | :heavy_minus_sign: | N/A | Jane's Electronics | | `ein` | *string* | :heavy_minus_sign: | N/A | 00-0000000 | | `website` | *string* | :heavy_minus_sign: | N/A | https://www.domain.com | -| `businessType` | *string* | :heavy_check_mark: | N/A | | \ No newline at end of file +| `businessType` | *"soleProprietorship"* | :heavy_check_mark: | N/A | | \ No newline at end of file diff --git a/docs/models/customers.md b/docs/models/customers.md index ed03252..e1fddf2 100644 --- a/docs/models/customers.md +++ b/docs/models/customers.md @@ -39,12 +39,14 @@ let value: Customers = { }, ], }, + total: 2, }; ``` ## Fields -| Field | Type | Required | Description | -| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | -| `links` | Record | :heavy_minus_sign: | N/A | -| `embedded` | [models.CustomersEmbedded](../models/customersembedded.md) | :heavy_minus_sign: | N/A | \ No newline at end of file +| Field | Type | Required | Description | Example | +| ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | ---------------------------------------------------------- | +| `links` | Record | :heavy_minus_sign: | N/A | | +| `embedded` | [models.CustomersEmbedded](../models/customersembedded.md) | :heavy_minus_sign: | N/A | | +| `total` | *number* | :heavy_minus_sign: | N/A | 2 | \ No newline at end of file diff --git a/docs/models/fundingsourcechannel.md b/docs/models/fundingsourcechannel.md index 0bc4a3d..4140fa3 100644 --- a/docs/models/fundingsourcechannel.md +++ b/docs/models/fundingsourcechannel.md @@ -11,5 +11,5 @@ let value: FundingSourceChannel = "ach"; ## Values ```typescript -"ach" | "real-time-payments" | "wire" +"ach" | "real-time-payments" | "wire" | "external" ``` \ No newline at end of file diff --git a/docs/models/operations/canceltransferrequest.md b/docs/models/operations/canceltransferrequest.md index 444feba..5fcc7ed 100644 --- a/docs/models/operations/canceltransferrequest.md +++ b/docs/models/operations/canceltransferrequest.md @@ -7,7 +7,9 @@ import { CancelTransferRequest } from "dwolla/models/operations"; let value: CancelTransferRequest = { id: "", - requestBody: {}, + requestBody: { + status: "cancelled", + }, }; ``` diff --git a/docs/models/operations/canceltransferrequestbody.md b/docs/models/operations/canceltransferrequestbody.md index 02a6640..78a1458 100644 --- a/docs/models/operations/canceltransferrequestbody.md +++ b/docs/models/operations/canceltransferrequestbody.md @@ -7,11 +7,13 @@ Parameters to cancel a transfer ```typescript import { CancelTransferRequestBody } from "dwolla/models/operations"; -let value: CancelTransferRequestBody = {}; +let value: CancelTransferRequestBody = { + status: "cancelled", +}; ``` ## Fields | Field | Type | Required | Description | | ------------------ | ------------------ | ------------------ | ------------------ | -| `status` | *string* | :heavy_check_mark: | N/A | \ No newline at end of file +| `status` | *"cancelled"* | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/operations/createapplicationaccesstokenresponse.md b/docs/models/operations/createapplicationaccesstokenresponse.md index 986059e..7ca083e 100644 --- a/docs/models/operations/createapplicationaccesstokenresponse.md +++ b/docs/models/operations/createapplicationaccesstokenresponse.md @@ -9,7 +9,7 @@ import { CreateApplicationAccessTokenResponse } from "dwolla/models/operations"; let value: CreateApplicationAccessTokenResponse = { accessToken: "gTm0p62yYXFiB1rOdhV0TsNOinC2V2P1CMaAtojkO9JEGbv3i5", - tokenType: "bearer", + tokenType: "Bearer", expiresIn: 3599, }; ``` @@ -19,5 +19,5 @@ let value: CreateApplicationAccessTokenResponse = { | Field | Type | Required | Description | Example | | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------ | | `accessToken` | *string* | :heavy_check_mark: | A new access token that is used to authenticate against resources that belong to the app itself. | gTm0p62yYXFiB1rOdhV0TsNOinC2V2P1CMaAtojkO9JEGbv3i5 | -| `tokenType` | [operations.TokenType](../../models/operations/tokentype.md) | :heavy_check_mark: | The type of token, always "bearer" | bearer | +| `tokenType` | *string* | :heavy_check_mark: | The type of token, always "Bearer" | Bearer | | `expiresIn` | *number* | :heavy_check_mark: | The lifetime of the access token, in seconds. Default is 3600. | 3599 | \ No newline at end of file diff --git a/docs/models/operations/createapplicationaccesstokensecurity.md b/docs/models/operations/createapplicationaccesstokensecurity.md new file mode 100644 index 0000000..204cfcf --- /dev/null +++ b/docs/models/operations/createapplicationaccesstokensecurity.md @@ -0,0 +1,17 @@ +# CreateApplicationAccessTokenSecurity + +## Example Usage + +```typescript +import { CreateApplicationAccessTokenSecurity } from "dwolla/models/operations"; + +let value: CreateApplicationAccessTokenSecurity = { + basicAuth: "", +}; +``` + +## Fields + +| Field | Type | Required | Description | +| ------------------ | ------------------ | ------------------ | ------------------ | +| `basicAuth` | *string* | :heavy_check_mark: | N/A | \ No newline at end of file diff --git a/docs/models/operations/createcustomerrequest.md b/docs/models/operations/createcustomerrequest.md index 04c2152..dcb81a6 100644 --- a/docs/models/operations/createcustomerrequest.md +++ b/docs/models/operations/createcustomerrequest.md @@ -12,6 +12,7 @@ const value: models.CreateReceiveOnlyUser = { firstName: "Account", lastName: "Admin", email: "accountAdmin@email.com", + type: "receive-only", ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", @@ -26,6 +27,7 @@ const value: models.CreateUnverifiedCustomer = { firstName: "Account", lastName: "Admin", email: "accountAdmin@email.com", + type: "unverified", ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", @@ -43,6 +45,7 @@ const value: models.CreateVerifiedPersonalCustomer = { ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", + type: "personal", address1: "99-99 33rd St", address2: "99-99 33rd St", city: "Some City", @@ -63,6 +66,7 @@ const value: models.CreateVerifiedSolePropCustomer = { ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", + type: "business", address1: "99-99 33rd St", address2: "99-99 33rd St", city: "Some City", @@ -75,6 +79,7 @@ const value: models.CreateVerifiedSolePropCustomer = { doingBusinessAs: "Jane's Electronics", ein: "00-0000000", website: "https://www.domain.com", + businessType: "soleProprietorship", }; ``` @@ -88,6 +93,7 @@ const value: models.CreateVerifiedBusinessCustomerWithController = { ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", + type: "business", address1: "99-99 33rd St", address2: "99-99 33rd St", city: "Some City", @@ -129,6 +135,7 @@ const value: models.CreateVerifiedBusinessCustomerWithInternationalController = ipAddress: "143.156.7.8", phone: "5555555555", correlationId: "fc451a7a-ae30-4404-aB95-e3553fcd733", + type: "business", address1: "99-99 33rd St", address2: "99-99 33rd St", city: "Some City", diff --git a/docs/models/operations/listtransferfeesresponse.md b/docs/models/operations/listtransferfeesresponse.md index 16b5de9..5940968 100644 --- a/docs/models/operations/listtransferfeesresponse.md +++ b/docs/models/operations/listtransferfeesresponse.md @@ -26,7 +26,7 @@ let value: ListTransferFeesResponse = { created: new Date("2016-02-22T20:46:38.777Z"), }, ], - total: "1", + total: 1, }; ``` @@ -35,4 +35,4 @@ let value: ListTransferFeesResponse = { | Field | Type | Required | Description | Example | | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------ | | `transactions` | [operations.Transaction](../../models/operations/transaction.md)[] | :heavy_minus_sign: | N/A | | -| `total` | *string* | :heavy_minus_sign: | N/A | 1 | \ No newline at end of file +| `total` | *number* | :heavy_minus_sign: | N/A | 1 | \ No newline at end of file diff --git a/docs/models/operations/tokentype.md b/docs/models/operations/tokentype.md deleted file mode 100644 index a73d5ef..0000000 --- a/docs/models/operations/tokentype.md +++ /dev/null @@ -1,17 +0,0 @@ -# TokenType - -The type of token, always "bearer" - -## Example Usage - -```typescript -import { TokenType } from "dwolla/models/operations"; - -let value: TokenType = "bearer"; -``` - -## Values - -```typescript -"bearer" -``` \ No newline at end of file diff --git a/docs/sdks/tokens/README.md b/docs/sdks/tokens/README.md index c545608..ff5654d 100644 --- a/docs/sdks/tokens/README.md +++ b/docs/sdks/tokens/README.md @@ -19,15 +19,12 @@ Generate an application access token using OAuth 2.0 client credentials flow for ```typescript import { Dwolla } from "dwolla"; -const dwolla = new Dwolla({ - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, -}); +const dwolla = new Dwolla(); async function run() { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); @@ -47,15 +44,12 @@ import { tokensCreate } from "dwolla/funcs/tokensCreate.js"; // Use `DwollaCore` for best tree-shaking performance. // You can create one instance of it to use across an application. -const dwolla = new DwollaCore({ - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, -}); +const dwolla = new DwollaCore(); async function run() { const res = await tokensCreate(dwolla, { + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); if (res.ok) { @@ -74,6 +68,7 @@ run(); | Parameter | Type | Required | Description | | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | `request` | [operations.CreateApplicationAccessTokenRequest](../../models/operations/createapplicationaccesstokenrequest.md) | :heavy_check_mark: | The request object to use for the request. | +| `security` | [operations.CreateApplicationAccessTokenSecurity](../../models/operations/createapplicationaccesstokensecurity.md) | :heavy_check_mark: | The security requirements to use for the request. | | `options` | RequestOptions | :heavy_minus_sign: | Used to set various options for making HTTP requests. | | `options.fetchOptions` | [RequestInit](https://developer.mozilla.org/en-US/docs/Web/API/Request/Request#options) | :heavy_minus_sign: | Options that are passed to the underlying HTTP request. This can be used to inject extra headers for examples. All `Request` options, except `method` and `body`, are allowed. | | `options.retries` | [RetryConfig](../../lib/utils/retryconfig.md) | :heavy_minus_sign: | Enables retrying HTTP requests under certain failure conditions. | diff --git a/docs/sdks/transfers/README.md b/docs/sdks/transfers/README.md index e746156..d00f145 100644 --- a/docs/sdks/transfers/README.md +++ b/docs/sdks/transfers/README.md @@ -300,7 +300,9 @@ const dwolla = new Dwolla({ async function run() { const result = await dwolla.transfers.cancel({ id: "", - requestBody: {}, + requestBody: { + status: "cancelled", + }, }); console.log(result); @@ -329,7 +331,9 @@ const dwolla = new DwollaCore({ async function run() { const res = await transfersCancel(dwolla, { id: "", - requestBody: {}, + requestBody: { + status: "cancelled", + }, }); if (res.ok) { const { value: result } = res; diff --git a/examples/package-lock.json b/examples/package-lock.json index e7bd7be..5cad5de 100644 --- a/examples/package-lock.json +++ b/examples/package-lock.json @@ -18,17 +18,19 @@ }, "..": { "name": "dwolla", - "version": "0.0.1-beta.13", + "version": "0.0.1-beta.14", "dependencies": { "zod": "^3.25.0 || ^4.0.0" }, "devDependencies": { "@eslint/js": "^9.19.0", + "@types/node": "^18.19.3", "eslint": "^9.19.0", "globals": "^15.14.0", "tshy": "^2.0.0", "typescript": "~5.8.3", - "typescript-eslint": "^8.26.0" + "typescript-eslint": "^8.26.0", + "vitest": "^3.0.2" } }, "node_modules/@esbuild/aix-ppc64": { diff --git a/examples/tokensCreate.example.ts b/examples/tokensCreate.example.ts index b6cdafc..cfefbaf 100644 --- a/examples/tokensCreate.example.ts +++ b/examples/tokensCreate.example.ts @@ -13,15 +13,12 @@ dotenv.config(); import { Dwolla } from "dwolla"; -const dwolla = new Dwolla({ - security: { - clientID: process.env["DWOLLA_CLIENT_ID"] ?? "", - clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "", - }, -}); +const dwolla = new Dwolla(); async function main() { const result = await dwolla.tokens.create({ + basicAuth: process.env["DWOLLA_BASIC_AUTH"] ?? "", + }, { grantType: "client_credentials", }); diff --git a/generated/openapi.yaml b/generated/openapi.yaml index 6d3e832..db433a6 100644 --- a/generated/openapi.yaml +++ b/generated/openapi.yaml @@ -68,6 +68,8 @@ paths: operationId: createApplicationAccessToken x-speakeasy-group: tokens x-speakeasy-name-override: create + security: + - basicAuth: [] x-codeSamples: - lang: bash source: | @@ -144,10 +146,8 @@ paths: example: gTm0p62yYXFiB1rOdhV0TsNOinC2V2P1CMaAtojkO9JEGbv3i5 token_type: type: string - enum: - - bearer - description: The type of token, always "bearer" - example: bearer + description: The type of token, always "Bearer" + example: Bearer expires_in: type: integer description: The lifetime of the access token, in seconds. Default is 3600. @@ -4713,8 +4713,9 @@ paths: format: date-time example: '2016-02-22T20:46:38.777Z' total: - type: string - example: '1' + type: integer + format: int32 + example: 1 '404': description: 404 Not Found headers: {} @@ -9427,7 +9428,7 @@ paths: '200': description: Client token created successfully content: - application/json: + application/vnd.dwolla.v1.hal+json: schema: type: object required: @@ -9899,6 +9900,7 @@ components: - ach - real-time-payments - wire + - external example: ach bankName: type: string @@ -10529,6 +10531,9 @@ components: - $ref: '#/components/schemas/VerifiedPersonalCustomer' - $ref: '#/components/schemas/VerifiedSolePropCustomer' - $ref: '#/components/schemas/VerifiedBusinessCustomer' + total: + type: integer + example: 2 ForbiddenError: title: ForbiddenError description: Error response schema for 403 Forbidden diff --git a/jsr.json b/jsr.json index 4fd3cfc..d17cef4 100644 --- a/jsr.json +++ b/jsr.json @@ -2,7 +2,7 @@ { "name": "dwolla", - "version": "0.0.1-beta.13", + "version": "0.0.1-beta.14", "exports": { ".": "./src/index.ts", "./models/errors": "./src/models/errors/index.ts", diff --git a/package-lock.json b/package-lock.json index 3a97e73..1e533d4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,22 +1,440 @@ { "name": "dwolla", - "version": "0.0.1-beta.13", + "version": "0.0.1-beta.14", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dwolla", - "version": "0.0.1-beta.13", + "version": "0.0.1-beta.14", "dependencies": { "zod": "^3.25.0 || ^4.0.0" }, "devDependencies": { "@eslint/js": "^9.19.0", + "@types/node": "^18.19.3", "eslint": "^9.19.0", "globals": "^15.14.0", "tshy": "^2.0.0", "typescript": "~5.8.3", - "typescript-eslint": "^8.26.0" + "typescript-eslint": "^8.26.0", + "vitest": "^3.0.2" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, "node_modules/@eslint-community/eslint-utils": { @@ -189,106 +607,414 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", "dev": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "engines": { + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.53.3.tgz", + "integrity": "sha512-mRSi+4cBjrRLoaal2PnqH82Wqyb+d3HsPUN/W+WslCXsZsyHa9ZeQQX/pQsZaVIWDkPcpV6jJ+3KLbTbgnwv8w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.53.3.tgz", + "integrity": "sha512-CbDGaMpdE9sh7sCmTrTUyllhrg65t6SwhjlMJsLr+J8YjFuPmCEjbBSx4Z/e4SmDyH3aB5hGaJUP2ltV/vcs4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.53.3.tgz", + "integrity": "sha512-Nr7SlQeqIBpOV6BHHGZgYBuSdanCXuw09hon14MGOLGmXAFYjx1wNvquVPmpZnl0tLjg25dEdr4IQ6GgyToCUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.53.3.tgz", + "integrity": "sha512-DZ8N4CSNfl965CmPktJ8oBnfYr3F8dTTNBQkRlffnUarJ2ohudQD17sZBa097J8xhQ26AwhHJ5mvUyQW8ddTsQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.53.3.tgz", + "integrity": "sha512-yMTrCrK92aGyi7GuDNtGn2sNW+Gdb4vErx4t3Gv/Tr+1zRb8ax4z8GWVRfr3Jw8zJWvpGHNpss3vVlbF58DZ4w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.53.3.tgz", + "integrity": "sha512-lMfF8X7QhdQzseM6XaX0vbno2m3hlyZFhwcndRMw8fbAGUGL3WFMBdK0hbUBIUYcEcMhVLr1SIamDeuLBnXS+Q==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.53.3.tgz", + "integrity": "sha512-k9oD15soC/Ln6d2Wv/JOFPzZXIAIFLp6B+i14KhxAfnq76ajt0EhYc5YPeX6W1xJkAdItcVT+JhKl1QZh44/qw==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.53.3.tgz", + "integrity": "sha512-vTNlKq+N6CK/8UktsrFuc+/7NlEYVxgaEgRXVUVK258Z5ymho29skzW1sutgYjqNnquGwVUObAaxae8rZ6YMhg==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.53.3.tgz", + "integrity": "sha512-RGrFLWgMhSxRs/EWJMIFM1O5Mzuz3Xy3/mnxJp/5cVhZ2XoCAxJnmNsEyeMJtpK+wu0FJFWz+QF4mjCA7AUQ3w==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.53.3.tgz", + "integrity": "sha512-kASyvfBEWYPEwe0Qv4nfu6pNkITLTb32p4yTgzFCocHnJLAHs+9LjUu9ONIhvfT/5lv4YS5muBHyuV84epBo/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.53.3.tgz", + "integrity": "sha512-JiuKcp2teLJwQ7vkJ95EwESWkNRFJD7TQgYmCnrPtlu50b4XvT5MOmurWNrCj3IFdyjBQ5p9vnrX4JM6I8OE7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.53.3.tgz", + "integrity": "sha512-EoGSa8nd6d3T7zLuqdojxC20oBfNT8nexBbB/rkxgKj5T5vhpAQKKnD+h3UkoMuTyXkP5jTjK/ccNRmQrPNDuw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.53.3.tgz", + "integrity": "sha512-4s+Wped2IHXHPnAEbIB0YWBv7SDohqxobiiPA1FIWZpX+w9o2i4LezzH/NkFUl8LRci/8udci6cLq+jJQlh+0g==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.53.3.tgz", + "integrity": "sha512-68k2g7+0vs2u9CxDt5ktXTngsxOQkSEV/xBbwlqYcUrAVh6P9EgMZvFsnHy4SEiUl46Xf0IObWVbMvPrr2gw8A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.53.3.tgz", + "integrity": "sha512-VYsFMpULAz87ZW6BVYw3I6sWesGpsP9OPcyKe8ofdg9LHxSbRMd7zrVrr5xi/3kMZtpWL/wC+UIJWJYVX5uTKg==", + "cpu": [ + "s390x" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.53.3.tgz", + "integrity": "sha512-3EhFi1FU6YL8HTUJZ51imGJWEX//ajQPfqWLI3BQq4TlvHy4X0MOr5q3D2Zof/ka0d5FNdPwZXm3Yyib/UEd+w==", + "cpu": [ + "x64" + ], "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.53.3.tgz", + "integrity": "sha512-eoROhjcc6HbZCJr+tvVT8X4fW3/5g/WkGvvmwz/88sDtSJzO7r/blvoBDgISDiCjDRZmHpwud7h+6Q9JxFwq1Q==", + "cpu": [ + "x64" + ], "dev": true, - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } + "optional": true, + "os": [ + "linux" + ] }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.53.3.tgz", + "integrity": "sha512-OueLAWgrNSPGAdUdIjSWXw+u/02BRTcnfw9PN41D2vq/JSEPnJnVuBgw18VkN8wcd4fjUs+jFHVM4t9+kBSNLw==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } + "optional": true, + "os": [ + "openharmony" + ] }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.53.3.tgz", + "integrity": "sha512-GOFuKpsxR/whszbF/bzydebLiXIHSgsEUp6M0JI8dWvi+fFa1TD6YQa4aSZHtpmh2/uAlj/Dy+nmby3TJ3pkTw==", + "cpu": [ + "arm64" + ], "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.53.3.tgz", + "integrity": "sha512-iah+THLcBJdpfZ1TstDFbKNznlzoxa8fmnFYK4V67HvmuNYkVdAywJSoteUszvBQ9/HqN2+9AZghbajMsFT+oA==", + "cpu": [ + "ia32" + ], "dev": true, - "engines": { - "node": ">= 8" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "cpu": [ + "x64" + ], "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } + "optional": true, + "os": [ + "win32" + ] }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "cpu": [ + "x64" + ], "dev": true, "optional": true, - "engines": { - "node": ">=14" + "os": [ + "win32" + ] + }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true + }, "node_modules/@types/estree": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", - "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", "dev": true }, "node_modules/@types/json-schema": { @@ -297,6 +1023,15 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/node": { + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.32.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.32.1.tgz", @@ -502,6 +1237,88 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@vitest/expect": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz", + "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==", + "dev": true, + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/spy": "3.2.4", + "@vitest/utils": "3.2.4", + "chai": "^5.2.0", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz", + "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==", + "dev": true, + "dependencies": { + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz", + "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==", + "dev": true, + "dependencies": { + "@vitest/utils": "3.2.4", + "pathe": "^2.0.3", + "strip-literal": "^3.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz", + "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==", + "dev": true, + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "magic-string": "^0.30.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz", + "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==", + "dev": true, + "dependencies": { + "tinyspy": "^4.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz", + "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==", + "dev": true, + "dependencies": { + "@vitest/pretty-format": "3.2.4", + "loupe": "^3.1.4", + "tinyrainbow": "^2.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, "node_modules/acorn": { "version": "8.14.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", @@ -585,6 +1402,15 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -625,6 +1451,15 @@ "node": ">=8" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -634,6 +1469,22 @@ "node": ">=6" } }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -650,6 +1501,15 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/check-error": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", + "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "dev": true, + "engines": { + "node": ">= 16" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -741,6 +1601,15 @@ } } }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -759,6 +1628,53 @@ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", "dev": true }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true + }, + "node_modules/esbuild": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", + "integrity": "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==", + "dev": true, + "hasInstallScript": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.12", + "@esbuild/android-arm": "0.25.12", + "@esbuild/android-arm64": "0.25.12", + "@esbuild/android-x64": "0.25.12", + "@esbuild/darwin-arm64": "0.25.12", + "@esbuild/darwin-x64": "0.25.12", + "@esbuild/freebsd-arm64": "0.25.12", + "@esbuild/freebsd-x64": "0.25.12", + "@esbuild/linux-arm": "0.25.12", + "@esbuild/linux-arm64": "0.25.12", + "@esbuild/linux-ia32": "0.25.12", + "@esbuild/linux-loong64": "0.25.12", + "@esbuild/linux-mips64el": "0.25.12", + "@esbuild/linux-ppc64": "0.25.12", + "@esbuild/linux-riscv64": "0.25.12", + "@esbuild/linux-s390x": "0.25.12", + "@esbuild/linux-x64": "0.25.12", + "@esbuild/netbsd-arm64": "0.25.12", + "@esbuild/netbsd-x64": "0.25.12", + "@esbuild/openbsd-arm64": "0.25.12", + "@esbuild/openbsd-x64": "0.25.12", + "@esbuild/openharmony-arm64": "0.25.12", + "@esbuild/sunos-x64": "0.25.12", + "@esbuild/win32-arm64": "0.25.12", + "@esbuild/win32-ia32": "0.25.12", + "@esbuild/win32-x64": "0.25.12" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -909,6 +1825,15 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -918,6 +1843,15 @@ "node": ">=0.10.0" } }, + "node_modules/expect-type": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", + "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "dev": true, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -1251,6 +2185,12 @@ "@pkgjs/parseargs": "^0.11.0" } }, + "node_modules/js-tokens": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", + "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==", + "dev": true + }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", @@ -1324,12 +2264,27 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true + }, "node_modules/lru-cache": { "version": "10.4.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true }, + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -1394,6 +2349,24 @@ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -1508,6 +2481,27 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "engines": { + "node": ">= 14.16" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -1532,6 +2526,34 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -1628,8 +2650,49 @@ "bin": { "rimraf": "dist/esm/bin.mjs" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", + "integrity": "sha512-w8GmOxZfBmKknvdXU1sdM9NHcoQejwF/4mNgj2JuEEdRaHwwF12K7e9eXn1nLZ07ad+du76mkVsyeb2rKGllsA==", + "dev": true, + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.53.3", + "@rollup/rollup-android-arm64": "4.53.3", + "@rollup/rollup-darwin-arm64": "4.53.3", + "@rollup/rollup-darwin-x64": "4.53.3", + "@rollup/rollup-freebsd-arm64": "4.53.3", + "@rollup/rollup-freebsd-x64": "4.53.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.53.3", + "@rollup/rollup-linux-arm-musleabihf": "4.53.3", + "@rollup/rollup-linux-arm64-gnu": "4.53.3", + "@rollup/rollup-linux-arm64-musl": "4.53.3", + "@rollup/rollup-linux-loong64-gnu": "4.53.3", + "@rollup/rollup-linux-ppc64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-gnu": "4.53.3", + "@rollup/rollup-linux-riscv64-musl": "4.53.3", + "@rollup/rollup-linux-s390x-gnu": "4.53.3", + "@rollup/rollup-linux-x64-gnu": "4.53.3", + "@rollup/rollup-linux-x64-musl": "4.53.3", + "@rollup/rollup-openharmony-arm64": "4.53.3", + "@rollup/rollup-win32-arm64-msvc": "4.53.3", + "@rollup/rollup-win32-ia32-msvc": "4.53.3", + "@rollup/rollup-win32-x64-gnu": "4.53.3", + "@rollup/rollup-win32-x64-msvc": "4.53.3", + "fsevents": "~2.3.2" } }, "node_modules/run-parallel": { @@ -1688,6 +2751,12 @@ "node": ">=8" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -1700,6 +2769,27 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true + }, + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -1808,6 +2898,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-literal": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", + "dev": true, + "dependencies": { + "js-tokens": "^9.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -1841,6 +2943,90 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true + }, + "node_modules/tinyexec": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true + }, + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", + "dev": true, + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz", + "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -1973,6 +3159,12 @@ "typescript": ">=4.8.4 <5.9.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -1982,6 +3174,351 @@ "punycode": "^2.1.0" } }, + "node_modules/vite-node": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz", + "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==", + "dev": true, + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.4.1", + "es-module-lexer": "^1.7.0", + "pathe": "^2.0.3", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vite-node/node_modules/@types/node": { + "version": "24.10.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.1.tgz", + "integrity": "sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==", + "dev": true, + "optional": true, + "peer": true, + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "node_modules/vite-node/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite-node/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vite-node/node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "optional": true, + "peer": true + }, + "node_modules/vite-node/node_modules/vite": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz", + "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==", + "dev": true, + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "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 + } + } + }, + "node_modules/vitest": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz", + "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==", + "dev": true, + "dependencies": { + "@types/chai": "^5.2.2", + "@vitest/expect": "3.2.4", + "@vitest/mocker": "3.2.4", + "@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.2.0", + "debug": "^4.4.1", + "expect-type": "^1.2.1", + "magic-string": "^0.30.17", + "pathe": "^2.0.3", + "picomatch": "^4.0.2", + "std-env": "^3.9.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.14", + "tinypool": "^1.1.1", + "tinyrainbow": "^2.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", + "vite-node": "3.2.4", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "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 + } + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz", + "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==", + "dev": true, + "dependencies": { + "@vitest/spy": "3.2.4", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.17" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz", + "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==", + "dev": true, + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "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 + } + } + }, "node_modules/walk-up-path": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", @@ -2003,6 +3540,22 @@ "node": ">= 8" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", diff --git a/package.json b/package.json index 5147caf..682ca9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dwolla", - "version": "0.0.1-beta.13", + "version": "0.0.1-beta.14", "author": "Speakeasy", "description": "Dwolla TypeScript SDK (Beta). Breaking changes may occur between beta versions.", "type": "module", @@ -25,6 +25,8 @@ "url": "https://github.com/Dwolla/dwolla-typescript.git" }, "scripts": { + "test": "vitest run src --reporter=junit --outputFile=.speakeasy/reports/tests.xml --reporter=default", + "check": "npm run test && npm run lint", "lint": "eslint --cache --max-warnings=0 src", "build": "tshy", "prepublishOnly": "npm run build" @@ -32,11 +34,13 @@ "peerDependencies": {}, "devDependencies": { "@eslint/js": "^9.19.0", + "@types/node": "^18.19.3", "eslint": "^9.19.0", "globals": "^15.14.0", "tshy": "^2.0.0", "typescript": "~5.8.3", - "typescript-eslint": "^8.26.0" + "typescript-eslint": "^8.26.0", + "vitest": "^3.0.2" }, "dependencies": { "zod": "^3.25.0 || ^4.0.0" diff --git a/src/__tests__/accounts.test.ts b/src/__tests__/accounts.test.ts new file mode 100644 index 0000000..f26cb9a --- /dev/null +++ b/src/__tests__/accounts.test.ts @@ -0,0 +1,31 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Accounts Get Account", async () => { + const testHttpClient = createTestHTTPClient("getAccount"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.accounts.get({ + id: "5e7cd80f-3a4a-451e-9cd6-a86fc571741f", + }); + expect(result).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.name).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(typeof result.timezoneOffset).toBe("number"); + expect(result.type).toBeDefined(); +}); diff --git a/src/__tests__/accountsexchanges.test.ts b/src/__tests__/accountsexchanges.test.ts new file mode 100644 index 0000000..eebf062 --- /dev/null +++ b/src/__tests__/accountsexchanges.test.ts @@ -0,0 +1,66 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Accounts Exchanges List Account Exchanges", async () => { + const testHttpClient = createTestHTTPClient("listAccountExchanges"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.accounts.exchanges.list(); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.exchanges ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + if ((result.embedded?.exchanges?.length ?? 0) > 0) { + const firstExchange = result.embedded!.exchanges![0]!; + expect(firstExchange.id).toBeDefined(); + expect(firstExchange.status).toBeDefined(); + expect(firstExchange.created).toBeInstanceOf(Date); + expect(firstExchange.links).toBeDefined(); + } +}); + +test.skip("Accounts Exchanges Create Account Exchange", async () => { + // Skipped: This test requires a valid Plaid processor token which expires quickly. + // The endpoint returns 201 with Location header and no body on success. + const testHttpClient = createTestHTTPClient("createAccountExchange"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.accounts.exchanges.create({ + links: { + exchangePartner: { + href: + "https://api-sandbox.dwolla.com/exchange-partners/3aef60d1-878f-4692-8c06-c6b478efb60d", + }, + }, + token: "processor-sandbox-add4b58b-902c-4810-b6cd-d58dda4e0fe3", + }); + + // Create exchange returns 201 with Location header, extract the exchange ID + const locationHeader = + result?.headers["Location"]?.[0] ?? result?.headers["location"]?.[0]; + expect(locationHeader).toBeDefined(); +}); diff --git a/src/__tests__/accountsfundingsources.test.ts b/src/__tests__/accountsfundingsources.test.ts new file mode 100644 index 0000000..1133f72 --- /dev/null +++ b/src/__tests__/accountsfundingsources.test.ts @@ -0,0 +1,39 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Accounts Fundingsources List Funding Sources", async () => { + const testHttpClient = createTestHTTPClient("listFundingSources"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.accounts.fundingSources.list({ + id: "5e7cd80f-3a4a-451e-9cd6-a86fc571741f", + }); + expect(result).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.fundingSources ?? [])).toBe(true); + + if ((result.embedded?.fundingSources?.length ?? 0) > 0) { + const firstFs = result.embedded!.fundingSources![0]!; + expect(firstFs.id).toBeDefined(); + expect(firstFs.status).toBeDefined(); + expect(firstFs.type).toBeDefined(); + expect(firstFs.name).toBeDefined(); + expect(firstFs.links).toBeDefined(); + expect(firstFs.created).toBeInstanceOf(Date); + } +}); diff --git a/src/__tests__/accountsmasspayments.test.ts b/src/__tests__/accountsmasspayments.test.ts new file mode 100644 index 0000000..2749110 --- /dev/null +++ b/src/__tests__/accountsmasspayments.test.ts @@ -0,0 +1,41 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Accounts Masspayments List Mass Payments", async () => { + const testHttpClient = createTestHTTPClient("listMassPayments"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.accounts.massPayments.list({ + id: "5e7cd80f-3a4a-451e-9cd6-a86fc571741f", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.massPayments ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + if ((result.embedded?.massPayments?.length ?? 0) > 0) { + const firstMp = result.embedded!.massPayments![0]!; + expect(firstMp.id).toBeDefined(); + expect(firstMp.status).toBeDefined(); + expect(firstMp.created).toBeInstanceOf(Date); + expect(firstMp.total).toBeDefined(); + expect(firstMp.total?.value).toBeDefined(); + expect(firstMp.total?.currency).toBeDefined(); + expect(firstMp.links).toBeDefined(); + } +}); diff --git a/src/__tests__/accountstransfers.test.ts b/src/__tests__/accountstransfers.test.ts new file mode 100644 index 0000000..40c614e --- /dev/null +++ b/src/__tests__/accountstransfers.test.ts @@ -0,0 +1,38 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Accounts Transfers List And Search Transfers", async () => { + const testHttpClient = createTestHTTPClient("listAndSearchTransfers"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.accounts.transfers.list({ + id: "5e7cd80f-3a4a-451e-9cd6-a86fc571741f", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.transfers ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + if ((result.embedded?.transfers?.length ?? 0) > 0) { + const firstTransfer = result.embedded!.transfers![0]!; + expect(firstTransfer.id).toBeDefined(); + expect(firstTransfer.status).toBeDefined(); + expect(firstTransfer.created).toBeInstanceOf(Date); + expect(firstTransfer.links).toBeDefined(); + } +}); diff --git a/src/__tests__/assertions.ts b/src/__tests__/assertions.ts new file mode 100644 index 0000000..c05351d --- /dev/null +++ b/src/__tests__/assertions.ts @@ -0,0 +1,13 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { fail } from "assert"; + +export function assertDefined(value: any): any { + if (value === undefined) { + fail("value is undefined"); + } + + return value; +} diff --git a/src/__tests__/balance.test.ts b/src/__tests__/balance.test.ts new file mode 100644 index 0000000..266d1cc --- /dev/null +++ b/src/__tests__/balance.test.ts @@ -0,0 +1,33 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Balance Get Funding Source Balance", async () => { + const testHttpClient = createTestHTTPClient("getFundingSourceBalance"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.fundingSources.balance.get({ + id: "0c09a8ba-43ab-475b-9287-8aef14a7735c", + }); + expect(result).toBeDefined(); + expect(result.links).toBeDefined(); + // expect(result.balance).toBeDefined(); + // expect(result.balance?.value).toBeDefined(); + // expect(result.balance?.currency).toBeDefined(); + // expect(result.total).toBeDefined(); + // expect(result.total?.value).toBeDefined(); + // expect(result.total?.currency).toBeDefined(); + expect(result.lastUpdated).toBeDefined(); +}); diff --git a/src/__tests__/beneficialowners.test.ts b/src/__tests__/beneficialowners.test.ts new file mode 100644 index 0000000..3248c48 --- /dev/null +++ b/src/__tests__/beneficialowners.test.ts @@ -0,0 +1,131 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { beforeAll, expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +let beneficialOwnerId: string | undefined; + +beforeAll(async () => { + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: createTestHTTPClient("beneficialOwners"), + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const createBeneficialOwnerResult = await dwolla.customers.beneficialOwners.create({ + id: "274322f3-3004-41ea-8448-2193b25dd745", + requestBody: { + firstName: "incomplete", + lastName: "Doe", + dateOfBirth: "1970-01-01", + address: { + address1: "123 Main St", + city: "Des Moines", + stateProvinceRegion: "IA", + country: "US", + postalCode: "50309", + }, + ssn: "123456789", + }, + }); + + const locationHeader = + createBeneficialOwnerResult?.headers["Location"]?.[0] ?? createBeneficialOwnerResult?.headers["location"]?.[0]; + expect(locationHeader).toBeDefined(); + beneficialOwnerId = new URL(locationHeader as string).pathname.split("/").pop(); +}); + +test("Beneficialowners Retrieve Beneficial Owner", async () => { + const testHttpClient = createTestHTTPClient("retrieveBeneficialOwner"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.beneficialOwners.get({ + id: beneficialOwnerId!, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.id).toBeDefined(); + expect(result.firstName).toBeDefined(); + expect(result.lastName).toBeDefined(); + expect(result.verificationStatus).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.address).toBeDefined(); + expect(result.address?.address1).toBeDefined(); + expect(result.address?.city).toBeDefined(); + expect(result.address?.country).toBeDefined(); +}); + +test("Beneficialowners Update Beneficial Owner", async () => { + const testHttpClient = createTestHTTPClient("updateBeneficialOwner"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.beneficialOwners.update({ + id: beneficialOwnerId!, + requestBody: { + firstName: "Lauryn", + lastName: "D'Amore", + dateOfBirth: "2005-10-23", + address: { + address1: "462 Main Street", + address2: "Suite 123", + address3: "Unit 123", + city: "Des Moines", + postalCode: "50309", + country: "US", + stateProvinceRegion: "IA", + }, + ssn: "123-45-6789", + }, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.id).toBeDefined(); + expect(result.firstName).toBeDefined(); + expect(result.lastName).toBeDefined(); + expect(result.verificationStatus).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.address).toBeDefined(); +}); + +test("Beneficialowners Delete Beneficial Owner", async () => { + const testHttpClient = createTestHTTPClient("deleteBeneficialOwner"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.beneficialOwners.delete({ + id: beneficialOwnerId!, + }); + expect(result).toBeDefined(); + // Delete returns an empty object on success +}); diff --git a/src/__tests__/beneficialownersdocuments.test.ts b/src/__tests__/beneficialownersdocuments.test.ts new file mode 100644 index 0000000..e9e8ff1 --- /dev/null +++ b/src/__tests__/beneficialownersdocuments.test.ts @@ -0,0 +1,52 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Beneficialowners Documents List Beneficial Owner Documents", async () => { + const testHttpClient = createTestHTTPClient("listBeneficialOwnerDocuments"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.beneficialOwners.documents.list({ + id: "ea164188-6585-4284-9dbb-932ee1b7b21a", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.documents ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + // Validate shape of the first document if present + if ((result.embedded?.documents?.length ?? 0) > 0) { + const first = result.embedded!.documents![0]!; + expect(first.id).toBeDefined(); + expect(first.status).toBeDefined(); + expect(first.type).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + expect(first.links?.self).toBeDefined(); + // Optional fields + if (first.documentVerificationStatus) { + expect(typeof first.documentVerificationStatus).toBe("string"); + } + if (first.failureReason) { + expect(typeof first.failureReason).toBe("string"); + } + if (first.allFailureReasons) { + expect(Array.isArray(first.allFailureReasons)).toBe(true); + } + } +}); diff --git a/src/__tests__/beneficialownership.test.ts b/src/__tests__/beneficialownership.test.ts new file mode 100644 index 0000000..fc643f7 --- /dev/null +++ b/src/__tests__/beneficialownership.test.ts @@ -0,0 +1,58 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Beneficialownership Get Beneficial Ownership Status For Customer", async () => { + const testHttpClient = createTestHTTPClient( + "getBeneficialOwnershipStatusForCustomer", + ); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.beneficialOwnership.get({ + id: "274322f3-3004-41ea-8448-2193b25dd745", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.status).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); +}); + +test("Beneficialownership Certify Beneficial Ownership For Customer", async () => { + const testHttpClient = createTestHTTPClient( + "certifyBeneficialOwnershipForCustomer", + ); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.beneficialOwnership.certify({ + id: "274322f3-3004-41ea-8448-2193b25dd745", + requestBody: { + status: "certified", + }, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.status).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); +}); diff --git a/src/__tests__/businessclassifications.test.ts b/src/__tests__/businessclassifications.test.ts new file mode 100644 index 0000000..62cfec0 --- /dev/null +++ b/src/__tests__/businessclassifications.test.ts @@ -0,0 +1,65 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Businessclassifications List Business Classifications", async () => { + const testHttpClient = createTestHTTPClient("listBusinessClassifications"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.businessClassifications.list(); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.businessClassifications ?? [])).toBe( + true, + ); + if ((result.embedded?.businessClassifications?.length ?? 0) > 0) { + const first = result.embedded!.businessClassifications![0]!; + expect(first.id).toBeDefined(); + expect(first.name).toBeDefined(); + } +}); + +test("Businessclassifications Retrieve Business Classification", async () => { + const testHttpClient = createTestHTTPClient("retrieveBusinessClassification"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.businessClassifications.get({ + id: "9ed3f669-7d6f-11e3-b545-5404a6144203", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.industryClassifications ?? [])).toBe( + true, + ); + expect(result.id).toBeDefined(); + expect(result.name).toBeDefined(); + if ((result.embedded?.industryClassifications?.length ?? 0) > 0) { + const first = result.embedded!.industryClassifications![0]!; + expect(first.id).toBeDefined(); + expect(first.name).toBeDefined(); + } +}); diff --git a/src/__tests__/clienttokens.test.ts b/src/__tests__/clienttokens.test.ts new file mode 100644 index 0000000..c7c1aa4 --- /dev/null +++ b/src/__tests__/clienttokens.test.ts @@ -0,0 +1,32 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Clienttokens Create Client Token", async () => { + const testHttpClient = createTestHTTPClient("createClientToken"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.clientTokens.create({ + action: "customer.update", + links: { + customer: { + href: + "https://api-sandbox.dwolla.com/customers/274322f3-3004-41ea-8448-2193b25dd745", + }, + }, + }); + expect(result).toBeDefined(); + expect(result.token).toBeDefined(); +}); diff --git a/src/__tests__/customers.test.ts b/src/__tests__/customers.test.ts new file mode 100644 index 0000000..b4b899b --- /dev/null +++ b/src/__tests__/customers.test.ts @@ -0,0 +1,126 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Customers List And Search Customers", async () => { + const testHttpClient = createTestHTTPClient("listAndSearchCustomers"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.list({}); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.customers ?? [])).toBe(true); + if ((result.embedded?.customers?.length ?? 0) > 0) { + const first = result.embedded!.customers![0]!; + expect(first.id).toBeDefined(); + expect(first.firstName).toBeDefined(); + expect(first.lastName).toBeDefined(); + expect(first.email).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.type).toBeDefined(); + expect(first.status).toBeDefined(); + } +}); + +test("Customers Get Customer", async () => { + const testHttpClient = createTestHTTPClient("getCustomer"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.get({ + id: "b2bedef2-2c66-4c4e-982d-1adcaa732b97", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.firstName).toBeDefined(); + expect(result.lastName).toBeDefined(); + expect(result.email).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.type).toBeDefined(); + expect(result.status).toBeDefined(); +}); + +test("Customers Update", async () => { + const testHttpClient = createTestHTTPClient("update"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.update({ + id: "86d3ca4b-8c3c-4ba9-88fc-3be8243daf9d", + requestBody: { + "operationType": "UpdateVerifiedBusiness", + "address1": "1 Hagrid's Hut", + "city": "Des Moines", + "state": "IA", + "postalCode": "50266", + }, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.firstName).toBeDefined(); + expect(result.lastName).toBeDefined(); + expect(result.email).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.type).toBeDefined(); + expect(result.status).toBeDefined(); +}); + +test("Customers List Available Exchange Connections", async () => { + const testHttpClient = createTestHTTPClient( + "listAvailableExchangeConnections", + ); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.listAvailableConnections({ + id: "43a07339-253d-4fd5-9291-db72a081698b", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links.self).toBeDefined(); + expect(result.links.customers).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect( + Array.isArray(result.embedded?.availableExchangeConnections ?? []), + ).toBe(true); +}); diff --git a/src/__tests__/customersbeneficialowners.test.ts b/src/__tests__/customersbeneficialowners.test.ts new file mode 100644 index 0000000..eaece7a --- /dev/null +++ b/src/__tests__/customersbeneficialowners.test.ts @@ -0,0 +1,48 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Customers Beneficialowners List Beneficial Owners For Customer", async () => { + const testHttpClient = createTestHTTPClient( + "listBeneficialOwnersForCustomer", + ); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.beneficialOwners.list({ + id: "86d3ca4b-8c3c-4ba9-88fc-3be8243daf9d", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.beneficialOwners ?? [])).toBe(true); + + // Validate shape of the first beneficial owner if present + if ((result.embedded?.beneficialOwners?.length ?? 0) > 0) { + const first = result.embedded!.beneficialOwners![0]!; + expect(first.id).toBeDefined(); + expect(first.firstName).toBeDefined(); + expect(first.lastName).toBeDefined(); + expect(first.verificationStatus).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + expect(first.links?.["self"]).toBeDefined(); + expect(first.address).toBeDefined(); + expect(first.address?.address1).toBeDefined(); + expect(first.address?.city).toBeDefined(); + expect(first.address?.country).toBeDefined(); + } +}); diff --git a/src/__tests__/customersdocuments.test.ts b/src/__tests__/customersdocuments.test.ts new file mode 100644 index 0000000..2cf9802 --- /dev/null +++ b/src/__tests__/customersdocuments.test.ts @@ -0,0 +1,52 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Customers Documents List Customer Documents", async () => { + const testHttpClient = createTestHTTPClient("listCustomerDocuments"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.documents.list({ + id: "86d3ca4b-8c3c-4ba9-88fc-3be8243daf9d", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.documents ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + // Validate shape of the first document if present + if ((result.embedded?.documents?.length ?? 0) > 0) { + const first = result.embedded!.documents![0]!; + expect(first.id).toBeDefined(); + expect(first.status).toBeDefined(); + expect(first.type).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + expect(first.links?.self).toBeDefined(); + // Optional fields + if (first.documentVerificationStatus) { + expect(typeof first.documentVerificationStatus).toBe("string"); + } + if (first.failureReason) { + expect(typeof first.failureReason).toBe("string"); + } + if (first.allFailureReasons) { + expect(Array.isArray(first.allFailureReasons)).toBe(true); + } + } +}); diff --git a/src/__tests__/customersexchanges.test.ts b/src/__tests__/customersexchanges.test.ts new file mode 100644 index 0000000..c6c6153 --- /dev/null +++ b/src/__tests__/customersexchanges.test.ts @@ -0,0 +1,44 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Customers Exchanges List Customer Exchanges", async () => { + const testHttpClient = createTestHTTPClient("listCustomerExchanges"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.exchanges.list({ + id: "a952ff26-af08-457f-a7da-dd09670c9d98", + }); + expect(result).toBeDefined(); + + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.exchanges ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + // Validate shape of the first exchange if present + if ((result.embedded?.exchanges?.length ?? 0) > 0) { + const first = result.embedded!.exchanges![0]!; + expect(first.id).toBeDefined(); + expect(first.status).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + expect(first.links?.["self"]).toBeDefined(); + expect(first.links?.["customer"]).toBeDefined(); + expect(first.links?.["exchange-partner"]).toBeDefined(); + } +}); diff --git a/src/__tests__/customersfundingsources.test.ts b/src/__tests__/customersfundingsources.test.ts new file mode 100644 index 0000000..cd6d905 --- /dev/null +++ b/src/__tests__/customersfundingsources.test.ts @@ -0,0 +1,57 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Customers Fundingsources List Customer Funding Sources", async () => { + const testHttpClient = createTestHTTPClient("listCustomerFundingSources"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.fundingSources.list({ + id: "86d3ca4b-8c3c-4ba9-88fc-3be8243daf9d", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.fundingSources ?? [])).toBe(true); + + // Validate shape of the first funding source if present + if ((result.embedded?.fundingSources?.length ?? 0) > 0) { + const first = result.embedded!.fundingSources![0]!; + expect(first.id).toBeDefined(); + expect(first.status).toBeDefined(); + expect(first.type).toBeDefined(); + expect(first.name).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + expect(first.links?.["self"]).toBeDefined(); + expect(typeof first.removed).toBe("boolean"); + expect(Array.isArray(first.channels ?? [])).toBe(true); + + // Optional fields for bank type + if (first.type === "bank") { + if (first.bankAccountType) { + expect(typeof first.bankAccountType).toBe("string"); + } + if (first.bankName) { + expect(typeof first.bankName).toBe("string"); + } + if (first.fingerprint) { + expect(typeof first.fingerprint).toBe("string"); + } + } + } +}); diff --git a/src/__tests__/customerslabels.test.ts b/src/__tests__/customerslabels.test.ts new file mode 100644 index 0000000..3c46337 --- /dev/null +++ b/src/__tests__/customerslabels.test.ts @@ -0,0 +1,43 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Customers Labels List Customer Labels", async () => { + const testHttpClient = createTestHTTPClient("listCustomerLabels"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.labels.list({ + id: "86d3ca4b-8c3c-4ba9-88fc-3be8243daf9d", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.labels ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + // Validate shape of the first label if present + if ((result.embedded?.labels?.length ?? 0) > 0) { + const first = result.embedded!.labels![0]!; + expect(first.id).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.amount).toBeDefined(); + expect(first.amount?.value).toBeDefined(); + expect(first.amount?.currency).toBeDefined(); + expect(first.links).toBeDefined(); + expect(first.links?.["self"]).toBeDefined(); + } +}); diff --git a/src/__tests__/customersmasspayments.test.ts b/src/__tests__/customersmasspayments.test.ts new file mode 100644 index 0000000..6a63eb2 --- /dev/null +++ b/src/__tests__/customersmasspayments.test.ts @@ -0,0 +1,51 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Customers Masspayments List Customer Mass Payments", async () => { + const testHttpClient = createTestHTTPClient("listCustomerMassPayments"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.massPayments.list({ + id: "86d3ca4b-8c3c-4ba9-88fc-3be8243daf9d", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.massPayments ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + // Validate shape of the first mass payment if present + if ((result.embedded?.massPayments?.length ?? 0) > 0) { + const first = result.embedded!.massPayments![0]!; + expect(first.id).toBeDefined(); + expect(first.status).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + expect(first.total).toBeDefined(); + expect(first.total?.value).toBeDefined(); + expect(first.total?.currency).toBeDefined(); + + // Optional fields + if (first.totalFees) { + expect(first.totalFees.value).toBeDefined(); + expect(first.totalFees.currency).toBeDefined(); + } + if (first.correlationId) { + expect(typeof first.correlationId).toBe("string"); + } + } +}); diff --git a/src/__tests__/customerstransfers.test.ts b/src/__tests__/customerstransfers.test.ts new file mode 100644 index 0000000..2b819ff --- /dev/null +++ b/src/__tests__/customerstransfers.test.ts @@ -0,0 +1,64 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Customers Transfers List Customer Transfers", async () => { + const testHttpClient = createTestHTTPClient("listCustomerTransfers"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.customers.transfers.list({ + id: "86d3ca4b-8c3c-4ba9-88fc-3be8243daf9d", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.transfers ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + // Validate shape of the first transfer if present + if ((result.embedded?.transfers?.length ?? 0) > 0) { + const first = result.embedded!.transfers![0]!; + expect(first.id).toBeDefined(); + expect(first.status).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.amount).toBeDefined(); + expect(first.amount?.value).toBeDefined(); + expect(first.amount?.currency).toBeDefined(); + expect(first.links).toBeDefined(); + expect(first.links?.["self"]).toBeDefined(); + + // Optional fields + if (first.clearing) { + expect(first.clearing.source).toBeDefined(); + } + if (first.correlationId) { + expect(typeof first.correlationId).toBe("string"); + } + if (first.metadata) { + expect(typeof first.metadata).toBe("object"); + } + if (first.achDetails) { + expect(typeof first.achDetails).toBe("object"); + } + if (first.rtpDetails) { + expect(typeof first.rtpDetails).toBe("object"); + } + if (first.processingChannel) { + expect(typeof first.processingChannel).toBe("object"); + } + } +}); diff --git a/src/__tests__/documents.test.ts b/src/__tests__/documents.test.ts new file mode 100644 index 0000000..fdc76c7 --- /dev/null +++ b/src/__tests__/documents.test.ts @@ -0,0 +1,43 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Documents Retrieve Document", async () => { + const testHttpClient = createTestHTTPClient("retrieveDocument"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.documents.get({ + id: "a54a110e-136a-47cb-a9ef-62cfc4398b3b", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.id).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.type).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + + // Optional fields + if (result.documentVerificationStatus) { + expect(typeof result.documentVerificationStatus).toBe("string"); + } + if (result.failureReason) { + expect(typeof result.failureReason).toBe("string"); + } + if (result.allFailureReasons) { + expect(Array.isArray(result.allFailureReasons)).toBe(true); + } +}); diff --git a/src/__tests__/events.test.ts b/src/__tests__/events.test.ts new file mode 100644 index 0000000..e754608 --- /dev/null +++ b/src/__tests__/events.test.ts @@ -0,0 +1,62 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Events List Events", async () => { + const testHttpClient = createTestHTTPClient("listEvents"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.events.list({ + limit: 25, + offset: 0, + }); + + expect(result).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.events ?? [])).toBe(true); + + if ((result.embedded?.events?.length ?? 0) > 0) { + const firstEvent = result.embedded!.events![0]!; + expect(firstEvent.id).toBeDefined(); + expect(firstEvent.topic).toBeDefined(); + expect(firstEvent.created).toBeInstanceOf(Date); + expect(firstEvent.links).toBeDefined(); + } +}); + +test("Events Get Event", async () => { + const testHttpClient = createTestHTTPClient("getEvent"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.events.get({ + id: "18631832-9263-42b6-a4c0-11ac8d2e832b", + }); + + expect(result).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.topic).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); +}); diff --git a/src/__tests__/exchangepartners.test.ts b/src/__tests__/exchangepartners.test.ts new file mode 100644 index 0000000..f9d9df7 --- /dev/null +++ b/src/__tests__/exchangepartners.test.ts @@ -0,0 +1,63 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Exchangepartners List Exchange Partners", async () => { + const testHttpClient = createTestHTTPClient("listExchangePartners"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.exchangePartners.list(); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.['self']).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.exchangePartners ?? [])).toBe(true); + + if ((result.embedded?.exchangePartners?.length ?? 0) > 0) { + const first = result.embedded!.exchangePartners![0]!; + expect(first.id).toBeDefined(); + expect(first.name).toBeDefined(); + expect(first.status).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + expect(first.links?.['self']).toBeDefined(); + } +}); + +test("Exchangepartners Get Exchange Partner", async () => { + const testHttpClient = createTestHTTPClient("getExchangePartner"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.exchangePartners.get({ + id: "3aef60d1-878f-4692-8c06-c6b478efb60d", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.['self']).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.name).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); +}); diff --git a/src/__tests__/exchanges.test.ts b/src/__tests__/exchanges.test.ts new file mode 100644 index 0000000..aa8282c --- /dev/null +++ b/src/__tests__/exchanges.test.ts @@ -0,0 +1,33 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Exchanges Get Exchange", async () => { + const testHttpClient = createTestHTTPClient("getExchange"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.exchanges.get({ + id: "45c5a507-887d-45c3-8abe-fe256ef379b4", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.id).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.links?.["customer"]).toBeDefined(); + expect(result.links?.["exchange-partner"]).toBeDefined(); +}); diff --git a/src/__tests__/exchangesessions.test.ts b/src/__tests__/exchangesessions.test.ts new file mode 100644 index 0000000..cd2b806 --- /dev/null +++ b/src/__tests__/exchangesessions.test.ts @@ -0,0 +1,33 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Exchangesessions Retrieve Customer Exchange Session", async () => { + const testHttpClient = createTestHTTPClient( + "retrieveCustomerExchangeSession", + ); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.exchangeSessions.get({ + id: "29ade3e9-2860-4acc-9bee-76b45ebbccdb", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.links?.exchangePartner).toBeDefined(); + expect(result.externalProviderSessionToken).toBeDefined(); +}); diff --git a/src/__tests__/failure.test.ts b/src/__tests__/failure.test.ts new file mode 100644 index 0000000..bfb80b9 --- /dev/null +++ b/src/__tests__/failure.test.ts @@ -0,0 +1,34 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Failure Get Transfer Failure Reason", async () => { + const testHttpClient = createTestHTTPClient("getTransferFailureReason"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.transfers.failure.get({ + id: "a90dfd45-99cf-f011-acd5-02ab38c54207", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.code).toBeDefined(); + expect(result.description).toBeDefined(); + expect(result.links).toBeDefined(); + + // Optional fields + if (result.explanation) { + expect(typeof result.explanation).toBe("string"); + } +}); diff --git a/src/__tests__/fees.test.ts b/src/__tests__/fees.test.ts new file mode 100644 index 0000000..94e19f2 --- /dev/null +++ b/src/__tests__/fees.test.ts @@ -0,0 +1,40 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Fees List Transfer Fees", async () => { + const testHttpClient = createTestHTTPClient("listTransferFees"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.transfers.fees.list({ + id: "07c37d95-99cf-f011-acd5-02ab38c54207", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(Array.isArray(result.transactions ?? [])).toBe(true); + expect(result.total).toBeDefined(); + + // Validate shape of the first transaction if present + if ((result.transactions?.length ?? 0) > 0) { + const first = result.transactions![0]!; + expect(first.id).toBeDefined(); + expect(first.status).toBeDefined(); + expect(first.amount).toBeDefined(); + expect(first.amount?.value).toBeDefined(); + expect(first.amount?.currency).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + } +}); diff --git a/src/__tests__/files.ts b/src/__tests__/files.ts new file mode 100644 index 0000000..f1df32f --- /dev/null +++ b/src/__tests__/files.ts @@ -0,0 +1,56 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { createReadStream } from "node:fs"; +import { readFile } from "node:fs/promises"; +import { Readable } from "node:stream"; + +export function filesToStream(filePath: string): ReadableStream { + return Readable.toWeb( + createReadStream(filePath), + ) as unknown as ReadableStream; +} + +export async function filesToByteArray(filePath: string): Promise { + return new Uint8Array(await readFile(filePath)); +} + +export async function filesToString(filePath: string): Promise { + return readFile(filePath, "utf8"); +} + +export async function streamToByteArray( + stream?: ReadableStream, +): Promise { + if (!stream) { + return Buffer.from(""); + } + + const chunks = []; + const reader = stream.getReader(); + + let done = false; + while (!done) { + const res = await reader.read(); + done = res.done; + if (res.value) { + chunks.push(res.value); + } + } + + return Buffer.concat(chunks); +} + +export function bytesToStream(bytes: Uint8Array): ReadableStream { + return new ReadableStream({ + start(controller) { + controller.enqueue(bytes); + }, + pull(controller) { + controller.close(); + }, + cancel() { + }, + }); +} diff --git a/src/__tests__/fundingsources.test.ts b/src/__tests__/fundingsources.test.ts new file mode 100644 index 0000000..840d385 --- /dev/null +++ b/src/__tests__/fundingsources.test.ts @@ -0,0 +1,108 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { beforeAll, expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +let fundingSourceId: string | undefined; + +beforeAll(async () => { + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: createTestHTTPClient("fundingSources"), + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + } + }); + + const created = await dwolla.customers.fundingSources.create({ + id: "86d3ca4b-8c3c-4ba9-88fc-3be8243daf9d", + createCustomerFundingSource: { + name: "My virtual account", + type: "virtual", + bankAccountType: "checking", + }, + }); + const locationHeader = + created?.headers["Location"]?.[0] ?? created?.headers["location"]?.[0]; + expect(locationHeader).toBeDefined(); + fundingSourceId = new URL(locationHeader as string).pathname.split("/").pop(); + +}); + +test("Fundingsources Get Funding Source", async () => { + const testHttpClient = createTestHTTPClient("getFundingSource"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.fundingSources.get({ + id: fundingSourceId!, + }); + expect(result).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.type).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + if (result.type === "bank") { + expect(result.bankAccountType).toBeDefined(); + } + expect(result.name).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.removed).toBeDefined(); + expect(result.channels).toBeDefined(); +}); + +test("Fundingsources Get Van Routing", async () => { + const testHttpClient = createTestHTTPClient("getVanRouting"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.fundingSources.getVanRouting({ + id: fundingSourceId!, + }); + expect(result).toBeDefined(); + expect(result.accountNumber).toBeDefined(); + expect(result.routingNumber).toBeDefined(); +}); + +test("Fundingsources Update Or Remove Funding Source", async () => { + const testHttpClient = createTestHTTPClient("updateOrRemoveFundingSource"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.fundingSources.updateOrRemove({ + id: fundingSourceId!, + requestBody: { + removed: true, + }, + }); + expect(result).toBeDefined(); + expect(result).toEqual({}); +}); diff --git a/src/__tests__/items.test.ts b/src/__tests__/items.test.ts new file mode 100644 index 0000000..113cd14 --- /dev/null +++ b/src/__tests__/items.test.ts @@ -0,0 +1,89 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Items List Mass Payment Items", async () => { + const testHttpClient = createTestHTTPClient("listMassPaymentItems"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.massPayments.items.list({ + id: "9061743f-7cd4-48d7-94db-b3a700fab810", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.items ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + // Validate shape of the first item if present + if ((result.embedded?.items?.length ?? 0) > 0) { + const first = result.embedded!.items![0]!; + expect(first.id).toBeDefined(); + expect(first.status).toBeDefined(); + expect(first.amount).toBeDefined(); + expect(first.amount?.value).toBeDefined(); + expect(first.amount?.currency).toBeDefined(); + expect(first.links).toBeDefined(); + expect(first.links?.self).toBeDefined(); + expect(first.links?.massPayment).toBeDefined(); + expect(first.links?.destination).toBeDefined(); + + // Optional fields + if (first.metadata) { + expect(typeof first.metadata).toBe("object"); + } + if (first.processingChannel) { + expect(typeof first.processingChannel).toBe("object"); + } + } +}); + +test("Items Get Mass Payment Item", async () => { + const testHttpClient = createTestHTTPClient("getMassPaymentItem"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.massPayments.items.get({ + itemId: "233d76b2-26f8-4b73-b7fe-5f8d94d0bdb3", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.id).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.amount).toBeDefined(); + expect(result.amount?.value).toBeDefined(); + expect(result.amount?.currency).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.links?.massPayment).toBeDefined(); + expect(result.links?.destination).toBeDefined(); + + // Optional fields + if (result.metadata) { + expect(typeof result.metadata).toBe("object"); + } + if (result.processingChannel) { + expect(typeof result.processingChannel).toBe("object"); + } +}); diff --git a/src/__tests__/kba.test.ts b/src/__tests__/kba.test.ts new file mode 100644 index 0000000..9497493 --- /dev/null +++ b/src/__tests__/kba.test.ts @@ -0,0 +1,152 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { afterAll, beforeAll, expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +let kbaSessionId: string | undefined; +let customerId: string | undefined; + +beforeAll(async () => { + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: createTestHTTPClient("kba"), + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + // Create a Personal Verified Customer with firstName "kba" to trigger KBA status + const timestamp = Date.now(); + const customerResult = await dwolla.customers.create({ + firstName: "kba", + lastName: "Test", + email: `kba-test-${timestamp}@example.com`, + type: "personal", + address1: "123 Main St", + city: "Des Moines", + state: "IA", + postalCode: "50309", + dateOfBirth: "1980-01-01", + ssn: "1234", + }); + + const customerLocationHeader = + customerResult?.headers["Location"]?.[0] ?? customerResult?.headers["location"]?.[0]; + expect(customerLocationHeader).toBeDefined(); + customerId = new URL(customerLocationHeader as string).pathname.split("/").pop(); + + // Initiate a KBA session for the customer + const kbaResult = await dwolla.customers.kba.initiate({ + id: customerId!, + }); + + const kbaLocationHeader = + kbaResult?.headers["Location"]?.[0] ?? kbaResult?.headers["location"]?.[0]; + expect(kbaLocationHeader).toBeDefined(); + kbaSessionId = new URL(kbaLocationHeader as string).pathname.split("/").pop(); +}); + +afterAll(async () => { + // Clean up: deactivate the customer + if (customerId) { + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: createTestHTTPClient("kba-cleanup"), + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + await dwolla.customers.update({ + id: customerId, + requestBody: { + status: "deactivated", + }, + }); + } +}); + +test("Kba Get Kba Questions", async () => { + const testHttpClient = createTestHTTPClient("getKbaQuestions"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.kba.getQuestions({ + id: kbaSessionId!, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.id).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.answer).toBeDefined(); + expect(Array.isArray(result.questions ?? [])).toBe(true); + + // Validate shape of the first question if present + if ((result.questions?.length ?? 0) > 0) { + const first = result.questions![0]!; + expect(first.id).toBeDefined(); + expect(first.text).toBeDefined(); + expect(Array.isArray(first.answers ?? [])).toBe(true); + + if ((first.answers?.length ?? 0) > 0) { + const firstAnswer = first.answers![0]!; + expect(firstAnswer.id).toBeDefined(); + expect(firstAnswer.text).toBeDefined(); + } + } +}); + +test("Kba Verify Kba Questions", async () => { + const testHttpClient = createTestHTTPClient("verifyKbaQuestions"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.kba.verify({ + id: kbaSessionId!, + requestBody: + { + "answers": [ + { + "questionId": "2355953375", + "answerId": "2687969335" + }, + { + "questionId": "2355953385", + "answerId": "2687969385" + }, + { + "questionId": "2355953395", + "answerId": "2687969435" + }, + { + "questionId": "2355953405", + "answerId": "2687969485" + } + ] + }, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.verificationStatus).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.customer).toBeDefined(); +}); diff --git a/src/__tests__/labels.test.ts b/src/__tests__/labels.test.ts new file mode 100644 index 0000000..e0ca203 --- /dev/null +++ b/src/__tests__/labels.test.ts @@ -0,0 +1,99 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { beforeAll, expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +let labelId: string | undefined; + +beforeAll(async () => { + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: createTestHTTPClient("labels"), + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + } + }); + + const created = await dwolla.customers.labels.create({ + id: "86d3ca4b-8c3c-4ba9-88fc-3be8243daf9d", + requestBody: { + amount: { + value: "10.00", + currency: "USD", + }, + }, + }); + const locationHeader = + created?.headers["Location"]?.[0] ?? created?.headers["location"]?.[0]; + expect(locationHeader).toBeDefined(); + labelId = new URL(locationHeader as string).pathname.split("/").pop(); + +}); + +test("Labels Get Label", async () => { + const testHttpClient = createTestHTTPClient("getLabel"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.labels.get({ + id: labelId!, + }); + expect(result).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.amount).toBeDefined(); + expect(result.amount?.value).toBeDefined(); + expect(result.amount?.currency).toBe("USD"); + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); +}); + +test("Labels Remove Label", async () => { + const testHttpClient = createTestHTTPClient("removeLabel"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + // create a label ledger entry to zero out the label to prepare for removal + await dwolla.labels.ledgerEntries.create({ + id: labelId!, + requestBody: { + amount: { + value: "-10.00", + currency: "USD", + }, + }, + }); + + // remove the label + const result = await dwolla.labels.remove({ + id: labelId!, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.id).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.amount).toBeDefined(); + expect(result.amount?.value).toBeDefined(); + expect(result.amount?.currency).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); +}); diff --git a/src/__tests__/ledgerentries.test.ts b/src/__tests__/ledgerentries.test.ts new file mode 100644 index 0000000..833ec0f --- /dev/null +++ b/src/__tests__/ledgerentries.test.ts @@ -0,0 +1,66 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Ledgerentries List Label Ledger Entries", async () => { + const testHttpClient = createTestHTTPClient("listLabelLedgerEntries"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.labels.ledgerEntries.list({ + id: "8f04600b-ef47-4e2c-b001-dc5887a9fa67", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.ledgerEntries ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + // Validate shape of the first ledger entry if present + if ((result.embedded?.ledgerEntries?.length ?? 0) > 0) { + const first = result.embedded!.ledgerEntries![0]!; + expect(first.id).toBeDefined(); + expect(first.amount).toBeDefined(); + expect(first.amount?.value).toBeDefined(); + expect(first.amount?.currency).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + } +}); + +test("Ledgerentries Get Label Ledger Entry", async () => { + const testHttpClient = createTestHTTPClient("getLabelLedgerEntry"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.labels.ledgerEntries.get({ + ledgerEntryId: "a308b898-7b38-4013-b71a-d5bae7a4889e", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.id).toBeDefined(); + expect(result.amount).toBeDefined(); + expect(result.amount?.value).toBeDefined(); + expect(result.amount?.currency).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); +}); diff --git a/src/__tests__/masspayments.test.ts b/src/__tests__/masspayments.test.ts new file mode 100644 index 0000000..9b196b9 --- /dev/null +++ b/src/__tests__/masspayments.test.ts @@ -0,0 +1,163 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { beforeAll, expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +let massPaymentId: string | undefined; + +beforeAll(async () => { + const testHttpClient = createTestHTTPClient("getMassPayment"); + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + const result = await dwolla.massPayments.create({ + requestBody:{ + links: { + source: { + href: "https://api-sandbox.dwolla.com/funding-sources/daeec1c1-c54a-4ec2-93aa-5ae0aab23a03", + }, + }, + items: [ + { + links: { + destination: { + href: "https://api-sandbox.dwolla.com/funding-sources/e417ab60-a3e0-4043-9646-29f2c782c993", + }, + }, + amount: { + value: "100", + currency: "USD", + }, + clearing: { + destination: "next-available", + }, + achDetails: { + destination: { + addenda: { + values: ["EMP001 PAYROLL 2025-12-02"], + }, + }, + } + }, + { + links: { + destination: { + href: "https://api-sandbox.dwolla.com/funding-sources/e417ab60-a3e0-4043-9646-29f2c782c993", + }, + }, + amount: { + value: "200", + currency: "USD", + }, + clearing: { + destination: "next-available", + }, + achDetails: { + destination: { + addenda: { + values: ["EMP002 PAYROLL 2025-12-02"], + }, + }, + } + }, + ], + status: "deferred", + clearing: { + source: "next-available", + }, + achDetails: { + source: { + addenda: { + values: ["BATCH REF 12345"], + }, + }, + }, + } + }); + + const locationHeader = + result?.headers["Location"]?.[0] ?? result?.headers["location"]?.[0]; + expect(locationHeader).toBeDefined(); + massPaymentId = new URL(locationHeader as string).pathname.split("/").pop(); +}); + +test("Masspayments Get Mass Payment", async () => { + const testHttpClient = createTestHTTPClient("getMassPayment"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.massPayments.get({ + id: massPaymentId!, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.id).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.total).toBeDefined(); + expect(result.total?.value).toBeDefined(); + expect(result.total?.currency).toBeDefined(); + + // Optional fields + if (result.totalFees) { + expect(result.totalFees.value).toBeDefined(); + expect(result.totalFees.currency).toBeDefined(); + } + if (result.correlationId) { + expect(typeof result.correlationId).toBe("string"); + } +}); + +test("Masspayments Update Mass Payment", async () => { + const testHttpClient = createTestHTTPClient("updateMassPayment"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.massPayments.update({ + id: massPaymentId!, + requestBody: { + status: "cancelled", + }, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.id).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.total).toBeDefined(); + expect(result.total?.value).toBeDefined(); + expect(result.total?.currency).toBeDefined(); + + // Optional fields + if (result.totalFees) { + expect(result.totalFees.value).toBeDefined(); + expect(result.totalFees.currency).toBeDefined(); + } + if (result.correlationId) { + expect(typeof result.correlationId).toBe("string"); + } +}); diff --git a/src/__tests__/microdeposits.test.ts b/src/__tests__/microdeposits.test.ts new file mode 100644 index 0000000..7a0a9e1 --- /dev/null +++ b/src/__tests__/microdeposits.test.ts @@ -0,0 +1,129 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { afterAll, beforeAll, expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +let fundingSourceId: string | undefined; + +beforeAll(async () => { + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: createTestHTTPClient("microDeposits"), + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + try { + const fundingSource = await dwolla.customers.fundingSources.create({ + id: "b2bedef2-2c66-4c4e-982d-1adcaa732b97", + createCustomerFundingSource: { + name: "My First Bank", + bankAccountType: "checking", + routingNumber: "222222226", + accountNumber: "1234", + }, + }); + + const fsLocationHeader = + fundingSource?.headers["Location"]?.[0] ?? fundingSource?.headers["location"]?.[0]; + fundingSourceId = new URL(fsLocationHeader as string).pathname.split("/").pop(); + } catch (error: any) { + // If bank already exists, extract the ID from the error response + if (error?.statusCode === 400 && error?.body?.includes("DuplicateResource")) { + const bodyObj = JSON.parse(error.body); + const existingHref = bodyObj._links?.about?.href; + if (existingHref) { + fundingSourceId = new URL(existingHref).pathname.split("/").pop(); + } + } else { + throw error; + } + } + + await dwolla.fundingSources.microDeposits.initiate({ + id: fundingSourceId!, + }); +}); + +afterAll(async () => { + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: createTestHTTPClient("microDeposits-cleanup"), + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + // Clean up: remove the funding source + await dwolla.fundingSources.updateOrRemove({ + id: fundingSourceId!, + requestBody: { + removed: true, + }, + }); +}); + +test("Microdeposits Get Micro Deposits", async () => { + const testHttpClient = createTestHTTPClient("getMicroDeposits"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.fundingSources.microDeposits.get({ + id: fundingSourceId!, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.created).toBeInstanceOf(Date); + expect(result.status).toBeDefined(); + expect(result.links).toBeDefined(); + + // Optional fields + if (result.failure) { + expect(result.failure.code).toBeDefined(); + expect(result.failure.description).toBeDefined(); + } +}); + +test("Microdeposits Verify Micro Deposits", async () => { + const testHttpClient = createTestHTTPClient("verifyMicroDeposits"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.fundingSources.microDeposits.verify({ + id: fundingSourceId!, + requestBody: { + amount1: { + value: "0.02", + currency: "USD", + }, + amount2: { + value: "0.03", + currency: "USD", + }, + }, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); +}); diff --git a/src/__tests__/mockserver/testdata/example.file b/src/__tests__/mockserver/testdata/example.file new file mode 100644 index 0000000..3b18e51 --- /dev/null +++ b/src/__tests__/mockserver/testdata/example.file @@ -0,0 +1 @@ +hello world diff --git a/src/__tests__/ondemandtransferauthorizations.test.ts b/src/__tests__/ondemandtransferauthorizations.test.ts new file mode 100644 index 0000000..3477341 --- /dev/null +++ b/src/__tests__/ondemandtransferauthorizations.test.ts @@ -0,0 +1,31 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Ondemandtransferauthorizations Create On Demand Transfer Authorization", async () => { + const testHttpClient = createTestHTTPClient( + "createOnDemandTransferAuthorization", + ); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.fundingSources.onDemandTransferAuthorizations + .create(); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.bodyText).toBeDefined(); + expect(result.buttonText).toBeDefined(); +}); diff --git a/src/__tests__/reallocations.test.ts b/src/__tests__/reallocations.test.ts new file mode 100644 index 0000000..ceab5e7 --- /dev/null +++ b/src/__tests__/reallocations.test.ts @@ -0,0 +1,31 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Reallocations Retrieve Label Reallocation", async () => { + const testHttpClient = createTestHTTPClient("retrieveLabelReallocation"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.labels.reallocations.get({ + reallocationId: "9158494e-2aac-4fe8-8f35-f40db0c7c123", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.created).toBeInstanceOf(Date); + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.links?.toLedgerEntry).toBeDefined(); + expect(result.links?.fromLedgerEntry).toBeDefined(); +}); diff --git a/src/__tests__/retries.test.ts b/src/__tests__/retries.test.ts new file mode 100644 index 0000000..ccd2970 --- /dev/null +++ b/src/__tests__/retries.test.ts @@ -0,0 +1,41 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Retries List Webhook Retries", async () => { + const testHttpClient = createTestHTTPClient("listWebhookRetries"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.webhooks.retries.list({ + id: "b9fa8254-3427-4a07-ab36-b7a76504b614", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.retries ?? [])).toBe(true); + expect(typeof result.total).toBe("number"); + + // Validate shape of the first retry if present + if ((result.embedded?.retries?.length ?? 0) > 0) { + const first = result.embedded!.retries![0]!; + expect(first.id).toBeDefined(); + expect(first.timestamp).toBeInstanceOf(Date); + expect(first.links).toBeDefined(); + expect(first.links?.self).toBeDefined(); + expect(first.links?.webhook).toBeDefined(); + } +}); diff --git a/src/__tests__/root.test.ts b/src/__tests__/root.test.ts new file mode 100644 index 0000000..99fd55f --- /dev/null +++ b/src/__tests__/root.test.ts @@ -0,0 +1,27 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Root Get Root", async () => { + const testHttpClient = createTestHTTPClient("getRoot"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.root.get(); + expect(result).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.["account"]).toBeDefined(); + expect(result.links?.["customers"]).toBeDefined(); + expect(result.links?.["webhook-subscriptions"]).toBeDefined(); +}); diff --git a/src/__tests__/sandboxsimulations.test.ts b/src/__tests__/sandboxsimulations.test.ts new file mode 100644 index 0000000..edcd2d4 --- /dev/null +++ b/src/__tests__/sandboxsimulations.test.ts @@ -0,0 +1,24 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Sandbox Simulations Simulate Bank Transfer Processing", async () => { + const testHttpClient = createTestHTTPClient("simulateBankTransferProcessing"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.sandboxSimulations.simulate(); + expect(result).toBeDefined(); + // Sandbox simulation returns an empty object on success +}); diff --git a/src/__tests__/testclient.ts b/src/__tests__/testclient.ts new file mode 100644 index 0000000..9f09f5c --- /dev/null +++ b/src/__tests__/testclient.ts @@ -0,0 +1,48 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +import { getRandomValues } from "crypto"; +import { HTTPClient } from "../lib/http.js"; + +export function createTestHTTPClient(testName: string): HTTPClient { + const httpClient = new HTTPClient({ + fetcher: (request: URL | RequestInfo) => { + return fetch(request); + }, + }); + + const testInstanceId = genTestId(); + + httpClient.addHook("beforeRequest", (request: Request) => { + const nextRequest = new Request(request, { + signal: request.signal || AbortSignal.timeout(20000), + }); + + nextRequest.headers.set("x-speakeasy-test-name", testName); + nextRequest.headers.set("x-speakeasy-test-instance-id", testInstanceId); + + return nextRequest; + }); + + return httpClient; +} + +function genTestId(): string { + const b = new Uint8Array(16); + getRandomValues(b); + + return `${buf2hex(b.slice(0, 4))}-${buf2hex(b.slice(4, 6))}-${ + buf2hex( + b.slice(6, 8), + ) + }-${buf2hex(b.slice(8, 10))}-${buf2hex(b.slice(10))}`; +} + +// Helper function to convert buffer to hex string +function buf2hex(buffer: Uint8Array): string { + return [...buffer] + .map((x) => x.toString(16).padStart(2, "0")) + .join("") + .toUpperCase(); +} diff --git a/src/__tests__/tokens.test.ts b/src/__tests__/tokens.test.ts new file mode 100644 index 0000000..67f77c4 --- /dev/null +++ b/src/__tests__/tokens.test.ts @@ -0,0 +1,36 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Tokens Create Application Access Token", async () => { + const testHttpClient = createTestHTTPClient("createApplicationAccessToken"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const clientId = process.env["DWOLLA_CLIENT_ID"] ?? ""; + const clientSecret = process.env["DWOLLA_CLIENT_SECRET"] ?? ""; + const dwollaBasicAuth = Buffer.from(`${clientId}:${clientSecret}`).toString("base64"); + + const result = await dwolla.tokens.create({ + basicAuth: "Basic" + dwollaBasicAuth, + }, { + grantType: "client_credentials", + }); + + expect(result).toBeDefined(); + // Assert structure rather than exact payload + expect(result.accessToken).toBeDefined(); + expect(result.tokenType).toBeDefined(); + expect(typeof result.expiresIn).toBe("number"); +}); diff --git a/src/__tests__/transfers.test.ts b/src/__tests__/transfers.test.ts new file mode 100644 index 0000000..7aeea6c --- /dev/null +++ b/src/__tests__/transfers.test.ts @@ -0,0 +1,104 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Transfers Get Transfer", async () => { + const testHttpClient = createTestHTTPClient("getTransfer"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.transfers.get({ + id: "5cefc1b4-c2ce-f011-acd5-02ab38c54207", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.id).toBeDefined(); + expect(result.status).toBeDefined(); + expect(result.created).toBeInstanceOf(Date); + expect(result.amount).toBeDefined(); + expect(result.amount?.value).toBeDefined(); + expect(result.amount?.currency).toBeDefined(); + expect(result.links).toBeDefined(); + expect(result.links?.["self"]).toBeDefined(); + expect(result.links?.["source"]).toBeDefined(); + expect(result.links?.["destination"]).toBeDefined(); + + // Optional fields - only check if present + if (result.clearing) { + expect(result.clearing.source).toBeDefined(); + } + if (result.correlationId) { + expect(typeof result.correlationId).toBe("string"); + } + if (result.metadata) { + expect(typeof result.metadata).toBe("object"); + } + if (result.achDetails) { + expect(typeof result.achDetails).toBe("object"); + } + if (result.rtpDetails) { + expect(typeof result.rtpDetails).toBe("object"); + } + if (result.fedNowDetails) { + expect(typeof result.fedNowDetails).toBe("object"); + } + if (result.processingChannel) { + expect(typeof result.processingChannel).toBe("object"); + } +}); + +test("Transfers Cancel Transfer", async () => { + const testHttpClient = createTestHTTPClient("cancelTransfer"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + // create a transfer to cancel in this test + const createTransferResult = await dwolla.transfers.create({ + requestBody: { + links: { + source: { + href: "https://api-sandbox.dwolla.com/funding-sources/e68fa049-56b8-4795-84b7-fa15906f2037", + }, + destination: { + href: "https://api-sandbox.dwolla.com/funding-sources/fbc97298-c9c9-4b45-a10b-8c40473542f7", + }, + }, + amount: { + value: "250.50", + currency: "USD", + }, + }, + }); + + const locationHeader = + createTransferResult?.headers["Location"]?.[0] ?? createTransferResult?.headers["location"]?.[0]; + expect(locationHeader).toBeDefined(); + const transferId = new URL(locationHeader as string).pathname.split("/").pop(); + + const result = await dwolla.transfers.cancel({ + id: transferId!, + requestBody: { + status: "cancelled", + }, + }); + expect(result).toBeDefined(); + // Cancel operation returns an empty object on success +}); \ No newline at end of file diff --git a/src/__tests__/webhooks.test.ts b/src/__tests__/webhooks.test.ts new file mode 100644 index 0000000..b88422e --- /dev/null +++ b/src/__tests__/webhooks.test.ts @@ -0,0 +1,50 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Webhooks Get Webhook", async () => { + const testHttpClient = createTestHTTPClient("getWebhook"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.webhooks.get({ + id: "b9fa8254-3427-4a07-ab36-b7a76504b614", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.links?.subscription).toBeDefined(); + expect(result.links?.retry).toBeDefined(); + expect(result.links?.event).toBeDefined(); + + expect(result.id).toBeDefined(); + expect(result.topic).toBeDefined(); + expect(result.accountId).toBeDefined(); + expect(result.eventId).toBeDefined(); + expect(result.subscriptionId).toBeDefined(); + + expect(Array.isArray(result.attempts ?? [])).toBe(true); + if ((result.attempts?.length ?? 0) > 0) { + const attempt = result.attempts![0]!; + expect(attempt.id).toBeDefined(); + expect(attempt.request).toBeDefined(); + expect(attempt.request?.url).toBeDefined(); + expect(attempt.request?.timestamp).toBeInstanceOf(Date); + expect(Array.isArray(attempt.request?.headers ?? [])).toBe(true); + expect(attempt.response).toBeDefined(); + expect(typeof attempt.response?.statusCode).toBe("number"); + expect(attempt.response?.timestamp).toBeInstanceOf(Date); + } +}); diff --git a/src/__tests__/webhooksubscriptions.test.ts b/src/__tests__/webhooksubscriptions.test.ts new file mode 100644 index 0000000..195b650 --- /dev/null +++ b/src/__tests__/webhooksubscriptions.test.ts @@ -0,0 +1,143 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { beforeAll, expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +let webhookId: string | undefined; + +beforeAll(async () => { + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: createTestHTTPClient("webhookSubscriptions"), + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + } + }); + + const created = await dwolla.webhookSubscriptions.create({ + url: "http://myapplication.com/webhooks", + secret: "mysecret", + }); + const locationHeader = + created?.headers["Location"]?.[0] ?? created?.headers["location"]?.[0]; + expect(locationHeader).toBeDefined(); + webhookId = new URL(locationHeader as string).pathname.split("/").pop(); + +}); + + +test("Webhooksubscriptions List Webhook Subscriptions", async () => { + const testHttpClient = createTestHTTPClient("listWebhookSubscriptions"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.webhookSubscriptions.list(); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.webhookSubscriptions ?? [])).toBe(true); + if ((result.embedded?.webhookSubscriptions?.length ?? 0) > 0) { + const first = result.embedded!.webhookSubscriptions![0]!; + expect(first.id).toBeDefined(); + expect(first.url).toBeDefined(); + expect(typeof first.paused).toBe("boolean"); + expect(first.links).toBeDefined(); + expect(first.links?.self).toBeDefined(); + expect(first.links?.webhooks).toBeDefined(); + expect(first.created).toBeInstanceOf(Date); + } +}); + +test("Webhooksubscriptions Get Webhook Subscription", async () => { + const testHttpClient = createTestHTTPClient("getWebhookSubscription"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.webhookSubscriptions.get({ + id: webhookId?? "", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.links?.webhooks).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.url).toBeDefined(); + expect(typeof result.paused).toBe("boolean"); + expect(result.created).toBeInstanceOf(Date); +}); + +test("Webhooksubscriptions Update Webhook Subscription", async () => { + const testHttpClient = createTestHTTPClient("updateWebhookSubscription"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.webhookSubscriptions.update({ + id: webhookId?? "", + requestBody: { + paused: true, + }, + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.links?.webhooks).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.url).toBeDefined(); + expect(typeof result.paused).toBe("boolean"); + expect(result.created).toBeInstanceOf(Date); +}); + +test("Webhooksubscriptions Delete", async () => { + const testHttpClient = createTestHTTPClient("delete"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + const result = await dwolla.webhookSubscriptions.delete({ + id: webhookId?? "" + }); + expect(result).toBeDefined(); + // Assert structure of deleted subscription rather than exact payload + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.links?.webhooks).toBeDefined(); + expect(result.id).toBeDefined(); + expect(result.url).toBeDefined(); + expect(typeof result.paused).toBe("boolean"); + expect(result.created).toBeInstanceOf(Date); +}); diff --git a/src/__tests__/webhooksubscriptionswebhooks.test.ts b/src/__tests__/webhooksubscriptionswebhooks.test.ts new file mode 100644 index 0000000..565e5ae --- /dev/null +++ b/src/__tests__/webhooksubscriptionswebhooks.test.ts @@ -0,0 +1,61 @@ +/* + * Code originally generated by Speakeasy (https://www.speakeasy.com). + */ + +import { expect, test } from "vitest"; +import { Dwolla } from "../index.js"; +import { createTestHTTPClient } from "./testclient.js"; + +test("Webhooksubscriptions Webhooks List Webhooks", async () => { + const testHttpClient = createTestHTTPClient("listWebhooks"); + + const dwolla = new Dwolla({ + serverURL: "https://api-sandbox.dwolla.com", + httpClient: testHttpClient, + security: { + clientID: process.env["DWOLLA_CLIENT_ID"] ?? "value", + clientSecret: process.env["DWOLLA_CLIENT_SECRET"] ?? "value", + }, + }); + + const result = await dwolla.webhookSubscriptions.webhooks.list({ + id: "ff29dec3-344d-4132-b890-151bd372ca0a", + }); + expect(result).toBeDefined(); + // Assert structure rather than exact payload to tolerate real sandbox data + expect(result.links).toBeDefined(); + expect(result.links?.self).toBeDefined(); + expect(result.embedded).toBeDefined(); + expect(Array.isArray(result.embedded?.webhooks ?? [])).toBe(true); + + if ((result.embedded?.webhooks?.length ?? 0) > 0) { + const first = result.embedded!.webhooks![0]!; + // Core webhook fields + expect(first.id).toBeDefined(); + expect(first.topic).toBeDefined(); + expect(first.accountId).toBeDefined(); + expect(first.eventId).toBeDefined(); + expect(first.subscriptionId).toBeDefined(); + + // Links structure + expect(first.links).toBeDefined(); + expect(first.links?.self).toBeDefined(); + expect(first.links?.subscription).toBeDefined(); + expect(first.links?.retry).toBeDefined(); + expect(first.links?.event).toBeDefined(); + + // Attempts structure + expect(Array.isArray(first.attempts ?? [])).toBe(true); + if ((first.attempts?.length ?? 0) > 0) { + const attempt = first.attempts![0]!; + expect(attempt.id).toBeDefined(); + expect(attempt.request).toBeDefined(); + expect(attempt.request?.url).toBeDefined(); + expect(attempt.request?.timestamp).toBeInstanceOf(Date); + expect(Array.isArray(attempt.request?.headers ?? [])).toBe(true); + expect(attempt.response).toBeDefined(); + expect(typeof attempt.response?.statusCode).toBe("number"); + expect(attempt.response?.timestamp).toBeInstanceOf(Date); + } + } +}); diff --git a/src/funcs/clientTokensCreate.ts b/src/funcs/clientTokensCreate.ts index 231da58..9048ea4 100644 --- a/src/funcs/clientTokensCreate.ts +++ b/src/funcs/clientTokensCreate.ts @@ -94,7 +94,7 @@ async function $do( const headers = new Headers(compactMap({ "Content-Type": "application/json", - Accept: "application/json", + Accept: "application/vnd.dwolla.v1.hal+json", })); const securityInput = await extractSecurity(client._options.security); @@ -158,7 +158,9 @@ async function $do( | UnexpectedClientError | SDKValidationError >( - M.json(200, operations.CreateClientTokenResponse$inboundSchema), + M.json(200, operations.CreateClientTokenResponse$inboundSchema, { + ctype: "application/vnd.dwolla.v1.hal+json", + }), M.jsonErr(400, errors.BadRequestError$inboundSchema, { ctype: "application/vnd.dwolla.v1.hal+json", }), diff --git a/src/funcs/tokensCreate.ts b/src/funcs/tokensCreate.ts index e001db9..6ed3f16 100644 --- a/src/funcs/tokensCreate.ts +++ b/src/funcs/tokensCreate.ts @@ -8,7 +8,7 @@ import * as M from "../lib/matchers.js"; import { compactMap } from "../lib/primitives.js"; import { safeParse } from "../lib/schemas.js"; import { RequestOptions } from "../lib/sdks.js"; -import { extractSecurity, resolveGlobalSecurity } from "../lib/security.js"; +import { resolveSecurity } from "../lib/security.js"; import { pathToFunc } from "../lib/url.js"; import { DwollaError } from "../models/errors/dwollaerror.js"; import { @@ -33,6 +33,7 @@ import { Result } from "../types/fp.js"; */ export function tokensCreate( client: DwollaCore, + security: operations.CreateApplicationAccessTokenSecurity, request: operations.CreateApplicationAccessTokenRequest, options?: RequestOptions, ): APIPromise< @@ -51,6 +52,7 @@ export function tokensCreate( > { return new APIPromise($do( client, + security, request, options, )); @@ -58,6 +60,7 @@ export function tokensCreate( async function $do( client: DwollaCore, + security: operations.CreateApplicationAccessTokenSecurity, request: operations.CreateApplicationAccessTokenRequest, options?: RequestOptions, ): Promise< @@ -101,18 +104,25 @@ async function $do( Accept: "application/json", })); - const securityInput = await extractSecurity(client._options.security); - const requestSecurity = resolveGlobalSecurity(securityInput); + const requestSecurity = resolveSecurity( + [ + { + fieldName: "Authorization", + type: "apiKey:header", + value: security?.basicAuth, + }, + ], + ); const context = { options: client._options, baseURL: options?.serverURL ?? client._baseURL ?? "", operationID: "createApplicationAccessToken", - oAuth2Scopes: [], + oAuth2Scopes: null, resolvedSecurity: requestSecurity, - securitySource: client._options.security, + securitySource: security, retryConfig: options?.retries || client._options.retryConfig || { strategy: "none" }, diff --git a/src/lib/config.ts b/src/lib/config.ts index 5768259..ea3027a 100644 --- a/src/lib/config.ts +++ b/src/lib/config.ts @@ -68,7 +68,7 @@ export function serverURLFromOptions(options: SDKOptions): URL | null { export const SDK_METADATA = { language: "typescript", openapiDocVersion: "2.0", - sdkVersion: "0.0.1-beta.13", - genVersion: "2.755.9", - userAgent: "speakeasy-sdk/typescript 0.0.1-beta.13 2.755.9 2.0 dwolla", + sdkVersion: "0.0.1-beta.14", + genVersion: "2.769.1", + userAgent: "speakeasy-sdk/typescript 0.0.1-beta.14 2.769.1 2.0 dwolla", } as const; diff --git a/src/lib/encodings.ts b/src/lib/encodings.ts index 25c9dcb..31cd373 100644 --- a/src/lib/encodings.ts +++ b/src/lib/encodings.ts @@ -102,8 +102,9 @@ export function encodeLabel( }); encValue = mapped?.join("").slice(1); } else { - const k = - options?.explode && isPlainObject(value) ? `${encodeString(pk)}=` : ""; + const k = options?.explode && isPlainObject(value) + ? `${encodeString(pk)}=` + : ""; encValue = `${k}${encodeValue(pv)}`; } @@ -426,6 +427,7 @@ export function queryJoin(...args: (string | undefined)[]): string { type QueryEncoderOptions = { explode?: boolean; charEncoding?: "percent" | "none"; + allowEmptyValue?: string[]; }; type QueryEncoder = ( @@ -440,7 +442,7 @@ type BulkQueryEncoder = ( ) => string; export function queryEncoder(f: QueryEncoder): BulkQueryEncoder { - const bulkEncode = function ( + const bulkEncode = function( values: Record, options?: QueryEncoderOptions, ): string { @@ -450,7 +452,19 @@ export function queryEncoder(f: QueryEncoder): BulkQueryEncoder { charEncoding: options?.charEncoding ?? "percent", }; + const allowEmptySet = new Set(options?.allowEmptyValue ?? []); + const encoded = Object.entries(values).map(([key, value]) => { + if (allowEmptySet.has(key)) { + if ( + value === undefined + || value === null + || value === "" + || (Array.isArray(value) && value.length === 0) + ) { + return `${encodeURIComponent(key)}=`; + } + } return f(key, value, opts); }); return queryJoin(...encoded); diff --git a/src/models/createcustomerfundingsource.ts b/src/models/createcustomerfundingsource.ts index aa1930e..b05109d 100644 --- a/src/models/createcustomerfundingsource.ts +++ b/src/models/createcustomerfundingsource.ts @@ -3,7 +3,7 @@ */ import * as z from "zod/v3"; -import { smartUnion } from "../types/union.js"; +import { smartUnion } from "../types/smartUnion.js"; import { CreateCustomerBankFundingSourceWithAccountNumbers, CreateCustomerBankFundingSourceWithAccountNumbers$Outbound, diff --git a/src/models/createreceiveonlyuser.ts b/src/models/createreceiveonlyuser.ts index a21afcd..8ce3782 100644 --- a/src/models/createreceiveonlyuser.ts +++ b/src/models/createreceiveonlyuser.ts @@ -11,7 +11,7 @@ export type CreateReceiveOnlyUser = { firstName: string; lastName: string; email: string; - type?: "receive-only" | undefined; + type: "receive-only"; ipAddress?: string | undefined; phone?: string | undefined; correlationId?: string | undefined; diff --git a/src/models/createunverifiedcustomer.ts b/src/models/createunverifiedcustomer.ts index ca8eed7..321683e 100644 --- a/src/models/createunverifiedcustomer.ts +++ b/src/models/createunverifiedcustomer.ts @@ -11,7 +11,7 @@ export type CreateUnverifiedCustomer = { firstName: string; lastName: string; email: string; - type?: "unverified" | undefined; + type: "unverified"; ipAddress?: string | undefined; phone?: string | undefined; correlationId?: string | undefined; diff --git a/src/models/createverifiedbusinesscustomerwithcontroller.ts b/src/models/createverifiedbusinesscustomerwithcontroller.ts index a3418d5..8e41d24 100644 --- a/src/models/createverifiedbusinesscustomerwithcontroller.ts +++ b/src/models/createverifiedbusinesscustomerwithcontroller.ts @@ -37,7 +37,7 @@ export type CreateVerifiedBusinessCustomerWithController = { ipAddress?: string | undefined; phone?: string | undefined; correlationId?: string | undefined; - type?: "business" | undefined; + type: "business"; address1: string; address2?: string | undefined; city: string; diff --git a/src/models/createverifiedbusinesscustomerwithinternationalcontroller.ts b/src/models/createverifiedbusinesscustomerwithinternationalcontroller.ts index e352f0d..f9c3729 100644 --- a/src/models/createverifiedbusinesscustomerwithinternationalcontroller.ts +++ b/src/models/createverifiedbusinesscustomerwithinternationalcontroller.ts @@ -46,7 +46,7 @@ export type CreateVerifiedBusinessCustomerWithInternationalController = { ipAddress?: string | undefined; phone?: string | undefined; correlationId?: string | undefined; - type?: "business" | undefined; + type: "business"; address1: string; address2?: string | undefined; city: string; diff --git a/src/models/createverifiedpersonalcustomer.ts b/src/models/createverifiedpersonalcustomer.ts index 97fbbd6..bfd6f7d 100644 --- a/src/models/createverifiedpersonalcustomer.ts +++ b/src/models/createverifiedpersonalcustomer.ts @@ -14,7 +14,7 @@ export type CreateVerifiedPersonalCustomer = { ipAddress?: string | undefined; phone?: string | undefined; correlationId?: string | undefined; - type?: "personal" | undefined; + type: "personal"; address1: string; address2?: string | undefined; city: string; diff --git a/src/models/createverifiedsolepropcustomer.ts b/src/models/createverifiedsolepropcustomer.ts index 71e86c4..9c2966c 100644 --- a/src/models/createverifiedsolepropcustomer.ts +++ b/src/models/createverifiedsolepropcustomer.ts @@ -14,7 +14,7 @@ export type CreateVerifiedSolePropCustomer = { ipAddress?: string | undefined; phone?: string | undefined; correlationId?: string | undefined; - type?: "business" | undefined; + type: "business"; address1: string; address2?: string | undefined; city: string; @@ -27,7 +27,7 @@ export type CreateVerifiedSolePropCustomer = { doingBusinessAs?: string | undefined; ein?: string | undefined; website?: string | undefined; - businessType?: "soleProprietorship" | undefined; + businessType: "soleProprietorship"; }; /** @internal */ diff --git a/src/models/customers.ts b/src/models/customers.ts index 59bec87..f9a76f0 100644 --- a/src/models/customers.ts +++ b/src/models/customers.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../lib/primitives.js"; import { safeParse } from "../lib/schemas.js"; import { Result as SafeParseResult } from "../types/fp.js"; -import { smartUnion } from "../types/union.js"; +import { smartUnion } from "../types/smartUnion.js"; import { SDKValidationError } from "./errors/sdkvalidationerror.js"; import { HalLink, HalLink$inboundSchema } from "./hallink.js"; import { @@ -52,6 +52,7 @@ export type CustomersEmbedded = { export type Customers = { links?: { [k: string]: HalLink } | undefined; embedded?: CustomersEmbedded | undefined; + total?: number | undefined; }; /** @internal */ @@ -112,6 +113,7 @@ export const Customers$inboundSchema: z.ZodType< > = z.object({ _links: z.record(HalLink$inboundSchema).optional(), _embedded: z.lazy(() => CustomersEmbedded$inboundSchema).optional(), + total: z.number().int().optional(), }).transform((v) => { return remap$(v, { "_links": "links", diff --git a/src/models/errors/canceltransfer.ts b/src/models/errors/canceltransfer.ts index 88606d1..9753ab4 100644 --- a/src/models/errors/canceltransfer.ts +++ b/src/models/errors/canceltransfer.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { BadRequestError, BadRequestError$inboundSchema, diff --git a/src/models/errors/createaccountexchange.ts b/src/models/errors/createaccountexchange.ts index 56f0087..d41bf2e 100644 --- a/src/models/errors/createaccountexchange.ts +++ b/src/models/errors/createaccountexchange.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { DwollaError } from "./dwollaerror.js"; import { InvalidExchangeError, diff --git a/src/models/errors/createbeneficialownerdocument.ts b/src/models/errors/createbeneficialownerdocument.ts index 595b27b..aa1da6e 100644 --- a/src/models/errors/createbeneficialownerdocument.ts +++ b/src/models/errors/createbeneficialownerdocument.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { DuplicateResourceSchemaError, DuplicateResourceSchemaError$inboundSchema, diff --git a/src/models/errors/createcustomerdocument.ts b/src/models/errors/createcustomerdocument.ts index e3b99c2..851f094 100644 --- a/src/models/errors/createcustomerdocument.ts +++ b/src/models/errors/createcustomerdocument.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { DuplicateResourceSchemaError, DuplicateResourceSchemaError$inboundSchema, diff --git a/src/models/errors/createcustomerexchange.ts b/src/models/errors/createcustomerexchange.ts index 92aa33e..f3df72e 100644 --- a/src/models/errors/createcustomerexchange.ts +++ b/src/models/errors/createcustomerexchange.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { DwollaError } from "./dwollaerror.js"; import { InvalidExchangeError, diff --git a/src/models/errors/createcustomerexchangesession.ts b/src/models/errors/createcustomerexchangesession.ts index 2abcaba..65b991e 100644 --- a/src/models/errors/createcustomerexchangesession.ts +++ b/src/models/errors/createcustomerexchangesession.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { DwollaError } from "./dwollaerror.js"; import { SDKValidationError } from "./sdkvalidationerror.js"; diff --git a/src/models/errors/createcustomerfundingsource.ts b/src/models/errors/createcustomerfundingsource.ts index a30da0a..a5272ec 100644 --- a/src/models/errors/createcustomerfundingsource.ts +++ b/src/models/errors/createcustomerfundingsource.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { DuplicateFundingSourceError, DuplicateFundingSourceError$inboundSchema, diff --git a/src/models/errors/createfundingsource.ts b/src/models/errors/createfundingsource.ts index 6138064..4a8b35d 100644 --- a/src/models/errors/createfundingsource.ts +++ b/src/models/errors/createfundingsource.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { BadRequestSchemaError, BadRequestSchemaError$inboundSchema, diff --git a/src/models/errors/createwebhooksubscription.ts b/src/models/errors/createwebhooksubscription.ts index 3960fb0..9722bd3 100644 --- a/src/models/errors/createwebhooksubscription.ts +++ b/src/models/errors/createwebhooksubscription.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { InvalidUrlFormatError, InvalidUrlFormatError$inboundSchema, diff --git a/src/models/errors/initiatekbaforcustomer.ts b/src/models/errors/initiatekbaforcustomer.ts index 4bbcbb6..a9da447 100644 --- a/src/models/errors/initiatekbaforcustomer.ts +++ b/src/models/errors/initiatekbaforcustomer.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { ForbiddenError, ForbiddenError$inboundSchema, diff --git a/src/models/errors/initiatetransfer.ts b/src/models/errors/initiatetransfer.ts index c144801..32e7ab1 100644 --- a/src/models/errors/initiatetransfer.ts +++ b/src/models/errors/initiatetransfer.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { AchAddendaEntriesNotEnabledForAccountError, AchAddendaEntriesNotEnabledForAccountError$inboundSchema, diff --git a/src/models/errors/verifykbaquestions.ts b/src/models/errors/verifykbaquestions.ts index ff8fb1b..6c44baa 100644 --- a/src/models/errors/verifykbaquestions.ts +++ b/src/models/errors/verifykbaquestions.ts @@ -5,7 +5,7 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { DwollaError } from "./dwollaerror.js"; import { ExpiredKbaSessionError, diff --git a/src/models/fundingsource.ts b/src/models/fundingsource.ts index 8a9c68f..edaba33 100644 --- a/src/models/fundingsource.ts +++ b/src/models/fundingsource.ts @@ -14,6 +14,7 @@ export const FundingSourceChannel = { Ach: "ach", RealTimePayments: "real-time-payments", Wire: "wire", + External: "external", } as const; export type FundingSourceChannel = ClosedEnum; diff --git a/src/models/operations/canceltransfer.ts b/src/models/operations/canceltransfer.ts index 263dc52..2b52e2d 100644 --- a/src/models/operations/canceltransfer.ts +++ b/src/models/operations/canceltransfer.ts @@ -12,7 +12,7 @@ import { SDKValidationError } from "../errors/sdkvalidationerror.js"; * Parameters to cancel a transfer */ export type CancelTransferRequestBody = { - status?: "cancelled" | undefined; + status: "cancelled"; }; export type CancelTransferRequest = { diff --git a/src/models/operations/createaccountexchange.ts b/src/models/operations/createaccountexchange.ts index cc2b051..c9b695e 100644 --- a/src/models/operations/createaccountexchange.ts +++ b/src/models/operations/createaccountexchange.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; diff --git a/src/models/operations/createapplicationaccesstoken.ts b/src/models/operations/createapplicationaccesstoken.ts index 1ac4c2a..a2f3dcf 100644 --- a/src/models/operations/createapplicationaccesstoken.ts +++ b/src/models/operations/createapplicationaccesstoken.ts @@ -9,6 +9,10 @@ import { ClosedEnum } from "../../types/enums.js"; import { Result as SafeParseResult } from "../../types/fp.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; +export type CreateApplicationAccessTokenSecurity = { + basicAuth: string; +}; + /** * Must be set to "client_credentials" */ @@ -30,17 +34,6 @@ export type CreateApplicationAccessTokenRequest = { grantType: GrantType; }; -/** - * The type of token, always "bearer" - */ -export const TokenType = { - Bearer: "bearer", -} as const; -/** - * The type of token, always "bearer" - */ -export type TokenType = ClosedEnum; - /** * successful operation */ @@ -50,15 +43,39 @@ export type CreateApplicationAccessTokenResponse = { */ accessToken: string; /** - * The type of token, always "bearer" + * The type of token, always "Bearer" */ - tokenType: TokenType; + tokenType: string; /** * The lifetime of the access token, in seconds. Default is 3600. */ expiresIn: number; }; +/** @internal */ +export type CreateApplicationAccessTokenSecurity$Outbound = { + basicAuth: string; +}; + +/** @internal */ +export const CreateApplicationAccessTokenSecurity$outboundSchema: z.ZodType< + CreateApplicationAccessTokenSecurity$Outbound, + z.ZodTypeDef, + CreateApplicationAccessTokenSecurity +> = z.object({ + basicAuth: z.string(), +}); + +export function createApplicationAccessTokenSecurityToJSON( + createApplicationAccessTokenSecurity: CreateApplicationAccessTokenSecurity, +): string { + return JSON.stringify( + CreateApplicationAccessTokenSecurity$outboundSchema.parse( + createApplicationAccessTokenSecurity, + ), + ); +} + /** @internal */ export const GrantType$outboundSchema: z.ZodNativeEnum = z .nativeEnum(GrantType); @@ -91,10 +108,6 @@ export function createApplicationAccessTokenRequestToJSON( ); } -/** @internal */ -export const TokenType$inboundSchema: z.ZodNativeEnum = z - .nativeEnum(TokenType); - /** @internal */ export const CreateApplicationAccessTokenResponse$inboundSchema: z.ZodType< CreateApplicationAccessTokenResponse, @@ -102,7 +115,7 @@ export const CreateApplicationAccessTokenResponse$inboundSchema: z.ZodType< unknown > = z.object({ access_token: z.string(), - token_type: TokenType$inboundSchema, + token_type: z.string(), expires_in: z.number().int(), }).transform((v) => { return remap$(v, { diff --git a/src/models/operations/createbeneficialownerforcustomer.ts b/src/models/operations/createbeneficialownerforcustomer.ts index b1f4581..cb43a54 100644 --- a/src/models/operations/createbeneficialownerforcustomer.ts +++ b/src/models/operations/createbeneficialownerforcustomer.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; diff --git a/src/models/operations/createcustomer.ts b/src/models/operations/createcustomer.ts index 49eeb46..5202fa6 100644 --- a/src/models/operations/createcustomer.ts +++ b/src/models/operations/createcustomer.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; diff --git a/src/models/operations/createcustomerexchange.ts b/src/models/operations/createcustomerexchange.ts index 6413209..bf7fd07 100644 --- a/src/models/operations/createcustomerexchange.ts +++ b/src/models/operations/createcustomerexchange.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; diff --git a/src/models/operations/createcustomerexchangesession.ts b/src/models/operations/createcustomerexchangesession.ts index 28809af..c02ee39 100644 --- a/src/models/operations/createcustomerexchangesession.ts +++ b/src/models/operations/createcustomerexchangesession.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; diff --git a/src/models/operations/createreauthexchangesession.ts b/src/models/operations/createreauthexchangesession.ts index c0094e9..7611942 100644 --- a/src/models/operations/createreauthexchangesession.ts +++ b/src/models/operations/createreauthexchangesession.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; diff --git a/src/models/operations/getcustomer.ts b/src/models/operations/getcustomer.ts index 1dde556..153ece2 100644 --- a/src/models/operations/getcustomer.ts +++ b/src/models/operations/getcustomer.ts @@ -5,7 +5,6 @@ import * as z from "zod/v3"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; @@ -20,10 +19,10 @@ export type GetCustomerRequest = { * successful operation */ export type GetCustomerResponse = - | models.VerifiedBusinessCustomer - | models.VerifiedPersonalCustomer - | models.UnverifiedCustomer - | models.ReceiveOnlyCustomer; + | (models.UnverifiedCustomer & { type: "unverified" }) + | (models.ReceiveOnlyCustomer & { type: "receive-only" }) + | (models.VerifiedPersonalCustomer & { type: "personal" }) + | (models.VerifiedBusinessCustomer & { type: "business" }); /** @internal */ export type GetCustomerRequest$Outbound = { @@ -52,11 +51,19 @@ export const GetCustomerResponse$inboundSchema: z.ZodType< GetCustomerResponse, z.ZodTypeDef, unknown -> = smartUnion([ - models.VerifiedBusinessCustomer$inboundSchema, - models.VerifiedPersonalCustomer$inboundSchema, - models.UnverifiedCustomer$inboundSchema, - models.ReceiveOnlyCustomer$inboundSchema, +> = z.union([ + models.UnverifiedCustomer$inboundSchema.and( + z.object({ type: z.literal("unverified") }), + ), + models.ReceiveOnlyCustomer$inboundSchema.and( + z.object({ type: z.literal("receive-only") }), + ), + models.VerifiedPersonalCustomer$inboundSchema.and( + z.object({ type: z.literal("personal") }), + ), + models.VerifiedBusinessCustomer$inboundSchema.and( + z.object({ type: z.literal("business") }), + ), ]); export function getCustomerResponseFromJSON( diff --git a/src/models/operations/getfundingsourcebalance.ts b/src/models/operations/getfundingsourcebalance.ts index ec5506b..329dfae 100644 --- a/src/models/operations/getfundingsourcebalance.ts +++ b/src/models/operations/getfundingsourcebalance.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; diff --git a/src/models/operations/listtransferfees.ts b/src/models/operations/listtransferfees.ts index 6f2dd62..7ff87e8 100644 --- a/src/models/operations/listtransferfees.ts +++ b/src/models/operations/listtransferfees.ts @@ -34,7 +34,7 @@ export type Transaction = { */ export type ListTransferFeesResponse = { transactions?: Array | undefined; - total?: string | undefined; + total?: number | undefined; }; /** @internal */ @@ -114,7 +114,7 @@ export const ListTransferFeesResponse$inboundSchema: z.ZodType< unknown > = z.object({ transactions: z.array(z.lazy(() => Transaction$inboundSchema)).optional(), - total: z.string().optional(), + total: z.number().int().optional(), }); export function listTransferFeesResponseFromJSON( diff --git a/src/models/operations/update.ts b/src/models/operations/update.ts index 7615f36..3dba8de 100644 --- a/src/models/operations/update.ts +++ b/src/models/operations/update.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; diff --git a/src/models/operations/updatebeneficialowner.ts b/src/models/operations/updatebeneficialowner.ts index ee8f9d0..be98241 100644 --- a/src/models/operations/updatebeneficialowner.ts +++ b/src/models/operations/updatebeneficialowner.ts @@ -4,7 +4,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import * as models from "../index.js"; /** diff --git a/src/models/operations/updateorremovefundingsource.ts b/src/models/operations/updateorremovefundingsource.ts index 90aedf3..451e807 100644 --- a/src/models/operations/updateorremovefundingsource.ts +++ b/src/models/operations/updateorremovefundingsource.ts @@ -6,7 +6,7 @@ import * as z from "zod/v3"; import { remap as remap$ } from "../../lib/primitives.js"; import { safeParse } from "../../lib/schemas.js"; import { Result as SafeParseResult } from "../../types/fp.js"; -import { smartUnion } from "../../types/union.js"; +import { smartUnion } from "../../types/smartUnion.js"; import { SDKValidationError } from "../errors/sdkvalidationerror.js"; import * as models from "../index.js"; diff --git a/src/sdk/tokens.ts b/src/sdk/tokens.ts index ddf17c4..9fb3037 100644 --- a/src/sdk/tokens.ts +++ b/src/sdk/tokens.ts @@ -15,11 +15,13 @@ export class Tokens extends ClientSDK { * Generate an application access token using OAuth 2.0 client credentials flow for server-to-server authentication. Requires client ID and secret sent via Basic authentication header with grant_type=client_credentials in the request body. Returns a bearer access token with expiration time for authenticating API requests scoped to your application. Essential for secure API access. */ async create( + security: operations.CreateApplicationAccessTokenSecurity, request: operations.CreateApplicationAccessTokenRequest, options?: RequestOptions, ): Promise { return unwrapAsync(tokensCreate( this, + security, request, options, )); diff --git a/src/types/enums.ts b/src/types/enums.ts index 32ad7bc..aba0ffd 100644 --- a/src/types/enums.ts +++ b/src/types/enums.ts @@ -3,34 +3,14 @@ */ import * as z from "zod/v3"; +import { Unrecognized, unrecognized } from "./unrecognized.js"; -declare const __brand: unique symbol; -export type Unrecognized = T & { [__brand]: "unrecognized" }; export type ClosedEnum>> = T[keyof T]; export type OpenEnum>> = | T[keyof T] | Unrecognized; -function unrecognized(value: T): Unrecognized { - unrecognizedCount++; - return value as Unrecognized; -} - -let unrecognizedCount = 0; -let refCount = 0; -export function unrecognizedCounter() { - refCount++; - const start = unrecognizedCount; - return { - count: () => { - const count = unrecognizedCount - start; - if (--refCount === 0) unrecognizedCount = 0; - return count; - }, - }; -} - export function inboundSchema>( enumObj: T, ): z.ZodType, z.ZodTypeDef, unknown> { diff --git a/src/types/index.ts b/src/types/index.ts index 92d9f73..abf0b7a 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -3,8 +3,9 @@ */ export { blobLikeSchema, isBlobLike } from "./blobs.js"; -export type { ClosedEnum, OpenEnum, Unrecognized } from "./enums.js"; +export type { ClosedEnum, OpenEnum } from "./enums.js"; export type { Result } from "./fp.js"; export type { PageIterator, Paginator } from "./operations.js"; export { createPageIterator } from "./operations.js"; export { RFCDate } from "./rfcdate.js"; +export * from "./unrecognized.js"; diff --git a/src/types/union.ts b/src/types/smartUnion.ts similarity index 67% rename from src/types/union.ts rename to src/types/smartUnion.ts index 0caf17a..866c3ab 100644 --- a/src/types/union.ts +++ b/src/types/smartUnion.ts @@ -2,9 +2,10 @@ * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. */ +// Not needed if lax mode import * as z from "zod/v3"; -import * as openEnums from "./enums.js"; import { RFCDate } from "./rfcdate.js"; +import { startCountingUnrecognized } from "./unrecognized.js"; interface Candidate { data: unknown; @@ -12,6 +13,8 @@ interface Candidate { fieldCount: number; /** Number of fields which only matched due to lax parsing */ inexactCount: number; + /** Number of fields which defaulted to zero values */ + zeroDefaultCount: number; } /** @@ -31,15 +34,21 @@ export function smartUnion< const candidates: Candidate[] = []; const errors: z.ZodIssue[][] = options.map(() => []); + const parentUnrecognizedCtr = startCountingUnrecognized(); + // Filter out invalid options for (const [i, option] of options.entries()) { - const counter = openEnums.unrecognizedCounter(); + const unrecognizedCtr = startCountingUnrecognized(); + const result = option.safeParse(input); + const inexactCount = unrecognizedCtr.end(); + const zeroDefaultCount = 0; if (result.success) { candidates.push({ data: result.data, - fieldCount: 0, - inexactCount: counter.count(), + inexactCount, + zeroDefaultCount, + fieldCount: -1, // We'll count this later if needed }); continue; } @@ -48,6 +57,7 @@ export function smartUnion< // No valid options if (candidates.length === 0) { + parentUnrecognizedCtr.end(0); ctx.addIssue({ code: "invalid_union", unionErrors: errors.map(issues => new z.ZodError(issues)), @@ -57,21 +67,28 @@ export function smartUnion< let best = candidates[0]!; - // Just one valid option - short circuit - if (candidates.length === 1) return best.data; - // Find the best option for (const candidate of candidates) { - candidate.fieldCount = countFieldsRecursive(candidate.data); + // Minor optimization to avoid counting fields if there's only one candidate + if (candidates.length > 1) { + candidate.fieldCount = countFieldsRecursive(candidate.data); + } best = better(candidate, best); } + // The cost of this union should be the cost of the best candidate not all the candidates + parentUnrecognizedCtr.end(best.inexactCount); + return best.data; }) as any; } function better(a: Candidate, b: Candidate): Candidate { - if (a.fieldCount !== b.fieldCount) return a.fieldCount > b.fieldCount ? a : b; + const actualFieldCountA = a.fieldCount - a.zeroDefaultCount; + const actualFieldCountB = b.fieldCount - b.zeroDefaultCount; + if (actualFieldCountA !== actualFieldCountB) { + return actualFieldCountA > actualFieldCountB ? a : b; + } return a.inexactCount < b.inexactCount ? a : b; } @@ -89,14 +106,15 @@ function countFieldsRecursive(parsed: unknown): number { while (index < queue.length) { const value = queue[index++]; - if (value === null || value === undefined) { + if (value === undefined) { continue; } // Check if it's a primitive value const type = typeof value; if ( - type === "number" + value === null + || type === "number" || type === "string" || type === "boolean" || type === "bigint" @@ -114,9 +132,8 @@ function countFieldsRecursive(parsed: unknown): number { } // Handle objects - if (typeof value === "object") { - const obj = value as Record; - queue.push(...Object.values(obj)); + if (type === "object") { + queue.push(...Object.values(value)); } } diff --git a/src/types/unrecognized.ts b/src/types/unrecognized.ts new file mode 100644 index 0000000..b7a2a13 --- /dev/null +++ b/src/types/unrecognized.ts @@ -0,0 +1,35 @@ +/* + * Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT. + */ + +declare const __brand: unique symbol; +export type Unrecognized = T & { [__brand]: "unrecognized" }; + +function unrecognized(value: T): Unrecognized { + globalCount++; + return value as Unrecognized; +} + +let globalCount = 0; +let refCount = 0; +export function startCountingUnrecognized() { + refCount++; + const start = globalCount; + return { + /** + * Ends counting and returns the delta. + * @param delta - If provided, only this amount is added to the parent counter + * (used for nested unions where we only want to record the winning option's count). + * If not provided, records all counts since start(). + */ + end: (delta?: number) => { + const count = globalCount - start; + // Reset globalCount back to start, then add only the specified delta + globalCount = start + (delta ?? count); + if (--refCount === 0) globalCount = 0; + return count; + }, + }; +} + +export { unrecognized }; diff --git a/tsconfig.json b/tsconfig.json index 94d81a3..0ccdbe2 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,6 @@ { "compilerOptions": { - "incremental": true, - "tsBuildInfoFile": ".tsbuildinfo", + "incremental": false, "target": "ES2020", "lib": ["ES2022", "DOM", "DOM.Iterable"], "jsx": "react-jsx",