diff --git a/.eslintignore b/.eslintignore deleted file mode 100644 index 763301fc..00000000 --- a/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -dist/ -node_modules/ \ No newline at end of file diff --git a/.eslintrc-examples.js b/.eslintrc-examples.js deleted file mode 100644 index 0bcdc76e..00000000 --- a/.eslintrc-examples.js +++ /dev/null @@ -1,15 +0,0 @@ -module.exports = { - ignorePatterns: ["examples/disabled_deno-prerecorded/index.js"], - root: true, - extends: ["eslint:recommended"], - parserOptions: { - ecmaVersion: 2020, - }, - env: { - node: true, - es6: true, - }, - rules: { - "no-unused-vars": ["error", { argsIgnorePattern: "^_" }], - }, -}; diff --git a/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 682da4f8..00000000 --- a/.eslintrc.js +++ /dev/null @@ -1,26 +0,0 @@ -// .eslintrc.js -module.exports = { - root: true, - parser: "@typescript-eslint/parser", - plugins: ["@typescript-eslint"], - extends: ["eslint:recommended", "plugin:@typescript-eslint/recommended"], - rules: { - // TODO: Enable these once we've fixed the issues - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-unsafe-function-type": "off", - - // Prevent Node.js built-in module imports without type-only - "no-restricted-imports": [ - "error", - { - patterns: [ - { - group: ["stream", "fs", "path", "crypto", "os", "child_process", "url", "util"], - message: - 'Node.js built-in modules should use type-only imports. Use: import type { ... } from "..."', - }, - ], - }, - ], - }, -}; diff --git a/.fernignore b/.fernignore new file mode 100644 index 00000000..084a8ebb --- /dev/null +++ b/.fernignore @@ -0,0 +1 @@ +# Specify files that shouldn't be modified by Fern diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 67b5e5f4..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,6 +0,0 @@ -# Global code owners - these users will be requested for review on all API SPEC PRs -# DX TEAM Members -* @lukeocodes - -# Future Reference: you can also specify owners for specific paths if needed: -# /src/ @username1 @username2 \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index e52c98d5..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Bug report -about: Something is occurring that I think is wrong -title: '' -labels: "\U0001F41B bug" -assignees: '' - ---- - -## What is the current behavior? - -> What's happening that seems wrong? - -## Steps to reproduce - -> To make it faster to diagnose the root problem. Tell us how can we reproduce the bug. - -## Expected behavior - -> What would you expect to happen when following the steps above? - -## Please tell us about your environment - -> We want to make sure the problem isn't specific to your operating system or programming language. - -- **Operating System/Version:** Windows 10 -- **Language:** [all | TypeScript | Python | PHP | etc] -- **Browser:** Chrome - -## Other information - -> Anything else we should know? (e.g. detailed explanation, stack-traces, related issues, suggestions how to fix, links for us to have context, eg. stack overflow, codepen, etc) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml deleted file mode 100644 index b19bf489..00000000 --- a/.github/ISSUE_TEMPLATE/config.yml +++ /dev/null @@ -1,6 +0,0 @@ -blank_issues_enabled: false -contact_links: - - name: Deepgram Developer Community - url: https://github.com/orgs/deepgram/discussions - - name: Deepgram on Twitter - url: https://twitter.com/DeepgramAI diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md deleted file mode 100644 index a0d6b36d..00000000 --- a/.github/ISSUE_TEMPLATE/feature-request.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -name: Feature Request -about: I think X would be a cool addition or change. -title: '' -labels: "✨ enhancement" -assignees: '' - ---- - -## Proposed changes - -> Provide a detailed description of the change or addition you are proposing - -## Context - -> Why is this change important to you? How would you use it? How can it benefit other users? - -## Possible Implementation - -> Not obligatory, but suggest an idea for implementing addition or change - -## Other information - -> Anything else we should know? (e.g. detailed explanation, related issues, links for us to have context, eg. stack overflow, codepen, etc) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 16753583..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,30 +0,0 @@ -## Proposed changes - - - -## Types of changes - -What types of changes does your code introduce to the community JavaScript SDK? -_Put an `x` in the boxes that apply_ - -- [ ] Bugfix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] Documentation update or tests (if none of the other choices apply) - -## Checklist - -_Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code._ - -- [ ] I have read the [CONTRIBUTING](../CONTRIBUTING.md) doc -- [ ] I have lint'ed all of my code using repo standards -- [ ] I have added tests that prove my fix is effective or that my feature works -- [ ] I have added necessary documentation (if appropriate) - -## Further comments - - diff --git a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md b/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md deleted file mode 100644 index 69f01d8c..00000000 --- a/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +++ /dev/null @@ -1,27 +0,0 @@ -## Proposed changes - -Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue. - -## Types of changes - -What types of changes does your code introduce to the Vonage for Visual Studio Code extension? -_Put an `x` in the boxes that apply_ - -- [ ] Bugfix (non-breaking change which fixes an issue) -- [ ] New feature (non-breaking change which adds functionality) -- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) -- [ ] Documentation update or tests (if none of the other choices apply) - -## Checklist - -_Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code._ - -- [ ] I have read the [CONTRIBUTING](../../CONTRIBUTING.md) doc -- [ ] Lint and unit tests pass locally with my changes -- [ ] I have added tests that prove my fix is effective or that my feature works -- [ ] I have added necessary documentation (if appropriate) -- [ ] Any dependent changes have been merged and published in downstream modules - -## Further comments - -If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml deleted file mode 100644 index c05a4de8..00000000 --- a/.github/workflows/CI.yml +++ /dev/null @@ -1,68 +0,0 @@ -name: CI - -on: - pull_request: - branches: - - main - - next - - rc - - beta - - alpha - paths-ignore: - - "docs/**" - - "**/*.md" - - ".prettierrc" - - "**/*ignore" - push: - branches: - - main - - next - - rc - - beta - - alpha - paths-ignore: - - "docs/**" - - "**/*.md" - - ".prettierrc" - - "**/*ignore" - -jobs: - test: - name: Test / OS ${{ matrix.os }} / Node ${{ matrix.node }} - strategy: - matrix: - os: [ubuntu-latest] - node: ["18", "22"] - - runs-on: ${{ matrix.os }} - - steps: - - uses: actions/checkout@v3 - - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: latest - - - name: Set up Node - uses: actions/setup-node@v3 - with: - node-version: ${{ matrix.node }} - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Lint files - run: pnpm run lint - - - name: Validate build - run: pnpm run build - - - name: Run tests - run: pnpm run test:coverage - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v3 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/browser-build-test.yml b/.github/workflows/browser-build-test.yml deleted file mode 100644 index 94f1d50d..00000000 --- a/.github/workflows/browser-build-test.yml +++ /dev/null @@ -1,74 +0,0 @@ -name: Browser Build Test - -on: - pull_request: - paths: - - "src/**" - - "package.json" - - "webpack.config.js" - - "tsconfig*.json" - workflow_dispatch: - -jobs: - browser-build-test: - name: Test Browser Builds - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: latest - - - name: Set up Node - uses: actions/setup-node@v3 - with: - node-version: 20 - cache: "pnpm" - - - name: Install dependencies - run: pnpm install --frozen-lockfile - - - name: Build library - run: pnpm run build - - - name: Test with Vite - run: | - cd /tmp - npm create vite@latest test-app -- --template react-ts -y - cd test-app - npm install - npm install $GITHUB_WORKSPACE - echo "import { createClient } from '@deepgram/sdk';" > src/test.ts - echo "const client = createClient('test-key');" >> src/test.ts - echo "console.log('Deepgram client created:', client);" >> src/test.ts - echo "export { client };" >> src/test.ts - npm run build - - - name: Test with Create React App - run: | - cd /tmp - npx create-react-app test-cra --template typescript - cd test-cra - npm install $GITHUB_WORKSPACE - echo "import { createClient } from '@deepgram/sdk';" > src/test.ts - echo "const client = createClient('test-key');" >> src/test.ts - echo "console.log('Deepgram client created:', client);" >> src/test.ts - echo "export { client };" >> src/test.ts - npm run build - - - name: Test with plain webpack - run: | - cd /tmp - mkdir webpack-test && cd webpack-test - npm init -y - npm install webpack webpack-cli typescript ts-loader - npm install $GITHUB_WORKSPACE - echo "import { createClient } from '@deepgram/sdk';" > index.ts - echo "const client = createClient('test-key');" >> index.ts - echo "console.log('Deepgram client created:', client);" >> index.ts - echo '{"compilerOptions": {"target": "es5", "module": "commonjs", "strict": true, "esModuleInterop": true, "skipLibCheck": true}}' > tsconfig.json - echo "module.exports = { entry: './index.ts', module: { rules: [{ test: /\.ts$/, use: 'ts-loader' }] }, resolve: { extensions: ['.ts', '.js'] } };" > webpack.config.js - npx webpack --mode production diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..7f884eea --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,30 @@ +name: ci + +on: [push] + +jobs: + compile: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set up node + uses: actions/setup-node@v3 + + - name: Compile + run: yarn && yarn build + + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Set up node + uses: actions/setup-node@v3 + + - name: Compile + run: yarn && yarn test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 00c4a235..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,41 +0,0 @@ -name: Release - -on: - push: - branches: - - main - - next - - rc - - beta - - alpha - workflow_dispatch: - -jobs: - release: - name: Release - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Install pnpm - uses: pnpm/action-setup@v2 - with: - version: latest - - - name: Set up Node - uses: actions/setup-node@v3 - with: - node-version-file: ".nvmrc" - cache: "pnpm" - - - name: Install dependencies and build - run: | - pnpm install --frozen-lockfile - pnpm run build - - - name: Create a release - run: pnpm dlx semantic-release - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.gitignore b/.gitignore index ea94053f..72271e04 100644 --- a/.gitignore +++ b/.gitignore @@ -1,107 +1,3 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* +node_modules .DS_Store - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage -*.lcov - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# TypeScript cache -*.tsbuildinfo - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Microbundle cache -.rpt2_cache/ -.rts2_cache_cjs/ -.rts2_cache_es/ -.rts2_cache_umd/ - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# dotenv environment variables file -.env -.env.test - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# Next.js build output -.next - -# Nuxt.js build / generate output -.nuxt -dist - -# Gatsby files -.cache/ -# Comment in the public line in if your project uses Gatsby and *not* Next.js -# https://nextjs.org/blog/next-9-1#public-directory-support -# public - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ - -# TernJS port file -.tern-port - -docs/v2 +/dist \ No newline at end of file diff --git a/.markdownlint.jsonc b/.markdownlint.jsonc deleted file mode 100644 index feb7e523..00000000 --- a/.markdownlint.jsonc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "default": true, - "line-length": false, - "no-bare-urls": false, - "no-duplicate-heading": false -} diff --git a/.npmignore b/.npmignore index e876efb8..383dd369 100644 --- a/.npmignore +++ b/.npmignore @@ -1,27 +1,10 @@ -*.log -npm-debug.log* - -# Coverage directory used by tools like istanbul -coverage -.nyc_output - -# Dependency directories node_modules - -# npm package lock -package-lock.json -yarn.lock - -# project files src -test -examples -example-next-js -umd_temp -CHANGELOG.md -.travis.yml -.editorconfig -.eslintignore -.eslintrc -.babelrc -.gitignore \ No newline at end of file +tests +.gitignore +.github +.fernignore +.prettierrc.yml +tsconfig.json +yarn.lock +pnpm-lock.yaml \ No newline at end of file diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 47ec7e17..00000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -node-options=--no-deprecation diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index 728f7de5..00000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -22.9.0 diff --git a/.prettierignore b/.prettierignore deleted file mode 100644 index 2c0e30b9..00000000 --- a/.prettierignore +++ /dev/null @@ -1,5 +0,0 @@ -.expo -.next -node_modules -package-lock.json -docker* \ No newline at end of file diff --git a/.prettierrc b/.prettierrc deleted file mode 100644 index 466e1ad4..00000000 --- a/.prettierrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "trailingComma": "es5", - "tabWidth": 2, - "printWidth": 100 -} diff --git a/.prettierrc.yml b/.prettierrc.yml new file mode 100644 index 00000000..0c06786b --- /dev/null +++ b/.prettierrc.yml @@ -0,0 +1,2 @@ +tabWidth: 4 +printWidth: 120 diff --git a/.releaserc.json b/.releaserc.json deleted file mode 100644 index 9ddd6c82..00000000 --- a/.releaserc.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "branches": [ - { "name": "main" }, - { "name": "next", "channel": "next", "prerelease": true }, - { "name": "rc", "channel": "rc", "prerelease": true }, - { "name": "beta", "channel": "beta", "prerelease": true }, - { "name": "alpha", "channel": "alpha", "prerelease": true } - ], - "plugins": [ - [ - "semantic-release-plugin-update-version-in-files", - { - "files": [ - "src/lib/version.ts", - "dist/main/lib/version.js", - "dist/main/lib/version.d.ts", - "dist/module/lib/version.js", - "dist/module/lib/version.d.ts", - "dist/umd/supabase.js" - ], - "placeholder": "0.0.0-automated" - } - ], - "@semantic-release/commit-analyzer", - "@semantic-release/release-notes-generator", - "@semantic-release/npm", - [ - "@semantic-release/github", - { - "successComment": false, - "releasedLabels": false, - "failTitle": false, - "addReleases": false - } - ] - ] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index bcadbc14..00000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "markdown.extension.toc.omittedFromToc": { - "README.md": ["# Deepgram JavaScript SDK"] - } -} diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index f30c4563..00000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,131 +0,0 @@ -# Code of Conduct - -The Deepgram developer community is filled with amazing, clever and creative people, and we're excited for you to join us. Our goal is to create safe and inclusive spaces, have meaningful conversations, and explore ways to make sure that every voice is heard and understood. - -## Being a Good Community Member - -Because we prioritize creating a safe space for our members, we believe in actively working on how we, as individuals, can ensure a positive community environment through our own actions and mindsets. - -Every supportive community starts with each member. We feel it’s important to be open to others, respectful, and supportive. As part of the Deepgram community, please begin by thinking carefully about and agreeing with the following statements: - -- I will be welcoming to everyone at the table; -- I will be patient and open to learning from everyone around me; -- I will treat everyone with respect, because they deserve it; -- I will be mindful of the needs and boundaries of others; - -We strive to create a space where we learn and grow together. Here are some other key things you can do to make the community great: - -### BE HUMBLE - -People come from all different places, and it’s best not to make assumptions about what they think or feel. Approach others with curiosity and openness. We **all** have a lot to learn from each other. - -### BE HELPFUL - -If someone asks for help, consider jumping in. You don’t have to be an expert to talk through a problem, suggest a resource, or help find a solution. We all have something to contribute. - -### ENCOURAGE OTHERS - -There’s no one path to have a career in technology or to this community. Let’s engage others in ways that create opportunities for learning and fun for all of us. - -## Our Pledge - -Everyone who participates in our community must agree to abide by our Code of Conduct. By agreeing, you help create a welcoming, respectful, and friendly community based on respect and trust. We are committed to creating a harassment-free community. - -These rules will be strictly enforced in any and all of our official spaces, including direct messages, social media, and physical and virtual events. Everyone who participates in these spaces is required to agree to this community code. We also ask and expect community members to observe these rules anywhere the community is meeting (for example, online chats on unofficial platforms or event after-parties). - -## Our Standards - -### BE RESPECTFUL - -Exercise consideration and respect in your speech and actions. Be willing to accept and give feedback gracefully. - -Don’t make offensive comments related to gender, gender identity and expression, sexual orientation, disability, mental illness, neuro(a)typicality, physical appearance, body size, race, ethnicity, immigration status, religion, experience level, socioeconomic status, nationality, or other identity markers. - -Additionally, don’t insult or demean others. This includes making unwelcome comments about a person’s lifestyle choices and practices, including things related to diet, health, parenting, drugs, or employment. It’s not okay to insult or demean others if it’s "just a joke." - -### BE WELCOMING AND OPEN - -Encourage others, be supportive and willing to listen, and be willing to learn from others’ perspectives and experiences. Lead with empathy and kindness. - -Don’t engage in gatekeeping behaviors, like questioning the intelligence or knowledge of others as a way to prove their credentials. And don’t exclude people for prejudicial reasons. - -### RESPECT PRIVACY - -Do not publish private communications without consent. Additionally, never disclose private aspects of a person’s personal identity without consent, except as necessary to protect them from intentional abuse. - -### RESPECT PERSONAL BOUNDARIES - -Do not introduce gratuitous or off-topic sexual images, languages, or behavior in spaces where they are not appropriate. Never make physical contact or simulated physical contact without consent or after a request to stop. Additionally, do not continue to message others about anything if they ask you to stop or leave them alone. - -#### BE A GOOD NEIGHBOR - -Contribute to the community in a positive and thoughtful way. Consider what’s best for the overall community. Do not make threats of violence, intimidate others, incite violence or intimidation against others, incite self-harm, stalk, follow, or otherwise harass others. Be mindful of your surroundings and of your fellow participants. - -Alert community leaders if you notice a dangerous situation, someone in distress, or violations of this Code of Conduct, even if they seem inconsequential. - -## Additional rules for online spaces - -For Deepgram’s official online spaces, like our YouTube & Twitch chats, we have some additional rules. Any of the following behaviors can result in a ban without warning. - -### DON'T SPAM - -Don't spam. We'll ban you. - -### KEEP IT LEGAL - -If it’s illegal, it’s not allowed on our websites or in our online spaces. Please don’t share links to pirated material or other nefarious things. - -### NO TROLLING - -Please be earnest. Don’t use excessive sarcasm to annoy or undermine other people. And don’t bait them with bad faith comments or abuse. - -### PORNOGRAPHY AND OTHER NSFW STUFF - -Please don’t post it or link to it. It doesn’t belong in our online spaces. - -### FOUL AND GRAPHIC LANGUAGE - -Please do not use excessive curse words. Additionally, do not use graphic sexual or violent language — again, think of our spaces as places for people of all ages. - -## Enforcement & Reporting - -If you are being harassed by a member of the Deepgram developer community, if you observe someone else being harassed, or you experience actions or behaviors that are contrary to our Code of Conduct, please report the behavior using our [Code of Conduct Report Form](https://developers.deepgram.com/code-of-conduct/report-form/). - -### Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this Code of Conduct: - -#### 1. Correction - -**_Community Impact:_** Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community. - -**_Consequence:_** A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested. - -#### 2. Warning - -**_Community Impact:_** A violation through a single incident or series of actions. - -**_Consequence:_** A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban. - -#### 3. Temporary Ban - -**_Community Impact:_** A serious violation of community standards, including sustained inappropriate behavior. - -**_Consequence:_** A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban. - -#### 4. Permanent Ban - -**_Community Impact:_** Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals. - -**_Consequence:_** A permanent ban from any sort of public interaction within the community. - -## Attribution - -This Code of Conduct is adapted from: - -- Contributor Covenant, version 2.0, available at https://www.contributor-covenant.org/version/2/0/code_of_conduct -- https://eventhandler.community/conduct/, which itself is inspired by Quest, who in turn provides credit to Scripto, the #botALLY Code of Conduct, the LGBTQ in Tech code of Conduct, and the XOXO Code of Conduct. - -Community Impact Guidelines, which were copied from InnerSource Commons, were inspired by Mozilla’s code of conduct enforcement ladder. - -For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index af130273..00000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,50 +0,0 @@ -# Contributing Guidelines - -Want to contribute to this project? We ❤️ it! - -Here are a few types of contributions that we would be interested in hearing about. - -- Bug fixes - - If you find a bug, please first report it using Github Issues. - - Issues that have already been identified as a bug will be labeled `🐛 bug`. - - If you'd like to submit a fix for a bug, send a Pull Request from your own fork and mention the Issue number. - - Include a test that isolates the bug and verifies that it was fixed. -- New Features - - If you'd like to accomplish something in the extension that it doesn't already do, describe the problem in a new Github Issue. - - Issues that have been identified as a feature request will be labeled `✨ enhancement`. - - If you'd like to implement the new feature, please wait for feedback from the project maintainers before spending - too much time writing the code. In some cases, `✨ enhancement`s may not align well with the project objectives at - the time. -- Tests, Documentation, Miscellaneous - - If you think the test coverage could be improved, the documentation could be clearer, you've got an alternative - implementation of something that may have more advantages, or any other change we would still be glad hear about - it. - - If its a trivial change, go ahead and send a Pull Request with the changes you have in mind - - If not, open a Github Issue to discuss the idea first. -- Snippets - - To add snippets: - - Add a directory in the `snippets` folder with the name of the language. - - Add one or more files in the language directory with snippets. - - Update the `package.json` to include the snippets you added. - -We also welcome anyone to work on any existing issues with the `👋🏽 good first issue` tag. - -## Requirements - -For a contribution to be accepted: - -- The test suite must be complete and pass -- Code must follow existing styling conventions -- Commit messages must be descriptive. Related issues should be mentioned by number. - -If the contribution doesn't meet these criteria, a maintainer will discuss it with you on the Issue. You can still -continue to add more commits to the branch you have sent the Pull Request from. - -## How To - -1. Fork this repository on GitHub. -1. Clone/fetch your fork to your local development machine. -1. Create a new branch (e.g. `issue-12`, `feat.add_foo`, etc) and check it out. -1. Make your changes and commit them. (Did the tests pass? No linting errors?) -1. Push your new branch to your fork. (e.g. `git push myname issue-12`) -1. Open a Pull Request from your new branch to the original fork's `main` branch. diff --git a/LICENSE b/LICENSE index 458cd0d3..853b289d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Deepgram +Copyright (c) 2025 Deepgram. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md index 80795d56..13ddea6c 100644 --- a/README.md +++ b/README.md @@ -1,102 +1,15 @@ -# Deepgram JavaScript SDK - -[![Static Badge](https://img.shields.io/badge/%24__-Discord-blue?logo=discord&logoColor=white&link=https%3A%2F%2Fdiscord.gg%2Fdeepgram)](https://discord.gg/deepgram) [![CI](https://github.com/deepgram/node-sdk/actions/workflows/CI.yml/badge.svg)](https://github.com/deepgram/node-sdk/actions/workflows/CI.yml) [![npm (scoped)](https://img.shields.io/npm/v/@deepgram/sdk)](https://www.npmjs.com/package/@deepgram/sdk) [![Contributor Covenant](https://img.shields.io/badge/Contributor%20Covenant-v2.0%20adopted-ff69b4.svg?style=flat-rounded)](CODE_OF_CONDUCT.md) - -> 🎯 **Development Setup**: This project uses [Corepack](https://nodejs.org/api/corepack.html) for package manager consistency. Run `corepack enable` once, then use `pnpm` commands normally. See [DEVELOPMENT.md](./DEVELOPMENT.md) for details. - - - -- [Documentation](#documentation) -- [Migrating from earlier versions](#migrating-from-earlier-versions) - - [V2 to V3](#v2-to-v3) - - [V3.\* to V3.4](#v3-to-v34) - - [V3.\* to V4](#v3-to-v4) -- [Installation](#installation) - - [UMD](#umd) - - [ESM](#esm) -- [Authentication](#authentication) - - [1. API Key Authentication (Recommended)](#1-api-key-authentication-recommended) - - [2. Access Token Authentication](#2-access-token-authentication) - - [3. Proxy Authentication](#3-proxy-authentication) - - [Getting Credentials](#getting-credentials) - - [API Keys](#api-keys) - - [Access Tokens](#access-tokens) - - [Environment Variables](#environment-variables) - - [Getting an API Key](#getting-an-api-key) -- [Scoped Configuration](#scoped-configuration) - - [Global Defaults](#global-defaults) - - [Namespace-specific Configurations](#namespace-specific-configurations) - - [Transport Options](#transport-options) - - [Examples](#examples) - - [Change the API url used for all SDK methods](#change-the-api-url-used-for-all-sdk-methods) - - [Change the API url used for the Voice Agent websocket](#change-the-api-url-used-for-the-voice-agent-websocket) - - [Change the API url used for transcription only](#change-the-api-url-used-for-transcription-only) - - [Override fetch transmitter](#override-fetch-transmitter) - - [Proxy requests in the browser](#proxy-requests-in-the-browser) - - [Set custom headers for fetch](#set-custom-headers-for-fetch) -- [Browser Usage](#browser-usage) -- [Transcription](#transcription) - - [Remote Files](#remote-files) - - [Local Files](#local-files) - - [Callbacks / Async](#callbacks--async) - - [Live Transcription (WebSocket)](#live-transcription-websocket) - - [Captions](#captions) -- [Voice Agent](#voice-agent) -- [Text to Speech](#text-to-speech) - - [Single-Request](#single-request) - - [Continuous Text Stream (WebSocket)](#continuous-text-stream-websocket) -- [Text Intelligence](#text-intelligence) -- [Token Management](#token-management) - - [Get Token Details](#get-token-details) - - [Grant Access Token](#grant-access-token) -- [Projects](#projects) - - [Get Projects](#get-projects) - - [Get Project](#get-project) - - [Update Project](#update-project) - - [Delete Project](#delete-project) -- [Keys](#keys) - - [List Keys](#list-keys) - - [Get Key](#get-key) - - [Create Key](#create-key) - - [Delete Key](#delete-key) -- [Members](#members) - - [Get Members](#get-members) - - [Remove Member](#remove-member) -- [Scopes](#scopes) - - [Get Member Scopes](#get-member-scopes) - - [Update Scope](#update-scope) -- [Invitations](#invitations) - - [List Invites](#list-invites) - - [Send Invite](#send-invite) - - [Delete Invite](#delete-invite) - - [Leave Project](#leave-project) -- [Usage](#usage) - - [Get All Requests](#get-all-requests) - - [Get Request](#get-request) - - [Summarize Usage](#summarize-usage) - - [Get Fields](#get-fields) - - [Summarize Usage (Deprecated)](#summarize-usage-1) -- [Billing](#billing) - - [Get All Balances](#get-all-balances) - - [Get Balance](#get-balance) -- [Models](#models) - - [Get All Models](#get-all-models) - - [Get All Project Models](#get-all-project-models) - - [Get Model](#get-model) -- [On-Prem APIs](#on-prem-apis) - - [List On-Prem credentials](#list-on-prem-credentials) - - [Get On-Prem credentials](#get-on-prem-credentials) - - [Create On-Prem credentials](#create-on-prem-credentials) - - [Delete On-Prem credentials](#delete-on-prem-credentials) -- [Backwards Compatibility](#backwards-compatibility) -- [Development and Contributing](#development-and-contributing) - - [Debugging and making changes locally](#debugging-and-making-changes-locally) -- [Getting Help](#getting-help) - +# Deepgram API TypeScript Library + +![](https://developers.deepgram.com) + +[![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Fdeepgram%2Fdeepgram-js-sdk) +[![npm shield](https://img.shields.io/npm/v/@deepgram/sdk)](https://www.npmjs.com/package/@deepgram/sdk) + +Power your apps with world-class speech and Language AI models ## Documentation -You can learn more about the Deepgram API at [developers.deepgram.com](https://developers.deepgram.com/docs). +API reference documentation is available [here](https://developers.deepgram.com/reference/deepgram-api-overview). ## Migrating from earlier versions @@ -114,62 +27,8 @@ The Voice Agent interfaces have been updated to use the new Voice Agent V1 API. ## Installation -You can install this SDK directly from [[npm](https://www.npmjs.com/package/@deepgram/sdk)](https://www.npmjs.com/package/@deepgram/sdk). - -```bash -npm install @deepgram/sdk -``` - -or - -```bash -pnpm install @deepgram/sdk -``` - -or - -```bash -yarn add @deepgram/sdk -``` - -### UMD - -You can now use plain ` -``` - -or even: - -```html - -``` - -Then you can use it from a global deepgram variable: - -```html - -``` - -### ESM - -You can now use type="module" ` +```sh +npm i -s @deepgram/sdk ``` ## Authentication @@ -215,7 +74,7 @@ For browser environments or custom proxy setups. Pass `"proxy"` as the API key. import { createClient } from "@deepgram/sdk"; const deepgramClient = createClient("proxy", { - global: { fetch: { options: { proxy: { url: "http://localhost:8080" } } } }, + global: { fetch: { options: { proxy: { url: "http://localhost:8080" } } } }, }); ``` @@ -229,8 +88,8 @@ Create API keys via the Management API: ```js const { result, error } = await deepgramClient.manage.createProjectKey(projectId, { - comment: "My API key", - scopes: ["usage:write"], + comment: "My API key", + scopes: ["usage:write"], }); ``` @@ -293,7 +152,7 @@ import { createClient } from "@deepgram/sdk"; // const { createClient } = require("@deepgram/sdk"); const deepgramClient = createClient(DEEPGRAM_API_KEY, { - global: { fetch: { options: { url: "https://api.beta.deepgram.com" } } }, + global: { fetch: { options: { url: "https://api.beta.deepgram.com" } } }, }); ``` @@ -307,7 +166,7 @@ import { createClient } from "@deepgram/sdk"; // const { createClient } = require("@deepgram/sdk"); const deepgramClient = createClient(DEEPGRAM_API_KEY, { - global: { websocket: { options: { url: "ws://localhost:8080" } } }, + global: { websocket: { options: { url: "ws://localhost:8080" } } }, }); ``` @@ -321,7 +180,7 @@ import { createClient } from "@deepgram/sdk"; // const { createClient } = require("@deepgram/sdk"); const deepgramClient = createClient(DEEPGRAM_API_KEY, { - listen: { fetch: { options: { url: "http://localhost:8080" } } }, + listen: { fetch: { options: { url: "http://localhost:8080" } } }, }); ``` @@ -335,11 +194,11 @@ import { createClient } from "@deepgram/sdk"; // const { createClient } = require("@deepgram/sdk"); const yourFetch = async () => { - return Response("...etc"); + return Response("...etc"); }; const deepgramClient = createClient(DEEPGRAM_API_KEY, { - global: { fetch: { client: yourFetch } }, + global: { fetch: { client: yourFetch } }, }); ``` @@ -351,7 +210,7 @@ This SDK now works in the browser. If you'd like to make REST-based requests (pr import { createClient } from "@deepgram/sdk"; const deepgramClient = createClient("proxy", { - global: { fetch: { options: { proxy: { url: "http://localhost:8080" } } } }, + global: { fetch: { options: { proxy: { url: "http://localhost:8080" } } } }, }); ``` @@ -369,7 +228,7 @@ Useful for many things. import { createClient } from "@deepgram/sdk"; const deepgramClient = createClient({ - global: { fetch: { options: { headers: { "x-custom-header": "foo" } } } }, + global: { fetch: { options: { headers: { "x-custom-header": "foo" } } } }, }); ``` @@ -396,8 +255,8 @@ The SDK works in modern browsers with some considerations: ```html ``` @@ -405,8 +264,8 @@ The SDK works in modern browsers with some considerations: ```html ``` @@ -422,11 +281,11 @@ Transcribe audio from a URL. ```js const { result, error } = await deepgramClient.listen.prerecorded.transcribeUrl( - { url: "https://dpgr.am/spacewalk.wav" }, - { - model: "nova-3", - // pre-recorded transcription options - } + { url: "https://dpgr.am/spacewalk.wav" }, + { + model: "nova-3", + // pre-recorded transcription options + }, ); ``` @@ -440,11 +299,11 @@ Transcribe audio from a file. ```js const { result, error } = await deepgramClient.listen.prerecorded.transcribeFile( - fs.createReadStream("./examples/spacewalk.wav"), - { - model: "nova-3", - // pre-recorded transcription options - } + fs.createReadStream("./examples/spacewalk.wav"), + { + model: "nova-3", + // pre-recorded transcription options + }, ); ``` @@ -460,12 +319,12 @@ We have a `Callback` version of both `transcribeFile` and `transcribeUrl`, which import { CallbackUrl } from "@deepgram/sdk"; const { result, error } = await deepgramClient.listen.prerecorded.transcribeUrlCallback( - { url: "https://dpgr.am/spacewalk.wav" }, - new CallbackUrl("http://callback/endpoint"), - { - model: "nova-3", - // pre-recorded transcription options - } + { url: "https://dpgr.am/spacewalk.wav" }, + new CallbackUrl("http://callback/endpoint"), + { + model: "nova-3", + // pre-recorded transcription options + }, ); ``` @@ -479,18 +338,18 @@ Connect to our websocket and transcribe live streaming audio. ```js const deepgramConnection = deepgramClient.listen.live({ - model: "nova-3", - // live transcription options + model: "nova-3", + // live transcription options }); deepgramConnection.on(LiveTranscriptionEvents.Open, () => { - deepgramConnection.on(LiveTranscriptionEvents.Transcript, (data) => { - console.log(data); - }); + deepgramConnection.on(LiveTranscriptionEvents.Transcript, (data) => { + console.log(data); + }); - source.addListener("got-some-audio", async (event) => { - deepgramConnection.send(event.raw_audio_data); - }); + source.addListener("got-some-audio", async (event) => { + deepgramConnection.send(event.raw_audio_data); + }); }); ``` @@ -506,8 +365,8 @@ Convert deepgram transcriptions to captions. import { webvtt, srt } from "@deepgram/sdk"; const { result, error } = await deepgramClient.listen.prerecorded.transcribeUrl({ - model: "nova-3", - // pre-recorded transcription options + model: "nova-3", + // pre-recorded transcription options }); const vttResult = webvtt(result); @@ -528,21 +387,21 @@ const deepgramConnection = deepgramClient.agent(); // Set up event handlers deepgramConnection.on(AgentEvents.Open, () => { - console.log("Connection opened"); + console.log("Connection opened"); - // Set up event handlers - deepgramConnection.on(AgentEvents.ConversationText, (data) => { - console.log(data); - }); + // Set up event handlers + deepgramConnection.on(AgentEvents.ConversationText, (data) => { + console.log(data); + }); - // other events + // other events - // Configure the agent once connection is established - deepgramConnection.configure({ - // agent configuration - }); + // Configure the agent once connection is established + deepgramConnection.configure({ + // agent configuration + }); - // etc... + // etc... }); ``` @@ -558,11 +417,11 @@ Convert text into speech using the REST API. ```js const { result } = await deepgramClient.speak.request( - { text }, - { - model: "aura-2-thalia-en", - // text to speech options - } + { text }, + { + model: "aura-2-thalia-en", + // text to speech options + }, ); ``` @@ -576,22 +435,22 @@ Connect to our websocket and send a continuous text stream to generate speech. ```js const deepgramConnection = deepgramClient.speak.live({ - model: "aura-2-thalia-en", - // live text to speech options + model: "aura-2-thalia-en", + // live text to speech options }); deepgramConnection.on(LiveTTSEvents.Open, () => { - console.log("Connection opened"); + console.log("Connection opened"); - // Send text data for TTS synthesis - deepgramConnection.sendText(text); + // Send text data for TTS synthesis + deepgramConnection.sendText(text); - // Send Flush message to the server after sending the text - deepgramConnection.flush(); + // Send Flush message to the server after sending the text + deepgramConnection.flush(); - deepgramConnection.on(LiveTTSEvents.Close, () => { - console.log("Connection closed"); - }); + deepgramConnection.on(LiveTTSEvents.Close, () => { + console.log("Connection closed"); + }); }); ``` @@ -609,11 +468,11 @@ lazy dog'. The earliest known appearance of the phrase was in The Boston Journal...`; const { result, error } = await deepgramClient.read.analyzeText( - { text }, - { - language: "en", - // text intelligence options - } + { text }, + { + language: "en", + // text intelligence options + }, ); ``` @@ -736,11 +595,11 @@ Creates an API key with the provided scopes. ```js const { result, error } = await deepgramClient.manage.createProjectKey(projectId, { - comment: "My API key", - scopes: ["usage:write"], // Required: array of scope strings - tags: ["production"], // Optional: array of tag strings - time_to_live_in_seconds: 86400, // Optional: TTL in seconds - // OR use expiration_date: "2024-12-31T23:59:59Z" // Optional: ISO date string + comment: "My API key", + scopes: ["usage:write"], // Required: array of scope strings + tags: ["production"], // Optional: array of tag strings + time_to_live_in_seconds: 86400, // Optional: TTL in seconds + // OR use expiration_date: "2024-12-31T23:59:59Z" // Optional: ISO date string }); ``` @@ -793,10 +652,7 @@ const { error } = await deepgramClient.manage.removeProjectMember(projectId, pro Retrieves scopes of the specified member in the specified project. ```js -const { result, error } = await deepgramClient.manage.getProjectMemberScopes( - projectId, - projectMemberId -); +const { result, error } = await deepgramClient.manage.getProjectMemberScopes(projectId, projectMemberId); ``` **API Endpoint**: `GET https://api.deepgram.com/v1/projects/:projectId/members/:memberId/scopes` @@ -808,11 +664,7 @@ const { result, error } = await deepgramClient.manage.getProjectMemberScopes( Updates the scope for the specified member in the specified project. ```js -const { result, error } = await deepgramClient.manage.updateProjectMemberScope( - projectId, - projectMemberId, - options -); +const { result, error } = await deepgramClient.manage.updateProjectMemberScope(projectId, projectMemberId, options); ``` **API Endpoint**: `PUT https://api.deepgram.com/v1/projects/:projectId/members/:memberId/scopes` @@ -869,66 +721,22 @@ const { result, error } = await deepgramClient.manage.leaveProject(projectId); [See our API reference for more info](https://developers.deepgram.com/reference/leave-project). -## Usage - -### Get All Requests - -Retrieves all requests associated with the provided project_id based on the provided options. - -```js -const { result, error } = await deepgramClient.manage.getProjectUsageRequests(projectId, options); -``` - -**API Endpoint**: `GET https://api.deepgram.com/v1/projects/:projectId/requests` - -### Get Request - -Retrieves a specific request associated with the provided project_id. - -```js -const { result, error } = await deepgramClient.manage.getProjectUsageRequest(projectId, requestId); -``` - -**API Endpoint**: `GET https://api.deepgram.com/v1/projects/:projectId/requests/:requestId` - -[See our API reference for more info](https://developers.deepgram.com/reference/get-request). - -### Summarize Usage - -Retrieves usage associated with the provided project_id based on the provided options. - -```js -const { result, error } = await deepgramClient.manage.getProjectUsageSummary(projectId, options); -``` - -**API Endpoint**: `GET https://api.deepgram.com/v1/projects/:projectId/usage` - -[See our API reference for more info](https://developers.deepgram.com/reference/summarize-usage). - -### Get Fields +## Reference -Lists the features, models, tags, languages, and processing method used for requests in the specified project. +A full reference for this library is available [here](https://github.com/deepgram/deepgram-js-sdk/blob/HEAD/./reference.md). -```js -const { result, error } = await deepgramClient.manage.getProjectUsageFields(projectId, options); -``` - -**API Endpoint**: `GET https://api.deepgram.com/v1/projects/:projectId/usage/fields` - -[See our API reference for more info](https://developers.deepgram.com/reference/get-fields). +## Usage -### Summarize Usage +Instantiate and use the client with the following: -`Deprecated` Retrieves the usage for a specific project. Use Get Project Usage Breakdown for a more comprehensive usage summary. +```typescript +import { createReadStream } from "fs"; +import { DeepgramClient } from "@deepgram/sdk"; -```js -const { result, error } = await deepgramClient.manage.getProjectUsage(projectId, options); +const client = new DeepgramClient({ apiKey: "YOUR_API_KEY" }); +await client.listen.v1.media.transcribeFile(createReadStream("path/to/file"), {}); ``` -**API Endpoint**: `GET https://api.deepgram.com/v1/projects/:projectId/usage` (deprecated) - -[See our API reference for more info](https://developers.deepgram.com/reference/management-api/usage/get). - ## Billing ### Get All Balances @@ -1065,3 +873,589 @@ project, let us know! You can either: - [Open an issue in this repository](https://github.com/deepgram/deepgram-node-sdk/issues/new) - [Join the Deepgram Discord Community](https://discord.gg/xWRaCDBtW4) - [Join the Deepgram Github Discussions Community](https://github.com/orgs/deepgram/discussions) + +## Request And Response Types + +The SDK exports all request and response types as TypeScript interfaces. Simply import them with the +following namespace: + +```typescript +import { Deepgram } from "@deepgram/sdk"; + +const request: Deepgram.GrantV1Request = { + ... +}; +``` + +## Exception Handling + +When the API returns a non-success status code (4xx or 5xx response), a subclass of the following error +will be thrown. + +```typescript +import { DeepgramError } from "@deepgram/sdk"; + +try { + await client.listen.v1.media.transcribeFile(...); +} catch (err) { + if (err instanceof DeepgramError) { + console.log(err.statusCode); + console.log(err.message); + console.log(err.body); + console.log(err.rawResponse); + } +} +``` + +## File Uploads + +You can upload files using the client: + +```typescript +import { createReadStream } from "fs"; + +await client.listen.v1.media.transcribeFile(createReadStream("path/to/file"), ...); +await client.listen.v1.media.transcribeFile(new ReadableStream(), ...); +await client.listen.v1.media.transcribeFile(Buffer.from('binary data'), ...); +await client.listen.v1.media.transcribeFile(new Blob(['binary data'], { type: 'audio/mpeg' }), ...); +await client.listen.v1.media.transcribeFile(new File(['binary data'], 'file.mp3'), ...); +await client.listen.v1.media.transcribeFile(new ArrayBuffer(8), ...); +await client.listen.v1.media.transcribeFile(new Uint8Array([0, 1, 2]), ...); +``` + +The client accepts a variety of types for file upload parameters: + +- Stream types: `fs.ReadStream`, `stream.Readable`, and `ReadableStream` +- Buffered types: `Buffer`, `Blob`, `File`, `ArrayBuffer`, `ArrayBufferView`, and `Uint8Array` + +### Metadata + +You can configure metadata when uploading a file: + +```typescript +const file: Uploadable.WithMetadata = { + data: createReadStream("path/to/file"), + filename: "my-file", // optional + contentType: "audio/mpeg", // optional + contentLength: 1949, // optional +}; +``` + +Alternatively, you can upload a file directly from a file path: + +```typescript +const file: Uploadable.FromPath = { + path: "path/to/file", + filename: "my-file", // optional + contentType: "audio/mpeg", // optional + contentLength: 1949, // optional +}; +``` + +The metadata is used to set the `Content-Length`, `Content-Type`, and `Content-Disposition` headers. If not provided, the client will attempt to determine them automatically. +For example, `fs.ReadStream` has a `path` property which the SDK uses to retrieve the file size from the filesystem without loading it into memory. + +## Binary Response + +You can consume binary data from endpoints using the `BinaryResponse` type which lets you choose how to consume the data: + +```typescript +const response = await client.speak.v1.audio.generate(...); +const stream: ReadableStream = response.stream(); +// const arrayBuffer: ArrayBuffer = await response.arrayBuffer(); +// const blob: Blob = response.blob(); +// const bytes: Uint8Array = response.bytes(); +// You can only use the response body once, so you must choose one of the above methods. +// If you want to check if the response body has been used, you can use the following property. +const bodyUsed = response.bodyUsed; +``` + +
+Save binary response to a file + +
+
+Node.js + +
+
+ReadableStream (most-efficient) + +```ts +import { createWriteStream } from 'fs'; +import { Readable } from 'stream'; +import { pipeline } from 'stream/promises'; + +const response = await client.speak.v1.audio.generate(...); + +const stream = response.stream(); +const nodeStream = Readable.fromWeb(stream); +const writeStream = createWriteStream('path/to/file'); + +await pipeline(nodeStream, writeStream); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +import { writeFile } from 'fs/promises'; + +const response = await client.speak.v1.audio.generate(...); + +const arrayBuffer = await response.arrayBuffer(); +await writeFile('path/to/file', Buffer.from(arrayBuffer)); +``` + +
+
+ +
+
+Blob + +```ts +import { writeFile } from 'fs/promises'; + +const response = await client.speak.v1.audio.generate(...); + +const blob = await response.blob(); +const arrayBuffer = await blob.arrayBuffer(); +await writeFile('output.bin', Buffer.from(arrayBuffer)); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +import { writeFile } from 'fs/promises'; + +const response = await client.speak.v1.audio.generate(...); + +const bytes = await response.bytes(); +await writeFile('path/to/file', bytes); +``` + +
+
+ +
+
+ +
+
+Bun + +
+
+ReadableStream (most-efficient) + +```ts +const response = await client.speak.v1.audio.generate(...); + +const stream = response.stream(); +await Bun.write('path/to/file', stream); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.speak.v1.audio.generate(...); + +const arrayBuffer = await response.arrayBuffer(); +await Bun.write('path/to/file', arrayBuffer); +``` + +
+
+ +
+
+Blob + +```ts +const response = await client.speak.v1.audio.generate(...); + +const blob = await response.blob(); +await Bun.write('path/to/file', blob); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.speak.v1.audio.generate(...); + +const bytes = await response.bytes(); +await Bun.write('path/to/file', bytes); +``` + +
+
+ +
+
+ +
+
+Deno + +
+
+ReadableStream (most-efficient) + +```ts +const response = await client.speak.v1.audio.generate(...); + +const stream = response.stream(); +const file = await Deno.open('path/to/file', { write: true, create: true }); +await stream.pipeTo(file.writable); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.speak.v1.audio.generate(...); + +const arrayBuffer = await response.arrayBuffer(); +await Deno.writeFile('path/to/file', new Uint8Array(arrayBuffer)); +``` + +
+
+ +
+
+Blob + +```ts +const response = await client.speak.v1.audio.generate(...); + +const blob = await response.blob(); +const arrayBuffer = await blob.arrayBuffer(); +await Deno.writeFile('path/to/file', new Uint8Array(arrayBuffer)); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.speak.v1.audio.generate(...); + +const bytes = await response.bytes(); +await Deno.writeFile('path/to/file', bytes); +``` + +
+
+ +
+
+ +
+
+Browser + +
+
+Blob (most-efficient) + +```ts +const response = await client.speak.v1.audio.generate(...); + +const blob = await response.blob(); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+ReadableStream + +```ts +const response = await client.speak.v1.audio.generate(...); + +const stream = response.stream(); +const reader = stream.getReader(); +const chunks = []; + +while (true) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); +} + +const blob = new Blob(chunks); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.speak.v1.audio.generate(...); + +const arrayBuffer = await response.arrayBuffer(); +const blob = new Blob([arrayBuffer]); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.speak.v1.audio.generate(...); + +const bytes = await response.bytes(); +const blob = new Blob([bytes]); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+ +
+ + +
+Convert binary response to text + +
+
+ReadableStream + +```ts +const response = await client.speak.v1.audio.generate(...); + +const stream = response.stream(); +const text = await new Response(stream).text(); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.speak.v1.audio.generate(...); + +const arrayBuffer = await response.arrayBuffer(); +const text = new TextDecoder().decode(arrayBuffer); +``` + +
+
+ +
+
+Blob + +```ts +const response = await client.speak.v1.audio.generate(...); + +const blob = await response.blob(); +const text = await blob.text(); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.speak.v1.audio.generate(...); + +const bytes = await response.bytes(); +const text = new TextDecoder().decode(bytes); +``` + +
+
+ +
+ +## Advanced + +### Additional Headers + +If you would like to send additional headers as part of the request, use the `headers` request option. + +```typescript +const response = await client.listen.v1.media.transcribeFile(..., { + headers: { + 'X-Custom-Header': 'custom value' + } +}); +``` + +### Additional Query String Parameters + +If you would like to send additional query string parameters as part of the request, use the `queryParams` request option. + +```typescript +const response = await client.listen.v1.media.transcribeFile(..., { + queryParams: { + 'customQueryParamKey': 'custom query param value' + } +}); +``` + +### Retries + +The SDK is instrumented with automatic retries with exponential backoff. A request will be retried as long +as the request is deemed retryable and the number of retry attempts has not grown larger than the configured +retry limit (default: 2). + +A request is deemed retryable when any of the following HTTP status codes is returned: + +- [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout) +- [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests) +- [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors) + +Use the `maxRetries` request option to configure this behavior. + +```typescript +const response = await client.listen.v1.media.transcribeFile(..., { + maxRetries: 0 // override maxRetries at the request level +}); +``` + +### Timeouts + +The SDK defaults to a 60 second timeout. Use the `timeoutInSeconds` option to configure this behavior. + +```typescript +const response = await client.listen.v1.media.transcribeFile(..., { + timeoutInSeconds: 30 // override timeout to 30s +}); +``` + +### Aborting Requests + +The SDK allows users to abort requests at any point by passing in an abort signal. + +```typescript +const controller = new AbortController(); +const response = await client.listen.v1.media.transcribeFile(..., { + abortSignal: controller.signal +}); +controller.abort(); // aborts the request +``` + +### Access Raw Response Data + +The SDK provides access to raw response data, including headers, through the `.withRawResponse()` method. +The `.withRawResponse()` method returns a promise that results to an object with a `data` and a `rawResponse` property. + +```typescript +const { data, rawResponse } = await client.listen.v1.media.transcribeFile(...).withRawResponse(); + +console.log(data); +console.log(rawResponse.headers['X-My-Header']); +``` + +### Runtime Compatibility + +The SDK works in the following runtimes: + +- Node.js 18+ +- Vercel +- Cloudflare Workers +- Deno v1.25+ +- Bun 1.0+ +- React Native + +### Customizing Fetch Client + +The SDK provides a way for you to customize the underlying HTTP client / Fetch function. If you're running in an +unsupported environment, this provides a way for you to break glass and ensure the SDK works. + +```typescript +import { DeepgramClient } from "@deepgram/sdk"; + +const client = new DeepgramClient({ + ... + fetcher: // provide your implementation here +}); +``` + +## Contributing + +While we value open-source contributions to this SDK, this library is generated programmatically. +Additions made directly to this library would have to be moved over to our generation code, +otherwise they would be overwritten upon the next generated release. Feel free to open a PR as +a proof of concept, but know that we will not be able to merge it as-is. We suggest opening +an issue first to discuss with us! + +On the other hand, contributions to the README are always very welcome! diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index a8e6c01b..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,20 +0,0 @@ -# Security Policy - -## Supported Versions - -Use this section to tell people about which versions of your project are -currently being supported with security updates. - -| Version | Supported | -| ------- | ------------------ | -| 3.3.x | :white_check_mark: | -| 2.4.x | :white_check_mark: | -| < 2.4.x | :x: | - -## Reporting a Vulnerability - -Use this section to tell people how to report a vulnerability. - -Tell them where to go, how often they can expect to get an update on a -reported vulnerability, what to expect if the vulnerability is accepted or -declined, etc. diff --git a/commitlint.config.js b/commitlint.config.js deleted file mode 100644 index 5073c20d..00000000 --- a/commitlint.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = { extends: ["@commitlint/config-conventional"] }; diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index 186389a2..00000000 --- a/examples/README.md +++ /dev/null @@ -1,15 +0,0 @@ -# Examples - -This directory contains examples for using the Deepgram JS SDK. - -## Setup - -First, build the SDK from the root of the project: - -```bash -pnpm run build -``` - -## Running the Examples - -Each example has its own `README.md` with instructions on how to run it. Be sure to add your Deepgram API key to the example file before running it. diff --git a/examples/browser-live/README.md b/examples/browser-live/README.md deleted file mode 100644 index d95026f5..00000000 --- a/examples/browser-live/README.md +++ /dev/null @@ -1,23 +0,0 @@ -# Live Transcription (Browser) - -This example demonstrates how to transcribe a live audio stream in the browser using the Deepgram JS SDK. - -## Setup - -1. From the root of the project, start a local web server: - - ```bash - npx http-server . - ``` - -2. Open your browser to the following URL: - - [http://localhost:8080/examples/browser-live/](http://localhost:8080/examples/browser-live/) - -3. Add your `DEEPGRAM_API_KEY` as a query string parameter to the URL. - - For example: `http://localhost:8080/examples/browser-live/?key=YOUR_DEEPGRAM_API_KEY` - -## Usage - -Once the page is loaded with your API key, you can use the "Start" and "Stop" buttons to control the live transcription. diff --git a/examples/browser-live/index.html b/examples/browser-live/index.html deleted file mode 100644 index 886d380f..00000000 --- a/examples/browser-live/index.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - Deepgram Live Transcription - - - -

Live Transcription

- - -

-
-    
-    
-  
-
diff --git a/examples/browser-prerecorded/README.md b/examples/browser-prerecorded/README.md
deleted file mode 100644
index 0a65688d..00000000
--- a/examples/browser-prerecorded/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# Prerecorded Transcription (Browser)
-
-This example demonstrates how to transcribe a prerecorded audio file in the browser using the Deepgram JS SDK.
-
-## Setup
-
-1.  From the root of the project, start a local web server:
-
-    ```bash
-    npx http-server .
-    ```
-
-2.  Open your browser to the following URL:
-
-    [http://localhost:8080/examples/browser-prerecorded/](http://localhost:8080/examples/browser-prerecorded/)
-
-3.  Add your `DEEPGRAM_API_KEY` as a query string parameter to the URL.
-
-    For example: `http://localhost:8080/examples/browser-prerecorded/?key=YOUR_DEEPGRAM_API_KEY`
-
-## Usage
-
-Once the page is loaded with your API key, you can click the "Transcribe" button to see the transcription results in the console.
diff --git a/examples/browser-prerecorded/index.html b/examples/browser-prerecorded/index.html
deleted file mode 100644
index 268d373f..00000000
--- a/examples/browser-prerecorded/index.html
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-  
-    Deepgram Prerecorded Transcription
-  
-
-  
-    

Prerecorded Transcription

-

Open the console to see the transcription results.

- - - - - - diff --git a/examples/nasa.mp4 b/examples/nasa.mp4 deleted file mode 100644 index 021dd52a..00000000 Binary files a/examples/nasa.mp4 and /dev/null differ diff --git a/examples/node-agent-live/.gitignore b/examples/node-agent-live/.gitignore deleted file mode 100644 index e2278d77..00000000 --- a/examples/node-agent-live/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -chatlog.txt -output-*.wav -node_modules -.env diff --git a/examples/node-agent-live/README.md b/examples/node-agent-live/README.md deleted file mode 100644 index 8cb2ad03..00000000 --- a/examples/node-agent-live/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Live Agent - -This example demonstrates how to use the Deepgram JS SDK to interact with a live agent. - -## Setup - -1. Make sure you have a `.env` file with your `DEEPGRAM_API_KEY`. -2. Install the dependencies: - - ```bash - pnpm install - ``` - -## Usage - -Run the example with the following command: - -```bash -pnpm start -``` diff --git a/examples/node-agent-live/index.js b/examples/node-agent-live/index.js deleted file mode 100644 index e93aa141..00000000 --- a/examples/node-agent-live/index.js +++ /dev/null @@ -1,131 +0,0 @@ -/* eslint-env node */ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, no-console */ - -const { createClient, AgentEvents } = require("../../dist/main/index"); -const fetch = require("cross-fetch"); -require("dotenv").config(); - -console.log("🔑 API Key loaded successfully"); - -const agent = async () => { - // Checks for API key - if (!process.env.DEEPGRAM_API_KEY) { - console.error("❌ Error: DEEPGRAM_API_KEY environment variable is required"); - console.log("💡 Run with: DEEPGRAM_API_KEY=your_api_key_here npm start"); - process.exit(1); - } - - console.log("🚀 Starting Deepgram Agent Live example..."); - const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - - console.log("📞 Connecting to Deepgram Agent API..."); - const connection = deepgram.agent(); - - // Error handler - connection.on(AgentEvents.Error, (error) => { - if (error.code === 'CLIENT_MESSAGE_TIMEOUT') { - console.log("⏰ Agent session timed out"); - } else { - console.error("❌ Agent error:", error.description || error.message); - } - }); - - connection.on(AgentEvents.Open, () => { - console.log("✅ Connected to Deepgram Agent"); - console.log("⚙️ Configuring agent with tags and providers..."); - - const config = { - // Agent tags for filtered searching and analytics - tags: ["live-agent-test", "nodejs-example"], - agent: { - listen: { - provider: { - type: "deepgram", - model: "nova-3" - } - }, - speak: { - provider: { - type: "deepgram", - model: "aura-asteria-en" - } - }, - greeting: "Hello! I'm a Deepgram voice agent. How can I help you today?" - }, - }; - - connection.configure(config); - }); - - connection.on(AgentEvents.SettingsApplied, () => { - console.log("⚙️ Agent configuration applied successfully"); - console.log("🏷️ Tags:", ["live-agent-test", "nodejs-example"]); - console.log("🎵 Starting 15-second audio demo..."); - startAudioStream(); - }); - - function startAudioStream() { - fetch("http://stream.live.vc.bbcmedia.co.uk/bbc_world_service") - .then((r) => r.body) - .then((res) => { - console.log("🔊 Streaming live audio to agent..."); - - let isStreamActive = true; - - // Stop stream after 15 seconds - setTimeout(() => { - isStreamActive = false; - res.destroy(); - console.log("⏹️ Audio stream stopped after 15 seconds"); - console.log("🎯 Agent tags demo completed successfully!"); - console.log("📊 Tags used: ['live-agent-test', 'nodejs-example']"); - - // Close connection after a brief delay - setTimeout(() => { - connection.disconnect(); - }, 2000); - }, 15000); - - res.on("readable", () => { - if (!isStreamActive) return; - - const chunk = res.read(); - if (chunk) { - connection.send(chunk); - } - }); - - res.on("error", (error) => { - if (isStreamActive) { - console.error("❌ Audio stream error:", error); - } - }); - }) - .catch((error) => { - console.error("❌ Failed to fetch audio stream:", error); - }); - } - - // Agent conversation events - connection.on(AgentEvents.ConversationText, (data) => { - console.log(`💬 ${data.role}: ${data.content}`); - }); - - connection.on(AgentEvents.UserStartedSpeaking, () => { - console.log("🎤 User speaking detected"); - }); - - connection.on(AgentEvents.AgentThinking, () => { - console.log("🤔 Agent processing..."); - }); - - connection.on(AgentEvents.AgentStartedSpeaking, () => { - console.log("🗨️ Agent responding"); - }); - - connection.on(AgentEvents.Close, () => { - console.log("👋 Agent session ended"); - }); -}; - -agent(); diff --git a/examples/node-agent-live/package.json b/examples/node-agent-live/package.json deleted file mode 100644 index 147ddb98..00000000 --- a/examples/node-agent-live/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "deepgram-node-agent-live-example", - "version": "1.0.0", - "description": "A simple example of using the Deepgram JS SDK to interact with a live agent in Node.js.", - "main": "index.js", - "scripts": { - "start": "node index.js" - }, - "dependencies": { - "dotenv": "^16.3.1" - } -} diff --git a/examples/node-live-token/.gitignore b/examples/node-live-token/.gitignore deleted file mode 100644 index 37d7e734..00000000 --- a/examples/node-live-token/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.env diff --git a/examples/node-live-token/README.md b/examples/node-live-token/README.md deleted file mode 100644 index 81c0ff31..00000000 --- a/examples/node-live-token/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Live Transcription with a Temporary Token - -This example demonstrates how to transcribe a live audio stream using a temporary token with the Deepgram JS SDK. - -## Setup - -1. Make sure you have a `.env` file with your `DEEPGRAM_API_KEY` to generate the token. -2. Install the dependencies: - - ```bash - pnpm install - ``` - -## Usage - -Run the example with the following command: - -```bash -pnpm start -``` diff --git a/examples/node-live-token/index.js b/examples/node-live-token/index.js deleted file mode 100644 index a784e20b..00000000 --- a/examples/node-live-token/index.js +++ /dev/null @@ -1,57 +0,0 @@ -/* eslint-env node */ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, no-console */ - -const { createClient, LiveTranscriptionEvents } = require("../../dist/main/index"); -const fetch = require("cross-fetch"); -require("dotenv").config(); - -const live = async () => { - const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - - // First, generate a temporary token with 60 second TTL - console.log("🔍 Requesting token with ttl_seconds: 60"); - const { result: token, error } = await deepgram.auth.grantToken({ - ttl_seconds: 60, - }); - - if (error) { - console.error("❌ Failed to generate token:", error); - return; - } - - // Log successful token generation - console.log("✅ Token generated successfully!"); - console.log(` • Expires in: ${token.expires_in} seconds`); - console.log(` • Token preview: ${token.access_token.substring(0, 20)}...`); - console.log(""); - - // Now, use the temporary token to create a new client - // Note: Must use 'accessToken' property, not 'key' - const deepgramWithToken = createClient({ accessToken: token.access_token }); - console.log("✅ Client created with temporary token - ready for live transcription!"); - const connection = deepgramWithToken.listen.live({ - model: "nova-3", - }); - - connection.on(LiveTranscriptionEvents.Open, () => { - console.log("Connection opened."); - - fetch("http://stream.live.vc.bbcmedia.co.uk/bbc_world_service") - .then((r) => r.body) - .then((res) => { - res.on("readable", () => { - connection.send(res.read()); - }); - }); - - connection.on(LiveTranscriptionEvents.Transcript, (data) => { - console.log(data.channel.alternatives[0].transcript); - }); - - connection.on(LiveTranscriptionEvents.Close, () => { - console.log("Connection closed."); - }); - }); -}; - -live(); diff --git a/examples/node-live-token/package.json b/examples/node-live-token/package.json deleted file mode 100644 index 952ad7bb..00000000 --- a/examples/node-live-token/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "deepgram-node-live-token-example", - "version": "1.0.0", - "description": "A simple example of using a temporary token to transcribe a live audio stream in Node.js.", - "main": "index.js", - "scripts": { - "start": "node index.js" - }, - "dependencies": { - "dotenv": "^16.3.1" - } -} diff --git a/examples/node-live/.gitignore b/examples/node-live/.gitignore deleted file mode 100644 index 37d7e734..00000000 --- a/examples/node-live/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.env diff --git a/examples/node-live/README.md b/examples/node-live/README.md deleted file mode 100644 index 1b75efcd..00000000 --- a/examples/node-live/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Live Transcription - -This example demonstrates how to transcribe a live audio stream using the Deepgram JS SDK. - -## Setup - -1. Make sure you have a `.env` file with your `DEEPGRAM_API_KEY`. -2. Install the dependencies: - - ```bash - pnpm install - ``` - -## Usage - -Run the example with the following command: - -```bash -pnpm start -``` diff --git a/examples/node-live/index.js b/examples/node-live/index.js deleted file mode 100644 index 64087563..00000000 --- a/examples/node-live/index.js +++ /dev/null @@ -1,35 +0,0 @@ -/* eslint-env node */ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, no-console */ - -const { createClient, LiveTranscriptionEvents } = require("../../dist/main/index"); -const fetch = require("cross-fetch"); -require("dotenv").config(); - -const live = async () => { - const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - const connection = deepgram.listen.live({ - model: "nova-3", - }); - - connection.on(LiveTranscriptionEvents.Open, () => { - console.log("Connection opened."); - - fetch("http://stream.live.vc.bbcmedia.co.uk/bbc_world_service") - .then((r) => r.body) - .then((res) => { - res.on("readable", () => { - connection.send(res.read()); - }); - }); - - connection.on(LiveTranscriptionEvents.Transcript, (data) => { - console.log(data.channel.alternatives[0].transcript); - }); - - connection.on(LiveTranscriptionEvents.Close, () => { - console.log("Connection closed."); - }); - }); -}; - -live(); diff --git a/examples/node-live/package.json b/examples/node-live/package.json deleted file mode 100644 index e0205c30..00000000 --- a/examples/node-live/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "deepgram-node-live-example", - "version": "1.0.0", - "description": "A simple example of using the Deepgram JS SDK to transcribe a live audio stream in Node.js.", - "main": "index.js", - "scripts": { - "start": "node index.js" - }, - "dependencies": { - "dotenv": "^16.3.1" - } -} diff --git a/examples/node-prerecorded/.gitignore b/examples/node-prerecorded/.gitignore deleted file mode 100644 index 37d7e734..00000000 --- a/examples/node-prerecorded/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.env diff --git a/examples/node-prerecorded/README.md b/examples/node-prerecorded/README.md deleted file mode 100644 index 48d96033..00000000 --- a/examples/node-prerecorded/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Prerecorded Transcription - -This example demonstrates how to transcribe a prerecorded audio file using the Deepgram JS SDK. - -## Setup - -1. Make sure you have a `.env` file with your `DEEPGRAM_API_KEY`. -2. Install the dependencies: - - ```bash - pnpm install - ``` - -## Usage - -Run the example with the following command: - -```bash -pnpm start -``` diff --git a/examples/node-prerecorded/index.js b/examples/node-prerecorded/index.js deleted file mode 100644 index aeb5ac5a..00000000 --- a/examples/node-prerecorded/index.js +++ /dev/null @@ -1,120 +0,0 @@ -/* eslint-env node */ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, no-console */ - -const { createClient } = require("../../dist/main/index"); -const { readFileSync } = require("fs"); -const { resolve } = require("path"); -require("dotenv").config(); - -const transcribeUrlAuthWithFactory = async () => { - console.log("transcribing url with auth factory"); - - const authFactory = async () => { - const deepgramTokenClient = createClient(process.env.DEEPGRAM_API_KEY); - - const { result: tokenResult, error: tokenError } = await deepgramTokenClient.auth.grantToken(); - - if (tokenError) console.error(tokenError); - if (!tokenError) return tokenResult.access_token; - }; - - const deepgramClient = createClient({ accessToken: authFactory }); - - console.log("Transcribing URL", "https://dpgr.am/spacewalk.wav"); - const { result, error } = await deepgramClient.listen.prerecorded.transcribeUrl( - { - url: "https://dpgr.am/spacewalk.wav", - }, - { - model: "nova-3", - } - ); - - if (error) console.error(error); - if (!error) console.dir(result, { depth: 1 }); -}; - -const transcribeUrlWithAccessToken = async () => { - console.log("transcribing url with access token"); - - const deepgramTokenClient = createClient(process.env.DEEPGRAM_API_KEY); - - const { result: tokenResult, error: tokenError } = await deepgramTokenClient.auth.grantToken(); - - if (tokenError) console.error(tokenError); - - const deepgramClient = createClient({ accessToken: tokenResult.access_token }); - - console.log("Transcribing URL", "https://dpgr.am/spacewalk.wav"); - const { result, error } = await deepgramClient.listen.prerecorded.transcribeUrl( - { - url: "https://dpgr.am/spacewalk.wav", - }, - { - model: "nova-3", - } - ); - - if (error) console.error(error); - if (!error) console.dir(result, { depth: 1 }); -}; - -const transcribeUrl = async () => { - console.log("transcribing url with api key"); - - const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - - console.log("Transcribing URL", "https://dpgr.am/spacewalk.wav"); - const { result, error } = await deepgram.listen.prerecorded.transcribeUrl( - { - url: "https://dpgr.am/spacewalk.wav", - }, - { - model: "nova-3", - } - ); - - if (error) console.error(error); - if (!error) console.dir(result, { depth: 1 }); -}; - -const transcribeFile = async () => { - console.log("transcribing file with api key"); - - const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - - const filePath = resolve(__dirname, "../spacewalk.wav"); - console.log(filePath); - const file = readFileSync(filePath); - - console.log("Transcribing file", file); - const { result, error } = await deepgram.listen.prerecorded.transcribeFile(file, { - model: "nova-3", - }); - - if (error) console.error(error); - if (!error) console.dir(result, { depth: 1 }); -}; - -const transcribe = async () => { - const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - const audio = readFileSync(resolve(__dirname, "../spacewalk.wav")); - - const { result, error } = await deepgram.listen.prerecorded.transcribeFile(audio, { - model: "nova-3", - }); - - if (error) { - console.error(error); - } else { - console.log(result.results.channels[0].alternatives[0].transcript); - } -}; - -(async () => { - await transcribeUrl(); - await transcribeFile(); - await transcribeUrlAuthWithFactory(); - await transcribeUrlWithAccessToken(); - await transcribe(); -})(); diff --git a/examples/node-prerecorded/package.json b/examples/node-prerecorded/package.json deleted file mode 100644 index f04ae89f..00000000 --- a/examples/node-prerecorded/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "deepgram-node-prerecorded-example", - "version": "1.0.0", - "description": "A simple example of using the Deepgram JS SDK to transcribe a prerecorded audio file in Node.js.", - "main": "index.js", - "scripts": { - "start": "node index.js" - }, - "dependencies": { - "dotenv": "^16.3.1" - } -} diff --git a/examples/node-read/.gitignore b/examples/node-read/.gitignore deleted file mode 100644 index 37d7e734..00000000 --- a/examples/node-read/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -.env diff --git a/examples/node-read/README.md b/examples/node-read/README.md deleted file mode 100644 index 9d9519d2..00000000 --- a/examples/node-read/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Read (Text Analysis) - -This example demonstrates how to analyze text using the Deepgram JS SDK. - -## Setup - -1. Make sure you have a `.env` file with your `DEEPGRAM_API_KEY`. -2. Install the dependencies: - - ```bash - pnpm install - ``` - -## Usage - -Run the example with the following command: - -```bash -pnpm start -``` diff --git a/examples/node-read/index.js b/examples/node-read/index.js deleted file mode 100644 index 78eca5a9..00000000 --- a/examples/node-read/index.js +++ /dev/null @@ -1,25 +0,0 @@ -/* eslint-env node */ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, no-console */ - -const { createClient } = require("../../dist/main/index"); -require("dotenv").config(); - -const analyze = async () => { - const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - const text = "Hello, world!"; - - const { result, error } = await deepgram.read.analyzeText( - { text }, - { - model: "nova-3", - } - ); - - if (error) { - console.error(error); - } else { - console.dir(result, { depth: null }); - } -}; - -analyze(); diff --git a/examples/node-read/package.json b/examples/node-read/package.json deleted file mode 100644 index 2bf05686..00000000 --- a/examples/node-read/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "deepgram-node-read-example", - "version": "1.0.0", - "description": "A simple example of using the Deepgram JS SDK to analyze text in Node.js.", - "main": "index.js", - "scripts": { - "start": "node index.js" - }, - "dependencies": { - "dotenv": "^16.3.1" - } -} diff --git a/examples/node-speak-live/.gitignore b/examples/node-speak-live/.gitignore deleted file mode 100644 index 7444d06a..00000000 --- a/examples/node-speak-live/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -.env -output.mp3 diff --git a/examples/node-speak-live/README.md b/examples/node-speak-live/README.md deleted file mode 100644 index 9bbdeafd..00000000 --- a/examples/node-speak-live/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Live Speak (Text-to-Speech) - -This example demonstrates how to synthesize speech from a live text stream using the Deepgram JS SDK. - -## Setup - -1. Make sure you have a `.env` file with your `DEEPGRAM_API_KEY`. -2. Install the dependencies: - - ```bash - pnpm install - ``` - -## Usage - -Run the example with the following command: - -```bash -pnpm start -``` diff --git a/examples/node-speak-live/index.js b/examples/node-speak-live/index.js deleted file mode 100644 index a19e0690..00000000 --- a/examples/node-speak-live/index.js +++ /dev/null @@ -1,38 +0,0 @@ -/* eslint-env node */ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, no-console */ - -const { createClient, LiveTTSEvents } = require("../../dist/main/index"); -const { writeFileSync } = require("fs"); -const { resolve } = require("path"); -require("dotenv").config(); - -const speak = async () => { - const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - const connection = deepgram.speak.live({ - model: "aura-asteria-en", - }); - - const audioChunks = []; - - connection.on(LiveTTSEvents.Open, () => { - console.log("Connection opened."); - connection.sendText("Hello, world! This is a live text-to-speech test."); - connection.sendText("This is a second sentence."); - connection.finish(); - }); - - connection.on(LiveTTSEvents.Audio, (audio) => { - console.log("Received audio chunk."); - audioChunks.push(audio); - }); - - connection.on(LiveTTSEvents.Close, () => { - console.log("Connection closed."); - const buffer = Buffer.concat(audioChunks); - const filePath = resolve(__dirname, "output.mp3"); - writeFileSync(filePath, buffer); - console.log(`Audio file saved to ${filePath}`); - }); -}; - -speak(); diff --git a/examples/node-speak-live/package.json b/examples/node-speak-live/package.json deleted file mode 100644 index 23ada3f6..00000000 --- a/examples/node-speak-live/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "deepgram-node-speak-live-example", - "version": "1.0.0", - "description": "A simple example of using the Deepgram JS SDK to synthesize speech from a live text stream in Node.js.", - "main": "index.js", - "scripts": { - "start": "node index.js" - }, - "dependencies": { - "dotenv": "^16.3.1" - } -} diff --git a/examples/node-speak/.gitignore b/examples/node-speak/.gitignore deleted file mode 100644 index 7444d06a..00000000 --- a/examples/node-speak/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -node_modules -.env -output.mp3 diff --git a/examples/node-speak/README.md b/examples/node-speak/README.md deleted file mode 100644 index e009a4d8..00000000 --- a/examples/node-speak/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Speak (Text-to-Speech) - -This example demonstrates how to synthesize speech from text using the Deepgram JS SDK. - -## Setup - -1. Make sure you have a `.env` file with your `DEEPGRAM_API_KEY`. -2. Install the dependencies: - - ```bash - pnpm install - ``` - -## Usage - -Run the example with the following command: - -```bash -pnpm start -``` diff --git a/examples/node-speak/index.js b/examples/node-speak/index.js deleted file mode 100644 index fea1211a..00000000 --- a/examples/node-speak/index.js +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-env node */ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports, no-console */ - -const { createClient } = require("../../dist/main/index"); -const { writeFileSync } = require("fs"); -const { resolve } = require("path"); -require("dotenv").config(); - -const speak = async () => { - const deepgram = createClient(process.env.DEEPGRAM_API_KEY); - const text = "Hello, world! This is a test of the Deepgram JS SDK."; - - const response = await deepgram.speak.request( - { text }, - { - model: "aura-asteria-en", - } - ); - - const stream = await response.getStream(); - const headers = await response.getHeaders(); - - if (stream) { - const buffer = await new Promise((resolve, reject) => { - const chunks = []; - stream.on("data", (chunk) => chunks.push(chunk)); - stream.on("end", () => resolve(Buffer.concat(chunks))); - stream.on("error", reject); - }); - - const filePath = resolve(__dirname, "output.mp3"); - writeFileSync(filePath, buffer); - console.log(`Audio file saved to ${filePath}`); - } else { - console.error("Error: Could not get audio stream."); - } - - if (headers) { - console.log("Headers:", headers); - } -}; - -speak(); diff --git a/examples/node-speak/package.json b/examples/node-speak/package.json deleted file mode 100644 index eec5d6a6..00000000 --- a/examples/node-speak/package.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "name": "deepgram-node-speak-example", - "version": "1.0.0", - "description": "A simple example of using the Deepgram JS SDK to synthesize speech in Node.js.", - "main": "index.js", - "scripts": { - "start": "node index.js" - }, - "dependencies": { - "dotenv": "^16.3.1" - } -} diff --git a/examples/spacewalk.wav b/examples/spacewalk.wav deleted file mode 100644 index 498be744..00000000 Binary files a/examples/spacewalk.wav and /dev/null differ diff --git a/jest.config.js b/jest.config.js deleted file mode 100644 index 3f2adae4..00000000 --- a/jest.config.js +++ /dev/null @@ -1,53 +0,0 @@ -/** @type {import('jest').Config} */ -/* eslint-env node */ -module.exports = { - preset: "ts-jest", - testEnvironment: "node", - - // Test file patterns - testMatch: ["/tests/**/*.test.ts", "/tests/**/*.spec.ts"], - - // Module path mapping - moduleNameMapper: { - "^@/(.*)$": "/src/$1", - "^@deepgram/sdk$": "/src/index.ts", - }, - - // Setup files - setupFilesAfterEnv: ["/tests/setup.ts"], - - // Coverage configuration - collectCoverageFrom: [ - "src/**/*.ts", - "!src/**/*.d.ts", - "!src/**/index.ts", - "!src/**/__tests__/**", - "!src/**/__mocks__/**", - ], - - coverageDirectory: "coverage", - coverageReporters: ["text", "lcov", "html", "json"], - - // Test timeout - testTimeout: 10000, - - // Transform configuration - transform: { - "^.+\\.ts$": [ - "ts-jest", - { - tsconfig: "tsconfig.json", - }, - ], - }, - - // Module file extensions - moduleFileExtensions: ["ts", "js", "json"], - - // Clear mocks between tests - clearMocks: true, - restoreMocks: true, - - // Detect open handles to identify resource leaks - detectOpenHandles: true, -}; diff --git a/jest.config.mjs b/jest.config.mjs new file mode 100644 index 00000000..b6927007 --- /dev/null +++ b/jest.config.mjs @@ -0,0 +1,42 @@ +/** @type {import('jest').Config} */ +export default { + preset: "ts-jest", + testEnvironment: "node", + projects: [ + { + displayName: "unit", + preset: "ts-jest", + testEnvironment: "node", + moduleNameMapper: { + "^(\.{1,2}/.*)\.js$": "$1", + }, + roots: ["/tests"], + testPathIgnorePatterns: ["\.browser\.(spec|test)\.[jt]sx?$", "/tests/wire/"], + setupFilesAfterEnv: [], + }, + { + displayName: "browser", + preset: "ts-jest", + testEnvironment: "/tests/BrowserTestEnvironment.ts", + moduleNameMapper: { + "^(\.{1,2}/.*)\.js$": "$1", + }, + roots: ["/tests"], + testMatch: ["/tests/unit/**/?(*.)+(browser).(spec|test).[jt]s?(x)"], + setupFilesAfterEnv: [], + }, + , + { + displayName: "wire", + preset: "ts-jest", + testEnvironment: "node", + moduleNameMapper: { + "^(\.{1,2}/.*)\.js$": "$1", + }, + roots: ["/tests/wire"], + setupFilesAfterEnv: ["/tests/mock-server/setup.ts"], + }, + ], + workerThreads: false, + passWithNoTests: true, +}; diff --git a/package.json b/package.json index 07a760ec..eb848ed1 100644 --- a/package.json +++ b/package.json @@ -1,117 +1,66 @@ { - "name": "@deepgram/sdk", - "version": "0.0.0-automated", - "description": "Isomorphic Javascript client for Deepgram", - "keywords": [ - "javascript", - "typescript", - "deepgram", - "asr", - "speech", - "sdk" - ], - "packageManager": "pnpm@10.12.1", - "homepage": "https://github.com/deepgram/deepgram-js-sdk", - "bugs": "https://github.com/deepgram/deepgram-js-sdk/issues", - "license": "MIT", - "author": { - "name": "Deepgram DevRel Team", - "email": "devrel@deepgram.com" - }, - "contributors": [ - "Brian Barrow", - "Brian Hillis", - "Luke Oliff", - "Michael Jolley", - "Sandra Rodgers", - "Shir Goldberg" - ], - "files": [ - "dist", - "src" - ], - "engines": { - "node": ">=18.0.0" - }, - "main": "dist/main/index.js", - "module": "dist/module/index.js", - "types": "dist/module/index.d.ts", - "sideEffects": false, - "repository": "deepgram/deepgram-js-sdk", - "scripts": { - "clean": "rimraf dist docs/v2", - "format": "prettier --write \"src/**/*.ts\"", - "build": "run-s clean format build:*", - "build:main": "tsc -p tsconfig.json", - "build:module": "tsc -p tsconfig.module.json", - "build:umd": "webpack --mode=production", - "lint": "run-s lint:*", - "lint:js": "eslint -c .eslintrc-examples.js examples --max-warnings 0", - "lint:md": "markdownlint **/*.md *.md", - "lint:yml": "yamllint .github/workflows", - "lint:ts": "eslint src --max-warnings 0", - "watch": "nodemon -e ts --watch src --exec \"npm run build\"", - "docs": "typedoc --entryPoints src/index.ts --out docs/ --includes src/packages/**/*.ts --emit none", - "docs:json": "typedoc --entryPoints src/index.ts --includes src/packages/**/*.ts --json docs/spec.json --emit none", - "test": "jest", - "test:unit": "jest --testPathPattern=tests/unit", - "test:e2e": "jest --testPathPattern=tests/e2e", - "test:e2e:offline": "node scripts/test-offline.js", - "test:watch": "jest --watch", - "test:coverage": "jest --coverage", - "test:ci": "jest --ci --coverage --watchAll=false" - }, - "dependencies": { - "@deepgram/captions": "^1.1.1", - "@types/node": "^18.19.39", - "cross-fetch": "^3.1.5", - "deepmerge": "^4.3.1", - "events": "^3.3.0", - "ws": "^8.17.0" - }, - "devDependencies": { - "@commitlint/cli": "^17.6.7", - "@commitlint/config-conventional": "^17.6.7", - "@types/jest": "^29.5.12", - "@types/ws": "^8.5.10", - "@typescript-eslint/eslint-plugin": "^8.7.0", - "@typescript-eslint/parser": "^8.7.0", - "buffer": "^6.0.3", - "cross-env": "^7.0.3", - "dotenv": "^16.5.0", - "eslint": "^8.57.1", - "husky": "^4.3.0", - "jest": "^29.7.0", - "jest-environment-jsdom": "^29.7.0", - "markdownlint": "^0.35.0", - "markdownlint-cli": "^0.42.0", - "nodemon": "^3.0.1", - "npm-run-all": "^4.1.5", - "prettier": "^2.5.1", - "pretty-quick": "^3.1.3", - "rimraf": "^3.0.2", - "semantic-release-plugin-update-version-in-files": "^1.1.0", - "stream-browserify": "^3.0.0", - "ts-jest": "^29.1.2", - "ts-loader": "^8.0.11", - "ts-node": "^10.9.1", - "typedoc": "^0.22.16", - "typescript": "^4.5.5", - "url": "^0.11.4", - "util": "^0.12.5", - "webpack": "^5.69.1", - "webpack-cli": "^4.9.2", - "yaml-lint": "^1.7.0" - }, - "overrides": { - "es5-ext": "0.10.53" - }, - "husky": { - "hooks": { - "pre-commit": "pretty-quick --staged", - "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" - } - }, - "jsdelivr": "dist/umd/deepgram.js", - "unpkg": "dist/umd/deepgram.js" + "name": "@deepgram/sdk", + "version": "4.11.3", + "private": false, + "repository": "github:deepgram/deepgram-js-sdk", + "license": "MIT", + "type": "commonjs", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.mjs", + "types": "./dist/cjs/index.d.ts", + "exports": { + ".": { + "types": "./dist/cjs/index.d.ts", + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + }, + "default": "./dist/cjs/index.js" + }, + "./package.json": "./package.json" + }, + "files": [ + "dist", + "reference.md", + "README.md", + "LICENSE" + ], + "scripts": { + "format": "prettier . --write --ignore-unknown", + "build": "yarn build:cjs && yarn build:esm", + "build:cjs": "tsc --project ./tsconfig.cjs.json", + "build:esm": "tsc --project ./tsconfig.esm.json && node scripts/rename-to-esm-files.js dist/esm", + "test": "jest --config jest.config.mjs", + "test:unit": "jest --selectProjects unit", + "test:browser": "jest --selectProjects browser", + "test:wire": "jest --selectProjects wire" + }, + "devDependencies": { + "webpack": "^5.97.1", + "ts-loader": "^9.5.1", + "jest": "^29.7.0", + "@jest/globals": "^29.7.0", + "@types/jest": "^29.5.14", + "ts-jest": "^29.3.4", + "jest-environment-jsdom": "^29.7.0", + "msw": "^2.8.4", + "@types/node": "^18.19.70", + "prettier": "^3.4.2", + "typescript": "~5.7.2" + }, + "browser": { + "fs": false, + "os": false, + "path": false, + "stream": false + }, + "packageManager": "yarn@1.22.22", + "engines": { + "node": ">=18.0.0" + }, + "sideEffects": false } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index e021df84..00000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,9769 +0,0 @@ -lockfileVersion: "9.0" - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -importers: - .: - dependencies: - "@deepgram/captions": - specifier: ^1.1.1 - version: 1.2.0 - "@types/node": - specifier: ^18.19.39 - version: 18.19.112 - cross-fetch: - specifier: ^3.1.5 - version: 3.2.0 - deepmerge: - specifier: ^4.3.1 - version: 4.3.1 - events: - specifier: ^3.3.0 - version: 3.3.0 - ws: - specifier: ^8.17.0 - version: 8.18.2 - devDependencies: - "@commitlint/cli": - specifier: ^17.6.7 - version: 17.8.1 - "@commitlint/config-conventional": - specifier: ^17.6.7 - version: 17.8.1 - "@types/jest": - specifier: ^29.5.12 - version: 29.5.14 - "@types/ws": - specifier: ^8.5.10 - version: 8.18.1 - "@typescript-eslint/eslint-plugin": - specifier: ^8.7.0 - version: 8.34.0(@typescript-eslint/parser@8.34.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) - "@typescript-eslint/parser": - specifier: ^8.7.0 - version: 8.34.0(eslint@8.57.1)(typescript@4.9.5) - buffer: - specifier: ^6.0.3 - version: 6.0.3 - cross-env: - specifier: ^7.0.3 - version: 7.0.3 - dotenv: - specifier: ^16.5.0 - version: 16.5.0 - eslint: - specifier: ^8.57.1 - version: 8.57.1 - husky: - specifier: ^4.3.0 - version: 4.3.8 - jest: - specifier: ^29.7.0 - version: 29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)) - jest-environment-jsdom: - specifier: ^29.7.0 - version: 29.7.0 - markdownlint: - specifier: ^0.35.0 - version: 0.35.0 - markdownlint-cli: - specifier: ^0.42.0 - version: 0.42.0 - nodemon: - specifier: ^3.0.1 - version: 3.1.10 - npm-run-all: - specifier: ^4.1.5 - version: 4.1.5 - prettier: - specifier: ^2.5.1 - version: 2.8.8 - pretty-quick: - specifier: ^3.1.3 - version: 3.3.1(prettier@2.8.8) - rimraf: - specifier: ^3.0.2 - version: 3.0.2 - semantic-release-plugin-update-version-in-files: - specifier: ^1.1.0 - version: 1.1.0 - stream-browserify: - specifier: ^3.0.0 - version: 3.0.0 - ts-jest: - specifier: ^29.1.2 - version: 29.4.0(@babel/core@7.27.4)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.4))(jest-util@29.7.0)(jest@29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)))(typescript@4.9.5) - ts-loader: - specifier: ^8.0.11 - version: 8.4.0(typescript@4.9.5)(webpack@5.99.9) - ts-node: - specifier: ^10.9.1 - version: 10.9.2(@types/node@18.19.112)(typescript@4.9.5) - typedoc: - specifier: ^0.22.16 - version: 0.22.18(typescript@4.9.5) - typescript: - specifier: ^4.5.5 - version: 4.9.5 - url: - specifier: ^0.11.4 - version: 0.11.4 - util: - specifier: ^0.12.5 - version: 0.12.5 - webpack: - specifier: ^5.69.1 - version: 5.99.9(webpack-cli@4.10.0) - webpack-cli: - specifier: ^4.9.2 - version: 4.10.0(webpack@5.99.9) - yaml-lint: - specifier: ^1.7.0 - version: 1.7.0 - -packages: - "@ampproject/remapping@2.3.0": - resolution: - { - integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==, - } - engines: { node: ">=6.0.0" } - - "@babel/code-frame@7.27.1": - resolution: - { - integrity: sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==, - } - engines: { node: ">=6.9.0" } - - "@babel/compat-data@7.27.5": - resolution: - { - integrity: sha512-KiRAp/VoJaWkkte84TvUd9qjdbZAdiqyvMxrGl1N6vzFogKmaLgoM3L1kgtLicp2HP5fBJS8JrZKLVIZGVJAVg==, - } - engines: { node: ">=6.9.0" } - - "@babel/core@7.27.4": - resolution: - { - integrity: sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==, - } - engines: { node: ">=6.9.0" } - - "@babel/generator@7.27.5": - resolution: - { - integrity: sha512-ZGhA37l0e/g2s1Cnzdix0O3aLYm66eF8aufiVteOgnwxgnRP8GoyMj7VWsgWnQbVKXyge7hqrFh2K2TQM6t1Hw==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-compilation-targets@7.27.2": - resolution: - { - integrity: sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-module-imports@7.27.1": - resolution: - { - integrity: sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-module-transforms@7.27.3": - resolution: - { - integrity: sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0 - - "@babel/helper-plugin-utils@7.27.1": - resolution: - { - integrity: sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-string-parser@7.27.1": - resolution: - { - integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-validator-identifier@7.27.1": - resolution: - { - integrity: sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==, - } - engines: { node: ">=6.9.0" } - - "@babel/helper-validator-option@7.27.1": - resolution: - { - integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==, - } - engines: { node: ">=6.9.0" } - - "@babel/helpers@7.27.6": - resolution: - { - integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==, - } - engines: { node: ">=6.9.0" } - - "@babel/parser@7.27.5": - resolution: - { - integrity: sha512-OsQd175SxWkGlzbny8J3K8TnnDD0N3lrIUtB92xwyRpzaenGZhxDvxN/JgU00U3CDZNj9tPuDJ5H0WS4Nt3vKg==, - } - engines: { node: ">=6.0.0" } - hasBin: true - - "@babel/plugin-syntax-async-generators@7.8.4": - resolution: - { - integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-bigint@7.8.3": - resolution: - { - integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-class-properties@7.12.13": - resolution: - { - integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-class-static-block@7.14.5": - resolution: - { - integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-import-attributes@7.27.1": - resolution: - { - integrity: sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-import-meta@7.10.4": - resolution: - { - integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-json-strings@7.8.3": - resolution: - { - integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-jsx@7.27.1": - resolution: - { - integrity: sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-logical-assignment-operators@7.10.4": - resolution: - { - integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3": - resolution: - { - integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-numeric-separator@7.10.4": - resolution: - { - integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-object-rest-spread@7.8.3": - resolution: - { - integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-optional-catch-binding@7.8.3": - resolution: - { - integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-optional-chaining@7.8.3": - resolution: - { - integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==, - } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-private-property-in-object@7.14.5": - resolution: - { - integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-top-level-await@7.14.5": - resolution: - { - integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/plugin-syntax-typescript@7.27.1": - resolution: - { - integrity: sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==, - } - engines: { node: ">=6.9.0" } - peerDependencies: - "@babel/core": ^7.0.0-0 - - "@babel/template@7.27.2": - resolution: - { - integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==, - } - engines: { node: ">=6.9.0" } - - "@babel/traverse@7.27.4": - resolution: - { - integrity: sha512-oNcu2QbHqts9BtOWJosOVJapWjBDSxGCpFvikNR5TGDYDQf3JwpIoMzIKrvfoti93cLfPJEG4tH9SPVeyCGgdA==, - } - engines: { node: ">=6.9.0" } - - "@babel/types@7.27.6": - resolution: - { - integrity: sha512-ETyHEk2VHHvl9b9jZP5IHPavHYk57EhanlRRuae9XCpb/j5bDCbPPMOBfCWhnl/7EDJz0jEMCi/RhccCE8r1+Q==, - } - engines: { node: ">=6.9.0" } - - "@bcoe/v8-coverage@0.2.3": - resolution: - { - integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==, - } - - "@commitlint/cli@17.8.1": - resolution: - { - integrity: sha512-ay+WbzQesE0Rv4EQKfNbSMiJJ12KdKTDzIt0tcK4k11FdsWmtwP0Kp1NWMOUswfIWo6Eb7p7Ln721Nx9FLNBjg==, - } - engines: { node: ">=v14" } - hasBin: true - - "@commitlint/config-conventional@17.8.1": - resolution: - { - integrity: sha512-NxCOHx1kgneig3VLauWJcDWS40DVjg7nKOpBEEK9E5fjJpQqLCilcnKkIIjdBH98kEO1q3NpE5NSrZ2kl/QGJg==, - } - engines: { node: ">=v14" } - - "@commitlint/config-validator@17.8.1": - resolution: - { - integrity: sha512-UUgUC+sNiiMwkyiuIFR7JG2cfd9t/7MV8VB4TZ+q02ZFkHoduUS4tJGsCBWvBOGD9Btev6IecPMvlWUfJorkEA==, - } - engines: { node: ">=v14" } - - "@commitlint/ensure@17.8.1": - resolution: - { - integrity: sha512-xjafwKxid8s1K23NFpL8JNo6JnY/ysetKo8kegVM7c8vs+kWLP8VrQq+NbhgVlmCojhEDbzQKp4eRXSjVOGsow==, - } - engines: { node: ">=v14" } - - "@commitlint/execute-rule@17.8.1": - resolution: - { - integrity: sha512-JHVupQeSdNI6xzA9SqMF+p/JjrHTcrJdI02PwesQIDCIGUrv04hicJgCcws5nzaoZbROapPs0s6zeVHoxpMwFQ==, - } - engines: { node: ">=v14" } - - "@commitlint/format@17.8.1": - resolution: - { - integrity: sha512-f3oMTyZ84M9ht7fb93wbCKmWxO5/kKSbwuYvS867duVomoOsgrgljkGGIztmT/srZnaiGbaK8+Wf8Ik2tSr5eg==, - } - engines: { node: ">=v14" } - - "@commitlint/is-ignored@17.8.1": - resolution: - { - integrity: sha512-UshMi4Ltb4ZlNn4F7WtSEugFDZmctzFpmbqvpyxD3la510J+PLcnyhf9chs7EryaRFJMdAKwsEKfNK0jL/QM4g==, - } - engines: { node: ">=v14" } - - "@commitlint/lint@17.8.1": - resolution: - { - integrity: sha512-aQUlwIR1/VMv2D4GXSk7PfL5hIaFSfy6hSHV94O8Y27T5q+DlDEgd/cZ4KmVI+MWKzFfCTiTuWqjfRSfdRllCA==, - } - engines: { node: ">=v14" } - - "@commitlint/load@17.8.1": - resolution: - { - integrity: sha512-iF4CL7KDFstP1kpVUkT8K2Wl17h2yx9VaR1ztTc8vzByWWcbO/WaKwxsnCOqow9tVAlzPfo1ywk9m2oJ9ucMqA==, - } - engines: { node: ">=v14" } - - "@commitlint/message@17.8.1": - resolution: - { - integrity: sha512-6bYL1GUQsD6bLhTH3QQty8pVFoETfFQlMn2Nzmz3AOLqRVfNNtXBaSY0dhZ0dM6A2MEq4+2d7L/2LP8TjqGRkA==, - } - engines: { node: ">=v14" } - - "@commitlint/parse@17.8.1": - resolution: - { - integrity: sha512-/wLUickTo0rNpQgWwLPavTm7WbwkZoBy3X8PpkUmlSmQJyWQTj0m6bDjiykMaDt41qcUbfeFfaCvXfiR4EGnfw==, - } - engines: { node: ">=v14" } - - "@commitlint/read@17.8.1": - resolution: - { - integrity: sha512-Fd55Oaz9irzBESPCdMd8vWWgxsW3OWR99wOntBDHgf9h7Y6OOHjWEdS9Xzen1GFndqgyoaFplQS5y7KZe0kO2w==, - } - engines: { node: ">=v14" } - - "@commitlint/resolve-extends@17.8.1": - resolution: - { - integrity: sha512-W/ryRoQ0TSVXqJrx5SGkaYuAaE/BUontL1j1HsKckvM6e5ZaG0M9126zcwL6peKSuIetJi7E87PRQF8O86EW0Q==, - } - engines: { node: ">=v14" } - - "@commitlint/rules@17.8.1": - resolution: - { - integrity: sha512-2b7OdVbN7MTAt9U0vKOYKCDsOvESVXxQmrvuVUZ0rGFMCrCPJWWP1GJ7f0lAypbDAhaGb8zqtdOr47192LBrIA==, - } - engines: { node: ">=v14" } - - "@commitlint/to-lines@17.8.1": - resolution: - { - integrity: sha512-LE0jb8CuR/mj6xJyrIk8VLz03OEzXFgLdivBytoooKO5xLt5yalc8Ma5guTWobw998sbR3ogDd+2jed03CFmJA==, - } - engines: { node: ">=v14" } - - "@commitlint/top-level@17.8.1": - resolution: - { - integrity: sha512-l6+Z6rrNf5p333SHfEte6r+WkOxGlWK4bLuZKbtf/2TXRN+qhrvn1XE63VhD8Oe9oIHQ7F7W1nG2k/TJFhx2yA==, - } - engines: { node: ">=v14" } - - "@commitlint/types@17.8.1": - resolution: - { - integrity: sha512-PXDQXkAmiMEG162Bqdh9ChML/GJZo6vU+7F03ALKDK8zYc6SuAr47LjG7hGYRqUOz+WK0dU7bQ0xzuqFMdxzeQ==, - } - engines: { node: ">=v14" } - - "@cspotcode/source-map-support@0.8.1": - resolution: - { - integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==, - } - engines: { node: ">=12" } - - "@deepgram/captions@1.2.0": - resolution: - { - integrity: sha512-8B1C/oTxTxyHlSFubAhNRgCbQ2SQ5wwvtlByn8sDYZvdDtdn/VE2yEPZ4BvUnrKWmsbTQY6/ooLV+9Ka2qmDSQ==, - } - engines: { node: ">=18.0.0" } - - "@discoveryjs/json-ext@0.5.7": - resolution: - { - integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==, - } - engines: { node: ">=10.0.0" } - - "@eslint-community/eslint-utils@4.7.0": - resolution: - { - integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 - - "@eslint-community/regexpp@4.12.1": - resolution: - { - integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==, - } - engines: { node: ^12.0.0 || ^14.0.0 || >=16.0.0 } - - "@eslint/eslintrc@2.1.4": - resolution: - { - integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - - "@eslint/js@8.57.1": - resolution: - { - integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - - "@humanwhocodes/config-array@0.13.0": - resolution: - { - integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==, - } - engines: { node: ">=10.10.0" } - deprecated: Use @eslint/config-array instead - - "@humanwhocodes/module-importer@1.0.1": - resolution: - { - integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==, - } - engines: { node: ">=12.22" } - - "@humanwhocodes/object-schema@2.0.3": - resolution: - { - integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==, - } - deprecated: Use @eslint/object-schema instead - - "@isaacs/balanced-match@4.0.1": - resolution: - { - integrity: sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==, - } - engines: { node: 20 || >=22 } - - "@isaacs/brace-expansion@5.0.0": - resolution: - { - integrity: sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==, - } - engines: { node: 20 || >=22 } - - "@isaacs/cliui@8.0.2": - resolution: - { - integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==, - } - engines: { node: ">=12" } - - "@istanbuljs/load-nyc-config@1.1.0": - resolution: - { - integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==, - } - engines: { node: ">=8" } - - "@istanbuljs/schema@0.1.3": - resolution: - { - integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==, - } - engines: { node: ">=8" } - - "@jest/console@29.7.0": - resolution: - { - integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/core@29.7.0": - resolution: - { - integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - "@jest/environment@29.7.0": - resolution: - { - integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/expect-utils@29.7.0": - resolution: - { - integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/expect@29.7.0": - resolution: - { - integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/fake-timers@29.7.0": - resolution: - { - integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/globals@29.7.0": - resolution: - { - integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/reporters@29.7.0": - resolution: - { - integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - "@jest/schemas@29.6.3": - resolution: - { - integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/source-map@29.6.3": - resolution: - { - integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/test-result@29.7.0": - resolution: - { - integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/test-sequencer@29.7.0": - resolution: - { - integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/transform@29.7.0": - resolution: - { - integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jest/types@29.6.3": - resolution: - { - integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - "@jridgewell/gen-mapping@0.3.8": - resolution: - { - integrity: sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/resolve-uri@3.1.2": - resolution: - { - integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/set-array@1.2.1": - resolution: - { - integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==, - } - engines: { node: ">=6.0.0" } - - "@jridgewell/source-map@0.3.6": - resolution: - { - integrity: sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==, - } - - "@jridgewell/sourcemap-codec@1.5.0": - resolution: - { - integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==, - } - - "@jridgewell/trace-mapping@0.3.25": - resolution: - { - integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==, - } - - "@jridgewell/trace-mapping@0.3.9": - resolution: - { - integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==, - } - - "@nodelib/fs.scandir@2.1.5": - resolution: - { - integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==, - } - engines: { node: ">= 8" } - - "@nodelib/fs.stat@2.0.5": - resolution: - { - integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==, - } - engines: { node: ">= 8" } - - "@nodelib/fs.walk@1.2.8": - resolution: - { - integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==, - } - engines: { node: ">= 8" } - - "@sinclair/typebox@0.27.8": - resolution: - { - integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==, - } - - "@sinonjs/commons@3.0.1": - resolution: - { - integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==, - } - - "@sinonjs/fake-timers@10.3.0": - resolution: - { - integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==, - } - - "@tootallnate/once@2.0.0": - resolution: - { - integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==, - } - engines: { node: ">= 10" } - - "@tsconfig/node10@1.0.11": - resolution: - { - integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==, - } - - "@tsconfig/node12@1.0.11": - resolution: - { - integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==, - } - - "@tsconfig/node14@1.0.3": - resolution: - { - integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==, - } - - "@tsconfig/node16@1.0.4": - resolution: - { - integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==, - } - - "@types/babel__core@7.20.5": - resolution: - { - integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==, - } - - "@types/babel__generator@7.27.0": - resolution: - { - integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==, - } - - "@types/babel__template@7.4.4": - resolution: - { - integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==, - } - - "@types/babel__traverse@7.20.7": - resolution: - { - integrity: sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==, - } - - "@types/eslint-scope@3.7.7": - resolution: - { - integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==, - } - - "@types/eslint@9.6.1": - resolution: - { - integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==, - } - - "@types/estree@1.0.8": - resolution: - { - integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==, - } - - "@types/graceful-fs@4.1.9": - resolution: - { - integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==, - } - - "@types/istanbul-lib-coverage@2.0.6": - resolution: - { - integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==, - } - - "@types/istanbul-lib-report@3.0.3": - resolution: - { - integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==, - } - - "@types/istanbul-reports@3.0.4": - resolution: - { - integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==, - } - - "@types/jest@29.5.14": - resolution: - { - integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==, - } - - "@types/jsdom@20.0.1": - resolution: - { - integrity: sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ==, - } - - "@types/json-schema@7.0.15": - resolution: - { - integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==, - } - - "@types/minimist@1.2.5": - resolution: - { - integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==, - } - - "@types/node@18.19.112": - resolution: - { - integrity: sha512-i+Vukt9POdS/MBI7YrrkkI5fMfwFtOjphSmt4WXYLfwqsfr6z/HdCx7LqT9M7JktGob8WNgj8nFB4TbGNE4Cog==, - } - - "@types/node@20.5.1": - resolution: - { - integrity: sha512-4tT2UrL5LBqDwoed9wZ6N3umC4Yhz3W3FloMmiiG4JwmUJWpie0c7lcnUNd4gtMKuDEO4wRVS8B6Xa0uMRsMKg==, - } - - "@types/normalize-package-data@2.4.4": - resolution: - { - integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==, - } - - "@types/parse-json@4.0.2": - resolution: - { - integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==, - } - - "@types/stack-utils@2.0.3": - resolution: - { - integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==, - } - - "@types/tough-cookie@4.0.5": - resolution: - { - integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==, - } - - "@types/ws@8.18.1": - resolution: - { - integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==, - } - - "@types/yargs-parser@21.0.3": - resolution: - { - integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==, - } - - "@types/yargs@17.0.33": - resolution: - { - integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==, - } - - "@typescript-eslint/eslint-plugin@8.34.0": - resolution: - { - integrity: sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - "@typescript-eslint/parser": ^8.34.0 - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - - "@typescript-eslint/parser@8.34.0": - resolution: - { - integrity: sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - - "@typescript-eslint/project-service@8.34.0": - resolution: - { - integrity: sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - typescript: ">=4.8.4 <5.9.0" - - "@typescript-eslint/scope-manager@8.34.0": - resolution: - { - integrity: sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@typescript-eslint/tsconfig-utils@8.34.0": - resolution: - { - integrity: sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - typescript: ">=4.8.4 <5.9.0" - - "@typescript-eslint/type-utils@8.34.0": - resolution: - { - integrity: sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - - "@typescript-eslint/types@8.34.0": - resolution: - { - integrity: sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@typescript-eslint/typescript-estree@8.34.0": - resolution: - { - integrity: sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - typescript: ">=4.8.4 <5.9.0" - - "@typescript-eslint/utils@8.34.0": - resolution: - { - integrity: sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: ">=4.8.4 <5.9.0" - - "@typescript-eslint/visitor-keys@8.34.0": - resolution: - { - integrity: sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - "@ungap/structured-clone@1.3.0": - resolution: - { - integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==, - } - - "@webassemblyjs/ast@1.14.1": - resolution: - { - integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==, - } - - "@webassemblyjs/floating-point-hex-parser@1.13.2": - resolution: - { - integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==, - } - - "@webassemblyjs/helper-api-error@1.13.2": - resolution: - { - integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==, - } - - "@webassemblyjs/helper-buffer@1.14.1": - resolution: - { - integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==, - } - - "@webassemblyjs/helper-numbers@1.13.2": - resolution: - { - integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==, - } - - "@webassemblyjs/helper-wasm-bytecode@1.13.2": - resolution: - { - integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==, - } - - "@webassemblyjs/helper-wasm-section@1.14.1": - resolution: - { - integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==, - } - - "@webassemblyjs/ieee754@1.13.2": - resolution: - { - integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==, - } - - "@webassemblyjs/leb128@1.13.2": - resolution: - { - integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==, - } - - "@webassemblyjs/utf8@1.13.2": - resolution: - { - integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==, - } - - "@webassemblyjs/wasm-edit@1.14.1": - resolution: - { - integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==, - } - - "@webassemblyjs/wasm-gen@1.14.1": - resolution: - { - integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==, - } - - "@webassemblyjs/wasm-opt@1.14.1": - resolution: - { - integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==, - } - - "@webassemblyjs/wasm-parser@1.14.1": - resolution: - { - integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==, - } - - "@webassemblyjs/wast-printer@1.14.1": - resolution: - { - integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==, - } - - "@webpack-cli/configtest@1.2.0": - resolution: - { - integrity: sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==, - } - peerDependencies: - webpack: 4.x.x || 5.x.x - webpack-cli: 4.x.x - - "@webpack-cli/info@1.5.0": - resolution: - { - integrity: sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==, - } - peerDependencies: - webpack-cli: 4.x.x - - "@webpack-cli/serve@1.7.0": - resolution: - { - integrity: sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==, - } - peerDependencies: - webpack-cli: 4.x.x - webpack-dev-server: "*" - peerDependenciesMeta: - webpack-dev-server: - optional: true - - "@xtuc/ieee754@1.2.0": - resolution: - { - integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==, - } - - "@xtuc/long@4.2.2": - resolution: - { - integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==, - } - - JSONStream@1.3.5: - resolution: - { - integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==, - } - hasBin: true - - abab@2.0.6: - resolution: - { - integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==, - } - deprecated: Use your platform's native atob() and btoa() methods instead - - acorn-globals@7.0.1: - resolution: - { - integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==, - } - - acorn-jsx@5.3.2: - resolution: - { - integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==, - } - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - - acorn-walk@8.3.4: - resolution: - { - integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==, - } - engines: { node: ">=0.4.0" } - - acorn@8.15.0: - resolution: - { - integrity: sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==, - } - engines: { node: ">=0.4.0" } - hasBin: true - - agent-base@6.0.2: - resolution: - { - integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==, - } - engines: { node: ">= 6.0.0" } - - ajv-formats@2.1.1: - resolution: - { - integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==, - } - peerDependencies: - ajv: ^8.0.0 - peerDependenciesMeta: - ajv: - optional: true - - ajv-keywords@5.1.0: - resolution: - { - integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==, - } - peerDependencies: - ajv: ^8.8.2 - - ajv@6.12.6: - resolution: - { - integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==, - } - - ajv@8.17.1: - resolution: - { - integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==, - } - - ansi-escapes@4.3.2: - resolution: - { - integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==, - } - engines: { node: ">=8" } - - ansi-regex@5.0.1: - resolution: - { - integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==, - } - engines: { node: ">=8" } - - ansi-regex@6.1.0: - resolution: - { - integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==, - } - engines: { node: ">=12" } - - ansi-styles@3.2.1: - resolution: - { - integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==, - } - engines: { node: ">=4" } - - ansi-styles@4.3.0: - resolution: - { - integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==, - } - engines: { node: ">=8" } - - ansi-styles@5.2.0: - resolution: - { - integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==, - } - engines: { node: ">=10" } - - ansi-styles@6.2.1: - resolution: - { - integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==, - } - engines: { node: ">=12" } - - anymatch@3.1.3: - resolution: - { - integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==, - } - engines: { node: ">= 8" } - - arg@4.1.3: - resolution: - { - integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==, - } - - argparse@1.0.10: - resolution: - { - integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==, - } - - argparse@2.0.1: - resolution: - { - integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==, - } - - array-buffer-byte-length@1.0.2: - resolution: - { - integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==, - } - engines: { node: ">= 0.4" } - - array-ify@1.0.0: - resolution: - { - integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==, - } - - array-union@2.1.0: - resolution: - { - integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==, - } - engines: { node: ">=8" } - - arraybuffer.prototype.slice@1.0.4: - resolution: - { - integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==, - } - engines: { node: ">= 0.4" } - - arrify@1.0.1: - resolution: - { - integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==, - } - engines: { node: ">=0.10.0" } - - async-function@1.0.0: - resolution: - { - integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==, - } - engines: { node: ">= 0.4" } - - async@3.2.6: - resolution: - { - integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==, - } - - asynckit@0.4.0: - resolution: - { - integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==, - } - - available-typed-arrays@1.0.7: - resolution: - { - integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==, - } - engines: { node: ">= 0.4" } - - babel-jest@29.7.0: - resolution: - { - integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - peerDependencies: - "@babel/core": ^7.8.0 - - babel-plugin-istanbul@6.1.1: - resolution: - { - integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==, - } - engines: { node: ">=8" } - - babel-plugin-jest-hoist@29.6.3: - resolution: - { - integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - babel-preset-current-node-syntax@1.1.0: - resolution: - { - integrity: sha512-ldYss8SbBlWva1bs28q78Ju5Zq1F+8BrqBZZ0VFhLBvhh6lCpC2o3gDJi/5DRLs9FgYZCnmPYIVFU4lRXCkyUw==, - } - peerDependencies: - "@babel/core": ^7.0.0 - - babel-preset-jest@29.6.3: - resolution: - { - integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - peerDependencies: - "@babel/core": ^7.0.0 - - balanced-match@1.0.2: - resolution: - { - integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==, - } - - base64-js@1.5.1: - resolution: - { - integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==, - } - - big.js@5.2.2: - resolution: - { - integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==, - } - - binary-extensions@2.3.0: - resolution: - { - integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==, - } - engines: { node: ">=8" } - - brace-expansion@1.1.12: - resolution: - { - integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==, - } - - brace-expansion@2.0.2: - resolution: - { - integrity: sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==, - } - - braces@3.0.3: - resolution: - { - integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==, - } - engines: { node: ">=8" } - - browserslist@4.25.0: - resolution: - { - integrity: sha512-PJ8gYKeS5e/whHBh8xrwYK+dAvEj7JXtz6uTucnMRB8OiGTsKccFekoRrjajPBHV8oOY+2tI4uxeceSimKwMFA==, - } - engines: { node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7 } - hasBin: true - - bs-logger@0.2.6: - resolution: - { - integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==, - } - engines: { node: ">= 6" } - - bser@2.1.1: - resolution: - { - integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==, - } - - buffer-from@1.1.2: - resolution: - { - integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==, - } - - buffer@6.0.3: - resolution: - { - integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==, - } - - call-bind-apply-helpers@1.0.2: - resolution: - { - integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==, - } - engines: { node: ">= 0.4" } - - call-bind@1.0.8: - resolution: - { - integrity: sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==, - } - engines: { node: ">= 0.4" } - - call-bound@1.0.4: - resolution: - { - integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==, - } - engines: { node: ">= 0.4" } - - callsites@3.1.0: - resolution: - { - integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==, - } - engines: { node: ">=6" } - - camelcase-keys@6.2.2: - resolution: - { - integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==, - } - engines: { node: ">=8" } - - camelcase@5.3.1: - resolution: - { - integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==, - } - engines: { node: ">=6" } - - camelcase@6.3.0: - resolution: - { - integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==, - } - engines: { node: ">=10" } - - caniuse-lite@1.0.30001723: - resolution: - { - integrity: sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==, - } - - chalk@2.4.2: - resolution: - { - integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==, - } - engines: { node: ">=4" } - - chalk@4.1.2: - resolution: - { - integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==, - } - engines: { node: ">=10" } - - char-regex@1.0.2: - resolution: - { - integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==, - } - engines: { node: ">=10" } - - chokidar@3.6.0: - resolution: - { - integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==, - } - engines: { node: ">= 8.10.0" } - - chrome-trace-event@1.0.4: - resolution: - { - integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==, - } - engines: { node: ">=6.0" } - - ci-info@2.0.0: - resolution: - { - integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==, - } - - ci-info@3.9.0: - resolution: - { - integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==, - } - engines: { node: ">=8" } - - cjs-module-lexer@1.4.3: - resolution: - { - integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==, - } - - cliui@7.0.4: - resolution: - { - integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==, - } - - cliui@8.0.1: - resolution: - { - integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==, - } - engines: { node: ">=12" } - - clone-deep@4.0.1: - resolution: - { - integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==, - } - engines: { node: ">=6" } - - co@4.6.0: - resolution: - { - integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==, - } - engines: { iojs: ">= 1.0.0", node: ">= 0.12.0" } - - collect-v8-coverage@1.0.2: - resolution: - { - integrity: sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==, - } - - color-convert@1.9.3: - resolution: - { - integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==, - } - - color-convert@2.0.1: - resolution: - { - integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==, - } - engines: { node: ">=7.0.0" } - - color-name@1.1.3: - resolution: - { - integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==, - } - - color-name@1.1.4: - resolution: - { - integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==, - } - - colorette@2.0.20: - resolution: - { - integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==, - } - - combined-stream@1.0.8: - resolution: - { - integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==, - } - engines: { node: ">= 0.8" } - - commander@12.1.0: - resolution: - { - integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==, - } - engines: { node: ">=18" } - - commander@2.20.3: - resolution: - { - integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==, - } - - commander@7.2.0: - resolution: - { - integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==, - } - engines: { node: ">= 10" } - - compare-func@2.0.0: - resolution: - { - integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==, - } - - compare-versions@3.6.0: - resolution: - { - integrity: sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==, - } - - concat-map@0.0.1: - resolution: - { - integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==, - } - - consola@2.15.3: - resolution: - { - integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==, - } - - conventional-changelog-angular@6.0.0: - resolution: - { - integrity: sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg==, - } - engines: { node: ">=14" } - - conventional-changelog-conventionalcommits@6.1.0: - resolution: - { - integrity: sha512-3cS3GEtR78zTfMzk0AizXKKIdN4OvSh7ibNz6/DPbhWWQu7LqE/8+/GqSodV+sywUR2gpJAdP/1JFf4XtN7Zpw==, - } - engines: { node: ">=14" } - - conventional-commits-parser@4.0.0: - resolution: - { - integrity: sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==, - } - engines: { node: ">=14" } - hasBin: true - - convert-source-map@2.0.0: - resolution: - { - integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==, - } - - core-util-is@1.0.3: - resolution: - { - integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==, - } - - cosmiconfig-typescript-loader@4.4.0: - resolution: - { - integrity: sha512-BabizFdC3wBHhbI4kJh0VkQP9GkBfoHPydD0COMce1nJ1kJAB3F2TmJ/I7diULBKtmEWSwEbuN/KDtgnmUUVmw==, - } - engines: { node: ">=v14.21.3" } - peerDependencies: - "@types/node": "*" - cosmiconfig: ">=7" - ts-node: ">=10" - typescript: ">=4" - - cosmiconfig@7.1.0: - resolution: - { - integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==, - } - engines: { node: ">=10" } - - cosmiconfig@8.3.6: - resolution: - { - integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==, - } - engines: { node: ">=14" } - peerDependencies: - typescript: ">=4.9.5" - peerDependenciesMeta: - typescript: - optional: true - - create-jest@29.7.0: - resolution: - { - integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - hasBin: true - - create-require@1.1.1: - resolution: - { - integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==, - } - - cross-env@7.0.3: - resolution: - { - integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==, - } - engines: { node: ">=10.14", npm: ">=6", yarn: ">=1" } - hasBin: true - - cross-fetch@3.2.0: - resolution: - { - integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==, - } - - cross-spawn@6.0.6: - resolution: - { - integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==, - } - engines: { node: ">=4.8" } - - cross-spawn@7.0.6: - resolution: - { - integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==, - } - engines: { node: ">= 8" } - - cssom@0.3.8: - resolution: - { - integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==, - } - - cssom@0.5.0: - resolution: - { - integrity: sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==, - } - - cssstyle@2.3.0: - resolution: - { - integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==, - } - engines: { node: ">=8" } - - dargs@7.0.0: - resolution: - { - integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==, - } - engines: { node: ">=8" } - - data-urls@3.0.2: - resolution: - { - integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==, - } - engines: { node: ">=12" } - - data-view-buffer@1.0.2: - resolution: - { - integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==, - } - engines: { node: ">= 0.4" } - - data-view-byte-length@1.0.2: - resolution: - { - integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==, - } - engines: { node: ">= 0.4" } - - data-view-byte-offset@1.0.1: - resolution: - { - integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==, - } - engines: { node: ">= 0.4" } - - dayjs@1.11.13: - resolution: - { - integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==, - } - - debug@4.4.1: - resolution: - { - integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==, - } - engines: { node: ">=6.0" } - peerDependencies: - supports-color: "*" - peerDependenciesMeta: - supports-color: - optional: true - - decamelize-keys@1.1.1: - resolution: - { - integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==, - } - engines: { node: ">=0.10.0" } - - decamelize@1.2.0: - resolution: - { - integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==, - } - engines: { node: ">=0.10.0" } - - decimal.js@10.5.0: - resolution: - { - integrity: sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==, - } - - dedent@1.6.0: - resolution: - { - integrity: sha512-F1Z+5UCFpmQUzJa11agbyPVMbpgT/qA3/SKyJ1jyBgm7dUcUEa8v9JwDkerSQXfakBwFljIxhOJqGkjUwZ9FSA==, - } - peerDependencies: - babel-plugin-macros: ^3.1.0 - peerDependenciesMeta: - babel-plugin-macros: - optional: true - - deep-extend@0.6.0: - resolution: - { - integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==, - } - engines: { node: ">=4.0.0" } - - deep-is@0.1.4: - resolution: - { - integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==, - } - - deepmerge@4.3.1: - resolution: - { - integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==, - } - engines: { node: ">=0.10.0" } - - define-data-property@1.1.4: - resolution: - { - integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==, - } - engines: { node: ">= 0.4" } - - define-properties@1.2.1: - resolution: - { - integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==, - } - engines: { node: ">= 0.4" } - - delayed-stream@1.0.0: - resolution: - { - integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==, - } - engines: { node: ">=0.4.0" } - - detect-newline@3.1.0: - resolution: - { - integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==, - } - engines: { node: ">=8" } - - diff-sequences@29.6.3: - resolution: - { - integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - diff@4.0.2: - resolution: - { - integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==, - } - engines: { node: ">=0.3.1" } - - dir-glob@3.0.1: - resolution: - { - integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==, - } - engines: { node: ">=8" } - - doctrine@3.0.0: - resolution: - { - integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==, - } - engines: { node: ">=6.0.0" } - - domexception@4.0.0: - resolution: - { - integrity: sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==, - } - engines: { node: ">=12" } - deprecated: Use your platform's native DOMException instead - - dot-prop@5.3.0: - resolution: - { - integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==, - } - engines: { node: ">=8" } - - dotenv@16.5.0: - resolution: - { - integrity: sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==, - } - engines: { node: ">=12" } - - dunder-proto@1.0.1: - resolution: - { - integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==, - } - engines: { node: ">= 0.4" } - - eastasianwidth@0.2.0: - resolution: - { - integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==, - } - - ejs@3.1.10: - resolution: - { - integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==, - } - engines: { node: ">=0.10.0" } - hasBin: true - - electron-to-chromium@1.5.167: - resolution: - { - integrity: sha512-LxcRvnYO5ez2bMOFpbuuVuAI5QNeY1ncVytE/KXaL6ZNfzX1yPlAO0nSOyIHx2fVAuUprMqPs/TdVhUFZy7SIQ==, - } - - emittery@0.13.1: - resolution: - { - integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==, - } - engines: { node: ">=12" } - - emoji-regex@8.0.0: - resolution: - { - integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==, - } - - emoji-regex@9.2.2: - resolution: - { - integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==, - } - - emojis-list@3.0.0: - resolution: - { - integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==, - } - engines: { node: ">= 4" } - - end-of-stream@1.4.4: - resolution: - { - integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==, - } - - enhanced-resolve@4.5.0: - resolution: - { - integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==, - } - engines: { node: ">=6.9.0" } - - enhanced-resolve@5.18.1: - resolution: - { - integrity: sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==, - } - engines: { node: ">=10.13.0" } - - entities@4.5.0: - resolution: - { - integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==, - } - engines: { node: ">=0.12" } - - entities@6.0.1: - resolution: - { - integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==, - } - engines: { node: ">=0.12" } - - envinfo@7.14.0: - resolution: - { - integrity: sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==, - } - engines: { node: ">=4" } - hasBin: true - - errno@0.1.8: - resolution: - { - integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==, - } - hasBin: true - - error-ex@1.3.2: - resolution: - { - integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==, - } - - es-abstract@1.24.0: - resolution: - { - integrity: sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==, - } - engines: { node: ">= 0.4" } - - es-define-property@1.0.1: - resolution: - { - integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==, - } - engines: { node: ">= 0.4" } - - es-errors@1.3.0: - resolution: - { - integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==, - } - engines: { node: ">= 0.4" } - - es-module-lexer@1.7.0: - resolution: - { - integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==, - } - - es-object-atoms@1.1.1: - resolution: - { - integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==, - } - engines: { node: ">= 0.4" } - - es-set-tostringtag@2.1.0: - resolution: - { - integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==, - } - engines: { node: ">= 0.4" } - - es-to-primitive@1.3.0: - resolution: - { - integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==, - } - engines: { node: ">= 0.4" } - - escalade@3.2.0: - resolution: - { - integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==, - } - engines: { node: ">=6" } - - escape-string-regexp@1.0.5: - resolution: - { - integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==, - } - engines: { node: ">=0.8.0" } - - escape-string-regexp@2.0.0: - resolution: - { - integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==, - } - engines: { node: ">=8" } - - escape-string-regexp@4.0.0: - resolution: - { - integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==, - } - engines: { node: ">=10" } - - escodegen@2.1.0: - resolution: - { - integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==, - } - engines: { node: ">=6.0" } - hasBin: true - - eslint-scope@5.1.1: - resolution: - { - integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==, - } - engines: { node: ">=8.0.0" } - - eslint-scope@7.2.2: - resolution: - { - integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - - eslint-visitor-keys@3.4.3: - resolution: - { - integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - - eslint-visitor-keys@4.2.1: - resolution: - { - integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==, - } - engines: { node: ^18.18.0 || ^20.9.0 || >=21.1.0 } - - eslint@8.57.1: - resolution: - { - integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. - hasBin: true - - espree@9.6.1: - resolution: - { - integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==, - } - engines: { node: ^12.22.0 || ^14.17.0 || >=16.0.0 } - - esprima@4.0.1: - resolution: - { - integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==, - } - engines: { node: ">=4" } - hasBin: true - - esquery@1.6.0: - resolution: - { - integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==, - } - engines: { node: ">=0.10" } - - esrecurse@4.3.0: - resolution: - { - integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==, - } - engines: { node: ">=4.0" } - - estraverse@4.3.0: - resolution: - { - integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==, - } - engines: { node: ">=4.0" } - - estraverse@5.3.0: - resolution: - { - integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==, - } - engines: { node: ">=4.0" } - - esutils@2.0.3: - resolution: - { - integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==, - } - engines: { node: ">=0.10.0" } - - events@3.3.0: - resolution: - { - integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==, - } - engines: { node: ">=0.8.x" } - - execa@4.1.0: - resolution: - { - integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==, - } - engines: { node: ">=10" } - - execa@5.1.1: - resolution: - { - integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==, - } - engines: { node: ">=10" } - - exit@0.1.2: - resolution: - { - integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==, - } - engines: { node: ">= 0.8.0" } - - expect@29.7.0: - resolution: - { - integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - fast-deep-equal@3.1.3: - resolution: - { - integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==, - } - - fast-glob@3.3.3: - resolution: - { - integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==, - } - engines: { node: ">=8.6.0" } - - fast-json-stable-stringify@2.1.0: - resolution: - { - integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==, - } - - fast-levenshtein@2.0.6: - resolution: - { - integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==, - } - - fast-uri@3.0.6: - resolution: - { - integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==, - } - - fastest-levenshtein@1.0.16: - resolution: - { - integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==, - } - engines: { node: ">= 4.9.1" } - - fastq@1.19.1: - resolution: - { - integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==, - } - - fb-watchman@2.0.2: - resolution: - { - integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==, - } - - file-entry-cache@6.0.1: - resolution: - { - integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==, - } - engines: { node: ^10.12.0 || >=12.0.0 } - - filelist@1.0.4: - resolution: - { - integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==, - } - - fill-range@7.1.1: - resolution: - { - integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==, - } - engines: { node: ">=8" } - - find-up@4.1.0: - resolution: - { - integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==, - } - engines: { node: ">=8" } - - find-up@5.0.0: - resolution: - { - integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==, - } - engines: { node: ">=10" } - - find-versions@4.0.0: - resolution: - { - integrity: sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==, - } - engines: { node: ">=10" } - - flat-cache@3.2.0: - resolution: - { - integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==, - } - engines: { node: ^10.12.0 || >=12.0.0 } - - flat@5.0.2: - resolution: - { - integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==, - } - hasBin: true - - flatted@3.3.3: - resolution: - { - integrity: sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==, - } - - for-each@0.3.5: - resolution: - { - integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==, - } - engines: { node: ">= 0.4" } - - foreground-child@3.3.1: - resolution: - { - integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==, - } - engines: { node: ">=14" } - - form-data@4.0.3: - resolution: - { - integrity: sha512-qsITQPfmvMOSAdeyZ+12I1c+CKSstAFAwu+97zrnWAbIr5u8wfsExUzCesVLC8NgHuRUqNN4Zy6UPWUTRGslcA==, - } - engines: { node: ">= 6" } - - fs-extra@11.3.0: - resolution: - { - integrity: sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==, - } - engines: { node: ">=14.14" } - - fs.realpath@1.0.0: - resolution: - { - integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==, - } - - fsevents@2.3.3: - resolution: - { - integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==, - } - engines: { node: ^8.16.0 || ^10.6.0 || >=11.0.0 } - os: [darwin] - - function-bind@1.1.2: - resolution: - { - integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==, - } - - function.prototype.name@1.1.8: - resolution: - { - integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==, - } - engines: { node: ">= 0.4" } - - functions-have-names@1.2.3: - resolution: - { - integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==, - } - - gensync@1.0.0-beta.2: - resolution: - { - integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==, - } - engines: { node: ">=6.9.0" } - - get-caller-file@2.0.5: - resolution: - { - integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==, - } - engines: { node: 6.* || 8.* || >= 10.* } - - get-intrinsic@1.3.0: - resolution: - { - integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==, - } - engines: { node: ">= 0.4" } - - get-package-type@0.1.0: - resolution: - { - integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==, - } - engines: { node: ">=8.0.0" } - - get-proto@1.0.1: - resolution: - { - integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==, - } - engines: { node: ">= 0.4" } - - get-stdin@9.0.0: - resolution: - { - integrity: sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==, - } - engines: { node: ">=12" } - - get-stream@5.2.0: - resolution: - { - integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==, - } - engines: { node: ">=8" } - - get-stream@6.0.1: - resolution: - { - integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==, - } - engines: { node: ">=10" } - - get-symbol-description@1.1.0: - resolution: - { - integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==, - } - engines: { node: ">= 0.4" } - - git-raw-commits@2.0.11: - resolution: - { - integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==, - } - engines: { node: ">=10" } - hasBin: true - - glob-parent@5.1.2: - resolution: - { - integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==, - } - engines: { node: ">= 6" } - - glob-parent@6.0.2: - resolution: - { - integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==, - } - engines: { node: ">=10.13.0" } - - glob-to-regexp@0.4.1: - resolution: - { - integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==, - } - - glob@11.0.3: - resolution: - { - integrity: sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==, - } - engines: { node: 20 || >=22 } - hasBin: true - - glob@7.2.3: - resolution: - { - integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==, - } - deprecated: Glob versions prior to v9 are no longer supported - - glob@8.1.0: - resolution: - { - integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==, - } - engines: { node: ">=12" } - deprecated: Glob versions prior to v9 are no longer supported - - global-dirs@0.1.1: - resolution: - { - integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==, - } - engines: { node: ">=4" } - - globals@11.12.0: - resolution: - { - integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==, - } - engines: { node: ">=4" } - - globals@13.24.0: - resolution: - { - integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==, - } - engines: { node: ">=8" } - - globalthis@1.0.4: - resolution: - { - integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==, - } - engines: { node: ">= 0.4" } - - globby@11.1.0: - resolution: - { - integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==, - } - engines: { node: ">=10" } - - gopd@1.2.0: - resolution: - { - integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==, - } - engines: { node: ">= 0.4" } - - graceful-fs@4.2.11: - resolution: - { - integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==, - } - - graphemer@1.4.0: - resolution: - { - integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==, - } - - hard-rejection@2.1.0: - resolution: - { - integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==, - } - engines: { node: ">=6" } - - has-bigints@1.1.0: - resolution: - { - integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==, - } - engines: { node: ">= 0.4" } - - has-flag@3.0.0: - resolution: - { - integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==, - } - engines: { node: ">=4" } - - has-flag@4.0.0: - resolution: - { - integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==, - } - engines: { node: ">=8" } - - has-property-descriptors@1.0.2: - resolution: - { - integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==, - } - - has-proto@1.2.0: - resolution: - { - integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==, - } - engines: { node: ">= 0.4" } - - has-symbols@1.1.0: - resolution: - { - integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==, - } - engines: { node: ">= 0.4" } - - has-tostringtag@1.0.2: - resolution: - { - integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==, - } - engines: { node: ">= 0.4" } - - hasown@2.0.2: - resolution: - { - integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==, - } - engines: { node: ">= 0.4" } - - hosted-git-info@2.8.9: - resolution: - { - integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==, - } - - hosted-git-info@4.1.0: - resolution: - { - integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==, - } - engines: { node: ">=10" } - - html-encoding-sniffer@3.0.0: - resolution: - { - integrity: sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==, - } - engines: { node: ">=12" } - - html-escaper@2.0.2: - resolution: - { - integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==, - } - - http-proxy-agent@5.0.0: - resolution: - { - integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==, - } - engines: { node: ">= 6" } - - https-proxy-agent@5.0.1: - resolution: - { - integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==, - } - engines: { node: ">= 6" } - - human-signals@1.1.1: - resolution: - { - integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==, - } - engines: { node: ">=8.12.0" } - - human-signals@2.1.0: - resolution: - { - integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==, - } - engines: { node: ">=10.17.0" } - - husky@4.3.8: - resolution: - { - integrity: sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==, - } - engines: { node: ">=10" } - hasBin: true - - iconv-lite@0.6.3: - resolution: - { - integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==, - } - engines: { node: ">=0.10.0" } - - ieee754@1.2.1: - resolution: - { - integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==, - } - - ignore-by-default@1.0.1: - resolution: - { - integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==, - } - - ignore@5.3.2: - resolution: - { - integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==, - } - engines: { node: ">= 4" } - - ignore@6.0.2: - resolution: - { - integrity: sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==, - } - engines: { node: ">= 4" } - - ignore@7.0.5: - resolution: - { - integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==, - } - engines: { node: ">= 4" } - - import-fresh@3.3.1: - resolution: - { - integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==, - } - engines: { node: ">=6" } - - import-local@3.2.0: - resolution: - { - integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==, - } - engines: { node: ">=8" } - hasBin: true - - imurmurhash@0.1.4: - resolution: - { - integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==, - } - engines: { node: ">=0.8.19" } - - indent-string@4.0.0: - resolution: - { - integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==, - } - engines: { node: ">=8" } - - inflight@1.0.6: - resolution: - { - integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==, - } - deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. - - inherits@2.0.4: - resolution: - { - integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==, - } - - ini@1.3.8: - resolution: - { - integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==, - } - - ini@2.0.0: - resolution: - { - integrity: sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==, - } - engines: { node: ">=10" } - - ini@4.1.3: - resolution: - { - integrity: sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==, - } - engines: { node: ^14.17.0 || ^16.13.0 || >=18.0.0 } - - internal-slot@1.1.0: - resolution: - { - integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==, - } - engines: { node: ">= 0.4" } - - interpret@2.2.0: - resolution: - { - integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==, - } - engines: { node: ">= 0.10" } - - is-arguments@1.2.0: - resolution: - { - integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==, - } - engines: { node: ">= 0.4" } - - is-array-buffer@3.0.5: - resolution: - { - integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==, - } - engines: { node: ">= 0.4" } - - is-arrayish@0.2.1: - resolution: - { - integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==, - } - - is-async-function@2.1.1: - resolution: - { - integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==, - } - engines: { node: ">= 0.4" } - - is-bigint@1.1.0: - resolution: - { - integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==, - } - engines: { node: ">= 0.4" } - - is-binary-path@2.1.0: - resolution: - { - integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==, - } - engines: { node: ">=8" } - - is-boolean-object@1.2.2: - resolution: - { - integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==, - } - engines: { node: ">= 0.4" } - - is-callable@1.2.7: - resolution: - { - integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==, - } - engines: { node: ">= 0.4" } - - is-core-module@2.16.1: - resolution: - { - integrity: sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==, - } - engines: { node: ">= 0.4" } - - is-data-view@1.0.2: - resolution: - { - integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==, - } - engines: { node: ">= 0.4" } - - is-date-object@1.1.0: - resolution: - { - integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==, - } - engines: { node: ">= 0.4" } - - is-extglob@2.1.1: - resolution: - { - integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==, - } - engines: { node: ">=0.10.0" } - - is-finalizationregistry@1.1.1: - resolution: - { - integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==, - } - engines: { node: ">= 0.4" } - - is-fullwidth-code-point@3.0.0: - resolution: - { - integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==, - } - engines: { node: ">=8" } - - is-generator-fn@2.1.0: - resolution: - { - integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==, - } - engines: { node: ">=6" } - - is-generator-function@1.1.0: - resolution: - { - integrity: sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==, - } - engines: { node: ">= 0.4" } - - is-glob@4.0.3: - resolution: - { - integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==, - } - engines: { node: ">=0.10.0" } - - is-map@2.0.3: - resolution: - { - integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==, - } - engines: { node: ">= 0.4" } - - is-negative-zero@2.0.3: - resolution: - { - integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==, - } - engines: { node: ">= 0.4" } - - is-number-object@1.1.1: - resolution: - { - integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==, - } - engines: { node: ">= 0.4" } - - is-number@7.0.0: - resolution: - { - integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==, - } - engines: { node: ">=0.12.0" } - - is-obj@2.0.0: - resolution: - { - integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==, - } - engines: { node: ">=8" } - - is-path-inside@3.0.3: - resolution: - { - integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==, - } - engines: { node: ">=8" } - - is-plain-obj@1.1.0: - resolution: - { - integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==, - } - engines: { node: ">=0.10.0" } - - is-plain-object@2.0.4: - resolution: - { - integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==, - } - engines: { node: ">=0.10.0" } - - is-potential-custom-element-name@1.0.1: - resolution: - { - integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==, - } - - is-regex@1.2.1: - resolution: - { - integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==, - } - engines: { node: ">= 0.4" } - - is-set@2.0.3: - resolution: - { - integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==, - } - engines: { node: ">= 0.4" } - - is-shared-array-buffer@1.0.4: - resolution: - { - integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==, - } - engines: { node: ">= 0.4" } - - is-stream@2.0.1: - resolution: - { - integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==, - } - engines: { node: ">=8" } - - is-string@1.1.1: - resolution: - { - integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==, - } - engines: { node: ">= 0.4" } - - is-symbol@1.1.1: - resolution: - { - integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==, - } - engines: { node: ">= 0.4" } - - is-text-path@1.0.1: - resolution: - { - integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==, - } - engines: { node: ">=0.10.0" } - - is-typed-array@1.1.15: - resolution: - { - integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==, - } - engines: { node: ">= 0.4" } - - is-weakmap@2.0.2: - resolution: - { - integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==, - } - engines: { node: ">= 0.4" } - - is-weakref@1.1.1: - resolution: - { - integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==, - } - engines: { node: ">= 0.4" } - - is-weakset@2.0.4: - resolution: - { - integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==, - } - engines: { node: ">= 0.4" } - - isarray@1.0.0: - resolution: - { - integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==, - } - - isarray@2.0.5: - resolution: - { - integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==, - } - - isexe@2.0.0: - resolution: - { - integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==, - } - - isobject@3.0.1: - resolution: - { - integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==, - } - engines: { node: ">=0.10.0" } - - istanbul-lib-coverage@3.2.2: - resolution: - { - integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==, - } - engines: { node: ">=8" } - - istanbul-lib-instrument@5.2.1: - resolution: - { - integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==, - } - engines: { node: ">=8" } - - istanbul-lib-instrument@6.0.3: - resolution: - { - integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==, - } - engines: { node: ">=10" } - - istanbul-lib-report@3.0.1: - resolution: - { - integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==, - } - engines: { node: ">=10" } - - istanbul-lib-source-maps@4.0.1: - resolution: - { - integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==, - } - engines: { node: ">=10" } - - istanbul-reports@3.1.7: - resolution: - { - integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==, - } - engines: { node: ">=8" } - - jackspeak@4.1.1: - resolution: - { - integrity: sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==, - } - engines: { node: 20 || >=22 } - - jake@10.9.2: - resolution: - { - integrity: sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==, - } - engines: { node: ">=10" } - hasBin: true - - jest-changed-files@29.7.0: - resolution: - { - integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-circus@29.7.0: - resolution: - { - integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-cli@29.7.0: - resolution: - { - integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - jest-config@29.7.0: - resolution: - { - integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - peerDependencies: - "@types/node": "*" - ts-node: ">=9.0.0" - peerDependenciesMeta: - "@types/node": - optional: true - ts-node: - optional: true - - jest-diff@29.7.0: - resolution: - { - integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-docblock@29.7.0: - resolution: - { - integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-each@29.7.0: - resolution: - { - integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-environment-jsdom@29.7.0: - resolution: - { - integrity: sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - - jest-environment-node@29.7.0: - resolution: - { - integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-get-type@29.6.3: - resolution: - { - integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-haste-map@29.7.0: - resolution: - { - integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-leak-detector@29.7.0: - resolution: - { - integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-matcher-utils@29.7.0: - resolution: - { - integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-message-util@29.7.0: - resolution: - { - integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-mock@29.7.0: - resolution: - { - integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-pnp-resolver@1.2.3: - resolution: - { - integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==, - } - engines: { node: ">=6" } - peerDependencies: - jest-resolve: "*" - peerDependenciesMeta: - jest-resolve: - optional: true - - jest-regex-util@29.6.3: - resolution: - { - integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-resolve-dependencies@29.7.0: - resolution: - { - integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-resolve@29.7.0: - resolution: - { - integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-runner@29.7.0: - resolution: - { - integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-runtime@29.7.0: - resolution: - { - integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-snapshot@29.7.0: - resolution: - { - integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-util@29.7.0: - resolution: - { - integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-validate@29.7.0: - resolution: - { - integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-watcher@29.7.0: - resolution: - { - integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest-worker@27.5.1: - resolution: - { - integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==, - } - engines: { node: ">= 10.13.0" } - - jest-worker@29.7.0: - resolution: - { - integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - jest@29.7.0: - resolution: - { - integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - hasBin: true - peerDependencies: - node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 - peerDependenciesMeta: - node-notifier: - optional: true - - js-tokens@4.0.0: - resolution: - { - integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==, - } - - js-yaml@3.14.1: - resolution: - { - integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==, - } - hasBin: true - - js-yaml@4.1.0: - resolution: - { - integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==, - } - hasBin: true - - jsdom@20.0.3: - resolution: - { - integrity: sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==, - } - engines: { node: ">=14" } - peerDependencies: - canvas: ^2.5.0 - peerDependenciesMeta: - canvas: - optional: true - - jsesc@3.1.0: - resolution: - { - integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==, - } - engines: { node: ">=6" } - hasBin: true - - json-buffer@3.0.1: - resolution: - { - integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==, - } - - json-parse-better-errors@1.0.2: - resolution: - { - integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==, - } - - json-parse-even-better-errors@2.3.1: - resolution: - { - integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==, - } - - json-schema-traverse@0.4.1: - resolution: - { - integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==, - } - - json-schema-traverse@1.0.0: - resolution: - { - integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==, - } - - json-stable-stringify-without-jsonify@1.0.1: - resolution: - { - integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==, - } - - json5@2.2.3: - resolution: - { - integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==, - } - engines: { node: ">=6" } - hasBin: true - - jsonc-parser@3.3.1: - resolution: - { - integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==, - } - - jsonfile@6.1.0: - resolution: - { - integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==, - } - - jsonparse@1.3.1: - resolution: - { - integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==, - } - engines: { "0": node >= 0.2.0 } - - jsonpointer@5.0.1: - resolution: - { - integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==, - } - engines: { node: ">=0.10.0" } - - keyv@4.5.4: - resolution: - { - integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==, - } - - kind-of@6.0.3: - resolution: - { - integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==, - } - engines: { node: ">=0.10.0" } - - kleur@3.0.3: - resolution: - { - integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==, - } - engines: { node: ">=6" } - - leven@3.1.0: - resolution: - { - integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==, - } - engines: { node: ">=6" } - - levn@0.4.1: - resolution: - { - integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==, - } - engines: { node: ">= 0.8.0" } - - lines-and-columns@1.2.4: - resolution: - { - integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==, - } - - linkify-it@5.0.0: - resolution: - { - integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==, - } - - load-json-file@4.0.0: - resolution: - { - integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==, - } - engines: { node: ">=4" } - - loader-runner@4.3.0: - resolution: - { - integrity: sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==, - } - engines: { node: ">=6.11.5" } - - loader-utils@2.0.4: - resolution: - { - integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==, - } - engines: { node: ">=8.9.0" } - - locate-path@5.0.0: - resolution: - { - integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==, - } - engines: { node: ">=8" } - - locate-path@6.0.0: - resolution: - { - integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==, - } - engines: { node: ">=10" } - - lodash.camelcase@4.3.0: - resolution: - { - integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==, - } - - lodash.isfunction@3.0.9: - resolution: - { - integrity: sha512-AirXNj15uRIMMPihnkInB4i3NHeb4iBtNg9WRWuK2o31S+ePwwNmDPaTL3o7dTJ+VXNZim7rFs4rxN4YU1oUJw==, - } - - lodash.isplainobject@4.0.6: - resolution: - { - integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==, - } - - lodash.kebabcase@4.1.1: - resolution: - { - integrity: sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==, - } - - lodash.memoize@4.1.2: - resolution: - { - integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==, - } - - lodash.merge@4.6.2: - resolution: - { - integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==, - } - - lodash.mergewith@4.6.2: - resolution: - { - integrity: sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==, - } - - lodash.snakecase@4.1.1: - resolution: - { - integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==, - } - - lodash.startcase@4.4.0: - resolution: - { - integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==, - } - - lodash.uniq@4.5.0: - resolution: - { - integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==, - } - - lodash.upperfirst@4.3.1: - resolution: - { - integrity: sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==, - } - - lodash@4.17.21: - resolution: - { - integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==, - } - - lru-cache@11.1.0: - resolution: - { - integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==, - } - engines: { node: 20 || >=22 } - - lru-cache@5.1.1: - resolution: - { - integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==, - } - - lru-cache@6.0.0: - resolution: - { - integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==, - } - engines: { node: ">=10" } - - lunr@2.3.9: - resolution: - { - integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==, - } - - make-dir@4.0.0: - resolution: - { - integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==, - } - engines: { node: ">=10" } - - make-error@1.3.6: - resolution: - { - integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==, - } - - makeerror@1.0.12: - resolution: - { - integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==, - } - - map-obj@1.0.1: - resolution: - { - integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==, - } - engines: { node: ">=0.10.0" } - - map-obj@4.3.0: - resolution: - { - integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==, - } - engines: { node: ">=8" } - - markdown-it@14.1.0: - resolution: - { - integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==, - } - hasBin: true - - markdownlint-cli@0.42.0: - resolution: - { - integrity: sha512-AjkzhhZa3TmEGi/CE2Wpmny69x1IrzqK2gPB0k8SmNMRgnSAJfyEO5FgZdWTHtJ6Nrdv5FWt5c4C5pkG6Dk30A==, - } - engines: { node: ">=18" } - hasBin: true - - markdownlint-micromark@0.1.10: - resolution: - { - integrity: sha512-no5ZfdqAdWGxftCLlySHSgddEjyW4kui4z7amQcGsSKfYC5v/ou+8mIQVyg9KQMeEZLNtz9OPDTj7nnTnoR4FQ==, - } - engines: { node: ">=18" } - - markdownlint@0.35.0: - resolution: - { - integrity: sha512-wgp8yesWjFBL7bycA3hxwHRdsZGJhjhyP1dSxKVKrza0EPFYtn+mHtkVy6dvP1kGSjovyG5B8yNP6Frj0UFUJg==, - } - engines: { node: ">=18" } - - marked@4.3.0: - resolution: - { - integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==, - } - engines: { node: ">= 12" } - hasBin: true - - math-intrinsics@1.1.0: - resolution: - { - integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==, - } - engines: { node: ">= 0.4" } - - mdurl@2.0.0: - resolution: - { - integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==, - } - - memory-fs@0.5.0: - resolution: - { - integrity: sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==, - } - engines: { node: ">=4.3.0 <5.0.0 || >=5.10" } - - memorystream@0.3.1: - resolution: - { - integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==, - } - engines: { node: ">= 0.10.0" } - - meow@8.1.2: - resolution: - { - integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==, - } - engines: { node: ">=10" } - - merge-stream@2.0.0: - resolution: - { - integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==, - } - - merge2@1.4.1: - resolution: - { - integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==, - } - engines: { node: ">= 8" } - - micromatch@4.0.8: - resolution: - { - integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==, - } - engines: { node: ">=8.6" } - - mime-db@1.52.0: - resolution: - { - integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==, - } - engines: { node: ">= 0.6" } - - mime-types@2.1.35: - resolution: - { - integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==, - } - engines: { node: ">= 0.6" } - - mimic-fn@2.1.0: - resolution: - { - integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==, - } - engines: { node: ">=6" } - - min-indent@1.0.1: - resolution: - { - integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==, - } - engines: { node: ">=4" } - - minimatch@10.0.3: - resolution: - { - integrity: sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==, - } - engines: { node: 20 || >=22 } - - minimatch@3.1.2: - resolution: - { - integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==, - } - - minimatch@5.1.6: - resolution: - { - integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==, - } - engines: { node: ">=10" } - - minimatch@9.0.5: - resolution: - { - integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==, - } - engines: { node: ">=16 || 14 >=14.17" } - - minimist-options@4.1.0: - resolution: - { - integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==, - } - engines: { node: ">= 6" } - - minimist@1.2.8: - resolution: - { - integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==, - } - - minipass@7.1.2: - resolution: - { - integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==, - } - engines: { node: ">=16 || 14 >=14.17" } - - mri@1.2.0: - resolution: - { - integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==, - } - engines: { node: ">=4" } - - ms@2.1.3: - resolution: - { - integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==, - } - - natural-compare@1.4.0: - resolution: - { - integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==, - } - - nconf@0.12.1: - resolution: - { - integrity: sha512-p2cfF+B3XXacQdswUYWZ0w6Vld0832A/tuqjLBu3H1sfUcby4N2oVbGhyuCkZv+t3iY3aiFEj7gZGqax9Q2c1w==, - } - engines: { node: ">= 0.4.0" } - - neo-async@2.6.2: - resolution: - { - integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==, - } - - nice-try@1.0.5: - resolution: - { - integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==, - } - - node-fetch@2.7.0: - resolution: - { - integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==, - } - engines: { node: 4.x || >=6.0.0 } - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - - node-int64@0.4.0: - resolution: - { - integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==, - } - - node-releases@2.0.19: - resolution: - { - integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==, - } - - nodemon@3.1.10: - resolution: - { - integrity: sha512-WDjw3pJ0/0jMFmyNDp3gvY2YizjLmmOUQo6DEBY+JgdvW/yQ9mEeSw6H5ythl5Ny2ytb7f9C2nIbjSxMNzbJXw==, - } - engines: { node: ">=10" } - hasBin: true - - normalize-package-data@2.5.0: - resolution: - { - integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==, - } - - normalize-package-data@3.0.3: - resolution: - { - integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==, - } - engines: { node: ">=10" } - - normalize-path@3.0.0: - resolution: - { - integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==, - } - engines: { node: ">=0.10.0" } - - npm-run-all@4.1.5: - resolution: - { - integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==, - } - engines: { node: ">= 4" } - hasBin: true - - npm-run-path@4.0.1: - resolution: - { - integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==, - } - engines: { node: ">=8" } - - nwsapi@2.2.20: - resolution: - { - integrity: sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==, - } - - object-inspect@1.13.4: - resolution: - { - integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==, - } - engines: { node: ">= 0.4" } - - object-keys@1.1.1: - resolution: - { - integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==, - } - engines: { node: ">= 0.4" } - - object.assign@4.1.7: - resolution: - { - integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==, - } - engines: { node: ">= 0.4" } - - once@1.4.0: - resolution: - { - integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==, - } - - onetime@5.1.2: - resolution: - { - integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==, - } - engines: { node: ">=6" } - - opencollective-postinstall@2.0.3: - resolution: - { - integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==, - } - hasBin: true - - optionator@0.9.4: - resolution: - { - integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==, - } - engines: { node: ">= 0.8.0" } - - own-keys@1.0.1: - resolution: - { - integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==, - } - engines: { node: ">= 0.4" } - - p-limit@2.3.0: - resolution: - { - integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==, - } - engines: { node: ">=6" } - - p-limit@3.1.0: - resolution: - { - integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==, - } - engines: { node: ">=10" } - - p-locate@4.1.0: - resolution: - { - integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==, - } - engines: { node: ">=8" } - - p-locate@5.0.0: - resolution: - { - integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==, - } - engines: { node: ">=10" } - - p-try@2.2.0: - resolution: - { - integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==, - } - engines: { node: ">=6" } - - package-json-from-dist@1.0.1: - resolution: - { - integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==, - } - - parent-module@1.0.1: - resolution: - { - integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==, - } - engines: { node: ">=6" } - - parse-json@4.0.0: - resolution: - { - integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==, - } - engines: { node: ">=4" } - - parse-json@5.2.0: - resolution: - { - integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==, - } - engines: { node: ">=8" } - - parse5@7.3.0: - resolution: - { - integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==, - } - - path-exists@4.0.0: - resolution: - { - integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==, - } - engines: { node: ">=8" } - - path-is-absolute@1.0.1: - resolution: - { - integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==, - } - engines: { node: ">=0.10.0" } - - path-key@2.0.1: - resolution: - { - integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==, - } - engines: { node: ">=4" } - - path-key@3.1.1: - resolution: - { - integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==, - } - engines: { node: ">=8" } - - path-parse@1.0.7: - resolution: - { - integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==, - } - - path-scurry@2.0.0: - resolution: - { - integrity: sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==, - } - engines: { node: 20 || >=22 } - - path-type@3.0.0: - resolution: - { - integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==, - } - engines: { node: ">=4" } - - path-type@4.0.0: - resolution: - { - integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==, - } - engines: { node: ">=8" } - - picocolors@1.1.1: - resolution: - { - integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==, - } - - picomatch@2.3.1: - resolution: - { - integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==, - } - engines: { node: ">=8.6" } - - picomatch@3.0.1: - resolution: - { - integrity: sha512-I3EurrIQMlRc9IaAZnqRR044Phh2DXY+55o7uJ0V+hYZAcQYSuFWsc9q5PvyDHUSCe1Qxn/iBz+78s86zWnGag==, - } - engines: { node: ">=10" } - - pidtree@0.3.1: - resolution: - { - integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==, - } - engines: { node: ">=0.10" } - hasBin: true - - pify@3.0.0: - resolution: - { - integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==, - } - engines: { node: ">=4" } - - pirates@4.0.7: - resolution: - { - integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==, - } - engines: { node: ">= 6" } - - pkg-dir@4.2.0: - resolution: - { - integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==, - } - engines: { node: ">=8" } - - pkg-dir@5.0.0: - resolution: - { - integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==, - } - engines: { node: ">=10" } - - please-upgrade-node@3.2.0: - resolution: - { - integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==, - } - - possible-typed-array-names@1.1.0: - resolution: - { - integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==, - } - engines: { node: ">= 0.4" } - - prelude-ls@1.2.1: - resolution: - { - integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==, - } - engines: { node: ">= 0.8.0" } - - prettier@2.8.8: - resolution: - { - integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==, - } - engines: { node: ">=10.13.0" } - hasBin: true - - pretty-format@29.7.0: - resolution: - { - integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==, - } - engines: { node: ^14.15.0 || ^16.10.0 || >=18.0.0 } - - pretty-quick@3.3.1: - resolution: - { - integrity: sha512-3b36UXfYQ+IXXqex6mCca89jC8u0mYLqFAN5eTQKoXO6oCQYcIVYZEB/5AlBHI7JPYygReM2Vv6Vom/Gln7fBg==, - } - engines: { node: ">=10.13" } - hasBin: true - peerDependencies: - prettier: ^2.0.0 - - process-nextick-args@2.0.1: - resolution: - { - integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==, - } - - prompts@2.4.2: - resolution: - { - integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==, - } - engines: { node: ">= 6" } - - prr@1.0.1: - resolution: - { - integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==, - } - - psl@1.15.0: - resolution: - { - integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==, - } - - pstree.remy@1.1.8: - resolution: - { - integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==, - } - - pump@3.0.3: - resolution: - { - integrity: sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==, - } - - punycode.js@2.3.1: - resolution: - { - integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==, - } - engines: { node: ">=6" } - - punycode@1.4.1: - resolution: - { - integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==, - } - - punycode@2.3.1: - resolution: - { - integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==, - } - engines: { node: ">=6" } - - pure-rand@6.1.0: - resolution: - { - integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==, - } - - qs@6.14.0: - resolution: - { - integrity: sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==, - } - engines: { node: ">=0.6" } - - querystringify@2.2.0: - resolution: - { - integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==, - } - - queue-microtask@1.2.3: - resolution: - { - integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==, - } - - quick-lru@4.0.1: - resolution: - { - integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==, - } - engines: { node: ">=8" } - - randombytes@2.1.0: - resolution: - { - integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==, - } - - react-is@18.3.1: - resolution: - { - integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==, - } - - read-pkg-up@7.0.1: - resolution: - { - integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==, - } - engines: { node: ">=8" } - - read-pkg@3.0.0: - resolution: - { - integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==, - } - engines: { node: ">=4" } - - read-pkg@5.2.0: - resolution: - { - integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==, - } - engines: { node: ">=8" } - - readable-stream@2.3.8: - resolution: - { - integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==, - } - - readable-stream@3.6.2: - resolution: - { - integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==, - } - engines: { node: ">= 6" } - - readdirp@3.6.0: - resolution: - { - integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==, - } - engines: { node: ">=8.10.0" } - - rechoir@0.7.1: - resolution: - { - integrity: sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==, - } - engines: { node: ">= 0.10" } - - redent@3.0.0: - resolution: - { - integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==, - } - engines: { node: ">=8" } - - reflect.getprototypeof@1.0.10: - resolution: - { - integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==, - } - engines: { node: ">= 0.4" } - - regexp.prototype.flags@1.5.4: - resolution: - { - integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==, - } - engines: { node: ">= 0.4" } - - require-directory@2.1.1: - resolution: - { - integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==, - } - engines: { node: ">=0.10.0" } - - require-from-string@2.0.2: - resolution: - { - integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==, - } - engines: { node: ">=0.10.0" } - - requires-port@1.0.0: - resolution: - { - integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==, - } - - resolve-cwd@3.0.0: - resolution: - { - integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==, - } - engines: { node: ">=8" } - - resolve-from@4.0.0: - resolution: - { - integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==, - } - engines: { node: ">=4" } - - resolve-from@5.0.0: - resolution: - { - integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==, - } - engines: { node: ">=8" } - - resolve-global@1.0.0: - resolution: - { - integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==, - } - engines: { node: ">=8" } - - resolve.exports@2.0.3: - resolution: - { - integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==, - } - engines: { node: ">=10" } - - resolve@1.22.10: - resolution: - { - integrity: sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==, - } - engines: { node: ">= 0.4" } - hasBin: true - - reusify@1.1.0: - resolution: - { - integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==, - } - engines: { iojs: ">=1.0.0", node: ">=0.10.0" } - - rimraf@3.0.2: - resolution: - { - integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==, - } - deprecated: Rimraf versions prior to v4 are no longer supported - hasBin: true - - run-con@1.3.2: - resolution: - { - integrity: sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==, - } - hasBin: true - - run-parallel@1.2.0: - resolution: - { - integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==, - } - - safe-array-concat@1.1.3: - resolution: - { - integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==, - } - engines: { node: ">=0.4" } - - safe-buffer@5.1.2: - resolution: - { - integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==, - } - - safe-buffer@5.2.1: - resolution: - { - integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==, - } - - safe-push-apply@1.0.0: - resolution: - { - integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==, - } - engines: { node: ">= 0.4" } - - safe-regex-test@1.1.0: - resolution: - { - integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==, - } - engines: { node: ">= 0.4" } - - safer-buffer@2.1.2: - resolution: - { - integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==, - } - - saxes@6.0.0: - resolution: - { - integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==, - } - engines: { node: ">=v12.22.7" } - - schema-utils@4.3.2: - resolution: - { - integrity: sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==, - } - engines: { node: ">= 10.13.0" } - - secure-keys@1.0.0: - resolution: - { - integrity: sha512-nZi59hW3Sl5P3+wOO89eHBAAGwmCPd2aE1+dLZV5MO+ItQctIvAqihzaAXIQhvtH4KJPxM080HsnqltR2y8cWg==, - } - - semantic-release-plugin-update-version-in-files@1.1.0: - resolution: - { - integrity: sha512-OWBrved3Rr0w3YP4iID81MhG9qhGrG+XtxdO9VMhKJ9qte3yBdMz5cSxDiPE/uhnGJQF00fqQetY3yhHFGabWw==, - } - - semver-compare@1.0.0: - resolution: - { - integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==, - } - - semver-regex@3.1.4: - resolution: - { - integrity: sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==, - } - engines: { node: ">=8" } - - semver@5.7.2: - resolution: - { - integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==, - } - hasBin: true - - semver@6.3.1: - resolution: - { - integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==, - } - hasBin: true - - semver@7.5.4: - resolution: - { - integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==, - } - engines: { node: ">=10" } - hasBin: true - - semver@7.7.2: - resolution: - { - integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==, - } - engines: { node: ">=10" } - hasBin: true - - serialize-javascript@6.0.2: - resolution: - { - integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==, - } - - set-function-length@1.2.2: - resolution: - { - integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==, - } - engines: { node: ">= 0.4" } - - set-function-name@2.0.2: - resolution: - { - integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==, - } - engines: { node: ">= 0.4" } - - set-proto@1.0.0: - resolution: - { - integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==, - } - engines: { node: ">= 0.4" } - - shallow-clone@3.0.1: - resolution: - { - integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==, - } - engines: { node: ">=8" } - - shebang-command@1.2.0: - resolution: - { - integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==, - } - engines: { node: ">=0.10.0" } - - shebang-command@2.0.0: - resolution: - { - integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==, - } - engines: { node: ">=8" } - - shebang-regex@1.0.0: - resolution: - { - integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==, - } - engines: { node: ">=0.10.0" } - - shebang-regex@3.0.0: - resolution: - { - integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==, - } - engines: { node: ">=8" } - - shell-quote@1.8.3: - resolution: - { - integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==, - } - engines: { node: ">= 0.4" } - - shiki@0.10.1: - resolution: - { - integrity: sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==, - } - - side-channel-list@1.0.0: - resolution: - { - integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==, - } - engines: { node: ">= 0.4" } - - side-channel-map@1.0.1: - resolution: - { - integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==, - } - engines: { node: ">= 0.4" } - - side-channel-weakmap@1.0.2: - resolution: - { - integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==, - } - engines: { node: ">= 0.4" } - - side-channel@1.1.0: - resolution: - { - integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==, - } - engines: { node: ">= 0.4" } - - signal-exit@3.0.7: - resolution: - { - integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==, - } - - signal-exit@4.1.0: - resolution: - { - integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==, - } - engines: { node: ">=14" } - - simple-update-notifier@2.0.0: - resolution: - { - integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==, - } - engines: { node: ">=10" } - - sisteransi@1.0.5: - resolution: - { - integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==, - } - - slash@3.0.0: - resolution: - { - integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==, - } - engines: { node: ">=8" } - - smol-toml@1.3.4: - resolution: - { - integrity: sha512-UOPtVuYkzYGee0Bd2Szz8d2G3RfMfJ2t3qVdZUAozZyAk+a0Sxa+QKix0YCwjL/A1RR0ar44nCxaoN9FxdJGwA==, - } - engines: { node: ">= 18" } - - source-map-support@0.5.13: - resolution: - { - integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==, - } - - source-map-support@0.5.21: - resolution: - { - integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==, - } - - source-map@0.6.1: - resolution: - { - integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==, - } - engines: { node: ">=0.10.0" } - - spdx-correct@3.2.0: - resolution: - { - integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==, - } - - spdx-exceptions@2.5.0: - resolution: - { - integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==, - } - - spdx-expression-parse@3.0.1: - resolution: - { - integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==, - } - - spdx-license-ids@3.0.21: - resolution: - { - integrity: sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==, - } - - split2@3.2.2: - resolution: - { - integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==, - } - - sprintf-js@1.0.3: - resolution: - { - integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==, - } - - stack-utils@2.0.6: - resolution: - { - integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==, - } - engines: { node: ">=10" } - - stop-iteration-iterator@1.1.0: - resolution: - { - integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==, - } - engines: { node: ">= 0.4" } - - stream-browserify@3.0.0: - resolution: - { - integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==, - } - - string-length@4.0.2: - resolution: - { - integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==, - } - engines: { node: ">=10" } - - string-width@4.2.3: - resolution: - { - integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==, - } - engines: { node: ">=8" } - - string-width@5.1.2: - resolution: - { - integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==, - } - engines: { node: ">=12" } - - string.prototype.padend@3.1.6: - resolution: - { - integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==, - } - engines: { node: ">= 0.4" } - - string.prototype.trim@1.2.10: - resolution: - { - integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==, - } - engines: { node: ">= 0.4" } - - string.prototype.trimend@1.0.9: - resolution: - { - integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==, - } - engines: { node: ">= 0.4" } - - string.prototype.trimstart@1.0.8: - resolution: - { - integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==, - } - engines: { node: ">= 0.4" } - - string_decoder@1.1.1: - resolution: - { - integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==, - } - - string_decoder@1.3.0: - resolution: - { - integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==, - } - - strip-ansi@6.0.1: - resolution: - { - integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==, - } - engines: { node: ">=8" } - - strip-ansi@7.1.0: - resolution: - { - integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==, - } - engines: { node: ">=12" } - - strip-bom@3.0.0: - resolution: - { - integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==, - } - engines: { node: ">=4" } - - strip-bom@4.0.0: - resolution: - { - integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==, - } - engines: { node: ">=8" } - - strip-final-newline@2.0.0: - resolution: - { - integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==, - } - engines: { node: ">=6" } - - strip-indent@3.0.0: - resolution: - { - integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==, - } - engines: { node: ">=8" } - - strip-json-comments@3.1.1: - resolution: - { - integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==, - } - engines: { node: ">=8" } - - supports-color@5.5.0: - resolution: - { - integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==, - } - engines: { node: ">=4" } - - supports-color@7.2.0: - resolution: - { - integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==, - } - engines: { node: ">=8" } - - supports-color@8.1.1: - resolution: - { - integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==, - } - engines: { node: ">=10" } - - supports-preserve-symlinks-flag@1.0.0: - resolution: - { - integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==, - } - engines: { node: ">= 0.4" } - - symbol-tree@3.2.4: - resolution: - { - integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==, - } - - tapable@1.1.3: - resolution: - { - integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==, - } - engines: { node: ">=6" } - - tapable@2.2.2: - resolution: - { - integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==, - } - engines: { node: ">=6" } - - terser-webpack-plugin@5.3.14: - resolution: - { - integrity: sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==, - } - engines: { node: ">= 10.13.0" } - peerDependencies: - "@swc/core": "*" - esbuild: "*" - uglify-js: "*" - webpack: ^5.1.0 - peerDependenciesMeta: - "@swc/core": - optional: true - esbuild: - optional: true - uglify-js: - optional: true - - terser@5.42.0: - resolution: - { - integrity: sha512-UYCvU9YQW2f/Vwl+P0GfhxJxbUGLwd+5QrrGgLajzWAtC/23AX0vcise32kkP7Eu0Wu9VlzzHAXkLObgjQfFlQ==, - } - engines: { node: ">=10" } - hasBin: true - - test-exclude@6.0.0: - resolution: - { - integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==, - } - engines: { node: ">=8" } - - text-extensions@1.9.0: - resolution: - { - integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==, - } - engines: { node: ">=0.10" } - - text-table@0.2.0: - resolution: - { - integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==, - } - - through2@4.0.2: - resolution: - { - integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==, - } - - through@2.3.8: - resolution: - { - integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==, - } - - tmpl@1.0.5: - resolution: - { - integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==, - } - - to-regex-range@5.0.1: - resolution: - { - integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==, - } - engines: { node: ">=8.0" } - - touch@3.1.1: - resolution: - { - integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==, - } - hasBin: true - - tough-cookie@4.1.4: - resolution: - { - integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==, - } - engines: { node: ">=6" } - - tr46@0.0.3: - resolution: - { - integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==, - } - - tr46@3.0.0: - resolution: - { - integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==, - } - engines: { node: ">=12" } - - trim-newlines@3.0.1: - resolution: - { - integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==, - } - engines: { node: ">=8" } - - ts-api-utils@2.1.0: - resolution: - { - integrity: sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==, - } - engines: { node: ">=18.12" } - peerDependencies: - typescript: ">=4.8.4" - - ts-jest@29.4.0: - resolution: - { - integrity: sha512-d423TJMnJGu80/eSgfQ5w/R+0zFJvdtTxwtF9KzFFunOpSeD+79lHJQIiAhluJoyGRbvj9NZJsl9WjCUo0ND7Q==, - } - engines: { node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0 } - hasBin: true - peerDependencies: - "@babel/core": ">=7.0.0-beta.0 <8" - "@jest/transform": ^29.0.0 || ^30.0.0 - "@jest/types": ^29.0.0 || ^30.0.0 - babel-jest: ^29.0.0 || ^30.0.0 - esbuild: "*" - jest: ^29.0.0 || ^30.0.0 - jest-util: ^29.0.0 || ^30.0.0 - typescript: ">=4.3 <6" - peerDependenciesMeta: - "@babel/core": - optional: true - "@jest/transform": - optional: true - "@jest/types": - optional: true - babel-jest: - optional: true - esbuild: - optional: true - jest-util: - optional: true - - ts-loader@8.4.0: - resolution: - { - integrity: sha512-6nFY3IZ2//mrPc+ImY3hNWx1vCHyEhl6V+wLmL4CZcm6g1CqX7UKrkc6y0i4FwcfOhxyMPCfaEvh20f4r9GNpw==, - } - engines: { node: ">=10.0.0" } - peerDependencies: - typescript: "*" - webpack: "*" - - ts-node@10.9.2: - resolution: - { - integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==, - } - hasBin: true - peerDependencies: - "@swc/core": ">=1.2.50" - "@swc/wasm": ">=1.2.50" - "@types/node": "*" - typescript: ">=2.7" - peerDependenciesMeta: - "@swc/core": - optional: true - "@swc/wasm": - optional: true - - tslib@2.8.1: - resolution: - { - integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==, - } - - type-check@0.4.0: - resolution: - { - integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==, - } - engines: { node: ">= 0.8.0" } - - type-detect@4.0.8: - resolution: - { - integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==, - } - engines: { node: ">=4" } - - type-fest@0.18.1: - resolution: - { - integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==, - } - engines: { node: ">=10" } - - type-fest@0.20.2: - resolution: - { - integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==, - } - engines: { node: ">=10" } - - type-fest@0.21.3: - resolution: - { - integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==, - } - engines: { node: ">=10" } - - type-fest@0.6.0: - resolution: - { - integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==, - } - engines: { node: ">=8" } - - type-fest@0.8.1: - resolution: - { - integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==, - } - engines: { node: ">=8" } - - type-fest@4.41.0: - resolution: - { - integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==, - } - engines: { node: ">=16" } - - typed-array-buffer@1.0.3: - resolution: - { - integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==, - } - engines: { node: ">= 0.4" } - - typed-array-byte-length@1.0.3: - resolution: - { - integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==, - } - engines: { node: ">= 0.4" } - - typed-array-byte-offset@1.0.4: - resolution: - { - integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==, - } - engines: { node: ">= 0.4" } - - typed-array-length@1.0.7: - resolution: - { - integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==, - } - engines: { node: ">= 0.4" } - - typedoc@0.22.18: - resolution: - { - integrity: sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA==, - } - engines: { node: ">= 12.10.0" } - hasBin: true - peerDependencies: - typescript: 4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x - - typescript@4.9.5: - resolution: - { - integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==, - } - engines: { node: ">=4.2.0" } - hasBin: true - - uc.micro@2.1.0: - resolution: - { - integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==, - } - - unbox-primitive@1.1.0: - resolution: - { - integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==, - } - engines: { node: ">= 0.4" } - - undefsafe@2.0.5: - resolution: - { - integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==, - } - - undici-types@5.26.5: - resolution: - { - integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==, - } - - universalify@0.2.0: - resolution: - { - integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==, - } - engines: { node: ">= 4.0.0" } - - universalify@2.0.1: - resolution: - { - integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==, - } - engines: { node: ">= 10.0.0" } - - update-browserslist-db@1.1.3: - resolution: - { - integrity: sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==, - } - hasBin: true - peerDependencies: - browserslist: ">= 4.21.0" - - uri-js@4.4.1: - resolution: - { - integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==, - } - - url-parse@1.5.10: - resolution: - { - integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==, - } - - url@0.11.4: - resolution: - { - integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==, - } - engines: { node: ">= 0.4" } - - util-deprecate@1.0.2: - resolution: - { - integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==, - } - - util@0.12.5: - resolution: - { - integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==, - } - - v8-compile-cache-lib@3.0.1: - resolution: - { - integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==, - } - - v8-to-istanbul@9.3.0: - resolution: - { - integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==, - } - engines: { node: ">=10.12.0" } - - validate-npm-package-license@3.0.4: - resolution: - { - integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==, - } - - vscode-oniguruma@1.7.0: - resolution: - { - integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==, - } - - vscode-textmate@5.2.0: - resolution: - { - integrity: sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==, - } - - w3c-xmlserializer@4.0.0: - resolution: - { - integrity: sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==, - } - engines: { node: ">=14" } - - walker@1.0.8: - resolution: - { - integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==, - } - - watchpack@2.4.4: - resolution: - { - integrity: sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==, - } - engines: { node: ">=10.13.0" } - - webidl-conversions@3.0.1: - resolution: - { - integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==, - } - - webidl-conversions@7.0.0: - resolution: - { - integrity: sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==, - } - engines: { node: ">=12" } - - webpack-cli@4.10.0: - resolution: - { - integrity: sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==, - } - engines: { node: ">=10.13.0" } - hasBin: true - peerDependencies: - "@webpack-cli/generators": "*" - "@webpack-cli/migrate": "*" - webpack: 4.x.x || 5.x.x - webpack-bundle-analyzer: "*" - webpack-dev-server: "*" - peerDependenciesMeta: - "@webpack-cli/generators": - optional: true - "@webpack-cli/migrate": - optional: true - webpack-bundle-analyzer: - optional: true - webpack-dev-server: - optional: true - - webpack-merge@5.10.0: - resolution: - { - integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==, - } - engines: { node: ">=10.0.0" } - - webpack-sources@3.3.2: - resolution: - { - integrity: sha512-ykKKus8lqlgXX/1WjudpIEjqsafjOTcOJqxnAbMLAu/KCsDCJ6GBtvscewvTkrn24HsnvFwrSCbenFrhtcCsAA==, - } - engines: { node: ">=10.13.0" } - - webpack@5.99.9: - resolution: - { - integrity: sha512-brOPwM3JnmOa+7kd3NsmOUOwbDAj8FT9xDsG3IW0MgbN9yZV7Oi/s/+MNQ/EcSMqw7qfoRyXPoeEWT8zLVdVGg==, - } - engines: { node: ">=10.13.0" } - hasBin: true - peerDependencies: - webpack-cli: "*" - peerDependenciesMeta: - webpack-cli: - optional: true - - whatwg-encoding@2.0.0: - resolution: - { - integrity: sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==, - } - engines: { node: ">=12" } - - whatwg-mimetype@3.0.0: - resolution: - { - integrity: sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==, - } - engines: { node: ">=12" } - - whatwg-url@11.0.0: - resolution: - { - integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==, - } - engines: { node: ">=12" } - - whatwg-url@5.0.0: - resolution: - { - integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==, - } - - which-boxed-primitive@1.1.1: - resolution: - { - integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==, - } - engines: { node: ">= 0.4" } - - which-builtin-type@1.2.1: - resolution: - { - integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==, - } - engines: { node: ">= 0.4" } - - which-collection@1.0.2: - resolution: - { - integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==, - } - engines: { node: ">= 0.4" } - - which-pm-runs@1.1.0: - resolution: - { - integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==, - } - engines: { node: ">=4" } - - which-typed-array@1.1.19: - resolution: - { - integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==, - } - engines: { node: ">= 0.4" } - - which@1.3.1: - resolution: - { - integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==, - } - hasBin: true - - which@2.0.2: - resolution: - { - integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==, - } - engines: { node: ">= 8" } - hasBin: true - - wildcard@2.0.1: - resolution: - { - integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==, - } - - word-wrap@1.2.5: - resolution: - { - integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==, - } - engines: { node: ">=0.10.0" } - - wrap-ansi@7.0.0: - resolution: - { - integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==, - } - engines: { node: ">=10" } - - wrap-ansi@8.1.0: - resolution: - { - integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==, - } - engines: { node: ">=12" } - - wrappy@1.0.2: - resolution: - { - integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==, - } - - write-file-atomic@4.0.2: - resolution: - { - integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==, - } - engines: { node: ^12.13.0 || ^14.15.0 || >=16.0.0 } - - ws@8.18.2: - resolution: - { - integrity: sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==, - } - engines: { node: ">=10.0.0" } - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ">=5.0.2" - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - - xml-name-validator@4.0.0: - resolution: - { - integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==, - } - engines: { node: ">=12" } - - xmlchars@2.2.0: - resolution: - { - integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==, - } - - y18n@5.0.8: - resolution: - { - integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==, - } - engines: { node: ">=10" } - - yallist@3.1.1: - resolution: - { - integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==, - } - - yallist@4.0.0: - resolution: - { - integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==, - } - - yaml-lint@1.7.0: - resolution: - { - integrity: sha512-zeBC/kskKQo4zuoGQ+IYjw6C9a/YILr2SXoEZA9jM0COrSwvwVbfTiFegT8qYBSBgOwLMWGL8sY137tOmFXGnQ==, - } - hasBin: true - - yaml@1.10.2: - resolution: - { - integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==, - } - engines: { node: ">= 6" } - - yargs-parser@20.2.9: - resolution: - { - integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==, - } - engines: { node: ">=10" } - - yargs-parser@21.1.1: - resolution: - { - integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==, - } - engines: { node: ">=12" } - - yargs@16.2.0: - resolution: - { - integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==, - } - engines: { node: ">=10" } - - yargs@17.7.2: - resolution: - { - integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==, - } - engines: { node: ">=12" } - - yn@3.1.1: - resolution: - { - integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==, - } - engines: { node: ">=6" } - - yocto-queue@0.1.0: - resolution: - { - integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==, - } - engines: { node: ">=10" } - -snapshots: - "@ampproject/remapping@2.3.0": - dependencies: - "@jridgewell/gen-mapping": 0.3.8 - "@jridgewell/trace-mapping": 0.3.25 - - "@babel/code-frame@7.27.1": - dependencies: - "@babel/helper-validator-identifier": 7.27.1 - js-tokens: 4.0.0 - picocolors: 1.1.1 - - "@babel/compat-data@7.27.5": {} - - "@babel/core@7.27.4": - dependencies: - "@ampproject/remapping": 2.3.0 - "@babel/code-frame": 7.27.1 - "@babel/generator": 7.27.5 - "@babel/helper-compilation-targets": 7.27.2 - "@babel/helper-module-transforms": 7.27.3(@babel/core@7.27.4) - "@babel/helpers": 7.27.6 - "@babel/parser": 7.27.5 - "@babel/template": 7.27.2 - "@babel/traverse": 7.27.4 - "@babel/types": 7.27.6 - convert-source-map: 2.0.0 - debug: 4.4.1(supports-color@5.5.0) - gensync: 1.0.0-beta.2 - json5: 2.2.3 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - "@babel/generator@7.27.5": - dependencies: - "@babel/parser": 7.27.5 - "@babel/types": 7.27.6 - "@jridgewell/gen-mapping": 0.3.8 - "@jridgewell/trace-mapping": 0.3.25 - jsesc: 3.1.0 - - "@babel/helper-compilation-targets@7.27.2": - dependencies: - "@babel/compat-data": 7.27.5 - "@babel/helper-validator-option": 7.27.1 - browserslist: 4.25.0 - lru-cache: 5.1.1 - semver: 6.3.1 - - "@babel/helper-module-imports@7.27.1": - dependencies: - "@babel/traverse": 7.27.4 - "@babel/types": 7.27.6 - transitivePeerDependencies: - - supports-color - - "@babel/helper-module-transforms@7.27.3(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-module-imports": 7.27.1 - "@babel/helper-validator-identifier": 7.27.1 - "@babel/traverse": 7.27.4 - transitivePeerDependencies: - - supports-color - - "@babel/helper-plugin-utils@7.27.1": {} - - "@babel/helper-string-parser@7.27.1": {} - - "@babel/helper-validator-identifier@7.27.1": {} - - "@babel/helper-validator-option@7.27.1": {} - - "@babel/helpers@7.27.6": - dependencies: - "@babel/template": 7.27.2 - "@babel/types": 7.27.6 - - "@babel/parser@7.27.5": - dependencies: - "@babel/types": 7.27.6 - - "@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-import-attributes@7.27.1(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-jsx@7.27.1(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/plugin-syntax-typescript@7.27.1(@babel/core@7.27.4)": - dependencies: - "@babel/core": 7.27.4 - "@babel/helper-plugin-utils": 7.27.1 - - "@babel/template@7.27.2": - dependencies: - "@babel/code-frame": 7.27.1 - "@babel/parser": 7.27.5 - "@babel/types": 7.27.6 - - "@babel/traverse@7.27.4": - dependencies: - "@babel/code-frame": 7.27.1 - "@babel/generator": 7.27.5 - "@babel/parser": 7.27.5 - "@babel/template": 7.27.2 - "@babel/types": 7.27.6 - debug: 4.4.1(supports-color@5.5.0) - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - - "@babel/types@7.27.6": - dependencies: - "@babel/helper-string-parser": 7.27.1 - "@babel/helper-validator-identifier": 7.27.1 - - "@bcoe/v8-coverage@0.2.3": {} - - "@commitlint/cli@17.8.1": - dependencies: - "@commitlint/format": 17.8.1 - "@commitlint/lint": 17.8.1 - "@commitlint/load": 17.8.1 - "@commitlint/read": 17.8.1 - "@commitlint/types": 17.8.1 - execa: 5.1.1 - lodash.isfunction: 3.0.9 - resolve-from: 5.0.0 - resolve-global: 1.0.0 - yargs: 17.7.2 - transitivePeerDependencies: - - "@swc/core" - - "@swc/wasm" - - "@commitlint/config-conventional@17.8.1": - dependencies: - conventional-changelog-conventionalcommits: 6.1.0 - - "@commitlint/config-validator@17.8.1": - dependencies: - "@commitlint/types": 17.8.1 - ajv: 8.17.1 - - "@commitlint/ensure@17.8.1": - dependencies: - "@commitlint/types": 17.8.1 - lodash.camelcase: 4.3.0 - lodash.kebabcase: 4.1.1 - lodash.snakecase: 4.1.1 - lodash.startcase: 4.4.0 - lodash.upperfirst: 4.3.1 - - "@commitlint/execute-rule@17.8.1": {} - - "@commitlint/format@17.8.1": - dependencies: - "@commitlint/types": 17.8.1 - chalk: 4.1.2 - - "@commitlint/is-ignored@17.8.1": - dependencies: - "@commitlint/types": 17.8.1 - semver: 7.5.4 - - "@commitlint/lint@17.8.1": - dependencies: - "@commitlint/is-ignored": 17.8.1 - "@commitlint/parse": 17.8.1 - "@commitlint/rules": 17.8.1 - "@commitlint/types": 17.8.1 - - "@commitlint/load@17.8.1": - dependencies: - "@commitlint/config-validator": 17.8.1 - "@commitlint/execute-rule": 17.8.1 - "@commitlint/resolve-extends": 17.8.1 - "@commitlint/types": 17.8.1 - "@types/node": 20.5.1 - chalk: 4.1.2 - cosmiconfig: 8.3.6(typescript@4.9.5) - cosmiconfig-typescript-loader: 4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@4.9.5))(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5))(typescript@4.9.5) - lodash.isplainobject: 4.0.6 - lodash.merge: 4.6.2 - lodash.uniq: 4.5.0 - resolve-from: 5.0.0 - ts-node: 10.9.2(@types/node@20.5.1)(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - "@swc/core" - - "@swc/wasm" - - "@commitlint/message@17.8.1": {} - - "@commitlint/parse@17.8.1": - dependencies: - "@commitlint/types": 17.8.1 - conventional-changelog-angular: 6.0.0 - conventional-commits-parser: 4.0.0 - - "@commitlint/read@17.8.1": - dependencies: - "@commitlint/top-level": 17.8.1 - "@commitlint/types": 17.8.1 - fs-extra: 11.3.0 - git-raw-commits: 2.0.11 - minimist: 1.2.8 - - "@commitlint/resolve-extends@17.8.1": - dependencies: - "@commitlint/config-validator": 17.8.1 - "@commitlint/types": 17.8.1 - import-fresh: 3.3.1 - lodash.mergewith: 4.6.2 - resolve-from: 5.0.0 - resolve-global: 1.0.0 - - "@commitlint/rules@17.8.1": - dependencies: - "@commitlint/ensure": 17.8.1 - "@commitlint/message": 17.8.1 - "@commitlint/to-lines": 17.8.1 - "@commitlint/types": 17.8.1 - execa: 5.1.1 - - "@commitlint/to-lines@17.8.1": {} - - "@commitlint/top-level@17.8.1": - dependencies: - find-up: 5.0.0 - - "@commitlint/types@17.8.1": - dependencies: - chalk: 4.1.2 - - "@cspotcode/source-map-support@0.8.1": - dependencies: - "@jridgewell/trace-mapping": 0.3.9 - - "@deepgram/captions@1.2.0": - dependencies: - dayjs: 1.11.13 - - "@discoveryjs/json-ext@0.5.7": {} - - "@eslint-community/eslint-utils@4.7.0(eslint@8.57.1)": - dependencies: - eslint: 8.57.1 - eslint-visitor-keys: 3.4.3 - - "@eslint-community/regexpp@4.12.1": {} - - "@eslint/eslintrc@2.1.4": - dependencies: - ajv: 6.12.6 - debug: 4.4.1(supports-color@5.5.0) - espree: 9.6.1 - globals: 13.24.0 - ignore: 5.3.2 - import-fresh: 3.3.1 - js-yaml: 4.1.0 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - - "@eslint/js@8.57.1": {} - - "@humanwhocodes/config-array@0.13.0": - dependencies: - "@humanwhocodes/object-schema": 2.0.3 - debug: 4.4.1(supports-color@5.5.0) - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - - "@humanwhocodes/module-importer@1.0.1": {} - - "@humanwhocodes/object-schema@2.0.3": {} - - "@isaacs/balanced-match@4.0.1": {} - - "@isaacs/brace-expansion@5.0.0": - dependencies: - "@isaacs/balanced-match": 4.0.1 - - "@isaacs/cliui@8.0.2": - dependencies: - string-width: 5.1.2 - string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 - strip-ansi-cjs: strip-ansi@6.0.1 - wrap-ansi: 8.1.0 - wrap-ansi-cjs: wrap-ansi@7.0.0 - - "@istanbuljs/load-nyc-config@1.1.0": - dependencies: - camelcase: 5.3.1 - find-up: 4.1.0 - get-package-type: 0.1.0 - js-yaml: 3.14.1 - resolve-from: 5.0.0 - - "@istanbuljs/schema@0.1.3": {} - - "@jest/console@29.7.0": - dependencies: - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - chalk: 4.1.2 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - - "@jest/core@29.7.0(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5))": - dependencies: - "@jest/console": 29.7.0 - "@jest/reporters": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - ci-info: 3.9.0 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)) - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-resolve-dependencies: 29.7.0 - jest-runner: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - jest-watcher: 29.7.0 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-ansi: 6.0.1 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - ts-node - - "@jest/environment@29.7.0": - dependencies: - "@jest/fake-timers": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - jest-mock: 29.7.0 - - "@jest/expect-utils@29.7.0": - dependencies: - jest-get-type: 29.6.3 - - "@jest/expect@29.7.0": - dependencies: - expect: 29.7.0 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - "@jest/fake-timers@29.7.0": - dependencies: - "@jest/types": 29.6.3 - "@sinonjs/fake-timers": 10.3.0 - "@types/node": 18.19.112 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - "@jest/globals@29.7.0": - dependencies: - "@jest/environment": 29.7.0 - "@jest/expect": 29.7.0 - "@jest/types": 29.6.3 - jest-mock: 29.7.0 - transitivePeerDependencies: - - supports-color - - "@jest/reporters@29.7.0": - dependencies: - "@bcoe/v8-coverage": 0.2.3 - "@jest/console": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@jridgewell/trace-mapping": 0.3.25 - "@types/node": 18.19.112 - chalk: 4.1.2 - collect-v8-coverage: 1.0.2 - exit: 0.1.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-instrument: 6.0.3 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 4.0.1 - istanbul-reports: 3.1.7 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - jest-worker: 29.7.0 - slash: 3.0.0 - string-length: 4.0.2 - strip-ansi: 6.0.1 - v8-to-istanbul: 9.3.0 - transitivePeerDependencies: - - supports-color - - "@jest/schemas@29.6.3": - dependencies: - "@sinclair/typebox": 0.27.8 - - "@jest/source-map@29.6.3": - dependencies: - "@jridgewell/trace-mapping": 0.3.25 - callsites: 3.1.0 - graceful-fs: 4.2.11 - - "@jest/test-result@29.7.0": - dependencies: - "@jest/console": 29.7.0 - "@jest/types": 29.6.3 - "@types/istanbul-lib-coverage": 2.0.6 - collect-v8-coverage: 1.0.2 - - "@jest/test-sequencer@29.7.0": - dependencies: - "@jest/test-result": 29.7.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - slash: 3.0.0 - - "@jest/transform@29.7.0": - dependencies: - "@babel/core": 7.27.4 - "@jest/types": 29.6.3 - "@jridgewell/trace-mapping": 0.3.25 - babel-plugin-istanbul: 6.1.1 - chalk: 4.1.2 - convert-source-map: 2.0.0 - fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - micromatch: 4.0.8 - pirates: 4.0.7 - slash: 3.0.0 - write-file-atomic: 4.0.2 - transitivePeerDependencies: - - supports-color - - "@jest/types@29.6.3": - dependencies: - "@jest/schemas": 29.6.3 - "@types/istanbul-lib-coverage": 2.0.6 - "@types/istanbul-reports": 3.0.4 - "@types/node": 18.19.112 - "@types/yargs": 17.0.33 - chalk: 4.1.2 - - "@jridgewell/gen-mapping@0.3.8": - dependencies: - "@jridgewell/set-array": 1.2.1 - "@jridgewell/sourcemap-codec": 1.5.0 - "@jridgewell/trace-mapping": 0.3.25 - - "@jridgewell/resolve-uri@3.1.2": {} - - "@jridgewell/set-array@1.2.1": {} - - "@jridgewell/source-map@0.3.6": - dependencies: - "@jridgewell/gen-mapping": 0.3.8 - "@jridgewell/trace-mapping": 0.3.25 - - "@jridgewell/sourcemap-codec@1.5.0": {} - - "@jridgewell/trace-mapping@0.3.25": - dependencies: - "@jridgewell/resolve-uri": 3.1.2 - "@jridgewell/sourcemap-codec": 1.5.0 - - "@jridgewell/trace-mapping@0.3.9": - dependencies: - "@jridgewell/resolve-uri": 3.1.2 - "@jridgewell/sourcemap-codec": 1.5.0 - - "@nodelib/fs.scandir@2.1.5": - dependencies: - "@nodelib/fs.stat": 2.0.5 - run-parallel: 1.2.0 - - "@nodelib/fs.stat@2.0.5": {} - - "@nodelib/fs.walk@1.2.8": - dependencies: - "@nodelib/fs.scandir": 2.1.5 - fastq: 1.19.1 - - "@sinclair/typebox@0.27.8": {} - - "@sinonjs/commons@3.0.1": - dependencies: - type-detect: 4.0.8 - - "@sinonjs/fake-timers@10.3.0": - dependencies: - "@sinonjs/commons": 3.0.1 - - "@tootallnate/once@2.0.0": {} - - "@tsconfig/node10@1.0.11": {} - - "@tsconfig/node12@1.0.11": {} - - "@tsconfig/node14@1.0.3": {} - - "@tsconfig/node16@1.0.4": {} - - "@types/babel__core@7.20.5": - dependencies: - "@babel/parser": 7.27.5 - "@babel/types": 7.27.6 - "@types/babel__generator": 7.27.0 - "@types/babel__template": 7.4.4 - "@types/babel__traverse": 7.20.7 - - "@types/babel__generator@7.27.0": - dependencies: - "@babel/types": 7.27.6 - - "@types/babel__template@7.4.4": - dependencies: - "@babel/parser": 7.27.5 - "@babel/types": 7.27.6 - - "@types/babel__traverse@7.20.7": - dependencies: - "@babel/types": 7.27.6 - - "@types/eslint-scope@3.7.7": - dependencies: - "@types/eslint": 9.6.1 - "@types/estree": 1.0.8 - - "@types/eslint@9.6.1": - dependencies: - "@types/estree": 1.0.8 - "@types/json-schema": 7.0.15 - - "@types/estree@1.0.8": {} - - "@types/graceful-fs@4.1.9": - dependencies: - "@types/node": 18.19.112 - - "@types/istanbul-lib-coverage@2.0.6": {} - - "@types/istanbul-lib-report@3.0.3": - dependencies: - "@types/istanbul-lib-coverage": 2.0.6 - - "@types/istanbul-reports@3.0.4": - dependencies: - "@types/istanbul-lib-report": 3.0.3 - - "@types/jest@29.5.14": - dependencies: - expect: 29.7.0 - pretty-format: 29.7.0 - - "@types/jsdom@20.0.1": - dependencies: - "@types/node": 18.19.112 - "@types/tough-cookie": 4.0.5 - parse5: 7.3.0 - - "@types/json-schema@7.0.15": {} - - "@types/minimist@1.2.5": {} - - "@types/node@18.19.112": - dependencies: - undici-types: 5.26.5 - - "@types/node@20.5.1": {} - - "@types/normalize-package-data@2.4.4": {} - - "@types/parse-json@4.0.2": {} - - "@types/stack-utils@2.0.3": {} - - "@types/tough-cookie@4.0.5": {} - - "@types/ws@8.18.1": - dependencies: - "@types/node": 18.19.112 - - "@types/yargs-parser@21.0.3": {} - - "@types/yargs@17.0.33": - dependencies: - "@types/yargs-parser": 21.0.3 - - "@typescript-eslint/eslint-plugin@8.34.0(@typescript-eslint/parser@8.34.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)": - dependencies: - "@eslint-community/regexpp": 4.12.1 - "@typescript-eslint/parser": 8.34.0(eslint@8.57.1)(typescript@4.9.5) - "@typescript-eslint/scope-manager": 8.34.0 - "@typescript-eslint/type-utils": 8.34.0(eslint@8.57.1)(typescript@4.9.5) - "@typescript-eslint/utils": 8.34.0(eslint@8.57.1)(typescript@4.9.5) - "@typescript-eslint/visitor-keys": 8.34.0 - eslint: 8.57.1 - graphemer: 1.4.0 - ignore: 7.0.5 - natural-compare: 1.4.0 - ts-api-utils: 2.1.0(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/parser@8.34.0(eslint@8.57.1)(typescript@4.9.5)": - dependencies: - "@typescript-eslint/scope-manager": 8.34.0 - "@typescript-eslint/types": 8.34.0 - "@typescript-eslint/typescript-estree": 8.34.0(typescript@4.9.5) - "@typescript-eslint/visitor-keys": 8.34.0 - debug: 4.4.1(supports-color@5.5.0) - eslint: 8.57.1 - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/project-service@8.34.0(typescript@4.9.5)": - dependencies: - "@typescript-eslint/tsconfig-utils": 8.34.0(typescript@4.9.5) - "@typescript-eslint/types": 8.34.0 - debug: 4.4.1(supports-color@5.5.0) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/scope-manager@8.34.0": - dependencies: - "@typescript-eslint/types": 8.34.0 - "@typescript-eslint/visitor-keys": 8.34.0 - - "@typescript-eslint/tsconfig-utils@8.34.0(typescript@4.9.5)": - dependencies: - typescript: 4.9.5 - - "@typescript-eslint/type-utils@8.34.0(eslint@8.57.1)(typescript@4.9.5)": - dependencies: - "@typescript-eslint/typescript-estree": 8.34.0(typescript@4.9.5) - "@typescript-eslint/utils": 8.34.0(eslint@8.57.1)(typescript@4.9.5) - debug: 4.4.1(supports-color@5.5.0) - eslint: 8.57.1 - ts-api-utils: 2.1.0(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/types@8.34.0": {} - - "@typescript-eslint/typescript-estree@8.34.0(typescript@4.9.5)": - dependencies: - "@typescript-eslint/project-service": 8.34.0(typescript@4.9.5) - "@typescript-eslint/tsconfig-utils": 8.34.0(typescript@4.9.5) - "@typescript-eslint/types": 8.34.0 - "@typescript-eslint/visitor-keys": 8.34.0 - debug: 4.4.1(supports-color@5.5.0) - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.2 - ts-api-utils: 2.1.0(typescript@4.9.5) - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/utils@8.34.0(eslint@8.57.1)(typescript@4.9.5)": - dependencies: - "@eslint-community/eslint-utils": 4.7.0(eslint@8.57.1) - "@typescript-eslint/scope-manager": 8.34.0 - "@typescript-eslint/types": 8.34.0 - "@typescript-eslint/typescript-estree": 8.34.0(typescript@4.9.5) - eslint: 8.57.1 - typescript: 4.9.5 - transitivePeerDependencies: - - supports-color - - "@typescript-eslint/visitor-keys@8.34.0": - dependencies: - "@typescript-eslint/types": 8.34.0 - eslint-visitor-keys: 4.2.1 - - "@ungap/structured-clone@1.3.0": {} - - "@webassemblyjs/ast@1.14.1": - dependencies: - "@webassemblyjs/helper-numbers": 1.13.2 - "@webassemblyjs/helper-wasm-bytecode": 1.13.2 - - "@webassemblyjs/floating-point-hex-parser@1.13.2": {} - - "@webassemblyjs/helper-api-error@1.13.2": {} - - "@webassemblyjs/helper-buffer@1.14.1": {} - - "@webassemblyjs/helper-numbers@1.13.2": - dependencies: - "@webassemblyjs/floating-point-hex-parser": 1.13.2 - "@webassemblyjs/helper-api-error": 1.13.2 - "@xtuc/long": 4.2.2 - - "@webassemblyjs/helper-wasm-bytecode@1.13.2": {} - - "@webassemblyjs/helper-wasm-section@1.14.1": - dependencies: - "@webassemblyjs/ast": 1.14.1 - "@webassemblyjs/helper-buffer": 1.14.1 - "@webassemblyjs/helper-wasm-bytecode": 1.13.2 - "@webassemblyjs/wasm-gen": 1.14.1 - - "@webassemblyjs/ieee754@1.13.2": - dependencies: - "@xtuc/ieee754": 1.2.0 - - "@webassemblyjs/leb128@1.13.2": - dependencies: - "@xtuc/long": 4.2.2 - - "@webassemblyjs/utf8@1.13.2": {} - - "@webassemblyjs/wasm-edit@1.14.1": - dependencies: - "@webassemblyjs/ast": 1.14.1 - "@webassemblyjs/helper-buffer": 1.14.1 - "@webassemblyjs/helper-wasm-bytecode": 1.13.2 - "@webassemblyjs/helper-wasm-section": 1.14.1 - "@webassemblyjs/wasm-gen": 1.14.1 - "@webassemblyjs/wasm-opt": 1.14.1 - "@webassemblyjs/wasm-parser": 1.14.1 - "@webassemblyjs/wast-printer": 1.14.1 - - "@webassemblyjs/wasm-gen@1.14.1": - dependencies: - "@webassemblyjs/ast": 1.14.1 - "@webassemblyjs/helper-wasm-bytecode": 1.13.2 - "@webassemblyjs/ieee754": 1.13.2 - "@webassemblyjs/leb128": 1.13.2 - "@webassemblyjs/utf8": 1.13.2 - - "@webassemblyjs/wasm-opt@1.14.1": - dependencies: - "@webassemblyjs/ast": 1.14.1 - "@webassemblyjs/helper-buffer": 1.14.1 - "@webassemblyjs/wasm-gen": 1.14.1 - "@webassemblyjs/wasm-parser": 1.14.1 - - "@webassemblyjs/wasm-parser@1.14.1": - dependencies: - "@webassemblyjs/ast": 1.14.1 - "@webassemblyjs/helper-api-error": 1.13.2 - "@webassemblyjs/helper-wasm-bytecode": 1.13.2 - "@webassemblyjs/ieee754": 1.13.2 - "@webassemblyjs/leb128": 1.13.2 - "@webassemblyjs/utf8": 1.13.2 - - "@webassemblyjs/wast-printer@1.14.1": - dependencies: - "@webassemblyjs/ast": 1.14.1 - "@xtuc/long": 4.2.2 - - "@webpack-cli/configtest@1.2.0(webpack-cli@4.10.0)(webpack@5.99.9)": - dependencies: - webpack: 5.99.9(webpack-cli@4.10.0) - webpack-cli: 4.10.0(webpack@5.99.9) - - "@webpack-cli/info@1.5.0(webpack-cli@4.10.0)": - dependencies: - envinfo: 7.14.0 - webpack-cli: 4.10.0(webpack@5.99.9) - - "@webpack-cli/serve@1.7.0(webpack-cli@4.10.0)": - dependencies: - webpack-cli: 4.10.0(webpack@5.99.9) - - "@xtuc/ieee754@1.2.0": {} - - "@xtuc/long@4.2.2": {} - - JSONStream@1.3.5: - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - - abab@2.0.6: {} - - acorn-globals@7.0.1: - dependencies: - acorn: 8.15.0 - acorn-walk: 8.3.4 - - acorn-jsx@5.3.2(acorn@8.15.0): - dependencies: - acorn: 8.15.0 - - acorn-walk@8.3.4: - dependencies: - acorn: 8.15.0 - - acorn@8.15.0: {} - - agent-base@6.0.2: - dependencies: - debug: 4.4.1(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - ajv-formats@2.1.1(ajv@8.17.1): - optionalDependencies: - ajv: 8.17.1 - - ajv-keywords@5.1.0(ajv@8.17.1): - dependencies: - ajv: 8.17.1 - fast-deep-equal: 3.1.3 - - ajv@6.12.6: - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - - ajv@8.17.1: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - - ansi-escapes@4.3.2: - dependencies: - type-fest: 0.21.3 - - ansi-regex@5.0.1: {} - - ansi-regex@6.1.0: {} - - ansi-styles@3.2.1: - dependencies: - color-convert: 1.9.3 - - ansi-styles@4.3.0: - dependencies: - color-convert: 2.0.1 - - ansi-styles@5.2.0: {} - - ansi-styles@6.2.1: {} - - anymatch@3.1.3: - dependencies: - normalize-path: 3.0.0 - picomatch: 2.3.1 - - arg@4.1.3: {} - - argparse@1.0.10: - dependencies: - sprintf-js: 1.0.3 - - argparse@2.0.1: {} - - array-buffer-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - is-array-buffer: 3.0.5 - - array-ify@1.0.0: {} - - array-union@2.1.0: {} - - arraybuffer.prototype.slice@1.0.4: - dependencies: - array-buffer-byte-length: 1.0.2 - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - is-array-buffer: 3.0.5 - - arrify@1.0.1: {} - - async-function@1.0.0: {} - - async@3.2.6: {} - - asynckit@0.4.0: {} - - available-typed-arrays@1.0.7: - dependencies: - possible-typed-array-names: 1.1.0 - - babel-jest@29.7.0(@babel/core@7.27.4): - dependencies: - "@babel/core": 7.27.4 - "@jest/transform": 29.7.0 - "@types/babel__core": 7.20.5 - babel-plugin-istanbul: 6.1.1 - babel-preset-jest: 29.6.3(@babel/core@7.27.4) - chalk: 4.1.2 - graceful-fs: 4.2.11 - slash: 3.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-istanbul@6.1.1: - dependencies: - "@babel/helper-plugin-utils": 7.27.1 - "@istanbuljs/load-nyc-config": 1.1.0 - "@istanbuljs/schema": 0.1.3 - istanbul-lib-instrument: 5.2.1 - test-exclude: 6.0.0 - transitivePeerDependencies: - - supports-color - - babel-plugin-jest-hoist@29.6.3: - dependencies: - "@babel/template": 7.27.2 - "@babel/types": 7.27.6 - "@types/babel__core": 7.20.5 - "@types/babel__traverse": 7.20.7 - - babel-preset-current-node-syntax@1.1.0(@babel/core@7.27.4): - dependencies: - "@babel/core": 7.27.4 - "@babel/plugin-syntax-async-generators": 7.8.4(@babel/core@7.27.4) - "@babel/plugin-syntax-bigint": 7.8.3(@babel/core@7.27.4) - "@babel/plugin-syntax-class-properties": 7.12.13(@babel/core@7.27.4) - "@babel/plugin-syntax-class-static-block": 7.14.5(@babel/core@7.27.4) - "@babel/plugin-syntax-import-attributes": 7.27.1(@babel/core@7.27.4) - "@babel/plugin-syntax-import-meta": 7.10.4(@babel/core@7.27.4) - "@babel/plugin-syntax-json-strings": 7.8.3(@babel/core@7.27.4) - "@babel/plugin-syntax-logical-assignment-operators": 7.10.4(@babel/core@7.27.4) - "@babel/plugin-syntax-nullish-coalescing-operator": 7.8.3(@babel/core@7.27.4) - "@babel/plugin-syntax-numeric-separator": 7.10.4(@babel/core@7.27.4) - "@babel/plugin-syntax-object-rest-spread": 7.8.3(@babel/core@7.27.4) - "@babel/plugin-syntax-optional-catch-binding": 7.8.3(@babel/core@7.27.4) - "@babel/plugin-syntax-optional-chaining": 7.8.3(@babel/core@7.27.4) - "@babel/plugin-syntax-private-property-in-object": 7.14.5(@babel/core@7.27.4) - "@babel/plugin-syntax-top-level-await": 7.14.5(@babel/core@7.27.4) - - babel-preset-jest@29.6.3(@babel/core@7.27.4): - dependencies: - "@babel/core": 7.27.4 - babel-plugin-jest-hoist: 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) - - balanced-match@1.0.2: {} - - base64-js@1.5.1: {} - - big.js@5.2.2: {} - - binary-extensions@2.3.0: {} - - brace-expansion@1.1.12: - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - - brace-expansion@2.0.2: - dependencies: - balanced-match: 1.0.2 - - braces@3.0.3: - dependencies: - fill-range: 7.1.1 - - browserslist@4.25.0: - dependencies: - caniuse-lite: 1.0.30001723 - electron-to-chromium: 1.5.167 - node-releases: 2.0.19 - update-browserslist-db: 1.1.3(browserslist@4.25.0) - - bs-logger@0.2.6: - dependencies: - fast-json-stable-stringify: 2.1.0 - - bser@2.1.1: - dependencies: - node-int64: 0.4.0 - - buffer-from@1.1.2: {} - - buffer@6.0.3: - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - - call-bind-apply-helpers@1.0.2: - dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - - call-bind@1.0.8: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - get-intrinsic: 1.3.0 - set-function-length: 1.2.2 - - call-bound@1.0.4: - dependencies: - call-bind-apply-helpers: 1.0.2 - get-intrinsic: 1.3.0 - - callsites@3.1.0: {} - - camelcase-keys@6.2.2: - dependencies: - camelcase: 5.3.1 - map-obj: 4.3.0 - quick-lru: 4.0.1 - - camelcase@5.3.1: {} - - camelcase@6.3.0: {} - - caniuse-lite@1.0.30001723: {} - - chalk@2.4.2: - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - - char-regex@1.0.2: {} - - chokidar@3.6.0: - dependencies: - anymatch: 3.1.3 - braces: 3.0.3 - glob-parent: 5.1.2 - is-binary-path: 2.1.0 - is-glob: 4.0.3 - normalize-path: 3.0.0 - readdirp: 3.6.0 - optionalDependencies: - fsevents: 2.3.3 - - chrome-trace-event@1.0.4: {} - - ci-info@2.0.0: {} - - ci-info@3.9.0: {} - - cjs-module-lexer@1.4.3: {} - - cliui@7.0.4: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - cliui@8.0.1: - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - - clone-deep@4.0.1: - dependencies: - is-plain-object: 2.0.4 - kind-of: 6.0.3 - shallow-clone: 3.0.1 - - co@4.6.0: {} - - collect-v8-coverage@1.0.2: {} - - color-convert@1.9.3: - dependencies: - color-name: 1.1.3 - - color-convert@2.0.1: - dependencies: - color-name: 1.1.4 - - color-name@1.1.3: {} - - color-name@1.1.4: {} - - colorette@2.0.20: {} - - combined-stream@1.0.8: - dependencies: - delayed-stream: 1.0.0 - - commander@12.1.0: {} - - commander@2.20.3: {} - - commander@7.2.0: {} - - compare-func@2.0.0: - dependencies: - array-ify: 1.0.0 - dot-prop: 5.3.0 - - compare-versions@3.6.0: {} - - concat-map@0.0.1: {} - - consola@2.15.3: {} - - conventional-changelog-angular@6.0.0: - dependencies: - compare-func: 2.0.0 - - conventional-changelog-conventionalcommits@6.1.0: - dependencies: - compare-func: 2.0.0 - - conventional-commits-parser@4.0.0: - dependencies: - JSONStream: 1.3.5 - is-text-path: 1.0.1 - meow: 8.1.2 - split2: 3.2.2 - - convert-source-map@2.0.0: {} - - core-util-is@1.0.3: {} - - cosmiconfig-typescript-loader@4.4.0(@types/node@20.5.1)(cosmiconfig@8.3.6(typescript@4.9.5))(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5))(typescript@4.9.5): - dependencies: - "@types/node": 20.5.1 - cosmiconfig: 8.3.6(typescript@4.9.5) - ts-node: 10.9.2(@types/node@18.19.112)(typescript@4.9.5) - typescript: 4.9.5 - - cosmiconfig@7.1.0: - dependencies: - "@types/parse-json": 4.0.2 - import-fresh: 3.3.1 - parse-json: 5.2.0 - path-type: 4.0.0 - yaml: 1.10.2 - - cosmiconfig@8.3.6(typescript@4.9.5): - dependencies: - import-fresh: 3.3.1 - js-yaml: 4.1.0 - parse-json: 5.2.0 - path-type: 4.0.0 - optionalDependencies: - typescript: 4.9.5 - - create-jest@29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)): - dependencies: - "@jest/types": 29.6.3 - chalk: 4.1.2 - exit: 0.1.2 - graceful-fs: 4.2.11 - jest-config: 29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)) - jest-util: 29.7.0 - prompts: 2.4.2 - transitivePeerDependencies: - - "@types/node" - - babel-plugin-macros - - supports-color - - ts-node - - create-require@1.1.1: {} - - cross-env@7.0.3: - dependencies: - cross-spawn: 7.0.6 - - cross-fetch@3.2.0: - dependencies: - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - - cross-spawn@6.0.6: - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.2 - shebang-command: 1.2.0 - which: 1.3.1 - - cross-spawn@7.0.6: - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - - cssom@0.3.8: {} - - cssom@0.5.0: {} - - cssstyle@2.3.0: - dependencies: - cssom: 0.3.8 - - dargs@7.0.0: {} - - data-urls@3.0.2: - dependencies: - abab: 2.0.6 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 - - data-view-buffer@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-length@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - data-view-byte-offset@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-data-view: 1.0.2 - - dayjs@1.11.13: {} - - debug@4.4.1(supports-color@5.5.0): - dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 5.5.0 - - decamelize-keys@1.1.1: - dependencies: - decamelize: 1.2.0 - map-obj: 1.0.1 - - decamelize@1.2.0: {} - - decimal.js@10.5.0: {} - - dedent@1.6.0: {} - - deep-extend@0.6.0: {} - - deep-is@0.1.4: {} - - deepmerge@4.3.1: {} - - define-data-property@1.1.4: - dependencies: - es-define-property: 1.0.1 - es-errors: 1.3.0 - gopd: 1.2.0 - - define-properties@1.2.1: - dependencies: - define-data-property: 1.1.4 - has-property-descriptors: 1.0.2 - object-keys: 1.1.1 - - delayed-stream@1.0.0: {} - - detect-newline@3.1.0: {} - - diff-sequences@29.6.3: {} - - diff@4.0.2: {} - - dir-glob@3.0.1: - dependencies: - path-type: 4.0.0 - - doctrine@3.0.0: - dependencies: - esutils: 2.0.3 - - domexception@4.0.0: - dependencies: - webidl-conversions: 7.0.0 - - dot-prop@5.3.0: - dependencies: - is-obj: 2.0.0 - - dotenv@16.5.0: {} - - dunder-proto@1.0.1: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-errors: 1.3.0 - gopd: 1.2.0 - - eastasianwidth@0.2.0: {} - - ejs@3.1.10: - dependencies: - jake: 10.9.2 - - electron-to-chromium@1.5.167: {} - - emittery@0.13.1: {} - - emoji-regex@8.0.0: {} - - emoji-regex@9.2.2: {} - - emojis-list@3.0.0: {} - - end-of-stream@1.4.4: - dependencies: - once: 1.4.0 - - enhanced-resolve@4.5.0: - dependencies: - graceful-fs: 4.2.11 - memory-fs: 0.5.0 - tapable: 1.1.3 - - enhanced-resolve@5.18.1: - dependencies: - graceful-fs: 4.2.11 - tapable: 2.2.2 - - entities@4.5.0: {} - - entities@6.0.1: {} - - envinfo@7.14.0: {} - - errno@0.1.8: - dependencies: - prr: 1.0.1 - - error-ex@1.3.2: - dependencies: - is-arrayish: 0.2.1 - - es-abstract@1.24.0: - dependencies: - array-buffer-byte-length: 1.0.2 - arraybuffer.prototype.slice: 1.0.4 - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - data-view-buffer: 1.0.2 - data-view-byte-length: 1.0.2 - data-view-byte-offset: 1.0.1 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - es-set-tostringtag: 2.1.0 - es-to-primitive: 1.3.0 - function.prototype.name: 1.1.8 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - get-symbol-description: 1.1.0 - globalthis: 1.0.4 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - has-proto: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - internal-slot: 1.1.0 - is-array-buffer: 3.0.5 - is-callable: 1.2.7 - is-data-view: 1.0.2 - is-negative-zero: 2.0.3 - is-regex: 1.2.1 - is-set: 2.0.3 - is-shared-array-buffer: 1.0.4 - is-string: 1.1.1 - is-typed-array: 1.1.15 - is-weakref: 1.1.1 - math-intrinsics: 1.1.0 - object-inspect: 1.13.4 - object-keys: 1.1.1 - object.assign: 4.1.7 - own-keys: 1.0.1 - regexp.prototype.flags: 1.5.4 - safe-array-concat: 1.1.3 - safe-push-apply: 1.0.0 - safe-regex-test: 1.1.0 - set-proto: 1.0.0 - stop-iteration-iterator: 1.1.0 - string.prototype.trim: 1.2.10 - string.prototype.trimend: 1.0.9 - string.prototype.trimstart: 1.0.8 - typed-array-buffer: 1.0.3 - typed-array-byte-length: 1.0.3 - typed-array-byte-offset: 1.0.4 - typed-array-length: 1.0.7 - unbox-primitive: 1.1.0 - which-typed-array: 1.1.19 - - es-define-property@1.0.1: {} - - es-errors@1.3.0: {} - - es-module-lexer@1.7.0: {} - - es-object-atoms@1.1.1: - dependencies: - es-errors: 1.3.0 - - es-set-tostringtag@2.1.0: - dependencies: - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - es-to-primitive@1.3.0: - dependencies: - is-callable: 1.2.7 - is-date-object: 1.1.0 - is-symbol: 1.1.1 - - escalade@3.2.0: {} - - escape-string-regexp@1.0.5: {} - - escape-string-regexp@2.0.0: {} - - escape-string-regexp@4.0.0: {} - - escodegen@2.1.0: - dependencies: - esprima: 4.0.1 - estraverse: 5.3.0 - esutils: 2.0.3 - optionalDependencies: - source-map: 0.6.1 - - eslint-scope@5.1.1: - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - - eslint-scope@7.2.2: - dependencies: - esrecurse: 4.3.0 - estraverse: 5.3.0 - - eslint-visitor-keys@3.4.3: {} - - eslint-visitor-keys@4.2.1: {} - - eslint@8.57.1: - dependencies: - "@eslint-community/eslint-utils": 4.7.0(eslint@8.57.1) - "@eslint-community/regexpp": 4.12.1 - "@eslint/eslintrc": 2.1.4 - "@eslint/js": 8.57.1 - "@humanwhocodes/config-array": 0.13.0 - "@humanwhocodes/module-importer": 1.0.1 - "@nodelib/fs.walk": 1.2.8 - "@ungap/structured-clone": 1.3.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.1(supports-color@5.5.0) - doctrine: 3.0.0 - escape-string-regexp: 4.0.0 - eslint-scope: 7.2.2 - eslint-visitor-keys: 3.4.3 - espree: 9.6.1 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - find-up: 5.0.0 - glob-parent: 6.0.2 - globals: 13.24.0 - graphemer: 1.4.0 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - strip-ansi: 6.0.1 - text-table: 0.2.0 - transitivePeerDependencies: - - supports-color - - espree@9.6.1: - dependencies: - acorn: 8.15.0 - acorn-jsx: 5.3.2(acorn@8.15.0) - eslint-visitor-keys: 3.4.3 - - esprima@4.0.1: {} - - esquery@1.6.0: - dependencies: - estraverse: 5.3.0 - - esrecurse@4.3.0: - dependencies: - estraverse: 5.3.0 - - estraverse@4.3.0: {} - - estraverse@5.3.0: {} - - esutils@2.0.3: {} - - events@3.3.0: {} - - execa@4.1.0: - dependencies: - cross-spawn: 7.0.6 - get-stream: 5.2.0 - human-signals: 1.1.1 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - execa@5.1.1: - dependencies: - cross-spawn: 7.0.6 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - - exit@0.1.2: {} - - expect@29.7.0: - dependencies: - "@jest/expect-utils": 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - - fast-deep-equal@3.1.3: {} - - fast-glob@3.3.3: - dependencies: - "@nodelib/fs.stat": 2.0.5 - "@nodelib/fs.walk": 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.8 - - fast-json-stable-stringify@2.1.0: {} - - fast-levenshtein@2.0.6: {} - - fast-uri@3.0.6: {} - - fastest-levenshtein@1.0.16: {} - - fastq@1.19.1: - dependencies: - reusify: 1.1.0 - - fb-watchman@2.0.2: - dependencies: - bser: 2.1.1 - - file-entry-cache@6.0.1: - dependencies: - flat-cache: 3.2.0 - - filelist@1.0.4: - dependencies: - minimatch: 5.1.6 - - fill-range@7.1.1: - dependencies: - to-regex-range: 5.0.1 - - find-up@4.1.0: - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - - find-up@5.0.0: - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - - find-versions@4.0.0: - dependencies: - semver-regex: 3.1.4 - - flat-cache@3.2.0: - dependencies: - flatted: 3.3.3 - keyv: 4.5.4 - rimraf: 3.0.2 - - flat@5.0.2: {} - - flatted@3.3.3: {} - - for-each@0.3.5: - dependencies: - is-callable: 1.2.7 - - foreground-child@3.3.1: - dependencies: - cross-spawn: 7.0.6 - signal-exit: 4.1.0 - - form-data@4.0.3: - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - es-set-tostringtag: 2.1.0 - hasown: 2.0.2 - mime-types: 2.1.35 - - fs-extra@11.3.0: - dependencies: - graceful-fs: 4.2.11 - jsonfile: 6.1.0 - universalify: 2.0.1 - - fs.realpath@1.0.0: {} - - fsevents@2.3.3: - optional: true - - function-bind@1.1.2: {} - - function.prototype.name@1.1.8: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - functions-have-names: 1.2.3 - hasown: 2.0.2 - is-callable: 1.2.7 - - functions-have-names@1.2.3: {} - - gensync@1.0.0-beta.2: {} - - get-caller-file@2.0.5: {} - - get-intrinsic@1.3.0: - dependencies: - call-bind-apply-helpers: 1.0.2 - es-define-property: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - function-bind: 1.1.2 - get-proto: 1.0.1 - gopd: 1.2.0 - has-symbols: 1.1.0 - hasown: 2.0.2 - math-intrinsics: 1.1.0 - - get-package-type@0.1.0: {} - - get-proto@1.0.1: - dependencies: - dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 - - get-stdin@9.0.0: {} - - get-stream@5.2.0: - dependencies: - pump: 3.0.3 - - get-stream@6.0.1: {} - - get-symbol-description@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - - git-raw-commits@2.0.11: - dependencies: - dargs: 7.0.0 - lodash: 4.17.21 - meow: 8.1.2 - split2: 3.2.2 - through2: 4.0.2 - - glob-parent@5.1.2: - dependencies: - is-glob: 4.0.3 - - glob-parent@6.0.2: - dependencies: - is-glob: 4.0.3 - - glob-to-regexp@0.4.1: {} - - glob@11.0.3: - dependencies: - foreground-child: 3.3.1 - jackspeak: 4.1.1 - minimatch: 10.0.3 - minipass: 7.1.2 - package-json-from-dist: 1.0.1 - path-scurry: 2.0.0 - - glob@7.2.3: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - - glob@8.1.0: - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 5.1.6 - once: 1.4.0 - - global-dirs@0.1.1: - dependencies: - ini: 1.3.8 - - globals@11.12.0: {} - - globals@13.24.0: - dependencies: - type-fest: 0.20.2 - - globalthis@1.0.4: - dependencies: - define-properties: 1.2.1 - gopd: 1.2.0 - - globby@11.1.0: - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 3.0.0 - - gopd@1.2.0: {} - - graceful-fs@4.2.11: {} - - graphemer@1.4.0: {} - - hard-rejection@2.1.0: {} - - has-bigints@1.1.0: {} - - has-flag@3.0.0: {} - - has-flag@4.0.0: {} - - has-property-descriptors@1.0.2: - dependencies: - es-define-property: 1.0.1 - - has-proto@1.2.0: - dependencies: - dunder-proto: 1.0.1 - - has-symbols@1.1.0: {} - - has-tostringtag@1.0.2: - dependencies: - has-symbols: 1.1.0 - - hasown@2.0.2: - dependencies: - function-bind: 1.1.2 - - hosted-git-info@2.8.9: {} - - hosted-git-info@4.1.0: - dependencies: - lru-cache: 6.0.0 - - html-encoding-sniffer@3.0.0: - dependencies: - whatwg-encoding: 2.0.0 - - html-escaper@2.0.2: {} - - http-proxy-agent@5.0.0: - dependencies: - "@tootallnate/once": 2.0.0 - agent-base: 6.0.2 - debug: 4.4.1(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - https-proxy-agent@5.0.1: - dependencies: - agent-base: 6.0.2 - debug: 4.4.1(supports-color@5.5.0) - transitivePeerDependencies: - - supports-color - - human-signals@1.1.1: {} - - human-signals@2.1.0: {} - - husky@4.3.8: - dependencies: - chalk: 4.1.2 - ci-info: 2.0.0 - compare-versions: 3.6.0 - cosmiconfig: 7.1.0 - find-versions: 4.0.0 - opencollective-postinstall: 2.0.3 - pkg-dir: 5.0.0 - please-upgrade-node: 3.2.0 - slash: 3.0.0 - which-pm-runs: 1.1.0 - - iconv-lite@0.6.3: - dependencies: - safer-buffer: 2.1.2 - - ieee754@1.2.1: {} - - ignore-by-default@1.0.1: {} - - ignore@5.3.2: {} - - ignore@6.0.2: {} - - ignore@7.0.5: {} - - import-fresh@3.3.1: - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - - import-local@3.2.0: - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - - imurmurhash@0.1.4: {} - - indent-string@4.0.0: {} - - inflight@1.0.6: - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - - inherits@2.0.4: {} - - ini@1.3.8: {} - - ini@2.0.0: {} - - ini@4.1.3: {} - - internal-slot@1.1.0: - dependencies: - es-errors: 1.3.0 - hasown: 2.0.2 - side-channel: 1.1.0 - - interpret@2.2.0: {} - - is-arguments@1.2.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-array-buffer@3.0.5: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - is-arrayish@0.2.1: {} - - is-async-function@2.1.1: - dependencies: - async-function: 1.0.0 - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-bigint@1.1.0: - dependencies: - has-bigints: 1.1.0 - - is-binary-path@2.1.0: - dependencies: - binary-extensions: 2.3.0 - - is-boolean-object@1.2.2: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-callable@1.2.7: {} - - is-core-module@2.16.1: - dependencies: - hasown: 2.0.2 - - is-data-view@1.0.2: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - is-typed-array: 1.1.15 - - is-date-object@1.1.0: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-extglob@2.1.1: {} - - is-finalizationregistry@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-fullwidth-code-point@3.0.0: {} - - is-generator-fn@2.1.0: {} - - is-generator-function@1.1.0: - dependencies: - call-bound: 1.0.4 - get-proto: 1.0.1 - has-tostringtag: 1.0.2 - safe-regex-test: 1.1.0 - - is-glob@4.0.3: - dependencies: - is-extglob: 2.1.1 - - is-map@2.0.3: {} - - is-negative-zero@2.0.3: {} - - is-number-object@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-number@7.0.0: {} - - is-obj@2.0.0: {} - - is-path-inside@3.0.3: {} - - is-plain-obj@1.1.0: {} - - is-plain-object@2.0.4: - dependencies: - isobject: 3.0.1 - - is-potential-custom-element-name@1.0.1: {} - - is-regex@1.2.1: - dependencies: - call-bound: 1.0.4 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - hasown: 2.0.2 - - is-set@2.0.3: {} - - is-shared-array-buffer@1.0.4: - dependencies: - call-bound: 1.0.4 - - is-stream@2.0.1: {} - - is-string@1.1.1: - dependencies: - call-bound: 1.0.4 - has-tostringtag: 1.0.2 - - is-symbol@1.1.1: - dependencies: - call-bound: 1.0.4 - has-symbols: 1.1.0 - safe-regex-test: 1.1.0 - - is-text-path@1.0.1: - dependencies: - text-extensions: 1.9.0 - - is-typed-array@1.1.15: - dependencies: - which-typed-array: 1.1.19 - - is-weakmap@2.0.2: {} - - is-weakref@1.1.1: - dependencies: - call-bound: 1.0.4 - - is-weakset@2.0.4: - dependencies: - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - - isarray@1.0.0: {} - - isarray@2.0.5: {} - - isexe@2.0.0: {} - - isobject@3.0.1: {} - - istanbul-lib-coverage@3.2.2: {} - - istanbul-lib-instrument@5.2.1: - dependencies: - "@babel/core": 7.27.4 - "@babel/parser": 7.27.5 - "@istanbuljs/schema": 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 6.3.1 - transitivePeerDependencies: - - supports-color - - istanbul-lib-instrument@6.0.3: - dependencies: - "@babel/core": 7.27.4 - "@babel/parser": 7.27.5 - "@istanbuljs/schema": 0.1.3 - istanbul-lib-coverage: 3.2.2 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - - istanbul-lib-source-maps@4.0.1: - dependencies: - debug: 4.4.1(supports-color@5.5.0) - istanbul-lib-coverage: 3.2.2 - source-map: 0.6.1 - transitivePeerDependencies: - - supports-color - - istanbul-reports@3.1.7: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - - jackspeak@4.1.1: - dependencies: - "@isaacs/cliui": 8.0.2 - - jake@10.9.2: - dependencies: - async: 3.2.6 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 - - jest-changed-files@29.7.0: - dependencies: - execa: 5.1.1 - jest-util: 29.7.0 - p-limit: 3.1.0 - - jest-circus@29.7.0: - dependencies: - "@jest/environment": 29.7.0 - "@jest/expect": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - chalk: 4.1.2 - co: 4.6.0 - dedent: 1.6.0 - is-generator-fn: 2.1.0 - jest-each: 29.7.0 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-runtime: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - p-limit: 3.1.0 - pretty-format: 29.7.0 - pure-rand: 6.1.0 - slash: 3.0.0 - stack-utils: 2.0.6 - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-cli@29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)): - dependencies: - "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)) - "@jest/test-result": 29.7.0 - "@jest/types": 29.6.3 - chalk: 4.1.2 - create-jest: 29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)) - exit: 0.1.2 - import-local: 3.2.0 - jest-config: 29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)) - jest-util: 29.7.0 - jest-validate: 29.7.0 - yargs: 17.7.2 - transitivePeerDependencies: - - "@types/node" - - babel-plugin-macros - - supports-color - - ts-node - - jest-config@29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)): - dependencies: - "@babel/core": 7.27.4 - "@jest/test-sequencer": 29.7.0 - "@jest/types": 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.4) - chalk: 4.1.2 - ci-info: 3.9.0 - deepmerge: 4.3.1 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-circus: 29.7.0 - jest-environment-node: 29.7.0 - jest-get-type: 29.6.3 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-runner: 29.7.0 - jest-util: 29.7.0 - jest-validate: 29.7.0 - micromatch: 4.0.8 - parse-json: 5.2.0 - pretty-format: 29.7.0 - slash: 3.0.0 - strip-json-comments: 3.1.1 - optionalDependencies: - "@types/node": 18.19.112 - ts-node: 10.9.2(@types/node@18.19.112)(typescript@4.9.5) - transitivePeerDependencies: - - babel-plugin-macros - - supports-color - - jest-diff@29.7.0: - dependencies: - chalk: 4.1.2 - diff-sequences: 29.6.3 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-docblock@29.7.0: - dependencies: - detect-newline: 3.1.0 - - jest-each@29.7.0: - dependencies: - "@jest/types": 29.6.3 - chalk: 4.1.2 - jest-get-type: 29.6.3 - jest-util: 29.7.0 - pretty-format: 29.7.0 - - jest-environment-jsdom@29.7.0: - dependencies: - "@jest/environment": 29.7.0 - "@jest/fake-timers": 29.7.0 - "@jest/types": 29.6.3 - "@types/jsdom": 20.0.1 - "@types/node": 18.19.112 - jest-mock: 29.7.0 - jest-util: 29.7.0 - jsdom: 20.0.3 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - jest-environment-node@29.7.0: - dependencies: - "@jest/environment": 29.7.0 - "@jest/fake-timers": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - jest-mock: 29.7.0 - jest-util: 29.7.0 - - jest-get-type@29.6.3: {} - - jest-haste-map@29.7.0: - dependencies: - "@jest/types": 29.6.3 - "@types/graceful-fs": 4.1.9 - "@types/node": 18.19.112 - anymatch: 3.1.3 - fb-watchman: 2.0.2 - graceful-fs: 4.2.11 - jest-regex-util: 29.6.3 - jest-util: 29.7.0 - jest-worker: 29.7.0 - micromatch: 4.0.8 - walker: 1.0.8 - optionalDependencies: - fsevents: 2.3.3 - - jest-leak-detector@29.7.0: - dependencies: - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-matcher-utils@29.7.0: - dependencies: - chalk: 4.1.2 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - pretty-format: 29.7.0 - - jest-message-util@29.7.0: - dependencies: - "@babel/code-frame": 7.27.1 - "@jest/types": 29.6.3 - "@types/stack-utils": 2.0.3 - chalk: 4.1.2 - graceful-fs: 4.2.11 - micromatch: 4.0.8 - pretty-format: 29.7.0 - slash: 3.0.0 - stack-utils: 2.0.6 - - jest-mock@29.7.0: - dependencies: - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - jest-util: 29.7.0 - - jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): - optionalDependencies: - jest-resolve: 29.7.0 - - jest-regex-util@29.6.3: {} - - jest-resolve-dependencies@29.7.0: - dependencies: - jest-regex-util: 29.6.3 - jest-snapshot: 29.7.0 - transitivePeerDependencies: - - supports-color - - jest-resolve@29.7.0: - dependencies: - chalk: 4.1.2 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) - jest-util: 29.7.0 - jest-validate: 29.7.0 - resolve: 1.22.10 - resolve.exports: 2.0.3 - slash: 3.0.0 - - jest-runner@29.7.0: - dependencies: - "@jest/console": 29.7.0 - "@jest/environment": 29.7.0 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - chalk: 4.1.2 - emittery: 0.13.1 - graceful-fs: 4.2.11 - jest-docblock: 29.7.0 - jest-environment-node: 29.7.0 - jest-haste-map: 29.7.0 - jest-leak-detector: 29.7.0 - jest-message-util: 29.7.0 - jest-resolve: 29.7.0 - jest-runtime: 29.7.0 - jest-util: 29.7.0 - jest-watcher: 29.7.0 - jest-worker: 29.7.0 - p-limit: 3.1.0 - source-map-support: 0.5.13 - transitivePeerDependencies: - - supports-color - - jest-runtime@29.7.0: - dependencies: - "@jest/environment": 29.7.0 - "@jest/fake-timers": 29.7.0 - "@jest/globals": 29.7.0 - "@jest/source-map": 29.6.3 - "@jest/test-result": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - chalk: 4.1.2 - cjs-module-lexer: 1.4.3 - collect-v8-coverage: 1.0.2 - glob: 7.2.3 - graceful-fs: 4.2.11 - jest-haste-map: 29.7.0 - jest-message-util: 29.7.0 - jest-mock: 29.7.0 - jest-regex-util: 29.6.3 - jest-resolve: 29.7.0 - jest-snapshot: 29.7.0 - jest-util: 29.7.0 - slash: 3.0.0 - strip-bom: 4.0.0 - transitivePeerDependencies: - - supports-color - - jest-snapshot@29.7.0: - dependencies: - "@babel/core": 7.27.4 - "@babel/generator": 7.27.5 - "@babel/plugin-syntax-jsx": 7.27.1(@babel/core@7.27.4) - "@babel/plugin-syntax-typescript": 7.27.1(@babel/core@7.27.4) - "@babel/types": 7.27.6 - "@jest/expect-utils": 29.7.0 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - babel-preset-current-node-syntax: 1.1.0(@babel/core@7.27.4) - chalk: 4.1.2 - expect: 29.7.0 - graceful-fs: 4.2.11 - jest-diff: 29.7.0 - jest-get-type: 29.6.3 - jest-matcher-utils: 29.7.0 - jest-message-util: 29.7.0 - jest-util: 29.7.0 - natural-compare: 1.4.0 - pretty-format: 29.7.0 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - - jest-util@29.7.0: - dependencies: - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - chalk: 4.1.2 - ci-info: 3.9.0 - graceful-fs: 4.2.11 - picomatch: 2.3.1 - - jest-validate@29.7.0: - dependencies: - "@jest/types": 29.6.3 - camelcase: 6.3.0 - chalk: 4.1.2 - jest-get-type: 29.6.3 - leven: 3.1.0 - pretty-format: 29.7.0 - - jest-watcher@29.7.0: - dependencies: - "@jest/test-result": 29.7.0 - "@jest/types": 29.6.3 - "@types/node": 18.19.112 - ansi-escapes: 4.3.2 - chalk: 4.1.2 - emittery: 0.13.1 - jest-util: 29.7.0 - string-length: 4.0.2 - - jest-worker@27.5.1: - dependencies: - "@types/node": 18.19.112 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - jest-worker@29.7.0: - dependencies: - "@types/node": 18.19.112 - jest-util: 29.7.0 - merge-stream: 2.0.0 - supports-color: 8.1.1 - - jest@29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)): - dependencies: - "@jest/core": 29.7.0(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)) - "@jest/types": 29.6.3 - import-local: 3.2.0 - jest-cli: 29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)) - transitivePeerDependencies: - - "@types/node" - - babel-plugin-macros - - supports-color - - ts-node - - js-tokens@4.0.0: {} - - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 - - jsdom@20.0.3: - dependencies: - abab: 2.0.6 - acorn: 8.15.0 - acorn-globals: 7.0.1 - cssom: 0.5.0 - cssstyle: 2.3.0 - data-urls: 3.0.2 - decimal.js: 10.5.0 - domexception: 4.0.0 - escodegen: 2.1.0 - form-data: 4.0.3 - html-encoding-sniffer: 3.0.0 - http-proxy-agent: 5.0.0 - https-proxy-agent: 5.0.1 - is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.20 - parse5: 7.3.0 - saxes: 6.0.0 - symbol-tree: 3.2.4 - tough-cookie: 4.1.4 - w3c-xmlserializer: 4.0.0 - webidl-conversions: 7.0.0 - whatwg-encoding: 2.0.0 - whatwg-mimetype: 3.0.0 - whatwg-url: 11.0.0 - ws: 8.18.2 - xml-name-validator: 4.0.0 - transitivePeerDependencies: - - bufferutil - - supports-color - - utf-8-validate - - jsesc@3.1.0: {} - - json-buffer@3.0.1: {} - - json-parse-better-errors@1.0.2: {} - - json-parse-even-better-errors@2.3.1: {} - - json-schema-traverse@0.4.1: {} - - json-schema-traverse@1.0.0: {} - - json-stable-stringify-without-jsonify@1.0.1: {} - - json5@2.2.3: {} - - jsonc-parser@3.3.1: {} - - jsonfile@6.1.0: - dependencies: - universalify: 2.0.1 - optionalDependencies: - graceful-fs: 4.2.11 - - jsonparse@1.3.1: {} - - jsonpointer@5.0.1: {} - - keyv@4.5.4: - dependencies: - json-buffer: 3.0.1 - - kind-of@6.0.3: {} - - kleur@3.0.3: {} - - leven@3.1.0: {} - - levn@0.4.1: - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - - lines-and-columns@1.2.4: {} - - linkify-it@5.0.0: - dependencies: - uc.micro: 2.1.0 - - load-json-file@4.0.0: - dependencies: - graceful-fs: 4.2.11 - parse-json: 4.0.0 - pify: 3.0.0 - strip-bom: 3.0.0 - - loader-runner@4.3.0: {} - - loader-utils@2.0.4: - dependencies: - big.js: 5.2.2 - emojis-list: 3.0.0 - json5: 2.2.3 - - locate-path@5.0.0: - dependencies: - p-locate: 4.1.0 - - locate-path@6.0.0: - dependencies: - p-locate: 5.0.0 - - lodash.camelcase@4.3.0: {} - - lodash.isfunction@3.0.9: {} - - lodash.isplainobject@4.0.6: {} - - lodash.kebabcase@4.1.1: {} - - lodash.memoize@4.1.2: {} - - lodash.merge@4.6.2: {} - - lodash.mergewith@4.6.2: {} - - lodash.snakecase@4.1.1: {} - - lodash.startcase@4.4.0: {} - - lodash.uniq@4.5.0: {} - - lodash.upperfirst@4.3.1: {} - - lodash@4.17.21: {} - - lru-cache@11.1.0: {} - - lru-cache@5.1.1: - dependencies: - yallist: 3.1.1 - - lru-cache@6.0.0: - dependencies: - yallist: 4.0.0 - - lunr@2.3.9: {} - - make-dir@4.0.0: - dependencies: - semver: 7.7.2 - - make-error@1.3.6: {} - - makeerror@1.0.12: - dependencies: - tmpl: 1.0.5 - - map-obj@1.0.1: {} - - map-obj@4.3.0: {} - - markdown-it@14.1.0: - dependencies: - argparse: 2.0.1 - entities: 4.5.0 - linkify-it: 5.0.0 - mdurl: 2.0.0 - punycode.js: 2.3.1 - uc.micro: 2.1.0 - - markdownlint-cli@0.42.0: - dependencies: - commander: 12.1.0 - get-stdin: 9.0.0 - glob: 11.0.3 - ignore: 6.0.2 - js-yaml: 4.1.0 - jsonc-parser: 3.3.1 - jsonpointer: 5.0.1 - markdownlint: 0.35.0 - minimatch: 10.0.3 - run-con: 1.3.2 - smol-toml: 1.3.4 - - markdownlint-micromark@0.1.10: {} - - markdownlint@0.35.0: - dependencies: - markdown-it: 14.1.0 - markdownlint-micromark: 0.1.10 - - marked@4.3.0: {} - - math-intrinsics@1.1.0: {} - - mdurl@2.0.0: {} - - memory-fs@0.5.0: - dependencies: - errno: 0.1.8 - readable-stream: 2.3.8 - - memorystream@0.3.1: {} - - meow@8.1.2: - dependencies: - "@types/minimist": 1.2.5 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.1 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 3.0.3 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.18.1 - yargs-parser: 20.2.9 - - merge-stream@2.0.0: {} - - merge2@1.4.1: {} - - micromatch@4.0.8: - dependencies: - braces: 3.0.3 - picomatch: 2.3.1 - - mime-db@1.52.0: {} - - mime-types@2.1.35: - dependencies: - mime-db: 1.52.0 - - mimic-fn@2.1.0: {} - - min-indent@1.0.1: {} - - minimatch@10.0.3: - dependencies: - "@isaacs/brace-expansion": 5.0.0 - - minimatch@3.1.2: - dependencies: - brace-expansion: 1.1.12 - - minimatch@5.1.6: - dependencies: - brace-expansion: 2.0.2 - - minimatch@9.0.5: - dependencies: - brace-expansion: 2.0.2 - - minimist-options@4.1.0: - dependencies: - arrify: 1.0.1 - is-plain-obj: 1.1.0 - kind-of: 6.0.3 - - minimist@1.2.8: {} - - minipass@7.1.2: {} - - mri@1.2.0: {} - - ms@2.1.3: {} - - natural-compare@1.4.0: {} - - nconf@0.12.1: - dependencies: - async: 3.2.6 - ini: 2.0.0 - secure-keys: 1.0.0 - yargs: 16.2.0 - - neo-async@2.6.2: {} - - nice-try@1.0.5: {} - - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - - node-int64@0.4.0: {} - - node-releases@2.0.19: {} - - nodemon@3.1.10: - dependencies: - chokidar: 3.6.0 - debug: 4.4.1(supports-color@5.5.0) - ignore-by-default: 1.0.1 - minimatch: 3.1.2 - pstree.remy: 1.1.8 - semver: 7.7.2 - simple-update-notifier: 2.0.0 - supports-color: 5.5.0 - touch: 3.1.1 - undefsafe: 2.0.5 - - normalize-package-data@2.5.0: - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.22.10 - semver: 5.7.2 - validate-npm-package-license: 3.0.4 - - normalize-package-data@3.0.3: - dependencies: - hosted-git-info: 4.1.0 - is-core-module: 2.16.1 - semver: 7.7.2 - validate-npm-package-license: 3.0.4 - - normalize-path@3.0.0: {} - - npm-run-all@4.1.5: - dependencies: - ansi-styles: 3.2.1 - chalk: 2.4.2 - cross-spawn: 6.0.6 - memorystream: 0.3.1 - minimatch: 3.1.2 - pidtree: 0.3.1 - read-pkg: 3.0.0 - shell-quote: 1.8.3 - string.prototype.padend: 3.1.6 - - npm-run-path@4.0.1: - dependencies: - path-key: 3.1.1 - - nwsapi@2.2.20: {} - - object-inspect@1.13.4: {} - - object-keys@1.1.1: {} - - object.assign@4.1.7: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - has-symbols: 1.1.0 - object-keys: 1.1.1 - - once@1.4.0: - dependencies: - wrappy: 1.0.2 - - onetime@5.1.2: - dependencies: - mimic-fn: 2.1.0 - - opencollective-postinstall@2.0.3: {} - - optionator@0.9.4: - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.5 - - own-keys@1.0.1: - dependencies: - get-intrinsic: 1.3.0 - object-keys: 1.1.1 - safe-push-apply: 1.0.0 - - p-limit@2.3.0: - dependencies: - p-try: 2.2.0 - - p-limit@3.1.0: - dependencies: - yocto-queue: 0.1.0 - - p-locate@4.1.0: - dependencies: - p-limit: 2.3.0 - - p-locate@5.0.0: - dependencies: - p-limit: 3.1.0 - - p-try@2.2.0: {} - - package-json-from-dist@1.0.1: {} - - parent-module@1.0.1: - dependencies: - callsites: 3.1.0 - - parse-json@4.0.0: - dependencies: - error-ex: 1.3.2 - json-parse-better-errors: 1.0.2 - - parse-json@5.2.0: - dependencies: - "@babel/code-frame": 7.27.1 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - - parse5@7.3.0: - dependencies: - entities: 6.0.1 - - path-exists@4.0.0: {} - - path-is-absolute@1.0.1: {} - - path-key@2.0.1: {} - - path-key@3.1.1: {} - - path-parse@1.0.7: {} - - path-scurry@2.0.0: - dependencies: - lru-cache: 11.1.0 - minipass: 7.1.2 - - path-type@3.0.0: - dependencies: - pify: 3.0.0 - - path-type@4.0.0: {} - - picocolors@1.1.1: {} - - picomatch@2.3.1: {} - - picomatch@3.0.1: {} - - pidtree@0.3.1: {} - - pify@3.0.0: {} - - pirates@4.0.7: {} - - pkg-dir@4.2.0: - dependencies: - find-up: 4.1.0 - - pkg-dir@5.0.0: - dependencies: - find-up: 5.0.0 - - please-upgrade-node@3.2.0: - dependencies: - semver-compare: 1.0.0 - - possible-typed-array-names@1.1.0: {} - - prelude-ls@1.2.1: {} - - prettier@2.8.8: {} - - pretty-format@29.7.0: - dependencies: - "@jest/schemas": 29.6.3 - ansi-styles: 5.2.0 - react-is: 18.3.1 - - pretty-quick@3.3.1(prettier@2.8.8): - dependencies: - execa: 4.1.0 - find-up: 4.1.0 - ignore: 5.3.2 - mri: 1.2.0 - picocolors: 1.1.1 - picomatch: 3.0.1 - prettier: 2.8.8 - tslib: 2.8.1 - - process-nextick-args@2.0.1: {} - - prompts@2.4.2: - dependencies: - kleur: 3.0.3 - sisteransi: 1.0.5 - - prr@1.0.1: {} - - psl@1.15.0: - dependencies: - punycode: 2.3.1 - - pstree.remy@1.1.8: {} - - pump@3.0.3: - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - - punycode.js@2.3.1: {} - - punycode@1.4.1: {} - - punycode@2.3.1: {} - - pure-rand@6.1.0: {} - - qs@6.14.0: - dependencies: - side-channel: 1.1.0 - - querystringify@2.2.0: {} - - queue-microtask@1.2.3: {} - - quick-lru@4.0.1: {} - - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 - - react-is@18.3.1: {} - - read-pkg-up@7.0.1: - dependencies: - find-up: 4.1.0 - read-pkg: 5.2.0 - type-fest: 0.8.1 - - read-pkg@3.0.0: - dependencies: - load-json-file: 4.0.0 - normalize-package-data: 2.5.0 - path-type: 3.0.0 - - read-pkg@5.2.0: - dependencies: - "@types/normalize-package-data": 2.4.4 - normalize-package-data: 2.5.0 - parse-json: 5.2.0 - type-fest: 0.6.0 - - readable-stream@2.3.8: - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - - readable-stream@3.6.2: - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - - readdirp@3.6.0: - dependencies: - picomatch: 2.3.1 - - rechoir@0.7.1: - dependencies: - resolve: 1.22.10 - - redent@3.0.0: - dependencies: - indent-string: 4.0.0 - strip-indent: 3.0.0 - - reflect.getprototypeof@1.0.10: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - get-intrinsic: 1.3.0 - get-proto: 1.0.1 - which-builtin-type: 1.2.1 - - regexp.prototype.flags@1.5.4: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-errors: 1.3.0 - get-proto: 1.0.1 - gopd: 1.2.0 - set-function-name: 2.0.2 - - require-directory@2.1.1: {} - - require-from-string@2.0.2: {} - - requires-port@1.0.0: {} - - resolve-cwd@3.0.0: - dependencies: - resolve-from: 5.0.0 - - resolve-from@4.0.0: {} - - resolve-from@5.0.0: {} - - resolve-global@1.0.0: - dependencies: - global-dirs: 0.1.1 - - resolve.exports@2.0.3: {} - - resolve@1.22.10: - dependencies: - is-core-module: 2.16.1 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - - reusify@1.1.0: {} - - rimraf@3.0.2: - dependencies: - glob: 7.2.3 - - run-con@1.3.2: - dependencies: - deep-extend: 0.6.0 - ini: 4.1.3 - minimist: 1.2.8 - strip-json-comments: 3.1.1 - - run-parallel@1.2.0: - dependencies: - queue-microtask: 1.2.3 - - safe-array-concat@1.1.3: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - get-intrinsic: 1.3.0 - has-symbols: 1.1.0 - isarray: 2.0.5 - - safe-buffer@5.1.2: {} - - safe-buffer@5.2.1: {} - - safe-push-apply@1.0.0: - dependencies: - es-errors: 1.3.0 - isarray: 2.0.5 - - safe-regex-test@1.1.0: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-regex: 1.2.1 - - safer-buffer@2.1.2: {} - - saxes@6.0.0: - dependencies: - xmlchars: 2.2.0 - - schema-utils@4.3.2: - dependencies: - "@types/json-schema": 7.0.15 - ajv: 8.17.1 - ajv-formats: 2.1.1(ajv@8.17.1) - ajv-keywords: 5.1.0(ajv@8.17.1) - - secure-keys@1.0.0: {} - - semantic-release-plugin-update-version-in-files@1.1.0: - dependencies: - debug: 4.4.1(supports-color@5.5.0) - glob: 7.2.3 - transitivePeerDependencies: - - supports-color - - semver-compare@1.0.0: {} - - semver-regex@3.1.4: {} - - semver@5.7.2: {} - - semver@6.3.1: {} - - semver@7.5.4: - dependencies: - lru-cache: 6.0.0 - - semver@7.7.2: {} - - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 - - set-function-length@1.2.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.3.0 - gopd: 1.2.0 - has-property-descriptors: 1.0.2 - - set-function-name@2.0.2: - dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - functions-have-names: 1.2.3 - has-property-descriptors: 1.0.2 - - set-proto@1.0.0: - dependencies: - dunder-proto: 1.0.1 - es-errors: 1.3.0 - es-object-atoms: 1.1.1 - - shallow-clone@3.0.1: - dependencies: - kind-of: 6.0.3 - - shebang-command@1.2.0: - dependencies: - shebang-regex: 1.0.0 - - shebang-command@2.0.0: - dependencies: - shebang-regex: 3.0.0 - - shebang-regex@1.0.0: {} - - shebang-regex@3.0.0: {} - - shell-quote@1.8.3: {} - - shiki@0.10.1: - dependencies: - jsonc-parser: 3.3.1 - vscode-oniguruma: 1.7.0 - vscode-textmate: 5.2.0 - - side-channel-list@1.0.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - - side-channel-map@1.0.1: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - - side-channel-weakmap@1.0.2: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - get-intrinsic: 1.3.0 - object-inspect: 1.13.4 - side-channel-map: 1.0.1 - - side-channel@1.1.0: - dependencies: - es-errors: 1.3.0 - object-inspect: 1.13.4 - side-channel-list: 1.0.0 - side-channel-map: 1.0.1 - side-channel-weakmap: 1.0.2 - - signal-exit@3.0.7: {} - - signal-exit@4.1.0: {} - - simple-update-notifier@2.0.0: - dependencies: - semver: 7.7.2 - - sisteransi@1.0.5: {} - - slash@3.0.0: {} - - smol-toml@1.3.4: {} - - source-map-support@0.5.13: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map-support@0.5.21: - dependencies: - buffer-from: 1.1.2 - source-map: 0.6.1 - - source-map@0.6.1: {} - - spdx-correct@3.2.0: - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.21 - - spdx-exceptions@2.5.0: {} - - spdx-expression-parse@3.0.1: - dependencies: - spdx-exceptions: 2.5.0 - spdx-license-ids: 3.0.21 - - spdx-license-ids@3.0.21: {} - - split2@3.2.2: - dependencies: - readable-stream: 3.6.2 - - sprintf-js@1.0.3: {} - - stack-utils@2.0.6: - dependencies: - escape-string-regexp: 2.0.0 - - stop-iteration-iterator@1.1.0: - dependencies: - es-errors: 1.3.0 - internal-slot: 1.1.0 - - stream-browserify@3.0.0: - dependencies: - inherits: 2.0.4 - readable-stream: 3.6.2 - - string-length@4.0.2: - dependencies: - char-regex: 1.0.2 - strip-ansi: 6.0.1 - - string-width@4.2.3: - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - - string-width@5.1.2: - dependencies: - eastasianwidth: 0.2.0 - emoji-regex: 9.2.2 - strip-ansi: 7.1.0 - - string.prototype.padend@3.1.6: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - - string.prototype.trim@1.2.10: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-data-property: 1.1.4 - define-properties: 1.2.1 - es-abstract: 1.24.0 - es-object-atoms: 1.1.1 - has-property-descriptors: 1.0.2 - - string.prototype.trimend@1.0.9: - dependencies: - call-bind: 1.0.8 - call-bound: 1.0.4 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string.prototype.trimstart@1.0.8: - dependencies: - call-bind: 1.0.8 - define-properties: 1.2.1 - es-object-atoms: 1.1.1 - - string_decoder@1.1.1: - dependencies: - safe-buffer: 5.1.2 - - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - - strip-ansi@6.0.1: - dependencies: - ansi-regex: 5.0.1 - - strip-ansi@7.1.0: - dependencies: - ansi-regex: 6.1.0 - - strip-bom@3.0.0: {} - - strip-bom@4.0.0: {} - - strip-final-newline@2.0.0: {} - - strip-indent@3.0.0: - dependencies: - min-indent: 1.0.1 - - strip-json-comments@3.1.1: {} - - supports-color@5.5.0: - dependencies: - has-flag: 3.0.0 - - supports-color@7.2.0: - dependencies: - has-flag: 4.0.0 - - supports-color@8.1.1: - dependencies: - has-flag: 4.0.0 - - supports-preserve-symlinks-flag@1.0.0: {} - - symbol-tree@3.2.4: {} - - tapable@1.1.3: {} - - tapable@2.2.2: {} - - terser-webpack-plugin@5.3.14(webpack@5.99.9): - dependencies: - "@jridgewell/trace-mapping": 0.3.25 - jest-worker: 27.5.1 - schema-utils: 4.3.2 - serialize-javascript: 6.0.2 - terser: 5.42.0 - webpack: 5.99.9(webpack-cli@4.10.0) - - terser@5.42.0: - dependencies: - "@jridgewell/source-map": 0.3.6 - acorn: 8.15.0 - commander: 2.20.3 - source-map-support: 0.5.21 - - test-exclude@6.0.0: - dependencies: - "@istanbuljs/schema": 0.1.3 - glob: 7.2.3 - minimatch: 3.1.2 - - text-extensions@1.9.0: {} - - text-table@0.2.0: {} - - through2@4.0.2: - dependencies: - readable-stream: 3.6.2 - - through@2.3.8: {} - - tmpl@1.0.5: {} - - to-regex-range@5.0.1: - dependencies: - is-number: 7.0.0 - - touch@3.1.1: {} - - tough-cookie@4.1.4: - dependencies: - psl: 1.15.0 - punycode: 2.3.1 - universalify: 0.2.0 - url-parse: 1.5.10 - - tr46@0.0.3: {} - - tr46@3.0.0: - dependencies: - punycode: 2.3.1 - - trim-newlines@3.0.1: {} - - ts-api-utils@2.1.0(typescript@4.9.5): - dependencies: - typescript: 4.9.5 - - ts-jest@29.4.0(@babel/core@7.27.4)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.27.4))(jest-util@29.7.0)(jest@29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)))(typescript@4.9.5): - dependencies: - bs-logger: 0.2.6 - ejs: 3.1.10 - fast-json-stable-stringify: 2.1.0 - jest: 29.7.0(@types/node@18.19.112)(ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5)) - json5: 2.2.3 - lodash.memoize: 4.1.2 - make-error: 1.3.6 - semver: 7.7.2 - type-fest: 4.41.0 - typescript: 4.9.5 - yargs-parser: 21.1.1 - optionalDependencies: - "@babel/core": 7.27.4 - "@jest/transform": 29.7.0 - "@jest/types": 29.6.3 - babel-jest: 29.7.0(@babel/core@7.27.4) - jest-util: 29.7.0 - - ts-loader@8.4.0(typescript@4.9.5)(webpack@5.99.9): - dependencies: - chalk: 4.1.2 - enhanced-resolve: 4.5.0 - loader-utils: 2.0.4 - micromatch: 4.0.8 - semver: 7.7.2 - typescript: 4.9.5 - webpack: 5.99.9(webpack-cli@4.10.0) - - ts-node@10.9.2(@types/node@18.19.112)(typescript@4.9.5): - dependencies: - "@cspotcode/source-map-support": 0.8.1 - "@tsconfig/node10": 1.0.11 - "@tsconfig/node12": 1.0.11 - "@tsconfig/node14": 1.0.3 - "@tsconfig/node16": 1.0.4 - "@types/node": 18.19.112 - acorn: 8.15.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.9.5 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - - ts-node@10.9.2(@types/node@20.5.1)(typescript@4.9.5): - dependencies: - "@cspotcode/source-map-support": 0.8.1 - "@tsconfig/node10": 1.0.11 - "@tsconfig/node12": 1.0.11 - "@tsconfig/node14": 1.0.3 - "@tsconfig/node16": 1.0.4 - "@types/node": 20.5.1 - acorn: 8.15.0 - acorn-walk: 8.3.4 - arg: 4.1.3 - create-require: 1.1.1 - diff: 4.0.2 - make-error: 1.3.6 - typescript: 4.9.5 - v8-compile-cache-lib: 3.0.1 - yn: 3.1.1 - - tslib@2.8.1: {} - - type-check@0.4.0: - dependencies: - prelude-ls: 1.2.1 - - type-detect@4.0.8: {} - - type-fest@0.18.1: {} - - type-fest@0.20.2: {} - - type-fest@0.21.3: {} - - type-fest@0.6.0: {} - - type-fest@0.8.1: {} - - type-fest@4.41.0: {} - - typed-array-buffer@1.0.3: - dependencies: - call-bound: 1.0.4 - es-errors: 1.3.0 - is-typed-array: 1.1.15 - - typed-array-byte-length@1.0.3: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - - typed-array-byte-offset@1.0.4: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - has-proto: 1.2.0 - is-typed-array: 1.1.15 - reflect.getprototypeof: 1.0.10 - - typed-array-length@1.0.7: - dependencies: - call-bind: 1.0.8 - for-each: 0.3.5 - gopd: 1.2.0 - is-typed-array: 1.1.15 - possible-typed-array-names: 1.1.0 - reflect.getprototypeof: 1.0.10 - - typedoc@0.22.18(typescript@4.9.5): - dependencies: - glob: 8.1.0 - lunr: 2.3.9 - marked: 4.3.0 - minimatch: 5.1.6 - shiki: 0.10.1 - typescript: 4.9.5 - - typescript@4.9.5: {} - - uc.micro@2.1.0: {} - - unbox-primitive@1.1.0: - dependencies: - call-bound: 1.0.4 - has-bigints: 1.1.0 - has-symbols: 1.1.0 - which-boxed-primitive: 1.1.1 - - undefsafe@2.0.5: {} - - undici-types@5.26.5: {} - - universalify@0.2.0: {} - - universalify@2.0.1: {} - - update-browserslist-db@1.1.3(browserslist@4.25.0): - dependencies: - browserslist: 4.25.0 - escalade: 3.2.0 - picocolors: 1.1.1 - - uri-js@4.4.1: - dependencies: - punycode: 2.3.1 - - url-parse@1.5.10: - dependencies: - querystringify: 2.2.0 - requires-port: 1.0.0 - - url@0.11.4: - dependencies: - punycode: 1.4.1 - qs: 6.14.0 - - util-deprecate@1.0.2: {} - - util@0.12.5: - dependencies: - inherits: 2.0.4 - is-arguments: 1.2.0 - is-generator-function: 1.1.0 - is-typed-array: 1.1.15 - which-typed-array: 1.1.19 - - v8-compile-cache-lib@3.0.1: {} - - v8-to-istanbul@9.3.0: - dependencies: - "@jridgewell/trace-mapping": 0.3.25 - "@types/istanbul-lib-coverage": 2.0.6 - convert-source-map: 2.0.0 - - validate-npm-package-license@3.0.4: - dependencies: - spdx-correct: 3.2.0 - spdx-expression-parse: 3.0.1 - - vscode-oniguruma@1.7.0: {} - - vscode-textmate@5.2.0: {} - - w3c-xmlserializer@4.0.0: - dependencies: - xml-name-validator: 4.0.0 - - walker@1.0.8: - dependencies: - makeerror: 1.0.12 - - watchpack@2.4.4: - dependencies: - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - - webidl-conversions@3.0.1: {} - - webidl-conversions@7.0.0: {} - - webpack-cli@4.10.0(webpack@5.99.9): - dependencies: - "@discoveryjs/json-ext": 0.5.7 - "@webpack-cli/configtest": 1.2.0(webpack-cli@4.10.0)(webpack@5.99.9) - "@webpack-cli/info": 1.5.0(webpack-cli@4.10.0) - "@webpack-cli/serve": 1.7.0(webpack-cli@4.10.0) - colorette: 2.0.20 - commander: 7.2.0 - cross-spawn: 7.0.6 - fastest-levenshtein: 1.0.16 - import-local: 3.2.0 - interpret: 2.2.0 - rechoir: 0.7.1 - webpack: 5.99.9(webpack-cli@4.10.0) - webpack-merge: 5.10.0 - - webpack-merge@5.10.0: - dependencies: - clone-deep: 4.0.1 - flat: 5.0.2 - wildcard: 2.0.1 - - webpack-sources@3.3.2: {} - - webpack@5.99.9(webpack-cli@4.10.0): - dependencies: - "@types/eslint-scope": 3.7.7 - "@types/estree": 1.0.8 - "@types/json-schema": 7.0.15 - "@webassemblyjs/ast": 1.14.1 - "@webassemblyjs/wasm-edit": 1.14.1 - "@webassemblyjs/wasm-parser": 1.14.1 - acorn: 8.15.0 - browserslist: 4.25.0 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.18.1 - es-module-lexer: 1.7.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - json-parse-even-better-errors: 2.3.1 - loader-runner: 4.3.0 - mime-types: 2.1.35 - neo-async: 2.6.2 - schema-utils: 4.3.2 - tapable: 2.2.2 - terser-webpack-plugin: 5.3.14(webpack@5.99.9) - watchpack: 2.4.4 - webpack-sources: 3.3.2 - optionalDependencies: - webpack-cli: 4.10.0(webpack@5.99.9) - transitivePeerDependencies: - - "@swc/core" - - esbuild - - uglify-js - - whatwg-encoding@2.0.0: - dependencies: - iconv-lite: 0.6.3 - - whatwg-mimetype@3.0.0: {} - - whatwg-url@11.0.0: - dependencies: - tr46: 3.0.0 - webidl-conversions: 7.0.0 - - whatwg-url@5.0.0: - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - - which-boxed-primitive@1.1.1: - dependencies: - is-bigint: 1.1.0 - is-boolean-object: 1.2.2 - is-number-object: 1.1.1 - is-string: 1.1.1 - is-symbol: 1.1.1 - - which-builtin-type@1.2.1: - dependencies: - call-bound: 1.0.4 - function.prototype.name: 1.1.8 - has-tostringtag: 1.0.2 - is-async-function: 2.1.1 - is-date-object: 1.1.0 - is-finalizationregistry: 1.1.1 - is-generator-function: 1.1.0 - is-regex: 1.2.1 - is-weakref: 1.1.1 - isarray: 2.0.5 - which-boxed-primitive: 1.1.1 - which-collection: 1.0.2 - which-typed-array: 1.1.19 - - which-collection@1.0.2: - dependencies: - is-map: 2.0.3 - is-set: 2.0.3 - is-weakmap: 2.0.2 - is-weakset: 2.0.4 - - which-pm-runs@1.1.0: {} - - which-typed-array@1.1.19: - dependencies: - available-typed-arrays: 1.0.7 - call-bind: 1.0.8 - call-bound: 1.0.4 - for-each: 0.3.5 - get-proto: 1.0.1 - gopd: 1.2.0 - has-tostringtag: 1.0.2 - - which@1.3.1: - dependencies: - isexe: 2.0.0 - - which@2.0.2: - dependencies: - isexe: 2.0.0 - - wildcard@2.0.1: {} - - word-wrap@1.2.5: {} - - wrap-ansi@7.0.0: - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - - wrap-ansi@8.1.0: - dependencies: - ansi-styles: 6.2.1 - string-width: 5.1.2 - strip-ansi: 7.1.0 - - wrappy@1.0.2: {} - - write-file-atomic@4.0.2: - dependencies: - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - - ws@8.18.2: {} - - xml-name-validator@4.0.0: {} - - xmlchars@2.2.0: {} - - y18n@5.0.8: {} - - yallist@3.1.1: {} - - yallist@4.0.0: {} - - yaml-lint@1.7.0: - dependencies: - consola: 2.15.3 - globby: 11.1.0 - js-yaml: 4.1.0 - nconf: 0.12.1 - - yaml@1.10.2: {} - - yargs-parser@20.2.9: {} - - yargs-parser@21.1.1: {} - - yargs@16.2.0: - dependencies: - cliui: 7.0.4 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - - yargs@17.7.2: - dependencies: - cliui: 8.0.1 - escalade: 3.2.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - - yn@3.1.1: {} - - yocto-queue@0.1.0: {} diff --git a/reference.md b/reference.md new file mode 100644 index 00000000..feb0416a --- /dev/null +++ b/reference.md @@ -0,0 +1,2883 @@ +# Reference + +## Agent V1 Settings Think Models + +
client.agent.v1.settings.think.models.list() -> Deepgram.AgentThinkModelsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves the available think models that can be used for AI agent processing + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.agent.v1.settings.think.models.list(); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**requestOptions:** `Models.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Auth V1 Tokens + +
client.auth.v1.tokens.grant({ ...params }) -> Deepgram.GrantV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Generates a temporary JSON Web Token (JWT) with a 30-second (by default) TTL and usage::write permission for core voice APIs, requiring an API key with Member or higher authorization. Tokens created with this endpoint will not work with the Manage APIs. + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.auth.v1.tokens.grant(); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Deepgram.auth.v1.GrantV1Request` + +
+
+ +
+
+ +**requestOptions:** `Tokens.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Listen V1 Media + +
client.listen.v1.media.transcribeUrl({ ...params }) -> Deepgram.MediaTranscribeResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Transcribe audio and video using Deepgram's speech-to-text REST API + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.listen.v1.media.transcribeUrl({ + callback: "callback", + callback_method: "POST", + extra: "extra", + sentiment: true, + summarize: "v2", + tag: "tag", + topics: true, + custom_topic: "custom_topic", + custom_topic_mode: "extended", + intents: true, + custom_intent: "custom_intent", + custom_intent_mode: "extended", + detect_entities: true, + detect_language: true, + diarize: true, + dictation: true, + encoding: "linear16", + filler_words: true, + keywords: "keywords", + language: "language", + measurements: true, + model: "nova-3", + multichannel: true, + numerals: true, + paragraphs: true, + profanity_filter: true, + punctuate: true, + redact: "redact", + replace: "replace", + search: "search", + smart_format: true, + utterances: true, + utt_split: 1.1, + version: "latest", + mip_opt_out: true, + url: "https://dpgr.am/spacewalk.wav", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Deepgram.listen.v1.ListenV1RequestUrl` + +
+
+ +
+
+ +**requestOptions:** `Media.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.listen.v1.media.transcribeFile(uploadable, { ...params }) -> Deepgram.MediaTranscribeResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Transcribe audio and video using Deepgram's speech-to-text REST API + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.listen.v1.media.transcribeFile(createReadStream("path/to/file"), {}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**uploadable:** `core.file.Uploadable` + +
+
+ +
+
+ +**request:** `Deepgram.listen.v1.MediaTranscribeRequestOctetStream` + +
+
+ +
+
+ +**requestOptions:** `Media.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Models + +
client.manage.v1.models.list({ ...params }) -> Deepgram.ListModelsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Returns metadata on all the latest public models. To retrieve custom models, use Get Project Models. + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.models.list({ + include_outdated: true, +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.ModelsListRequest` + +
+
+ +
+
+ +**requestOptions:** `Models.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.models.get(modelId) -> Deepgram.GetModelV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Returns metadata for a specific public model + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.models.get("af6e9977-99f6-4d8f-b6f5-dfdf6fb6e291"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**modelId:** `string` — The specific UUID of the model + +
+
+ +
+
+ +**requestOptions:** `Models.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects + +
client.manage.v1.projects.list() -> Deepgram.ListProjectsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves basic information about the projects associated with the API key + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.list(); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**requestOptions:** `Projects.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.get(projectId, { ...params }) -> Deepgram.GetProjectV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves information about the specified project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.get("123456-7890-1234-5678-901234", { + limit: 1.1, + page: 1.1, +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.ProjectsGetRequest` + +
+
+ +
+
+ +**requestOptions:** `Projects.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.delete(projectId) -> Deepgram.DeleteProjectV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Deletes the specified project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.delete("123456-7890-1234-5678-901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**requestOptions:** `Projects.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.update(projectId, { ...params }) -> Deepgram.UpdateProjectV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Updates the name or other properties of an existing project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.update("123456-7890-1234-5678-901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.UpdateProjectV1Request` + +
+
+ +
+
+ +**requestOptions:** `Projects.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.leave(projectId) -> Deepgram.LeaveProjectV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Removes the authenticated account from the specific project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.leave("123456-7890-1234-5678-901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**requestOptions:** `Projects.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Keys + +
client.manage.v1.projects.keys.list(projectId, { ...params }) -> Deepgram.ListProjectKeysV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves all API keys associated with the specified project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.keys.list("123456-7890-1234-5678-901234", { + status: "active", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.KeysListRequest` + +
+
+ +
+
+ +**requestOptions:** `Keys.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.keys.create(projectId, { ...params }) -> Deepgram.CreateKeyV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Creates a new API key with specified settings for the project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.keys.create("project_id", { + key: "value", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.CreateKeyV1RequestOne` + +
+
+ +
+
+ +**requestOptions:** `Keys.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.keys.get(projectId, keyId) -> Deepgram.GetProjectKeyV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves information about a specified API key + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.keys.get("123456-7890-1234-5678-901234", "123456789012345678901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**keyId:** `string` — The unique identifier of the API key + +
+
+ +
+
+ +**requestOptions:** `Keys.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.keys.delete(projectId, keyId) -> Deepgram.DeleteProjectKeyV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Deletes an API key for a specific project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.keys.delete("123456-7890-1234-5678-901234", "123456789012345678901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**keyId:** `string` — The unique identifier of the API key + +
+
+ +
+
+ +**requestOptions:** `Keys.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Members + +
client.manage.v1.projects.members.list(projectId) -> Deepgram.ListProjectMembersV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a list of members for a given project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.members.list("123456-7890-1234-5678-901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**requestOptions:** `Members.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.members.delete(projectId, memberId) -> Deepgram.DeleteProjectMemberV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Removes a member from the project using their unique member ID + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.members.delete("123456-7890-1234-5678-901234", "123456789012345678901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**memberId:** `string` — The unique identifier of the Member + +
+
+ +
+
+ +**requestOptions:** `Members.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Models + +
client.manage.v1.projects.models.list(projectId, { ...params }) -> Deepgram.ListModelsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Returns metadata on all the latest models that a specific project has access to, including non-public models + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.models.list("123456-7890-1234-5678-901234", { + include_outdated: true, +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.ModelsListRequest` + +
+
+ +
+
+ +**requestOptions:** `Models.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.models.get(projectId, modelId) -> Deepgram.GetModelV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Returns metadata for a specific model + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.models.get("123456-7890-1234-5678-901234", "af6e9977-99f6-4d8f-b6f5-dfdf6fb6e291"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**modelId:** `string` — The specific UUID of the model + +
+
+ +
+
+ +**requestOptions:** `Models.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Requests + +
client.manage.v1.projects.requests.list(projectId, { ...params }) -> Deepgram.ListProjectRequestsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Generates a list of requests for a specific project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.requests.list("123456-7890-1234-5678-901234", { + start: "2024-01-15T09:30:00Z", + end: "2024-01-15T09:30:00Z", + limit: 1.1, + page: 1.1, + accessor: "12345678-1234-1234-1234-123456789012", + request_id: "12345678-1234-1234-1234-123456789012", + deployment: "hosted", + endpoint: "listen", + method: "sync", + status: "succeeded", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.RequestsListRequest` + +
+
+ +
+
+ +**requestOptions:** `Requests.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.requests.get(projectId, requestId) -> Deepgram.GetProjectRequestV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a specific request for a specific project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.requests.get("123456-7890-1234-5678-901234", "123456-7890-1234-5678-901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**requestId:** `string` — The unique identifier of the request + +
+
+ +
+
+ +**requestOptions:** `Requests.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Usage + +
client.manage.v1.projects.usage.get(projectId, { ...params }) -> Deepgram.UsageV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves the usage for a specific project. Use Get Project Usage Breakdown for a more comprehensive usage summary. + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.usage.get("123456-7890-1234-5678-901234", { + start: "start", + end: "end", + accessor: "12345678-1234-1234-1234-123456789012", + alternatives: true, + callback_method: true, + callback: true, + channels: true, + custom_intent_mode: true, + custom_intent: true, + custom_topic_mode: true, + custom_topic: true, + deployment: "hosted", + detect_entities: true, + detect_language: true, + diarize: true, + dictation: true, + encoding: true, + endpoint: "listen", + extra: true, + filler_words: true, + intents: true, + keyterm: true, + keywords: true, + language: true, + measurements: true, + method: "sync", + model: "6f548761-c9c0-429a-9315-11a1d28499c8", + multichannel: true, + numerals: true, + paragraphs: true, + profanity_filter: true, + punctuate: true, + redact: true, + replace: true, + sample_rate: true, + search: true, + sentiment: true, + smart_format: true, + summarize: true, + tag: "tag1", + topics: true, + utt_split: true, + utterances: true, + version: true, +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.UsageGetRequest` + +
+
+ +
+
+ +**requestOptions:** `Usage.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Billing Balances + +
client.manage.v1.projects.billing.balances.list(projectId) -> Deepgram.ListProjectBalancesV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Generates a list of outstanding balances for the specified project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.billing.balances.list("123456-7890-1234-5678-901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**requestOptions:** `Balances.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.billing.balances.get(projectId, balanceId) -> Deepgram.GetProjectBalanceV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves details about the specified balance + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.billing.balances.get("123456-7890-1234-5678-901234", "123456-7890-1234-5678-901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**balanceId:** `string` — The unique identifier of the balance + +
+
+ +
+
+ +**requestOptions:** `Balances.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Billing Breakdown + +
client.manage.v1.projects.billing.breakdown.list(projectId, { ...params }) -> Deepgram.BillingBreakdownV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves the billing summary for a specific project, with various filter options or by grouping options. + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.billing.breakdown.list("123456-7890-1234-5678-901234", { + start: "start", + end: "end", + accessor: "12345678-1234-1234-1234-123456789012", + deployment: "hosted", + tag: "tag1", + line_item: "streaming::nova-3", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.billing.BreakdownListRequest` + +
+
+ +
+
+ +**requestOptions:** `Breakdown.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Billing Purchases + +
client.manage.v1.projects.billing.purchases.list(projectId, { ...params }) -> Deepgram.ListProjectPurchasesV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Returns the original purchased amount on an order transaction + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.billing.purchases.list("123456-7890-1234-5678-901234", { + limit: 1.1, +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.billing.PurchasesListRequest` + +
+
+ +
+
+ +**requestOptions:** `Purchases.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Members Invites + +
client.manage.v1.projects.members.invites.list(projectId) -> Deepgram.ListProjectInvitesV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Generates a list of invites for a specific project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.members.invites.list("123456-7890-1234-5678-901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**requestOptions:** `Invites.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.members.invites.create(projectId, { ...params }) -> Deepgram.CreateProjectInviteV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Generates an invite for a specific project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.members.invites.create("123456-7890-1234-5678-901234", { + email: "email", + scope: "scope", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.members.CreateProjectInviteV1Request` + +
+
+ +
+
+ +**requestOptions:** `Invites.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.members.invites.delete(projectId, email) -> Deepgram.DeleteProjectInviteV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Deletes an invite for a specific project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.members.invites.delete("123456-7890-1234-5678-901234", "john.doe@example.com"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**email:** `string` — The email address of the member + +
+
+ +
+
+ +**requestOptions:** `Invites.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Members Scopes + +
client.manage.v1.projects.members.scopes.list(projectId, memberId) -> Deepgram.ListProjectMemberScopesV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves a list of scopes for a specific member + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.members.scopes.list("123456-7890-1234-5678-901234", "123456789012345678901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**memberId:** `string` — The unique identifier of the Member + +
+
+ +
+
+ +**requestOptions:** `Scopes.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.manage.v1.projects.members.scopes.update(projectId, memberId, { ...params }) -> Deepgram.UpdateProjectMemberScopesV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Updates the scopes for a specific member + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.members.scopes.update("123456-7890-1234-5678-901234", "123456789012345678901234", { + scope: "admin", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**memberId:** `string` — The unique identifier of the Member + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.members.UpdateProjectMemberScopesV1Request` + +
+
+ +
+
+ +**requestOptions:** `Scopes.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Usage Breakdown + +
client.manage.v1.projects.usage.breakdown.get(projectId, { ...params }) -> Deepgram.UsageBreakdownV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Retrieves the usage breakdown for a specific project, with various filter options by API feature or by groupings. Setting a feature (e.g. diarize) to true includes requests that used that feature, while false excludes requests that used it. Multiple true filters are combined with OR logic, while false filters use AND logic. + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.usage.breakdown.get("123456-7890-1234-5678-901234", { + start: "start", + end: "end", + grouping: "accessor", + accessor: "12345678-1234-1234-1234-123456789012", + alternatives: true, + callback_method: true, + callback: true, + channels: true, + custom_intent_mode: true, + custom_intent: true, + custom_topic_mode: true, + custom_topic: true, + deployment: "hosted", + detect_entities: true, + detect_language: true, + diarize: true, + dictation: true, + encoding: true, + endpoint: "listen", + extra: true, + filler_words: true, + intents: true, + keyterm: true, + keywords: true, + language: true, + measurements: true, + method: "sync", + model: "6f548761-c9c0-429a-9315-11a1d28499c8", + multichannel: true, + numerals: true, + paragraphs: true, + profanity_filter: true, + punctuate: true, + redact: true, + replace: true, + sample_rate: true, + search: true, + sentiment: true, + smart_format: true, + summarize: true, + tag: "tag1", + topics: true, + utt_split: true, + utterances: true, + version: true, +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.usage.BreakdownGetRequest` + +
+
+ +
+
+ +**requestOptions:** `Breakdown.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Manage V1 Projects Usage Fields + +
client.manage.v1.projects.usage.fields.list(projectId, { ...params }) -> Deepgram.UsageFieldsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Lists the features, models, tags, languages, and processing method used for requests in the specified project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.manage.v1.projects.usage.fields.list("123456-7890-1234-5678-901234", { + start: "start", + end: "end", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.manage.v1.projects.usage.FieldsListRequest` + +
+
+ +
+
+ +**requestOptions:** `Fields.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Read V1 Text + +
client.read.v1.text.analyze({ ...params }) -> Deepgram.ReadV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Analyze text content using Deepgrams text analysis API + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.read.v1.text.analyze({ + callback: "callback", + callback_method: "POST", + sentiment: true, + summarize: "v2", + tag: "tag", + topics: true, + custom_topic: "custom_topic", + custom_topic_mode: "extended", + intents: true, + custom_intent: "custom_intent", + custom_intent_mode: "extended", + language: "language", + body: { + url: "url", + }, +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Deepgram.read.v1.TextAnalyzeRequest` + +
+
+ +
+
+ +**requestOptions:** `Text.RequestOptions` + +
+
+
+
+ +
+
+
+ +## SelfHosted V1 DistributionCredentials + +
client.selfHosted.v1.distributionCredentials.list(projectId) -> Deepgram.ListProjectDistributionCredentialsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Lists sets of distribution credentials for the specified project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.selfHosted.v1.distributionCredentials.list("123456-7890-1234-5678-901234"); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**requestOptions:** `DistributionCredentials.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.selfHosted.v1.distributionCredentials.create(projectId, { ...params }) -> Deepgram.CreateProjectDistributionCredentialsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Creates a set of distribution credentials for the specified project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.selfHosted.v1.distributionCredentials.create("123456-7890-1234-5678-901234", { + provider: "quay", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**request:** `Deepgram.selfHosted.v1.CreateProjectDistributionCredentialsV1Request` + +
+
+ +
+
+ +**requestOptions:** `DistributionCredentials.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.selfHosted.v1.distributionCredentials.get(projectId, distributionCredentialsId) -> Deepgram.GetProjectDistributionCredentialsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Returns a set of distribution credentials for the specified project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.selfHosted.v1.distributionCredentials.get( + "123456-7890-1234-5678-901234", + "8b36cfd0-472f-4a21-833f-2d6343c3a2f3", +); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**distributionCredentialsId:** `string` — The UUID of the distribution credentials + +
+
+ +
+
+ +**requestOptions:** `DistributionCredentials.RequestOptions` + +
+
+
+
+ +
+
+
+ +
client.selfHosted.v1.distributionCredentials.delete(projectId, distributionCredentialsId) -> Deepgram.GetProjectDistributionCredentialsV1Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Deletes a set of distribution credentials for the specified project + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.selfHosted.v1.distributionCredentials.delete( + "123456-7890-1234-5678-901234", + "8b36cfd0-472f-4a21-833f-2d6343c3a2f3", +); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**projectId:** `string` — The unique identifier of the project + +
+
+ +
+
+ +**distributionCredentialsId:** `string` — The UUID of the distribution credentials + +
+
+ +
+
+ +**requestOptions:** `DistributionCredentials.RequestOptions` + +
+
+
+
+ +
+
+
+ +## Speak V1 Audio + +
client.speak.v1.audio.generate({ ...params }) -> core.BinaryResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Convert text into natural-sounding speech using Deepgram's TTS REST API + +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.speak.v1.audio.generate({ + text: "text", +}); +``` + +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `Deepgram.speak.v1.SpeakV1Request` + +
+
+ +
+
+ +**requestOptions:** `Audio.RequestOptions` + +
+
+
+
+ +
+
+
diff --git a/scripts/rename-to-esm-files.js b/scripts/rename-to-esm-files.js new file mode 100644 index 00000000..dc1df1cb --- /dev/null +++ b/scripts/rename-to-esm-files.js @@ -0,0 +1,123 @@ +#!/usr/bin/env node + +const fs = require("fs").promises; +const path = require("path"); + +const extensionMap = { + ".js": ".mjs", + ".d.ts": ".d.mts", +}; +const oldExtensions = Object.keys(extensionMap); + +async function findFiles(rootPath) { + const files = []; + + async function scan(directory) { + const entries = await fs.readdir(directory, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(directory, entry.name); + + if (entry.isDirectory()) { + if (entry.name !== "node_modules" && !entry.name.startsWith(".")) { + await scan(fullPath); + } + } else if (entry.isFile()) { + if (oldExtensions.some((ext) => entry.name.endsWith(ext))) { + files.push(fullPath); + } + } + } + } + + await scan(rootPath); + return files; +} + +async function updateFiles(files) { + const updatedFiles = []; + for (const file of files) { + const updated = await updateFileContents(file); + updatedFiles.push(updated); + } + + console.log(`Updated imports in ${updatedFiles.length} files.`); +} + +async function updateFileContents(file) { + const content = await fs.readFile(file, "utf8"); + + let newContent = content; + // Update each extension type defined in the map + for (const [oldExt, newExt] of Object.entries(extensionMap)) { + // Handle static imports/exports + const staticRegex = new RegExp(`(import|export)(.+from\\s+['"])(\\.\\.?\\/[^'"]+)(\\${oldExt})(['"])`, "g"); + newContent = newContent.replace(staticRegex, `$1$2$3${newExt}$5`); + + // Handle dynamic imports (yield import, await import, regular import()) + const dynamicRegex = new RegExp( + `(yield\\s+import|await\\s+import|import)\\s*\\(\\s*['"](\\.\\.\?\\/[^'"]+)(\\${oldExt})['"]\\s*\\)`, + "g", + ); + newContent = newContent.replace(dynamicRegex, `$1("$2${newExt}")`); + } + + if (content !== newContent) { + await fs.writeFile(file, newContent, "utf8"); + return true; + } + return false; +} + +async function renameFiles(files) { + let counter = 0; + for (const file of files) { + const ext = oldExtensions.find((ext) => file.endsWith(ext)); + const newExt = extensionMap[ext]; + + if (newExt) { + const newPath = file.slice(0, -ext.length) + newExt; + await fs.rename(file, newPath); + counter++; + } + } + + console.log(`Renamed ${counter} files.`); +} + +async function main() { + try { + const targetDir = process.argv[2]; + if (!targetDir) { + console.error("Please provide a target directory"); + process.exit(1); + } + + const targetPath = path.resolve(targetDir); + const targetStats = await fs.stat(targetPath); + + if (!targetStats.isDirectory()) { + console.error("The provided path is not a directory"); + process.exit(1); + } + + console.log(`Scanning directory: ${targetDir}`); + + const files = await findFiles(targetDir); + + if (files.length === 0) { + console.log("No matching files found."); + process.exit(0); + } + + console.log(`Found ${files.length} files.`); + await updateFiles(files); + await renameFiles(files); + console.log("\nDone!"); + } catch (error) { + console.error("An error occurred:", error.message); + process.exit(1); + } +} + +main(); diff --git a/scripts/test-offline.js b/scripts/test-offline.js deleted file mode 100755 index d3466165..00000000 --- a/scripts/test-offline.js +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env node - -/* eslint-env node */ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */ - -/** - * Test script to verify e2e tests work properly offline - * This script simulates offline conditions and runs the tests - */ - -const { spawn } = require("child_process"); - -console.log("🧪 Testing Deepgram JS SDK e2e tests in offline mode\n"); - -// Environment variables to ensure offline testing -const env = { - ...process.env, - JEST_SILENT: "false", - NODE_ENV: "test", - // Remove any real API key to force mock usage - DEEPGRAM_API_KEY: "mock-api-key-for-offline-testing", -}; - -// Test command -const testCommand = "npm"; -const testArgs = ["test", "--", "tests/e2e/", "--verbose"]; - -console.log("🎭 Running e2e tests with mocked API calls..."); -console.log(`Command: ${testCommand} ${testArgs.join(" ")}\n`); - -const testProcess = spawn(testCommand, testArgs, { - env, - stdio: "inherit", - shell: true, -}); - -testProcess.on("close", (code) => { - if (code === 0) { - console.log("\n✅ All e2e tests passed in offline mode!"); - console.log("🎉 Your tests are properly configured to work without internet connection."); - console.log("\n💡 To run tests with real API calls (for updating snapshots):"); - console.log(" npm test -- tests/e2e/ --updateSnapshot"); - console.log("\n🔧 To force real API calls without updating snapshots:"); - console.log(" DEEPGRAM_FORCE_REAL_API=true npm test -- tests/e2e/"); - } else { - console.log(`\n❌ Tests failed with exit code ${code}`); - console.log("🔍 This indicates there might be network dependencies that need to be mocked."); - } -}); - -testProcess.on("error", (error) => { - console.error("❌ Failed to run tests:", error); - process.exit(1); -}); diff --git a/src/Client.ts b/src/Client.ts new file mode 100644 index 00000000..15bd61e9 --- /dev/null +++ b/src/Client.ts @@ -0,0 +1,95 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "./environments.js"; +import * as core from "./core/index.js"; +import { mergeHeaders } from "./core/headers.js"; +import { Agent } from "./api/resources/agent/client/Client.js"; +import { Auth } from "./api/resources/auth/client/Client.js"; +import { Listen } from "./api/resources/listen/client/Client.js"; +import { Manage } from "./api/resources/manage/client/Client.js"; +import { Read } from "./api/resources/read/client/Client.js"; +import { SelfHosted } from "./api/resources/selfHosted/client/Client.js"; +import { Speak } from "./api/resources/speak/client/Client.js"; + +export declare namespace DeepgramClient { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class DeepgramClient { + protected readonly _options: DeepgramClient.Options; + protected _agent: Agent | undefined; + protected _auth: Auth | undefined; + protected _listen: Listen | undefined; + protected _manage: Manage | undefined; + protected _read: Read | undefined; + protected _selfHosted: SelfHosted | undefined; + protected _speak: Speak | undefined; + + constructor(_options: DeepgramClient.Options = {}) { + this._options = { + ..._options, + headers: mergeHeaders( + { + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@deepgram/sdk", + "X-Fern-SDK-Version": "4.11.3", + "User-Agent": "@deepgram/sdk/4.11.3", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + _options?.headers, + ), + }; + } + + public get agent(): Agent { + return (this._agent ??= new Agent(this._options)); + } + + public get auth(): Auth { + return (this._auth ??= new Auth(this._options)); + } + + public get listen(): Listen { + return (this._listen ??= new Listen(this._options)); + } + + public get manage(): Manage { + return (this._manage ??= new Manage(this._options)); + } + + public get read(): Read { + return (this._read ??= new Read(this._options)); + } + + public get selfHosted(): SelfHosted { + return (this._selfHosted ??= new SelfHosted(this._options)); + } + + public get speak(): Speak { + return (this._speak ??= new Speak(this._options)); + } +} diff --git a/src/DeepgramClient.ts b/src/DeepgramClient.ts deleted file mode 100644 index 5f7bc99a..00000000 --- a/src/DeepgramClient.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { DeepgramVersionError } from "./lib/errors"; -import { - AbstractClient, - AgentLiveClient, - AuthRestClient, - ListenClient, - ManageClient, - ReadClient, - OnPremClient, - SelfHostedRestClient, - SpeakClient, - ModelsRestClient, -} from "./packages"; - -/** - * The DeepgramClient class provides access to various Deepgram API clients, including ListenClient, ManageClient, SelfHostedRestClient, ReadClient, and SpeakClient. - * - * @see https://github.com/deepgram/deepgram-js-sdk - */ -export default class DeepgramClient extends AbstractClient { - /** - * Returns a new instance of the AuthRestClient, which provides access to the Deepgram API's temporary token endpoints. - * - * @returns {AuthRestClient} A new instance of the AuthRestClient. - * @see https://developers.deepgram.com/reference/token-based-auth-api/grant-token - */ - get auth(): AuthRestClient { - return new AuthRestClient(this.options); - } - /** - * Returns a new instance of the ListenClient, which provides access to the Deepgram API's listening functionality. - * - * @returns {ListenClient} A new instance of the ListenClient. - */ - get listen(): ListenClient { - return new ListenClient(this.options); - } - - /** - * Returns a new instance of the ManageClient, which provides access to the Deepgram API's management functionality. - * - * @returns {ManageClient} A new instance of the ManageClient. - */ - get manage(): ManageClient { - return new ManageClient(this.options); - } - - /** - * Returns a new instance of the ModelsRestClient, which provides access to the Deepgram API's model functionality. - * - * @returns {ModelsRestClient} A new instance of the ModelsRestClient. - */ - get models(): ModelsRestClient { - return new ModelsRestClient(this.options); - } - - /** - * Returns a new instance of the SelfHostedRestClient, which provides access to the Deepgram API's self-hosted functionality. - * - * @returns {OnPremClient} A new instance of the SelfHostedRestClient named as OnPremClient. - * @deprecated use selfhosted() instead - */ - get onprem(): OnPremClient { - return this.selfhosted; - } - - /** - * Returns a new instance of the SelfHostedRestClient, which provides access to the Deepgram API's self-hosted functionality. - * - * @returns {SelfHostedRestClient} A new instance of the SelfHostedRestClient. - */ - get selfhosted(): SelfHostedRestClient { - return new SelfHostedRestClient(this.options); - } - - /** - * Returns a new instance of the ReadClient, which provides access to the Deepgram API's reading functionality. - * - * @returns {ReadClient} A new instance of the ReadClient. - */ - get read(): ReadClient { - return new ReadClient(this.options); - } - - /** - * Returns a new instance of the SpeakClient, which provides access to the Deepgram API's speaking functionality. - * - * @returns {SpeakClient} A new instance of the SpeakClient. - */ - get speak(): SpeakClient { - return new SpeakClient(this.options); - } - - /** - * Returns a new instance of the AgentLiveClient, which provides access to Deepgram's Voice Agent API. - * - * @returns {AgentLiveClient} A new instance of the AgentLiveClient. - * @beta - */ - public agent(endpoint: string = "/:version/agent/converse"): AgentLiveClient { - return new AgentLiveClient(this.options, endpoint); - } - - /** - * @deprecated - * @see https://dpgr.am/js-v3 - */ - get transcription(): any { - throw new DeepgramVersionError(); - } - - /** - * @deprecated - * @see https://dpgr.am/js-v3 - */ - get projects(): any { - throw new DeepgramVersionError(); - } - - /** - * @deprecated - * @see https://dpgr.am/js-v3 - */ - get keys(): any { - throw new DeepgramVersionError(); - } - - /** - * @deprecated - * @see https://dpgr.am/js-v3 - */ - get members(): any { - throw new DeepgramVersionError(); - } - - /** - * @deprecated - * @see https://dpgr.am/js-v3 - */ - get scopes(): any { - throw new DeepgramVersionError(); - } - - /** - * @deprecated - * @see https://dpgr.am/js-v3 - */ - get invitation(): any { - throw new DeepgramVersionError(); - } - - /** - * @deprecated - * @see https://dpgr.am/js-v3 - */ - get usage(): any { - throw new DeepgramVersionError(); - } - - /** - * @deprecated - * @see https://dpgr.am/js-v3 - */ - get billing(): any { - throw new DeepgramVersionError(); - } -} diff --git a/src/api/errors/BadRequestError.ts b/src/api/errors/BadRequestError.ts new file mode 100644 index 00000000..6d71a9dc --- /dev/null +++ b/src/api/errors/BadRequestError.ts @@ -0,0 +1,18 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as errors from "../../errors/index.js"; +import * as core from "../../core/index.js"; + +export class BadRequestError extends errors.DeepgramError { + constructor(body?: unknown, rawResponse?: core.RawResponse) { + super({ + message: "BadRequestError", + statusCode: 400, + body: body, + rawResponse: rawResponse, + }); + Object.setPrototypeOf(this, BadRequestError.prototype); + } +} diff --git a/src/api/errors/index.ts b/src/api/errors/index.ts new file mode 100644 index 00000000..db9ee322 --- /dev/null +++ b/src/api/errors/index.ts @@ -0,0 +1 @@ +export * from "./BadRequestError.js"; diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 00000000..72cddbe7 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,3 @@ +export * from "./resources/index.js"; +export * from "./types/index.js"; +export * from "./errors/index.js"; diff --git a/src/api/resources/agent/client/Client.ts b/src/api/resources/agent/client/Client.ts new file mode 100644 index 00000000..e065c4be --- /dev/null +++ b/src/api/resources/agent/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments.js"; +import * as core from "../../../../core/index.js"; +import { V1 } from "../resources/v1/client/Client.js"; + +export declare namespace Agent { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class Agent { + protected readonly _options: Agent.Options; + protected _v1: V1 | undefined; + + constructor(_options: Agent.Options = {}) { + this._options = _options; + } + + public get v1(): V1 { + return (this._v1 ??= new V1(this._options)); + } +} diff --git a/src/api/resources/agent/client/index.ts b/src/api/resources/agent/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/agent/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/agent/index.ts b/src/api/resources/agent/index.ts new file mode 100644 index 00000000..9eb1192d --- /dev/null +++ b/src/api/resources/agent/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./resources/index.js"; diff --git a/src/api/resources/agent/resources/index.ts b/src/api/resources/agent/resources/index.ts new file mode 100644 index 00000000..c6b56d24 --- /dev/null +++ b/src/api/resources/agent/resources/index.ts @@ -0,0 +1 @@ +export * as v1 from "./v1/index.js"; diff --git a/src/api/resources/agent/resources/v1/client/Client.ts b/src/api/resources/agent/resources/v1/client/Client.ts new file mode 100644 index 00000000..88b0b5c3 --- /dev/null +++ b/src/api/resources/agent/resources/v1/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../environments.js"; +import * as core from "../../../../../../core/index.js"; +import { Settings } from "../resources/settings/client/Client.js"; + +export declare namespace V1 { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class V1 { + protected readonly _options: V1.Options; + protected _settings: Settings | undefined; + + constructor(_options: V1.Options = {}) { + this._options = _options; + } + + public get settings(): Settings { + return (this._settings ??= new Settings(this._options)); + } +} diff --git a/src/api/resources/agent/resources/v1/client/index.ts b/src/api/resources/agent/resources/v1/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/agent/resources/v1/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/agent/resources/v1/index.ts b/src/api/resources/agent/resources/v1/index.ts new file mode 100644 index 00000000..9eb1192d --- /dev/null +++ b/src/api/resources/agent/resources/v1/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./resources/index.js"; diff --git a/src/api/resources/agent/resources/v1/resources/index.ts b/src/api/resources/agent/resources/v1/resources/index.ts new file mode 100644 index 00000000..5d08c463 --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/index.ts @@ -0,0 +1 @@ +export * as settings from "./settings/index.js"; diff --git a/src/api/resources/agent/resources/v1/resources/settings/client/Client.ts b/src/api/resources/agent/resources/v1/resources/settings/client/Client.ts new file mode 100644 index 00000000..b34585b3 --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../environments.js"; +import * as core from "../../../../../../../../core/index.js"; +import { Think } from "../resources/think/client/Client.js"; + +export declare namespace Settings { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class Settings { + protected readonly _options: Settings.Options; + protected _think: Think | undefined; + + constructor(_options: Settings.Options = {}) { + this._options = _options; + } + + public get think(): Think { + return (this._think ??= new Think(this._options)); + } +} diff --git a/src/api/resources/agent/resources/v1/resources/settings/client/index.ts b/src/api/resources/agent/resources/v1/resources/settings/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/agent/resources/v1/resources/settings/index.ts b/src/api/resources/agent/resources/v1/resources/settings/index.ts new file mode 100644 index 00000000..9eb1192d --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./resources/index.js"; diff --git a/src/api/resources/agent/resources/v1/resources/settings/resources/index.ts b/src/api/resources/agent/resources/v1/resources/settings/resources/index.ts new file mode 100644 index 00000000..48db7d4c --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/resources/index.ts @@ -0,0 +1 @@ +export * as think from "./think/index.js"; diff --git a/src/api/resources/agent/resources/v1/resources/settings/resources/think/client/Client.ts b/src/api/resources/agent/resources/v1/resources/settings/resources/think/client/Client.ts new file mode 100644 index 00000000..09a33af1 --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/resources/think/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../core/index.js"; +import { Models } from "../resources/models/client/Client.js"; + +export declare namespace Think { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class Think { + protected readonly _options: Think.Options; + protected _models: Models | undefined; + + constructor(_options: Think.Options = {}) { + this._options = _options; + } + + public get models(): Models { + return (this._models ??= new Models(this._options)); + } +} diff --git a/src/api/resources/agent/resources/v1/resources/settings/resources/think/client/index.ts b/src/api/resources/agent/resources/v1/resources/settings/resources/think/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/resources/think/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/agent/resources/v1/resources/settings/resources/think/index.ts b/src/api/resources/agent/resources/v1/resources/settings/resources/think/index.ts new file mode 100644 index 00000000..9eb1192d --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/resources/think/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./resources/index.js"; diff --git a/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/index.ts b/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/index.ts new file mode 100644 index 00000000..4920fabe --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/index.ts @@ -0,0 +1 @@ +export * as models from "./models/index.js"; diff --git a/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/models/client/Client.ts b/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/models/client/Client.ts new file mode 100644 index 00000000..faa12fc0 --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/models/client/Client.ts @@ -0,0 +1,121 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../../../errors/index.js"; + +export declare namespace Models { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Models { + protected readonly _options: Models.Options; + + constructor(_options: Models.Options = {}) { + this._options = _options; + } + + /** + * Retrieves the available think models that can be used for AI agent processing + * + * @param {Models.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.agent.v1.settings.think.models.list() + */ + public list(requestOptions?: Models.RequestOptions): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(requestOptions)); + } + + private async __list( + requestOptions?: Models.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + "v1/agent/settings/think/models", + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.AgentThinkModelsV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/agent/settings/think/models.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/models/client/index.ts b/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/models/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/models/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/models/index.ts b/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/models/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/src/api/resources/agent/resources/v1/resources/settings/resources/think/resources/models/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/auth/client/Client.ts b/src/api/resources/auth/client/Client.ts new file mode 100644 index 00000000..2d61e82f --- /dev/null +++ b/src/api/resources/auth/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments.js"; +import * as core from "../../../../core/index.js"; +import { V1 } from "../resources/v1/client/Client.js"; + +export declare namespace Auth { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class Auth { + protected readonly _options: Auth.Options; + protected _v1: V1 | undefined; + + constructor(_options: Auth.Options = {}) { + this._options = _options; + } + + public get v1(): V1 { + return (this._v1 ??= new V1(this._options)); + } +} diff --git a/src/api/resources/auth/client/index.ts b/src/api/resources/auth/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/auth/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/auth/index.ts b/src/api/resources/auth/index.ts new file mode 100644 index 00000000..9eb1192d --- /dev/null +++ b/src/api/resources/auth/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./resources/index.js"; diff --git a/src/api/resources/auth/resources/index.ts b/src/api/resources/auth/resources/index.ts new file mode 100644 index 00000000..c6b56d24 --- /dev/null +++ b/src/api/resources/auth/resources/index.ts @@ -0,0 +1 @@ +export * as v1 from "./v1/index.js"; diff --git a/src/api/resources/auth/resources/v1/client/Client.ts b/src/api/resources/auth/resources/v1/client/Client.ts new file mode 100644 index 00000000..facfbdba --- /dev/null +++ b/src/api/resources/auth/resources/v1/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../environments.js"; +import * as core from "../../../../../../core/index.js"; +import { Tokens } from "../resources/tokens/client/Client.js"; + +export declare namespace V1 { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class V1 { + protected readonly _options: V1.Options; + protected _tokens: Tokens | undefined; + + constructor(_options: V1.Options = {}) { + this._options = _options; + } + + public get tokens(): Tokens { + return (this._tokens ??= new Tokens(this._options)); + } +} diff --git a/src/api/resources/auth/resources/v1/client/index.ts b/src/api/resources/auth/resources/v1/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/auth/resources/v1/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/auth/resources/v1/index.ts b/src/api/resources/auth/resources/v1/index.ts new file mode 100644 index 00000000..9eb1192d --- /dev/null +++ b/src/api/resources/auth/resources/v1/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./resources/index.js"; diff --git a/src/api/resources/auth/resources/v1/resources/index.ts b/src/api/resources/auth/resources/v1/resources/index.ts new file mode 100644 index 00000000..258b1f1b --- /dev/null +++ b/src/api/resources/auth/resources/v1/resources/index.ts @@ -0,0 +1,2 @@ +export * as tokens from "./tokens/index.js"; +export * from "./tokens/client/requests/index.js"; diff --git a/src/api/resources/auth/resources/v1/resources/tokens/client/Client.ts b/src/api/resources/auth/resources/v1/resources/tokens/client/Client.ts new file mode 100644 index 00000000..b2e3c0b8 --- /dev/null +++ b/src/api/resources/auth/resources/v1/resources/tokens/client/Client.ts @@ -0,0 +1,127 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../environments.js"; +import * as core from "../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../errors/index.js"; + +export declare namespace Tokens { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Tokens { + protected readonly _options: Tokens.Options; + + constructor(_options: Tokens.Options = {}) { + this._options = _options; + } + + /** + * Generates a temporary JSON Web Token (JWT) with a 30-second (by default) TTL and usage::write permission for core voice APIs, requiring an API key with Member or higher authorization. Tokens created with this endpoint will not work with the Manage APIs. + * + * @param {Deepgram.auth.v1.GrantV1Request} request + * @param {Tokens.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.auth.v1.tokens.grant() + */ + public grant( + request: Deepgram.auth.v1.GrantV1Request = {}, + requestOptions?: Tokens.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__grant(request, requestOptions)); + } + + private async __grant( + request: Deepgram.auth.v1.GrantV1Request = {}, + requestOptions?: Tokens.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + "v1/auth/grant", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.GrantV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling POST /v1/auth/grant."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/auth/resources/v1/resources/tokens/client/index.ts b/src/api/resources/auth/resources/v1/resources/tokens/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/auth/resources/v1/resources/tokens/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/auth/resources/v1/resources/tokens/client/requests/GrantV1Request.ts b/src/api/resources/auth/resources/v1/resources/tokens/client/requests/GrantV1Request.ts new file mode 100644 index 00000000..4314ced8 --- /dev/null +++ b/src/api/resources/auth/resources/v1/resources/tokens/client/requests/GrantV1Request.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * {} + */ +export interface GrantV1Request { + /** Time to live in seconds for the token. Defaults to 30 seconds. */ + ttl_seconds?: number; +} diff --git a/src/api/resources/auth/resources/v1/resources/tokens/client/requests/index.ts b/src/api/resources/auth/resources/v1/resources/tokens/client/requests/index.ts new file mode 100644 index 00000000..0ab5dcfe --- /dev/null +++ b/src/api/resources/auth/resources/v1/resources/tokens/client/requests/index.ts @@ -0,0 +1 @@ +export { type GrantV1Request } from "./GrantV1Request.js"; diff --git a/src/api/resources/auth/resources/v1/resources/tokens/index.ts b/src/api/resources/auth/resources/v1/resources/tokens/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/src/api/resources/auth/resources/v1/resources/tokens/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/index.ts b/src/api/resources/index.ts new file mode 100644 index 00000000..64324146 --- /dev/null +++ b/src/api/resources/index.ts @@ -0,0 +1,7 @@ +export * as listen from "./listen/index.js"; +export * as manage from "./manage/index.js"; +export * as read from "./read/index.js"; +export * as selfHosted from "./selfHosted/index.js"; +export * as speak from "./speak/index.js"; +export * as agent from "./agent/index.js"; +export * as auth from "./auth/index.js"; diff --git a/src/api/resources/listen/client/Client.ts b/src/api/resources/listen/client/Client.ts new file mode 100644 index 00000000..73192178 --- /dev/null +++ b/src/api/resources/listen/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments.js"; +import * as core from "../../../../core/index.js"; +import { V1 } from "../resources/v1/client/Client.js"; + +export declare namespace Listen { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class Listen { + protected readonly _options: Listen.Options; + protected _v1: V1 | undefined; + + constructor(_options: Listen.Options = {}) { + this._options = _options; + } + + public get v1(): V1 { + return (this._v1 ??= new V1(this._options)); + } +} diff --git a/src/api/resources/listen/client/index.ts b/src/api/resources/listen/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/listen/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/listen/index.ts b/src/api/resources/listen/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/listen/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/listen/resources/index.ts b/src/api/resources/listen/resources/index.ts new file mode 100644 index 00000000..c6b56d24 --- /dev/null +++ b/src/api/resources/listen/resources/index.ts @@ -0,0 +1 @@ +export * as v1 from "./v1/index.js"; diff --git a/src/api/resources/listen/resources/v1/client/Client.ts b/src/api/resources/listen/resources/v1/client/Client.ts new file mode 100644 index 00000000..8da02626 --- /dev/null +++ b/src/api/resources/listen/resources/v1/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../environments.js"; +import * as core from "../../../../../../core/index.js"; +import { Media } from "../resources/media/client/Client.js"; + +export declare namespace V1 { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class V1 { + protected readonly _options: V1.Options; + protected _media: Media | undefined; + + constructor(_options: V1.Options = {}) { + this._options = _options; + } + + public get media(): Media { + return (this._media ??= new Media(this._options)); + } +} diff --git a/src/api/resources/listen/resources/v1/client/index.ts b/src/api/resources/listen/resources/v1/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/listen/resources/v1/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/listen/resources/v1/index.ts b/src/api/resources/listen/resources/v1/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/listen/resources/v1/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/listen/resources/v1/resources/index.ts b/src/api/resources/listen/resources/v1/resources/index.ts new file mode 100644 index 00000000..1387e267 --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/index.ts @@ -0,0 +1,3 @@ +export * as media from "./media/index.js"; +export * from "./media/types/index.js"; +export * from "./media/client/requests/index.js"; diff --git a/src/api/resources/listen/resources/v1/resources/media/client/Client.ts b/src/api/resources/listen/resources/v1/resources/media/client/Client.ts new file mode 100644 index 00000000..bcaca202 --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/client/Client.ts @@ -0,0 +1,650 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../environments.js"; +import * as core from "../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../errors/index.js"; + +export declare namespace Media { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Media { + protected readonly _options: Media.Options; + + constructor(_options: Media.Options = {}) { + this._options = _options; + } + + /** + * Transcribe audio and video using Deepgram's speech-to-text REST API + * + * @param {Deepgram.listen.v1.ListenV1RequestUrl} request + * @param {Media.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.listen.v1.media.transcribeUrl({ + * callback: "callback", + * callback_method: "POST", + * extra: "extra", + * sentiment: true, + * summarize: "v2", + * tag: "tag", + * topics: true, + * custom_topic: "custom_topic", + * custom_topic_mode: "extended", + * intents: true, + * custom_intent: "custom_intent", + * custom_intent_mode: "extended", + * detect_entities: true, + * detect_language: true, + * diarize: true, + * dictation: true, + * encoding: "linear16", + * filler_words: true, + * keywords: "keywords", + * language: "language", + * measurements: true, + * model: "nova-3", + * multichannel: true, + * numerals: true, + * paragraphs: true, + * profanity_filter: true, + * punctuate: true, + * redact: "redact", + * replace: "replace", + * search: "search", + * smart_format: true, + * utterances: true, + * utt_split: 1.1, + * version: "latest", + * mip_opt_out: true, + * url: "https://dpgr.am/spacewalk.wav" + * }) + */ + public transcribeUrl( + request: Deepgram.listen.v1.ListenV1RequestUrl, + requestOptions?: Media.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__transcribeUrl(request, requestOptions)); + } + + private async __transcribeUrl( + request: Deepgram.listen.v1.ListenV1RequestUrl, + requestOptions?: Media.RequestOptions, + ): Promise> { + const { + callback, + callback_method: callbackMethod, + extra, + sentiment, + summarize, + tag, + topics, + custom_topic: customTopic, + custom_topic_mode: customTopicMode, + intents, + custom_intent: customIntent, + custom_intent_mode: customIntentMode, + detect_entities: detectEntities, + detect_language: detectLanguage, + diarize, + dictation, + encoding, + filler_words: fillerWords, + keyterm, + keywords, + language, + measurements, + model, + multichannel, + numerals, + paragraphs, + profanity_filter: profanityFilter, + punctuate, + redact, + replace, + search, + smart_format: smartFormat, + utterances, + utt_split: uttSplit, + version, + mip_opt_out: mipOptOut, + ..._body + } = request; + const _queryParams: Record = {}; + if (callback != null) { + _queryParams["callback"] = callback; + } + + if (callbackMethod != null) { + _queryParams["callback_method"] = callbackMethod; + } + + if (extra != null) { + if (Array.isArray(extra)) { + _queryParams["extra"] = extra.map((item) => item); + } else { + _queryParams["extra"] = extra; + } + } + + if (sentiment != null) { + _queryParams["sentiment"] = sentiment.toString(); + } + + if (summarize != null) { + _queryParams["summarize"] = summarize; + } + + if (tag != null) { + if (Array.isArray(tag)) { + _queryParams["tag"] = tag.map((item) => item); + } else { + _queryParams["tag"] = tag; + } + } + + if (topics != null) { + _queryParams["topics"] = topics.toString(); + } + + if (customTopic != null) { + if (Array.isArray(customTopic)) { + _queryParams["custom_topic"] = customTopic.map((item) => item); + } else { + _queryParams["custom_topic"] = customTopic; + } + } + + if (customTopicMode != null) { + _queryParams["custom_topic_mode"] = customTopicMode; + } + + if (intents != null) { + _queryParams["intents"] = intents.toString(); + } + + if (customIntent != null) { + if (Array.isArray(customIntent)) { + _queryParams["custom_intent"] = customIntent.map((item) => item); + } else { + _queryParams["custom_intent"] = customIntent; + } + } + + if (customIntentMode != null) { + _queryParams["custom_intent_mode"] = customIntentMode; + } + + if (detectEntities != null) { + _queryParams["detect_entities"] = detectEntities.toString(); + } + + if (detectLanguage != null) { + _queryParams["detect_language"] = detectLanguage.toString(); + } + + if (diarize != null) { + _queryParams["diarize"] = diarize.toString(); + } + + if (dictation != null) { + _queryParams["dictation"] = dictation.toString(); + } + + if (encoding != null) { + _queryParams["encoding"] = encoding; + } + + if (fillerWords != null) { + _queryParams["filler_words"] = fillerWords.toString(); + } + + if (keyterm != null) { + if (Array.isArray(keyterm)) { + _queryParams["keyterm"] = keyterm.map((item) => item); + } else { + _queryParams["keyterm"] = keyterm; + } + } + + if (keywords != null) { + if (Array.isArray(keywords)) { + _queryParams["keywords"] = keywords.map((item) => item); + } else { + _queryParams["keywords"] = keywords; + } + } + + if (language != null) { + _queryParams["language"] = language; + } + + if (measurements != null) { + _queryParams["measurements"] = measurements.toString(); + } + + if (model != null) { + _queryParams["model"] = model; + } + + if (multichannel != null) { + _queryParams["multichannel"] = multichannel.toString(); + } + + if (numerals != null) { + _queryParams["numerals"] = numerals.toString(); + } + + if (paragraphs != null) { + _queryParams["paragraphs"] = paragraphs.toString(); + } + + if (profanityFilter != null) { + _queryParams["profanity_filter"] = profanityFilter.toString(); + } + + if (punctuate != null) { + _queryParams["punctuate"] = punctuate.toString(); + } + + if (redact != null) { + _queryParams["redact"] = redact; + } + + if (replace != null) { + if (Array.isArray(replace)) { + _queryParams["replace"] = replace.map((item) => item); + } else { + _queryParams["replace"] = replace; + } + } + + if (search != null) { + if (Array.isArray(search)) { + _queryParams["search"] = search.map((item) => item); + } else { + _queryParams["search"] = search; + } + } + + if (smartFormat != null) { + _queryParams["smart_format"] = smartFormat.toString(); + } + + if (utterances != null) { + _queryParams["utterances"] = utterances.toString(); + } + + if (uttSplit != null) { + _queryParams["utt_split"] = uttSplit.toString(); + } + + if (version != null) { + _queryParams["version"] = version; + } + + if (mipOptOut != null) { + _queryParams["mip_opt_out"] = mipOptOut.toString(); + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + "v1/listen", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + requestType: "json", + body: _body, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.listen.v1.MediaTranscribeResponse, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling POST /v1/listen."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Transcribe audio and video using Deepgram's speech-to-text REST API + * + * @param {core.file.Uploadable} uploadable + * @param {Deepgram.listen.v1.MediaTranscribeRequestOctetStream} request + * @param {Media.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * import { createReadStream } from "fs"; + * await client.listen.v1.media.transcribeFile(createReadStream("path/to/file"), {}) + */ + public transcribeFile( + uploadable: core.file.Uploadable, + request: Deepgram.listen.v1.MediaTranscribeRequestOctetStream, + requestOptions?: Media.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__transcribeFile(uploadable, request, requestOptions)); + } + + private async __transcribeFile( + uploadable: core.file.Uploadable, + request: Deepgram.listen.v1.MediaTranscribeRequestOctetStream, + requestOptions?: Media.RequestOptions, + ): Promise> { + const _queryParams: Record = {}; + if (request.callback != null) { + _queryParams["callback"] = request.callback; + } + + if (request.callback_method != null) { + _queryParams["callback_method"] = request.callback_method; + } + + if (request.extra != null) { + if (Array.isArray(request.extra)) { + _queryParams["extra"] = request.extra.map((item) => item); + } else { + _queryParams["extra"] = request.extra; + } + } + + if (request.sentiment != null) { + _queryParams["sentiment"] = request.sentiment.toString(); + } + + if (request.summarize != null) { + _queryParams["summarize"] = request.summarize; + } + + if (request.tag != null) { + if (Array.isArray(request.tag)) { + _queryParams["tag"] = request.tag.map((item) => item); + } else { + _queryParams["tag"] = request.tag; + } + } + + if (request.topics != null) { + _queryParams["topics"] = request.topics.toString(); + } + + if (request.custom_topic != null) { + if (Array.isArray(request.custom_topic)) { + _queryParams["custom_topic"] = request.custom_topic.map((item) => item); + } else { + _queryParams["custom_topic"] = request.custom_topic; + } + } + + if (request.custom_topic_mode != null) { + _queryParams["custom_topic_mode"] = request.custom_topic_mode; + } + + if (request.intents != null) { + _queryParams["intents"] = request.intents.toString(); + } + + if (request.custom_intent != null) { + if (Array.isArray(request.custom_intent)) { + _queryParams["custom_intent"] = request.custom_intent.map((item) => item); + } else { + _queryParams["custom_intent"] = request.custom_intent; + } + } + + if (request.custom_intent_mode != null) { + _queryParams["custom_intent_mode"] = request.custom_intent_mode; + } + + if (request.detect_entities != null) { + _queryParams["detect_entities"] = request.detect_entities.toString(); + } + + if (request.detect_language != null) { + _queryParams["detect_language"] = request.detect_language.toString(); + } + + if (request.diarize != null) { + _queryParams["diarize"] = request.diarize.toString(); + } + + if (request.dictation != null) { + _queryParams["dictation"] = request.dictation.toString(); + } + + if (request.encoding != null) { + _queryParams["encoding"] = request.encoding; + } + + if (request.filler_words != null) { + _queryParams["filler_words"] = request.filler_words.toString(); + } + + if (request.keyterm != null) { + if (Array.isArray(request.keyterm)) { + _queryParams["keyterm"] = request.keyterm.map((item) => item); + } else { + _queryParams["keyterm"] = request.keyterm; + } + } + + if (request.keywords != null) { + if (Array.isArray(request.keywords)) { + _queryParams["keywords"] = request.keywords.map((item) => item); + } else { + _queryParams["keywords"] = request.keywords; + } + } + + if (request.language != null) { + _queryParams["language"] = request.language; + } + + if (request.measurements != null) { + _queryParams["measurements"] = request.measurements.toString(); + } + + if (request.model != null) { + _queryParams["model"] = request.model; + } + + if (request.multichannel != null) { + _queryParams["multichannel"] = request.multichannel.toString(); + } + + if (request.numerals != null) { + _queryParams["numerals"] = request.numerals.toString(); + } + + if (request.paragraphs != null) { + _queryParams["paragraphs"] = request.paragraphs.toString(); + } + + if (request.profanity_filter != null) { + _queryParams["profanity_filter"] = request.profanity_filter.toString(); + } + + if (request.punctuate != null) { + _queryParams["punctuate"] = request.punctuate.toString(); + } + + if (request.redact != null) { + _queryParams["redact"] = request.redact; + } + + if (request.replace != null) { + if (Array.isArray(request.replace)) { + _queryParams["replace"] = request.replace.map((item) => item); + } else { + _queryParams["replace"] = request.replace; + } + } + + if (request.search != null) { + if (Array.isArray(request.search)) { + _queryParams["search"] = request.search.map((item) => item); + } else { + _queryParams["search"] = request.search; + } + } + + if (request.smart_format != null) { + _queryParams["smart_format"] = request.smart_format.toString(); + } + + if (request.utterances != null) { + _queryParams["utterances"] = request.utterances.toString(); + } + + if (request.utt_split != null) { + _queryParams["utt_split"] = request.utt_split.toString(); + } + + if (request.version != null) { + _queryParams["version"] = request.version; + } + + if (request.mip_opt_out != null) { + _queryParams["mip_opt_out"] = request.mip_opt_out.toString(); + } + + const _binaryUploadRequest = await core.file.toBinaryUploadRequest(uploadable); + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + _binaryUploadRequest.headers, + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + "v1/listen", + ), + method: "POST", + headers: _headers, + contentType: "application/octet-stream", + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + requestType: "bytes", + duplex: "half", + body: _binaryUploadRequest.body, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.listen.v1.MediaTranscribeResponse, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling POST /v1/listen."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/listen/resources/v1/resources/media/client/index.ts b/src/api/resources/listen/resources/v1/resources/media/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/listen/resources/v1/resources/media/client/requests/ListenV1RequestUrl.ts b/src/api/resources/listen/resources/v1/resources/media/client/requests/ListenV1RequestUrl.ts new file mode 100644 index 00000000..7fb1b612 --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/client/requests/ListenV1RequestUrl.ts @@ -0,0 +1,122 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../index.js"; + +/** + * @example + * { + * callback: "callback", + * callback_method: "POST", + * extra: "extra", + * sentiment: true, + * summarize: "v2", + * tag: "tag", + * topics: true, + * custom_topic: "custom_topic", + * custom_topic_mode: "extended", + * intents: true, + * custom_intent: "custom_intent", + * custom_intent_mode: "extended", + * detect_entities: true, + * detect_language: true, + * diarize: true, + * dictation: true, + * encoding: "linear16", + * filler_words: true, + * keywords: "keywords", + * language: "language", + * measurements: true, + * model: "nova-3", + * multichannel: true, + * numerals: true, + * paragraphs: true, + * profanity_filter: true, + * punctuate: true, + * redact: "redact", + * replace: "replace", + * search: "search", + * smart_format: true, + * utterances: true, + * utt_split: 1.1, + * version: "latest", + * mip_opt_out: true, + * url: "https://dpgr.am/spacewalk.wav" + * } + */ +export interface ListenV1RequestUrl { + /** URL to which we'll make the callback request */ + callback?: string; + /** HTTP method by which the callback request will be made */ + callback_method?: Deepgram.listen.v1.MediaTranscribeRequestCallbackMethod; + /** Arbitrary key-value pairs that are attached to the API response for usage in downstream processing */ + extra?: string | string[]; + /** Recognizes the sentiment throughout a transcript or text */ + sentiment?: boolean; + /** Summarize content. For Listen API, supports string version option. For Read API, accepts boolean only. */ + summarize?: Deepgram.listen.v1.MediaTranscribeRequestSummarize; + /** Label your requests for the purpose of identification during usage reporting */ + tag?: string | string[]; + /** Detect topics throughout a transcript or text */ + topics?: boolean; + /** Custom topics you want the model to detect within your input audio or text if present Submit up to `100`. */ + custom_topic?: string | string[]; + /** Sets how the model will interpret strings submitted to the `custom_topic` param. When `strict`, the model will only return topics submitted using the `custom_topic` param. When `extended`, the model will return its own detected topics in addition to those submitted using the `custom_topic` param */ + custom_topic_mode?: Deepgram.listen.v1.MediaTranscribeRequestCustomTopicMode; + /** Recognizes speaker intent throughout a transcript or text */ + intents?: boolean; + /** Custom intents you want the model to detect within your input audio if present */ + custom_intent?: string | string[]; + /** Sets how the model will interpret intents submitted to the `custom_intent` param. When `strict`, the model will only return intents submitted using the `custom_intent` param. When `extended`, the model will return its own detected intents in the `custom_intent` param. */ + custom_intent_mode?: Deepgram.listen.v1.MediaTranscribeRequestCustomIntentMode; + /** Identifies and extracts key entities from content in submitted audio */ + detect_entities?: boolean; + /** Identifies the dominant language spoken in submitted audio */ + detect_language?: boolean; + /** Recognize speaker changes. Each word in the transcript will be assigned a speaker number starting at 0 */ + diarize?: boolean; + /** Dictation mode for controlling formatting with dictated speech */ + dictation?: boolean; + /** Specify the expected encoding of your submitted audio */ + encoding?: Deepgram.listen.v1.MediaTranscribeRequestEncoding; + /** Filler Words can help transcribe interruptions in your audio, like "uh" and "um" */ + filler_words?: boolean; + /** Key term prompting can boost or suppress specialized terminology and brands. Only compatible with Nova-3 */ + keyterm?: string | string[]; + /** Keywords can boost or suppress specialized terminology and brands */ + keywords?: string | string[]; + /** The [BCP-47 language tag](https://tools.ietf.org/html/bcp47) that hints at the primary spoken language. Depending on the Model and API endpoint you choose only certain languages are available */ + language?: string; + /** Spoken measurements will be converted to their corresponding abbreviations */ + measurements?: boolean; + /** AI model used to process submitted audio */ + model?: Deepgram.listen.v1.MediaTranscribeRequestModel; + /** Transcribe each audio channel independently */ + multichannel?: boolean; + /** Numerals converts numbers from written format to numerical format */ + numerals?: boolean; + /** Splits audio into paragraphs to improve transcript readability */ + paragraphs?: boolean; + /** Profanity Filter looks for recognized profanity and converts it to the nearest recognized non-profane word or removes it from the transcript completely */ + profanity_filter?: boolean; + /** Add punctuation and capitalization to the transcript */ + punctuate?: boolean; + /** Redaction removes sensitive information from your transcripts */ + redact?: string; + /** Search for terms or phrases in submitted audio and replaces them */ + replace?: string | string[]; + /** Search for terms or phrases in submitted audio */ + search?: string | string[]; + /** Apply formatting to transcript output. When set to true, additional formatting will be applied to transcripts to improve readability */ + smart_format?: boolean; + /** Segments speech into meaningful semantic units */ + utterances?: boolean; + /** Seconds to wait before detecting a pause between words in submitted audio */ + utt_split?: number; + /** Version of an AI model to use */ + version?: Deepgram.listen.v1.MediaTranscribeRequestVersion; + /** Opts out requests from the Deepgram Model Improvement Program. Refer to our Docs for pricing impacts before setting this to true. https://dpgr.am/deepgram-mip */ + mip_opt_out?: boolean; + url: string; +} diff --git a/src/api/resources/listen/resources/v1/resources/media/client/requests/MediaTranscribeRequestOctetStream.ts b/src/api/resources/listen/resources/v1/resources/media/client/requests/MediaTranscribeRequestOctetStream.ts new file mode 100644 index 00000000..355cb96f --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/client/requests/MediaTranscribeRequestOctetStream.ts @@ -0,0 +1,87 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../index.js"; + +/** + * @example + * {} + * + * @example + * {} + */ +export interface MediaTranscribeRequestOctetStream { + /** URL to which we'll make the callback request */ + callback?: string; + /** HTTP method by which the callback request will be made */ + callback_method?: Deepgram.listen.v1.MediaTranscribeRequestCallbackMethod; + /** Arbitrary key-value pairs that are attached to the API response for usage in downstream processing */ + extra?: string | string[]; + /** Recognizes the sentiment throughout a transcript or text */ + sentiment?: boolean; + /** Summarize content. For Listen API, supports string version option. For Read API, accepts boolean only. */ + summarize?: Deepgram.listen.v1.MediaTranscribeRequestSummarize; + /** Label your requests for the purpose of identification during usage reporting */ + tag?: string | string[]; + /** Detect topics throughout a transcript or text */ + topics?: boolean; + /** Custom topics you want the model to detect within your input audio or text if present Submit up to `100`. */ + custom_topic?: string | string[]; + /** Sets how the model will interpret strings submitted to the `custom_topic` param. When `strict`, the model will only return topics submitted using the `custom_topic` param. When `extended`, the model will return its own detected topics in addition to those submitted using the `custom_topic` param */ + custom_topic_mode?: Deepgram.listen.v1.MediaTranscribeRequestCustomTopicMode; + /** Recognizes speaker intent throughout a transcript or text */ + intents?: boolean; + /** Custom intents you want the model to detect within your input audio if present */ + custom_intent?: string | string[]; + /** Sets how the model will interpret intents submitted to the `custom_intent` param. When `strict`, the model will only return intents submitted using the `custom_intent` param. When `extended`, the model will return its own detected intents in the `custom_intent` param. */ + custom_intent_mode?: Deepgram.listen.v1.MediaTranscribeRequestCustomIntentMode; + /** Identifies and extracts key entities from content in submitted audio */ + detect_entities?: boolean; + /** Identifies the dominant language spoken in submitted audio */ + detect_language?: boolean; + /** Recognize speaker changes. Each word in the transcript will be assigned a speaker number starting at 0 */ + diarize?: boolean; + /** Dictation mode for controlling formatting with dictated speech */ + dictation?: boolean; + /** Specify the expected encoding of your submitted audio */ + encoding?: Deepgram.listen.v1.MediaTranscribeRequestEncoding; + /** Filler Words can help transcribe interruptions in your audio, like "uh" and "um" */ + filler_words?: boolean; + /** Key term prompting can boost or suppress specialized terminology and brands. Only compatible with Nova-3 */ + keyterm?: string | string[]; + /** Keywords can boost or suppress specialized terminology and brands */ + keywords?: string | string[]; + /** The [BCP-47 language tag](https://tools.ietf.org/html/bcp47) that hints at the primary spoken language. Depending on the Model and API endpoint you choose only certain languages are available */ + language?: string; + /** Spoken measurements will be converted to their corresponding abbreviations */ + measurements?: boolean; + /** AI model used to process submitted audio */ + model?: Deepgram.listen.v1.MediaTranscribeRequestModel; + /** Transcribe each audio channel independently */ + multichannel?: boolean; + /** Numerals converts numbers from written format to numerical format */ + numerals?: boolean; + /** Splits audio into paragraphs to improve transcript readability */ + paragraphs?: boolean; + /** Profanity Filter looks for recognized profanity and converts it to the nearest recognized non-profane word or removes it from the transcript completely */ + profanity_filter?: boolean; + /** Add punctuation and capitalization to the transcript */ + punctuate?: boolean; + /** Redaction removes sensitive information from your transcripts */ + redact?: string; + /** Search for terms or phrases in submitted audio and replaces them */ + replace?: string | string[]; + /** Search for terms or phrases in submitted audio */ + search?: string | string[]; + /** Apply formatting to transcript output. When set to true, additional formatting will be applied to transcripts to improve readability */ + smart_format?: boolean; + /** Segments speech into meaningful semantic units */ + utterances?: boolean; + /** Seconds to wait before detecting a pause between words in submitted audio */ + utt_split?: number; + /** Version of an AI model to use */ + version?: Deepgram.listen.v1.MediaTranscribeRequestVersion; + /** Opts out requests from the Deepgram Model Improvement Program. Refer to our Docs for pricing impacts before setting this to true. https://dpgr.am/deepgram-mip */ + mip_opt_out?: boolean; +} diff --git a/src/api/resources/listen/resources/v1/resources/media/client/requests/index.ts b/src/api/resources/listen/resources/v1/resources/media/client/requests/index.ts new file mode 100644 index 00000000..d380d08c --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/client/requests/index.ts @@ -0,0 +1,2 @@ +export { type ListenV1RequestUrl } from "./ListenV1RequestUrl.js"; +export { type MediaTranscribeRequestOctetStream } from "./MediaTranscribeRequestOctetStream.js"; diff --git a/src/api/resources/listen/resources/v1/resources/media/index.ts b/src/api/resources/listen/resources/v1/resources/media/index.ts new file mode 100644 index 00000000..f095e147 --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/index.ts @@ -0,0 +1,2 @@ +export * from "./types/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestCallbackMethod.ts b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestCallbackMethod.ts new file mode 100644 index 00000000..59c00b90 --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestCallbackMethod.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MediaTranscribeRequestCallbackMethod = "POST" | "PUT"; +export const MediaTranscribeRequestCallbackMethod = { + Post: "POST", + Put: "PUT", +} as const; diff --git a/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestCustomIntentMode.ts b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestCustomIntentMode.ts new file mode 100644 index 00000000..6204434b --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestCustomIntentMode.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MediaTranscribeRequestCustomIntentMode = "extended" | "strict"; +export const MediaTranscribeRequestCustomIntentMode = { + Extended: "extended", + Strict: "strict", +} as const; diff --git a/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestCustomTopicMode.ts b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestCustomTopicMode.ts new file mode 100644 index 00000000..bad5f1db --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestCustomTopicMode.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MediaTranscribeRequestCustomTopicMode = "extended" | "strict"; +export const MediaTranscribeRequestCustomTopicMode = { + Extended: "extended", + Strict: "strict", +} as const; diff --git a/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestEncoding.ts b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestEncoding.ts new file mode 100644 index 00000000..85110e99 --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestEncoding.ts @@ -0,0 +1,23 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MediaTranscribeRequestEncoding = + | "linear16" + | "flac" + | "mulaw" + | "amr-nb" + | "amr-wb" + | "opus" + | "speex" + | "g729"; +export const MediaTranscribeRequestEncoding = { + Linear16: "linear16", + Flac: "flac", + Mulaw: "mulaw", + AmrNb: "amr-nb", + AmrWb: "amr-wb", + Opus: "opus", + Speex: "speex", + G729: "g729", +} as const; diff --git a/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestModel.ts b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestModel.ts new file mode 100644 index 00000000..f334cb6f --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestModel.ts @@ -0,0 +1,65 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MediaTranscribeRequestModel = + | "nova-3" + | "nova-3-general" + | "nova-3-medical" + | "nova-2" + | "nova-2-general" + | "nova-2-meeting" + | "nova-2-finance" + | "nova-2-conversationalai" + | "nova-2-voicemail" + | "nova-2-video" + | "nova-2-medical" + | "nova-2-drivethru" + | "nova-2-automotive" + | "nova" + | "nova-general" + | "nova-phonecall" + | "nova-medical" + | "enhanced" + | "enhanced-general" + | "enhanced-meeting" + | "enhanced-phonecall" + | "enhanced-finance" + | "base" + | "meeting" + | "phonecall" + | "finance" + | "conversationalai" + | "voicemail" + | "video"; +export const MediaTranscribeRequestModel = { + Nova3: "nova-3", + Nova3General: "nova-3-general", + Nova3Medical: "nova-3-medical", + Nova2: "nova-2", + Nova2General: "nova-2-general", + Nova2Meeting: "nova-2-meeting", + Nova2Finance: "nova-2-finance", + Nova2Conversationalai: "nova-2-conversationalai", + Nova2Voicemail: "nova-2-voicemail", + Nova2Video: "nova-2-video", + Nova2Medical: "nova-2-medical", + Nova2Drivethru: "nova-2-drivethru", + Nova2Automotive: "nova-2-automotive", + Nova: "nova", + NovaGeneral: "nova-general", + NovaPhonecall: "nova-phonecall", + NovaMedical: "nova-medical", + Enhanced: "enhanced", + EnhancedGeneral: "enhanced-general", + EnhancedMeeting: "enhanced-meeting", + EnhancedPhonecall: "enhanced-phonecall", + EnhancedFinance: "enhanced-finance", + Base: "base", + Meeting: "meeting", + Phonecall: "phonecall", + Finance: "finance", + Conversationalai: "conversationalai", + Voicemail: "voicemail", + Video: "video", +} as const; diff --git a/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestSummarize.ts b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestSummarize.ts new file mode 100644 index 00000000..828c3c27 --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestSummarize.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MediaTranscribeRequestSummarize = "v2" | "v1"; +export const MediaTranscribeRequestSummarize = { + V2: "v2", + V1: "v1", +} as const; diff --git a/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestVersion.ts b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestVersion.ts new file mode 100644 index 00000000..f47a726b --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeRequestVersion.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type MediaTranscribeRequestVersion = "latest"; +export const MediaTranscribeRequestVersion = { + Latest: "latest", +} as const; diff --git a/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeResponse.ts b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeResponse.ts new file mode 100644 index 00000000..aea3dac2 --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/types/MediaTranscribeResponse.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../index.js"; + +export type MediaTranscribeResponse = Deepgram.ListenV1Response | Deepgram.ListenV1AcceptedResponse; diff --git a/src/api/resources/listen/resources/v1/resources/media/types/index.ts b/src/api/resources/listen/resources/v1/resources/media/types/index.ts new file mode 100644 index 00000000..6c7fc900 --- /dev/null +++ b/src/api/resources/listen/resources/v1/resources/media/types/index.ts @@ -0,0 +1,8 @@ +export * from "./MediaTranscribeRequestCallbackMethod.js"; +export * from "./MediaTranscribeRequestSummarize.js"; +export * from "./MediaTranscribeRequestCustomTopicMode.js"; +export * from "./MediaTranscribeRequestCustomIntentMode.js"; +export * from "./MediaTranscribeRequestEncoding.js"; +export * from "./MediaTranscribeRequestModel.js"; +export * from "./MediaTranscribeRequestVersion.js"; +export * from "./MediaTranscribeResponse.js"; diff --git a/src/api/resources/manage/client/Client.ts b/src/api/resources/manage/client/Client.ts new file mode 100644 index 00000000..36ac4582 --- /dev/null +++ b/src/api/resources/manage/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments.js"; +import * as core from "../../../../core/index.js"; +import { V1 } from "../resources/v1/client/Client.js"; + +export declare namespace Manage { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class Manage { + protected readonly _options: Manage.Options; + protected _v1: V1 | undefined; + + constructor(_options: Manage.Options = {}) { + this._options = _options; + } + + public get v1(): V1 { + return (this._v1 ??= new V1(this._options)); + } +} diff --git a/src/api/resources/manage/client/index.ts b/src/api/resources/manage/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/manage/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/manage/index.ts b/src/api/resources/manage/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/manage/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/index.ts b/src/api/resources/manage/resources/index.ts new file mode 100644 index 00000000..c6b56d24 --- /dev/null +++ b/src/api/resources/manage/resources/index.ts @@ -0,0 +1 @@ +export * as v1 from "./v1/index.js"; diff --git a/src/api/resources/manage/resources/v1/client/Client.ts b/src/api/resources/manage/resources/v1/client/Client.ts new file mode 100644 index 00000000..6f213221 --- /dev/null +++ b/src/api/resources/manage/resources/v1/client/Client.ts @@ -0,0 +1,38 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../environments.js"; +import * as core from "../../../../../../core/index.js"; +import { Models } from "../resources/models/client/Client.js"; +import { Projects } from "../resources/projects/client/Client.js"; + +export declare namespace V1 { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class V1 { + protected readonly _options: V1.Options; + protected _models: Models | undefined; + protected _projects: Projects | undefined; + + constructor(_options: V1.Options = {}) { + this._options = _options; + } + + public get models(): Models { + return (this._models ??= new Models(this._options)); + } + + public get projects(): Projects { + return (this._projects ??= new Projects(this._options)); + } +} diff --git a/src/api/resources/manage/resources/v1/client/index.ts b/src/api/resources/manage/resources/v1/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/manage/resources/v1/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/manage/resources/v1/index.ts b/src/api/resources/manage/resources/v1/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/manage/resources/v1/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/index.ts b/src/api/resources/manage/resources/v1/resources/index.ts new file mode 100644 index 00000000..c064c62a --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/index.ts @@ -0,0 +1,4 @@ +export * as projects from "./projects/index.js"; +export * as models from "./models/index.js"; +export * from "./models/client/requests/index.js"; +export * from "./projects/client/requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/models/client/Client.ts b/src/api/resources/manage/resources/v1/resources/models/client/Client.ts new file mode 100644 index 00000000..700ee047 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/models/client/Client.ts @@ -0,0 +1,209 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../environments.js"; +import * as core from "../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../errors/index.js"; + +export declare namespace Models { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Models { + protected readonly _options: Models.Options; + + constructor(_options: Models.Options = {}) { + this._options = _options; + } + + /** + * Returns metadata on all the latest public models. To retrieve custom models, use Get Project Models. + * + * @param {Deepgram.manage.v1.ModelsListRequest} request + * @param {Models.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.models.list({ + * include_outdated: true + * }) + */ + public list( + request: Deepgram.manage.v1.ModelsListRequest = {}, + requestOptions?: Models.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); + } + + private async __list( + request: Deepgram.manage.v1.ModelsListRequest = {}, + requestOptions?: Models.RequestOptions, + ): Promise> { + const { include_outdated: includeOutdated } = request; + const _queryParams: Record = {}; + if (includeOutdated != null) { + _queryParams["include_outdated"] = includeOutdated.toString(); + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + "v1/models", + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.ListModelsV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling GET /v1/models."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Returns metadata for a specific public model + * + * @param {string} modelId - The specific UUID of the model + * @param {Models.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.models.get("af6e9977-99f6-4d8f-b6f5-dfdf6fb6e291") + */ + public get( + modelId: string, + requestOptions?: Models.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(modelId, requestOptions)); + } + + private async __get( + modelId: string, + requestOptions?: Models.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/models/${encodeURIComponent(modelId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.GetModelV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling GET /v1/models/{model_id}."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/models/client/index.ts b/src/api/resources/manage/resources/v1/resources/models/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/models/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/models/client/requests/ModelsListRequest.ts b/src/api/resources/manage/resources/v1/resources/models/client/requests/ModelsListRequest.ts new file mode 100644 index 00000000..6e025977 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/models/client/requests/ModelsListRequest.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * { + * include_outdated: true + * } + */ +export interface ModelsListRequest { + /** returns non-latest versions of models */ + include_outdated?: boolean; +} diff --git a/src/api/resources/manage/resources/v1/resources/models/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/models/client/requests/index.ts new file mode 100644 index 00000000..b5563ac6 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/models/client/requests/index.ts @@ -0,0 +1 @@ +export { type ModelsListRequest } from "./ModelsListRequest.js"; diff --git a/src/api/resources/manage/resources/v1/resources/models/index.ts b/src/api/resources/manage/resources/v1/resources/models/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/models/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/client/Client.ts new file mode 100644 index 00000000..c5636bfd --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/client/Client.ts @@ -0,0 +1,489 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../environments.js"; +import * as core from "../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../errors/index.js"; +import { Keys } from "../resources/keys/client/Client.js"; +import { Members } from "../resources/members/client/Client.js"; +import { Models } from "../resources/models/client/Client.js"; +import { Requests } from "../resources/requests/client/Client.js"; +import { Usage } from "../resources/usage/client/Client.js"; +import { Billing } from "../resources/billing/client/Client.js"; + +export declare namespace Projects { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Projects { + protected readonly _options: Projects.Options; + protected _keys: Keys | undefined; + protected _members: Members | undefined; + protected _models: Models | undefined; + protected _requests: Requests | undefined; + protected _usage: Usage | undefined; + protected _billing: Billing | undefined; + + constructor(_options: Projects.Options = {}) { + this._options = _options; + } + + public get keys(): Keys { + return (this._keys ??= new Keys(this._options)); + } + + public get members(): Members { + return (this._members ??= new Members(this._options)); + } + + public get models(): Models { + return (this._models ??= new Models(this._options)); + } + + public get requests(): Requests { + return (this._requests ??= new Requests(this._options)); + } + + public get usage(): Usage { + return (this._usage ??= new Usage(this._options)); + } + + public get billing(): Billing { + return (this._billing ??= new Billing(this._options)); + } + + /** + * Retrieves basic information about the projects associated with the API key + * + * @param {Projects.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.list() + */ + public list(requestOptions?: Projects.RequestOptions): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(requestOptions)); + } + + private async __list( + requestOptions?: Projects.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + "v1/projects", + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.ListProjectsV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling GET /v1/projects."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retrieves information about the specified project + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.ProjectsGetRequest} request + * @param {Projects.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.get("123456-7890-1234-5678-901234", { + * limit: 1.1, + * page: 1.1 + * }) + */ + public get( + projectId: string, + request: Deepgram.manage.v1.ProjectsGetRequest = {}, + requestOptions?: Projects.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(projectId, request, requestOptions)); + } + + private async __get( + projectId: string, + request: Deepgram.manage.v1.ProjectsGetRequest = {}, + requestOptions?: Projects.RequestOptions, + ): Promise> { + const { limit, page } = request; + const _queryParams: Record = {}; + if (limit != null) { + _queryParams["limit"] = limit.toString(); + } + + if (page != null) { + _queryParams["page"] = page.toString(); + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.GetProjectV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling GET /v1/projects/{project_id}."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Deletes the specified project + * + * @param {string} projectId - The unique identifier of the project + * @param {Projects.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.delete("123456-7890-1234-5678-901234") + */ + public delete( + projectId: string, + requestOptions?: Projects.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(projectId, requestOptions)); + } + + private async __delete( + projectId: string, + requestOptions?: Projects.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}`, + ), + method: "DELETE", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.DeleteProjectV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling DELETE /v1/projects/{project_id}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Updates the name or other properties of an existing project + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.UpdateProjectV1Request} request + * @param {Projects.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.update("123456-7890-1234-5678-901234") + */ + public update( + projectId: string, + request: Deepgram.manage.v1.UpdateProjectV1Request = {}, + requestOptions?: Projects.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__update(projectId, request, requestOptions)); + } + + private async __update( + projectId: string, + request: Deepgram.manage.v1.UpdateProjectV1Request = {}, + requestOptions?: Projects.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}`, + ), + method: "PATCH", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.UpdateProjectV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling PATCH /v1/projects/{project_id}."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Removes the authenticated account from the specific project + * + * @param {string} projectId - The unique identifier of the project + * @param {Projects.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.leave("123456-7890-1234-5678-901234") + */ + public leave( + projectId: string, + requestOptions?: Projects.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__leave(projectId, requestOptions)); + } + + private async __leave( + projectId: string, + requestOptions?: Projects.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/leave`, + ), + method: "DELETE", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.LeaveProjectV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling DELETE /v1/projects/{project_id}/leave.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/client/requests/ProjectsGetRequest.ts b/src/api/resources/manage/resources/v1/resources/projects/client/requests/ProjectsGetRequest.ts new file mode 100644 index 00000000..b1543e30 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/client/requests/ProjectsGetRequest.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * { + * limit: 1.1, + * page: 1.1 + * } + */ +export interface ProjectsGetRequest { + /** Number of results to return per page. Default 10. Range [1,1000] */ + limit?: number; + /** Navigate and return the results to retrieve specific portions of information of the response */ + page?: number; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/client/requests/UpdateProjectV1Request.ts b/src/api/resources/manage/resources/v1/resources/projects/client/requests/UpdateProjectV1Request.ts new file mode 100644 index 00000000..c13fc5a2 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/client/requests/UpdateProjectV1Request.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * {} + */ +export interface UpdateProjectV1Request { + /** The name of the project */ + name?: string; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/client/requests/index.ts new file mode 100644 index 00000000..49666a8c --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/client/requests/index.ts @@ -0,0 +1,2 @@ +export { type ProjectsGetRequest } from "./ProjectsGetRequest.js"; +export { type UpdateProjectV1Request } from "./UpdateProjectV1Request.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/index.ts b/src/api/resources/manage/resources/v1/resources/projects/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/client/Client.ts new file mode 100644 index 00000000..146779c2 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/client/Client.ts @@ -0,0 +1,44 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../core/index.js"; +import { Balances } from "../resources/balances/client/Client.js"; +import { Breakdown } from "../resources/breakdown/client/Client.js"; +import { Purchases } from "../resources/purchases/client/Client.js"; + +export declare namespace Billing { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class Billing { + protected readonly _options: Billing.Options; + protected _balances: Balances | undefined; + protected _breakdown: Breakdown | undefined; + protected _purchases: Purchases | undefined; + + constructor(_options: Billing.Options = {}) { + this._options = _options; + } + + public get balances(): Balances { + return (this._balances ??= new Balances(this._options)); + } + + public get breakdown(): Breakdown { + return (this._breakdown ??= new Breakdown(this._options)); + } + + public get purchases(): Purchases { + return (this._purchases ??= new Purchases(this._options)); + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/balances/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/balances/client/Client.ts new file mode 100644 index 00000000..8be8d96b --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/balances/client/Client.ts @@ -0,0 +1,211 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../../../errors/index.js"; + +export declare namespace Balances { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Balances { + protected readonly _options: Balances.Options; + + constructor(_options: Balances.Options = {}) { + this._options = _options; + } + + /** + * Generates a list of outstanding balances for the specified project + * + * @param {string} projectId - The unique identifier of the project + * @param {Balances.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.billing.balances.list("123456-7890-1234-5678-901234") + */ + public list( + projectId: string, + requestOptions?: Balances.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, requestOptions)); + } + + private async __list( + projectId: string, + requestOptions?: Balances.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/balances`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.ListProjectBalancesV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/balances.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retrieves details about the specified balance + * + * @param {string} projectId - The unique identifier of the project + * @param {string} balanceId - The unique identifier of the balance + * @param {Balances.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.billing.balances.get("123456-7890-1234-5678-901234", "123456-7890-1234-5678-901234") + */ + public get( + projectId: string, + balanceId: string, + requestOptions?: Balances.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(projectId, balanceId, requestOptions)); + } + + private async __get( + projectId: string, + balanceId: string, + requestOptions?: Balances.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/balances/${encodeURIComponent(balanceId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.GetProjectBalanceV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/balances/{balance_id}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/balances/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/balances/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/balances/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/balances/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/balances/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/balances/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/Client.ts new file mode 100644 index 00000000..78bfde52 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/Client.ts @@ -0,0 +1,170 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../../../errors/index.js"; + +export declare namespace Breakdown { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Breakdown { + protected readonly _options: Breakdown.Options; + + constructor(_options: Breakdown.Options = {}) { + this._options = _options; + } + + /** + * Retrieves the billing summary for a specific project, with various filter options or by grouping options. + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.projects.billing.BreakdownListRequest} request + * @param {Breakdown.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.billing.breakdown.list("123456-7890-1234-5678-901234", { + * start: "start", + * end: "end", + * accessor: "12345678-1234-1234-1234-123456789012", + * deployment: "hosted", + * tag: "tag1", + * line_item: "streaming::nova-3" + * }) + */ + public list( + projectId: string, + request: Deepgram.manage.v1.projects.billing.BreakdownListRequest = {}, + requestOptions?: Breakdown.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, request, requestOptions)); + } + + private async __list( + projectId: string, + request: Deepgram.manage.v1.projects.billing.BreakdownListRequest = {}, + requestOptions?: Breakdown.RequestOptions, + ): Promise> { + const { start, end, accessor, deployment, tag, line_item: lineItem, grouping } = request; + const _queryParams: Record = {}; + if (start != null) { + _queryParams["start"] = start; + } + + if (end != null) { + _queryParams["end"] = end; + } + + if (accessor != null) { + _queryParams["accessor"] = accessor; + } + + if (deployment != null) { + _queryParams["deployment"] = deployment; + } + + if (tag != null) { + _queryParams["tag"] = tag; + } + + if (lineItem != null) { + _queryParams["line_item"] = lineItem; + } + + if (grouping != null) { + if (Array.isArray(grouping)) { + _queryParams["grouping"] = grouping.map((item) => item); + } else { + _queryParams["grouping"] = grouping; + } + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/billing/breakdown`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.BillingBreakdownV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/billing/breakdown.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/requests/BreakdownListRequest.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/requests/BreakdownListRequest.ts new file mode 100644 index 00000000..fb7eff33 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/requests/BreakdownListRequest.ts @@ -0,0 +1,35 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../../../../../index.js"; + +/** + * @example + * { + * start: "start", + * end: "end", + * accessor: "12345678-1234-1234-1234-123456789012", + * deployment: "hosted", + * tag: "tag1", + * line_item: "streaming::nova-3" + * } + */ +export interface BreakdownListRequest { + /** Start date of the requested date range. Format accepted is YYYY-MM-DD */ + start?: string; + /** End date of the requested date range. Format accepted is YYYY-MM-DD */ + end?: string; + /** Filter for requests where a specific accessor was used */ + accessor?: string; + /** Filter for requests where a specific deployment was used */ + deployment?: Deepgram.manage.v1.projects.billing.BreakdownListRequestDeployment; + /** Filter for requests where a specific tag was used */ + tag?: string; + /** Filter requests by line item (e.g. streaming::nova-3) */ + line_item?: string; + /** Group billing breakdown by one or more dimensions (accessor, deployment, line_item, tags) */ + grouping?: + | Deepgram.manage.v1.projects.billing.BreakdownListRequestGroupingItem + | Deepgram.manage.v1.projects.billing.BreakdownListRequestGroupingItem[]; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/requests/index.ts new file mode 100644 index 00000000..ca1f5f01 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/client/requests/index.ts @@ -0,0 +1 @@ +export { type BreakdownListRequest } from "./BreakdownListRequest.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/index.ts new file mode 100644 index 00000000..f095e147 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/index.ts @@ -0,0 +1,2 @@ +export * from "./types/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/types/BreakdownListRequestDeployment.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/types/BreakdownListRequestDeployment.ts new file mode 100644 index 00000000..f6b7f167 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/types/BreakdownListRequestDeployment.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Deployment type for the requests + */ +export type BreakdownListRequestDeployment = "hosted" | "beta" | "self-hosted"; +export const BreakdownListRequestDeployment = { + Hosted: "hosted", + Beta: "beta", + SelfHosted: "self-hosted", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/types/BreakdownListRequestGroupingItem.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/types/BreakdownListRequestGroupingItem.ts new file mode 100644 index 00000000..5865e65b --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/types/BreakdownListRequestGroupingItem.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type BreakdownListRequestGroupingItem = "accessor" | "deployment" | "line_item" | "tags"; +export const BreakdownListRequestGroupingItem = { + Accessor: "accessor", + Deployment: "deployment", + LineItem: "line_item", + Tags: "tags", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/types/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/types/index.ts new file mode 100644 index 00000000..da00a52b --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/breakdown/types/index.ts @@ -0,0 +1,2 @@ +export * from "./BreakdownListRequestDeployment.js"; +export * from "./BreakdownListRequestGroupingItem.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/index.ts new file mode 100644 index 00000000..2fb870d9 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/index.ts @@ -0,0 +1,6 @@ +export * as breakdown from "./breakdown/index.js"; +export * from "./breakdown/types/index.js"; +export * as balances from "./balances/index.js"; +export * as purchases from "./purchases/index.js"; +export * from "./breakdown/client/requests/index.js"; +export * from "./purchases/client/requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/Client.ts new file mode 100644 index 00000000..5d7dbae6 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/Client.ts @@ -0,0 +1,140 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../../../errors/index.js"; + +export declare namespace Purchases { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Purchases { + protected readonly _options: Purchases.Options; + + constructor(_options: Purchases.Options = {}) { + this._options = _options; + } + + /** + * Returns the original purchased amount on an order transaction + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.projects.billing.PurchasesListRequest} request + * @param {Purchases.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.billing.purchases.list("123456-7890-1234-5678-901234", { + * limit: 1.1 + * }) + */ + public list( + projectId: string, + request: Deepgram.manage.v1.projects.billing.PurchasesListRequest = {}, + requestOptions?: Purchases.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, request, requestOptions)); + } + + private async __list( + projectId: string, + request: Deepgram.manage.v1.projects.billing.PurchasesListRequest = {}, + requestOptions?: Purchases.RequestOptions, + ): Promise> { + const { limit } = request; + const _queryParams: Record = {}; + if (limit != null) { + _queryParams["limit"] = limit.toString(); + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/purchases`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.ListProjectPurchasesV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/purchases.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/requests/PurchasesListRequest.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/requests/PurchasesListRequest.ts new file mode 100644 index 00000000..fcdc3c39 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/requests/PurchasesListRequest.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * { + * limit: 1.1 + * } + */ +export interface PurchasesListRequest { + /** Number of results to return per page. Default 10. Range [1,1000] */ + limit?: number; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/requests/index.ts new file mode 100644 index 00000000..811a9f58 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/client/requests/index.ts @@ -0,0 +1 @@ +export { type PurchasesListRequest } from "./PurchasesListRequest.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/billing/resources/purchases/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/index.ts new file mode 100644 index 00000000..10cc5ca2 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/index.ts @@ -0,0 +1,13 @@ +export * as keys from "./keys/index.js"; +export * from "./keys/types/index.js"; +export * as requests from "./requests/index.js"; +export * from "./requests/types/index.js"; +export * as usage from "./usage/index.js"; +export * from "./usage/types/index.js"; +export * as billing from "./billing/index.js"; +export * as members from "./members/index.js"; +export * as models from "./models/index.js"; +export * from "./keys/client/requests/index.js"; +export * from "./models/client/requests/index.js"; +export * from "./requests/client/requests/index.js"; +export * from "./usage/client/requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/Client.ts new file mode 100644 index 00000000..da96e2c7 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/Client.ts @@ -0,0 +1,388 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../errors/index.js"; + +export declare namespace Keys { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Keys { + protected readonly _options: Keys.Options; + + constructor(_options: Keys.Options = {}) { + this._options = _options; + } + + /** + * Retrieves all API keys associated with the specified project + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.projects.KeysListRequest} request + * @param {Keys.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.keys.list("123456-7890-1234-5678-901234", { + * status: "active" + * }) + */ + public list( + projectId: string, + request: Deepgram.manage.v1.projects.KeysListRequest = {}, + requestOptions?: Keys.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, request, requestOptions)); + } + + private async __list( + projectId: string, + request: Deepgram.manage.v1.projects.KeysListRequest = {}, + requestOptions?: Keys.RequestOptions, + ): Promise> { + const { status } = request; + const _queryParams: Record = {}; + if (status != null) { + _queryParams["status"] = status; + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/keys`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.ListProjectKeysV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/keys.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Creates a new API key with specified settings for the project + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.CreateKeyV1RequestOne} request + * @param {Keys.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.keys.create("project_id", { + * "key": "value" + * }) + */ + public create( + projectId: string, + request?: Deepgram.CreateKeyV1RequestOne, + requestOptions?: Keys.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__create(projectId, request, requestOptions)); + } + + private async __create( + projectId: string, + request?: Deepgram.CreateKeyV1RequestOne, + requestOptions?: Keys.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/keys`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.CreateKeyV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling POST /v1/projects/{project_id}/keys.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retrieves information about a specified API key + * + * @param {string} projectId - The unique identifier of the project + * @param {string} keyId - The unique identifier of the API key + * @param {Keys.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.keys.get("123456-7890-1234-5678-901234", "123456789012345678901234") + */ + public get( + projectId: string, + keyId: string, + requestOptions?: Keys.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(projectId, keyId, requestOptions)); + } + + private async __get( + projectId: string, + keyId: string, + requestOptions?: Keys.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/keys/${encodeURIComponent(keyId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.GetProjectKeyV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/keys/{key_id}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Deletes an API key for a specific project + * + * @param {string} projectId - The unique identifier of the project + * @param {string} keyId - The unique identifier of the API key + * @param {Keys.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.keys.delete("123456-7890-1234-5678-901234", "123456789012345678901234") + */ + public delete( + projectId: string, + keyId: string, + requestOptions?: Keys.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(projectId, keyId, requestOptions)); + } + + private async __delete( + projectId: string, + keyId: string, + requestOptions?: Keys.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/keys/${encodeURIComponent(keyId)}`, + ), + method: "DELETE", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.DeleteProjectKeyV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling DELETE /v1/projects/{project_id}/keys/{key_id}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/requests/KeysListRequest.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/requests/KeysListRequest.ts new file mode 100644 index 00000000..2048d74b --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/requests/KeysListRequest.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../../../index.js"; + +/** + * @example + * { + * status: "active" + * } + */ +export interface KeysListRequest { + /** Only return keys with a specific status */ + status?: Deepgram.manage.v1.projects.KeysListRequestStatus; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/requests/index.ts new file mode 100644 index 00000000..8f20ca7a --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/client/requests/index.ts @@ -0,0 +1 @@ +export { type KeysListRequest } from "./KeysListRequest.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/keys/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/index.ts new file mode 100644 index 00000000..f095e147 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/index.ts @@ -0,0 +1,2 @@ +export * from "./types/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/keys/types/KeysListRequestStatus.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/types/KeysListRequestStatus.ts new file mode 100644 index 00000000..f0e73fd5 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/types/KeysListRequestStatus.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type KeysListRequestStatus = "active" | "expired"; +export const KeysListRequestStatus = { + Active: "active", + Expired: "expired", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/keys/types/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/types/index.ts new file mode 100644 index 00000000..2d99304b --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/keys/types/index.ts @@ -0,0 +1 @@ +export * from "./KeysListRequestStatus.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/client/Client.ts new file mode 100644 index 00000000..154cc58a --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/client/Client.ts @@ -0,0 +1,226 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../errors/index.js"; +import { Invites } from "../resources/invites/client/Client.js"; +import { Scopes } from "../resources/scopes/client/Client.js"; + +export declare namespace Members { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Members { + protected readonly _options: Members.Options; + protected _invites: Invites | undefined; + protected _scopes: Scopes | undefined; + + constructor(_options: Members.Options = {}) { + this._options = _options; + } + + public get invites(): Invites { + return (this._invites ??= new Invites(this._options)); + } + + public get scopes(): Scopes { + return (this._scopes ??= new Scopes(this._options)); + } + + /** + * Retrieves a list of members for a given project + * + * @param {string} projectId - The unique identifier of the project + * @param {Members.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.members.list("123456-7890-1234-5678-901234") + */ + public list( + projectId: string, + requestOptions?: Members.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, requestOptions)); + } + + private async __list( + projectId: string, + requestOptions?: Members.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/members`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.ListProjectMembersV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/members.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Removes a member from the project using their unique member ID + * + * @param {string} projectId - The unique identifier of the project + * @param {string} memberId - The unique identifier of the Member + * @param {Members.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.members.delete("123456-7890-1234-5678-901234", "123456789012345678901234") + */ + public delete( + projectId: string, + memberId: string, + requestOptions?: Members.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(projectId, memberId, requestOptions)); + } + + private async __delete( + projectId: string, + memberId: string, + requestOptions?: Members.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/members/${encodeURIComponent(memberId)}`, + ), + method: "DELETE", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.DeleteProjectMemberV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling DELETE /v1/projects/{project_id}/members/{member_id}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/index.ts new file mode 100644 index 00000000..9eb1192d --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./resources/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/index.ts new file mode 100644 index 00000000..f1c1bf51 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/index.ts @@ -0,0 +1,4 @@ +export * as invites from "./invites/index.js"; +export * as scopes from "./scopes/index.js"; +export * from "./invites/client/requests/index.js"; +export * from "./scopes/client/requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/Client.ts new file mode 100644 index 00000000..dd3ae2bd --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/Client.ts @@ -0,0 +1,305 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../../../errors/index.js"; + +export declare namespace Invites { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Invites { + protected readonly _options: Invites.Options; + + constructor(_options: Invites.Options = {}) { + this._options = _options; + } + + /** + * Generates a list of invites for a specific project + * + * @param {string} projectId - The unique identifier of the project + * @param {Invites.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.members.invites.list("123456-7890-1234-5678-901234") + */ + public list( + projectId: string, + requestOptions?: Invites.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, requestOptions)); + } + + private async __list( + projectId: string, + requestOptions?: Invites.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/invites`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.ListProjectInvitesV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/invites.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Generates an invite for a specific project + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.projects.members.CreateProjectInviteV1Request} request + * @param {Invites.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.members.invites.create("123456-7890-1234-5678-901234", { + * email: "email", + * scope: "scope" + * }) + */ + public create( + projectId: string, + request: Deepgram.manage.v1.projects.members.CreateProjectInviteV1Request, + requestOptions?: Invites.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__create(projectId, request, requestOptions)); + } + + private async __create( + projectId: string, + request: Deepgram.manage.v1.projects.members.CreateProjectInviteV1Request, + requestOptions?: Invites.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/invites`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.CreateProjectInviteV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling POST /v1/projects/{project_id}/invites.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Deletes an invite for a specific project + * + * @param {string} projectId - The unique identifier of the project + * @param {string} email - The email address of the member + * @param {Invites.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.members.invites.delete("123456-7890-1234-5678-901234", "john.doe@example.com") + */ + public delete( + projectId: string, + email: string, + requestOptions?: Invites.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(projectId, email, requestOptions)); + } + + private async __delete( + projectId: string, + email: string, + requestOptions?: Invites.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/invites/${encodeURIComponent(email)}`, + ), + method: "DELETE", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.DeleteProjectInviteV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling DELETE /v1/projects/{project_id}/invites/{email}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/requests/CreateProjectInviteV1Request.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/requests/CreateProjectInviteV1Request.ts new file mode 100644 index 00000000..d988d504 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/requests/CreateProjectInviteV1Request.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * { + * email: "email", + * scope: "scope" + * } + */ +export interface CreateProjectInviteV1Request { + /** The email address of the invitee */ + email: string; + /** The scope of the invitee */ + scope: string; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/requests/index.ts new file mode 100644 index 00000000..53aa4032 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/client/requests/index.ts @@ -0,0 +1 @@ +export { type CreateProjectInviteV1Request } from "./CreateProjectInviteV1Request.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/invites/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/Client.ts new file mode 100644 index 00000000..8528b690 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/Client.ts @@ -0,0 +1,225 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../../../errors/index.js"; + +export declare namespace Scopes { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Scopes { + protected readonly _options: Scopes.Options; + + constructor(_options: Scopes.Options = {}) { + this._options = _options; + } + + /** + * Retrieves a list of scopes for a specific member + * + * @param {string} projectId - The unique identifier of the project + * @param {string} memberId - The unique identifier of the Member + * @param {Scopes.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.members.scopes.list("123456-7890-1234-5678-901234", "123456789012345678901234") + */ + public list( + projectId: string, + memberId: string, + requestOptions?: Scopes.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, memberId, requestOptions)); + } + + private async __list( + projectId: string, + memberId: string, + requestOptions?: Scopes.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/members/${encodeURIComponent(memberId)}/scopes`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.ListProjectMemberScopesV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/members/{member_id}/scopes.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Updates the scopes for a specific member + * + * @param {string} projectId - The unique identifier of the project + * @param {string} memberId - The unique identifier of the Member + * @param {Deepgram.manage.v1.projects.members.UpdateProjectMemberScopesV1Request} request + * @param {Scopes.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.members.scopes.update("123456-7890-1234-5678-901234", "123456789012345678901234", { + * scope: "admin" + * }) + */ + public update( + projectId: string, + memberId: string, + request: Deepgram.manage.v1.projects.members.UpdateProjectMemberScopesV1Request, + requestOptions?: Scopes.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__update(projectId, memberId, request, requestOptions)); + } + + private async __update( + projectId: string, + memberId: string, + request: Deepgram.manage.v1.projects.members.UpdateProjectMemberScopesV1Request, + requestOptions?: Scopes.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/members/${encodeURIComponent(memberId)}/scopes`, + ), + method: "PUT", + headers: _headers, + contentType: "application/json", + queryParameters: requestOptions?.queryParams, + requestType: "json", + body: request, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.UpdateProjectMemberScopesV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling PUT /v1/projects/{project_id}/members/{member_id}/scopes.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/requests/UpdateProjectMemberScopesV1Request.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/requests/UpdateProjectMemberScopesV1Request.ts new file mode 100644 index 00000000..a52e39c2 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/requests/UpdateProjectMemberScopesV1Request.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * { + * scope: "admin" + * } + */ +export interface UpdateProjectMemberScopesV1Request { + /** A scope to update */ + scope: string; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/requests/index.ts new file mode 100644 index 00000000..94ff0197 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/client/requests/index.ts @@ -0,0 +1 @@ +export { type UpdateProjectMemberScopesV1Request } from "./UpdateProjectMemberScopesV1Request.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/members/resources/scopes/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/Client.ts new file mode 100644 index 00000000..b2e57c4a --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/Client.ts @@ -0,0 +1,219 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../errors/index.js"; + +export declare namespace Models { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Models { + protected readonly _options: Models.Options; + + constructor(_options: Models.Options = {}) { + this._options = _options; + } + + /** + * Returns metadata on all the latest models that a specific project has access to, including non-public models + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.projects.ModelsListRequest} request + * @param {Models.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.models.list("123456-7890-1234-5678-901234", { + * include_outdated: true + * }) + */ + public list( + projectId: string, + request: Deepgram.manage.v1.projects.ModelsListRequest = {}, + requestOptions?: Models.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, request, requestOptions)); + } + + private async __list( + projectId: string, + request: Deepgram.manage.v1.projects.ModelsListRequest = {}, + requestOptions?: Models.RequestOptions, + ): Promise> { + const { include_outdated: includeOutdated } = request; + const _queryParams: Record = {}; + if (includeOutdated != null) { + _queryParams["include_outdated"] = includeOutdated.toString(); + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/models`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.ListModelsV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/models.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Returns metadata for a specific model + * + * @param {string} projectId - The unique identifier of the project + * @param {string} modelId - The specific UUID of the model + * @param {Models.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.models.get("123456-7890-1234-5678-901234", "af6e9977-99f6-4d8f-b6f5-dfdf6fb6e291") + */ + public get( + projectId: string, + modelId: string, + requestOptions?: Models.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(projectId, modelId, requestOptions)); + } + + private async __get( + projectId: string, + modelId: string, + requestOptions?: Models.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/models/${encodeURIComponent(modelId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.GetModelV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/models/{model_id}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/requests/ModelsListRequest.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/requests/ModelsListRequest.ts new file mode 100644 index 00000000..6e025977 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/requests/ModelsListRequest.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * { + * include_outdated: true + * } + */ +export interface ModelsListRequest { + /** returns non-latest versions of models */ + include_outdated?: boolean; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/requests/index.ts new file mode 100644 index 00000000..b5563ac6 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/models/client/requests/index.ts @@ -0,0 +1 @@ +export { type ModelsListRequest } from "./ModelsListRequest.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/models/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/models/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/models/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/Client.ts new file mode 100644 index 00000000..480858ef --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/Client.ts @@ -0,0 +1,278 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../errors/index.js"; + +export declare namespace Requests { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Requests { + protected readonly _options: Requests.Options; + + constructor(_options: Requests.Options = {}) { + this._options = _options; + } + + /** + * Generates a list of requests for a specific project + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.projects.RequestsListRequest} request + * @param {Requests.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.requests.list("123456-7890-1234-5678-901234", { + * start: "2024-01-15T09:30:00Z", + * end: "2024-01-15T09:30:00Z", + * limit: 1.1, + * page: 1.1, + * accessor: "12345678-1234-1234-1234-123456789012", + * request_id: "12345678-1234-1234-1234-123456789012", + * deployment: "hosted", + * endpoint: "listen", + * method: "sync", + * status: "succeeded" + * }) + */ + public list( + projectId: string, + request: Deepgram.manage.v1.projects.RequestsListRequest = {}, + requestOptions?: Requests.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, request, requestOptions)); + } + + private async __list( + projectId: string, + request: Deepgram.manage.v1.projects.RequestsListRequest = {}, + requestOptions?: Requests.RequestOptions, + ): Promise> { + const { + start, + end, + limit, + page, + accessor, + request_id: requestId, + deployment, + endpoint, + method, + status, + } = request; + const _queryParams: Record = {}; + if (start != null) { + _queryParams["start"] = start; + } + + if (end != null) { + _queryParams["end"] = end; + } + + if (limit != null) { + _queryParams["limit"] = limit.toString(); + } + + if (page != null) { + _queryParams["page"] = page.toString(); + } + + if (accessor != null) { + _queryParams["accessor"] = accessor; + } + + if (requestId != null) { + _queryParams["request_id"] = requestId; + } + + if (deployment != null) { + _queryParams["deployment"] = deployment; + } + + if (endpoint != null) { + _queryParams["endpoint"] = endpoint; + } + + if (method != null) { + _queryParams["method"] = method; + } + + if (status != null) { + _queryParams["status"] = status; + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/requests`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.ListProjectRequestsV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/requests.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Retrieves a specific request for a specific project + * + * @param {string} projectId - The unique identifier of the project + * @param {string} requestId - The unique identifier of the request + * @param {Requests.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.requests.get("123456-7890-1234-5678-901234", "123456-7890-1234-5678-901234") + */ + public get( + projectId: string, + requestId: string, + requestOptions?: Requests.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(projectId, requestId, requestOptions)); + } + + private async __get( + projectId: string, + requestId: string, + requestOptions?: Requests.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/requests/${encodeURIComponent(requestId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.GetProjectRequestV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/requests/{request_id}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/requests/RequestsListRequest.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/requests/RequestsListRequest.ts new file mode 100644 index 00000000..88b06480 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/requests/RequestsListRequest.ts @@ -0,0 +1,43 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../../../index.js"; + +/** + * @example + * { + * start: "2024-01-15T09:30:00Z", + * end: "2024-01-15T09:30:00Z", + * limit: 1.1, + * page: 1.1, + * accessor: "12345678-1234-1234-1234-123456789012", + * request_id: "12345678-1234-1234-1234-123456789012", + * deployment: "hosted", + * endpoint: "listen", + * method: "sync", + * status: "succeeded" + * } + */ +export interface RequestsListRequest { + /** Start date of the requested date range. Formats accepted are YYYY-MM-DD, YYYY-MM-DDTHH:MM:SS, or YYYY-MM-DDTHH:MM:SS+HH:MM */ + start?: string; + /** End date of the requested date range. Formats accepted are YYYY-MM-DD, YYYY-MM-DDTHH:MM:SS, or YYYY-MM-DDTHH:MM:SS+HH:MM */ + end?: string; + /** Number of results to return per page. Default 10. Range [1,1000] */ + limit?: number; + /** Navigate and return the results to retrieve specific portions of information of the response */ + page?: number; + /** Filter for requests where a specific accessor was used */ + accessor?: string; + /** Filter for a specific request id */ + request_id?: string; + /** Filter for requests where a specific deployment was used */ + deployment?: Deepgram.manage.v1.projects.RequestsListRequestDeployment; + /** Filter for requests where a specific endpoint was used */ + endpoint?: Deepgram.manage.v1.projects.RequestsListRequestEndpoint; + /** Filter for requests where a specific method was used */ + method?: Deepgram.manage.v1.projects.RequestsListRequestMethod; + /** Filter for requests that succeeded (status code < 300) or failed (status code >=400) */ + status?: Deepgram.manage.v1.projects.RequestsListRequestStatus; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/requests/index.ts new file mode 100644 index 00000000..ee401054 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/client/requests/index.ts @@ -0,0 +1 @@ +export { type RequestsListRequest } from "./RequestsListRequest.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/index.ts new file mode 100644 index 00000000..f095e147 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/index.ts @@ -0,0 +1,2 @@ +export * from "./types/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestDeployment.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestDeployment.ts new file mode 100644 index 00000000..2f7770c8 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestDeployment.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Deployment type for the requests + */ +export type RequestsListRequestDeployment = "hosted" | "beta" | "self-hosted"; +export const RequestsListRequestDeployment = { + Hosted: "hosted", + Beta: "beta", + SelfHosted: "self-hosted", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestEndpoint.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestEndpoint.ts new file mode 100644 index 00000000..1fad6dc7 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestEndpoint.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type RequestsListRequestEndpoint = "listen" | "read" | "speak" | "agent"; +export const RequestsListRequestEndpoint = { + Listen: "listen", + Read: "read", + Speak: "speak", + Agent: "agent", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestMethod.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestMethod.ts new file mode 100644 index 00000000..01b5e37d --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestMethod.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Method type for the request + */ +export type RequestsListRequestMethod = "sync" | "async" | "streaming"; +export const RequestsListRequestMethod = { + Sync: "sync", + Async: "async", + Streaming: "streaming", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestStatus.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestStatus.ts new file mode 100644 index 00000000..87a93cab --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/RequestsListRequestStatus.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type RequestsListRequestStatus = "succeeded" | "failed"; +export const RequestsListRequestStatus = { + Succeeded: "succeeded", + Failed: "failed", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/index.ts new file mode 100644 index 00000000..fec800d1 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/requests/types/index.ts @@ -0,0 +1,4 @@ +export * from "./RequestsListRequestDeployment.js"; +export * from "./RequestsListRequestEndpoint.js"; +export * from "./RequestsListRequestMethod.js"; +export * from "./RequestsListRequestStatus.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/Client.ts new file mode 100644 index 00000000..8df2dc18 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/Client.ts @@ -0,0 +1,409 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../errors/index.js"; +import { Breakdown } from "../resources/breakdown/client/Client.js"; +import { Fields } from "../resources/fields/client/Client.js"; + +export declare namespace Usage { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Usage { + protected readonly _options: Usage.Options; + protected _breakdown: Breakdown | undefined; + protected _fields: Fields | undefined; + + constructor(_options: Usage.Options = {}) { + this._options = _options; + } + + public get breakdown(): Breakdown { + return (this._breakdown ??= new Breakdown(this._options)); + } + + public get fields(): Fields { + return (this._fields ??= new Fields(this._options)); + } + + /** + * Retrieves the usage for a specific project. Use Get Project Usage Breakdown for a more comprehensive usage summary. + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.projects.UsageGetRequest} request + * @param {Usage.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.usage.get("123456-7890-1234-5678-901234", { + * start: "start", + * end: "end", + * accessor: "12345678-1234-1234-1234-123456789012", + * alternatives: true, + * callback_method: true, + * callback: true, + * channels: true, + * custom_intent_mode: true, + * custom_intent: true, + * custom_topic_mode: true, + * custom_topic: true, + * deployment: "hosted", + * detect_entities: true, + * detect_language: true, + * diarize: true, + * dictation: true, + * encoding: true, + * endpoint: "listen", + * extra: true, + * filler_words: true, + * intents: true, + * keyterm: true, + * keywords: true, + * language: true, + * measurements: true, + * method: "sync", + * model: "6f548761-c9c0-429a-9315-11a1d28499c8", + * multichannel: true, + * numerals: true, + * paragraphs: true, + * profanity_filter: true, + * punctuate: true, + * redact: true, + * replace: true, + * sample_rate: true, + * search: true, + * sentiment: true, + * smart_format: true, + * summarize: true, + * tag: "tag1", + * topics: true, + * utt_split: true, + * utterances: true, + * version: true + * }) + */ + public get( + projectId: string, + request: Deepgram.manage.v1.projects.UsageGetRequest = {}, + requestOptions?: Usage.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(projectId, request, requestOptions)); + } + + private async __get( + projectId: string, + request: Deepgram.manage.v1.projects.UsageGetRequest = {}, + requestOptions?: Usage.RequestOptions, + ): Promise> { + const { + start, + end, + accessor, + alternatives, + callback_method: callbackMethod, + callback, + channels, + custom_intent_mode: customIntentMode, + custom_intent: customIntent, + custom_topic_mode: customTopicMode, + custom_topic: customTopic, + deployment, + detect_entities: detectEntities, + detect_language: detectLanguage, + diarize, + dictation, + encoding, + endpoint, + extra, + filler_words: fillerWords, + intents, + keyterm, + keywords, + language, + measurements, + method, + model, + multichannel, + numerals, + paragraphs, + profanity_filter: profanityFilter, + punctuate, + redact, + replace, + sample_rate: sampleRate, + search, + sentiment, + smart_format: smartFormat, + summarize, + tag, + topics, + utt_split: uttSplit, + utterances, + version, + } = request; + const _queryParams: Record = {}; + if (start != null) { + _queryParams["start"] = start; + } + + if (end != null) { + _queryParams["end"] = end; + } + + if (accessor != null) { + _queryParams["accessor"] = accessor; + } + + if (alternatives != null) { + _queryParams["alternatives"] = alternatives.toString(); + } + + if (callbackMethod != null) { + _queryParams["callback_method"] = callbackMethod.toString(); + } + + if (callback != null) { + _queryParams["callback"] = callback.toString(); + } + + if (channels != null) { + _queryParams["channels"] = channels.toString(); + } + + if (customIntentMode != null) { + _queryParams["custom_intent_mode"] = customIntentMode.toString(); + } + + if (customIntent != null) { + _queryParams["custom_intent"] = customIntent.toString(); + } + + if (customTopicMode != null) { + _queryParams["custom_topic_mode"] = customTopicMode.toString(); + } + + if (customTopic != null) { + _queryParams["custom_topic"] = customTopic.toString(); + } + + if (deployment != null) { + _queryParams["deployment"] = deployment; + } + + if (detectEntities != null) { + _queryParams["detect_entities"] = detectEntities.toString(); + } + + if (detectLanguage != null) { + _queryParams["detect_language"] = detectLanguage.toString(); + } + + if (diarize != null) { + _queryParams["diarize"] = diarize.toString(); + } + + if (dictation != null) { + _queryParams["dictation"] = dictation.toString(); + } + + if (encoding != null) { + _queryParams["encoding"] = encoding.toString(); + } + + if (endpoint != null) { + _queryParams["endpoint"] = endpoint; + } + + if (extra != null) { + _queryParams["extra"] = extra.toString(); + } + + if (fillerWords != null) { + _queryParams["filler_words"] = fillerWords.toString(); + } + + if (intents != null) { + _queryParams["intents"] = intents.toString(); + } + + if (keyterm != null) { + _queryParams["keyterm"] = keyterm.toString(); + } + + if (keywords != null) { + _queryParams["keywords"] = keywords.toString(); + } + + if (language != null) { + _queryParams["language"] = language.toString(); + } + + if (measurements != null) { + _queryParams["measurements"] = measurements.toString(); + } + + if (method != null) { + _queryParams["method"] = method; + } + + if (model != null) { + _queryParams["model"] = model; + } + + if (multichannel != null) { + _queryParams["multichannel"] = multichannel.toString(); + } + + if (numerals != null) { + _queryParams["numerals"] = numerals.toString(); + } + + if (paragraphs != null) { + _queryParams["paragraphs"] = paragraphs.toString(); + } + + if (profanityFilter != null) { + _queryParams["profanity_filter"] = profanityFilter.toString(); + } + + if (punctuate != null) { + _queryParams["punctuate"] = punctuate.toString(); + } + + if (redact != null) { + _queryParams["redact"] = redact.toString(); + } + + if (replace != null) { + _queryParams["replace"] = replace.toString(); + } + + if (sampleRate != null) { + _queryParams["sample_rate"] = sampleRate.toString(); + } + + if (search != null) { + _queryParams["search"] = search.toString(); + } + + if (sentiment != null) { + _queryParams["sentiment"] = sentiment.toString(); + } + + if (smartFormat != null) { + _queryParams["smart_format"] = smartFormat.toString(); + } + + if (summarize != null) { + _queryParams["summarize"] = summarize.toString(); + } + + if (tag != null) { + _queryParams["tag"] = tag; + } + + if (topics != null) { + _queryParams["topics"] = topics.toString(); + } + + if (uttSplit != null) { + _queryParams["utt_split"] = uttSplit.toString(); + } + + if (utterances != null) { + _queryParams["utterances"] = utterances.toString(); + } + + if (version != null) { + _queryParams["version"] = version.toString(); + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/usage`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.UsageV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/usage.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/requests/UsageGetRequest.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/requests/UsageGetRequest.ts new file mode 100644 index 00000000..b367cc75 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/requests/UsageGetRequest.ts @@ -0,0 +1,145 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../../../index.js"; + +/** + * @example + * { + * start: "start", + * end: "end", + * accessor: "12345678-1234-1234-1234-123456789012", + * alternatives: true, + * callback_method: true, + * callback: true, + * channels: true, + * custom_intent_mode: true, + * custom_intent: true, + * custom_topic_mode: true, + * custom_topic: true, + * deployment: "hosted", + * detect_entities: true, + * detect_language: true, + * diarize: true, + * dictation: true, + * encoding: true, + * endpoint: "listen", + * extra: true, + * filler_words: true, + * intents: true, + * keyterm: true, + * keywords: true, + * language: true, + * measurements: true, + * method: "sync", + * model: "6f548761-c9c0-429a-9315-11a1d28499c8", + * multichannel: true, + * numerals: true, + * paragraphs: true, + * profanity_filter: true, + * punctuate: true, + * redact: true, + * replace: true, + * sample_rate: true, + * search: true, + * sentiment: true, + * smart_format: true, + * summarize: true, + * tag: "tag1", + * topics: true, + * utt_split: true, + * utterances: true, + * version: true + * } + */ +export interface UsageGetRequest { + /** Start date of the requested date range. Format accepted is YYYY-MM-DD */ + start?: string; + /** End date of the requested date range. Format accepted is YYYY-MM-DD */ + end?: string; + /** Filter for requests where a specific accessor was used */ + accessor?: string; + /** Filter for requests where alternatives were used */ + alternatives?: boolean; + /** Filter for requests where callback method was used */ + callback_method?: boolean; + /** Filter for requests where callback was used */ + callback?: boolean; + /** Filter for requests where channels were used */ + channels?: boolean; + /** Filter for requests where custom intent mode was used */ + custom_intent_mode?: boolean; + /** Filter for requests where custom intent was used */ + custom_intent?: boolean; + /** Filter for requests where custom topic mode was used */ + custom_topic_mode?: boolean; + /** Filter for requests where custom topic was used */ + custom_topic?: boolean; + /** Filter for requests where a specific deployment was used */ + deployment?: Deepgram.manage.v1.projects.UsageGetRequestDeployment; + /** Filter for requests where detect entities was used */ + detect_entities?: boolean; + /** Filter for requests where detect language was used */ + detect_language?: boolean; + /** Filter for requests where diarize was used */ + diarize?: boolean; + /** Filter for requests where dictation was used */ + dictation?: boolean; + /** Filter for requests where encoding was used */ + encoding?: boolean; + /** Filter for requests where a specific endpoint was used */ + endpoint?: Deepgram.manage.v1.projects.UsageGetRequestEndpoint; + /** Filter for requests where extra was used */ + extra?: boolean; + /** Filter for requests where filler words was used */ + filler_words?: boolean; + /** Filter for requests where intents was used */ + intents?: boolean; + /** Filter for requests where keyterm was used */ + keyterm?: boolean; + /** Filter for requests where keywords was used */ + keywords?: boolean; + /** Filter for requests where language was used */ + language?: boolean; + /** Filter for requests where measurements were used */ + measurements?: boolean; + /** Filter for requests where a specific method was used */ + method?: Deepgram.manage.v1.projects.UsageGetRequestMethod; + /** Filter for requests where a specific model uuid was used */ + model?: string; + /** Filter for requests where multichannel was used */ + multichannel?: boolean; + /** Filter for requests where numerals were used */ + numerals?: boolean; + /** Filter for requests where paragraphs were used */ + paragraphs?: boolean; + /** Filter for requests where profanity filter was used */ + profanity_filter?: boolean; + /** Filter for requests where punctuate was used */ + punctuate?: boolean; + /** Filter for requests where redact was used */ + redact?: boolean; + /** Filter for requests where replace was used */ + replace?: boolean; + /** Filter for requests where sample rate was used */ + sample_rate?: boolean; + /** Filter for requests where search was used */ + search?: boolean; + /** Filter for requests where sentiment was used */ + sentiment?: boolean; + /** Filter for requests where smart format was used */ + smart_format?: boolean; + /** Filter for requests where summarize was used */ + summarize?: boolean; + /** Filter for requests where a specific tag was used */ + tag?: string; + /** Filter for requests where topics was used */ + topics?: boolean; + /** Filter for requests where utt split was used */ + utt_split?: boolean; + /** Filter for requests where utterances was used */ + utterances?: boolean; + /** Filter for requests where version was used */ + version?: boolean; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/requests/index.ts new file mode 100644 index 00000000..76084c66 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/client/requests/index.ts @@ -0,0 +1 @@ +export { type UsageGetRequest } from "./UsageGetRequest.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/index.ts new file mode 100644 index 00000000..751123a2 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/index.ts @@ -0,0 +1,3 @@ +export * from "./types/index.js"; +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/Client.ts new file mode 100644 index 00000000..0f84b7da --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/Client.ts @@ -0,0 +1,403 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../../../errors/index.js"; + +export declare namespace Breakdown { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Breakdown { + protected readonly _options: Breakdown.Options; + + constructor(_options: Breakdown.Options = {}) { + this._options = _options; + } + + /** + * Retrieves the usage breakdown for a specific project, with various filter options by API feature or by groupings. Setting a feature (e.g. diarize) to true includes requests that used that feature, while false excludes requests that used it. Multiple true filters are combined with OR logic, while false filters use AND logic. + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.projects.usage.BreakdownGetRequest} request + * @param {Breakdown.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.usage.breakdown.get("123456-7890-1234-5678-901234", { + * start: "start", + * end: "end", + * grouping: "accessor", + * accessor: "12345678-1234-1234-1234-123456789012", + * alternatives: true, + * callback_method: true, + * callback: true, + * channels: true, + * custom_intent_mode: true, + * custom_intent: true, + * custom_topic_mode: true, + * custom_topic: true, + * deployment: "hosted", + * detect_entities: true, + * detect_language: true, + * diarize: true, + * dictation: true, + * encoding: true, + * endpoint: "listen", + * extra: true, + * filler_words: true, + * intents: true, + * keyterm: true, + * keywords: true, + * language: true, + * measurements: true, + * method: "sync", + * model: "6f548761-c9c0-429a-9315-11a1d28499c8", + * multichannel: true, + * numerals: true, + * paragraphs: true, + * profanity_filter: true, + * punctuate: true, + * redact: true, + * replace: true, + * sample_rate: true, + * search: true, + * sentiment: true, + * smart_format: true, + * summarize: true, + * tag: "tag1", + * topics: true, + * utt_split: true, + * utterances: true, + * version: true + * }) + */ + public get( + projectId: string, + request: Deepgram.manage.v1.projects.usage.BreakdownGetRequest = {}, + requestOptions?: Breakdown.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(projectId, request, requestOptions)); + } + + private async __get( + projectId: string, + request: Deepgram.manage.v1.projects.usage.BreakdownGetRequest = {}, + requestOptions?: Breakdown.RequestOptions, + ): Promise> { + const { + start, + end, + grouping, + accessor, + alternatives, + callback_method: callbackMethod, + callback, + channels, + custom_intent_mode: customIntentMode, + custom_intent: customIntent, + custom_topic_mode: customTopicMode, + custom_topic: customTopic, + deployment, + detect_entities: detectEntities, + detect_language: detectLanguage, + diarize, + dictation, + encoding, + endpoint, + extra, + filler_words: fillerWords, + intents, + keyterm, + keywords, + language, + measurements, + method, + model, + multichannel, + numerals, + paragraphs, + profanity_filter: profanityFilter, + punctuate, + redact, + replace, + sample_rate: sampleRate, + search, + sentiment, + smart_format: smartFormat, + summarize, + tag, + topics, + utt_split: uttSplit, + utterances, + version, + } = request; + const _queryParams: Record = {}; + if (start != null) { + _queryParams["start"] = start; + } + + if (end != null) { + _queryParams["end"] = end; + } + + if (grouping != null) { + _queryParams["grouping"] = grouping; + } + + if (accessor != null) { + _queryParams["accessor"] = accessor; + } + + if (alternatives != null) { + _queryParams["alternatives"] = alternatives.toString(); + } + + if (callbackMethod != null) { + _queryParams["callback_method"] = callbackMethod.toString(); + } + + if (callback != null) { + _queryParams["callback"] = callback.toString(); + } + + if (channels != null) { + _queryParams["channels"] = channels.toString(); + } + + if (customIntentMode != null) { + _queryParams["custom_intent_mode"] = customIntentMode.toString(); + } + + if (customIntent != null) { + _queryParams["custom_intent"] = customIntent.toString(); + } + + if (customTopicMode != null) { + _queryParams["custom_topic_mode"] = customTopicMode.toString(); + } + + if (customTopic != null) { + _queryParams["custom_topic"] = customTopic.toString(); + } + + if (deployment != null) { + _queryParams["deployment"] = deployment; + } + + if (detectEntities != null) { + _queryParams["detect_entities"] = detectEntities.toString(); + } + + if (detectLanguage != null) { + _queryParams["detect_language"] = detectLanguage.toString(); + } + + if (diarize != null) { + _queryParams["diarize"] = diarize.toString(); + } + + if (dictation != null) { + _queryParams["dictation"] = dictation.toString(); + } + + if (encoding != null) { + _queryParams["encoding"] = encoding.toString(); + } + + if (endpoint != null) { + _queryParams["endpoint"] = endpoint; + } + + if (extra != null) { + _queryParams["extra"] = extra.toString(); + } + + if (fillerWords != null) { + _queryParams["filler_words"] = fillerWords.toString(); + } + + if (intents != null) { + _queryParams["intents"] = intents.toString(); + } + + if (keyterm != null) { + _queryParams["keyterm"] = keyterm.toString(); + } + + if (keywords != null) { + _queryParams["keywords"] = keywords.toString(); + } + + if (language != null) { + _queryParams["language"] = language.toString(); + } + + if (measurements != null) { + _queryParams["measurements"] = measurements.toString(); + } + + if (method != null) { + _queryParams["method"] = method; + } + + if (model != null) { + _queryParams["model"] = model; + } + + if (multichannel != null) { + _queryParams["multichannel"] = multichannel.toString(); + } + + if (numerals != null) { + _queryParams["numerals"] = numerals.toString(); + } + + if (paragraphs != null) { + _queryParams["paragraphs"] = paragraphs.toString(); + } + + if (profanityFilter != null) { + _queryParams["profanity_filter"] = profanityFilter.toString(); + } + + if (punctuate != null) { + _queryParams["punctuate"] = punctuate.toString(); + } + + if (redact != null) { + _queryParams["redact"] = redact.toString(); + } + + if (replace != null) { + _queryParams["replace"] = replace.toString(); + } + + if (sampleRate != null) { + _queryParams["sample_rate"] = sampleRate.toString(); + } + + if (search != null) { + _queryParams["search"] = search.toString(); + } + + if (sentiment != null) { + _queryParams["sentiment"] = sentiment.toString(); + } + + if (smartFormat != null) { + _queryParams["smart_format"] = smartFormat.toString(); + } + + if (summarize != null) { + _queryParams["summarize"] = summarize.toString(); + } + + if (tag != null) { + _queryParams["tag"] = tag; + } + + if (topics != null) { + _queryParams["topics"] = topics.toString(); + } + + if (uttSplit != null) { + _queryParams["utt_split"] = uttSplit.toString(); + } + + if (utterances != null) { + _queryParams["utterances"] = utterances.toString(); + } + + if (version != null) { + _queryParams["version"] = version.toString(); + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/usage/breakdown`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.UsageBreakdownV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/usage/breakdown.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/requests/BreakdownGetRequest.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/requests/BreakdownGetRequest.ts new file mode 100644 index 00000000..b3c4084a --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/requests/BreakdownGetRequest.ts @@ -0,0 +1,148 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../../../../../index.js"; + +/** + * @example + * { + * start: "start", + * end: "end", + * grouping: "accessor", + * accessor: "12345678-1234-1234-1234-123456789012", + * alternatives: true, + * callback_method: true, + * callback: true, + * channels: true, + * custom_intent_mode: true, + * custom_intent: true, + * custom_topic_mode: true, + * custom_topic: true, + * deployment: "hosted", + * detect_entities: true, + * detect_language: true, + * diarize: true, + * dictation: true, + * encoding: true, + * endpoint: "listen", + * extra: true, + * filler_words: true, + * intents: true, + * keyterm: true, + * keywords: true, + * language: true, + * measurements: true, + * method: "sync", + * model: "6f548761-c9c0-429a-9315-11a1d28499c8", + * multichannel: true, + * numerals: true, + * paragraphs: true, + * profanity_filter: true, + * punctuate: true, + * redact: true, + * replace: true, + * sample_rate: true, + * search: true, + * sentiment: true, + * smart_format: true, + * summarize: true, + * tag: "tag1", + * topics: true, + * utt_split: true, + * utterances: true, + * version: true + * } + */ +export interface BreakdownGetRequest { + /** Start date of the requested date range. Format accepted is YYYY-MM-DD */ + start?: string; + /** End date of the requested date range. Format accepted is YYYY-MM-DD */ + end?: string; + /** Common usage grouping parameters */ + grouping?: Deepgram.manage.v1.projects.usage.BreakdownGetRequestGrouping; + /** Filter for requests where a specific accessor was used */ + accessor?: string; + /** Filter for requests where alternatives were used */ + alternatives?: boolean; + /** Filter for requests where callback method was used */ + callback_method?: boolean; + /** Filter for requests where callback was used */ + callback?: boolean; + /** Filter for requests where channels were used */ + channels?: boolean; + /** Filter for requests where custom intent mode was used */ + custom_intent_mode?: boolean; + /** Filter for requests where custom intent was used */ + custom_intent?: boolean; + /** Filter for requests where custom topic mode was used */ + custom_topic_mode?: boolean; + /** Filter for requests where custom topic was used */ + custom_topic?: boolean; + /** Filter for requests where a specific deployment was used */ + deployment?: Deepgram.manage.v1.projects.usage.BreakdownGetRequestDeployment; + /** Filter for requests where detect entities was used */ + detect_entities?: boolean; + /** Filter for requests where detect language was used */ + detect_language?: boolean; + /** Filter for requests where diarize was used */ + diarize?: boolean; + /** Filter for requests where dictation was used */ + dictation?: boolean; + /** Filter for requests where encoding was used */ + encoding?: boolean; + /** Filter for requests where a specific endpoint was used */ + endpoint?: Deepgram.manage.v1.projects.usage.BreakdownGetRequestEndpoint; + /** Filter for requests where extra was used */ + extra?: boolean; + /** Filter for requests where filler words was used */ + filler_words?: boolean; + /** Filter for requests where intents was used */ + intents?: boolean; + /** Filter for requests where keyterm was used */ + keyterm?: boolean; + /** Filter for requests where keywords was used */ + keywords?: boolean; + /** Filter for requests where language was used */ + language?: boolean; + /** Filter for requests where measurements were used */ + measurements?: boolean; + /** Filter for requests where a specific method was used */ + method?: Deepgram.manage.v1.projects.usage.BreakdownGetRequestMethod; + /** Filter for requests where a specific model uuid was used */ + model?: string; + /** Filter for requests where multichannel was used */ + multichannel?: boolean; + /** Filter for requests where numerals were used */ + numerals?: boolean; + /** Filter for requests where paragraphs were used */ + paragraphs?: boolean; + /** Filter for requests where profanity filter was used */ + profanity_filter?: boolean; + /** Filter for requests where punctuate was used */ + punctuate?: boolean; + /** Filter for requests where redact was used */ + redact?: boolean; + /** Filter for requests where replace was used */ + replace?: boolean; + /** Filter for requests where sample rate was used */ + sample_rate?: boolean; + /** Filter for requests where search was used */ + search?: boolean; + /** Filter for requests where sentiment was used */ + sentiment?: boolean; + /** Filter for requests where smart format was used */ + smart_format?: boolean; + /** Filter for requests where summarize was used */ + summarize?: boolean; + /** Filter for requests where a specific tag was used */ + tag?: string; + /** Filter for requests where topics was used */ + topics?: boolean; + /** Filter for requests where utt split was used */ + utt_split?: boolean; + /** Filter for requests where utterances was used */ + utterances?: boolean; + /** Filter for requests where version was used */ + version?: boolean; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/requests/index.ts new file mode 100644 index 00000000..332c1b39 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/client/requests/index.ts @@ -0,0 +1 @@ +export { type BreakdownGetRequest } from "./BreakdownGetRequest.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/index.ts new file mode 100644 index 00000000..f095e147 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/index.ts @@ -0,0 +1,2 @@ +export * from "./types/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestDeployment.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestDeployment.ts new file mode 100644 index 00000000..da36703a --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestDeployment.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Deployment type for the requests + */ +export type BreakdownGetRequestDeployment = "hosted" | "beta" | "self-hosted"; +export const BreakdownGetRequestDeployment = { + Hosted: "hosted", + Beta: "beta", + SelfHosted: "self-hosted", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestEndpoint.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestEndpoint.ts new file mode 100644 index 00000000..f3f06ace --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestEndpoint.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type BreakdownGetRequestEndpoint = "listen" | "read" | "speak" | "agent"; +export const BreakdownGetRequestEndpoint = { + Listen: "listen", + Read: "read", + Speak: "speak", + Agent: "agent", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestGrouping.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestGrouping.ts new file mode 100644 index 00000000..23540548 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestGrouping.ts @@ -0,0 +1,21 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type BreakdownGetRequestGrouping = + | "accessor" + | "endpoint" + | "feature_set" + | "models" + | "method" + | "tags" + | "deployment"; +export const BreakdownGetRequestGrouping = { + Accessor: "accessor", + Endpoint: "endpoint", + FeatureSet: "feature_set", + Models: "models", + Method: "method", + Tags: "tags", + Deployment: "deployment", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestMethod.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestMethod.ts new file mode 100644 index 00000000..f1838dda --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/BreakdownGetRequestMethod.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Method type for the request + */ +export type BreakdownGetRequestMethod = "sync" | "async" | "streaming"; +export const BreakdownGetRequestMethod = { + Sync: "sync", + Async: "async", + Streaming: "streaming", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/index.ts new file mode 100644 index 00000000..45fa1150 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/breakdown/types/index.ts @@ -0,0 +1,4 @@ +export * from "./BreakdownGetRequestGrouping.js"; +export * from "./BreakdownGetRequestDeployment.js"; +export * from "./BreakdownGetRequestEndpoint.js"; +export * from "./BreakdownGetRequestMethod.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/Client.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/Client.ts new file mode 100644 index 00000000..7764615a --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/Client.ts @@ -0,0 +1,142 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../../../../../environments.js"; +import * as core from "../../../../../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../../../../../errors/index.js"; + +export declare namespace Fields { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Fields { + protected readonly _options: Fields.Options; + + constructor(_options: Fields.Options = {}) { + this._options = _options; + } + + /** + * Lists the features, models, tags, languages, and processing method used for requests in the specified project + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.manage.v1.projects.usage.FieldsListRequest} request + * @param {Fields.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.manage.v1.projects.usage.fields.list("123456-7890-1234-5678-901234", { + * start: "start", + * end: "end" + * }) + */ + public list( + projectId: string, + request: Deepgram.manage.v1.projects.usage.FieldsListRequest = {}, + requestOptions?: Fields.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, request, requestOptions)); + } + + private async __list( + projectId: string, + request: Deepgram.manage.v1.projects.usage.FieldsListRequest = {}, + requestOptions?: Fields.RequestOptions, + ): Promise> { + const { start, end } = request; + const _queryParams: Record = {}; + if (start != null) { + _queryParams["start"] = start; + } + + if (end != null) { + _queryParams["end"] = end; + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/usage/fields`, + ), + method: "GET", + headers: _headers, + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.UsageFieldsV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/usage/fields.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/requests/FieldsListRequest.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/requests/FieldsListRequest.ts new file mode 100644 index 00000000..3712a3eb --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/requests/FieldsListRequest.ts @@ -0,0 +1,17 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * @example + * { + * start: "start", + * end: "end" + * } + */ +export interface FieldsListRequest { + /** Start date of the requested date range. Format accepted is YYYY-MM-DD */ + start?: string; + /** End date of the requested date range. Format accepted is YYYY-MM-DD */ + end?: string; +} diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/requests/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/requests/index.ts new file mode 100644 index 00000000..0855a585 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/client/requests/index.ts @@ -0,0 +1 @@ +export { type FieldsListRequest } from "./FieldsListRequest.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/index.ts new file mode 100644 index 00000000..914b8c3c --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/fields/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/index.ts new file mode 100644 index 00000000..5580c4e6 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/resources/index.ts @@ -0,0 +1,5 @@ +export * as breakdown from "./breakdown/index.js"; +export * from "./breakdown/types/index.js"; +export * as fields from "./fields/index.js"; +export * from "./breakdown/client/requests/index.js"; +export * from "./fields/client/requests/index.js"; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/UsageGetRequestDeployment.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/UsageGetRequestDeployment.ts new file mode 100644 index 00000000..8d040e9d --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/UsageGetRequestDeployment.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Deployment type for the requests + */ +export type UsageGetRequestDeployment = "hosted" | "beta" | "self-hosted"; +export const UsageGetRequestDeployment = { + Hosted: "hosted", + Beta: "beta", + SelfHosted: "self-hosted", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/UsageGetRequestEndpoint.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/UsageGetRequestEndpoint.ts new file mode 100644 index 00000000..b6646dbc --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/UsageGetRequestEndpoint.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type UsageGetRequestEndpoint = "listen" | "read" | "speak" | "agent"; +export const UsageGetRequestEndpoint = { + Listen: "listen", + Read: "read", + Speak: "speak", + Agent: "agent", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/UsageGetRequestMethod.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/UsageGetRequestMethod.ts new file mode 100644 index 00000000..0eabbd35 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/UsageGetRequestMethod.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Method type for the request + */ +export type UsageGetRequestMethod = "sync" | "async" | "streaming"; +export const UsageGetRequestMethod = { + Sync: "sync", + Async: "async", + Streaming: "streaming", +} as const; diff --git a/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/index.ts b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/index.ts new file mode 100644 index 00000000..57208132 --- /dev/null +++ b/src/api/resources/manage/resources/v1/resources/projects/resources/usage/types/index.ts @@ -0,0 +1,3 @@ +export * from "./UsageGetRequestDeployment.js"; +export * from "./UsageGetRequestEndpoint.js"; +export * from "./UsageGetRequestMethod.js"; diff --git a/src/api/resources/read/client/Client.ts b/src/api/resources/read/client/Client.ts new file mode 100644 index 00000000..39d75065 --- /dev/null +++ b/src/api/resources/read/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments.js"; +import * as core from "../../../../core/index.js"; +import { V1 } from "../resources/v1/client/Client.js"; + +export declare namespace Read { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class Read { + protected readonly _options: Read.Options; + protected _v1: V1 | undefined; + + constructor(_options: Read.Options = {}) { + this._options = _options; + } + + public get v1(): V1 { + return (this._v1 ??= new V1(this._options)); + } +} diff --git a/src/api/resources/read/client/index.ts b/src/api/resources/read/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/read/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/read/index.ts b/src/api/resources/read/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/read/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/read/resources/index.ts b/src/api/resources/read/resources/index.ts new file mode 100644 index 00000000..c6b56d24 --- /dev/null +++ b/src/api/resources/read/resources/index.ts @@ -0,0 +1 @@ +export * as v1 from "./v1/index.js"; diff --git a/src/api/resources/read/resources/v1/client/Client.ts b/src/api/resources/read/resources/v1/client/Client.ts new file mode 100644 index 00000000..580b17f7 --- /dev/null +++ b/src/api/resources/read/resources/v1/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../environments.js"; +import * as core from "../../../../../../core/index.js"; +import { Text } from "../resources/text/client/Client.js"; + +export declare namespace V1 { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class V1 { + protected readonly _options: V1.Options; + protected _text: Text | undefined; + + constructor(_options: V1.Options = {}) { + this._options = _options; + } + + public get text(): Text { + return (this._text ??= new Text(this._options)); + } +} diff --git a/src/api/resources/read/resources/v1/client/index.ts b/src/api/resources/read/resources/v1/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/read/resources/v1/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/read/resources/v1/index.ts b/src/api/resources/read/resources/v1/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/read/resources/v1/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/read/resources/v1/resources/index.ts b/src/api/resources/read/resources/v1/resources/index.ts new file mode 100644 index 00000000..dc1b88c4 --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/index.ts @@ -0,0 +1,3 @@ +export * as text from "./text/index.js"; +export * from "./text/types/index.js"; +export * from "./text/client/requests/index.js"; diff --git a/src/api/resources/read/resources/v1/resources/text/client/Client.ts b/src/api/resources/read/resources/v1/resources/text/client/Client.ts new file mode 100644 index 00000000..c512a276 --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/client/Client.ts @@ -0,0 +1,219 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../environments.js"; +import * as core from "../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../errors/index.js"; + +export declare namespace Text { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Text { + protected readonly _options: Text.Options; + + constructor(_options: Text.Options = {}) { + this._options = _options; + } + + /** + * Analyze text content using Deepgrams text analysis API + * + * @param {Deepgram.read.v1.TextAnalyzeRequest} request + * @param {Text.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.read.v1.text.analyze({ + * callback: "callback", + * callback_method: "POST", + * sentiment: true, + * summarize: "v2", + * tag: "tag", + * topics: true, + * custom_topic: "custom_topic", + * custom_topic_mode: "extended", + * intents: true, + * custom_intent: "custom_intent", + * custom_intent_mode: "extended", + * language: "language", + * body: { + * url: "url" + * } + * }) + */ + public analyze( + request: Deepgram.read.v1.TextAnalyzeRequest, + requestOptions?: Text.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__analyze(request, requestOptions)); + } + + private async __analyze( + request: Deepgram.read.v1.TextAnalyzeRequest, + requestOptions?: Text.RequestOptions, + ): Promise> { + const { + callback, + callback_method: callbackMethod, + sentiment, + summarize, + tag, + topics, + custom_topic: customTopic, + custom_topic_mode: customTopicMode, + intents, + custom_intent: customIntent, + custom_intent_mode: customIntentMode, + language, + body: _body, + } = request; + const _queryParams: Record = {}; + if (callback != null) { + _queryParams["callback"] = callback; + } + + if (callbackMethod != null) { + _queryParams["callback_method"] = callbackMethod; + } + + if (sentiment != null) { + _queryParams["sentiment"] = sentiment.toString(); + } + + if (summarize != null) { + _queryParams["summarize"] = summarize; + } + + if (tag != null) { + if (Array.isArray(tag)) { + _queryParams["tag"] = tag.map((item) => item); + } else { + _queryParams["tag"] = tag; + } + } + + if (topics != null) { + _queryParams["topics"] = topics.toString(); + } + + if (customTopic != null) { + if (Array.isArray(customTopic)) { + _queryParams["custom_topic"] = customTopic.map((item) => item); + } else { + _queryParams["custom_topic"] = customTopic; + } + } + + if (customTopicMode != null) { + _queryParams["custom_topic_mode"] = customTopicMode; + } + + if (intents != null) { + _queryParams["intents"] = intents.toString(); + } + + if (customIntent != null) { + if (Array.isArray(customIntent)) { + _queryParams["custom_intent"] = customIntent.map((item) => item); + } else { + _queryParams["custom_intent"] = customIntent; + } + } + + if (customIntentMode != null) { + _queryParams["custom_intent_mode"] = customIntentMode; + } + + if (language != null) { + _queryParams["language"] = language; + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + "v1/read", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + requestType: "json", + body: _body, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body as Deepgram.ReadV1Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling POST /v1/read."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/read/resources/v1/resources/text/client/index.ts b/src/api/resources/read/resources/v1/resources/text/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/read/resources/v1/resources/text/client/requests/TextAnalyzeRequest.ts b/src/api/resources/read/resources/v1/resources/text/client/requests/TextAnalyzeRequest.ts new file mode 100644 index 00000000..56f4dbec --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/client/requests/TextAnalyzeRequest.ts @@ -0,0 +1,53 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../index.js"; + +/** + * @example + * { + * callback: "callback", + * callback_method: "POST", + * sentiment: true, + * summarize: "v2", + * tag: "tag", + * topics: true, + * custom_topic: "custom_topic", + * custom_topic_mode: "extended", + * intents: true, + * custom_intent: "custom_intent", + * custom_intent_mode: "extended", + * language: "language", + * body: { + * url: "url" + * } + * } + */ +export interface TextAnalyzeRequest { + /** URL to which we'll make the callback request */ + callback?: string; + /** HTTP method by which the callback request will be made */ + callback_method?: Deepgram.read.v1.TextAnalyzeRequestCallbackMethod; + /** Recognizes the sentiment throughout a transcript or text */ + sentiment?: boolean; + /** Summarize content. For Listen API, supports string version option. For Read API, accepts boolean only. */ + summarize?: Deepgram.read.v1.TextAnalyzeRequestSummarize; + /** Label your requests for the purpose of identification during usage reporting */ + tag?: string | string[]; + /** Detect topics throughout a transcript or text */ + topics?: boolean; + /** Custom topics you want the model to detect within your input audio or text if present Submit up to `100`. */ + custom_topic?: string | string[]; + /** Sets how the model will interpret strings submitted to the `custom_topic` param. When `strict`, the model will only return topics submitted using the `custom_topic` param. When `extended`, the model will return its own detected topics in addition to those submitted using the `custom_topic` param */ + custom_topic_mode?: Deepgram.read.v1.TextAnalyzeRequestCustomTopicMode; + /** Recognizes speaker intent throughout a transcript or text */ + intents?: boolean; + /** Custom intents you want the model to detect within your input audio if present */ + custom_intent?: string | string[]; + /** Sets how the model will interpret intents submitted to the `custom_intent` param. When `strict`, the model will only return intents submitted using the `custom_intent` param. When `extended`, the model will return its own detected intents in the `custom_intent` param. */ + custom_intent_mode?: Deepgram.read.v1.TextAnalyzeRequestCustomIntentMode; + /** The [BCP-47 language tag](https://tools.ietf.org/html/bcp47) that hints at the primary spoken language. Depending on the Model and API endpoint you choose only certain languages are available */ + language?: string; + body: Deepgram.ReadV1Request; +} diff --git a/src/api/resources/read/resources/v1/resources/text/client/requests/index.ts b/src/api/resources/read/resources/v1/resources/text/client/requests/index.ts new file mode 100644 index 00000000..2c4c0f9a --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/client/requests/index.ts @@ -0,0 +1 @@ +export { type TextAnalyzeRequest } from "./TextAnalyzeRequest.js"; diff --git a/src/api/resources/read/resources/v1/resources/text/index.ts b/src/api/resources/read/resources/v1/resources/text/index.ts new file mode 100644 index 00000000..f095e147 --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/index.ts @@ -0,0 +1,2 @@ +export * from "./types/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestCallbackMethod.ts b/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestCallbackMethod.ts new file mode 100644 index 00000000..21c5d72d --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestCallbackMethod.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type TextAnalyzeRequestCallbackMethod = "POST" | "PUT"; +export const TextAnalyzeRequestCallbackMethod = { + Post: "POST", + Put: "PUT", +} as const; diff --git a/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestCustomIntentMode.ts b/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestCustomIntentMode.ts new file mode 100644 index 00000000..85b2bd7a --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestCustomIntentMode.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type TextAnalyzeRequestCustomIntentMode = "extended" | "strict"; +export const TextAnalyzeRequestCustomIntentMode = { + Extended: "extended", + Strict: "strict", +} as const; diff --git a/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestCustomTopicMode.ts b/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestCustomTopicMode.ts new file mode 100644 index 00000000..c0d78d1b --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestCustomTopicMode.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type TextAnalyzeRequestCustomTopicMode = "extended" | "strict"; +export const TextAnalyzeRequestCustomTopicMode = { + Extended: "extended", + Strict: "strict", +} as const; diff --git a/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestSummarize.ts b/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestSummarize.ts new file mode 100644 index 00000000..cc92dbf5 --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/types/TextAnalyzeRequestSummarize.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type TextAnalyzeRequestSummarize = "v2" | "v1"; +export const TextAnalyzeRequestSummarize = { + V2: "v2", + V1: "v1", +} as const; diff --git a/src/api/resources/read/resources/v1/resources/text/types/index.ts b/src/api/resources/read/resources/v1/resources/text/types/index.ts new file mode 100644 index 00000000..05e0fb13 --- /dev/null +++ b/src/api/resources/read/resources/v1/resources/text/types/index.ts @@ -0,0 +1,4 @@ +export * from "./TextAnalyzeRequestCallbackMethod.js"; +export * from "./TextAnalyzeRequestSummarize.js"; +export * from "./TextAnalyzeRequestCustomTopicMode.js"; +export * from "./TextAnalyzeRequestCustomIntentMode.js"; diff --git a/src/api/resources/selfHosted/client/Client.ts b/src/api/resources/selfHosted/client/Client.ts new file mode 100644 index 00000000..acdb6059 --- /dev/null +++ b/src/api/resources/selfHosted/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments.js"; +import * as core from "../../../../core/index.js"; +import { V1 } from "../resources/v1/client/Client.js"; + +export declare namespace SelfHosted { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class SelfHosted { + protected readonly _options: SelfHosted.Options; + protected _v1: V1 | undefined; + + constructor(_options: SelfHosted.Options = {}) { + this._options = _options; + } + + public get v1(): V1 { + return (this._v1 ??= new V1(this._options)); + } +} diff --git a/src/api/resources/selfHosted/client/index.ts b/src/api/resources/selfHosted/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/selfHosted/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/selfHosted/index.ts b/src/api/resources/selfHosted/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/selfHosted/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/selfHosted/resources/index.ts b/src/api/resources/selfHosted/resources/index.ts new file mode 100644 index 00000000..c6b56d24 --- /dev/null +++ b/src/api/resources/selfHosted/resources/index.ts @@ -0,0 +1 @@ +export * as v1 from "./v1/index.js"; diff --git a/src/api/resources/selfHosted/resources/v1/client/Client.ts b/src/api/resources/selfHosted/resources/v1/client/Client.ts new file mode 100644 index 00000000..9e7aa8e4 --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../environments.js"; +import * as core from "../../../../../../core/index.js"; +import { DistributionCredentials } from "../resources/distributionCredentials/client/Client.js"; + +export declare namespace V1 { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class V1 { + protected readonly _options: V1.Options; + protected _distributionCredentials: DistributionCredentials | undefined; + + constructor(_options: V1.Options = {}) { + this._options = _options; + } + + public get distributionCredentials(): DistributionCredentials { + return (this._distributionCredentials ??= new DistributionCredentials(this._options)); + } +} diff --git a/src/api/resources/selfHosted/resources/v1/client/index.ts b/src/api/resources/selfHosted/resources/v1/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/selfHosted/resources/v1/index.ts b/src/api/resources/selfHosted/resources/v1/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/Client.ts b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/Client.ts new file mode 100644 index 00000000..b4c8cb78 --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/Client.ts @@ -0,0 +1,405 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../environments.js"; +import * as core from "../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../errors/index.js"; + +export declare namespace DistributionCredentials { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class DistributionCredentials { + protected readonly _options: DistributionCredentials.Options; + + constructor(_options: DistributionCredentials.Options = {}) { + this._options = _options; + } + + /** + * Lists sets of distribution credentials for the specified project + * + * @param {string} projectId - The unique identifier of the project + * @param {DistributionCredentials.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.selfHosted.v1.distributionCredentials.list("123456-7890-1234-5678-901234") + */ + public list( + projectId: string, + requestOptions?: DistributionCredentials.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(projectId, requestOptions)); + } + + private async __list( + projectId: string, + requestOptions?: DistributionCredentials.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/self-hosted/distribution/credentials`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.ListProjectDistributionCredentialsV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/self-hosted/distribution/credentials.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Creates a set of distribution credentials for the specified project + * + * @param {string} projectId - The unique identifier of the project + * @param {Deepgram.selfHosted.v1.CreateProjectDistributionCredentialsV1Request} request + * @param {DistributionCredentials.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.selfHosted.v1.distributionCredentials.create("123456-7890-1234-5678-901234", { + * provider: "quay" + * }) + */ + public create( + projectId: string, + request: Deepgram.selfHosted.v1.CreateProjectDistributionCredentialsV1Request = {}, + requestOptions?: DistributionCredentials.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__create(projectId, request, requestOptions)); + } + + private async __create( + projectId: string, + request: Deepgram.selfHosted.v1.CreateProjectDistributionCredentialsV1Request = {}, + requestOptions?: DistributionCredentials.RequestOptions, + ): Promise> { + const { scopes, provider, ..._body } = request; + const _queryParams: Record = {}; + if (scopes != null) { + if (Array.isArray(scopes)) { + _queryParams["scopes"] = scopes.map((item) => item); + } else { + _queryParams["scopes"] = scopes; + } + } + + if (provider != null) { + _queryParams["provider"] = provider; + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/self-hosted/distribution/credentials`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + requestType: "json", + body: _body, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.CreateProjectDistributionCredentialsV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling POST /v1/projects/{project_id}/self-hosted/distribution/credentials.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Returns a set of distribution credentials for the specified project + * + * @param {string} projectId - The unique identifier of the project + * @param {string} distributionCredentialsId - The UUID of the distribution credentials + * @param {DistributionCredentials.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.selfHosted.v1.distributionCredentials.get("123456-7890-1234-5678-901234", "8b36cfd0-472f-4a21-833f-2d6343c3a2f3") + */ + public get( + projectId: string, + distributionCredentialsId: string, + requestOptions?: DistributionCredentials.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(projectId, distributionCredentialsId, requestOptions)); + } + + private async __get( + projectId: string, + distributionCredentialsId: string, + requestOptions?: DistributionCredentials.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/self-hosted/distribution/credentials/${encodeURIComponent(distributionCredentialsId)}`, + ), + method: "GET", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.GetProjectDistributionCredentialsV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling GET /v1/projects/{project_id}/self-hosted/distribution/credentials/{distribution_credentials_id}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + /** + * Deletes a set of distribution credentials for the specified project + * + * @param {string} projectId - The unique identifier of the project + * @param {string} distributionCredentialsId - The UUID of the distribution credentials + * @param {DistributionCredentials.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link Deepgram.BadRequestError} + * + * @example + * await client.selfHosted.v1.distributionCredentials.delete("123456-7890-1234-5678-901234", "8b36cfd0-472f-4a21-833f-2d6343c3a2f3") + */ + public delete( + projectId: string, + distributionCredentialsId: string, + requestOptions?: DistributionCredentials.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise( + this.__delete(projectId, distributionCredentialsId, requestOptions), + ); + } + + private async __delete( + projectId: string, + distributionCredentialsId: string, + requestOptions?: DistributionCredentials.RequestOptions, + ): Promise> { + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + `v1/projects/${encodeURIComponent(projectId)}/self-hosted/distribution/credentials/${encodeURIComponent(distributionCredentialsId)}`, + ), + method: "DELETE", + headers: _headers, + queryParameters: requestOptions?.queryParams, + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { + data: _response.body as Deepgram.GetProjectDistributionCredentialsV1Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError( + "Timeout exceeded when calling DELETE /v1/projects/{project_id}/self-hosted/distribution/credentials/{distribution_credentials_id}.", + ); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/index.ts b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/requests/CreateProjectDistributionCredentialsV1Request.ts b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/requests/CreateProjectDistributionCredentialsV1Request.ts new file mode 100644 index 00000000..540a46ae --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/requests/CreateProjectDistributionCredentialsV1Request.ts @@ -0,0 +1,22 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../index.js"; + +/** + * @example + * { + * provider: "quay" + * } + */ +export interface CreateProjectDistributionCredentialsV1Request { + /** List of permission scopes for the credentials */ + scopes?: + | Deepgram.selfHosted.v1.DistributionCredentialsCreateRequestScopesItem + | Deepgram.selfHosted.v1.DistributionCredentialsCreateRequestScopesItem[]; + /** The provider of the distribution service */ + provider?: "quay"; + /** Optional comment about the credentials */ + comment?: string; +} diff --git a/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/requests/index.ts b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/requests/index.ts new file mode 100644 index 00000000..225806f0 --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/client/requests/index.ts @@ -0,0 +1 @@ +export { type CreateProjectDistributionCredentialsV1Request } from "./CreateProjectDistributionCredentialsV1Request.js"; diff --git a/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/index.ts b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/index.ts new file mode 100644 index 00000000..f095e147 --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/index.ts @@ -0,0 +1,2 @@ +export * from "./types/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/types/DistributionCredentialsCreateRequestScopesItem.ts b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/types/DistributionCredentialsCreateRequestScopesItem.ts new file mode 100644 index 00000000..756d2b4b --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/types/DistributionCredentialsCreateRequestScopesItem.ts @@ -0,0 +1,23 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type DistributionCredentialsCreateRequestScopesItem = + | "self-hosted:products" + | "self-hosted:product:api" + | "self-hosted:product:engine" + | "self-hosted:product:license-proxy" + | "self-hosted:product:dgtools" + | "self-hosted:product:billing" + | "self-hosted:product:hotpepper" + | "self-hosted:product:metrics-server"; +export const DistributionCredentialsCreateRequestScopesItem = { + SelfHostedProducts: "self-hosted:products", + SelfHostedProductApi: "self-hosted:product:api", + SelfHostedProductEngine: "self-hosted:product:engine", + SelfHostedProductLicenseProxy: "self-hosted:product:license-proxy", + SelfHostedProductDgtools: "self-hosted:product:dgtools", + SelfHostedProductBilling: "self-hosted:product:billing", + SelfHostedProductHotpepper: "self-hosted:product:hotpepper", + SelfHostedProductMetricsServer: "self-hosted:product:metrics-server", +} as const; diff --git a/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/types/index.ts b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/types/index.ts new file mode 100644 index 00000000..74d8a642 --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/resources/distributionCredentials/types/index.ts @@ -0,0 +1 @@ +export * from "./DistributionCredentialsCreateRequestScopesItem.js"; diff --git a/src/api/resources/selfHosted/resources/v1/resources/index.ts b/src/api/resources/selfHosted/resources/v1/resources/index.ts new file mode 100644 index 00000000..ba64d2d8 --- /dev/null +++ b/src/api/resources/selfHosted/resources/v1/resources/index.ts @@ -0,0 +1,3 @@ +export * as distributionCredentials from "./distributionCredentials/index.js"; +export * from "./distributionCredentials/types/index.js"; +export * from "./distributionCredentials/client/requests/index.js"; diff --git a/src/api/resources/speak/client/Client.ts b/src/api/resources/speak/client/Client.ts new file mode 100644 index 00000000..153e6b06 --- /dev/null +++ b/src/api/resources/speak/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../environments.js"; +import * as core from "../../../../core/index.js"; +import { V1 } from "../resources/v1/client/Client.js"; + +export declare namespace Speak { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class Speak { + protected readonly _options: Speak.Options; + protected _v1: V1 | undefined; + + constructor(_options: Speak.Options = {}) { + this._options = _options; + } + + public get v1(): V1 { + return (this._v1 ??= new V1(this._options)); + } +} diff --git a/src/api/resources/speak/client/index.ts b/src/api/resources/speak/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/speak/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/speak/index.ts b/src/api/resources/speak/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/speak/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/speak/resources/index.ts b/src/api/resources/speak/resources/index.ts new file mode 100644 index 00000000..c6b56d24 --- /dev/null +++ b/src/api/resources/speak/resources/index.ts @@ -0,0 +1 @@ +export * as v1 from "./v1/index.js"; diff --git a/src/api/resources/speak/resources/v1/client/Client.ts b/src/api/resources/speak/resources/v1/client/Client.ts new file mode 100644 index 00000000..e1e93bef --- /dev/null +++ b/src/api/resources/speak/resources/v1/client/Client.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../environments.js"; +import * as core from "../../../../../../core/index.js"; +import { Audio } from "../resources/audio/client/Client.js"; + +export declare namespace V1 { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } +} + +export class V1 { + protected readonly _options: V1.Options; + protected _audio: Audio | undefined; + + constructor(_options: V1.Options = {}) { + this._options = _options; + } + + public get audio(): Audio { + return (this._audio ??= new Audio(this._options)); + } +} diff --git a/src/api/resources/speak/resources/v1/client/index.ts b/src/api/resources/speak/resources/v1/client/index.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/src/api/resources/speak/resources/v1/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/speak/resources/v1/index.ts b/src/api/resources/speak/resources/v1/index.ts new file mode 100644 index 00000000..02bb7065 --- /dev/null +++ b/src/api/resources/speak/resources/v1/index.ts @@ -0,0 +1,2 @@ +export * from "./resources/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/speak/resources/v1/resources/audio/client/Client.ts b/src/api/resources/speak/resources/v1/resources/audio/client/Client.ts new file mode 100644 index 00000000..d5c33143 --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/client/Client.ts @@ -0,0 +1,174 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as environments from "../../../../../../../../environments.js"; +import * as core from "../../../../../../../../core/index.js"; +import * as Deepgram from "../../../../../../../index.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../../../core/headers.js"; +import * as errors from "../../../../../../../../errors/index.js"; + +export declare namespace Audio { + export interface Options { + environment?: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + apiKey?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + fetcher?: core.FetchFunction; + } + + export interface RequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + } +} + +export class Audio { + protected readonly _options: Audio.Options; + + constructor(_options: Audio.Options = {}) { + this._options = _options; + } + + /** + * Convert text into natural-sounding speech using Deepgram's TTS REST API + * @throws {@link Deepgram.BadRequestError} + */ + public generate( + request: Deepgram.speak.v1.SpeakV1Request, + requestOptions?: Audio.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__generate(request, requestOptions)); + } + + private async __generate( + request: Deepgram.speak.v1.SpeakV1Request, + requestOptions?: Audio.RequestOptions, + ): Promise> { + const { + callback, + callback_method: callbackMethod, + mip_opt_out: mipOptOut, + tag, + bit_rate: bitRate, + container, + encoding, + model, + sample_rate: sampleRate, + ..._body + } = request; + const _queryParams: Record = {}; + if (callback != null) { + _queryParams["callback"] = callback; + } + + if (callbackMethod != null) { + _queryParams["callback_method"] = callbackMethod; + } + + if (mipOptOut != null) { + _queryParams["mip_opt_out"] = mipOptOut.toString(); + } + + if (tag != null) { + if (Array.isArray(tag)) { + _queryParams["tag"] = tag.map((item) => item); + } else { + _queryParams["tag"] = tag; + } + } + + if (bitRate != null) { + _queryParams["bit_rate"] = bitRate.toString(); + } + + if (container != null) { + _queryParams["container"] = container; + } + + if (encoding != null) { + _queryParams["encoding"] = encoding; + } + + if (model != null) { + _queryParams["model"] = model; + } + + if (sampleRate != null) { + _queryParams["sample_rate"] = sampleRate.toString(); + } + + let _headers: core.Fetcher.Args["headers"] = mergeHeaders( + this._options?.headers, + mergeOnlyDefinedHeaders({ ...(await this._getCustomAuthorizationHeaders()) }), + requestOptions?.headers, + ); + const _response = await (this._options.fetcher ?? core.fetcher)({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + ( + (await core.Supplier.get(this._options.environment)) ?? + environments.DeepgramEnvironment.Production + ).base, + "v1/speak", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryParameters: { ..._queryParams, ...requestOptions?.queryParams }, + requestType: "json", + body: _body, + responseType: "binary-response", + timeoutMs: requestOptions?.timeoutInSeconds != null ? requestOptions.timeoutInSeconds * 1000 : 60000, + maxRetries: requestOptions?.maxRetries, + abortSignal: requestOptions?.abortSignal, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new Deepgram.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + switch (_response.error.reason) { + case "non-json": + throw new errors.DeepgramError({ + statusCode: _response.error.statusCode, + body: _response.error.rawBody, + rawResponse: _response.rawResponse, + }); + case "timeout": + throw new errors.DeepgramTimeoutError("Timeout exceeded when calling POST /v1/speak."); + case "unknown": + throw new errors.DeepgramError({ + message: _response.error.errorMessage, + rawResponse: _response.rawResponse, + }); + } + } + + protected async _getCustomAuthorizationHeaders() { + const apiKeyValue = (await core.Supplier.get(this._options.apiKey)) ?? process?.env["DEEPGRAM_API_KEY"]; + return { Authorization: `Token ${apiKeyValue}` }; + } +} diff --git a/src/api/resources/speak/resources/v1/resources/audio/client/index.ts b/src/api/resources/speak/resources/v1/resources/audio/client/index.ts new file mode 100644 index 00000000..82648c6f --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/client/index.ts @@ -0,0 +1,2 @@ +export {}; +export * from "./requests/index.js"; diff --git a/src/api/resources/speak/resources/v1/resources/audio/client/requests/SpeakV1Request.ts b/src/api/resources/speak/resources/v1/resources/audio/client/requests/SpeakV1Request.ts new file mode 100644 index 00000000..b468e806 --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/client/requests/SpeakV1Request.ts @@ -0,0 +1,34 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../../../../../../../../index.js"; + +/** + * @example + * { + * text: "text" + * } + */ +export interface SpeakV1Request { + /** URL to which we'll make the callback request */ + callback?: string; + /** HTTP method by which the callback request will be made */ + callback_method?: Deepgram.speak.v1.AudioGenerateRequestCallbackMethod; + /** Opts out requests from the Deepgram Model Improvement Program. Refer to our Docs for pricing impacts before setting this to true. https://dpgr.am/deepgram-mip */ + mip_opt_out?: boolean; + /** Label your requests for the purpose of identification during usage reporting */ + tag?: string | string[]; + /** The bitrate of the audio in bits per second. Choose from predefined ranges or specific values based on the encoding type. */ + bit_rate?: number; + /** Container specifies the file format wrapper for the output audio. The available options depend on the encoding type. */ + container?: Deepgram.speak.v1.AudioGenerateRequestContainer; + /** Encoding allows you to specify the expected encoding of your audio output */ + encoding?: Deepgram.speak.v1.AudioGenerateRequestEncoding; + /** AI model used to process submitted text */ + model?: Deepgram.speak.v1.AudioGenerateRequestModel; + /** Sample Rate specifies the sample rate for the output audio. Based on the encoding, different sample rates are supported. For some encodings, the sample rate is not configurable */ + sample_rate?: number; + /** The text content to be converted to speech */ + text: string; +} diff --git a/src/api/resources/speak/resources/v1/resources/audio/client/requests/index.ts b/src/api/resources/speak/resources/v1/resources/audio/client/requests/index.ts new file mode 100644 index 00000000..82b242d5 --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/client/requests/index.ts @@ -0,0 +1 @@ +export { type SpeakV1Request } from "./SpeakV1Request.js"; diff --git a/src/api/resources/speak/resources/v1/resources/audio/index.ts b/src/api/resources/speak/resources/v1/resources/audio/index.ts new file mode 100644 index 00000000..f095e147 --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/index.ts @@ -0,0 +1,2 @@ +export * from "./types/index.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestCallbackMethod.ts b/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestCallbackMethod.ts new file mode 100644 index 00000000..f60e1051 --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestCallbackMethod.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type AudioGenerateRequestCallbackMethod = "POST" | "PUT"; +export const AudioGenerateRequestCallbackMethod = { + Post: "POST", + Put: "PUT", +} as const; diff --git a/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestContainer.ts b/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestContainer.ts new file mode 100644 index 00000000..d56e7bf9 --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestContainer.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type AudioGenerateRequestContainer = "none" | "wav" | "ogg"; +export const AudioGenerateRequestContainer = { + None: "none", + Wav: "wav", + Ogg: "ogg", +} as const; diff --git a/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestEncoding.ts b/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestEncoding.ts new file mode 100644 index 00000000..44caddbc --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestEncoding.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type AudioGenerateRequestEncoding = "linear16" | "flac" | "mulaw" | "alaw" | "mp3" | "opus" | "aac"; +export const AudioGenerateRequestEncoding = { + Linear16: "linear16", + Flac: "flac", + Mulaw: "mulaw", + Alaw: "alaw", + Mp3: "mp3", + Opus: "opus", + Aac: "aac", +} as const; diff --git a/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestModel.ts b/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestModel.ts new file mode 100644 index 00000000..603ccc98 --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/types/AudioGenerateRequestModel.ts @@ -0,0 +1,133 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type AudioGenerateRequestModel = + | "aura-asteria-en" + | "aura-luna-en" + | "aura-stella-en" + | "aura-athena-en" + | "aura-hera-en" + | "aura-orion-en" + | "aura-arcas-en" + | "aura-perseus-en" + | "aura-angus-en" + | "aura-orpheus-en" + | "aura-helios-en" + | "aura-zeus-en" + | "aura-2-amalthea-en" + | "aura-2-andromeda-en" + | "aura-2-apollo-en" + | "aura-2-arcas-en" + | "aura-2-aries-en" + | "aura-2-asteria-en" + | "aura-2-athena-en" + | "aura-2-atlas-en" + | "aura-2-aurora-en" + | "aura-2-callista-en" + | "aura-2-cordelia-en" + | "aura-2-cora-en" + | "aura-2-delia-en" + | "aura-2-draco-en" + | "aura-2-electra-en" + | "aura-2-harmonia-en" + | "aura-2-helena-en" + | "aura-2-hera-en" + | "aura-2-hermes-en" + | "aura-2-hyperion-en" + | "aura-2-iris-en" + | "aura-2-janus-en" + | "aura-2-juno-en" + | "aura-2-jupiter-en" + | "aura-2-luna-en" + | "aura-2-mars-en" + | "aura-2-minerva-en" + | "aura-2-neptune-en" + | "aura-2-odysseus-en" + | "aura-2-ophelia-en" + | "aura-2-orion-en" + | "aura-2-orpheus-en" + | "aura-2-pandora-en" + | "aura-2-phoebe-en" + | "aura-2-pluto-en" + | "aura-2-saturn-en" + | "aura-2-selene-en" + | "aura-2-thalia-en" + | "aura-2-theia-en" + | "aura-2-vesta-en" + | "aura-2-zeus-en" + | "aura-2-sirio-es" + | "aura-2-nestor-es" + | "aura-2-carina-es" + | "aura-2-celeste-es" + | "aura-2-alvaro-es" + | "aura-2-diana-es" + | "aura-2-aquila-es" + | "aura-2-selena-es" + | "aura-2-estrella-es" + | "aura-2-javier-es"; +export const AudioGenerateRequestModel = { + AuraAsteriaEn: "aura-asteria-en", + AuraLunaEn: "aura-luna-en", + AuraStellaEn: "aura-stella-en", + AuraAthenaEn: "aura-athena-en", + AuraHeraEn: "aura-hera-en", + AuraOrionEn: "aura-orion-en", + AuraArcasEn: "aura-arcas-en", + AuraPerseusEn: "aura-perseus-en", + AuraAngusEn: "aura-angus-en", + AuraOrpheusEn: "aura-orpheus-en", + AuraHeliosEn: "aura-helios-en", + AuraZeusEn: "aura-zeus-en", + Aura2AmaltheaEn: "aura-2-amalthea-en", + Aura2AndromedaEn: "aura-2-andromeda-en", + Aura2ApolloEn: "aura-2-apollo-en", + Aura2ArcasEn: "aura-2-arcas-en", + Aura2AriesEn: "aura-2-aries-en", + Aura2AsteriaEn: "aura-2-asteria-en", + Aura2AthenaEn: "aura-2-athena-en", + Aura2AtlasEn: "aura-2-atlas-en", + Aura2AuroraEn: "aura-2-aurora-en", + Aura2CallistaEn: "aura-2-callista-en", + Aura2CordeliaEn: "aura-2-cordelia-en", + Aura2CoraEn: "aura-2-cora-en", + Aura2DeliaEn: "aura-2-delia-en", + Aura2DracoEn: "aura-2-draco-en", + Aura2ElectraEn: "aura-2-electra-en", + Aura2HarmoniaEn: "aura-2-harmonia-en", + Aura2HelenaEn: "aura-2-helena-en", + Aura2HeraEn: "aura-2-hera-en", + Aura2HermesEn: "aura-2-hermes-en", + Aura2HyperionEn: "aura-2-hyperion-en", + Aura2IrisEn: "aura-2-iris-en", + Aura2JanusEn: "aura-2-janus-en", + Aura2JunoEn: "aura-2-juno-en", + Aura2JupiterEn: "aura-2-jupiter-en", + Aura2LunaEn: "aura-2-luna-en", + Aura2MarsEn: "aura-2-mars-en", + Aura2MinervaEn: "aura-2-minerva-en", + Aura2NeptuneEn: "aura-2-neptune-en", + Aura2OdysseusEn: "aura-2-odysseus-en", + Aura2OpheliaEn: "aura-2-ophelia-en", + Aura2OrionEn: "aura-2-orion-en", + Aura2OrpheusEn: "aura-2-orpheus-en", + Aura2PandoraEn: "aura-2-pandora-en", + Aura2PhoebeEn: "aura-2-phoebe-en", + Aura2PlutoEn: "aura-2-pluto-en", + Aura2SaturnEn: "aura-2-saturn-en", + Aura2SeleneEn: "aura-2-selene-en", + Aura2ThaliaEn: "aura-2-thalia-en", + Aura2TheiaEn: "aura-2-theia-en", + Aura2VestaEn: "aura-2-vesta-en", + Aura2ZeusEn: "aura-2-zeus-en", + Aura2SirioEs: "aura-2-sirio-es", + Aura2NestorEs: "aura-2-nestor-es", + Aura2CarinaEs: "aura-2-carina-es", + Aura2CelesteEs: "aura-2-celeste-es", + Aura2AlvaroEs: "aura-2-alvaro-es", + Aura2DianaEs: "aura-2-diana-es", + Aura2AquilaEs: "aura-2-aquila-es", + Aura2SelenaEs: "aura-2-selena-es", + Aura2EstrellaEs: "aura-2-estrella-es", + Aura2JavierEs: "aura-2-javier-es", +} as const; diff --git a/src/api/resources/speak/resources/v1/resources/audio/types/index.ts b/src/api/resources/speak/resources/v1/resources/audio/types/index.ts new file mode 100644 index 00000000..f62341ab --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/audio/types/index.ts @@ -0,0 +1,4 @@ +export * from "./AudioGenerateRequestCallbackMethod.js"; +export * from "./AudioGenerateRequestContainer.js"; +export * from "./AudioGenerateRequestEncoding.js"; +export * from "./AudioGenerateRequestModel.js"; diff --git a/src/api/resources/speak/resources/v1/resources/index.ts b/src/api/resources/speak/resources/v1/resources/index.ts new file mode 100644 index 00000000..7d405097 --- /dev/null +++ b/src/api/resources/speak/resources/v1/resources/index.ts @@ -0,0 +1,3 @@ +export * as audio from "./audio/index.js"; +export * from "./audio/types/index.js"; +export * from "./audio/client/requests/index.js"; diff --git a/src/api/types/AgentThinkModelsV1Response.ts b/src/api/types/AgentThinkModelsV1Response.ts new file mode 100644 index 00000000..88e5f6f7 --- /dev/null +++ b/src/api/types/AgentThinkModelsV1Response.ts @@ -0,0 +1,58 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface AgentThinkModelsV1Response { + models: AgentThinkModelsV1Response.Models.Item[]; +} + +export namespace AgentThinkModelsV1Response { + export type Models = Models.Item[]; + + export namespace Models { + export type Item = + /** + * OpenAI models */ + | { + id: + | "gpt-5" + | "gpt-5-mini" + | "gpt-5-nano" + | "gpt-4.1" + | "gpt-4.1-mini" + | "gpt-4.1-nano" + | "gpt-4o" + | "gpt-4o-mini"; + name: string; + provider: "open_ai"; + } + /** + * Anthropic models */ + | { + id: "claude-3-5-haiku-latest" | "claude-sonnet-4-20250514"; + name: string; + provider: "anthropic"; + } + /** + * Google models */ + | { + id: "gemini-2.5-flash" | "gemini-2.0-flash" | "gemini-2.0-flash-lite"; + name: string; + provider: "google"; + } + /** + * Groq models */ + | { + id: "openai/gpt-oss-20b"; + name: string; + provider: "groq"; + } + /** + * AWS Bedrock models (custom models accepted) */ + | { + id: string; + name: string; + provider: "aws_bedrock"; + }; + } +} diff --git a/src/api/types/BillingBreakdownV1Response.ts b/src/api/types/BillingBreakdownV1Response.ts new file mode 100644 index 00000000..f0c5782b --- /dev/null +++ b/src/api/types/BillingBreakdownV1Response.ts @@ -0,0 +1,48 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface BillingBreakdownV1Response { + /** Start date of the billing summmary period */ + start: string; + /** End date of the billing summary period */ + end: string; + resolution: BillingBreakdownV1Response.Resolution; + results: BillingBreakdownV1Response.Results.Item[]; +} + +export namespace BillingBreakdownV1Response { + export interface Resolution { + /** Time unit for the resolution */ + units: string; + /** Amount of units */ + amount: number; + } + + export type Results = Results.Item[]; + + export namespace Results { + export interface Item { + /** USD cost of the billing for this grouping */ + dollars: number; + grouping: Item.Grouping; + } + + export namespace Item { + export interface Grouping { + /** Start date for this group */ + start?: string; + /** End date for this group */ + end?: string; + /** Optional accessor identifier, null unless grouped by accessor. */ + accessor?: string; + /** Optional deployment identifier, null unless grouped by deployment. */ + deployment?: string; + /** Optional line item identifier, null unless grouped by line item. */ + line_item?: string; + /** Optional list of tags, null unless grouped by tags. */ + tags?: string[]; + } + } + } +} diff --git a/src/api/types/CreateKeyV1RequestOne.ts b/src/api/types/CreateKeyV1RequestOne.ts new file mode 100644 index 00000000..9f970749 --- /dev/null +++ b/src/api/types/CreateKeyV1RequestOne.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type CreateKeyV1RequestOne = unknown; diff --git a/src/api/types/CreateKeyV1Response.ts b/src/api/types/CreateKeyV1Response.ts new file mode 100644 index 00000000..de00bf53 --- /dev/null +++ b/src/api/types/CreateKeyV1Response.ts @@ -0,0 +1,21 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * API key created + */ +export interface CreateKeyV1Response { + /** The unique identifier of the API key */ + api_key_id?: string; + /** The API key */ + key?: string; + /** A comment for the API key */ + comment?: string; + /** The scopes for the API key */ + scopes?: string[]; + /** The tags for the API key */ + tags?: string[]; + /** The expiration date of the API key */ + expiration_date?: string; +} diff --git a/src/api/types/CreateProjectDistributionCredentialsV1Response.ts b/src/api/types/CreateProjectDistributionCredentialsV1Response.ts new file mode 100644 index 00000000..e74f6a42 --- /dev/null +++ b/src/api/types/CreateProjectDistributionCredentialsV1Response.ts @@ -0,0 +1,30 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface CreateProjectDistributionCredentialsV1Response { + member: CreateProjectDistributionCredentialsV1Response.Member; + distribution_credentials: CreateProjectDistributionCredentialsV1Response.DistributionCredentials; +} + +export namespace CreateProjectDistributionCredentialsV1Response { + export interface Member { + /** Unique identifier for the member */ + member_id: string; + /** Email address of the member */ + email: string; + } + + export interface DistributionCredentials { + /** Unique identifier for the distribution credentials */ + distribution_credentials_id: string; + /** The provider of the distribution service */ + provider: string; + /** Optional comment about the credentials */ + comment?: string; + /** List of permission scopes for the credentials */ + scopes: string[]; + /** Timestamp when the credentials were created */ + created: string; + } +} diff --git a/src/api/types/CreateProjectInviteV1Response.ts b/src/api/types/CreateProjectInviteV1Response.ts new file mode 100644 index 00000000..ae3d5779 --- /dev/null +++ b/src/api/types/CreateProjectInviteV1Response.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface CreateProjectInviteV1Response { + /** confirmation message */ + message?: string; +} diff --git a/src/api/types/DeleteProjectInviteV1Response.ts b/src/api/types/DeleteProjectInviteV1Response.ts new file mode 100644 index 00000000..5f395912 --- /dev/null +++ b/src/api/types/DeleteProjectInviteV1Response.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface DeleteProjectInviteV1Response { + /** confirmation message */ + message?: string; +} diff --git a/src/api/types/DeleteProjectKeyV1Response.ts b/src/api/types/DeleteProjectKeyV1Response.ts new file mode 100644 index 00000000..52414476 --- /dev/null +++ b/src/api/types/DeleteProjectKeyV1Response.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface DeleteProjectKeyV1Response { + message?: string; +} diff --git a/src/api/types/DeleteProjectMemberV1Response.ts b/src/api/types/DeleteProjectMemberV1Response.ts new file mode 100644 index 00000000..36300976 --- /dev/null +++ b/src/api/types/DeleteProjectMemberV1Response.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface DeleteProjectMemberV1Response { + /** confirmation message */ + message?: string; +} diff --git a/src/api/types/DeleteProjectV1Response.ts b/src/api/types/DeleteProjectV1Response.ts new file mode 100644 index 00000000..3ef0e036 --- /dev/null +++ b/src/api/types/DeleteProjectV1Response.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface DeleteProjectV1Response { + /** Confirmation message */ + message?: string; +} diff --git a/src/api/types/ErrorResponse.ts b/src/api/types/ErrorResponse.ts new file mode 100644 index 00000000..1642665a --- /dev/null +++ b/src/api/types/ErrorResponse.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +export type ErrorResponse = + | Deepgram.ErrorResponseTextError + | Deepgram.ErrorResponseLegacyError + | Deepgram.ErrorResponseModernError; diff --git a/src/api/types/ErrorResponseLegacyError.ts b/src/api/types/ErrorResponseLegacyError.ts new file mode 100644 index 00000000..1546bfc9 --- /dev/null +++ b/src/api/types/ErrorResponseLegacyError.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ErrorResponseLegacyError { + /** The error code */ + err_code?: string; + /** The error message */ + err_msg?: string; + /** The request ID */ + request_id?: string; +} diff --git a/src/api/types/ErrorResponseModernError.ts b/src/api/types/ErrorResponseModernError.ts new file mode 100644 index 00000000..3183c525 --- /dev/null +++ b/src/api/types/ErrorResponseModernError.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ErrorResponseModernError { + /** The category of the error */ + category?: string; + /** A message about the error */ + message?: string; + /** A description of the error */ + details?: string; + /** The unique identifier of the request */ + request_id?: string; +} diff --git a/src/api/types/ErrorResponseTextError.ts b/src/api/types/ErrorResponseTextError.ts new file mode 100644 index 00000000..aad5b01f --- /dev/null +++ b/src/api/types/ErrorResponseTextError.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ErrorResponseTextError = string; diff --git a/src/api/types/GetModelV1Response.ts b/src/api/types/GetModelV1Response.ts new file mode 100644 index 00000000..2361bf78 --- /dev/null +++ b/src/api/types/GetModelV1Response.ts @@ -0,0 +1,35 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type GetModelV1Response = + | { + name?: string | undefined; + canonical_name?: string | undefined; + architecture?: string | undefined; + languages?: string[] | undefined; + version?: string | undefined; + uuid?: string | undefined; + batch?: boolean | undefined; + streaming?: boolean | undefined; + formatted_output?: boolean | undefined; + } + | { + name?: string | undefined; + canonical_name?: string | undefined; + architecture?: string | undefined; + languages?: string[] | undefined; + version?: string | undefined; + uuid?: string | undefined; + metadata?: + | { + accent?: string | undefined; + age?: string | undefined; + color?: string | undefined; + image?: string | undefined; + sample?: string | undefined; + tags?: string[] | undefined; + use_cases?: string[] | undefined; + } + | undefined; + }; diff --git a/src/api/types/GetProjectBalanceV1Response.ts b/src/api/types/GetProjectBalanceV1Response.ts new file mode 100644 index 00000000..bd225f96 --- /dev/null +++ b/src/api/types/GetProjectBalanceV1Response.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetProjectBalanceV1Response { + /** The unique identifier of the balance */ + balance_id?: string; + /** The amount of the balance */ + amount?: number; + /** The units of the balance, such as "USD" */ + units?: string; + /** Description or reference of the purchase */ + purchase_order_id?: string; +} diff --git a/src/api/types/GetProjectDistributionCredentialsV1Response.ts b/src/api/types/GetProjectDistributionCredentialsV1Response.ts new file mode 100644 index 00000000..7101bb08 --- /dev/null +++ b/src/api/types/GetProjectDistributionCredentialsV1Response.ts @@ -0,0 +1,30 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetProjectDistributionCredentialsV1Response { + member: GetProjectDistributionCredentialsV1Response.Member; + distribution_credentials: GetProjectDistributionCredentialsV1Response.DistributionCredentials; +} + +export namespace GetProjectDistributionCredentialsV1Response { + export interface Member { + /** Unique identifier for the member */ + member_id: string; + /** Email address of the member */ + email: string; + } + + export interface DistributionCredentials { + /** Unique identifier for the distribution credentials */ + distribution_credentials_id: string; + /** The provider of the distribution service */ + provider: string; + /** Optional comment about the credentials */ + comment?: string; + /** List of permission scopes for the credentials */ + scopes: string[]; + /** Timestamp when the credentials were created */ + created: string; + } +} diff --git a/src/api/types/GetProjectKeyV1Response.ts b/src/api/types/GetProjectKeyV1Response.ts new file mode 100644 index 00000000..b41d973a --- /dev/null +++ b/src/api/types/GetProjectKeyV1Response.ts @@ -0,0 +1,34 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetProjectKeyV1Response { + item?: GetProjectKeyV1Response.Item; +} + +export namespace GetProjectKeyV1Response { + export interface Item { + member?: Item.Member; + } + + export namespace Item { + export interface Member { + member_id?: string; + email?: string; + first_name?: string; + last_name?: string; + api_key?: Member.ApiKey; + } + + export namespace Member { + export interface ApiKey { + api_key_id?: string; + comment?: string; + scopes?: string[]; + tags?: string[]; + expiration_date?: string; + created?: string; + } + } + } +} diff --git a/src/api/types/GetProjectRequestV1Response.ts b/src/api/types/GetProjectRequestV1Response.ts new file mode 100644 index 00000000..c4d2177d --- /dev/null +++ b/src/api/types/GetProjectRequestV1Response.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +export interface GetProjectRequestV1Response { + request?: Deepgram.ProjectRequestResponse; +} diff --git a/src/api/types/GetProjectV1Response.ts b/src/api/types/GetProjectV1Response.ts new file mode 100644 index 00000000..d1f85aeb --- /dev/null +++ b/src/api/types/GetProjectV1Response.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GetProjectV1Response { + /** The unique identifier of the project */ + project_id?: string; + /** Model Improvement Program opt-out */ + mip_opt_out?: boolean; + /** The name of the project */ + name?: string; +} diff --git a/src/api/types/GrantV1Response.ts b/src/api/types/GrantV1Response.ts new file mode 100644 index 00000000..aa6d8e5d --- /dev/null +++ b/src/api/types/GrantV1Response.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface GrantV1Response { + /** JSON Web Token (JWT) */ + access_token: string; + /** Time in seconds until the JWT expires */ + expires_in?: number; +} diff --git a/src/api/types/LeaveProjectV1Response.ts b/src/api/types/LeaveProjectV1Response.ts new file mode 100644 index 00000000..33bc3625 --- /dev/null +++ b/src/api/types/LeaveProjectV1Response.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface LeaveProjectV1Response { + /** confirmation message */ + message?: string; +} diff --git a/src/api/types/ListModelsV1Response.ts b/src/api/types/ListModelsV1Response.ts new file mode 100644 index 00000000..5fadee3e --- /dev/null +++ b/src/api/types/ListModelsV1Response.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +export interface ListModelsV1Response { + stt?: Deepgram.ListModelsV1ResponseSttModels[]; + tts?: Deepgram.ListModelsV1ResponseTtsModels[]; +} diff --git a/src/api/types/ListModelsV1ResponseSttModels.ts b/src/api/types/ListModelsV1ResponseSttModels.ts new file mode 100644 index 00000000..4c950faa --- /dev/null +++ b/src/api/types/ListModelsV1ResponseSttModels.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListModelsV1ResponseSttModels { + name?: string; + canonical_name?: string; + architecture?: string; + languages?: string[]; + version?: string; + uuid?: string; + batch?: boolean; + streaming?: boolean; + formatted_output?: boolean; +} diff --git a/src/api/types/ListModelsV1ResponseTtsModels.ts b/src/api/types/ListModelsV1ResponseTtsModels.ts new file mode 100644 index 00000000..889bb761 --- /dev/null +++ b/src/api/types/ListModelsV1ResponseTtsModels.ts @@ -0,0 +1,25 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListModelsV1ResponseTtsModels { + name?: string; + canonical_name?: string; + architecture?: string; + languages?: string[]; + version?: string; + uuid?: string; + metadata?: ListModelsV1ResponseTtsModels.Metadata; +} + +export namespace ListModelsV1ResponseTtsModels { + export interface Metadata { + accent?: string; + age?: string; + color?: string; + image?: string; + sample?: string; + tags?: string[]; + use_cases?: string[]; + } +} diff --git a/src/api/types/ListProjectBalancesV1Response.ts b/src/api/types/ListProjectBalancesV1Response.ts new file mode 100644 index 00000000..16ee4477 --- /dev/null +++ b/src/api/types/ListProjectBalancesV1Response.ts @@ -0,0 +1,24 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListProjectBalancesV1Response { + balances?: ListProjectBalancesV1Response.Balances.Item[]; +} + +export namespace ListProjectBalancesV1Response { + export type Balances = Balances.Item[]; + + export namespace Balances { + export interface Item { + /** The unique identifier of the balance */ + balance_id?: string; + /** The amount of the balance */ + amount?: number; + /** The units of the balance, such as "USD" */ + units?: string; + /** Description or reference of the purchase */ + purchase_order_id?: string; + } + } +} diff --git a/src/api/types/ListProjectDistributionCredentialsV1Response.ts b/src/api/types/ListProjectDistributionCredentialsV1Response.ts new file mode 100644 index 00000000..c8331401 --- /dev/null +++ b/src/api/types/ListProjectDistributionCredentialsV1Response.ts @@ -0,0 +1,41 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListProjectDistributionCredentialsV1Response { + /** Array of distribution credentials with associated member information */ + distribution_credentials?: ListProjectDistributionCredentialsV1Response.DistributionCredentials.Item[]; +} + +export namespace ListProjectDistributionCredentialsV1Response { + export type DistributionCredentials = DistributionCredentials.Item[]; + + export namespace DistributionCredentials { + export interface Item { + member: Item.Member; + distribution_credentials: Item.DistributionCredentials; + } + + export namespace Item { + export interface Member { + /** Unique identifier for the member */ + member_id: string; + /** Email address of the member */ + email: string; + } + + export interface DistributionCredentials { + /** Unique identifier for the distribution credentials */ + distribution_credentials_id: string; + /** The provider of the distribution service */ + provider: string; + /** Optional comment about the credentials */ + comment?: string; + /** List of permission scopes for the credentials */ + scopes: string[]; + /** Timestamp when the credentials were created */ + created: string; + } + } + } +} diff --git a/src/api/types/ListProjectInvitesV1Response.ts b/src/api/types/ListProjectInvitesV1Response.ts new file mode 100644 index 00000000..80f8ddca --- /dev/null +++ b/src/api/types/ListProjectInvitesV1Response.ts @@ -0,0 +1,20 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListProjectInvitesV1Response { + invites?: ListProjectInvitesV1Response.Invites.Item[]; +} + +export namespace ListProjectInvitesV1Response { + export type Invites = Invites.Item[]; + + export namespace Invites { + export interface Item { + /** The email address of the invitee */ + email?: string; + /** The scope of the invitee */ + scope?: string; + } + } +} diff --git a/src/api/types/ListProjectKeysV1Response.ts b/src/api/types/ListProjectKeysV1Response.ts new file mode 100644 index 00000000..7614a574 --- /dev/null +++ b/src/api/types/ListProjectKeysV1Response.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListProjectKeysV1Response { + api_keys?: ListProjectKeysV1Response.ApiKeys.Item[]; +} + +export namespace ListProjectKeysV1Response { + export type ApiKeys = ApiKeys.Item[]; + + export namespace ApiKeys { + export interface Item { + member?: Item.Member; + api_key?: Item.ApiKey; + } + + export namespace Item { + export interface Member { + member_id?: string; + email?: string; + } + + export interface ApiKey { + api_key_id?: string; + comment?: string; + scopes?: string[]; + created?: string; + } + } + } +} diff --git a/src/api/types/ListProjectMemberScopesV1Response.ts b/src/api/types/ListProjectMemberScopesV1Response.ts new file mode 100644 index 00000000..609b8709 --- /dev/null +++ b/src/api/types/ListProjectMemberScopesV1Response.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListProjectMemberScopesV1Response { + /** The API scopes of the member */ + scopes?: string[]; +} diff --git a/src/api/types/ListProjectMembersV1Response.ts b/src/api/types/ListProjectMembersV1Response.ts new file mode 100644 index 00000000..547a540c --- /dev/null +++ b/src/api/types/ListProjectMembersV1Response.ts @@ -0,0 +1,19 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListProjectMembersV1Response { + members?: ListProjectMembersV1Response.Members.Item[]; +} + +export namespace ListProjectMembersV1Response { + export type Members = Members.Item[]; + + export namespace Members { + export interface Item { + /** The unique identifier of the member */ + member_id?: string; + email?: string; + } + } +} diff --git a/src/api/types/ListProjectPurchasesV1Response.ts b/src/api/types/ListProjectPurchasesV1Response.ts new file mode 100644 index 00000000..e7d81a07 --- /dev/null +++ b/src/api/types/ListProjectPurchasesV1Response.ts @@ -0,0 +1,22 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListProjectPurchasesV1Response { + orders?: ListProjectPurchasesV1Response.Orders.Item[]; +} + +export namespace ListProjectPurchasesV1Response { + export type Orders = Orders.Item[]; + + export namespace Orders { + export interface Item { + order_id?: string; + expiration?: string; + created?: string; + amount?: number; + units?: string; + order_type?: string; + } + } +} diff --git a/src/api/types/ListProjectRequestsV1Response.ts b/src/api/types/ListProjectRequestsV1Response.ts new file mode 100644 index 00000000..7d9b5501 --- /dev/null +++ b/src/api/types/ListProjectRequestsV1Response.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +export interface ListProjectRequestsV1Response { + /** The page number of the paginated response */ + page?: number; + /** The number of results per page */ + limit?: number; + requests?: Deepgram.ProjectRequestResponse[]; +} diff --git a/src/api/types/ListProjectsV1Response.ts b/src/api/types/ListProjectsV1Response.ts new file mode 100644 index 00000000..77354176 --- /dev/null +++ b/src/api/types/ListProjectsV1Response.ts @@ -0,0 +1,20 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListProjectsV1Response { + projects?: ListProjectsV1Response.Projects.Item[]; +} + +export namespace ListProjectsV1Response { + export type Projects = Projects.Item[]; + + export namespace Projects { + export interface Item { + /** The unique identifier of the project */ + project_id?: string; + /** The name of the project */ + name?: string; + } + } +} diff --git a/src/api/types/ListenV1AcceptedResponse.ts b/src/api/types/ListenV1AcceptedResponse.ts new file mode 100644 index 00000000..7ad8c8ad --- /dev/null +++ b/src/api/types/ListenV1AcceptedResponse.ts @@ -0,0 +1,11 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Accepted response for asynchronous transcription requests + */ +export interface ListenV1AcceptedResponse { + /** Unique identifier for tracking the asynchronous request */ + request_id: string; +} diff --git a/src/api/types/ListenV1Callback.ts b/src/api/types/ListenV1Callback.ts new file mode 100644 index 00000000..6a46092f --- /dev/null +++ b/src/api/types/ListenV1Callback.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Callback = unknown; diff --git a/src/api/types/ListenV1CallbackMethod.ts b/src/api/types/ListenV1CallbackMethod.ts new file mode 100644 index 00000000..1c326c70 --- /dev/null +++ b/src/api/types/ListenV1CallbackMethod.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * HTTP method by which the callback request will be made + */ +export type ListenV1CallbackMethod = "POST" | "GET" | "PUT" | "DELETE"; +export const ListenV1CallbackMethod = { + Post: "POST", + Get: "GET", + Put: "PUT", + Delete: "DELETE", +} as const; diff --git a/src/api/types/ListenV1Channels.ts b/src/api/types/ListenV1Channels.ts new file mode 100644 index 00000000..16e51e25 --- /dev/null +++ b/src/api/types/ListenV1Channels.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Channels = unknown; diff --git a/src/api/types/ListenV1Diarize.ts b/src/api/types/ListenV1Diarize.ts new file mode 100644 index 00000000..c77bfeae --- /dev/null +++ b/src/api/types/ListenV1Diarize.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Defaults to `false`. Recognize speaker changes. Each word in the transcript will be assigned a speaker number starting at 0 + */ +export type ListenV1Diarize = "true" | "false"; +export const ListenV1Diarize = { + True: "true", + False: "false", +} as const; diff --git a/src/api/types/ListenV1Dictation.ts b/src/api/types/ListenV1Dictation.ts new file mode 100644 index 00000000..4214fa0f --- /dev/null +++ b/src/api/types/ListenV1Dictation.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Identify and extract key entities from content in submitted audio + */ +export type ListenV1Dictation = "true" | "false"; +export const ListenV1Dictation = { + True: "true", + False: "false", +} as const; diff --git a/src/api/types/ListenV1Encoding.ts b/src/api/types/ListenV1Encoding.ts new file mode 100644 index 00000000..e5d110b6 --- /dev/null +++ b/src/api/types/ListenV1Encoding.ts @@ -0,0 +1,32 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Specify the expected encoding of your submitted audio + */ +export type ListenV1Encoding = + | "linear16" + | "linear32" + | "flac" + | "alaw" + | "mulaw" + | "amr-nb" + | "amr-wb" + | "opus" + | "ogg-opus" + | "speex" + | "g729"; +export const ListenV1Encoding = { + Linear16: "linear16", + Linear32: "linear32", + Flac: "flac", + Alaw: "alaw", + Mulaw: "mulaw", + AmrNb: "amr-nb", + AmrWb: "amr-wb", + Opus: "opus", + OggOpus: "ogg-opus", + Speex: "speex", + G729: "g729", +} as const; diff --git a/src/api/types/ListenV1Endpointing.ts b/src/api/types/ListenV1Endpointing.ts new file mode 100644 index 00000000..7042b6d4 --- /dev/null +++ b/src/api/types/ListenV1Endpointing.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Endpointing = unknown; diff --git a/src/api/types/ListenV1Extra.ts b/src/api/types/ListenV1Extra.ts new file mode 100644 index 00000000..bcc05220 --- /dev/null +++ b/src/api/types/ListenV1Extra.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Extra = unknown; diff --git a/src/api/types/ListenV1InterimResults.ts b/src/api/types/ListenV1InterimResults.ts new file mode 100644 index 00000000..b9d80138 --- /dev/null +++ b/src/api/types/ListenV1InterimResults.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Specifies whether the streaming endpoint should provide ongoing transcription updates as more audio is received. When set to true, the endpoint sends continuous updates, meaning transcription results may evolve over time + */ +export type ListenV1InterimResults = "true" | "false"; +export const ListenV1InterimResults = { + True: "true", + False: "false", +} as const; diff --git a/src/api/types/ListenV1Keyterm.ts b/src/api/types/ListenV1Keyterm.ts new file mode 100644 index 00000000..9a5cb138 --- /dev/null +++ b/src/api/types/ListenV1Keyterm.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Keyterm = unknown; diff --git a/src/api/types/ListenV1Keywords.ts b/src/api/types/ListenV1Keywords.ts new file mode 100644 index 00000000..78702a13 --- /dev/null +++ b/src/api/types/ListenV1Keywords.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Keywords = unknown; diff --git a/src/api/types/ListenV1Language.ts b/src/api/types/ListenV1Language.ts new file mode 100644 index 00000000..166732ab --- /dev/null +++ b/src/api/types/ListenV1Language.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Language = unknown; diff --git a/src/api/types/ListenV1MipOptOut.ts b/src/api/types/ListenV1MipOptOut.ts new file mode 100644 index 00000000..3061010c --- /dev/null +++ b/src/api/types/ListenV1MipOptOut.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1MipOptOut = unknown; diff --git a/src/api/types/ListenV1Model.ts b/src/api/types/ListenV1Model.ts new file mode 100644 index 00000000..4e1b3385 --- /dev/null +++ b/src/api/types/ListenV1Model.ts @@ -0,0 +1,70 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * AI model to use for the transcription + */ +export type ListenV1Model = + | "nova-3" + | "nova-3-general" + | "nova-3-medical" + | "nova-2" + | "nova-2-general" + | "nova-2-meeting" + | "nova-2-finance" + | "nova-2-conversationalai" + | "nova-2-voicemail" + | "nova-2-video" + | "nova-2-medical" + | "nova-2-drivethru" + | "nova-2-automotive" + | "nova" + | "nova-general" + | "nova-phonecall" + | "nova-medical" + | "enhanced" + | "enhanced-general" + | "enhanced-meeting" + | "enhanced-phonecall" + | "enhanced-finance" + | "base" + | "meeting" + | "phonecall" + | "finance" + | "conversationalai" + | "voicemail" + | "video" + | "custom"; +export const ListenV1Model = { + Nova3: "nova-3", + Nova3General: "nova-3-general", + Nova3Medical: "nova-3-medical", + Nova2: "nova-2", + Nova2General: "nova-2-general", + Nova2Meeting: "nova-2-meeting", + Nova2Finance: "nova-2-finance", + Nova2Conversationalai: "nova-2-conversationalai", + Nova2Voicemail: "nova-2-voicemail", + Nova2Video: "nova-2-video", + Nova2Medical: "nova-2-medical", + Nova2Drivethru: "nova-2-drivethru", + Nova2Automotive: "nova-2-automotive", + Nova: "nova", + NovaGeneral: "nova-general", + NovaPhonecall: "nova-phonecall", + NovaMedical: "nova-medical", + Enhanced: "enhanced", + EnhancedGeneral: "enhanced-general", + EnhancedMeeting: "enhanced-meeting", + EnhancedPhonecall: "enhanced-phonecall", + EnhancedFinance: "enhanced-finance", + Base: "base", + Meeting: "meeting", + Phonecall: "phonecall", + Finance: "finance", + Conversationalai: "conversationalai", + Voicemail: "voicemail", + Video: "video", + Custom: "custom", +} as const; diff --git a/src/api/types/ListenV1Multichannel.ts b/src/api/types/ListenV1Multichannel.ts new file mode 100644 index 00000000..6fa0c96a --- /dev/null +++ b/src/api/types/ListenV1Multichannel.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Transcribe each audio channel independently + */ +export type ListenV1Multichannel = "true" | "false"; +export const ListenV1Multichannel = { + True: "true", + False: "false", +} as const; diff --git a/src/api/types/ListenV1Numerals.ts b/src/api/types/ListenV1Numerals.ts new file mode 100644 index 00000000..49f5b048 --- /dev/null +++ b/src/api/types/ListenV1Numerals.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Convert numbers from written format to numerical format + */ +export type ListenV1Numerals = "true" | "false"; +export const ListenV1Numerals = { + True: "true", + False: "false", +} as const; diff --git a/src/api/types/ListenV1ProfanityFilter.ts b/src/api/types/ListenV1ProfanityFilter.ts new file mode 100644 index 00000000..c846ab2d --- /dev/null +++ b/src/api/types/ListenV1ProfanityFilter.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Profanity Filter looks for recognized profanity and converts it to the nearest recognized non-profane word or removes it from the transcript completely + */ +export type ListenV1ProfanityFilter = "true" | "false"; +export const ListenV1ProfanityFilter = { + True: "true", + False: "false", +} as const; diff --git a/src/api/types/ListenV1Punctuate.ts b/src/api/types/ListenV1Punctuate.ts new file mode 100644 index 00000000..0086e1e2 --- /dev/null +++ b/src/api/types/ListenV1Punctuate.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Add punctuation and capitalization to the transcript + */ +export type ListenV1Punctuate = "true" | "false"; +export const ListenV1Punctuate = { + True: "true", + False: "false", +} as const; diff --git a/src/api/types/ListenV1Redact.ts b/src/api/types/ListenV1Redact.ts new file mode 100644 index 00000000..0ec94a22 --- /dev/null +++ b/src/api/types/ListenV1Redact.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Redaction removes sensitive information from your transcripts + */ +export type ListenV1Redact = "true" | "false" | "pci" | "numbers" | "aggressive_numbers" | "ssn"; +export const ListenV1Redact = { + True: "true", + False: "false", + Pci: "pci", + Numbers: "numbers", + AggressiveNumbers: "aggressive_numbers", + Ssn: "ssn", +} as const; diff --git a/src/api/types/ListenV1Replace.ts b/src/api/types/ListenV1Replace.ts new file mode 100644 index 00000000..3162888f --- /dev/null +++ b/src/api/types/ListenV1Replace.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Replace = unknown; diff --git a/src/api/types/ListenV1RequestFile.ts b/src/api/types/ListenV1RequestFile.ts new file mode 100644 index 00000000..bf2f64a2 --- /dev/null +++ b/src/api/types/ListenV1RequestFile.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Binary audio file to transcribe + */ +export type ListenV1RequestFile = string; diff --git a/src/api/types/ListenV1Response.ts b/src/api/types/ListenV1Response.ts new file mode 100644 index 00000000..836e4212 --- /dev/null +++ b/src/api/types/ListenV1Response.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +/** + * The standard transcription response + */ +export interface ListenV1Response { + metadata: Deepgram.ListenV1ResponseMetadata; + results: Deepgram.ListenV1ResponseResults; +} diff --git a/src/api/types/ListenV1ResponseMetadata.ts b/src/api/types/ListenV1ResponseMetadata.ts new file mode 100644 index 00000000..2ab42696 --- /dev/null +++ b/src/api/types/ListenV1ResponseMetadata.ts @@ -0,0 +1,45 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListenV1ResponseMetadata { + transaction_key?: string; + request_id: string; + sha256: string; + created: string; + duration: number; + channels: number; + models: string[]; + model_info: Record; + summary_info?: ListenV1ResponseMetadata.SummaryInfo; + sentiment_info?: ListenV1ResponseMetadata.SentimentInfo; + topics_info?: ListenV1ResponseMetadata.TopicsInfo; + intents_info?: ListenV1ResponseMetadata.IntentsInfo; + tags?: string[]; +} + +export namespace ListenV1ResponseMetadata { + export interface SummaryInfo { + model_uuid?: string; + input_tokens?: number; + output_tokens?: number; + } + + export interface SentimentInfo { + model_uuid?: string; + input_tokens?: number; + output_tokens?: number; + } + + export interface TopicsInfo { + model_uuid?: string; + input_tokens?: number; + output_tokens?: number; + } + + export interface IntentsInfo { + model_uuid?: string; + input_tokens?: number; + output_tokens?: number; + } +} diff --git a/src/api/types/ListenV1ResponseResults.ts b/src/api/types/ListenV1ResponseResults.ts new file mode 100644 index 00000000..38119c14 --- /dev/null +++ b/src/api/types/ListenV1ResponseResults.ts @@ -0,0 +1,14 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +export interface ListenV1ResponseResults { + channels: Deepgram.ListenV1ResponseResultsChannels; + utterances?: Deepgram.ListenV1ResponseResultsUtterances; + summary?: Deepgram.ListenV1ResponseResultsSummary; + topics?: Deepgram.SharedTopics; + intents?: Deepgram.SharedIntents; + sentiments?: Deepgram.SharedSentiments; +} diff --git a/src/api/types/ListenV1ResponseResultsChannels.ts b/src/api/types/ListenV1ResponseResultsChannels.ts new file mode 100644 index 00000000..465d7243 --- /dev/null +++ b/src/api/types/ListenV1ResponseResultsChannels.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +export type ListenV1ResponseResultsChannels = Deepgram.ListenV1ResponseResultsChannelsItem[]; diff --git a/src/api/types/ListenV1ResponseResultsChannelsItem.ts b/src/api/types/ListenV1ResponseResultsChannelsItem.ts new file mode 100644 index 00000000..a5d66424 --- /dev/null +++ b/src/api/types/ListenV1ResponseResultsChannelsItem.ts @@ -0,0 +1,111 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListenV1ResponseResultsChannelsItem { + search?: ListenV1ResponseResultsChannelsItem.Search.Item[]; + alternatives?: ListenV1ResponseResultsChannelsItem.Alternatives.Item[]; + detected_language?: string; +} + +export namespace ListenV1ResponseResultsChannelsItem { + export type Search = Search.Item[]; + + export namespace Search { + export interface Item { + query?: string; + hits?: Item.Hits.Item[]; + } + + export namespace Item { + export type Hits = Hits.Item[]; + + export namespace Hits { + export interface Item { + confidence?: number; + start?: number; + end?: number; + snippet?: string; + } + } + } + } + + export type Alternatives = Alternatives.Item[]; + + export namespace Alternatives { + export interface Item { + transcript?: string; + confidence?: number; + words?: Item.Words.Item[]; + paragraphs?: Item.Paragraphs; + summaries?: Item.Summaries.Item[]; + topics?: Item.Topics.Item[]; + } + + export namespace Item { + export type Words = Words.Item[]; + + export namespace Words { + export interface Item { + word?: string; + start?: number; + end?: number; + confidence?: number; + } + } + + export interface Paragraphs { + transcript?: string; + paragraphs?: Paragraphs.Paragraphs.Item[]; + } + + export namespace Paragraphs { + export type Paragraphs = Paragraphs.Item[]; + + export namespace Paragraphs { + export interface Item { + sentences?: Item.Sentences.Item[]; + speaker?: number; + num_words?: number; + start?: number; + end?: number; + } + + export namespace Item { + export type Sentences = Sentences.Item[]; + + export namespace Sentences { + export interface Item { + text?: string; + start?: number; + end?: number; + } + } + } + } + } + + export type Summaries = Summaries.Item[]; + + export namespace Summaries { + export interface Item { + summary?: string; + start_word?: number; + end_word?: number; + } + } + + export type Topics = Topics.Item[]; + + export namespace Topics { + export interface Item { + text?: string; + start_word?: number; + end_word?: number; + topics?: string[]; + } + } + } + } +} diff --git a/src/api/types/ListenV1ResponseResultsSummary.ts b/src/api/types/ListenV1ResponseResultsSummary.ts new file mode 100644 index 00000000..1d04b6dd --- /dev/null +++ b/src/api/types/ListenV1ResponseResultsSummary.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListenV1ResponseResultsSummary { + result?: string; + short?: string; +} diff --git a/src/api/types/ListenV1ResponseResultsUtterances.ts b/src/api/types/ListenV1ResponseResultsUtterances.ts new file mode 100644 index 00000000..36357f3f --- /dev/null +++ b/src/api/types/ListenV1ResponseResultsUtterances.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +export type ListenV1ResponseResultsUtterances = Deepgram.ListenV1ResponseResultsUtterancesItem[]; diff --git a/src/api/types/ListenV1ResponseResultsUtterancesItem.ts b/src/api/types/ListenV1ResponseResultsUtterancesItem.ts new file mode 100644 index 00000000..351f43fa --- /dev/null +++ b/src/api/types/ListenV1ResponseResultsUtterancesItem.ts @@ -0,0 +1,30 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ListenV1ResponseResultsUtterancesItem { + start?: number; + end?: number; + confidence?: number; + channel?: number; + transcript?: string; + words?: ListenV1ResponseResultsUtterancesItem.Words.Item[]; + speaker?: number; + id?: string; +} + +export namespace ListenV1ResponseResultsUtterancesItem { + export type Words = Words.Item[]; + + export namespace Words { + export interface Item { + word?: string; + start?: number; + end?: number; + confidence?: number; + speaker?: number; + speaker_confidence?: number; + punctuated_word?: string; + } + } +} diff --git a/src/api/types/ListenV1SampleRate.ts b/src/api/types/ListenV1SampleRate.ts new file mode 100644 index 00000000..663b3ba9 --- /dev/null +++ b/src/api/types/ListenV1SampleRate.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1SampleRate = unknown; diff --git a/src/api/types/ListenV1Search.ts b/src/api/types/ListenV1Search.ts new file mode 100644 index 00000000..911f9d3c --- /dev/null +++ b/src/api/types/ListenV1Search.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Search = unknown; diff --git a/src/api/types/ListenV1SmartFormat.ts b/src/api/types/ListenV1SmartFormat.ts new file mode 100644 index 00000000..a584ba52 --- /dev/null +++ b/src/api/types/ListenV1SmartFormat.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Apply formatting to transcript output. When set to true, additional formatting will be applied to transcripts to improve readability + */ +export type ListenV1SmartFormat = "true" | "false"; +export const ListenV1SmartFormat = { + True: "true", + False: "false", +} as const; diff --git a/src/api/types/ListenV1Tag.ts b/src/api/types/ListenV1Tag.ts new file mode 100644 index 00000000..a145a9d5 --- /dev/null +++ b/src/api/types/ListenV1Tag.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Tag = unknown; diff --git a/src/api/types/ListenV1UtteranceEndMs.ts b/src/api/types/ListenV1UtteranceEndMs.ts new file mode 100644 index 00000000..ce5c2c25 --- /dev/null +++ b/src/api/types/ListenV1UtteranceEndMs.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1UtteranceEndMs = unknown; diff --git a/src/api/types/ListenV1VadEvents.ts b/src/api/types/ListenV1VadEvents.ts new file mode 100644 index 00000000..7dcdfe28 --- /dev/null +++ b/src/api/types/ListenV1VadEvents.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Indicates that speech has started. You'll begin receiving Speech Started messages upon speech starting + */ +export type ListenV1VadEvents = "true" | "false"; +export const ListenV1VadEvents = { + True: "true", + False: "false", +} as const; diff --git a/src/api/types/ListenV1Version.ts b/src/api/types/ListenV1Version.ts new file mode 100644 index 00000000..9e5f8c3a --- /dev/null +++ b/src/api/types/ListenV1Version.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV1Version = unknown; diff --git a/src/api/types/ListenV2EagerEotThreshold.ts b/src/api/types/ListenV2EagerEotThreshold.ts new file mode 100644 index 00000000..9272db16 --- /dev/null +++ b/src/api/types/ListenV2EagerEotThreshold.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV2EagerEotThreshold = unknown; diff --git a/src/api/types/ListenV2Encoding.ts b/src/api/types/ListenV2Encoding.ts new file mode 100644 index 00000000..a63bb351 --- /dev/null +++ b/src/api/types/ListenV2Encoding.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Encoding of the audio stream. Required if sending non-containerized/raw audio. If sending containerized audio, this parameter should be omitted. + */ +export type ListenV2Encoding = "linear16" | "linear32" | "mulaw" | "alaw" | "opus" | "ogg-opus"; +export const ListenV2Encoding = { + Linear16: "linear16", + Linear32: "linear32", + Mulaw: "mulaw", + Alaw: "alaw", + Opus: "opus", + OggOpus: "ogg-opus", +} as const; diff --git a/src/api/types/ListenV2EotThreshold.ts b/src/api/types/ListenV2EotThreshold.ts new file mode 100644 index 00000000..af8fa04a --- /dev/null +++ b/src/api/types/ListenV2EotThreshold.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV2EotThreshold = unknown; diff --git a/src/api/types/ListenV2EotTimeoutMs.ts b/src/api/types/ListenV2EotTimeoutMs.ts new file mode 100644 index 00000000..606a7872 --- /dev/null +++ b/src/api/types/ListenV2EotTimeoutMs.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV2EotTimeoutMs = unknown; diff --git a/src/api/types/ListenV2Keyterm.ts b/src/api/types/ListenV2Keyterm.ts new file mode 100644 index 00000000..fceb87a1 --- /dev/null +++ b/src/api/types/ListenV2Keyterm.ts @@ -0,0 +1,9 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Keyterm prompting can improve recognition of specialized terminology. + * Pass multiple keyterm query parameters to boost multiple keyterms. + */ +export type ListenV2Keyterm = string | string[]; diff --git a/src/api/types/ListenV2MipOptOut.ts b/src/api/types/ListenV2MipOptOut.ts new file mode 100644 index 00000000..467dab0b --- /dev/null +++ b/src/api/types/ListenV2MipOptOut.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV2MipOptOut = unknown; diff --git a/src/api/types/ListenV2Model.ts b/src/api/types/ListenV2Model.ts new file mode 100644 index 00000000..e01e6e26 --- /dev/null +++ b/src/api/types/ListenV2Model.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Defines the AI model used to process submitted audio. + */ +export type ListenV2Model = "flux-general-en"; diff --git a/src/api/types/ListenV2SampleRate.ts b/src/api/types/ListenV2SampleRate.ts new file mode 100644 index 00000000..2cd11e08 --- /dev/null +++ b/src/api/types/ListenV2SampleRate.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV2SampleRate = unknown; diff --git a/src/api/types/ListenV2Tag.ts b/src/api/types/ListenV2Tag.ts new file mode 100644 index 00000000..6515387c --- /dev/null +++ b/src/api/types/ListenV2Tag.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type ListenV2Tag = unknown; diff --git a/src/api/types/ProjectRequestResponse.ts b/src/api/types/ProjectRequestResponse.ts new file mode 100644 index 00000000..cb84782c --- /dev/null +++ b/src/api/types/ProjectRequestResponse.ts @@ -0,0 +1,27 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * A single request + */ +export interface ProjectRequestResponse { + /** The unique identifier of the request */ + request_id?: string; + /** The unique identifier of the project */ + project_uuid?: string; + /** The date and time the request was created */ + created?: string; + /** The API path of the request */ + path?: string; + /** The unique identifier of the API key */ + api_key_id?: string; + /** The response of the request */ + response?: Record; + /** The response code of the request */ + code?: number; + /** The deployment type */ + deployment?: string; + /** The callback URL for the request */ + callback?: string; +} diff --git a/src/api/types/ReadV1Request.ts b/src/api/types/ReadV1Request.ts new file mode 100644 index 00000000..06572052 --- /dev/null +++ b/src/api/types/ReadV1Request.ts @@ -0,0 +1,7 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +export type ReadV1Request = Deepgram.ReadV1RequestUrl | Deepgram.ReadV1RequestText; diff --git a/src/api/types/ReadV1RequestText.ts b/src/api/types/ReadV1RequestText.ts new file mode 100644 index 00000000..04ee412a --- /dev/null +++ b/src/api/types/ReadV1RequestText.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ReadV1RequestText { + /** The plain text to analyze */ + text: string; +} diff --git a/src/api/types/ReadV1RequestUrl.ts b/src/api/types/ReadV1RequestUrl.ts new file mode 100644 index 00000000..f1c5c3cf --- /dev/null +++ b/src/api/types/ReadV1RequestUrl.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ReadV1RequestUrl { + /** A URL pointing to the text source */ + url: string; +} diff --git a/src/api/types/ReadV1Response.ts b/src/api/types/ReadV1Response.ts new file mode 100644 index 00000000..bf02a92f --- /dev/null +++ b/src/api/types/ReadV1Response.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +/** + * The standard text response + */ +export interface ReadV1Response { + metadata: Deepgram.ReadV1ResponseMetadata; + results: Deepgram.ReadV1ResponseResults; +} diff --git a/src/api/types/ReadV1ResponseMetadata.ts b/src/api/types/ReadV1ResponseMetadata.ts new file mode 100644 index 00000000..c1967d41 --- /dev/null +++ b/src/api/types/ReadV1ResponseMetadata.ts @@ -0,0 +1,45 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface ReadV1ResponseMetadata { + metadata?: ReadV1ResponseMetadata.Metadata; +} + +export namespace ReadV1ResponseMetadata { + export interface Metadata { + request_id?: string; + created?: string; + language?: string; + summary_info?: Metadata.SummaryInfo; + sentiment_info?: Metadata.SentimentInfo; + topics_info?: Metadata.TopicsInfo; + intents_info?: Metadata.IntentsInfo; + } + + export namespace Metadata { + export interface SummaryInfo { + model_uuid?: string; + input_tokens?: number; + output_tokens?: number; + } + + export interface SentimentInfo { + model_uuid?: string; + input_tokens?: number; + output_tokens?: number; + } + + export interface TopicsInfo { + model_uuid?: string; + input_tokens?: number; + output_tokens?: number; + } + + export interface IntentsInfo { + model_uuid?: string; + input_tokens?: number; + output_tokens?: number; + } + } +} diff --git a/src/api/types/ReadV1ResponseResults.ts b/src/api/types/ReadV1ResponseResults.ts new file mode 100644 index 00000000..531f9465 --- /dev/null +++ b/src/api/types/ReadV1ResponseResults.ts @@ -0,0 +1,12 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as Deepgram from "../index.js"; + +export interface ReadV1ResponseResults { + summary?: Deepgram.ReadV1ResponseResultsSummary; + topics?: Deepgram.SharedTopics; + intents?: Deepgram.SharedIntents; + sentiments?: Deepgram.SharedSentiments; +} diff --git a/src/api/types/ReadV1ResponseResultsSummary.ts b/src/api/types/ReadV1ResponseResultsSummary.ts new file mode 100644 index 00000000..8f684da5 --- /dev/null +++ b/src/api/types/ReadV1ResponseResultsSummary.ts @@ -0,0 +1,22 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Output whenever `summary=true` is used + */ +export interface ReadV1ResponseResultsSummary { + results?: ReadV1ResponseResultsSummary.Results; +} + +export namespace ReadV1ResponseResultsSummary { + export interface Results { + summary?: Results.Summary; + } + + export namespace Results { + export interface Summary { + text?: string; + } + } +} diff --git a/src/api/types/SharedIntents.ts b/src/api/types/SharedIntents.ts new file mode 100644 index 00000000..9c2f78ea --- /dev/null +++ b/src/api/types/SharedIntents.ts @@ -0,0 +1,46 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Output whenever `intents=true` is used + */ +export interface SharedIntents { + results?: SharedIntents.Results; +} + +export namespace SharedIntents { + export interface Results { + intents?: Results.Intents; + } + + export namespace Results { + export interface Intents { + segments?: Intents.Segments.Item[]; + } + + export namespace Intents { + export type Segments = Segments.Item[]; + + export namespace Segments { + export interface Item { + text?: string; + start_word?: number; + end_word?: number; + intents?: Item.Intents.Item[]; + } + + export namespace Item { + export type Intents = Intents.Item[]; + + export namespace Intents { + export interface Item { + intent?: string; + confidence_score?: number; + } + } + } + } + } + } +} diff --git a/src/api/types/SharedSentiments.ts b/src/api/types/SharedSentiments.ts new file mode 100644 index 00000000..ae1ea50e --- /dev/null +++ b/src/api/types/SharedSentiments.ts @@ -0,0 +1,30 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Output whenever `sentiment=true` is used + */ +export interface SharedSentiments { + segments?: SharedSentiments.Segments.Item[]; + average?: SharedSentiments.Average; +} + +export namespace SharedSentiments { + export type Segments = Segments.Item[]; + + export namespace Segments { + export interface Item { + text?: string; + start_word?: number; + end_word?: number; + sentiment?: string; + sentiment_score?: number; + } + } + + export interface Average { + sentiment?: string; + sentiment_score?: number; + } +} diff --git a/src/api/types/SharedTopics.ts b/src/api/types/SharedTopics.ts new file mode 100644 index 00000000..356cfcab --- /dev/null +++ b/src/api/types/SharedTopics.ts @@ -0,0 +1,46 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Output whenever `topics=true` is used + */ +export interface SharedTopics { + results?: SharedTopics.Results; +} + +export namespace SharedTopics { + export interface Results { + topics?: Results.Topics; + } + + export namespace Results { + export interface Topics { + segments?: Topics.Segments.Item[]; + } + + export namespace Topics { + export type Segments = Segments.Item[]; + + export namespace Segments { + export interface Item { + text?: string; + start_word?: number; + end_word?: number; + topics?: Item.Topics.Item[]; + } + + export namespace Item { + export type Topics = Topics.Item[]; + + export namespace Topics { + export interface Item { + topic?: string; + confidence_score?: number; + } + } + } + } + } + } +} diff --git a/src/api/types/SpeakV1Encoding.ts b/src/api/types/SpeakV1Encoding.ts new file mode 100644 index 00000000..e6ca75b8 --- /dev/null +++ b/src/api/types/SpeakV1Encoding.ts @@ -0,0 +1,13 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Encoding allows you to specify the expected encoding of your audio output for streaming TTS. Only streaming-compatible encodings are supported. + */ +export type SpeakV1Encoding = "linear16" | "mulaw" | "alaw"; +export const SpeakV1Encoding = { + Linear16: "linear16", + Mulaw: "mulaw", + Alaw: "alaw", +} as const; diff --git a/src/api/types/SpeakV1MipOptOut.ts b/src/api/types/SpeakV1MipOptOut.ts new file mode 100644 index 00000000..3f598dd2 --- /dev/null +++ b/src/api/types/SpeakV1MipOptOut.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type SpeakV1MipOptOut = unknown; diff --git a/src/api/types/SpeakV1Model.ts b/src/api/types/SpeakV1Model.ts new file mode 100644 index 00000000..2e5aa6f9 --- /dev/null +++ b/src/api/types/SpeakV1Model.ts @@ -0,0 +1,136 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * AI model used to process submitted text + */ +export type SpeakV1Model = + | "aura-asteria-en" + | "aura-luna-en" + | "aura-stella-en" + | "aura-athena-en" + | "aura-hera-en" + | "aura-orion-en" + | "aura-arcas-en" + | "aura-perseus-en" + | "aura-angus-en" + | "aura-orpheus-en" + | "aura-helios-en" + | "aura-zeus-en" + | "aura-2-amalthea-en" + | "aura-2-andromeda-en" + | "aura-2-apollo-en" + | "aura-2-arcas-en" + | "aura-2-aries-en" + | "aura-2-asteria-en" + | "aura-2-athena-en" + | "aura-2-atlas-en" + | "aura-2-aurora-en" + | "aura-2-callista-en" + | "aura-2-cordelia-en" + | "aura-2-cora-en" + | "aura-2-delia-en" + | "aura-2-draco-en" + | "aura-2-electra-en" + | "aura-2-harmonia-en" + | "aura-2-helena-en" + | "aura-2-hera-en" + | "aura-2-hermes-en" + | "aura-2-hyperion-en" + | "aura-2-iris-en" + | "aura-2-janus-en" + | "aura-2-juno-en" + | "aura-2-jupiter-en" + | "aura-2-luna-en" + | "aura-2-mars-en" + | "aura-2-minerva-en" + | "aura-2-neptune-en" + | "aura-2-odysseus-en" + | "aura-2-ophelia-en" + | "aura-2-orion-en" + | "aura-2-orpheus-en" + | "aura-2-pandora-en" + | "aura-2-phoebe-en" + | "aura-2-pluto-en" + | "aura-2-saturn-en" + | "aura-2-selene-en" + | "aura-2-thalia-en" + | "aura-2-theia-en" + | "aura-2-vesta-en" + | "aura-2-zeus-en" + | "aura-2-sirio-es" + | "aura-2-nestor-es" + | "aura-2-carina-es" + | "aura-2-celeste-es" + | "aura-2-alvaro-es" + | "aura-2-diana-es" + | "aura-2-aquila-es" + | "aura-2-selena-es" + | "aura-2-estrella-es" + | "aura-2-javier-es"; +export const SpeakV1Model = { + AuraAsteriaEn: "aura-asteria-en", + AuraLunaEn: "aura-luna-en", + AuraStellaEn: "aura-stella-en", + AuraAthenaEn: "aura-athena-en", + AuraHeraEn: "aura-hera-en", + AuraOrionEn: "aura-orion-en", + AuraArcasEn: "aura-arcas-en", + AuraPerseusEn: "aura-perseus-en", + AuraAngusEn: "aura-angus-en", + AuraOrpheusEn: "aura-orpheus-en", + AuraHeliosEn: "aura-helios-en", + AuraZeusEn: "aura-zeus-en", + Aura2AmaltheaEn: "aura-2-amalthea-en", + Aura2AndromedaEn: "aura-2-andromeda-en", + Aura2ApolloEn: "aura-2-apollo-en", + Aura2ArcasEn: "aura-2-arcas-en", + Aura2AriesEn: "aura-2-aries-en", + Aura2AsteriaEn: "aura-2-asteria-en", + Aura2AthenaEn: "aura-2-athena-en", + Aura2AtlasEn: "aura-2-atlas-en", + Aura2AuroraEn: "aura-2-aurora-en", + Aura2CallistaEn: "aura-2-callista-en", + Aura2CordeliaEn: "aura-2-cordelia-en", + Aura2CoraEn: "aura-2-cora-en", + Aura2DeliaEn: "aura-2-delia-en", + Aura2DracoEn: "aura-2-draco-en", + Aura2ElectraEn: "aura-2-electra-en", + Aura2HarmoniaEn: "aura-2-harmonia-en", + Aura2HelenaEn: "aura-2-helena-en", + Aura2HeraEn: "aura-2-hera-en", + Aura2HermesEn: "aura-2-hermes-en", + Aura2HyperionEn: "aura-2-hyperion-en", + Aura2IrisEn: "aura-2-iris-en", + Aura2JanusEn: "aura-2-janus-en", + Aura2JunoEn: "aura-2-juno-en", + Aura2JupiterEn: "aura-2-jupiter-en", + Aura2LunaEn: "aura-2-luna-en", + Aura2MarsEn: "aura-2-mars-en", + Aura2MinervaEn: "aura-2-minerva-en", + Aura2NeptuneEn: "aura-2-neptune-en", + Aura2OdysseusEn: "aura-2-odysseus-en", + Aura2OpheliaEn: "aura-2-ophelia-en", + Aura2OrionEn: "aura-2-orion-en", + Aura2OrpheusEn: "aura-2-orpheus-en", + Aura2PandoraEn: "aura-2-pandora-en", + Aura2PhoebeEn: "aura-2-phoebe-en", + Aura2PlutoEn: "aura-2-pluto-en", + Aura2SaturnEn: "aura-2-saturn-en", + Aura2SeleneEn: "aura-2-selene-en", + Aura2ThaliaEn: "aura-2-thalia-en", + Aura2TheiaEn: "aura-2-theia-en", + Aura2VestaEn: "aura-2-vesta-en", + Aura2ZeusEn: "aura-2-zeus-en", + Aura2SirioEs: "aura-2-sirio-es", + Aura2NestorEs: "aura-2-nestor-es", + Aura2CarinaEs: "aura-2-carina-es", + Aura2CelesteEs: "aura-2-celeste-es", + Aura2AlvaroEs: "aura-2-alvaro-es", + Aura2DianaEs: "aura-2-diana-es", + Aura2AquilaEs: "aura-2-aquila-es", + Aura2SelenaEs: "aura-2-selena-es", + Aura2EstrellaEs: "aura-2-estrella-es", + Aura2JavierEs: "aura-2-javier-es", +} as const; diff --git a/src/api/types/SpeakV1Response.ts b/src/api/types/SpeakV1Response.ts new file mode 100644 index 00000000..c2a52d23 --- /dev/null +++ b/src/api/types/SpeakV1Response.ts @@ -0,0 +1,5 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export type SpeakV1Response = string; diff --git a/src/api/types/SpeakV1SampleRate.ts b/src/api/types/SpeakV1SampleRate.ts new file mode 100644 index 00000000..5cb33204 --- /dev/null +++ b/src/api/types/SpeakV1SampleRate.ts @@ -0,0 +1,15 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +/** + * Sample Rate specifies the sample rate for the output audio. Based on encoding 8000 or 24000 are possible defaults. For some encodings sample rate is not configurable. + */ +export type SpeakV1SampleRate = "8000" | "16000" | "24000" | "44100" | "48000"; +export const SpeakV1SampleRate = { + EightThousand: "8000", + SixteenThousand: "16000", + TwentyFourThousand: "24000", + FortyFourThousandOneHundred: "44100", + FortyEightThousand: "48000", +} as const; diff --git a/src/api/types/UpdateProjectMemberScopesV1Response.ts b/src/api/types/UpdateProjectMemberScopesV1Response.ts new file mode 100644 index 00000000..95bfdeeb --- /dev/null +++ b/src/api/types/UpdateProjectMemberScopesV1Response.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface UpdateProjectMemberScopesV1Response { + /** confirmation message */ + message?: string; +} diff --git a/src/api/types/UpdateProjectV1Response.ts b/src/api/types/UpdateProjectV1Response.ts new file mode 100644 index 00000000..ba492366 --- /dev/null +++ b/src/api/types/UpdateProjectV1Response.ts @@ -0,0 +1,8 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface UpdateProjectV1Response { + /** confirmation message */ + message?: string; +} diff --git a/src/api/types/UsageBreakdownV1Response.ts b/src/api/types/UsageBreakdownV1Response.ts new file mode 100644 index 00000000..35f6cef4 --- /dev/null +++ b/src/api/types/UsageBreakdownV1Response.ts @@ -0,0 +1,66 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface UsageBreakdownV1Response { + /** Start date of the usage period */ + start: string; + /** End date of the usage period */ + end: string; + resolution: UsageBreakdownV1Response.Resolution; + results: UsageBreakdownV1Response.Results.Item[]; +} + +export namespace UsageBreakdownV1Response { + export interface Resolution { + /** Time unit for the resolution */ + units: string; + /** Amount of units */ + amount: number; + } + + export type Results = Results.Item[]; + + export namespace Results { + export interface Item { + /** Audio hours processed */ + hours: number; + /** Total hours including all processing */ + total_hours: number; + /** Agent hours used */ + agent_hours: number; + /** Number of input tokens */ + tokens_in: number; + /** Number of output tokens */ + tokens_out: number; + /** Number of text-to-speech characters processed */ + tts_characters: number; + /** Number of requests */ + requests: number; + grouping: Item.Grouping; + } + + export namespace Item { + export interface Grouping { + /** Start date for this group */ + start?: string; + /** End date for this group */ + end?: string; + /** Optional accessor identifier */ + accessor?: string; + /** Optional endpoint identifier */ + endpoint?: string; + /** Optional feature set identifier */ + feature_set?: string; + /** Optional models identifier */ + models?: string; + /** Optional method identifier */ + method?: string; + /** Optional tags */ + tags?: string; + /** Optional deployment identifier */ + deployment?: string; + } + } + } +} diff --git a/src/api/types/UsageFieldsV1Response.ts b/src/api/types/UsageFieldsV1Response.ts new file mode 100644 index 00000000..4057b77c --- /dev/null +++ b/src/api/types/UsageFieldsV1Response.ts @@ -0,0 +1,31 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface UsageFieldsV1Response { + /** List of tags associated with the project */ + tags?: string[]; + /** List of models available for the project. */ + models?: UsageFieldsV1Response.Models.Item[]; + /** Processing methods supported by the API */ + processing_methods?: string[]; + /** API features available to the project */ + features?: string[]; +} + +export namespace UsageFieldsV1Response { + export type Models = Models.Item[]; + + export namespace Models { + export interface Item { + /** Name of the model. */ + name?: string; + /** The language supported by the model (IETF language tag). */ + language?: string; + /** Version identifier of the model, typically with a date and a revision number. */ + version?: string; + /** Unique identifier for the model. */ + model_id?: string; + } + } +} diff --git a/src/api/types/UsageV1Response.ts b/src/api/types/UsageV1Response.ts new file mode 100644 index 00000000..1e6b04d4 --- /dev/null +++ b/src/api/types/UsageV1Response.ts @@ -0,0 +1,16 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface UsageV1Response { + start?: string; + end?: string; + resolution?: UsageV1Response.Resolution; +} + +export namespace UsageV1Response { + export interface Resolution { + units?: string; + amount?: number; + } +} diff --git a/src/api/types/index.ts b/src/api/types/index.ts new file mode 100644 index 00000000..6d946a62 --- /dev/null +++ b/src/api/types/index.ts @@ -0,0 +1,101 @@ +export * from "./AgentThinkModelsV1Response.js"; +export * from "./ErrorResponseTextError.js"; +export * from "./ErrorResponseLegacyError.js"; +export * from "./ErrorResponseModernError.js"; +export * from "./ErrorResponse.js"; +export * from "./GrantV1Response.js"; +export * from "./ListenV1RequestFile.js"; +export * from "./ListenV1ResponseMetadata.js"; +export * from "./ListenV1ResponseResultsChannelsItem.js"; +export * from "./ListenV1ResponseResultsChannels.js"; +export * from "./ListenV1ResponseResultsUtterancesItem.js"; +export * from "./ListenV1ResponseResultsUtterances.js"; +export * from "./ListenV1ResponseResultsSummary.js"; +export * from "./SharedTopics.js"; +export * from "./SharedIntents.js"; +export * from "./SharedSentiments.js"; +export * from "./ListenV1ResponseResults.js"; +export * from "./ListenV1Response.js"; +export * from "./ListenV1AcceptedResponse.js"; +export * from "./ListModelsV1ResponseSttModels.js"; +export * from "./ListModelsV1ResponseTtsModels.js"; +export * from "./ListModelsV1Response.js"; +export * from "./GetModelV1Response.js"; +export * from "./ListProjectsV1Response.js"; +export * from "./GetProjectV1Response.js"; +export * from "./UpdateProjectV1Response.js"; +export * from "./DeleteProjectV1Response.js"; +export * from "./ListProjectBalancesV1Response.js"; +export * from "./GetProjectBalanceV1Response.js"; +export * from "./BillingBreakdownV1Response.js"; +export * from "./ListProjectInvitesV1Response.js"; +export * from "./CreateProjectInviteV1Response.js"; +export * from "./DeleteProjectInviteV1Response.js"; +export * from "./ListProjectKeysV1Response.js"; +export * from "./CreateKeyV1RequestOne.js"; +export * from "./CreateKeyV1Response.js"; +export * from "./GetProjectKeyV1Response.js"; +export * from "./DeleteProjectKeyV1Response.js"; +export * from "./LeaveProjectV1Response.js"; +export * from "./ListProjectMembersV1Response.js"; +export * from "./DeleteProjectMemberV1Response.js"; +export * from "./ListProjectMemberScopesV1Response.js"; +export * from "./UpdateProjectMemberScopesV1Response.js"; +export * from "./ListProjectPurchasesV1Response.js"; +export * from "./ProjectRequestResponse.js"; +export * from "./ListProjectRequestsV1Response.js"; +export * from "./GetProjectRequestV1Response.js"; +export * from "./ListProjectDistributionCredentialsV1Response.js"; +export * from "./CreateProjectDistributionCredentialsV1Response.js"; +export * from "./GetProjectDistributionCredentialsV1Response.js"; +export * from "./UsageV1Response.js"; +export * from "./UsageBreakdownV1Response.js"; +export * from "./UsageFieldsV1Response.js"; +export * from "./ReadV1RequestUrl.js"; +export * from "./ReadV1RequestText.js"; +export * from "./ReadV1Request.js"; +export * from "./ReadV1ResponseMetadata.js"; +export * from "./ReadV1ResponseResultsSummary.js"; +export * from "./ReadV1ResponseResults.js"; +export * from "./ReadV1Response.js"; +export * from "./SpeakV1Response.js"; +export * from "./SpeakV1Encoding.js"; +export * from "./SpeakV1MipOptOut.js"; +export * from "./SpeakV1Model.js"; +export * from "./SpeakV1SampleRate.js"; +export * from "./ListenV1Callback.js"; +export * from "./ListenV1CallbackMethod.js"; +export * from "./ListenV1Channels.js"; +export * from "./ListenV1Diarize.js"; +export * from "./ListenV1Dictation.js"; +export * from "./ListenV1Encoding.js"; +export * from "./ListenV1Endpointing.js"; +export * from "./ListenV1Extra.js"; +export * from "./ListenV1InterimResults.js"; +export * from "./ListenV1Keyterm.js"; +export * from "./ListenV1Keywords.js"; +export * from "./ListenV1Language.js"; +export * from "./ListenV1MipOptOut.js"; +export * from "./ListenV1Model.js"; +export * from "./ListenV1Multichannel.js"; +export * from "./ListenV1Numerals.js"; +export * from "./ListenV1ProfanityFilter.js"; +export * from "./ListenV1Punctuate.js"; +export * from "./ListenV1Redact.js"; +export * from "./ListenV1Replace.js"; +export * from "./ListenV1SampleRate.js"; +export * from "./ListenV1Search.js"; +export * from "./ListenV1SmartFormat.js"; +export * from "./ListenV1Tag.js"; +export * from "./ListenV1UtteranceEndMs.js"; +export * from "./ListenV1VadEvents.js"; +export * from "./ListenV1Version.js"; +export * from "./ListenV2Model.js"; +export * from "./ListenV2Encoding.js"; +export * from "./ListenV2SampleRate.js"; +export * from "./ListenV2EagerEotThreshold.js"; +export * from "./ListenV2EotThreshold.js"; +export * from "./ListenV2EotTimeoutMs.js"; +export * from "./ListenV2Keyterm.js"; +export * from "./ListenV2MipOptOut.js"; +export * from "./ListenV2Tag.js"; diff --git a/src/core/exports.ts b/src/core/exports.ts new file mode 100644 index 00000000..e415a8f6 --- /dev/null +++ b/src/core/exports.ts @@ -0,0 +1 @@ +export * from "./file/exports.js"; diff --git a/src/core/fetcher/APIResponse.ts b/src/core/fetcher/APIResponse.ts new file mode 100644 index 00000000..dd4b9466 --- /dev/null +++ b/src/core/fetcher/APIResponse.ts @@ -0,0 +1,23 @@ +import { RawResponse } from "./RawResponse.js"; + +/** + * The response of an API call. + * It is a successful response or a failed response. + */ +export type APIResponse = SuccessfulResponse | FailedResponse; + +export interface SuccessfulResponse { + ok: true; + body: T; + /** + * @deprecated Use `rawResponse` instead + */ + headers?: Record; + rawResponse: RawResponse; +} + +export interface FailedResponse { + ok: false; + error: T; + rawResponse: RawResponse; +} diff --git a/src/core/fetcher/BinaryResponse.ts b/src/core/fetcher/BinaryResponse.ts new file mode 100644 index 00000000..614cb59b --- /dev/null +++ b/src/core/fetcher/BinaryResponse.ts @@ -0,0 +1,36 @@ +import { ResponseWithBody } from "./ResponseWithBody.js"; + +export type BinaryResponse = { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bodyUsed) */ + bodyUsed: boolean; + /** + * Returns a ReadableStream of the response body. + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/body) + */ + stream: () => ReadableStream; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/arrayBuffer) */ + arrayBuffer: () => Promise; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/blob) */ + blob: () => Promise; + /** + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bytes) + * Some versions of the Fetch API may not support this method. + */ + bytes?(): Promise; +}; + +export function getBinaryResponse(response: ResponseWithBody): BinaryResponse { + const binaryResponse: BinaryResponse = { + get bodyUsed() { + return response.bodyUsed; + }, + stream: () => response.body, + arrayBuffer: response.arrayBuffer.bind(response), + blob: response.blob.bind(response), + }; + if ("bytes" in response && typeof response.bytes === "function") { + binaryResponse.bytes = response.bytes.bind(response); + } + + return binaryResponse; +} diff --git a/src/core/fetcher/Fetcher.ts b/src/core/fetcher/Fetcher.ts new file mode 100644 index 00000000..39e69143 --- /dev/null +++ b/src/core/fetcher/Fetcher.ts @@ -0,0 +1,163 @@ +import { toJson } from "../json.js"; +import { APIResponse } from "./APIResponse.js"; +import { createRequestUrl } from "./createRequestUrl.js"; +import { getErrorResponseBody } from "./getErrorResponseBody.js"; +import { getFetchFn } from "./getFetchFn.js"; +import { getRequestBody } from "./getRequestBody.js"; +import { getResponseBody } from "./getResponseBody.js"; +import { makeRequest } from "./makeRequest.js"; +import { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; +import { requestWithRetries } from "./requestWithRetries.js"; +import { Supplier } from "./Supplier.js"; + +export type FetchFunction = (args: Fetcher.Args) => Promise>; + +export declare namespace Fetcher { + export interface Args { + url: string; + method: string; + contentType?: string; + headers?: Record | null | undefined>; + queryParameters?: Record; + body?: unknown; + timeoutMs?: number; + maxRetries?: number; + withCredentials?: boolean; + abortSignal?: AbortSignal; + requestType?: "json" | "file" | "bytes"; + responseType?: "json" | "blob" | "sse" | "streaming" | "text" | "arrayBuffer" | "binary-response"; + duplex?: "half"; + } + + export type Error = FailedStatusCodeError | NonJsonError | TimeoutError | UnknownError; + + export interface FailedStatusCodeError { + reason: "status-code"; + statusCode: number; + body: unknown; + } + + export interface NonJsonError { + reason: "non-json"; + statusCode: number; + rawBody: string; + } + + export interface TimeoutError { + reason: "timeout"; + } + + export interface UnknownError { + reason: "unknown"; + errorMessage: string; + } +} + +async function getHeaders(args: Fetcher.Args): Promise> { + const newHeaders: Record = {}; + if (args.body !== undefined && args.contentType != null) { + newHeaders["Content-Type"] = args.contentType; + } + + if (args.headers == null) { + return newHeaders; + } + + for (const [key, value] of Object.entries(args.headers)) { + const result = await Supplier.get(value); + if (typeof result === "string") { + newHeaders[key] = result; + continue; + } + if (result == null) { + continue; + } + newHeaders[key] = `${result}`; + } + return newHeaders; +} + +export async function fetcherImpl(args: Fetcher.Args): Promise> { + const url = createRequestUrl(args.url, args.queryParameters); + const requestBody: BodyInit | undefined = await getRequestBody({ + body: args.body, + type: args.requestType === "json" ? "json" : "other", + }); + const fetchFn = await getFetchFn(); + + try { + const response = await requestWithRetries( + async () => + makeRequest( + fetchFn, + url, + args.method, + await getHeaders(args), + requestBody, + args.timeoutMs, + args.abortSignal, + args.withCredentials, + args.duplex, + ), + args.maxRetries, + ); + + if (response.status >= 200 && response.status < 400) { + return { + ok: true, + body: (await getResponseBody(response, args.responseType)) as R, + headers: response.headers, + rawResponse: toRawResponse(response), + }; + } else { + return { + ok: false, + error: { + reason: "status-code", + statusCode: response.status, + body: await getErrorResponseBody(response), + }, + rawResponse: toRawResponse(response), + }; + } + } catch (error) { + if (args.abortSignal != null && args.abortSignal.aborted) { + return { + ok: false, + error: { + reason: "unknown", + errorMessage: "The user aborted a request", + }, + rawResponse: abortRawResponse, + }; + } else if (error instanceof Error && error.name === "AbortError") { + return { + ok: false, + error: { + reason: "timeout", + }, + rawResponse: abortRawResponse, + }; + } else if (error instanceof Error) { + return { + ok: false, + error: { + reason: "unknown", + errorMessage: error.message, + }, + rawResponse: unknownRawResponse, + }; + } + + return { + ok: false, + error: { + reason: "unknown", + errorMessage: toJson(error), + }, + rawResponse: unknownRawResponse, + }; + } +} + +export const fetcher: FetchFunction = fetcherImpl; diff --git a/src/core/fetcher/Headers.ts b/src/core/fetcher/Headers.ts new file mode 100644 index 00000000..af841aa2 --- /dev/null +++ b/src/core/fetcher/Headers.ts @@ -0,0 +1,93 @@ +let Headers: typeof globalThis.Headers; + +if (typeof globalThis.Headers !== "undefined") { + Headers = globalThis.Headers; +} else { + Headers = class Headers implements Headers { + private headers: Map; + + constructor(init?: HeadersInit) { + this.headers = new Map(); + + if (init) { + if (init instanceof Headers) { + init.forEach((value, key) => this.append(key, value)); + } else if (Array.isArray(init)) { + for (const [key, value] of init) { + if (typeof key === "string" && typeof value === "string") { + this.append(key, value); + } else { + throw new TypeError("Each header entry must be a [string, string] tuple"); + } + } + } else { + for (const [key, value] of Object.entries(init)) { + if (typeof value === "string") { + this.append(key, value); + } else { + throw new TypeError("Header values must be strings"); + } + } + } + } + } + + append(name: string, value: string): void { + const key = name.toLowerCase(); + const existing = this.headers.get(key) || []; + this.headers.set(key, [...existing, value]); + } + + delete(name: string): void { + const key = name.toLowerCase(); + this.headers.delete(key); + } + + get(name: string): string | null { + const key = name.toLowerCase(); + const values = this.headers.get(key); + return values ? values.join(", ") : null; + } + + has(name: string): boolean { + const key = name.toLowerCase(); + return this.headers.has(key); + } + + set(name: string, value: string): void { + const key = name.toLowerCase(); + this.headers.set(key, [value]); + } + + forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: unknown): void { + const boundCallback = thisArg ? callbackfn.bind(thisArg) : callbackfn; + this.headers.forEach((values, key) => boundCallback(values.join(", "), key, this)); + } + + getSetCookie(): string[] { + return this.headers.get("set-cookie") || []; + } + + *entries(): HeadersIterator<[string, string]> { + for (const [key, values] of this.headers.entries()) { + yield [key, values.join(", ")]; + } + } + + *keys(): HeadersIterator { + yield* this.headers.keys(); + } + + *values(): HeadersIterator { + for (const values of this.headers.values()) { + yield values.join(", "); + } + } + + [Symbol.iterator](): HeadersIterator<[string, string]> { + return this.entries(); + } + }; +} + +export { Headers }; diff --git a/src/core/fetcher/HttpResponsePromise.ts b/src/core/fetcher/HttpResponsePromise.ts new file mode 100644 index 00000000..026d88f1 --- /dev/null +++ b/src/core/fetcher/HttpResponsePromise.ts @@ -0,0 +1,116 @@ +import { WithRawResponse } from "./RawResponse.js"; + +/** + * A promise that returns the parsed response and lets you retrieve the raw response too. + */ +export class HttpResponsePromise extends Promise { + private innerPromise: Promise>; + private unwrappedPromise: Promise | undefined; + + private constructor(promise: Promise>) { + // Initialize with a no-op to avoid premature parsing + super((resolve) => { + resolve(undefined as unknown as T); + }); + this.innerPromise = promise; + } + + /** + * Creates an `HttpResponsePromise` from a function that returns a promise. + * + * @param fn - A function that returns a promise resolving to a `WithRawResponse` object. + * @param args - Arguments to pass to the function. + * @returns An `HttpResponsePromise` instance. + */ + public static fromFunction Promise>, T>( + fn: F, + ...args: Parameters + ): HttpResponsePromise { + return new HttpResponsePromise(fn(...args)); + } + + /** + * Creates a function that returns an `HttpResponsePromise` from a function that returns a promise. + * + * @param fn - A function that returns a promise resolving to a `WithRawResponse` object. + * @returns A function that returns an `HttpResponsePromise` instance. + */ + public static interceptFunction< + F extends (...args: never[]) => Promise>, + T = Awaited>["data"], + >(fn: F): (...args: Parameters) => HttpResponsePromise { + return (...args: Parameters): HttpResponsePromise => { + return HttpResponsePromise.fromPromise(fn(...args)); + }; + } + + /** + * Creates an `HttpResponsePromise` from an existing promise. + * + * @param promise - A promise resolving to a `WithRawResponse` object. + * @returns An `HttpResponsePromise` instance. + */ + public static fromPromise(promise: Promise>): HttpResponsePromise { + return new HttpResponsePromise(promise); + } + + /** + * Creates an `HttpResponsePromise` from an executor function. + * + * @param executor - A function that takes resolve and reject callbacks to create a promise. + * @returns An `HttpResponsePromise` instance. + */ + public static fromExecutor( + executor: (resolve: (value: WithRawResponse) => void, reject: (reason?: unknown) => void) => void, + ): HttpResponsePromise { + const promise = new Promise>(executor); + return new HttpResponsePromise(promise); + } + + /** + * Creates an `HttpResponsePromise` from a resolved result. + * + * @param result - A `WithRawResponse` object to resolve immediately. + * @returns An `HttpResponsePromise` instance. + */ + public static fromResult(result: WithRawResponse): HttpResponsePromise { + const promise = Promise.resolve(result); + return new HttpResponsePromise(promise); + } + + private unwrap(): Promise { + if (!this.unwrappedPromise) { + this.unwrappedPromise = this.innerPromise.then(({ data }) => data); + } + return this.unwrappedPromise; + } + + /** @inheritdoc */ + public override then( + onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, + onrejected?: ((reason: unknown) => TResult2 | PromiseLike) | null, + ): Promise { + return this.unwrap().then(onfulfilled, onrejected); + } + + /** @inheritdoc */ + public override catch( + onrejected?: ((reason: unknown) => TResult | PromiseLike) | null, + ): Promise { + return this.unwrap().catch(onrejected); + } + + /** @inheritdoc */ + public override finally(onfinally?: (() => void) | null): Promise { + return this.unwrap().finally(onfinally); + } + + /** + * Retrieves the data and raw response. + * + * @returns A promise resolving to a `WithRawResponse` object. + */ + public async withRawResponse(): Promise> { + return await this.innerPromise; + } +} diff --git a/src/core/fetcher/RawResponse.ts b/src/core/fetcher/RawResponse.ts new file mode 100644 index 00000000..37fb44e2 --- /dev/null +++ b/src/core/fetcher/RawResponse.ts @@ -0,0 +1,61 @@ +import { Headers } from "./Headers.js"; + +/** + * The raw response from the fetch call excluding the body. + */ +export type RawResponse = Omit< + { + [K in keyof Response as Response[K] extends Function ? never : K]: Response[K]; // strips out functions + }, + "ok" | "body" | "bodyUsed" +>; // strips out body and bodyUsed + +/** + * A raw response indicating that the request was aborted. + */ +export const abortRawResponse: RawResponse = { + headers: new Headers(), + redirected: false, + status: 499, + statusText: "Client Closed Request", + type: "error", + url: "", +} as const; + +/** + * A raw response indicating an unknown error. + */ +export const unknownRawResponse: RawResponse = { + headers: new Headers(), + redirected: false, + status: 0, + statusText: "Unknown Error", + type: "error", + url: "", +} as const; + +/** + * Converts a `RawResponse` object into a `RawResponse` by extracting its properties, + * excluding the `body` and `bodyUsed` fields. + * + * @param response - The `RawResponse` object to convert. + * @returns A `RawResponse` object containing the extracted properties of the input response. + */ +export function toRawResponse(response: Response): RawResponse { + return { + headers: response.headers, + redirected: response.redirected, + status: response.status, + statusText: response.statusText, + type: response.type, + url: response.url, + }; +} + +/** + * Creates a `RawResponse` from a standard `Response` object. + */ +export interface WithRawResponse { + readonly data: T; + readonly rawResponse: RawResponse; +} diff --git a/src/core/fetcher/ResponseWithBody.ts b/src/core/fetcher/ResponseWithBody.ts new file mode 100644 index 00000000..445d40f8 --- /dev/null +++ b/src/core/fetcher/ResponseWithBody.ts @@ -0,0 +1,7 @@ +export type ResponseWithBody = Response & { + body: ReadableStream; +}; + +export function isResponseWithBody(response: Response): response is ResponseWithBody { + return (response as ResponseWithBody).body != null; +} diff --git a/src/core/fetcher/Supplier.ts b/src/core/fetcher/Supplier.ts new file mode 100644 index 00000000..867c931c --- /dev/null +++ b/src/core/fetcher/Supplier.ts @@ -0,0 +1,11 @@ +export type Supplier = T | Promise | (() => T | Promise); + +export const Supplier = { + get: async (supplier: Supplier): Promise => { + if (typeof supplier === "function") { + return (supplier as () => T)(); + } else { + return supplier; + } + }, +}; diff --git a/src/core/fetcher/createRequestUrl.ts b/src/core/fetcher/createRequestUrl.ts new file mode 100644 index 00000000..88e13265 --- /dev/null +++ b/src/core/fetcher/createRequestUrl.ts @@ -0,0 +1,6 @@ +import { toQueryString } from "../url/qs.js"; + +export function createRequestUrl(baseUrl: string, queryParameters?: Record): string { + const queryString = toQueryString(queryParameters, { arrayFormat: "repeat" }); + return queryString ? `${baseUrl}?${queryString}` : baseUrl; +} diff --git a/src/core/fetcher/getErrorResponseBody.ts b/src/core/fetcher/getErrorResponseBody.ts new file mode 100644 index 00000000..450424bd --- /dev/null +++ b/src/core/fetcher/getErrorResponseBody.ts @@ -0,0 +1,32 @@ +import { fromJson } from "../json.js"; +import { getResponseBody } from "./getResponseBody.js"; + +export async function getErrorResponseBody(response: Response): Promise { + let contentType = response.headers.get("Content-Type")?.toLowerCase(); + if (contentType == null || contentType.length === 0) { + return getResponseBody(response); + } + + if (contentType.indexOf(";") !== -1) { + contentType = contentType.split(";")[0]?.trim() ?? ""; + } + switch (contentType) { + case "application/hal+json": + case "application/json": + case "application/ld+json": + case "application/problem+json": + case "application/vnd.api+json": + case "text/json": + const text = await response.text(); + return text.length > 0 ? fromJson(text) : undefined; + default: + if (contentType.startsWith("application/vnd.") && contentType.endsWith("+json")) { + const text = await response.text(); + return text.length > 0 ? fromJson(text) : undefined; + } + + // Fallback to plain text if content type is not recognized + // Even if no body is present, the response will be an empty string + return await response.text(); + } +} diff --git a/src/core/fetcher/getFetchFn.ts b/src/core/fetcher/getFetchFn.ts new file mode 100644 index 00000000..9f845b95 --- /dev/null +++ b/src/core/fetcher/getFetchFn.ts @@ -0,0 +1,3 @@ +export async function getFetchFn(): Promise { + return fetch; +} diff --git a/src/core/fetcher/getHeader.ts b/src/core/fetcher/getHeader.ts new file mode 100644 index 00000000..50f922b0 --- /dev/null +++ b/src/core/fetcher/getHeader.ts @@ -0,0 +1,8 @@ +export function getHeader(headers: Record, header: string): string | undefined { + for (const [headerKey, headerValue] of Object.entries(headers)) { + if (headerKey.toLowerCase() === header.toLowerCase()) { + return headerValue; + } + } + return undefined; +} diff --git a/src/core/fetcher/getRequestBody.ts b/src/core/fetcher/getRequestBody.ts new file mode 100644 index 00000000..e38457c5 --- /dev/null +++ b/src/core/fetcher/getRequestBody.ts @@ -0,0 +1,16 @@ +import { toJson } from "../json.js"; + +export declare namespace GetRequestBody { + interface Args { + body: unknown; + type: "json" | "file" | "bytes" | "other"; + } +} + +export async function getRequestBody({ body, type }: GetRequestBody.Args): Promise { + if (type.includes("json")) { + return toJson(body); + } else { + return body as BodyInit; + } +} diff --git a/src/core/fetcher/getResponseBody.ts b/src/core/fetcher/getResponseBody.ts new file mode 100644 index 00000000..7ca8b3d2 --- /dev/null +++ b/src/core/fetcher/getResponseBody.ts @@ -0,0 +1,43 @@ +import { getBinaryResponse } from "./BinaryResponse.js"; +import { isResponseWithBody } from "./ResponseWithBody.js"; +import { fromJson } from "../json.js"; + +export async function getResponseBody(response: Response, responseType?: string): Promise { + if (!isResponseWithBody(response)) { + return undefined; + } + switch (responseType) { + case "binary-response": + return getBinaryResponse(response); + case "blob": + return await response.blob(); + case "arrayBuffer": + return await response.arrayBuffer(); + case "sse": + return response.body; + case "streaming": + return response.body; + + case "text": + return await response.text(); + } + + // if responseType is "json" or not specified, try to parse as JSON + const text = await response.text(); + if (text.length > 0) { + try { + let responseBody = fromJson(text); + return responseBody; + } catch (err) { + return { + ok: false, + error: { + reason: "non-json", + statusCode: response.status, + rawBody: text, + }, + }; + } + } + return undefined; +} diff --git a/src/core/fetcher/index.ts b/src/core/fetcher/index.ts new file mode 100644 index 00000000..a131e346 --- /dev/null +++ b/src/core/fetcher/index.ts @@ -0,0 +1,9 @@ +export type { APIResponse } from "./APIResponse.js"; +export type { BinaryResponse } from "./BinaryResponse.js"; +export type { Fetcher, FetchFunction } from "./Fetcher.js"; +export { fetcher } from "./Fetcher.js"; +export { getHeader } from "./getHeader.js"; +export { HttpResponsePromise } from "./HttpResponsePromise.js"; +export type { RawResponse, WithRawResponse } from "./RawResponse.js"; +export { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; +export { Supplier } from "./Supplier.js"; diff --git a/src/core/fetcher/makeRequest.ts b/src/core/fetcher/makeRequest.ts new file mode 100644 index 00000000..1a5ffd3c --- /dev/null +++ b/src/core/fetcher/makeRequest.ts @@ -0,0 +1,44 @@ +import { anySignal, getTimeoutSignal } from "./signals.js"; + +export const makeRequest = async ( + fetchFn: (url: string, init: RequestInit) => Promise, + url: string, + method: string, + headers: Record, + requestBody: BodyInit | undefined, + timeoutMs?: number, + abortSignal?: AbortSignal, + withCredentials?: boolean, + duplex?: "half", +): Promise => { + const signals: AbortSignal[] = []; + + // Add timeout signal + let timeoutAbortId: NodeJS.Timeout | undefined = undefined; + if (timeoutMs != null) { + const { signal, abortId } = getTimeoutSignal(timeoutMs); + timeoutAbortId = abortId; + signals.push(signal); + } + + // Add arbitrary signal + if (abortSignal != null) { + signals.push(abortSignal); + } + let newSignals = anySignal(signals); + const response = await fetchFn(url, { + method: method, + headers, + body: requestBody, + signal: newSignals, + credentials: withCredentials ? "include" : undefined, + // @ts-ignore + duplex, + }); + + if (timeoutAbortId != null) { + clearTimeout(timeoutAbortId); + } + + return response; +}; diff --git a/src/core/fetcher/requestWithRetries.ts b/src/core/fetcher/requestWithRetries.ts new file mode 100644 index 00000000..560432ef --- /dev/null +++ b/src/core/fetcher/requestWithRetries.ts @@ -0,0 +1,73 @@ +const INITIAL_RETRY_DELAY = 1000; // in milliseconds +const MAX_RETRY_DELAY = 60000; // in milliseconds +const DEFAULT_MAX_RETRIES = 2; +const JITTER_FACTOR = 0.2; // 20% random jitter + +function addPositiveJitter(delay: number): number { + // Generate a random value between 0 and +JITTER_FACTOR + const jitterMultiplier = 1 + Math.random() * JITTER_FACTOR; + return delay * jitterMultiplier; +} + +function addSymmetricJitter(delay: number): number { + // Generate a random value in a JITTER_FACTOR-sized percentage range around delay + const jitterMultiplier = 1 + (Math.random() - 0.5) * JITTER_FACTOR; + return delay * jitterMultiplier; +} + +function getRetryDelayFromHeaders(response: Response, retryAttempt: number): number { + // Check for Retry-After header first (RFC 7231), with no jitter + const retryAfter = response.headers.get("Retry-After"); + if (retryAfter) { + // Parse as number of seconds... + const retryAfterSeconds = parseInt(retryAfter, 10); + if (!isNaN(retryAfterSeconds) && retryAfterSeconds > 0) { + return Math.min(retryAfterSeconds * 1000, MAX_RETRY_DELAY); + } + + // ...or as an HTTP date; both are valid + const retryAfterDate = new Date(retryAfter); + if (!isNaN(retryAfterDate.getTime())) { + const delay = retryAfterDate.getTime() - Date.now(); + if (delay > 0) { + return Math.min(Math.max(delay, 0), MAX_RETRY_DELAY); + } + } + } + + // Then check for industry-standard X-RateLimit-Reset header, with positive jitter + const rateLimitReset = response.headers.get("X-RateLimit-Reset"); + if (rateLimitReset) { + const resetTime = parseInt(rateLimitReset, 10); + if (!isNaN(resetTime)) { + // Assume Unix timestamp in epoch seconds + const delay = resetTime * 1000 - Date.now(); + if (delay > 0) { + return addPositiveJitter(Math.min(delay, MAX_RETRY_DELAY)); + } + } + } + + // Fall back to exponential backoff, with symmetric jitter + return addSymmetricJitter(Math.min(INITIAL_RETRY_DELAY * Math.pow(2, retryAttempt), MAX_RETRY_DELAY)); +} + +export async function requestWithRetries( + requestFn: () => Promise, + maxRetries: number = DEFAULT_MAX_RETRIES, +): Promise { + let response: Response = await requestFn(); + + for (let i = 0; i < maxRetries; ++i) { + if ([408, 429].includes(response.status) || response.status >= 500) { + // Get delay with appropriate jitter applied + const delay = getRetryDelayFromHeaders(response, i); + + await new Promise((resolve) => setTimeout(resolve, delay)); + response = await requestFn(); + } else { + break; + } + } + return response!; +} diff --git a/src/core/fetcher/signals.ts b/src/core/fetcher/signals.ts new file mode 100644 index 00000000..a8d32a2e --- /dev/null +++ b/src/core/fetcher/signals.ts @@ -0,0 +1,38 @@ +const TIMEOUT = "timeout"; + +export function getTimeoutSignal(timeoutMs: number): { signal: AbortSignal; abortId: NodeJS.Timeout } { + const controller = new AbortController(); + const abortId = setTimeout(() => controller.abort(TIMEOUT), timeoutMs); + return { signal: controller.signal, abortId }; +} + +/** + * Returns an abort signal that is getting aborted when + * at least one of the specified abort signals is aborted. + * + * Requires at least node.js 18. + */ +export function anySignal(...args: AbortSignal[] | [AbortSignal[]]): AbortSignal { + // Allowing signals to be passed either as array + // of signals or as multiple arguments. + const signals = (args.length === 1 && Array.isArray(args[0]) ? args[0] : args) as AbortSignal[]; + + const controller = new AbortController(); + + for (const signal of signals) { + if (signal.aborted) { + // Exiting early if one of the signals + // is already aborted. + controller.abort((signal as any)?.reason); + break; + } + + // Listening for signals and removing the listeners + // when at least one symbol is aborted. + signal.addEventListener("abort", () => controller.abort((signal as any)?.reason), { + signal: controller.signal, + }); + } + + return controller.signal; +} diff --git a/src/core/file/exports.ts b/src/core/file/exports.ts new file mode 100644 index 00000000..acda0367 --- /dev/null +++ b/src/core/file/exports.ts @@ -0,0 +1 @@ +export { Uploadable } from "./types.js"; diff --git a/src/core/file/file.ts b/src/core/file/file.ts new file mode 100644 index 00000000..bc4b7e50 --- /dev/null +++ b/src/core/file/file.ts @@ -0,0 +1,186 @@ +import { Uploadable } from "./types.js"; + +export async function toBinaryUploadRequest( + file: Uploadable, +): Promise<{ body: Uploadable.FileLike; headers?: Record }> { + const { data, filename, contentLength, contentType } = await getFileWithMetadata(file); + const request = { + body: data, + headers: {} as Record, + }; + if (filename) { + request.headers["Content-Disposition"] = `attachment; filename="${filename}"`; + } + if (contentType) { + request.headers["Content-Type"] = contentType; + } + if (contentLength != null) { + request.headers["Content-Length"] = contentLength.toString(); + } + return request; +} + +async function getFileWithMetadata(file: Uploadable): Promise { + if (isFileLike(file)) { + return getFileWithMetadata({ + data: file, + }); + } + if ("path" in file) { + const fs = await import("fs"); + if (!fs || !fs.createReadStream) { + throw new Error("File path uploads are not supported in this environment."); + } + const data = fs.createReadStream(file.path); + const contentLength = file.contentLength ?? (await tryGetFileSizeFromPath(file.path)); + const filename = file.filename ?? getNameFromPath(file.path); + return { + data, + filename, + contentType: file.contentType, + contentLength, + }; + } + if ("data" in file) { + const data = file.data; + const contentLength = file.contentLength ?? (await tryGetContentLengthFromFileLike(data)); + const filename = file.filename ?? tryGetNameFromFileLike(data); + return { + data, + filename, + contentType: file.contentType ?? tryGetContentTypeFromFileLike(data), + contentLength, + }; + } + + throw new Error(`Invalid FileUpload of type ${typeof file}: ${JSON.stringify(file)}`); +} + +function isFileLike(value: unknown): value is Uploadable.FileLike { + return ( + isBuffer(value) || + isArrayBufferView(value) || + isArrayBuffer(value) || + isUint8Array(value) || + isBlob(value) || + isFile(value) || + isStreamLike(value) || + isReadableStream(value) + ); +} + +async function tryGetFileSizeFromPath(path: string): Promise { + try { + const fs = await import("fs"); + if (!fs || !fs.promises || !fs.promises.stat) { + return undefined; + } + const fileStat = await fs.promises.stat(path); + return fileStat.size; + } catch (fallbackError) { + return undefined; + } +} + +function tryGetNameFromFileLike(data: Uploadable.FileLike): string | undefined { + if (isNamedValue(data)) { + return data.name; + } + if (isPathedValue(data)) { + return getNameFromPath(data.path.toString()); + } + return undefined; +} + +async function tryGetContentLengthFromFileLike(data: Uploadable.FileLike): Promise { + if (isBuffer(data)) { + return data.length; + } + if (isArrayBufferView(data)) { + return data.byteLength; + } + if (isArrayBuffer(data)) { + return data.byteLength; + } + if (isBlob(data)) { + return data.size; + } + if (isFile(data)) { + return data.size; + } + if (isPathedValue(data)) { + return await tryGetFileSizeFromPath(data.path.toString()); + } + return undefined; +} + +function tryGetContentTypeFromFileLike(data: Uploadable.FileLike): string | undefined { + if (isBlob(data)) { + return data.type; + } + if (isFile(data)) { + return data.type; + } + + return undefined; +} + +function getNameFromPath(path: string): string | undefined { + const lastForwardSlash = path.lastIndexOf("/"); + const lastBackSlash = path.lastIndexOf("\\"); + const lastSlashIndex = Math.max(lastForwardSlash, lastBackSlash); + return lastSlashIndex >= 0 ? path.substring(lastSlashIndex + 1) : path; +} + +type NamedValue = { + name: string; +} & unknown; + +type PathedValue = { + path: string | { toString(): string }; +} & unknown; + +type StreamLike = { + read?: () => unknown; + pipe?: (dest: unknown) => unknown; +} & unknown; + +function isNamedValue(value: unknown): value is NamedValue { + return typeof value === "object" && value != null && "name" in value; +} + +function isPathedValue(value: unknown): value is PathedValue { + return typeof value === "object" && value != null && "path" in value; +} + +function isStreamLike(value: unknown): value is StreamLike { + return typeof value === "object" && value != null && ("read" in value || "pipe" in value); +} + +function isReadableStream(value: unknown): value is ReadableStream { + return typeof value === "object" && value != null && "getReader" in value; +} + +function isBuffer(value: unknown): value is Buffer { + return typeof Buffer !== "undefined" && Buffer.isBuffer && Buffer.isBuffer(value); +} + +function isArrayBufferView(value: unknown): value is ArrayBufferView { + return typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView(value); +} + +function isArrayBuffer(value: unknown): value is ArrayBuffer { + return typeof ArrayBuffer !== "undefined" && value instanceof ArrayBuffer; +} + +function isUint8Array(value: unknown): value is Uint8Array { + return typeof Uint8Array !== "undefined" && value instanceof Uint8Array; +} + +function isBlob(value: unknown): value is Blob { + return typeof Blob !== "undefined" && value instanceof Blob; +} + +function isFile(value: unknown): value is File { + return typeof File !== "undefined" && value instanceof File; +} diff --git a/src/core/file/index.ts b/src/core/file/index.ts new file mode 100644 index 00000000..fc16dd52 --- /dev/null +++ b/src/core/file/index.ts @@ -0,0 +1,2 @@ +export * from "./file.js"; +export * from "./types.js"; diff --git a/src/core/file/types.ts b/src/core/file/types.ts new file mode 100644 index 00000000..531b6927 --- /dev/null +++ b/src/core/file/types.ts @@ -0,0 +1,81 @@ +/** + * A file that can be uploaded. Can be a file-like object (stream, buffer, blob, etc.), + * a path to a file, or an object with a file-like object and metadata. + */ +export type Uploadable = Uploadable.FileLike | Uploadable.FromPath | Uploadable.WithMetadata; + +export namespace Uploadable { + /** + * Various file-like objects that can be used to upload a file. + */ + export type FileLike = + | ArrayBuffer + | ArrayBufferLike + | ArrayBufferView + | Uint8Array + | import("buffer").Buffer + | import("buffer").Blob + | import("buffer").File + | import("stream").Readable + | import("stream/web").ReadableStream + | globalThis.Blob + | globalThis.File + | ReadableStream; + + /** + * A file path with optional metadata, used for uploading a file from the file system. + */ + export type FromPath = { + /** The path to the file to upload */ + path: string; + /** + * Optional override for the file name (defaults to basename of path). + * This is used to set the `Content-Disposition` header in upload requests. + */ + filename?: string; + /** + * Optional MIME type of the file (e.g., 'image/jpeg', 'text/plain'). + * This is used to set the `Content-Type` header in upload requests. + */ + contentType?: string; + /** + * Optional file size in bytes. + * If not provided, the file size will be determined from the file system. + * The content length is used to set the `Content-Length` header in upload requests. + */ + contentLength?: number; + }; + + /** + * A file-like object with metadata, used for uploading files. + */ + export type WithMetadata = { + /** The file data */ + data: FileLike; + /** + * Optional override for the file name (defaults to basename of path). + * This is used to set the `Content-Disposition` header in upload requests. + */ + filename?: string; + /** + * Optional MIME type of the file (e.g., 'image/jpeg', 'text/plain'). + * This is used to set the `Content-Type` header in upload requests. + * + * If not provided, the content type may be determined from the data itself. + * * If the data is a `File`, `Blob`, or similar, the content type will be determined from the file itself, if the type is set. + * * Any other data type will not have a content type set, and the upload request will use `Content-Type: application/octet-stream` instead. + */ + contentType?: string; + /** + * Optional file size in bytes. + * The content length is used to set the `Content-Length` header in upload requests. + * If the content length is not provided and cannot be determined, the upload request will not include the `Content-Length` header, but will use `Transfer-Encoding: chunked` instead. + * + * If not provided, the file size will be determined depending on the data type. + * * If the data is of type `fs.ReadStream` (`createReadStream`), the size will be determined from the file system. + * * If the data is a `Buffer`, `ArrayBuffer`, `Uint8Array`, `Blob`, `File`, or similar, the size will be determined from the data itself. + * * If the data is a `Readable` or `ReadableStream`, the size will not be determined. + */ + contentLength?: number; + }; +} diff --git a/src/core/headers.ts b/src/core/headers.ts new file mode 100644 index 00000000..85836147 --- /dev/null +++ b/src/core/headers.ts @@ -0,0 +1,43 @@ +import * as core from "./index.js"; + +export function mergeHeaders( + ...headersArray: ( + | Record | null | undefined> + | null + | undefined + )[] +): Record> { + const result: Record> = {}; + + for (const [key, value] of headersArray + .filter((headers) => headers != null) + .flatMap((headers) => Object.entries(headers))) { + if (value != null) { + result[key] = value; + } else if (key in result) { + delete result[key]; + } + } + + return result; +} + +export function mergeOnlyDefinedHeaders( + ...headersArray: ( + | Record | null | undefined> + | null + | undefined + )[] +): Record> { + const result: Record> = {}; + + for (const [key, value] of headersArray + .filter((headers) => headers != null) + .flatMap((headers) => Object.entries(headers))) { + if (value != null) { + result[key] = value; + } + } + + return result; +} diff --git a/src/core/index.ts b/src/core/index.ts new file mode 100644 index 00000000..018fe286 --- /dev/null +++ b/src/core/index.ts @@ -0,0 +1,4 @@ +export * from "./fetcher/index.js"; +export * from "./runtime/index.js"; +export * as url from "./url/index.js"; +export * as file from "./file/index.js"; diff --git a/src/core/json.ts b/src/core/json.ts new file mode 100644 index 00000000..c052f324 --- /dev/null +++ b/src/core/json.ts @@ -0,0 +1,27 @@ +/** + * Serialize a value to JSON + * @param value A JavaScript value, usually an object or array, to be converted. + * @param replacer A function that transforms the results. + * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. + * @returns JSON string + */ +export const toJson = ( + value: unknown, + replacer?: (this: unknown, key: string, value: unknown) => unknown, + space?: string | number, +): string => { + return JSON.stringify(value, replacer, space); +}; + +/** + * Parse JSON string to object, array, or other type + * @param text A valid JSON string. + * @param reviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is. + * @returns Parsed object, array, or other type + */ +export function fromJson( + text: string, + reviver?: (this: unknown, key: string, value: unknown) => unknown, +): T { + return JSON.parse(text, reviver); +} diff --git a/src/core/runtime/index.ts b/src/core/runtime/index.ts new file mode 100644 index 00000000..cfab23f9 --- /dev/null +++ b/src/core/runtime/index.ts @@ -0,0 +1 @@ +export { RUNTIME } from "./runtime.js"; diff --git a/src/core/runtime/runtime.ts b/src/core/runtime/runtime.ts new file mode 100644 index 00000000..08fd2563 --- /dev/null +++ b/src/core/runtime/runtime.ts @@ -0,0 +1,133 @@ +interface DenoGlobal { + version: { + deno: string; + }; +} + +interface BunGlobal { + version: string; +} + +declare const Deno: DenoGlobal | undefined; +declare const Bun: BunGlobal | undefined; +declare const EdgeRuntime: string | undefined; +declare const self: typeof globalThis.self & { + importScripts?: unknown; +}; + +/** + * A constant that indicates which environment and version the SDK is running in. + */ +export const RUNTIME: Runtime = evaluateRuntime(); + +export interface Runtime { + type: "browser" | "web-worker" | "deno" | "bun" | "node" | "react-native" | "unknown" | "workerd" | "edge-runtime"; + version?: string; + parsedVersion?: number; +} + +function evaluateRuntime(): Runtime { + /** + * A constant that indicates whether the environment the code is running is a Web Browser. + */ + const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined"; + if (isBrowser) { + return { + type: "browser", + version: window.navigator.userAgent, + }; + } + + /** + * A constant that indicates whether the environment the code is running is Cloudflare. + * https://developers.cloudflare.com/workers/runtime-apis/web-standards/#navigatoruseragent + */ + const isCloudflare = typeof globalThis !== "undefined" && globalThis?.navigator?.userAgent === "Cloudflare-Workers"; + if (isCloudflare) { + return { + type: "workerd", + }; + } + + /** + * A constant that indicates whether the environment the code is running is Edge Runtime. + * https://vercel.com/docs/functions/runtimes/edge-runtime#check-if-you're-running-on-the-edge-runtime + */ + const isEdgeRuntime = typeof EdgeRuntime === "string"; + if (isEdgeRuntime) { + return { + type: "edge-runtime", + }; + } + + /** + * A constant that indicates whether the environment the code is running is a Web Worker. + */ + const isWebWorker = + typeof self === "object" && + typeof self?.importScripts === "function" && + (self.constructor?.name === "DedicatedWorkerGlobalScope" || + self.constructor?.name === "ServiceWorkerGlobalScope" || + self.constructor?.name === "SharedWorkerGlobalScope"); + if (isWebWorker) { + return { + type: "web-worker", + }; + } + + /** + * A constant that indicates whether the environment the code is running is Deno. + * FYI Deno spoofs process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions + */ + const isDeno = + typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined"; + if (isDeno) { + return { + type: "deno", + version: Deno.version.deno, + }; + } + + /** + * A constant that indicates whether the environment the code is running is Bun.sh. + */ + const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undefined"; + if (isBun) { + return { + type: "bun", + version: Bun.version, + }; + } + + /** + * A constant that indicates whether the environment the code is running is Node.JS. + */ + const isNode = + typeof process !== "undefined" && + "version" in process && + !!process.version && + "versions" in process && + !!process.versions?.node; + if (isNode) { + return { + type: "node", + version: process.versions.node, + parsedVersion: Number(process.versions.node.split(".")[0]), + }; + } + + /** + * A constant that indicates whether the environment the code is running is in React-Native. + * https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js + */ + const isReactNative = typeof navigator !== "undefined" && navigator?.product === "ReactNative"; + if (isReactNative) { + return { + type: "react-native", + }; + } + + return { + type: "unknown", + }; +} diff --git a/src/core/url/index.ts b/src/core/url/index.ts new file mode 100644 index 00000000..ed5aa0ff --- /dev/null +++ b/src/core/url/index.ts @@ -0,0 +1,2 @@ +export { join } from "./join.js"; +export { toQueryString } from "./qs.js"; diff --git a/src/core/url/join.ts b/src/core/url/join.ts new file mode 100644 index 00000000..200426be --- /dev/null +++ b/src/core/url/join.ts @@ -0,0 +1,80 @@ +export function join(base: string, ...segments: string[]): string { + if (!base) { + return ""; + } + + if (segments.length === 0) { + return base; + } + + if (base.includes("://")) { + let url: URL; + try { + url = new URL(base); + } catch { + // Fallback to path joining if URL is malformed + return joinPath(base, ...segments); + } + + const lastSegment = segments[segments.length - 1]; + const shouldPreserveTrailingSlash = lastSegment && lastSegment.endsWith("/"); + + for (const segment of segments) { + const cleanSegment = trimSlashes(segment); + if (cleanSegment) { + url.pathname = joinPathSegments(url.pathname, cleanSegment); + } + } + + if (shouldPreserveTrailingSlash && !url.pathname.endsWith("/")) { + url.pathname += "/"; + } + + return url.toString(); + } + + return joinPath(base, ...segments); +} + +function joinPath(base: string, ...segments: string[]): string { + if (segments.length === 0) { + return base; + } + + let result = base; + + const lastSegment = segments[segments.length - 1]; + const shouldPreserveTrailingSlash = lastSegment && lastSegment.endsWith("/"); + + for (const segment of segments) { + const cleanSegment = trimSlashes(segment); + if (cleanSegment) { + result = joinPathSegments(result, cleanSegment); + } + } + + if (shouldPreserveTrailingSlash && !result.endsWith("/")) { + result += "/"; + } + + return result; +} + +function joinPathSegments(left: string, right: string): string { + if (left.endsWith("/")) { + return left + right; + } + return left + "/" + right; +} + +function trimSlashes(str: string): string { + if (!str) return str; + + let start = 0; + let end = str.length; + + if (str.startsWith("/")) start = 1; + if (str.endsWith("/")) end = str.length - 1; + + return start === 0 && end === str.length ? str : str.slice(start, end); +} diff --git a/src/core/url/qs.ts b/src/core/url/qs.ts new file mode 100644 index 00000000..13e89be9 --- /dev/null +++ b/src/core/url/qs.ts @@ -0,0 +1,74 @@ +interface QueryStringOptions { + arrayFormat?: "indices" | "repeat"; + encode?: boolean; +} + +const defaultQsOptions: Required = { + arrayFormat: "indices", + encode: true, +} as const; + +function encodeValue(value: unknown, shouldEncode: boolean): string { + if (value === undefined) { + return ""; + } + if (value === null) { + return ""; + } + const stringValue = String(value); + return shouldEncode ? encodeURIComponent(stringValue) : stringValue; +} + +function stringifyObject(obj: Record, prefix = "", options: Required): string[] { + const parts: string[] = []; + + for (const [key, value] of Object.entries(obj)) { + const fullKey = prefix ? `${prefix}[${key}]` : key; + + if (value === undefined) { + continue; + } + + if (Array.isArray(value)) { + if (value.length === 0) { + continue; + } + for (let i = 0; i < value.length; i++) { + const item = value[i]; + if (item === undefined) { + continue; + } + if (typeof item === "object" && !Array.isArray(item) && item !== null) { + const arrayKey = options.arrayFormat === "indices" ? `${fullKey}[${i}]` : fullKey; + parts.push(...stringifyObject(item as Record, arrayKey, options)); + } else { + const arrayKey = options.arrayFormat === "indices" ? `${fullKey}[${i}]` : fullKey; + const encodedKey = options.encode ? encodeURIComponent(arrayKey) : arrayKey; + parts.push(`${encodedKey}=${encodeValue(item, options.encode)}`); + } + } + } else if (typeof value === "object" && value !== null) { + if (Object.keys(value as Record).length === 0) { + continue; + } + parts.push(...stringifyObject(value as Record, fullKey, options)); + } else { + const encodedKey = options.encode ? encodeURIComponent(fullKey) : fullKey; + parts.push(`${encodedKey}=${encodeValue(value, options.encode)}`); + } + } + + return parts; +} + +export function toQueryString(obj: unknown, options?: QueryStringOptions): string { + if (obj == null || typeof obj !== "object") { + return ""; + } + + const parts = stringifyObject(obj as Record, "", { + ...defaultQsOptions, + ...options, + }); + return parts.join("&"); +} diff --git a/src/environments.ts b/src/environments.ts new file mode 100644 index 00000000..f3b62799 --- /dev/null +++ b/src/environments.ts @@ -0,0 +1,24 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export interface DeepgramEnvironmentUrls { + base: string; + production: string; + agent: string; +} + +export const DeepgramEnvironment = { + Production: { + base: "https://api.deepgram.com", + production: "wss://api.deepgram.com", + agent: "wss://agent.deepgram.com", + }, + Agent: { + base: "https://agent.deepgram.com", + production: "wss://api.deepgram.com", + agent: "wss://agent.deepgram.com", + }, +} as const; + +export type DeepgramEnvironment = typeof DeepgramEnvironment.Production | typeof DeepgramEnvironment.Agent; diff --git a/src/errors/DeepgramError.ts b/src/errors/DeepgramError.ts new file mode 100644 index 00000000..f4ca3c00 --- /dev/null +++ b/src/errors/DeepgramError.ts @@ -0,0 +1,55 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import * as core from "../core/index.js"; +import { toJson } from "../core/json.js"; + +export class DeepgramError extends Error { + public readonly statusCode?: number; + public readonly body?: unknown; + public readonly rawResponse?: core.RawResponse; + + constructor({ + message, + statusCode, + body, + rawResponse, + }: { + message?: string; + statusCode?: number; + body?: unknown; + rawResponse?: core.RawResponse; + }) { + super(buildMessage({ message, statusCode, body })); + Object.setPrototypeOf(this, DeepgramError.prototype); + this.statusCode = statusCode; + this.body = body; + this.rawResponse = rawResponse; + } +} + +function buildMessage({ + message, + statusCode, + body, +}: { + message: string | undefined; + statusCode: number | undefined; + body: unknown | undefined; +}): string { + let lines: string[] = []; + if (message != null) { + lines.push(message); + } + + if (statusCode != null) { + lines.push(`Status code: ${statusCode.toString()}`); + } + + if (body != null) { + lines.push(`Body: ${toJson(body, undefined, 2)}`); + } + + return lines.join("\n"); +} diff --git a/src/errors/DeepgramTimeoutError.ts b/src/errors/DeepgramTimeoutError.ts new file mode 100644 index 00000000..cca34f2f --- /dev/null +++ b/src/errors/DeepgramTimeoutError.ts @@ -0,0 +1,10 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +export class DeepgramTimeoutError extends Error { + constructor(message: string) { + super(message); + Object.setPrototypeOf(this, DeepgramTimeoutError.prototype); + } +} diff --git a/src/errors/index.ts b/src/errors/index.ts new file mode 100644 index 00000000..35d3b545 --- /dev/null +++ b/src/errors/index.ts @@ -0,0 +1,2 @@ +export { DeepgramError } from "./DeepgramError.js"; +export { DeepgramTimeoutError } from "./DeepgramTimeoutError.js"; diff --git a/src/exports.ts b/src/exports.ts new file mode 100644 index 00000000..7b70ee14 --- /dev/null +++ b/src/exports.ts @@ -0,0 +1 @@ +export * from "./core/exports.js"; diff --git a/src/index.ts b/src/index.ts index 7e4e873c..ccb69ad6 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,68 +1,5 @@ -import { DeepgramClientOptions, IKeyFactory } from "./lib/types/DeepgramClientOptions"; -import { DeepgramVersionError } from "./lib/errors"; -import DeepgramClient from "./DeepgramClient"; - -/** - * This class is deprecated and should not be used. It throws a `DeepgramVersionError` when instantiated. - * - * @deprecated - * @see https://dpgr.am/js-v3 - */ -class Deepgram { - constructor(protected apiKey: string, protected apiUrl?: string, protected requireSSL?: boolean) { - throw new DeepgramVersionError(); - } -} - -/** - * Creates a new Deepgram client instance. - * - * @param {DeepgramClientArgs} args - Arguments to pass to the Deepgram client constructor. - * @returns A new Deepgram client instance. - */ -function createClient(): DeepgramClient; -function createClient(key?: string | IKeyFactory): DeepgramClient; -function createClient(options?: DeepgramClientOptions): DeepgramClient; -function createClient(key?: string | IKeyFactory, options?: DeepgramClientOptions): DeepgramClient; -function createClient( - keyOrOptions?: string | IKeyFactory | DeepgramClientOptions, - options?: DeepgramClientOptions -): DeepgramClient { - let resolvedOptions: DeepgramClientOptions = {}; - - if (typeof keyOrOptions === "string" || typeof keyOrOptions === "function") { - if (typeof options === "object") { - resolvedOptions = options; - } - - resolvedOptions.key = keyOrOptions; - } else if (typeof keyOrOptions === "object") { - resolvedOptions = keyOrOptions; - } - - return new DeepgramClient(resolvedOptions); -} - -export { createClient, DeepgramClient, Deepgram }; - -/** - * Helpful exports. - */ -export * from "./packages"; -export * from "./lib/types"; -export * from "./lib/enums"; -export * from "./lib/constants"; -export * from "./lib/errors"; -export * from "./lib/helpers"; - -/** - * Captions. These will be tree-shaken if unused. - * - * @see https://github.com/deepgram/deepgram-node-captions - * - * import/export declarations don't do anything but set up an alias to the - * exported variable, they do not count as a "use". Given their semantics, - * they are tracked specially by any bundler and will not adversely affect - * tree-shaking. - */ -export { webvtt, srt } from "@deepgram/captions"; +export * as Deepgram from "./api/index.js"; +export { DeepgramError, DeepgramTimeoutError } from "./errors/index.js"; +export { DeepgramClient } from "./Client.js"; +export { DeepgramEnvironment, DeepgramEnvironmentUrls } from "./environments.js"; +export * from "./exports.js"; diff --git a/src/lib/constants.ts b/src/lib/constants.ts deleted file mode 100644 index 759221f8..00000000 --- a/src/lib/constants.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { convertProtocolToWs } from "./helpers"; -import { isBrowser, isBun, isNode, NODE_VERSION, BUN_VERSION, BROWSER_AGENT } from "./runtime"; -import { version } from "./version"; -import type { DefaultNamespaceOptions, DefaultClientOptions } from "./types"; - -const getAgent = () => { - if (isNode()) { - return `node/${NODE_VERSION}`; - } else if (isBun()) { - return `bun/${BUN_VERSION}`; - } else if (isBrowser()) { - return `javascript ${BROWSER_AGENT}`; - } else { - return `unknown`; - } -}; - -export const DEFAULT_HEADERS = { - "Content-Type": `application/json`, - "X-Client-Info": `@deepgram/sdk; ${isBrowser() ? "browser" : "server"}; v${version}`, - "User-Agent": `@deepgram/sdk/${version} ${getAgent()}`, -}; - -export const DEFAULT_URL = "https://api.deepgram.com"; -export const DEFAULT_AGENT_URL = "wss://agent.deepgram.com"; - -export const DEFAULT_GLOBAL_OPTIONS: Partial = { - fetch: { options: { url: DEFAULT_URL, headers: DEFAULT_HEADERS } }, - websocket: { - options: { url: convertProtocolToWs(DEFAULT_URL), _nodeOnlyHeaders: DEFAULT_HEADERS }, - }, -}; - -export const DEFAULT_AGENT_OPTIONS: Partial = { - fetch: { options: { url: DEFAULT_URL, headers: DEFAULT_HEADERS } }, - websocket: { - options: { url: DEFAULT_AGENT_URL, _nodeOnlyHeaders: DEFAULT_HEADERS }, - }, -}; - -export const DEFAULT_OPTIONS: DefaultClientOptions = { - global: DEFAULT_GLOBAL_OPTIONS, - agent: DEFAULT_AGENT_OPTIONS, -}; - -export enum SOCKET_STATES { - connecting = 0, - open = 1, - closing = 2, - closed = 3, -} - -export enum CONNECTION_STATE { - Connecting = "connecting", - Open = "open", - Closing = "closing", - Closed = "closed", -} diff --git a/src/lib/enums/AgentEvents.ts b/src/lib/enums/AgentEvents.ts deleted file mode 100644 index c8915ea9..00000000 --- a/src/lib/enums/AgentEvents.ts +++ /dev/null @@ -1,74 +0,0 @@ -export enum AgentEvents { - /** - * Built in socket events. - */ - Open = "Open", - Close = "Close", - Error = "Error", - /** - * Audio event? - */ - Audio = "Audio", - /** - * Confirms the successful connection to the websocket. - * { type: "Welcome", request_id: "String"} - */ - Welcome = "Welcome", - /** - * Confirms that your `configure` request was successful. - * { type: "SettingsApplied" } - */ - SettingsApplied = "SettingsApplied", - /** - * Triggered when the agent "hears" the user say something. - * { type: "ConversationText", role: string, content: string } - */ - ConversationText = "ConversationText", - /** - * Triggered when the agent begins receiving user audio. - * { type: "UserStartedSpeaking" } - */ - UserStartedSpeaking = "UserStartedSpeaking", - /** - * Triggered when the user has stopped speaking and the agent is processing the audio. - * { type: "AgentThinking", content: string } - */ - AgentThinking = "AgentThinking", - /** - * A request to call client-side functions. - * { type: "FunctionCallRequest", functions: { id: string; name: string; arguments: string; client_side: boolean}[] } - */ - FunctionCallRequest = "FunctionCallRequest", - /** - * Triggered when the agent begins streaming an audio response. - * YOU WILL ONLY RECEIVE THIS EVENT IF YOU HAVE ENABLED `experimental` IN YOUR CONFIG. - * { type: "AgentStartedSpeaking", total_latency: number, tts_latency: number, ttt_latency: number } - */ - AgentStartedSpeaking = "AgentStartedSpeaking", - /** - * Triggered when the agent has finished streaming an audio response. - * { type: "AgentAudioDone" } - */ - AgentAudioDone = "AgentAudioDone", - /** - * This event is only emitted when you send an `InjectAgentMessage` request while - * the user is currently speaking or the server is processing user audio. - * { type: "InjectionRefused", message: string } - */ - InjectionRefused = "InjectionRefused", - /** - * A successful response to the `UpdateInstructions` request. - * { type: "PromptUpdated" } - */ - PromptUpdated = "PromptUpdated", - /** - * A successful response to the `UpdateSpeak` request. - * { type: "SpeakUpdated" } - */ - SpeakUpdated = "SpeakUpdated", - - /** - * Catch all for any other message event - */ - Unhandled = "Unhandled", -} diff --git a/src/lib/enums/LiveConnectionState.ts b/src/lib/enums/LiveConnectionState.ts deleted file mode 100644 index 4fef1bc8..00000000 --- a/src/lib/enums/LiveConnectionState.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { SOCKET_STATES } from "../constants"; - -/** - * Enum representing the different states of a live connection. - * - * @deprecated Since 3.4. Use `SOCKET_STATES` for generic socket connection states instead. - */ -export enum LiveConnectionState { - CONNECTING = SOCKET_STATES.connecting, - OPEN = SOCKET_STATES.open, - CLOSING = SOCKET_STATES.closing, - CLOSED = SOCKET_STATES.closed, -} diff --git a/src/lib/enums/LiveTTSEvents.ts b/src/lib/enums/LiveTTSEvents.ts deleted file mode 100644 index 6c39a47e..00000000 --- a/src/lib/enums/LiveTTSEvents.ts +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Enumeration of events related to live text-to-speech synthesis. - * - * - `Open`: Built-in socket event for when the connection is opened. - * - `Close`: Built-in socket event for when the connection is closed. - * - `Error`: Built-in socket event for when an error occurs. - * - `Metadata`: Event for when metadata is received. - * - `Flushed`: Event for when the server has flushed the buffer. - * - `Warning`: Event for when a warning is received. - * - `Unhandled`: Catch-all event for any other message event. - */ -export enum LiveTTSEvents { - /** - * Built in socket events. - */ - Open = "Open", - Close = "Close", - Error = "Error", - - /** - * Message { type: string } - */ - Metadata = "Metadata", - Flushed = "Flushed", - Warning = "Warning", - - /** - * Audio data event. - */ - Audio = "Audio", - - /** - * Catch all for any other message event - */ - Unhandled = "Unhandled", -} diff --git a/src/lib/enums/LiveTranscriptionEvents.ts b/src/lib/enums/LiveTranscriptionEvents.ts deleted file mode 100644 index 022eb94f..00000000 --- a/src/lib/enums/LiveTranscriptionEvents.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Enumeration of events related to live transcription. - * - * - `Open`: Built-in socket event for when the connection is opened. - * - `Close`: Built-in socket event for when the connection is closed. - * - `Error`: Built-in socket event for when an error occurs. - * - `Transcript`: Event for when a transcript message is received. - * - `Metadata`: Event for when metadata is received. - * - `UtteranceEnd`: Event for when an utterance ends. - * - `SpeechStarted`: Event for when speech is detected. - * - `Unhandled`: Catch-all event for any other message event. - */ -export enum LiveTranscriptionEvents { - /** - * Built in socket events. - */ - Open = "open", - Close = "close", - Error = "error", - - /** - * Message { type: string } - */ - Transcript = "Results", - Metadata = "Metadata", - UtteranceEnd = "UtteranceEnd", - SpeechStarted = "SpeechStarted", - - /** - * Catch all for any other message event - */ - Unhandled = "Unhandled", -} diff --git a/src/lib/enums/index.ts b/src/lib/enums/index.ts deleted file mode 100644 index a4a31923..00000000 --- a/src/lib/enums/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from "./AgentEvents"; -export * from "./LiveConnectionState"; -export * from "./LiveTranscriptionEvents"; -export * from "./LiveTTSEvents"; diff --git a/src/lib/errors.ts b/src/lib/errors.ts deleted file mode 100644 index ea1a22b1..00000000 --- a/src/lib/errors.ts +++ /dev/null @@ -1,102 +0,0 @@ -export class DeepgramError extends Error { - protected __dgError = true; - - constructor(message: string) { - super(message); - this.name = "DeepgramError"; - } -} - -export function isDeepgramError(error: unknown): error is DeepgramError { - return typeof error === "object" && error !== null && "__dgError" in error; -} - -export class DeepgramApiError extends DeepgramError { - status: number; - - constructor(message: string, status: number) { - super(message); - this.name = "DeepgramApiError"; - this.status = status; - } - - toJSON() { - return { - name: this.name, - message: this.message, - status: this.status, - }; - } -} - -export class DeepgramUnknownError extends DeepgramError { - originalError: unknown; - - constructor(message: string, originalError: unknown) { - super(message); - this.name = "DeepgramUnknownError"; - this.originalError = originalError; - } -} - -export class DeepgramVersionError extends DeepgramError { - constructor() { - super( - `You are attempting to use an old format for a newer SDK version. Read more here: https://dpgr.am/js-v3` - ); - - this.name = "DeepgramVersionError"; - } -} - -/** - * Enhanced WebSocket error that captures additional debugging information - * including status codes, request IDs, and response headers when available. - */ -export class DeepgramWebSocketError extends DeepgramError { - originalEvent?: ErrorEvent | Event; - statusCode?: number; - requestId?: string; - responseHeaders?: Record; - url?: string; - readyState?: number; - - constructor( - message: string, - options: { - originalEvent?: ErrorEvent | Event; - statusCode?: number; - requestId?: string; - responseHeaders?: Record; - url?: string; - readyState?: number; - } = {} - ) { - super(message); - this.name = "DeepgramWebSocketError"; - this.originalEvent = options.originalEvent; - this.statusCode = options.statusCode; - this.requestId = options.requestId; - this.responseHeaders = options.responseHeaders; - this.url = options.url; - this.readyState = options.readyState; - } - - toJSON() { - return { - name: this.name, - message: this.message, - statusCode: this.statusCode, - requestId: this.requestId, - responseHeaders: this.responseHeaders, - url: this.url, - readyState: this.readyState, - originalEvent: this.originalEvent - ? { - type: this.originalEvent.type, - timeStamp: this.originalEvent.timeStamp, - } - : undefined, - }; - } -} diff --git a/src/lib/fetch.ts b/src/lib/fetch.ts deleted file mode 100644 index 214fe12d..00000000 --- a/src/lib/fetch.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { resolveHeadersConstructor } from "./helpers"; -import crossFetch from "cross-fetch"; -import type { Fetch } from "./types"; - -/** - * Resolves the appropriate fetch function to use, either a custom fetch function provided as an argument, or the global fetch function if available, or the cross-fetch library if the global fetch function is not available. - * - * @param customFetch - An optional custom fetch function to use instead of the global fetch function. - * @returns A fetch function that can be used to make HTTP requests. - */ -export const resolveFetch = (customFetch?: Fetch): Fetch => { - let _fetch: Fetch; - - if (customFetch) { - _fetch = customFetch; - } else if (typeof fetch === "undefined") { - _fetch = crossFetch as unknown as Fetch; - } else { - _fetch = fetch; - } - - return (...args) => _fetch(...args); -}; - -interface FetchWithAuthOptions { - apiKey?: string; - customFetch?: Fetch; - accessToken?: string; -} - -/** - * Resolves a fetch function that includes an "Authorization" header with the provided API key. - * - * @param apiKey - The API key to include in the "Authorization" header. - * @param customFetch - An optional custom fetch function to use instead of the global fetch function. - * @returns A fetch function that can be used to make HTTP requests with the provided API key in the "Authorization" header. - */ -export const fetchWithAuth = ({ - apiKey, - customFetch, - accessToken, -}: Readonly): Fetch => { - const fetch = resolveFetch(customFetch); - const HeadersConstructor = resolveHeadersConstructor(); - - return async (input, init) => { - const headers = new HeadersConstructor(init?.headers); - - if (!headers.has("Authorization")) { - headers.set("Authorization", accessToken ? `Bearer ${accessToken}` : `Token ${apiKey}`); - } - - return fetch(input, { ...init, headers }); - }; -}; - -/** - * Resolves the appropriate Response object to use, either the global Response object if available, or the Response object from the cross-fetch library if the global Response object is not available. - * - * @returns The appropriate Response object to use for making HTTP requests. - */ -export const resolveResponse = async () => { - if (typeof Response === "undefined") { - return (await import("cross-fetch")).Response; - } - - return Response; -}; diff --git a/src/lib/helpers.ts b/src/lib/helpers.ts deleted file mode 100644 index 9d0b16bb..00000000 --- a/src/lib/helpers.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { - DeepgramClientOptions, - FileSource, - PrerecordedSource, - UrlSource, - TextSource, - AnalyzeSource, - LiveSchema, - TranscriptionSchema, -} from "./types"; -import { Headers as CrossFetchHeaders } from "cross-fetch"; -import type { Readable } from "node:stream"; -import merge from "deepmerge"; -import { isBrowser } from "./runtime"; - -export function stripTrailingSlash(url: string): string { - return url.replace(/\/$/, ""); -} - -export function applyDefaults(options: Partial = {}, subordinate: Partial = {}): S { - return merge(subordinate, options); -} - -export function appendSearchParams( - searchParams: URLSearchParams, - options: Record -): void { - Object.keys(options).forEach((i) => { - if (Array.isArray(options[i])) { - const arrayParams = options[i] as Array; - arrayParams.forEach((param) => { - searchParams.append(i, String(param)); - }); - } else { - searchParams.append(i, String(options[i])); - } - }); -} - -export const resolveHeadersConstructor = () => { - if (typeof Headers === "undefined") { - return CrossFetchHeaders; - } - - return Headers; -}; - -export const isUrlSource = ( - providedSource: PrerecordedSource | AnalyzeSource -): providedSource is UrlSource => { - if (providedSource && (providedSource as UrlSource).url) return true; - - return false; -}; - -export const isTextSource = ( - providedSource: PrerecordedSource | AnalyzeSource -): providedSource is TextSource => { - if (providedSource && (providedSource as TextSource).text) return true; - - return false; -}; - -export const isFileSource = (providedSource: PrerecordedSource): providedSource is FileSource => { - if (isReadStreamSource(providedSource) || isBufferSource(providedSource)) return true; - - return false; -}; - -const isBufferSource = (providedSource: PrerecordedSource): providedSource is Buffer => { - return providedSource != null && Buffer.isBuffer(providedSource); -}; - -const isReadStreamSource = (providedSource: PrerecordedSource): providedSource is Readable => { - if (providedSource == null) return false; - - // In browser environments, there's no Readable stream from Node.js - if (isBrowser()) return false; - - // Check for stream-like properties without importing Readable - return ( - typeof providedSource === "object" && - typeof (providedSource as any).pipe === "function" && - typeof (providedSource as any).read === "function" && - typeof (providedSource as any)._readableState === "object" - ); -}; - -export class CallbackUrl extends URL { - public callbackUrl = true; -} - -export const convertProtocolToWs = (url: string) => { - const convert = (string: string) => string.toLowerCase().replace(/^http/, "ws"); - - return convert(url); -}; - -export const buildRequestUrl = ( - endpoint: string, - baseUrl: string | URL, - transcriptionOptions: LiveSchema | TranscriptionSchema -): URL => { - const url = new URL(endpoint, baseUrl); - appendSearchParams(url.searchParams, transcriptionOptions); - - return url; -}; - -export function isLiveSchema(arg: any): arg is LiveSchema { - return arg != null && typeof arg.interim_results !== "undefined"; -} - -export function isDeepgramClientOptions(arg: any): arg is DeepgramClientOptions { - return arg != null && typeof arg.global !== "undefined"; -} - -export const convertLegacyOptions = (optionsArg: DeepgramClientOptions): DeepgramClientOptions => { - const newOptions: DeepgramClientOptions = {}; - - if (optionsArg._experimentalCustomFetch) { - newOptions.global = { - fetch: { - client: optionsArg._experimentalCustomFetch, - }, - }; - } - - optionsArg = merge(optionsArg, newOptions); - - if (optionsArg.restProxy?.url) { - newOptions.global = { - fetch: { - options: { - proxy: { - url: optionsArg.restProxy?.url, - }, - }, - }, - }; - } - - optionsArg = merge(optionsArg, newOptions); - - if (optionsArg.global?.url) { - newOptions.global = { - fetch: { - options: { - url: optionsArg.global.url, - }, - }, - websocket: { - options: { - url: optionsArg.global.url, - }, - }, - }; - } - - optionsArg = merge(optionsArg, newOptions); - - if (optionsArg.global?.headers) { - newOptions.global = { - fetch: { - options: { - headers: optionsArg.global?.headers, - }, - }, - websocket: { - options: { - _nodeOnlyHeaders: optionsArg.global?.headers, - }, - }, - }; - } - - optionsArg = merge(optionsArg, newOptions); - - return optionsArg; -}; diff --git a/src/lib/runtime.ts b/src/lib/runtime.ts deleted file mode 100644 index b7f25d2b..00000000 --- a/src/lib/runtime.ts +++ /dev/null @@ -1,20 +0,0 @@ -export const NODE_VERSION = - typeof process !== "undefined" && process.versions && process.versions.node - ? process.versions.node - : "unknown"; - -export const BUN_VERSION = - typeof process !== "undefined" && process.versions && process.versions.bun - ? process.versions.bun - : "unknown"; - -export const BROWSER_AGENT = - typeof window !== "undefined" && window.navigator && window.navigator.userAgent - ? window.navigator.userAgent - : "unknown"; - -export const isBrowser = () => BROWSER_AGENT !== "unknown"; - -export const isNode = () => NODE_VERSION !== "unknown"; - -export const isBun = () => BUN_VERSION !== "unknown"; diff --git a/src/lib/types/AgentLiveSchema.ts b/src/lib/types/AgentLiveSchema.ts deleted file mode 100644 index a2f81a74..00000000 --- a/src/lib/types/AgentLiveSchema.ts +++ /dev/null @@ -1,92 +0,0 @@ -type Provider = { type: string } & Record; - -type SpeakProvider = { - provider: Provider; - endpoint?: { - url: string; - headers?: Record; - }; -}; - -/** - * @see https://developers.deepgram.com/docs/configure-voice-agent - */ -interface AgentLiveSchema extends Record { - /** - * Set to true to enable experimental features. - * @default false - */ - experimental?: boolean; - /** - * @see https://developers.deepgram.com/docs/the-deepgram-model-improvement-partnership-program - * To opt out of Deepgram Model Improvement Program. - * @default false - */ - mips_opt_out?: boolean; - audio: { - input?: { - /** - * @default "linear16" - */ - encoding: string; - /** - * @default 16000 - */ - sample_rate: number; - }; - /** - * @see https://developers.deepgram.com/docs/tts-media-output-settings#audio-format-combinations - */ - output?: { - encoding?: string; - sample_rate?: number; - bitrate?: number; - /** - * @default "none" - */ - container?: string; - }; - }; - agent: { - /** - * ISO 639-1 language code for agent language. - * @default "en" - */ - language?: string; - listen?: { - provider: Provider; - }; - speak?: SpeakProvider | SpeakProvider[]; - /** - * @see https://developers.deepgram.com/docs/voice-agent-tts-models - */ - think?: { - provider: Provider; - /** - * Optional ONLY if LLM provider is OpenAI or Anthropic. - */ - endpoint?: { - url: string; - headers?: Record; - }; - functions?: { - name?: string; - description?: string; - parameters?: Record; - endpoint?: { - url?: string; - method?: string; - headers?: Record; - }; - }[]; - prompt?: string; - context_length?: number | "max"; - }; - /** - * Optional message the agent will say at the start of the connection. - */ - greeting?: string; - }; -} - -export type { AgentLiveSchema, SpeakProvider }; diff --git a/src/lib/types/AnalyzeSchema.ts b/src/lib/types/AnalyzeSchema.ts deleted file mode 100644 index a15f9604..00000000 --- a/src/lib/types/AnalyzeSchema.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Options for read analysis - */ -interface AnalyzeSchema extends Record { - /** - * @see https://developers.deepgram.com/docs/callback - */ - callback?: string; - - /** - * @see https://developers.deepgram.com/docs/callback#results - */ - callback_method?: "put" | "post"; - - custom_intent?: string | string[]; - - custom_intent_mode?: "strict" | "extended"; - - custom_topic?: string | string[]; - - custom_topic_mode?: "strict" | "extended"; - - intents?: boolean; - - language?: string; - - summarize?: boolean; - - sentiment?: boolean; - - topics?: boolean; - - /** - * @see https://developers.deepgram.com/docs/extra-metadata - */ - extra?: string[] | string; -} - -export type { AnalyzeSchema }; diff --git a/src/lib/types/AsyncAnalyzeResponse.ts b/src/lib/types/AsyncAnalyzeResponse.ts deleted file mode 100644 index ba7dd76f..00000000 --- a/src/lib/types/AsyncAnalyzeResponse.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface AsyncAnalyzeResponse { - request_id: string; -} diff --git a/src/lib/types/AsyncPrerecordedResponse.ts b/src/lib/types/AsyncPrerecordedResponse.ts deleted file mode 100644 index e5a76bb6..00000000 --- a/src/lib/types/AsyncPrerecordedResponse.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface AsyncPrerecordedResponse { - request_id: string; -} diff --git a/src/lib/types/CreateOnPremCredentialsSchema.ts b/src/lib/types/CreateOnPremCredentialsSchema.ts deleted file mode 100644 index 655984bb..00000000 --- a/src/lib/types/CreateOnPremCredentialsSchema.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface CreateOnPremCredentialsSchema extends Record { - comment?: string; - scopes?: string[]; - provider?: string; -} diff --git a/src/lib/types/CreateProjectKeyResponse.ts b/src/lib/types/CreateProjectKeyResponse.ts deleted file mode 100644 index 73b83814..00000000 --- a/src/lib/types/CreateProjectKeyResponse.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface CreateProjectKeyResponse { - api_key_id: string; - key: string; - comment?: string; - scopes: string[]; - tags?: string[]; - created: string; - expiration_date?: string; -} diff --git a/src/lib/types/CreateProjectKeySchema.ts b/src/lib/types/CreateProjectKeySchema.ts deleted file mode 100644 index 9f43b0b5..00000000 --- a/src/lib/types/CreateProjectKeySchema.ts +++ /dev/null @@ -1,15 +0,0 @@ -export type CreateProjectKeySchema = ExpirationOptions | TtlOptions; - -interface ExpirationOptions extends CommonOptions { - expiration_date?: string; -} - -export interface TtlOptions extends CommonOptions { - time_to_live_in_seconds?: number; -} - -interface CommonOptions extends Record { - comment: string; - scopes: string[]; - tags?: string[]; -} diff --git a/src/lib/types/DeepgramClientOptions.ts b/src/lib/types/DeepgramClientOptions.ts deleted file mode 100644 index 4f074fdb..00000000 --- a/src/lib/types/DeepgramClientOptions.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { Fetch, FetchOptions } from "./Fetch"; - -export type IKeyFactory = () => string; -export type IFetch = typeof fetch; -export type IWebSocket = typeof WebSocket; - -interface TransportFetchOptions extends TransportOptions, FetchOptions {} -interface TransportWebSocketOptions extends TransportOptions { - _nodeOnlyHeaders?: { [index: string]: any }; -} - -type TransportUrl = string; - -interface TransportOptions { - url?: TransportUrl; - proxy?: { - url: TransportUrl; - }; -} - -interface ITransport { - client?: C; - options?: O; -} - -export type DefaultNamespaceOptions = { - key?: string | IKeyFactory; - accessToken?: string | IKeyFactory; - fetch: { - options: { url: TransportUrl }; - }; - websocket: { - options: { url: TransportUrl }; - }; -} & NamespaceOptions; - -export interface NamespaceOptions { - key?: string | IKeyFactory; - accessToken?: string | IKeyFactory; - fetch?: ITransport; - websocket?: ITransport; -} - -export type DefaultClientOptions = { - global: Partial; -} & DeepgramClientOptions; - -/** - * Configures the options for a Deepgram client. - * - * The `DeepgramClientOptions` interface defines the configuration options for a Deepgram client. It includes options for various namespaces, such as `global`, `listen`, `manage`, `onprem`, `read`, and `speak`. Each namespace has its own options for configuring the transport, including the URL, proxy, and options for the fetch and WebSocket clients. - * - * The `global` namespace is used to configure options that apply globally to the Deepgram client. The other namespaces are used to configure options specific to different Deepgram API endpoints. - * Support introductory formats: - * - fetch: FetchOptions; - * - _experimentalCustomFetch?: Fetch; - * - restProxy?: { - * url: null | string; - * }; - */ -export interface DeepgramClientOptions { - key?: string | IKeyFactory; - accessToken?: string | IKeyFactory; - global?: NamespaceOptions & { url?: string; headers?: { [index: string]: any } }; - listen?: NamespaceOptions; - manage?: NamespaceOptions; - onprem?: NamespaceOptions; - read?: NamespaceOptions; - speak?: NamespaceOptions; - agent?: NamespaceOptions; - - /** - * @deprecated as of 3.4, use a namespace like `global` instead - */ - fetch?: FetchOptions; - - /** - * @deprecated as of 3.4, use a namespace like `global` instead - */ - _experimentalCustomFetch?: Fetch; - - /** - * @deprecated as of 3.4, use a namespace like `global` instead - */ - restProxy?: { - url: null | string; - }; -} diff --git a/src/lib/types/DeepgramResponse.ts b/src/lib/types/DeepgramResponse.ts deleted file mode 100644 index 5a6c3893..00000000 --- a/src/lib/types/DeepgramResponse.ts +++ /dev/null @@ -1,13 +0,0 @@ -import { DeepgramError } from "../errors"; - -export type DeepgramResponse = SuccessResponse | ErrorResponse; - -interface SuccessResponse { - result: T; - error: null; -} - -interface ErrorResponse { - result: null; - error: DeepgramError; -} diff --git a/src/lib/types/DeepgramSource.ts b/src/lib/types/DeepgramSource.ts deleted file mode 100644 index b9169a72..00000000 --- a/src/lib/types/DeepgramSource.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { Readable } from "node:stream"; - -export type PrerecordedSource = UrlSource | Buffer | Readable; - -export type FileSource = Buffer | Readable; - -export interface UrlSource { - url: string; -} - -export interface TextSource { - text: string; -} - -export type AnalyzeSource = UrlSource | TextSource; diff --git a/src/lib/types/Fetch.ts b/src/lib/types/Fetch.ts deleted file mode 100644 index 0496c325..00000000 --- a/src/lib/types/Fetch.ts +++ /dev/null @@ -1,5 +0,0 @@ -export type Fetch = typeof fetch; - -export type FetchOptions = RequestInit & { method?: RequestMethodType; duplex?: string }; - -export type RequestMethodType = "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; diff --git a/src/lib/types/FunctionCallResponse.ts b/src/lib/types/FunctionCallResponse.ts deleted file mode 100644 index ab74bffa..00000000 --- a/src/lib/types/FunctionCallResponse.ts +++ /dev/null @@ -1,17 +0,0 @@ -/** - * Respond with this when you receive a `FunctionCallRequest` payload. - */ -export interface FunctionCallResponse { - /** - * This must be the ID that was received in the request. - */ - id: string; - /** - * The name of the function being called. - */ - name: string; - /** - * The result of the function call. - */ - content: string; -} diff --git a/src/lib/types/GetModelsResponse.ts b/src/lib/types/GetModelsResponse.ts deleted file mode 100644 index eefe613d..00000000 --- a/src/lib/types/GetModelsResponse.ts +++ /dev/null @@ -1,24 +0,0 @@ -type Model = { - name: string; - canonical_name: string; - architecture: string; - languages?: string[]; - version: string; - uuid: string; - batch?: boolean; - streaming?: boolean; - formatted_output?: boolean; - metadata?: { - accent: string; - color: string; - image: string; - sample: string; - }; -}; - -export type GetModelResponse = Model; - -export type GetModelsResponse = { - stt: Model[]; - tts: Model[]; -}; diff --git a/src/lib/types/GetModelsSchema.ts b/src/lib/types/GetModelsSchema.ts deleted file mode 100644 index b0f34982..00000000 --- a/src/lib/types/GetModelsSchema.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface GetModelsSchema extends Record { - include_outdated?: boolean; -} diff --git a/src/lib/types/GetProjectBalancesResponse.ts b/src/lib/types/GetProjectBalancesResponse.ts deleted file mode 100644 index f3527ea1..00000000 --- a/src/lib/types/GetProjectBalancesResponse.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface GetProjectBalancesResponse { - balances: GetProjectBalanceResponse[]; -} - -export interface GetProjectBalanceResponse { - balance_id: string; - amount: number; - units: string; - purchase: string; -} diff --git a/src/lib/types/GetProjectInvitesResponse.ts b/src/lib/types/GetProjectInvitesResponse.ts deleted file mode 100644 index cb5fce0d..00000000 --- a/src/lib/types/GetProjectInvitesResponse.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface GetProjectInvitesResponse { - invites: Invite[]; -} - -interface Invite { - email: string; - scope: string; -} diff --git a/src/lib/types/GetProjectKeysResponse.ts b/src/lib/types/GetProjectKeysResponse.ts deleted file mode 100644 index ff85c688..00000000 --- a/src/lib/types/GetProjectKeysResponse.ts +++ /dev/null @@ -1,23 +0,0 @@ -export interface GetProjectKeysResponse { - api_keys: GetProjectKeyResponse[]; -} - -export interface GetProjectKeyResponse { - member: Member; - api_key: Key; -} - -interface Member { - member_id: string; - email: string; - first_name: string; - last_name: string; -} - -interface Key { - api_key_id: string; - comment?: string; - scopes: string[]; - tags?: string[]; - created: string; -} diff --git a/src/lib/types/GetProjectMemberScopesResponse.ts b/src/lib/types/GetProjectMemberScopesResponse.ts deleted file mode 100644 index 0103f6bf..00000000 --- a/src/lib/types/GetProjectMemberScopesResponse.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface GetProjectMemberScopesResponse { - scopes: string[]; -} diff --git a/src/lib/types/GetProjectMembersResponse.ts b/src/lib/types/GetProjectMembersResponse.ts deleted file mode 100644 index 8f1e28a4..00000000 --- a/src/lib/types/GetProjectMembersResponse.ts +++ /dev/null @@ -1,11 +0,0 @@ -export interface GetProjectMembersResponse { - members: Member[]; -} - -interface Member { - member_id: string; - first_name: string; - last_name: string; - scopes: string[]; - email: string; -} diff --git a/src/lib/types/GetProjectResponse.ts b/src/lib/types/GetProjectResponse.ts deleted file mode 100644 index ce338334..00000000 --- a/src/lib/types/GetProjectResponse.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface GetProjectResponse { - project_id: string; - name: string; - company: string; -} diff --git a/src/lib/types/GetProjectUsageFieldsResponse.ts b/src/lib/types/GetProjectUsageFieldsResponse.ts deleted file mode 100644 index 42ff55a4..00000000 --- a/src/lib/types/GetProjectUsageFieldsResponse.ts +++ /dev/null @@ -1,14 +0,0 @@ -export interface GetProjectUsageFieldsResponse { - tags: string[]; - models: UsageModel[]; - processing_methods: string[]; - languages: string[]; - features: string[]; -} - -interface UsageModel { - name: string; - language: string; - version: string; - model_id: string; -} diff --git a/src/lib/types/GetProjectUsageFieldsSchema.ts b/src/lib/types/GetProjectUsageFieldsSchema.ts deleted file mode 100644 index 4b7004bf..00000000 --- a/src/lib/types/GetProjectUsageFieldsSchema.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface GetProjectUsageFieldsSchema extends Record { - start?: string; - end: string; -} diff --git a/src/lib/types/GetProjectUsageRequestsResponse.ts b/src/lib/types/GetProjectUsageRequestsResponse.ts deleted file mode 100644 index 6b67901f..00000000 --- a/src/lib/types/GetProjectUsageRequestsResponse.ts +++ /dev/null @@ -1,49 +0,0 @@ -export interface GetProjectUsageRequestsResponse { - page: number; - limit: number; - requests: GetProjectUsageRequestResponse[]; -} - -export interface GetProjectUsageRequestResponse { - request_id: string; - created: string; - path: string; - api_key_id: string; - response: { - details: { - usd?: number; - duration?: number; - total_audio?: number; - channels?: number; - streams?: number; - models?: string[]; - method?: string; - tags?: string[]; - features?: string[]; - config?: { - alternatives?: number; - callback?: string; - diarize?: boolean; - keywords?: string[]; - language?: string; - model?: string; - multichannel?: boolean; - ner?: boolean; - numerals?: boolean; - profanity_filter?: boolean; - punctuate?: boolean; - redact?: string[]; - search?: string[]; - utterances?: boolean; - [key: string]: unknown; - }; - }; - code?: number; - completed?: string; - }; - callback?: { - attempts?: number; - code?: number; - completed?: string; - }; -} diff --git a/src/lib/types/GetProjectUsageRequestsSchema.ts b/src/lib/types/GetProjectUsageRequestsSchema.ts deleted file mode 100644 index 1b4b4e3e..00000000 --- a/src/lib/types/GetProjectUsageRequestsSchema.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface GetProjectUsageRequestsSchema extends Record { - start?: string; - end?: string; - limit?: number; - status?: string; -} diff --git a/src/lib/types/GetProjectUsageSummaryResponse.ts b/src/lib/types/GetProjectUsageSummaryResponse.ts deleted file mode 100644 index c19687a9..00000000 --- a/src/lib/types/GetProjectUsageSummaryResponse.ts +++ /dev/null @@ -1,17 +0,0 @@ -export interface GetProjectUsageSummaryResponse { - start: string; - end: string; - resolution: { - units: string; - amount: number; - }; - results: UsageSummary[]; -} - -interface UsageSummary { - start: string; - end: string; - hours: number; - total_hours: number; - requests: number; -} diff --git a/src/lib/types/GetProjectUsageSummarySchema.ts b/src/lib/types/GetProjectUsageSummarySchema.ts deleted file mode 100644 index e91421f3..00000000 --- a/src/lib/types/GetProjectUsageSummarySchema.ts +++ /dev/null @@ -1,23 +0,0 @@ -export interface GetProjectUsageSummarySchema extends Record { - start?: string; - end: string; - accessor?: string; - tag?: string; - method?: string; - model?: string; - multichannel?: boolean; - interim_results?: boolean; - punctuate?: boolean; - ner?: boolean; - utterances?: boolean; - replace?: boolean; - profanity_filter?: boolean; - keywords?: boolean; - detect_topics?: boolean; - diarize?: boolean; - search?: boolean; - redact?: boolean; - alternatives?: boolean; - numerals?: boolean; - smart_format?: boolean; -} diff --git a/src/lib/types/GetProjectsResponse.ts b/src/lib/types/GetProjectsResponse.ts deleted file mode 100644 index 316ed39b..00000000 --- a/src/lib/types/GetProjectsResponse.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface GetProjectsResponse { - projects: Project[]; -} - -interface Project { - project_id: string; - name: string; -} diff --git a/src/lib/types/GetTokenDetailsResponse.ts b/src/lib/types/GetTokenDetailsResponse.ts deleted file mode 100644 index 23367434..00000000 --- a/src/lib/types/GetTokenDetailsResponse.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface GetTokenDetailsResponse { - [key: string]: unknown; -} diff --git a/src/lib/types/GrantTokenResponse.ts b/src/lib/types/GrantTokenResponse.ts deleted file mode 100644 index 8560b8ee..00000000 --- a/src/lib/types/GrantTokenResponse.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface GrantTokenResponse { - access_token: string; - expires_in: number; -} diff --git a/src/lib/types/GrantTokenSchema.ts b/src/lib/types/GrantTokenSchema.ts deleted file mode 100644 index 692b6e45..00000000 --- a/src/lib/types/GrantTokenSchema.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface GrantTokenSchema extends Record { - /** - * Time to live in seconds for the token. Defaults to 30 seconds. - * @minimum 1 - * @maximum 3600 - * @example 30 - */ - ttl_seconds?: number; -} diff --git a/src/lib/types/ListOnPremCredentialsResponse.ts b/src/lib/types/ListOnPremCredentialsResponse.ts deleted file mode 100644 index bc979dc1..00000000 --- a/src/lib/types/ListOnPremCredentialsResponse.ts +++ /dev/null @@ -1,17 +0,0 @@ -export interface ListOnPremCredentialsResponse { - distribution_credentials: OnPremCredentialResponse[]; -} - -export interface OnPremCredentialResponse { - member: { - member_id: string; - email: string; - }; - distribution_credentials: { - distribution_credentials_id: string; - provider: string; - comment: string; - scopes: string[]; - created: string; - }; -} diff --git a/src/lib/types/LiveConfigOptions.ts b/src/lib/types/LiveConfigOptions.ts deleted file mode 100644 index 47b60c87..00000000 --- a/src/lib/types/LiveConfigOptions.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { LiveSchema } from "./TranscriptionSchema"; - -/** - * Partial configuration options for the LiveSchema, including: - * - `numerals`: Configures how numerals are handled in the live transcription. - */ -export type LiveConfigOptions = Partial>; diff --git a/src/lib/types/LiveMetadataEvent.ts b/src/lib/types/LiveMetadataEvent.ts deleted file mode 100644 index b623615a..00000000 --- a/src/lib/types/LiveMetadataEvent.ts +++ /dev/null @@ -1,9 +0,0 @@ -export interface LiveMetadataEvent { - type: "Metadata"; - transaction_key: string; - request_id: string; - sha256: string; - created: string; - duration: number; - channels: number; -} diff --git a/src/lib/types/LiveTranscriptionEvent.ts b/src/lib/types/LiveTranscriptionEvent.ts deleted file mode 100644 index 9938f9ab..00000000 --- a/src/lib/types/LiveTranscriptionEvent.ts +++ /dev/null @@ -1,34 +0,0 @@ -export interface LiveTranscriptionEvent { - type: "Results"; - channel_index: number[]; - duration: number; - start: number; - is_final?: boolean; - speech_final?: boolean; - channel: { - alternatives: { - transcript: string; - confidence: number; - languages: string[]; - words: { - word: string; - start: number; - end: number; - confidence: number; - language: string; - punctuated_word: string; - speaker?: number; - }[]; - }[]; - }; - metadata: { - request_id: string; - model_info: { - name: string; - version: string; - arch: string; - }; - model_uuid: string; - }; - from_finalize?: boolean; -} diff --git a/src/lib/types/MessageResponse.ts b/src/lib/types/MessageResponse.ts deleted file mode 100644 index a2c23cc1..00000000 --- a/src/lib/types/MessageResponse.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface MessageResponse { - message: string; -} diff --git a/src/lib/types/SendProjectInviteSchema.ts b/src/lib/types/SendProjectInviteSchema.ts deleted file mode 100644 index 45dc78b4..00000000 --- a/src/lib/types/SendProjectInviteSchema.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface SendProjectInviteSchema extends Record { - email: string; - scope: string; -} diff --git a/src/lib/types/SpeakSchema.ts b/src/lib/types/SpeakSchema.ts deleted file mode 100644 index 3f37aa81..00000000 --- a/src/lib/types/SpeakSchema.ts +++ /dev/null @@ -1,29 +0,0 @@ -export interface SpeakSchema extends Record { - /** - * The model, voice, language, and version of the voice. - * Follows the format of[modelname]-[voicename]-[language]-[version]. - */ - model?: string; - - /** - * Encoding options for the output audio. Default is 'mp3'. - */ - encoding?: "linear16" | "mulaw" | "alaw" | "mp3" | "opus" | "flac" | "aac"; - - /** - * File format wrapper for the audio. - */ - container?: string; - - /** - * Sample rate of the audio output. - */ - sample_rate?: number; - - /** - * Bit rate of the audio output. - */ - bit_rate?: number; - - [key: string]: unknown; -} diff --git a/src/lib/types/SpeechStartedEvent.ts b/src/lib/types/SpeechStartedEvent.ts deleted file mode 100644 index 2a8bdaba..00000000 --- a/src/lib/types/SpeechStartedEvent.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface SpeechStartedEvent { - type: "SpeechStarted"; - channel: number[]; - timestamp: number; -} diff --git a/src/lib/types/SyncAnalyzeResponse.ts b/src/lib/types/SyncAnalyzeResponse.ts deleted file mode 100644 index d56fc85d..00000000 --- a/src/lib/types/SyncAnalyzeResponse.ts +++ /dev/null @@ -1,91 +0,0 @@ -export interface SyncAnalyzeResponse { - model_uuid: string; - metadata: Metadata; - results: Results; -} - -interface IntentsInfo { - model_uuid: string; - input_tokens: number; - output_tokens: number; -} - -interface SentimentInfo { - model_uuid: string; - input_tokens: number; - output_tokens: number; -} - -interface SummaryInfo { - model_uuid: string; - input_tokens: number; - output_tokens: number; -} - -interface TopicsInfo { - model_uuid: string; - input_tokens: number; - output_tokens: number; -} - -interface Metadata { - request_id: string; - created: string; - language: string; - intents_info: IntentsInfo; - sentiment_info: SentimentInfo; - summary_info: SummaryInfo; - topics_info: TopicsInfo; - extra?: { - [key: string]: unknown; - }; -} - -interface Average { - sentiment: string; - sentiment_score: number; -} - -interface Summary { - text: string; -} - -interface Topic { - topic: string; - confidence_score: number; -} - -interface Intent { - intent: string; - confidence_score: number; -} - -interface Segment { - text: string; - start_word: number; - end_word: number; - sentiment: "positive" | "neutral" | "negative"; - sentiment_score?: number; - topics?: Topic[]; - intents?: Intent[]; -} - -interface Sentiments { - segments: Segment[]; - average: Average; -} - -interface Topics { - segments: Segment[]; -} - -interface Intents { - segments: Segment[]; -} - -interface Results { - sentiments?: Sentiments; - summary?: Summary; - topics?: Topics; - intents?: Intents; -} diff --git a/src/lib/types/SyncPrerecordedResponse.ts b/src/lib/types/SyncPrerecordedResponse.ts deleted file mode 100644 index a0b51229..00000000 --- a/src/lib/types/SyncPrerecordedResponse.ts +++ /dev/null @@ -1,213 +0,0 @@ -export interface SyncPrerecordedResponse { - metadata: Metadata; - results: Result; -} - -interface Alternative { - transcript: string; - confidence: number; - words: WordBase[]; - summaries?: Summary[]; - paragraphs?: ParagraphGroup; - entities?: Entity[]; - translations?: Translation[]; - topics?: TopicGroup[]; - languages?: string[]; -} - -interface Channel { - search?: Search[]; - alternatives: Alternative[]; - detected_language?: string; - language_confidence?: number; -} - -interface Entity { - label: string; - value: string; - confidence: number; - start_word: number; - end_word: number; -} - -interface Hit { - confidence: number; - start: number; - end: number; - snippet: string; -} - -interface Metadata { - transaction_key: string; - request_id: string; - sha256: string; - created: string; - duration: number; - channels: number; - models: string[]; - warnings?: Warning[]; - model_info: Record; - summary_info?: SummaryInfo; - intents_info?: IntentsInfo; - sentiment_info?: SentimentInfo; - topics_info?: TopicsInfo; - extra?: { - [key: string]: unknown; - }; -} - -interface ModelInfo { - name: string; - version: string; - arch: string; -} - -interface SummaryInfo { - input_tokens: number; - output_tokens: number; - model_uuid: string; -} - -interface IntentsInfo { - model_uuid: string; - input_tokens: number; - output_tokens: number; -} - -interface SentimentInfo { - model_uuid: string; - input_tokens: number; - output_tokens: number; -} - -interface TopicsInfo { - model_uuid: string; - input_tokens: number; - output_tokens: number; -} - -interface Paragraph { - sentences: Sentence[]; - start: number; - end: number; - num_words: number; - speaker?: number; -} - -interface ParagraphGroup { - transcript: string; - paragraphs: Paragraph[]; -} - -interface Result { - channels: Channel[]; - utterances?: Utterance[]; - summary?: TranscriptionSummary; - sentiments?: Sentiments; - topics?: Topics; - intents?: Intents; -} - -interface Sentiments { - segments: Segment[]; - average: Average; -} - -interface Topics { - segments: Segment[]; -} - -interface Intents { - segments: Segment[]; -} - -interface Intent { - intent: string; - confidence_score: number; -} - -interface Average { - sentiment: string; - sentiment_score: number; -} - -interface Topic { - topic: string; - confidence_score: number; -} - -interface Segment { - text: string; - start_word: number; - end_word: number; - sentiment?: string; - sentiment_score?: number; - topics?: Topic[]; - intents?: Intent[]; -} - -interface Search { - query: string; - hits: Hit[]; -} - -interface Sentence { - text: string; - start: number; - end: number; -} - -interface Summary { - summary?: string; - start_word?: number; - end_word?: number; -} -interface TranscriptionSummary { - result: string; - short: string; -} - -interface Topic { - topic: string; - confidence: number; -} - -interface TopicGroup { - topics: Topic[]; - text: string; - start_word: number; - end_word: number; -} - -interface Translation { - language: string; - translation: string; -} - -interface Utterance { - start: number; - end: number; - confidence: number; - channel: number; - transcript: string; - words: WordBase[]; - speaker?: number; - id: string; -} - -interface Warning { - parameter: string; - type: string; - message: string; -} - -interface WordBase { - word: string; - start: number; - end: number; - confidence: number; - punctuated_word?: string; - speaker?: number; - speaker_confidence?: number; - language?: string; -} diff --git a/src/lib/types/TranscriptionSchema.ts b/src/lib/types/TranscriptionSchema.ts deleted file mode 100644 index cb55ab7f..00000000 --- a/src/lib/types/TranscriptionSchema.ts +++ /dev/null @@ -1,246 +0,0 @@ -/** - * Options for transcription - */ -interface TranscriptionSchema extends Record { - /** - * @see https://developers.deepgram.com/docs/model - */ - model?: string; - - /** - * @deprecated - * @see https://developers.deepgram.com/docs/tier - */ - tier?: string; - - /** - * @see https://developers.deepgram.com/docs/version - */ - version?: string; - - /** - * @see https://developers.deepgram.com/docs/language - */ - language?: string; - - /** - * @see https://developers.deepgram.com/docs/punctuation - */ - punctuate?: boolean; - - /** - * @see https://developers.deepgram.com/docs/profanity-filter - */ - profanity_filter?: boolean; - - /** - * @see https://developers.deepgram.com/docs/redaction - */ - redact?: string[] | string | boolean; - - /** - * @see https://developers.deepgram.com/docs/diarization - */ - diarize?: boolean; - - /** - * @see https://developers.deepgram.com/docs/diarization - */ - diarize_version?: string; - - /** - * @see https://developers.deepgram.com/docs/smart-format - */ - smart_format?: boolean; - - /** - * @see https://developers.deepgram.com/docs/filler-words - */ - filler_words?: boolean; - - /** - * @see https://developers.deepgram.com/docs/multichannel - */ - multichannel?: boolean; - - /** - * @see https://developers.deepgram.com/docs/numerals - * @deprecated - */ - numerals?: boolean; - - /** - * @see https://developers.deepgram.com/docs/search - */ - search?: string[] | string; - - /** - * @see https://developers.deepgram.com/docs/find-and-replace - */ - replace?: string[] | string; - - /** - * @see https://developers.deepgram.com/docs/callback - */ - callback?: string; - - /** - * @see https://developers.deepgram.com/docs/callback#results - */ - callback_method?: "put" | "post"; - - /** - * @see https://developers.deepgram.com/docs/keywords - */ - keywords?: string[] | string; - - /** - * @see https://developers.deepgram.com/docs/keyterm - */ - keyterm?: string[] | string; - - /** - * @see https://developers.deepgram.com/docs/tagging - */ - tag?: string[]; - - /** - * As yet unreleased. - */ - sentiment?: boolean; - - /** - * As yet unreleased. - */ - intents?: boolean; - - /** - * As yet unreleased. - */ - custom_intent?: string[] | string; - - /** - * As yet unreleased. - */ - custom_intent_mode?: "strict" | "extended"; - - /** - * As yet unreleased. - */ - topics?: boolean; - - /** - * As yet unreleased. - */ - custom_topic?: string[] | string; - - /** - * As yet unreleased. - */ - custom_topic_mode?: "strict" | "extended"; - - /** - * @see https://developers.deepgram.com/docs/extra-metadata - */ - extra?: string[] | string; -} - -interface PrerecordedSchema extends TranscriptionSchema { - /** - * @see https://developers.deepgram.com/docs/detect-entities - */ - detect_entities?: boolean; - - /** - * @see https://developers.deepgram.com/docs/language-detection - */ - detect_language?: boolean | string[]; - - /** - * @see https://developers.deepgram.com/docs/topic-detection - */ - detect_topics?: boolean; - - /** - * Alternatives will run your transcription X number of times and return - * that many variations of the transcription, allowing for the selection - * of the most accurate. Cost increases by number of alternatives. - * - * @deprecated - */ - alternatives?: number; - - /** - * @see https://developers.deepgram.com/docs/paragraphs - */ - paragraphs?: boolean; - - /** - * @see https://developers.deepgram.com/docs/summarization - */ - summarize?: boolean | string; - - /** - * @see https://developers.deepgram.com/docs/utterances - */ - utterances?: boolean; - - /** - * @see https://developers.deepgram.com/docs/utterance-split - */ - utt_split?: number; - - /** - * @see https://developers.deepgram.com/docs/smart-format#dictation - */ - dictation?: boolean; - - /** - * @see https://developers.deepgram.com/docs/smart-format#measurements - */ - measurements?: boolean; -} - -interface LiveSchema extends TranscriptionSchema { - /** - * @see https://developers.deepgram.com/docs/channels - */ - channels?: number; - - /** - * @see https://developers.deepgram.com/docs/encoding - */ - encoding?: string; - - /** - * @see https://developers.deepgram.com/docs/sample-rate - */ - sample_rate?: number; - - /** - * @see https://developers.deepgram.com/docs/endpointing - */ - endpointing?: false | number; - - /** - * @see https://developers.deepgram.com/docs/interim-results - */ - interim_results?: boolean; - - /** - * @see https://developers.deepgram.com/docs/smart-format#using-no-delay - */ - no_delay?: boolean; - - /** - * @see https://developers.deepgram.com/docs/understanding-end-of-speech-detection - */ - utterance_end_ms?: number; - - /** - * @see https://developers.deepgram.com/docs/start-of-speech-detection - */ - vad_events?: boolean; -} - -export type { TranscriptionSchema, PrerecordedSchema, LiveSchema }; diff --git a/src/lib/types/UpdateProjectMemberScopeSchema.ts b/src/lib/types/UpdateProjectMemberScopeSchema.ts deleted file mode 100644 index f4a7e64a..00000000 --- a/src/lib/types/UpdateProjectMemberScopeSchema.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface UpdateProjectMemberScopeSchema extends Record { - scope: string; -} diff --git a/src/lib/types/UpdateProjectSchema.ts b/src/lib/types/UpdateProjectSchema.ts deleted file mode 100644 index f5b090e5..00000000 --- a/src/lib/types/UpdateProjectSchema.ts +++ /dev/null @@ -1,4 +0,0 @@ -export interface UpdateProjectSchema extends Record { - name?: string; - company?: string; -} diff --git a/src/lib/types/UtteranceEndEvent.ts b/src/lib/types/UtteranceEndEvent.ts deleted file mode 100644 index 83e241cc..00000000 --- a/src/lib/types/UtteranceEndEvent.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface UtteranceEndEvent { - type: "UtteranceEnd"; - channel: number[]; - last_word_end: number; -} diff --git a/src/lib/types/VoidResponse.ts b/src/lib/types/VoidResponse.ts deleted file mode 100644 index cfb8d74b..00000000 --- a/src/lib/types/VoidResponse.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { DeepgramError } from "../errors"; - -export type VoidResponse = SuccessResponse | ErrorResponse; - -interface SuccessResponse { - error: null; -} - -interface ErrorResponse { - error: DeepgramError; -} diff --git a/src/lib/types/index.ts b/src/lib/types/index.ts deleted file mode 100644 index d0451ad0..00000000 --- a/src/lib/types/index.ts +++ /dev/null @@ -1,45 +0,0 @@ -export * from "./AgentLiveSchema"; -export * from "./AnalyzeSchema"; -export * from "./AsyncAnalyzeResponse"; -export * from "./AsyncPrerecordedResponse"; -export * from "./CreateOnPremCredentialsSchema"; -export * from "./CreateProjectKeyResponse"; -export * from "./CreateProjectKeySchema"; -export * from "./DeepgramClientOptions"; -export * from "./DeepgramResponse"; -export * from "./DeepgramSource"; -export * from "./Fetch"; -export * from "./FunctionCallResponse"; -export * from "./GetModelsResponse"; -export * from "./GetModelsSchema"; -export * from "./GetProjectBalancesResponse"; -export * from "./GetProjectInvitesResponse"; -export * from "./GetProjectKeysResponse"; -export * from "./GetProjectMemberScopesResponse"; -export * from "./GetProjectMembersResponse"; -export * from "./GetProjectResponse"; -export * from "./GetProjectsResponse"; -export * from "./GetProjectUsageFieldsResponse"; -export * from "./GetProjectUsageFieldsSchema"; -export * from "./GetProjectUsageRequestsResponse"; -export * from "./GetProjectUsageRequestsSchema"; -export * from "./GetProjectUsageSummaryResponse"; -export * from "./GetProjectUsageSummarySchema"; -export * from "./GetTokenDetailsResponse"; -export * from "./GrantTokenResponse"; -export * from "./GrantTokenSchema"; -export * from "./ListOnPremCredentialsResponse"; -export * from "./LiveConfigOptions"; -export * from "./LiveMetadataEvent"; -export * from "./LiveTranscriptionEvent"; -export * from "./MessageResponse"; -export * from "./SendProjectInviteSchema"; -export * from "./SpeakSchema"; -export * from "./SpeechStartedEvent"; -export * from "./SyncAnalyzeResponse"; -export * from "./SyncPrerecordedResponse"; -export * from "./TranscriptionSchema"; -export * from "./UpdateProjectMemberScopeSchema"; -export * from "./UpdateProjectSchema"; -export * from "./UtteranceEndEvent"; -export * from "./VoidResponse"; diff --git a/src/lib/version.ts b/src/lib/version.ts deleted file mode 100644 index c4963561..00000000 --- a/src/lib/version.ts +++ /dev/null @@ -1 +0,0 @@ -export const version = "0.0.0-automated"; diff --git a/src/packages/AbstractClient.ts b/src/packages/AbstractClient.ts deleted file mode 100644 index 1668c185..00000000 --- a/src/packages/AbstractClient.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { EventEmitter } from "events"; -import { DEFAULT_OPTIONS, DEFAULT_URL } from "../lib/constants"; -import { DeepgramError } from "../lib/errors"; -import { appendSearchParams, applyDefaults, convertLegacyOptions } from "../lib/helpers"; -import type { - DeepgramClientOptions, - DefaultClientOptions, - DefaultNamespaceOptions, - NamespaceOptions, -} from "../lib/types"; - -export const noop = () => {}; - -/** - * Represents an abstract Deepgram client that provides a base implementation for interacting with the Deepgram API. - * - * The `AbstractClient` class is responsible for: - * - Initializing the Deepgram API key - * - Applying default options for the client and namespace - * - Providing a namespace for organizing API requests - * - * Subclasses of `AbstractClient` should implement the specific functionality for interacting with the Deepgram API. - */ -export abstract class AbstractClient extends EventEmitter { - protected factory: Function | undefined = undefined; - protected key: string | undefined = undefined; - protected accessToken: string | undefined = undefined; - protected options: DefaultClientOptions; - public namespace: string = "global"; - public version: string = "v1"; - public baseUrl: string = DEFAULT_URL; - public logger: Function = noop; - - /** - * Constructs a new instance of the DeepgramClient class with the provided options. - * - * @param options - The options to configure the DeepgramClient instance. - * @param options.key - The Deepgram API key to use for authentication. If not provided, the `DEEPGRAM_API_KEY` environment variable will be used. - * @param options.accessToken - The Deepgram access token to use for authentication. If not provided, the `DEEPGRAM_ACCESS_TOKEN` environment variable will be used. - * @param options.global - Global options that apply to all requests made by the DeepgramClient instance. - * @param options.global.fetch - Options to configure the fetch requests made by the DeepgramClient instance. - * @param options.global.fetch.options - Additional options to pass to the fetch function, such as `url` and `headers`. - * @param options.namespace - Options specific to a particular namespace within the DeepgramClient instance. - */ - constructor(options: DeepgramClientOptions) { - super(); - - // run the factory for the access token if it's a function - if (typeof options.accessToken === "function") { - this.factory = options.accessToken; - this.accessToken = this.factory(); - } else { - this.accessToken = options.accessToken; - } - - // run the factory for the key if it's a function - if (typeof options.key === "function") { - this.factory = options.key; - this.key = this.factory(); - } else { - this.key = options.key; - } - - // implement priority-based credential resolution for environment variables - if (!this.key && !this.accessToken) { - // check for DEEPGRAM_ACCESS_TOKEN first (higher priority) - this.accessToken = process.env.DEEPGRAM_ACCESS_TOKEN as string; - - // if still no access token, fall back to DEEPGRAM_API_KEY (lower priority) - if (!this.accessToken) { - this.key = process.env.DEEPGRAM_API_KEY as string; - } - } - - // if we STILL have neither, throw an error - if (!this.key && !this.accessToken) { - throw new DeepgramError("A deepgram API key or access token is required."); - } - - options = convertLegacyOptions(options); - - /** - * Apply default options. - */ - this.options = applyDefaults( - options, - DEFAULT_OPTIONS - ); - } - - /** - * Sets the version for the current instance of the Deepgram API and returns the instance. - * - * @param version - The version to set for the Deepgram API instance. Defaults to "v1" if not provided. - * @returns The current instance of the AbstractClient with the updated version. - */ - public v(version: string = "v1"): this { - this.version = version; - - return this; - } - - /** - * Gets the namespace options for the current instance of the AbstractClient. - * The namespace options include the default options merged with the global options, - * and the API key for the current instance. - * - * @returns The namespace options for the current instance. - */ - get namespaceOptions(): DefaultNamespaceOptions { - const defaults = applyDefaults( - (this.options as any)[this.namespace], - this.options.global - ); - - return { - ...defaults, - key: this.key, - }; - } - - /** - * Generates a URL for an API endpoint with optional query parameters and transcription options. - * - * @param endpoint - The API endpoint URL, which may contain placeholders for fields. - * @param fields - An optional object containing key-value pairs to replace placeholders in the endpoint URL. - * @param transcriptionOptions - Optional transcription options to include as query parameters in the URL. - * @returns A URL object representing the constructed API request URL. - */ - public getRequestUrl( - endpoint: string, - fields: { [key: string]: string } = { version: this.version }, - transcriptionOptions?: { - [key: string]: unknown; - } - ): URL { - /** - * If we pass in fields without a version, set a version. - */ - fields.version = this.version; - - /** - * Version and template the endpoint for input argument.. - */ - endpoint = endpoint.replace(/:(\w+)/g, function (_, key) { - return fields![key]; - }); - - /** - * Create a URL object. - */ - const url = new URL(endpoint as string, this.baseUrl); - - /** - * If there are transcription options, append them to the request as URL querystring parameters - */ - if (transcriptionOptions) { - appendSearchParams(url.searchParams, transcriptionOptions); - } - - return url; - } - - /** - * Logs the message. - * - * For customized logging, `this.logger` can be overridden. - */ - public log(kind: string, msg: string, data?: any) { - this.logger(kind, msg, data); - } -} diff --git a/src/packages/AbstractLiveClient.ts b/src/packages/AbstractLiveClient.ts deleted file mode 100644 index b25675b4..00000000 --- a/src/packages/AbstractLiveClient.ts +++ /dev/null @@ -1,542 +0,0 @@ -import { AbstractClient, noop } from "./AbstractClient"; -import { CONNECTION_STATE, SOCKET_STATES } from "../lib/constants"; -import type { DeepgramClientOptions, LiveSchema } from "../lib/types"; -import type { WebSocket as WSWebSocket } from "ws"; -import { isBun } from "../lib/runtime"; -import { DeepgramWebSocketError } from "../lib/errors"; - -/** - * Represents a constructor for a WebSocket-like object that can be used in the application. - * The constructor takes the following parameters: - * @param address - The URL or address of the WebSocket server. - * @param _ignored - An optional parameter that is ignored. - * @param options - An optional object containing headers to be included in the WebSocket connection. - * @returns A WebSocket-like object that implements the WebSocketLike interface. - */ -interface WebSocketLikeConstructor { - new( - address: string | URL, - _ignored?: any, - options?: { headers: object | undefined } - ): WebSocketLike; -} - -/** - * Represents the types of WebSocket-like connections that can be used in the application. - * This type is used to provide a common interface for different WebSocket implementations, - * such as the native WebSocket API, a WebSocket wrapper library, or a dummy implementation - * for testing purposes. - */ -type WebSocketLike = WebSocket | WSWebSocket | WSWebSocketDummy; - -/** - * Represents the types of data that can be sent or received over a WebSocket-like connection. - */ -type SocketDataLike = string | ArrayBufferLike | Blob; - -/** - * Represents an error that occurred in a WebSocket-like connection. - * @property {any} error - The underlying error object. - * @property {string} message - A human-readable error message. - * @property {string} type - The type of the error. - */ -// interface WebSocketLikeError { -// error: any; -// message: string; -// type: string; -// } - -/** - * Indicates whether a native WebSocket implementation is available in the current environment. - */ -const NATIVE_WEBSOCKET_AVAILABLE = typeof WebSocket !== "undefined"; - -/** - * Represents an abstract live client that extends the AbstractClient class. - * The AbstractLiveClient class provides functionality for connecting, reconnecting, and disconnecting a WebSocket connection, as well as sending data over the connection. - * Subclasses of this class are responsible for setting up the connection event handlers. - * - * @abstract - */ -export abstract class AbstractLiveClient extends AbstractClient { - public headers: { [key: string]: string }; - public transport: WebSocketLikeConstructor | null; - public conn: WebSocketLike | null = null; - public sendBuffer: Function[] = []; - - constructor(options: DeepgramClientOptions) { - super(options); - - const { - key, - websocket: { options: websocketOptions, client }, - } = this.namespaceOptions; - - if (this.proxy) { - this.baseUrl = websocketOptions.proxy!.url; - } else { - this.baseUrl = websocketOptions.url; - } - - if (client) { - this.transport = client; - } else { - this.transport = null; - } - - if (websocketOptions._nodeOnlyHeaders) { - this.headers = websocketOptions._nodeOnlyHeaders; - } else { - this.headers = {}; - } - - if (!("Authorization" in this.headers)) { - if (this.accessToken) { - this.headers["Authorization"] = `Bearer ${this.accessToken}`; // Use token if available - } else { - this.headers["Authorization"] = `Token ${key}`; // Add default token - } - } - } - - /** - * Connects the socket, unless already connected. - * - * @protected Can only be called from within the class. - */ - protected connect(transcriptionOptions: LiveSchema, endpoint: string): void { - if (this.conn) { - return; - } - - this.reconnect = (options = transcriptionOptions) => { - this.connect(options, endpoint); - }; - - const requestUrl = this.getRequestUrl(endpoint, {}, transcriptionOptions); - const accessToken = this.accessToken; - const apiKey = this.key; - - if (!accessToken && !apiKey) { - throw new Error("No key or access token provided for WebSocket connection."); - } - - /** - * Custom websocket transport - */ - if (this.transport) { - this.conn = new this.transport(requestUrl, undefined, { - headers: this.headers, - }); - this.setupConnection(); - return; - } - - /** - * @summary Bun websocket transport has a bug where it's native WebSocket implementation messes up the headers - * @summary This is a workaround to use the WS package for the websocket connection instead of the native Bun WebSocket - * @summary you can track the issue here - * @link https://github.com/oven-sh/bun/issues/4529 - */ - if (isBun()) { - import("ws").then(({ default: WS }) => { - this.conn = new WS(requestUrl, { - headers: this.headers, - }); - console.log(`Using WS package`); - this.setupConnection(); - }); - return; - } - - /** - * Native websocket transport (browser) - */ - if (NATIVE_WEBSOCKET_AVAILABLE) { - this.conn = new WebSocket( - requestUrl, - accessToken ? ["bearer", accessToken] : ["token", apiKey!] - ); - this.setupConnection(); - return; - } - - /** - * Dummy websocket - */ - this.conn = new WSWebSocketDummy(requestUrl, undefined, { - close: () => { - this.conn = null; - }, - }); - - /** - * WS package for node environment - */ - import("ws").then(({ default: WS }) => { - this.conn = new WS(requestUrl, undefined, { - headers: this.headers, - }); - this.setupConnection(); - }); - } - - /** - * Reconnects the socket using new or existing transcription options. - * - * @param options - The transcription options to use when reconnecting the socket. - */ - public reconnect: (options: LiveSchema) => void = noop; - - /** - * Disconnects the socket from the client. - * - * @param code A numeric status code to send on disconnect. - * @param reason A custom reason for the disconnect. - */ - public disconnect(code?: number, reason?: string): void { - if (this.conn) { - this.conn.onclose = function () { }; // noop - if (code) { - this.conn.close(code, reason ?? ""); - } else { - this.conn.close(); - } - this.conn = null; - } - } - - /** - * Returns the current connection state of the WebSocket connection. - * - * @returns The current connection state of the WebSocket connection. - */ - public connectionState(): CONNECTION_STATE { - switch (this.conn && this.conn.readyState) { - case SOCKET_STATES.connecting: - return CONNECTION_STATE.Connecting; - case SOCKET_STATES.open: - return CONNECTION_STATE.Open; - case SOCKET_STATES.closing: - return CONNECTION_STATE.Closing; - default: - return CONNECTION_STATE.Closed; - } - } - - /** - * Returns the current ready state of the WebSocket connection. - * - * @returns The current ready state of the WebSocket connection. - */ - public getReadyState(): SOCKET_STATES { - return this.conn?.readyState ?? SOCKET_STATES.closed; - } - - /** - * Returns `true` is the connection is open. - */ - public isConnected(): boolean { - return this.connectionState() === CONNECTION_STATE.Open; - } - - /** - * Sends data to the Deepgram API via websocket connection - * @param data Audio data to send to Deepgram - * - * Conforms to RFC #146 for Node.js - does not send an empty byte. - * @see https://github.com/deepgram/deepgram-python-sdk/issues/146 - */ - send(data: SocketDataLike): void { - const callback = async () => { - if (data instanceof Blob) { - if (data.size === 0) { - this.log("warn", "skipping `send` for zero-byte blob", data); - - return; - } - - data = await data.arrayBuffer(); - } - - if (typeof data !== "string") { - if (!data?.byteLength) { - this.log("warn", "skipping `send` for zero-byte payload", data); - - return; - } - } - - this.conn?.send(data); - }; - - if (this.isConnected()) { - callback(); - } else { - this.sendBuffer.push(callback); - } - } - - /** - * Determines whether the current instance should proxy requests. - * @returns {boolean} true if the current instance should proxy requests; otherwise, false - */ - get proxy(): boolean { - return this.key === "proxy" && !!this.namespaceOptions.websocket.options.proxy?.url; - } - - /** - * Extracts enhanced error information from a WebSocket error event. - * This method attempts to capture additional debugging information such as - * status codes, request IDs, and response headers when available. - * - * @example - * ```typescript - * // Enhanced error information is now available in error events: - * connection.on(LiveTranscriptionEvents.Error, (err) => { - * console.error("WebSocket Error:", err.message); - * - * // Access HTTP status code (e.g., 502, 403, etc.) - * if (err.statusCode) { - * console.error(`HTTP Status Code: ${err.statusCode}`); - * } - * - * // Access Deepgram request ID for support tickets - * if (err.requestId) { - * console.error(`Deepgram Request ID: ${err.requestId}`); - * } - * - * // Access WebSocket URL and connection state - * if (err.url) { - * console.error(`WebSocket URL: ${err.url}`); - * } - * - * if (err.readyState !== undefined) { - * const stateNames = ['CONNECTING', 'OPEN', 'CLOSING', 'CLOSED']; - * console.error(`Connection State: ${stateNames[err.readyState]}`); - * } - * - * // Access response headers for additional debugging - * if (err.responseHeaders) { - * console.error("Response Headers:", err.responseHeaders); - * } - * - * // Access the enhanced error object for detailed debugging - * if (err.error?.name === 'DeepgramWebSocketError') { - * console.error("Enhanced Error Details:", err.error.toJSON()); - * } - * }); - * ``` - * - * @param event - The error event from the WebSocket - * @param conn - The WebSocket connection object - * @returns Enhanced error information object - */ - protected extractErrorInformation( - event: ErrorEvent | Event, - conn?: WebSocketLike - ): { - statusCode?: number; - requestId?: string; - responseHeaders?: Record; - url?: string; - readyState?: number; - } { - const errorInfo: { - statusCode?: number; - requestId?: string; - responseHeaders?: Record; - url?: string; - readyState?: number; - } = {}; - - // Extract basic connection information - if (conn) { - errorInfo.readyState = conn.readyState; - errorInfo.url = typeof conn.url === "string" ? conn.url : conn.url?.toString(); - } - - // Try to extract additional information from the WebSocket connection - // This works with the 'ws' package which exposes more detailed error information - if (conn && typeof conn === "object") { - const wsConn = conn as any; - - // Extract status code if available (from 'ws' package) - if (wsConn._req && wsConn._req.res) { - errorInfo.statusCode = wsConn._req.res.statusCode; - - // Extract response headers if available - if (wsConn._req.res.headers) { - errorInfo.responseHeaders = { ...wsConn._req.res.headers }; - - // Extract request ID from Deepgram response headers - const requestId = - wsConn._req.res.headers["dg-request-id"] || wsConn._req.res.headers["x-dg-request-id"]; - if (requestId) { - errorInfo.requestId = requestId; - } - } - } - - // For native WebSocket, try to extract information from the event - if (event && "target" in event && event.target) { - const target = event.target as any; - if (target.url) { - errorInfo.url = target.url; - } - if (target.readyState !== undefined) { - errorInfo.readyState = target.readyState; - } - } - } - - return errorInfo; - } - - /** - * Creates an enhanced error object with additional debugging information. - * This method provides backward compatibility by including both the original - * error event and enhanced error information. - * - * @param event - The original error event - * @param enhancedInfo - Additional error information extracted from the connection - * @returns An object containing both original and enhanced error information - */ - protected createEnhancedError( - event: ErrorEvent | Event, - enhancedInfo: { - statusCode?: number; - requestId?: string; - responseHeaders?: Record; - url?: string; - readyState?: number; - } - ) { - // Create the enhanced error for detailed debugging - const enhancedError = new DeepgramWebSocketError( - (event as ErrorEvent).message || "WebSocket connection error", - { - originalEvent: event, - ...enhancedInfo, - } - ); - - // Return an object that maintains backward compatibility - // while providing enhanced information - return { - // Original event for backward compatibility - ...event, - // Enhanced error information - error: enhancedError, - // Additional fields for easier access - statusCode: enhancedInfo.statusCode, - requestId: enhancedInfo.requestId, - responseHeaders: enhancedInfo.responseHeaders, - url: enhancedInfo.url, - readyState: enhancedInfo.readyState, - // Enhanced message with more context - message: this.buildEnhancedErrorMessage(event, enhancedInfo), - }; - } - - /** - * Builds an enhanced error message with additional context information. - * - * @param event - The original error event - * @param enhancedInfo - Additional error information - * @returns A more descriptive error message - */ - protected buildEnhancedErrorMessage( - event: ErrorEvent | Event, - enhancedInfo: { - statusCode?: number; - requestId?: string; - responseHeaders?: Record; - url?: string; - readyState?: number; - } - ): string { - let message = (event as ErrorEvent).message || "WebSocket connection error"; - - const details: string[] = []; - - if (enhancedInfo.statusCode) { - details.push(`Status: ${enhancedInfo.statusCode}`); - } - - if (enhancedInfo.requestId) { - details.push(`Request ID: ${enhancedInfo.requestId}`); - } - - if (enhancedInfo.readyState !== undefined) { - const stateNames = ["CONNECTING", "OPEN", "CLOSING", "CLOSED"]; - const stateName = - stateNames[enhancedInfo.readyState] || `Unknown(${enhancedInfo.readyState})`; - details.push(`Ready State: ${stateName}`); - } - - if (enhancedInfo.url) { - details.push(`URL: ${enhancedInfo.url}`); - } - - if (details.length > 0) { - message += ` (${details.join(", ")})`; - } - - return message; - } - - /** - * Sets up the standard connection event handlers (open, close, error) for WebSocket connections. - * This method abstracts the common connection event registration pattern used across all live clients. - * - * @param events - Object containing the event constants for the specific client type - * @param events.Open - Event constant for connection open - * @param events.Close - Event constant for connection close - * @param events.Error - Event constant for connection error - * @protected - */ - protected setupConnectionEvents(events: { Open: string; Close: string; Error: string }): void { - if (this.conn) { - this.conn.onopen = () => { - this.emit(events.Open, this); - }; - - this.conn.onclose = (event: any) => { - this.emit(events.Close, event); - }; - - this.conn.onerror = (event: ErrorEvent) => { - const enhancedInfo = this.extractErrorInformation(event, this.conn || undefined); - const enhancedError = this.createEnhancedError(event, enhancedInfo); - this.emit(events.Error, enhancedError); - }; - } - } - - /** - * Sets up the connection event handlers. - * - * @abstract Requires subclasses to set up context aware event handlers. - */ - abstract setupConnection(): void; -} - -class WSWebSocketDummy { - binaryType: string = "arraybuffer"; - close: Function; - onclose: Function = () => { }; - onerror: Function = () => { }; - onmessage: Function = () => { }; - onopen: Function = () => { }; - readyState: number = SOCKET_STATES.connecting; - send: Function = () => { }; - url: string | URL | null = null; - - constructor(address: URL, _protocols: undefined, options: { close: Function }) { - this.url = address.toString(); - this.close = options.close; - } -} - -export { AbstractLiveClient as AbstractWsClient }; diff --git a/src/packages/AbstractRestClient.ts b/src/packages/AbstractRestClient.ts deleted file mode 100644 index d36e92aa..00000000 --- a/src/packages/AbstractRestClient.ts +++ /dev/null @@ -1,223 +0,0 @@ -import { DeepgramApiError, DeepgramError, DeepgramUnknownError } from "../lib/errors"; -import type { Readable } from "node:stream"; -import { fetchWithAuth, resolveResponse } from "../lib/fetch"; -import type { Fetch, FetchOptions, RequestMethodType } from "../lib/types/Fetch"; -import { AbstractClient } from "./AbstractClient"; -import { DeepgramClientOptions } from "../lib/types"; -import { isBrowser } from "../lib/runtime"; -import merge from "deepmerge"; - -/** - * An abstract class that extends `AbstractClient` and provides a base implementation for a REST-based API client. - * This class handles authentication, error handling, and other common functionality for REST API clients. - */ -export abstract class AbstractRestClient extends AbstractClient { - protected fetch: Fetch; - - /** - * Constructs a new instance of the `AbstractRestClient` class with the provided options. - * - * @param options - The client options to use for this instance. - * @throws {DeepgramError} If the client is being used in a browser and no proxy is provided. - */ - constructor(options: DeepgramClientOptions) { - super(options); - - if (isBrowser() && !this.proxy) { - throw new DeepgramError( - "Due to CORS we are unable to support REST-based API calls to our API from the browser. Please consider using a proxy: https://dpgr.am/js-proxy for more information." - ); - } - - const { accessToken, key: apiKey, fetch: customFetch } = this; - - this.fetch = fetchWithAuth({ accessToken, apiKey, customFetch }); - - if (this.proxy) { - this.baseUrl = this.namespaceOptions.fetch.options.proxy!.url; - } else { - this.baseUrl = this.namespaceOptions.fetch.options.url; - } - } - - /** - * Constructs an error message from the provided error object. - * - * @param err - The error object to extract the error message from. - * @returns The constructed error message. - */ - protected _getErrorMessage(err: any): string { - return err.msg || err.message || err.error_description || err.error || JSON.stringify(err); - } - - /** - * Handles an error that occurred during a request. - * - * @param error - The error that occurred during the request. - * @param reject - The rejection function to call with the error. - * @returns A Promise that resolves when the error has been handled. - */ - protected async _handleError(error: unknown, reject: (reason?: any) => void) { - const Res = await resolveResponse(); - - if (error instanceof Res) { - error - .json() - .then((err) => { - reject(new DeepgramApiError(this._getErrorMessage(err), error.status || 500)); - }) - .catch((err) => { - reject(new DeepgramUnknownError(this._getErrorMessage(err), err)); - }); - } else { - reject(new DeepgramUnknownError(this._getErrorMessage(error), error)); - } - } - - /** - * Constructs the options object to be used for a fetch request. - * - * @param method - The HTTP method to use for the request, such as "GET", "POST", "PUT", "PATCH", or "DELETE". - * @param bodyOrOptions - For "POST", "PUT", and "PATCH" requests, the request body as a string, Buffer, or Readable stream. For "GET" and "DELETE" requests, the fetch options to use. - * @param options - Additional fetch options to use for the request. - * @returns The constructed fetch options object. - */ - protected _getRequestOptions( - method: RequestMethodType, - bodyOrOptions?: string | Buffer | Readable | FetchOptions, - options?: FetchOptions - ): FetchOptions { - let reqOptions: FetchOptions = { method }; - - if (method === "GET" || method === "DELETE") { - reqOptions = { ...reqOptions, ...(bodyOrOptions as FetchOptions) }; - } else { - reqOptions = { - duplex: "half", - body: bodyOrOptions as BodyInit, - ...reqOptions, - ...options, - }; - } - - return merge(this.namespaceOptions.fetch.options, reqOptions, { clone: false }); - } - - /** - * Handles an HTTP request using the provided method, URL, and optional request body and options. - * - * @param method - The HTTP method to use for the request, such as "GET", "POST", "PUT", "PATCH", or "DELETE". - * @param url - The URL to send the request to. - * @param bodyOrOptions - For "POST", "PUT", and "PATCH" requests, the request body as a string, Buffer, or Readable stream. For "GET" and "DELETE" requests, the fetch options to use. - * @param options - Additional fetch options to use for the request. - * @returns A Promise that resolves to the Response object for the request. - */ - protected async _handleRequest( - method: "GET" | "DELETE", - url: URL, - options?: FetchOptions - ): Promise; - protected async _handleRequest( - method: "POST" | "PUT" | "PATCH", - url: URL, - body: string | Buffer | Readable, - options?: FetchOptions - ): Promise; - protected async _handleRequest( - method: RequestMethodType, - url: URL, - bodyOrOptions?: string | Buffer | Readable | FetchOptions, - options?: FetchOptions - ): Promise { - return new Promise((resolve, reject) => { - const fetcher = this.fetch; - - fetcher(url, this._getRequestOptions(method, bodyOrOptions, options)) - .then((result) => { - if (!result.ok) throw result; - resolve(result); - }) - .catch((error) => this._handleError(error, reject)); - }); - } - - /** - * Handles an HTTP GET request using the provided URL and optional request options. - * - * @param url - The URL to send the GET request to. - * @param options - Additional fetch options to use for the GET request. - * @returns A Promise that resolves to the Response object for the GET request. - */ - protected async get(url: URL, options?: FetchOptions): Promise { - return this._handleRequest("GET", url, options); - } - - /** - * Handles an HTTP POST request using the provided URL, request body, and optional request options. - * - * @param url - The URL to send the POST request to. - * @param body - The request body as a string, Buffer, or Readable stream. - * @param options - Additional fetch options to use for the POST request. - * @returns A Promise that resolves to the Response object for the POST request. - */ - protected async post( - url: URL, - body: string | Buffer | Readable, - options?: FetchOptions - ): Promise { - return this._handleRequest("POST", url, body, options); - } - - /** - * Handles an HTTP PUT request using the provided URL, request body, and optional request options. - * - * @param url - The URL to send the PUT request to. - * @param body - The request body as a string, Buffer, or Readable stream. - * @param options - Additional fetch options to use for the PUT request. - * @returns A Promise that resolves to the Response object for the PUT request. - */ - protected async put( - url: URL, - body: string | Buffer | Readable, - options?: FetchOptions - ): Promise { - return this._handleRequest("PUT", url, body, options); - } - - /** - * Handles an HTTP PATCH request using the provided URL, request body, and optional request options. - * - * @param url - The URL to send the PATCH request to. - * @param body - The request body as a string, Buffer, or Readable stream. - * @param options - Additional fetch options to use for the PATCH request. - * @returns A Promise that resolves to the Response object for the PATCH request. - */ - protected async patch( - url: URL, - body: string | Buffer | Readable, - options?: FetchOptions - ): Promise { - return this._handleRequest("PATCH", url, body, options); - } - - /** - * Handles an HTTP DELETE request using the provided URL and optional request options. - * - * @param url - The URL to send the DELETE request to. - * @param options - Additional fetch options to use for the DELETE request. - * @returns A Promise that resolves to the Response object for the DELETE request. - */ - protected async delete(url: URL, options?: FetchOptions): Promise { - return this._handleRequest("DELETE", url, options); - } - - /** - * Determines whether the current instance should proxy requests. - * @returns {boolean} true if the current instance should proxy requests; otherwise, false - */ - get proxy(): boolean { - return this.key === "proxy" && !!this.namespaceOptions.fetch.options.proxy?.url; - } -} - -export { AbstractRestClient as AbstractRestfulClient }; diff --git a/src/packages/AgentLiveClient.ts b/src/packages/AgentLiveClient.ts deleted file mode 100644 index 59d9b1f8..00000000 --- a/src/packages/AgentLiveClient.ts +++ /dev/null @@ -1,170 +0,0 @@ -import { DEFAULT_AGENT_URL } from "../lib/constants"; -import { AgentEvents } from "../lib/enums/AgentEvents"; -import type { AgentLiveSchema, DeepgramClientOptions, FunctionCallResponse } from "../lib/types"; -import { AbstractLiveClient } from "./AbstractLiveClient"; - -export class AgentLiveClient extends AbstractLiveClient { - public namespace: string = "agent"; - - constructor(options: DeepgramClientOptions, endpoint: string = "/:version/agent/converse") { - super(options); - this.baseUrl = options.agent?.websocket?.options?.url ?? DEFAULT_AGENT_URL; - - this.connect({}, endpoint); - } - - /** - * Sets up the connection event handlers. - * This method is responsible for handling the various events that can occur on the WebSocket connection, such as opening, closing, and receiving messages. - * - When the connection is opened, it emits the `AgentEvents.Open` event. - * - When the connection is closed, it emits the `AgentEvents.Close` event. - * - When an error occurs on the connection, it emits the `AgentEvents.Error` event. - * - When a message is received, it parses the message and emits the appropriate event based on the message type. - */ - public setupConnection(): void { - // Set up standard connection events (open, close, error) using abstracted method - this.setupConnectionEvents({ - Open: AgentEvents.Open, - Close: AgentEvents.Close, - Error: AgentEvents.Error, - }); - - // Set up message handling specific to agent conversations - if (this.conn) { - this.conn.onmessage = (event: MessageEvent) => { - this.handleMessage(event); - }; - } - } - - /** - * Handles incoming messages from the WebSocket connection. - * @param event - The MessageEvent object representing the received message. - */ - protected handleMessage(event: MessageEvent): void { - if (typeof event.data === "string") { - try { - const data = JSON.parse(event.data); - this.handleTextMessage(data); - } catch (error) { - this.emit(AgentEvents.Error, { - event, - data: - event.data?.toString().substring(0, 200) + - (event.data?.toString().length > 200 ? "..." : ""), - message: "Unable to parse `data` as JSON.", - error, - url: this.conn?.url, - readyState: this.conn?.readyState, - }); - } - } else if (event.data instanceof Blob) { - event.data.arrayBuffer().then((buffer) => { - this.handleBinaryMessage(Buffer.from(buffer)); - }); - } else if (event.data instanceof ArrayBuffer) { - this.handleBinaryMessage(Buffer.from(event.data)); - } else if (Buffer.isBuffer(event.data)) { - this.handleBinaryMessage(event.data); - } else { - console.log("Received unknown data type", event.data); - this.emit(AgentEvents.Error, { - event, - message: "Received unknown data type.", - url: this.conn?.url, - readyState: this.conn?.readyState, - dataType: typeof event.data, - }); - } - } - - /** - * Handles binary messages received from the WebSocket connection. - * @param data - The binary data. - */ - protected handleBinaryMessage(data: Buffer): void { - this.emit(AgentEvents.Audio, data); - } - - /** - * Handles text messages received from the WebSocket connection. - * @param data - The parsed JSON data. - */ - protected handleTextMessage(data: any): void { - if (data.type in AgentEvents) { - this.emit(data.type, data); - } else { - this.emit(AgentEvents.Unhandled, data); - } - } - - /** - * To be called with your model configuration BEFORE sending - * any audio data. - * @param options - The SettingsConfiguration object. - */ - public configure(options: AgentLiveSchema): void { - const string = JSON.stringify({ - type: "Settings", - ...options, - }); - this.send(string); - } - - /** - * Provide new system prompt to the LLM. - * @param prompt - The system prompt to provide. - */ - public updatePrompt(prompt: string): void { - this.send(JSON.stringify({ type: "UpdatePrompt", prompt })); - } - - /** - * Change the speak model. - * @param model - The new model to use. - */ - public updateSpeak(speakConfig: Exclude): void { - this.send(JSON.stringify({ type: "UpdateSpeak", speak: speakConfig })); - } - - /** - * Immediately trigger an agent message. If this message - * is sent while the user is speaking, or while the server is in the - * middle of sending audio, then the request will be ignored and an InjectionRefused - * event will be emitted. - * @example "Hold on while I look that up for you." - * @example "Are you still on the line?" - * @param content - The message to speak. - */ - public injectAgentMessage(content: string): void { - this.send(JSON.stringify({ type: "InjectAgentMessage", content })); - } - - /** - * Send a text-based message to the agent as if it came from the user. - * This allows you to inject user messages into the conversation for the agent to respond to. - * @example "Hello! Can you hear me?" - * @example "What's the weather like today?" - * @param content - The specific phrase or statement the agent should respond to. - */ - public injectUserMessage(content: string): void { - this.send(JSON.stringify({ type: "InjectUserMessage", content })); - } - - /** - * Respond to a function call request. - * @param response - The response to the function call request. - */ - public functionCallResponse(response: FunctionCallResponse): void { - this.send(JSON.stringify({ type: "FunctionCallResponse", ...response })); - } - - /** - * Send a keepalive to avoid closing the websocket while you - * are not transmitting audio. This should be sent at least - * every 8 seconds. - */ - public keepAlive(): void { - this.send(JSON.stringify({ type: "KeepAlive" })); - } -} diff --git a/src/packages/AuthRestClient.ts b/src/packages/AuthRestClient.ts deleted file mode 100644 index 1f74c1fd..00000000 --- a/src/packages/AuthRestClient.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { isDeepgramError } from "../lib/errors"; -import type { DeepgramResponse } from "../lib/types/DeepgramResponse"; -import type { GrantTokenResponse } from "../lib/types/GrantTokenResponse"; -import type { GrantTokenSchema } from "../lib/types/GrantTokenSchema"; -import { AbstractRestClient } from "./AbstractRestClient"; - -export class AuthRestClient extends AbstractRestClient { - public namespace: string = "auth"; - - /** - * Generates a new temporary token for the Deepgram API. - * @param options Optional configuration options for the token generation. Includes ttl_seconds to set token expiration. - * @param endpoint Optional custom endpoint to use for the request. Defaults to ":version/auth/grant". - * @returns Object containing the result of the request or an error if one occurred. Result will contain access_token and expires_in properties. - */ - public async grantToken( - options: GrantTokenSchema = {}, - endpoint = ":version/auth/grant" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint); - const body = JSON.stringify(options); - const result: GrantTokenResponse = await this.post(requestUrl, body, { - headers: { "Content-Type": "application/json" }, - }).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } -} diff --git a/src/packages/ListenClient.ts b/src/packages/ListenClient.ts deleted file mode 100644 index 9473cdff..00000000 --- a/src/packages/ListenClient.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { AbstractClient } from "./AbstractClient"; -import { ListenLiveClient } from "./ListenLiveClient"; -import { ListenRestClient } from "./ListenRestClient"; -import { LiveSchema } from "../lib/types"; - -/** - * The `ListenClient` class extends the `AbstractClient` class and provides access to the "listen" namespace. - * It exposes two methods: - * - * 1. `prerecorded()`: Returns a `ListenRestClient` instance for interacting with the prerecorded listen API. - * 2. `live(transcriptionOptions: LiveSchema = {}, endpoint = ":version/listen")`: Returns a `ListenLiveClient` instance for interacting with the live listen API, with the provided transcription options and endpoint. - */ -export class ListenClient extends AbstractClient { - public namespace: string = "listen"; - - /** - * Returns a `ListenRestClient` instance for interacting with the prerecorded listen API. - */ - get prerecorded() { - return new ListenRestClient(this.options); - } - - /** - * Returns a `ListenLiveClient` instance for interacting with the live listen API, with the provided transcription options and endpoint. - * @param {LiveSchema} [transcriptionOptions={}] - The transcription options to use for the live listen API. - * @param {string} [endpoint=":version/listen"] - The endpoint to use for the live listen API. - * @returns {ListenLiveClient} - A `ListenLiveClient` instance for interacting with the live listen API. - */ - public live( - transcriptionOptions: LiveSchema = {}, - endpoint: string = ":version/listen" - ): ListenLiveClient { - return new ListenLiveClient(this.options, transcriptionOptions, endpoint); - } -} diff --git a/src/packages/ListenLiveClient.ts b/src/packages/ListenLiveClient.ts deleted file mode 100644 index a5f39670..00000000 --- a/src/packages/ListenLiveClient.ts +++ /dev/null @@ -1,150 +0,0 @@ -import { AbstractLiveClient } from "./AbstractLiveClient"; -import { LiveTranscriptionEvents } from "../lib/enums"; -import type { LiveSchema, LiveConfigOptions, DeepgramClientOptions } from "../lib/types"; -import { DeepgramError } from "../lib/errors"; - -/** - * The `ListenLiveClient` class extends the `AbstractLiveClient` class and provides functionality for setting up and managing a WebSocket connection for live transcription. - * - * The constructor takes in `DeepgramClientOptions` and an optional `LiveSchema` object, as well as an optional `endpoint` string. It then calls the `connect` method of the parent `AbstractLiveClient` class to establish the WebSocket connection. - * - * The `setupConnection` method is responsible for handling the various events that can occur on the WebSocket connection, such as opening, closing, and receiving messages. It sets up event handlers for these events and emits the appropriate events based on the message type. - * - * The `configure` method allows you to send additional configuration options to the connected session, such as enabling numerals. - * - * The `keepAlive` method sends a "KeepAlive" message to the server to maintain the connection. - * - * The `requestClose` method requests the server to close the connection. - * - * The `finish` method is deprecated as of version 3.4 and will be removed in version 4.0. Use `requestClose` instead. - */ -export class ListenLiveClient extends AbstractLiveClient { - public namespace: string = "listen"; - - /** - * Constructs a new `ListenLiveClient` instance with the provided options. - * - * @param options - The `DeepgramClientOptions` to use for the client connection. - * @param transcriptionOptions - An optional `LiveSchema` object containing additional configuration options for the live transcription. - * @param endpoint - An optional string representing the WebSocket endpoint to connect to. Defaults to `:version/listen`. - */ - constructor( - options: DeepgramClientOptions, - transcriptionOptions: LiveSchema = {}, - endpoint: string = ":version/listen" - ) { - super(options); - - if (transcriptionOptions.keyterm?.length && !transcriptionOptions.model?.startsWith("nova-3")) { - throw new DeepgramError("Keyterms are only supported with the Nova 3 models."); - } - - this.connect(transcriptionOptions, endpoint); - } - - /** - * Sets up the connection event handlers. - * This method is responsible for handling the various events that can occur on the WebSocket connection, such as opening, closing, and receiving messages. - * - When the connection is opened, it emits the `LiveTranscriptionEvents.Open` event. - * - When the connection is closed, it emits the `LiveTranscriptionEvents.Close` event. - * - When an error occurs on the connection, it emits the `LiveTranscriptionEvents.Error` event. - * - When a message is received, it parses the message and emits the appropriate event based on the message type, such as `LiveTranscriptionEvents.Metadata`, `LiveTranscriptionEvents.Transcript`, `LiveTranscriptionEvents.UtteranceEnd`, and `LiveTranscriptionEvents.SpeechStarted`. - */ - public setupConnection(): void { - // Set up standard connection events (open, close, error) using abstracted method - this.setupConnectionEvents({ - Open: LiveTranscriptionEvents.Open, - Close: LiveTranscriptionEvents.Close, - Error: LiveTranscriptionEvents.Error, - }); - - // Set up message handling specific to transcription - if (this.conn) { - this.conn.onmessage = (event: MessageEvent) => { - try { - const data: any = JSON.parse(event.data.toString()); - - if (data.type === LiveTranscriptionEvents.Metadata) { - this.emit(LiveTranscriptionEvents.Metadata, data); - } else if (data.type === LiveTranscriptionEvents.Transcript) { - this.emit(LiveTranscriptionEvents.Transcript, data); - } else if (data.type === LiveTranscriptionEvents.UtteranceEnd) { - this.emit(LiveTranscriptionEvents.UtteranceEnd, data); - } else if (data.type === LiveTranscriptionEvents.SpeechStarted) { - this.emit(LiveTranscriptionEvents.SpeechStarted, data); - } else { - this.emit(LiveTranscriptionEvents.Unhandled, data); - } - } catch (error) { - this.emit(LiveTranscriptionEvents.Error, { - event, - message: "Unable to parse `data` as JSON.", - error, - url: this.conn?.url, - readyState: this.conn?.readyState, - data: - event.data?.toString().substring(0, 200) + - (event.data?.toString().length > 200 ? "..." : ""), - }); - } - }; - } - } - - /** - * Sends additional config to the connected session. - * - * @param config - The configuration options to apply to the LiveClient. - * @param config.numerals - We currently only support numerals. - */ - public configure(config: LiveConfigOptions): void { - this.send( - JSON.stringify({ - type: "Configure", - processors: config, - }) - ); - } - - /** - * Sends a "KeepAlive" message to the server to maintain the connection. - */ - public keepAlive(): void { - this.send( - JSON.stringify({ - type: "KeepAlive", - }) - ); - } - - /** - * Sends a "Finalize" message to flush any transcription sitting in the server's buffer. - */ - public finalize(): void { - this.send( - JSON.stringify({ - type: "Finalize", - }) - ); - } - - /** - * @deprecated Since version 3.4. Will be removed in version 4.0. Use `requestClose` instead. - */ - public finish(): void { - this.requestClose(); - } - - /** - * Requests the server close the connection. - */ - public requestClose(): void { - this.send( - JSON.stringify({ - type: "CloseStream", - }) - ); - } -} - -export { ListenLiveClient as LiveClient }; diff --git a/src/packages/ListenRestClient.ts b/src/packages/ListenRestClient.ts deleted file mode 100644 index 754d7aad..00000000 --- a/src/packages/ListenRestClient.ts +++ /dev/null @@ -1,204 +0,0 @@ -import { CallbackUrl, isFileSource, isUrlSource } from "../lib/helpers"; -import { DeepgramError, isDeepgramError } from "../lib/errors"; -import type { - AsyncPrerecordedResponse, - DeepgramResponse, - FileSource, - PrerecordedSchema, - SyncPrerecordedResponse, - UrlSource, -} from "../lib/types"; -import { AbstractRestClient } from "./AbstractRestClient"; - -/** - * The `ListenRestClient` class extends the `AbstractRestClient` class and provides methods for transcribing audio from URLs or files using the Deepgram API. - * - * The `transcribeUrl` method is used to transcribe audio from a URL synchronously. It takes a `UrlSource` object as the source, an optional `PrerecordedSchema` object as options, and an optional endpoint string. It returns a `DeepgramResponse` object containing the transcription result or an error. - * - * The `transcribeFile` method is used to transcribe audio from a file synchronously. It takes a `FileSource` object as the source, an optional `PrerecordedSchema` object as options, and an optional endpoint string. It returns a `DeepgramResponse` object containing the transcription result or an error. - * - * The `transcribeUrlCallback` method is used to transcribe audio from a URL asynchronously. It takes a `UrlSource` object as the source, a `CallbackUrl` object as the callback, an optional `PrerecordedSchema` object as options, and an optional endpoint string. It returns a `DeepgramResponse` object containing the transcription result or an error. - * - * The `transcribeFileCallback` method is used to transcribe audio from a file asynchronously. It takes a `FileSource` object as the source, a `CallbackUrl` object as the callback, an optional `PrerecordedSchema` object as options, and an optional endpoint string. It returns a `DeepgramResponse` object containing the transcription result or an error. - */ -export class ListenRestClient extends AbstractRestClient { - public namespace: string = "listen"; - - /** - * Transcribes audio from a URL synchronously. - * - * @param source - The URL source object containing the audio URL to transcribe. - * @param options - An optional `PrerecordedSchema` object containing additional options for the transcription. - * @param endpoint - An optional endpoint string to use for the transcription request. - * @returns A `DeepgramResponse` object containing the transcription result or an error. - */ - async transcribeUrl( - source: UrlSource, - options?: PrerecordedSchema, - endpoint = ":version/listen" - ): Promise> { - try { - let body; - - if (isUrlSource(source)) { - body = JSON.stringify(source); - } else { - throw new DeepgramError("Unknown transcription source type"); - } - - if (options !== undefined && "callback" in options) { - throw new DeepgramError( - "Callback cannot be provided as an option to a synchronous transcription. Use `transcribeUrlCallback` or `transcribeFileCallback` instead." - ); - } - - if (options?.keyterm?.length && !options.model?.startsWith("nova-3")) { - throw new DeepgramError("Keyterms are only supported with the Nova 3 models."); - } - - const requestUrl = this.getRequestUrl(endpoint, {}, { ...{}, ...options }); - const result: SyncPrerecordedResponse = await this.post(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Transcribes audio from a file asynchronously. - * - * @param source - The file source object containing the audio file to transcribe. - * @param options - An optional `PrerecordedSchema` object containing additional options for the transcription. - * @param endpoint - An optional endpoint string to use for the transcription request. - * @returns A `DeepgramResponse` object containing the transcription result or an error. - */ - async transcribeFile( - source: FileSource, - options?: PrerecordedSchema, - endpoint = ":version/listen" - ): Promise> { - try { - let body; - - if (isFileSource(source)) { - body = source; - } else { - throw new DeepgramError("Unknown transcription source type"); - } - - if (options !== undefined && "callback" in options) { - throw new DeepgramError( - "Callback cannot be provided as an option to a synchronous transcription. Use `transcribeUrlCallback` or `transcribeFileCallback` instead." - ); - } - - const requestUrl = this.getRequestUrl(endpoint, {}, { ...{}, ...options }); - const result: SyncPrerecordedResponse = await this.post(requestUrl, body, { - headers: { "Content-Type": "deepgram/audio+video" }, - }).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Transcribes audio from a URL asynchronously. - * - * @param source - The URL source object containing the audio file to transcribe. - * @param callback - The callback URL to receive the transcription result. - * @param options - An optional `PrerecordedSchema` object containing additional options for the transcription. - * @param endpoint - An optional endpoint string to use for the transcription request. - * @returns A `DeepgramResponse` object containing the transcription result or an error. - */ - async transcribeUrlCallback( - source: UrlSource, - callback: CallbackUrl, - options?: PrerecordedSchema, - endpoint = ":version/listen" - ): Promise> { - try { - let body; - - if (isUrlSource(source)) { - body = JSON.stringify(source); - } else { - throw new DeepgramError("Unknown transcription source type"); - } - - const requestUrl = this.getRequestUrl( - endpoint, - {}, - { ...options, callback: callback.toString() } - ); - const result: AsyncPrerecordedResponse = await this.post(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Transcribes audio from a file asynchronously. - * - * @param source - The file source object containing the audio file to transcribe. - * @param callback - The callback URL to receive the transcription result. - * @param options - An optional `PrerecordedSchema` object containing additional options for the transcription. - * @param endpoint - An optional endpoint string to use for the transcription request. - * @returns A `DeepgramResponse` object containing the transcription result or an error. - */ - async transcribeFileCallback( - source: FileSource, - callback: CallbackUrl, - options?: PrerecordedSchema, - endpoint = ":version/listen" - ): Promise> { - try { - let body; - - if (isFileSource(source)) { - body = source; - } else { - throw new DeepgramError("Unknown transcription source type"); - } - - const requestUrl = this.getRequestUrl( - endpoint, - {}, - { ...options, callback: callback.toString() } - ); - const result: AsyncPrerecordedResponse = await this.post(requestUrl, body, { - headers: { "Content-Type": "deepgram/audio+video" }, - }).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } -} - -export { ListenRestClient as PrerecordedClient }; diff --git a/src/packages/ManageRestClient.ts b/src/packages/ManageRestClient.ts deleted file mode 100644 index 812c24c8..00000000 --- a/src/packages/ManageRestClient.ts +++ /dev/null @@ -1,814 +0,0 @@ -import { isDeepgramError } from "../lib/errors"; -import type { - CreateProjectKeySchema, - CreateProjectKeyResponse, - DeepgramResponse, - GetProjectBalanceResponse, - GetProjectBalancesResponse, - GetProjectInvitesResponse, - GetProjectKeyResponse, - GetProjectKeysResponse, - GetProjectMemberScopesResponse, - GetProjectMembersResponse, - GetProjectResponse, - GetProjectsResponse, - GetProjectUsageFieldsSchema, - GetProjectUsageFieldsResponse, - GetProjectUsageRequestResponse, - GetProjectUsageRequestsSchema, - GetProjectUsageRequestsResponse, - GetProjectUsageSummarySchema, - GetProjectUsageSummaryResponse, - MessageResponse, - SendProjectInviteSchema, - UpdateProjectMemberScopeSchema, - UpdateProjectSchema, - VoidResponse, - GetTokenDetailsResponse, - GetModelsResponse, - GetModelResponse, - GetModelsSchema, -} from "../lib/types"; -import { AbstractRestClient } from "./AbstractRestClient"; - -/** - * The `ManageRestClient` class provides a set of methods for interacting with the Deepgram Manage API. It extends the `AbstractRestClient` class and provides functionality for managing projects, keys, members, invites, usage, balances, and models. - * - * The class has a `namespace` property that is set to `"manage"`, which is used in the construction of the request URLs. - * - * The methods in this class include: - * - `getTokenDetails`: Retrieves the details of the current authentication token. - * - `getProjects`: Retrieves a list of all projects associated with the authenticated account. - * - `getProject`: Retrieves the details of a specific project. - * - `updateProject`: Updates the details of a specific project. - * - `deleteProject`: Deletes a specific project. - * - `getProjectKeys`: Retrieves a list of all API keys associated with a specific project. - * - `getProjectKey`: Retrieves the details of a specific API key. - * - `createProjectKey`: Creates a new API key for a specific project. - * - `deleteProjectKey`: Deletes a specific API key. - * - `getProjectMembers`: Retrieves a list of all members associated with a specific project. - * - `removeProjectMember`: Removes a specific member from a project. - * - `getProjectMemberScopes`: Retrieves the scopes associated with a specific project member. - * - `updateProjectMemberScope`: Updates the scopes associated with a specific project member. - * - `getProjectInvites`: Retrieves a list of all pending invitations for a specific project. - * - `sendProjectInvite`: Sends a new invitation to a specific email address for a project. - * - `deleteProjectInvite`: Deletes a specific invitation for a project. - * - `leaveProject`: Removes the authenticated user from a specific project. - * - `getProjectUsageRequests`: Retrieves a list of all usage requests for a specific project. - * - `getProjectUsageRequest`: Retrieves the details of a specific usage request. - * - `getProjectUsageSummary`: Retrieves a summary of the usage for a specific project. - * - `getProjectUsageFields`: Retrieves a list of the available usage fields for a specific project. - * - `getProjectBalances`: Retrieves a list of all balances associated with a specific project. - * - `getProjectBalance`: Retrieves the details of a specific balance for a project. - * - `getAllModels`: Retrieves all models for a project. - * - `getModel`: Retrieves a specific model. - */ -export class ManageRestClient extends AbstractRestClient { - public namespace: string = "manage"; - - /** - * Retrieves the details of the current authentication token. - * - * @returns A promise that resolves to an object containing the token details, or an error object if an error occurs. - * @see https://developers.deepgram.com/docs/authenticating#test-request - */ - async getTokenDetails( - endpoint = ":version/auth/token" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint); - const result: GetTokenDetailsResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves a list of all projects associated with the authenticated user. - * - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects". - * @returns A promise that resolves to an object containing the list of projects, or an error object if an error occurs. - * @see https://developers.deepgram.com/reference/get-projects - */ - async getProjects( - endpoint = ":version/projects" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint); - const result: GetProjectsResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves the details of a specific project associated with the authenticated user. - * - * @param projectId - The ID of the project to retrieve. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId". - * @returns A promise that resolves to an object containing the project details, or an error object if an error occurs. - * @see https://developers.deepgram.com/reference/get-project - */ - async getProject( - projectId: string, - endpoint = ":version/projects/:projectId" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }); - const result: GetProjectResponse = await this.get(requestUrl).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Updates an existing project associated with the authenticated user. - * - * @param projectId - The ID of the project to update. - * @param options - An object containing the updated project details. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId". - * @returns A promise that resolves to an object containing the response message, or an error object if an error occurs. - * @see https://developers.deepgram.com/reference/update-project - */ - async updateProject( - projectId: string, - options: UpdateProjectSchema, - endpoint = ":version/projects/:projectId" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }, options); - const body = JSON.stringify(options); - - const result: MessageResponse = await this.patch(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Deletes an existing project associated with the authenticated user. - * - * @param projectId - The ID of the project to delete. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId". - * @returns A promise that resolves to an object containing the response message, or an error object if an error occurs. - * @see https://developers.deepgram.com/reference/delete-project - */ - async deleteProject( - projectId: string, - endpoint = ":version/projects/:projectId" - ): Promise { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }); - await this.delete(requestUrl); - - return { error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { error }; - } - - throw error; - } - } - - /** - * Retrieves a list of project keys associated with the specified project. - * - * @param projectId - The ID of the project to retrieve the keys for. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/keys". - * @returns A promise that resolves to an object containing the list of project keys, or an error object if an error occurs. - * @see https://developers.deepgram.com/reference/list-keys - */ - async getProjectKeys( - projectId: string, - endpoint = ":version/projects/:projectId/keys" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }); - const result: GetProjectKeysResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves a specific project key associated with the specified project. - * - * @param projectId - The ID of the project to retrieve the key for. - * @param keyId - The ID of the project key to retrieve. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/keys/:keyId". - * @returns A promise that resolves to an object containing the project key, or an error object if an error occurs. - * @see https://developers.deepgram.com/reference/get-key - */ - async getProjectKey( - projectId: string, - keyId: string, - endpoint = ":version/projects/:projectId/keys/:keyId" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, keyId }); - const result: GetProjectKeyResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Creates a new project key for the specified project. - * - * @param projectId - The ID of the project to create the key for. - * @param options - An object containing the options for creating the project key. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/keys". - * @returns A promise that resolves to an object containing the created project key, or an error object if an error occurs. - * @see https://developers.deepgram.com/reference/create-key - */ - async createProjectKey( - projectId: string, - options: CreateProjectKeySchema, - endpoint = ":version/projects/:projectId/keys" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }, options); - const body = JSON.stringify(options); - - const result: CreateProjectKeyResponse = await this.post(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Deletes the specified project key. - * - * @param projectId - The ID of the project the key belongs to. - * @param keyId - The ID of the key to delete. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/keys/:keyId". - * @returns A promise that resolves to an object containing a null result and an error object if an error occurs. - * @see https://developers.deepgram.com/reference/delete-key - */ - async deleteProjectKey( - projectId: string, - keyId: string, - endpoint = ":version/projects/:projectId/keys/:keyId" - ): Promise { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, keyId }); - await this.delete(requestUrl); - - return { error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { error }; - } - - throw error; - } - } - - /** - * Retrieves the members of the specified project. - * - * @param projectId - The ID of the project to retrieve members for. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/members". - * @returns A promise that resolves to an object containing the project members and an error object if an error occurs. - * @see https://developers.deepgram.com/reference/get-members - */ - async getProjectMembers( - projectId: string, - endpoint = ":version/projects/:projectId/members" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }); - const result: GetProjectMembersResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Removes a member from the specified project. - * - * @param projectId - The ID of the project to remove the member from. - * @param memberId - The ID of the member to remove. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/members/:memberId". - * @returns A promise that resolves to an object containing a null error if the operation was successful, or an error object if an error occurred. - * @see https://developers.deepgram.com/reference/remove-member - */ - async removeProjectMember( - projectId: string, - memberId: string, - endpoint = ":version/projects/:projectId/members/:memberId" - ): Promise { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, memberId }); - await this.delete(requestUrl); - - return { error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { error }; - } - - throw error; - } - } - - /** - * Retrieves the scopes for the specified project member. - * - * @param projectId - The ID of the project to retrieve the member scopes for. - * @param memberId - The ID of the member to retrieve the scopes for. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/members/:memberId/scopes". - * @returns A promise that resolves to an object containing the retrieved scopes or an error object if an error occurred. - * @see https://developers.deepgram.com/reference/get-member-scopes - */ - async getProjectMemberScopes( - projectId: string, - memberId: string, - endpoint = ":version/projects/:projectId/members/:memberId/scopes" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, memberId }); - const result: GetProjectMemberScopesResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Updates the scopes for the specified project member. - * - * @param projectId - The ID of the project to update the member scopes for. - * @param memberId - The ID of the member to update the scopes for. - * @param options - An object containing the new scopes to apply to the member. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/members/:memberId/scopes". - * @returns A promise that resolves to an object containing the result of the update operation or an error object if an error occurred. - * @see https://developers.deepgram.com/reference/update-scope - */ - async updateProjectMemberScope( - projectId: string, - memberId: string, - options: UpdateProjectMemberScopeSchema, - endpoint = ":version/projects/:projectId/members/:memberId/scopes" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, memberId }, options); - const body = JSON.stringify(options); - - const result: MessageResponse = await this.put(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves the project invites for the specified project. - * - * @param projectId - The ID of the project to retrieve the invites for. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/invites". - * @returns A promise that resolves to an object containing the result of the get operation or an error object if an error occurred. - * @see https://developers.deepgram.com/reference/list-invites - */ - async getProjectInvites( - projectId: string, - endpoint = ":version/projects/:projectId/invites" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }); - const result: GetProjectInvitesResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Sends a project invite to the specified email addresses. - * - * @param projectId - The ID of the project to send the invite for. - * @param options - An object containing the email addresses to invite and any additional options. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/invites". - * @returns A promise that resolves to an object containing the result of the post operation or an error object if an error occurred. - * @see https://developers.deepgram.com/reference/send-invites - */ - async sendProjectInvite( - projectId: string, - options: SendProjectInviteSchema, - endpoint = ":version/projects/:projectId/invites" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }, options); - const body = JSON.stringify(options); - - const result: MessageResponse = await this.post(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Deletes a project invite for the specified email address. - * - * @param projectId - The ID of the project to delete the invite for. - * @param email - The email address of the invite to delete. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/invites/:email". - * @returns A promise that resolves to an object containing a null result and an error object if an error occurred. - * @see https://developers.deepgram.com/reference/delete-invite - */ - async deleteProjectInvite( - projectId: string, - email: string, - endpoint = ":version/projects/:projectId/invites/:email" - ): Promise { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, email }); - await this.delete(requestUrl); - - return { error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { error }; - } - - throw error; - } - } - - /** - * Leaves the specified project. - * - * @param projectId - The ID of the project to leave. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/leave". - * @returns A promise that resolves to an object containing a null result and an error object if an error occurred. - * @see https://developers.deepgram.com/reference/leave-project - */ - async leaveProject( - projectId: string, - endpoint = ":version/projects/:projectId/leave" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }); - const result: MessageResponse = await this.delete(requestUrl).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves a list of usage requests for the specified project. - * - * @param projectId - The ID of the project to retrieve usage requests for. - * @param options - An object containing options to filter the usage requests, such as pagination parameters. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/requests". - * @returns A promise that resolves to an object containing the list of usage requests and an error object if an error occurred. - * @see https://developers.deepgram.com/reference/get-all-requests - */ - async getProjectUsageRequests( - projectId: string, - options: GetProjectUsageRequestsSchema, - endpoint = ":version/projects/:projectId/requests" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }, options); - const result: GetProjectUsageRequestsResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves the details of a specific usage request for the specified project. - * - * @param projectId - The ID of the project to retrieve the usage request for. - * @param requestId - The ID of the usage request to retrieve. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/requests/:requestId". - * @returns A promise that resolves to an object containing the usage request details and an error object if an error occurred. - * @see https://developers.deepgram.com/reference/get-request - */ - async getProjectUsageRequest( - projectId: string, - requestId: string, - endpoint = ":version/projects/:projectId/requests/:requestId" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, requestId }); - const result: GetProjectUsageRequestResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves the usage summary for the specified project. - * - * @param projectId - The ID of the project to retrieve the usage summary for. - * @param options - An object containing optional parameters for the request, such as filters and pagination options. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/usage". - * @returns A promise that resolves to an object containing the usage summary and an error object if an error occurred. - * @see https://developers.deepgram.com/reference/get-usage - */ - async getProjectUsageSummary( - projectId: string, - options: GetProjectUsageSummarySchema, - endpoint = ":version/projects/:projectId/usage" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }, options); - const result: GetProjectUsageSummaryResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves the usage fields for the specified project. - * - * @param projectId - The ID of the project to retrieve the usage fields for. - * @param options - An object containing optional parameters for the request, such as filters and pagination options. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/usage/fields". - * @returns A promise that resolves to an object containing the usage fields and an error object if an error occurred. - * @see https://developers.deepgram.com/reference/get-fields - */ - async getProjectUsageFields( - projectId: string, - options: GetProjectUsageFieldsSchema, - endpoint = ":version/projects/:projectId/usage/fields" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }, options); - const result: GetProjectUsageFieldsResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves the balances for the specified project. - * - * @param projectId - The ID of the project to retrieve the balances for. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/balances". - * @returns A promise that resolves to an object containing the project balances and an error object if an error occurred. - * @see https://developers.deepgram.com/reference/get-all-balances - */ - async getProjectBalances( - projectId: string, - endpoint = ":version/projects/:projectId/balances" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }); - const result: GetProjectBalancesResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves the balance for the specified project and balance ID. - * - * @param projectId - The ID of the project to retrieve the balance for. - * @param balanceId - The ID of the balance to retrieve. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/projects/:projectId/balances/:balanceId". - * @returns A promise that resolves to an object containing the project balance and an error object if an error occurred. - * @see https://developers.deepgram.com/reference/get-balance - */ - async getProjectBalance( - projectId: string, - balanceId: string, - endpoint = ":version/projects/:projectId/balances/:balanceId" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, balanceId }); - const result: GetProjectBalanceResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves all models for a given project. - * - * @param projectId - The ID of the project. - * @param endpoint - (optional) The endpoint URL for retrieving models. Defaults to ":version/projects/:projectId/models". - * @returns A promise that resolves to a DeepgramResponse containing the GetModelsResponse. - * @example - * ```typescript - * import { createClient } from "@deepgram/sdk"; - * - * const deepgram = createClient(DEEPGRAM_API_KEY); - * const { result: models, error } = deepgram.manage.getAllModels("projectId"); - * - * if (error) { - * console.error(error); - * } else { - * console.log(models); - * } - * ``` - */ - async getAllModels( - projectId: string, - options: GetModelsSchema = {}, - endpoint = ":version/projects/:projectId/models" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }, options); - const result: GetModelsResponse = await this.get(requestUrl).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves a model from the specified project. - * - * @param projectId - The ID of the project. - * @param modelId - The ID of the model. - * @param endpoint - (optional) The endpoint URL for the request. Default value is ":version/projects/:projectId/models/:modelId". - * @returns A promise that resolves to a DeepgramResponse containing the GetModelResponse. - * @example - * ```typescript - * import { createClient } from "@deepgram/sdk"; - * - * const deepgram = createClient(DEEPGRAM_API_KEY); - * const { result: model, error } = deepgram.models.getModel("projectId", "modelId"); - * - * if (error) { - * console.error(error); - * } else { - * console.log(model); - * } - * ``` - */ - async getModel( - projectId: string, - modelId: string, - endpoint = ":version/projects/:projectId/models/:modelId" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, modelId }); - const result: GetModelResponse = await this.get(requestUrl).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } -} - -export { ManageRestClient as ManageClient }; diff --git a/src/packages/ModelsRestClient.ts b/src/packages/ModelsRestClient.ts deleted file mode 100644 index 0038a9a7..00000000 --- a/src/packages/ModelsRestClient.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { isDeepgramError } from "../lib/errors"; -import { - DeepgramResponse, - GetModelResponse, - GetModelsResponse, - GetModelsSchema, -} from "../lib/types"; -import { AbstractRestClient } from "./AbstractRestClient"; - -/** - * Represents a REST client for interacting with the Deepgram API. - * - * The `ModelsRestClient` class provides methods for interacting with the Deepgram API to retrieve information about available models. - * @extends AbstractRestClient - */ -export class ModelsRestClient extends AbstractRestClient { - public namespace: string = "models"; - - /** - * Retrieves a list of all available models. - * - * @param endpoint - (optional) The endpoint to request. - * @returns A promise that resolves with the response from the Deepgram API. - * @example - * ```typescript - * import { createClient } from "@deepgram/sdk"; - * - * const deepgram = createClient(DEEPGRAM_API_KEY); - * const { result: models, error } = deepgram.models.getAll(); - * - * if (error) { - * console.error(error); - * } else { - * console.log(models); - * } - * ``` - */ - async getAll( - endpoint = ":version/models", - options: GetModelsSchema = {} - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, {}, options); - const result: GetModelsResponse = await this.get(requestUrl).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves information about a specific model. - * - * @param modelId - The UUID of the model to retrieve. - * @param endpoint - (optional) The endpoint to request. - * @returns A promise that resolves with the response from the Deepgram API. - * @example - * ```typescript - * import { createClient } from "@deepgram/sdk"; - * - * const deepgram = createClient(DEEPGRAM_API_KEY); - * const { result: model, error } = deepgram.models.getModel("modelId"); - * - * if (error) { - * console.error(error); - * } else { - * console.log(model); - * } - * ``` - */ - async getModel( - modelId: string, - endpoint = ":version/models/:modelId" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { modelId }); - const result: GetModelResponse = await this.get(requestUrl).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } -} diff --git a/src/packages/ReadRestClient.ts b/src/packages/ReadRestClient.ts deleted file mode 100644 index d5782576..00000000 --- a/src/packages/ReadRestClient.ts +++ /dev/null @@ -1,200 +0,0 @@ -import { CallbackUrl, isTextSource, isUrlSource } from "../lib/helpers"; -import { DeepgramError, isDeepgramError } from "../lib/errors"; -import type { - AnalyzeSchema, - AsyncAnalyzeResponse, - DeepgramResponse, - SyncAnalyzeResponse, - TextSource, - UrlSource, -} from "../lib/types"; -import { AbstractRestClient } from "./AbstractRestClient"; - -/** - * The `ReadRestClient` class extends the `AbstractRestClient` class and provides methods for analyzing audio sources synchronously and asynchronously. - * - * The `analyzeUrl` method analyzes a URL-based audio source synchronously, returning a promise that resolves to the analysis response or an error. - * - * The `analyzeText` method analyzes a text-based audio source synchronously, returning a promise that resolves to the analysis response or an error. - * - * The `analyzeUrlCallback` method analyzes a URL-based audio source asynchronously, returning a promise that resolves to the analysis response or an error. - * - * The `analyzeTextCallback` method analyzes a text-based audio source asynchronously, returning a promise that resolves to the analysis response or an error. - */ -export class ReadRestClient extends AbstractRestClient { - public namespace: string = "read"; - - /** - * Analyzes a URL-based audio source synchronously. - * - * @param source - The URL-based audio source to analyze. - * @param options - Optional analysis options. - * @param endpoint - The API endpoint to use for the analysis. Defaults to ":version/read". - * @returns A promise that resolves to the analysis response, or an error if the analysis fails. - */ - async analyzeUrl( - source: UrlSource, - options?: AnalyzeSchema, - endpoint = ":version/read" - ): Promise> { - try { - let body; - - if (isUrlSource(source)) { - body = JSON.stringify(source); - } else { - throw new DeepgramError("Unknown source type"); - } - - if (options !== undefined && "callback" in options) { - throw new DeepgramError( - "Callback cannot be provided as an option to a synchronous transcription. Use `analyzeUrlCallback` or `analyzeTextCallback` instead." - ); - } - - const requestUrl = this.getRequestUrl(endpoint, {}, { ...{}, ...options }); - const result: SyncAnalyzeResponse = await this.post(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Analyzes a text-based audio source synchronously. - * - * @param source - The text-based audio source to analyze. - * @param options - Optional analysis options. - * @param endpoint - The API endpoint to use for the analysis. Defaults to ":version/read". - * @returns A promise that resolves to the analysis response, or an error if the analysis fails. - */ - async analyzeText( - source: TextSource, - options?: AnalyzeSchema, - endpoint = ":version/read" - ): Promise> { - try { - let body; - - if (isTextSource(source)) { - body = JSON.stringify(source); - } else { - throw new DeepgramError("Unknown source type"); - } - - if (options !== undefined && "callback" in options) { - throw new DeepgramError( - "Callback cannot be provided as an option to a synchronous requests. Use `analyzeUrlCallback` or `analyzeTextCallback` instead." - ); - } - - const requestUrl = this.getRequestUrl(endpoint, {}, { ...{}, ...options }); - const result: SyncAnalyzeResponse = await this.post(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Analyzes a URL-based audio source asynchronously. - * - * @param source - The URL-based audio source to analyze. - * @param callback - The URL to call back with the analysis results. - * @param options - Optional analysis options. - * @param endpoint - The API endpoint to use for the analysis. Defaults to ":version/read". - * @returns A promise that resolves to the analysis response, or an error if the analysis fails. - */ - async analyzeUrlCallback( - source: UrlSource, - callback: CallbackUrl, - options?: AnalyzeSchema, - endpoint = ":version/read" - ): Promise> { - try { - let body; - - if (isUrlSource(source)) { - body = JSON.stringify(source); - } else { - throw new DeepgramError("Unknown source type"); - } - - const requestUrl = this.getRequestUrl( - endpoint, - {}, - { ...options, callback: callback.toString() } - ); - const result: AsyncAnalyzeResponse = await this.post(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Analyzes a text-based audio source asynchronously. - * - * @param source - The text-based audio source to analyze. - * @param callback - The URL to call back with the analysis results. - * @param options - Optional analysis options. - * @param endpoint - The API endpoint to use for the analysis. Defaults to ":version/read". - * @returns A promise that resolves to the analysis response, or an error if the analysis fails. - */ - async analyzeTextCallback( - source: TextSource, - callback: CallbackUrl, - options?: AnalyzeSchema, - endpoint = ":version/read" - ): Promise> { - try { - let body; - - if (isTextSource(source)) { - body = JSON.stringify(source); - } else { - throw new DeepgramError("Unknown source type"); - } - - const requestUrl = this.getRequestUrl( - endpoint, - {}, - { ...options, callback: callback.toString() } - ); - const result: AsyncAnalyzeResponse = await this.post(requestUrl, body, { - headers: { "Content-Type": "deepgram/audio+video" }, - }).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } -} - -export { ReadRestClient as ReadClient }; diff --git a/src/packages/SelfHostedRestClient.ts b/src/packages/SelfHostedRestClient.ts deleted file mode 100644 index f897334e..00000000 --- a/src/packages/SelfHostedRestClient.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { isDeepgramError } from "../lib/errors"; -import type { - CreateOnPremCredentialsSchema, - DeepgramResponse, - ListOnPremCredentialsResponse, - MessageResponse, - OnPremCredentialResponse, -} from "../lib/types"; -import { AbstractRestClient } from "./AbstractRestClient"; - -/** - * The `SelfHostedRestClient` class extends the `AbstractRestClient` class and provides methods for interacting with the Deepgram self-hosted API. - * - * This class is used to list, retrieve, create, and delete self-hosted credentials for a Deepgram project. - */ -export class SelfHostedRestClient extends AbstractRestClient { - public namespace: string = "selfhosted"; - - /** - * Lists the self-hosted credentials for a Deepgram project. - * - * @param projectId - The ID of the Deepgram project. - * @returns A promise that resolves to an object containing the list of self-hosted credentials and any error that occurred. - * @see https://developers.deepgram.com/reference/list-credentials - */ - async listCredentials( - projectId: string, - endpoint = ":version/projects/:projectId/onprem/distribution/credentials" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }); - const result: ListOnPremCredentialsResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Retrieves the self-hosted credentials for a specific Deepgram project and credentials ID. - * - * @param projectId - The ID of the Deepgram project. - * @param credentialsId - The ID of the self-hosted credentials to retrieve. - * @returns A promise that resolves to an object containing the self-hosted credentials and any error that occurred. - * @see https://developers.deepgram.com/reference/get-credentials - */ - async getCredentials( - projectId: string, - credentialsId: string, - endpoint = ":version/projects/:projectId/onprem/distribution/credentials/:credentialsId" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, credentialsId }); - const result: OnPremCredentialResponse = await this.get(requestUrl).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Creates self-hosted credentials for a specific Deepgram project. - * - * @param projectId - The ID of the Deepgram project. - * @param options - The options for creating the self-hosted credentials. - * @returns A promise that resolves to an object containing the created self-hosted credentials and any error that occurred. - * @see https://developers.deepgram.com/reference/create-credentials - */ - async createCredentials( - projectId: string, - options: CreateOnPremCredentialsSchema, - endpoint = ":version/projects/:projectId/onprem/distribution/credentials" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId }); - const body = JSON.stringify(options); - - const result: OnPremCredentialResponse = await this.post(requestUrl, body).then((result) => - result.json() - ); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } - - /** - * Deletes self-hosted credentials for a specific Deepgram project. - * - * @param projectId - The ID of the Deepgram project. - * @param credentialsId - The ID of the self-hosted credentials to delete. - * @returns A promise that resolves to an object containing a message response and any error that occurred. - * @see https://developers.deepgram.com/reference/delete-credentials - */ - async deleteCredentials( - projectId: string, - credentialsId: string, - endpoint = ":version/projects/:projectId/onprem/distribution/credentials/:credentialsId" - ): Promise> { - try { - const requestUrl = this.getRequestUrl(endpoint, { projectId, credentialsId }); - const result: MessageResponse = await this.delete(requestUrl).then((result) => result.json()); - - return { result, error: null }; - } catch (error) { - if (isDeepgramError(error)) { - return { result: null, error }; - } - - throw error; - } - } -} - -export { SelfHostedRestClient as OnPremClient }; diff --git a/src/packages/SpeakClient.ts b/src/packages/SpeakClient.ts deleted file mode 100644 index 097e0705..00000000 --- a/src/packages/SpeakClient.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { AbstractClient } from "./AbstractClient"; -import { SpeakLiveClient } from "./SpeakLiveClient"; -import { SpeakRestClient } from "./SpeakRestClient"; -import { SpeakSchema } from "../lib/types"; -import { TextSource } from "../lib/types"; - -/** - * The `SpeakClient` class extends the `AbstractClient` class and provides access to the "speak" namespace. - * It exposes two methods: - * - * 1. `request()`: Returns a `SpeakRestClient` instance for interacting with the rest speak API. - * 2. `live(ttsOptions: SpeakSchema = {}, endpoint = ":version/speak")`: Returns a `SpeakLiveClient` instance for interacting with the live speak API, with the provided TTS options and endpoint. - */ -export class SpeakClient extends AbstractClient { - public namespace: string = "speak"; - - /** - * Returns a `SpeakRestClient` instance for interacting with the rest speak API. - */ - public request(source: TextSource, options?: SpeakSchema, endpoint = ":version/speak") { - const client = new SpeakRestClient(this.options); - - return client.request(source, options, endpoint); - } - - /** - * Returns a `SpeakLiveClient` instance for interacting with the live speak API, with the provided TTS options and endpoint. - * @param {SpeakSchema} [ttsOptions={}] - The TTS options to use for the live speak API. - * @param {string} [endpoint=":version/speak"] - The endpoint to use for the live speak API. - * @returns {SpeakLiveClient} - A `SpeakLiveClient` instance for interacting with the live speak API. - */ - public live(ttsOptions: SpeakSchema = {}, endpoint: string = ":version/speak"): SpeakLiveClient { - return new SpeakLiveClient(this.options, ttsOptions, endpoint); - } -} diff --git a/src/packages/SpeakLiveClient.ts b/src/packages/SpeakLiveClient.ts deleted file mode 100644 index ef731ac6..00000000 --- a/src/packages/SpeakLiveClient.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { AbstractLiveClient } from "./AbstractLiveClient"; -import { LiveTTSEvents } from "../lib/enums"; -import type { SpeakSchema, DeepgramClientOptions } from "../lib/types"; - -/** - * The `SpeakLiveClient` class extends the `AbstractLiveClient` class and provides functionality for setting up and managing a WebSocket connection for live text-to-speech synthesis. - * - * The constructor takes in `DeepgramClientOptions` and an optional `SpeakSchema` object, as well as an optional `endpoint` string. It then calls the `connect` method of the parent `AbstractLiveClient` class to establish the WebSocket connection. - * - * The `setupConnection` method is responsible for handling the various events that can occur on the WebSocket connection, such as opening, closing, and receiving messages. It sets up event handlers for these events and emits the appropriate events based on the message type. - * - * The `configure` method allows you to send additional configuration options to the connected session. - * - * The `requestClose` method requests the server to close the connection. - */ -export class SpeakLiveClient extends AbstractLiveClient { - public namespace: string = "speak"; - - /** - * Constructs a new `SpeakLiveClient` instance with the provided options. - * - * @param options - The `DeepgramClientOptions` to use for the client connection. - * @param speakOptions - An optional `SpeakSchema` object containing additional configuration options for the text-to-speech. - * @param endpoint - An optional string representing the WebSocket endpoint to connect to. Defaults to `:version/speak`. - */ - constructor( - options: DeepgramClientOptions, - speakOptions: Omit = {}, - endpoint: string = ":version/speak" - ) { - super(options); - - this.connect(speakOptions, endpoint); - } - - /** - * Sets up the connection event handlers. - * This method is responsible for handling the various events that can occur on the WebSocket connection, such as opening, closing, and receiving data. - * - When the connection is opened, it emits the `LiveTTSEvents.Open` event. - * - When the connection is closed, it emits the `LiveTTSEvents.Close` event. - * - When an error occurs on the connection, it emits the `LiveTTSEvents.Error` event. - * - When a message is received, it parses the message and emits the appropriate event based on the message type, such as `LiveTTSEvents.Metadata`, `LiveTTSEvents.Flushed`, and `LiveTTSEvents.Warning`. - */ - public setupConnection(): void { - // Set up standard connection events (open, close, error) using abstracted method - this.setupConnectionEvents({ - Open: LiveTTSEvents.Open, - Close: LiveTTSEvents.Close, - Error: LiveTTSEvents.Error, - }); - - // Set up message handling specific to text-to-speech - if (this.conn) { - this.conn.onmessage = (event: MessageEvent) => { - this.handleMessage(event); - }; - } - } - - /** - * Handles text messages received from the WebSocket connection. - * @param data - The parsed JSON data. - */ - protected handleTextMessage(data: any): void { - if (data.type === LiveTTSEvents.Metadata) { - this.emit(LiveTTSEvents.Metadata, data); - } else if (data.type === LiveTTSEvents.Flushed) { - this.emit(LiveTTSEvents.Flushed, data); - } else if (data.type === LiveTTSEvents.Warning) { - this.emit(LiveTTSEvents.Warning, data); - } else { - this.emit(LiveTTSEvents.Unhandled, data); - } - } - - /** - * Handles binary messages received from the WebSocket connection. - * @param data - The binary data. - */ - protected handleBinaryMessage(data: Buffer): void { - this.emit(LiveTTSEvents.Audio, data); - } - - /** - * Sends a text input message to the server. - * - * @param {string} text - The text to convert to speech. - */ - public sendText(text: string): void { - this.send( - JSON.stringify({ - type: "Speak", - text, - }) - ); - } - - /** - * Requests the server flush the current buffer and return generated audio. - */ - public flush(): void { - this.send( - JSON.stringify({ - type: "Flush", - }) - ); - } - - /** - * Requests the server clear the current buffer. - */ - public clear(): void { - this.send( - JSON.stringify({ - type: "Clear", - }) - ); - } - - /** - * Requests the server close the connection. - */ - public requestClose(): void { - this.send( - JSON.stringify({ - type: "Close", - }) - ); - } - - /** - * Handles incoming messages from the WebSocket connection. - * @param event - The MessageEvent object representing the received message. - */ - protected handleMessage(event: MessageEvent): void { - if (typeof event.data === "string") { - try { - const data = JSON.parse(event.data); - this.handleTextMessage(data); - } catch (error) { - this.emit(LiveTTSEvents.Error, { - event, - message: "Unable to parse `data` as JSON.", - error, - url: this.conn?.url, - readyState: this.conn?.readyState, - data: - event.data?.toString().substring(0, 200) + - (event.data?.toString().length > 200 ? "..." : ""), - }); - } - } else if (event.data instanceof Blob) { - event.data.arrayBuffer().then((buffer) => { - this.handleBinaryMessage(Buffer.from(buffer)); - }); - } else if (event.data instanceof ArrayBuffer) { - this.handleBinaryMessage(Buffer.from(event.data)); - } else if (Buffer.isBuffer(event.data)) { - this.handleBinaryMessage(event.data); - } else { - console.log("Received unknown data type", event.data); - this.emit(LiveTTSEvents.Error, { - event, - message: "Received unknown data type.", - url: this.conn?.url, - readyState: this.conn?.readyState, - dataType: typeof event.data, - }); - } - } -} diff --git a/src/packages/SpeakRestClient.ts b/src/packages/SpeakRestClient.ts deleted file mode 100644 index ae272641..00000000 --- a/src/packages/SpeakRestClient.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { DeepgramError, DeepgramUnknownError } from "../lib/errors"; -import { isTextSource } from "../lib/helpers"; -import { SpeakSchema, TextSource } from "../lib/types"; -import { AbstractRestClient } from "./AbstractRestClient"; - -/** - * Provides a client for interacting with the Deepgram Text-to-Speech API. - */ -export class SpeakRestClient extends AbstractRestClient { - public namespace: string = "speak"; - public result: undefined | Response; - - /** - * Sends a request to the Deepgram Text-to-Speech API to generate audio from the provided text source. - * - * @param source - The text source to be converted to audio. - * @param options - Optional configuration options for the text-to-speech request. - * @param endpoint - The API endpoint to use for the request. Defaults to ":version/speak". - * @returns A promise that resolves to the SpeakRestClient instance, which can be used to retrieve the response headers and body. - * @throws {DeepgramError} If the text source type is unknown. - * @throws {DeepgramUnknownError} If the request was made before a previous request completed. - * @see https://developers.deepgram.com/reference/text-to-speech-api - */ - async request( - source: TextSource, - options?: SpeakSchema, - endpoint = ":version/speak" - ): Promise { - let body; - - if (isTextSource(source)) { - body = JSON.stringify(source); - } else { - throw new DeepgramError("Unknown transcription source type"); - } - - const requestUrl = this.getRequestUrl( - endpoint, - {}, - { ...{ model: "aura-2-thalia-en" }, ...options } - ); - this.result = await this.post(requestUrl, body, { - headers: { Accept: "audio/*", "Content-Type": "application/json" }, - }); - - return this; - } - - /** - * Retrieves the response body as a readable stream. - * - * @returns A promise that resolves to the response body as a readable stream, or `null` if no request has been made yet. - * @throws {DeepgramUnknownError} If a request has not been made yet. - */ - async getStream(): Promise | null> { - if (!this.result) - throw new DeepgramUnknownError("Tried to get stream before making request", ""); - - return this.result.body; - } - - /** - * Retrieves the response headers from the previous request. - * - * @returns A promise that resolves to the response headers, or throws a `DeepgramUnknownError` if no request has been made yet. - */ - async getHeaders(): Promise { - if (!this.result) - throw new DeepgramUnknownError("Tried to get headers before making request", ""); - - return this.result.headers; - } -} diff --git a/src/packages/index.ts b/src/packages/index.ts deleted file mode 100644 index f210a660..00000000 --- a/src/packages/index.ts +++ /dev/null @@ -1,15 +0,0 @@ -export * from "./AbstractClient"; -export * from "./AbstractLiveClient"; -export * from "./AbstractRestClient"; -export * from "./AgentLiveClient"; -export * from "./AuthRestClient"; -export * from "./ListenClient"; -export * from "./ListenLiveClient"; -export * from "./ListenRestClient"; -export * from "./ManageRestClient"; -export * from "./ModelsRestClient"; -export * from "./ReadRestClient"; -export * from "./SelfHostedRestClient"; -export * from "./SpeakClient"; -export * from "./SpeakLiveClient"; -export * from "./SpeakRestClient"; diff --git a/src/version.ts b/src/version.ts new file mode 100644 index 00000000..1d1a4f3e --- /dev/null +++ b/src/version.ts @@ -0,0 +1 @@ +export const SDK_VERSION = "4.11.3"; diff --git a/tests/BrowserTestEnvironment.ts b/tests/BrowserTestEnvironment.ts new file mode 100644 index 00000000..0f32bf7b --- /dev/null +++ b/tests/BrowserTestEnvironment.ts @@ -0,0 +1,17 @@ +import { TestEnvironment } from "jest-environment-jsdom"; + +class BrowserTestEnvironment extends TestEnvironment { + async setup() { + await super.setup(); + this.global.Request = Request; + this.global.Response = Response; + this.global.ReadableStream = ReadableStream; + this.global.TextEncoder = TextEncoder; + this.global.TextDecoder = TextDecoder; + this.global.FormData = FormData; + this.global.File = File; + this.global.Blob = Blob; + } +} + +export default BrowserTestEnvironment; diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 948575d0..00000000 --- a/tests/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Test Suites - -This directory contains the E2E and unit tests for the Deepgram JS SDK. - -## Running Tests - -### All Tests - -To run the entire test suite: - -```bash -pnpm test -``` - -### E2E Tests - -To run only the end-to-end tests: - -```bash -pnpm test tests/e2e/ -``` - -### Unit Tests - -To run only the unit tests: - -```bash -pnpm test tests/unit/ -``` - -### Snapshot Updates - -To update snapshots with real API calls: - -```bash -# Using Jest's update flag -pnpm test tests/e2e/ -- -u - -# or - -# By using an environment variable -DEEPGRAM_FORCE_REAL_API=true pnpm test tests/e2e/ -``` - -For more details on the testing strategy, please see the main [project README.md](../README.md). diff --git a/tests/__fixtures__/listen.ts b/tests/__fixtures__/listen.ts deleted file mode 100644 index 5c5f57db..00000000 --- a/tests/__fixtures__/listen.ts +++ /dev/null @@ -1,64 +0,0 @@ -/** - * Test fixtures for Listen (Speech-to-Text) API - */ - -/** - * Common transcription options used across multiple tests - */ -export const commonTranscriptionOptions = { - model: "nova-3", - smart_format: true, - punctuate: true, -} as const; - -/** - * Test audio URLs for different scenarios - */ -export const testAudioUrls = { - spacewalk: "https://dpgr.am/spacewalk.wav", -} as const; - -/** - * URL source objects for transcribeUrl tests - */ -export const urlSources = { - spacewalk: { - url: testAudioUrls.spacewalk, - }, -} as const; - -/** - * File paths for test audio files - */ -export const testAudioFiles = { - spacewalk: "spacewalk.wav", -} as const; - -/** - * Alternative transcription options for different test scenarios - */ -export const transcriptionOptions = { - basic: { - model: "nova-3", - }, - enhanced: { - model: "nova-3", - smart_format: true, - punctuate: true, - diarize: true, - }, - withKeyterms: { - model: "nova-3", - smart_format: true, - punctuate: true, - keyterm: ["spacewalk"], - }, -} as const; - -/** - * Callback URLs for async operations - */ -export const callbackUrls = { - webhook: "https://your-webhook-url.com/callback", - testEndpoint: "https://test-callback.example.com/webhook", -} as const; diff --git a/tests/__fixtures__/manage.ts b/tests/__fixtures__/manage.ts deleted file mode 100644 index f22e480b..00000000 --- a/tests/__fixtures__/manage.ts +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Test fixtures for Manage API (Project Management) - */ - -/** - * Test project IDs for management operations - */ -export const testProjectIds = { - primary: "test-project-123", - secondary: "test-project-456", - toDelete: "test-project-789", -} as const; - -/** - * Test member IDs for member management operations - */ -export const testMemberIds = { - member1: "test-member-123", - member2: "test-member-456", - toRemove: "test-member-789", -} as const; - -/** - * Test API key IDs for key management operations - */ -export const testKeyIds = { - key1: "test-key-123", - key2: "test-key-456", - toDelete: "test-key-789", -} as const; - -/** - * Test balance IDs for balance operations - */ -export const testBalanceIds = { - balance1: "test-balance-123", - balance2: "test-balance-456", -} as const; - -/** - * Test request IDs for usage operations - */ -export const testRequestIds = { - request1: "test-request-123", - request2: "test-request-456", -} as const; - -/** - * Project creation/update options - */ -export const projectOptions = { - create: { - name: "Test Project", - company: "Test Company", - }, - update: { - name: "Updated Test Project", - company: "Updated Test Company", - }, -} as const; - -/** - * API key creation options - */ -export const keyOptions = { - create: { - comment: "Test API key for e2e testing", - scopes: ["usage:write", "usage:read"], - }, - createMinimal: { - comment: "Minimal test key", - scopes: [], - }, -}; - -/** - * Member scope update options - */ -export const memberScopeOptions = { - update: { - scope: "member" as const, - }, - updateAdmin: { - scope: "admin" as const, - }, -} as const; - -/** - * Project invitation options - */ -export const inviteOptions = { - single: { - email: "test@example.com", - scope: "member", - }, - multiple: { - email: "test-bulk@example.com", // API may support bulk but type shows single - scope: "member", - }, -}; - -/** - * Usage request query options - */ -export const usageRequestOptions = { - basic: { - start: "2024-01-01", - end: "2024-01-31", - }, - withLimit: { - start: "2024-01-01", - end: "2024-01-31", - limit: 10, - }, - withPagination: { - start: "2024-01-01", - end: "2024-01-31", - limit: 5, - page: 1, - }, -} as const; - -/** - * Usage summary query options - */ -export const usageSummaryOptions = { - basic: { - start: "2024-01-01", - end: "2024-01-31", - }, - withFilters: { - start: "2024-01-01", - end: "2024-01-31", - accessor: "streaming", - tag: "test", - method: "POST", - model: "nova-2", - }, -} as const; - -/** - * Usage fields query options - */ -export const usageFieldsOptions = { - basic: { - start: "2024-01-01", - end: "2024-01-31", - }, - withFilters: { - start: "2024-01-01", - end: "2024-01-31", - include_tags: true, - }, -} as const; - -/** - * Test model IDs for project-scoped model operations - */ -export const testModelIds = { - sttModel: "nova-2", - ttsModel: "aura-thalia-en", - customModel: "custom-model-123", -} as const; - -/** - * Test email addresses for invite operations - */ -export const testEmails = { - toInvite: "test@example.com", - toDelete: "invited@example.com", - bulk: "test-bulk@example.com", -} as const; - -/** - * Project-scoped model query options - */ -export const modelOptions = { - basic: {}, - withFilters: { - includeOutdated: false, - }, -} as const; diff --git a/tests/__fixtures__/models.ts b/tests/__fixtures__/models.ts deleted file mode 100644 index 82f730fa..00000000 --- a/tests/__fixtures__/models.ts +++ /dev/null @@ -1,12 +0,0 @@ -/** - * Test fixtures for Models API - */ - -/** - * Test model IDs for model operations (mock IDs for testing) - */ -export const testModelIds = { - nova: "nova-2-general", - whisper: "whisper-medium", - custom: "custom-model-123", -} as const; diff --git a/tests/__fixtures__/read.ts b/tests/__fixtures__/read.ts deleted file mode 100644 index eec09723..00000000 --- a/tests/__fixtures__/read.ts +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Test fixtures for Read (Text Analysis) API - */ - -/** - * Test text sources for Read API (text analysis) scenarios - */ -export const testReadSources = { - simpleText: { text: "Hello world, this is a test." }, - complexText: { - text: "The quick brown fox jumps over the lazy dog. This sentence contains every letter of the alphabet.", - }, - sentimentText: { text: "I absolutely love this product! It's amazing and works perfectly." }, - urlSource: { url: "https://example.com/article.txt" }, -} as const; - -/** - * Common analysis options for Read API tests - */ -export const commonAnalysisOptions = { - sentiment: true, - summarize: true, - intents: true, - language: "en", -} as const; - -/** - * Callback URLs for async operations - */ -export const callbackUrls = { - webhook: "https://your-webhook-url.com/callback", - testEndpoint: "https://test-callback.example.com/webhook", -} as const; diff --git a/tests/__fixtures__/selfhosted.ts b/tests/__fixtures__/selfhosted.ts deleted file mode 100644 index 0a0f49e3..00000000 --- a/tests/__fixtures__/selfhosted.ts +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Test fixtures for Selfhosted API - */ - -/** - * Test project IDs for management operations (mock IDs for testing) - */ -export const testProjectIds = { - primary: "test-project-123", - secondary: "test-project-456", -} as const; - -/** - * Test credentials for self-hosted operations - */ -export const testCredentials = { - createOptions: { - comment: "Test credentials for e2e testing", - scopes: ["usage:write"] as string[], - }, - credentialId: "test-credential-123", -} as const; diff --git a/tests/__fixtures__/spacewalk.wav b/tests/__fixtures__/spacewalk.wav deleted file mode 100644 index 498be744..00000000 Binary files a/tests/__fixtures__/spacewalk.wav and /dev/null differ diff --git a/tests/__fixtures__/speak.ts b/tests/__fixtures__/speak.ts deleted file mode 100644 index 2656e216..00000000 --- a/tests/__fixtures__/speak.ts +++ /dev/null @@ -1,41 +0,0 @@ -/** - * Test fixtures for Speak (Text-to-Speech) API - */ - -/** - * Common TTS options used across multiple tests - */ -export const commonTTSOptions = { - model: "aura-2-thalia-en", - encoding: "mp3", -} as const; - -/** - * Test text sources for TTS scenarios - */ -export const testTextSources = { - greeting: { text: "Hello, how can I help you today?" }, - longText: { - text: "This is a longer text sample for testing text-to-speech functionality with multiple sentences. It should demonstrate how the API handles longer content.", - }, - multiline: { text: "Line one.\nLine two.\nLine three with more content." }, -} as const; - -/** - * Alternative TTS options for different test scenarios - */ -export const ttsOptions = { - basic: { - model: "aura-2-thalia-en", - }, - highQuality: { - model: "aura-2-thalia-en", - encoding: "linear16", - sample_rate: 48000, - }, - compressed: { - model: "aura-2-thalia-en", - encoding: "mp3", - bit_rate: 128000, - }, -} as const; diff --git a/tests/__utils__/index.ts b/tests/__utils__/index.ts deleted file mode 100644 index 7480c547..00000000 --- a/tests/__utils__/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export * from "./serializers"; -export * from "./mocks"; diff --git a/tests/__utils__/mocks.ts b/tests/__utils__/mocks.ts deleted file mode 100644 index b5638747..00000000 --- a/tests/__utils__/mocks.ts +++ /dev/null @@ -1,486 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars, @typescript-eslint/no-require-imports, no-console */ -import { - mockTranscribeUrlResponse, - mockTranscribeFileResponse, - mockAsyncListenUrlResponse, - mockAsyncListenFileResponse, -} from "../e2e/__mocks__/listen"; -import { mockAudioBuffer, mockTTSHeaders } from "../e2e/__mocks__/speak"; -import { mockGetAllModelsResponse, mockGetModelResponse } from "../e2e/__mocks__/models"; -import { mockGrantTokenResponse } from "../e2e/__mocks__/auth"; -import { - mockAnalyzeTextResponse, - mockAnalyzeUrlResponse, - mockAsyncAnalyzeResponse, - mockAsyncReadUrlResponse, - mockAsyncReadTextResponse, -} from "../e2e/__mocks__/read"; -import { - mockListCredentialsResponse, - mockGetCredentialsResponse, - mockCreateCredentialsResponse, - mockDeleteCredentialsResponse, -} from "../e2e/__mocks__/selfhosted"; -import { - mockGetProjectsResponse, - mockGetProjectResponse, - mockGetProjectKeysResponse, - mockGetProjectKeyResponse, - mockGetProjectMembersResponse, - mockGetProjectBalancesResponse, - mockGetProjectUsageRequestsResponse, - mockGetProjectUsageSummaryResponse, - mockCreateProjectKeyResponse, - mockGetTokenDetailsResponse, - mockDeleteProjectResponse, - mockDeleteProjectKeyResponse, - mockRemoveProjectMemberResponse, - mockDeleteProjectInviteResponse, - mockGetProjectMemberScopesResponse, - mockUpdateProjectMemberScopeResponse, - mockGetProjectInvitesResponse, - mockSendProjectInviteResponse, - mockLeaveProjectResponse, - mockGetProjectUsageRequestResponse, - mockGetProjectUsageFieldsResponse, - mockGetProjectBalanceResponse, - mockGetAllProjectModelsResponse, - mockGetProjectModelResponse, - mockUpdateProjectResponse, -} from "../e2e/__mocks__/manage"; - -// Store original fetch to restore later -let originalFetch: typeof global.fetch | undefined; -let originalCrossFetch: any; - -/** - * Determines if we're in snapshot update mode - */ -function isUpdatingSnapshots(): boolean { - const isUpdateMode = - process.argv.includes("--updateSnapshot") || - process.argv.includes("-u") || - process.env.DEEPGRAM_FORCE_REAL_API === "true"; - - return isUpdateMode; -} - -/** - * Creates a mock fetch function that handles Deepgram API requests - */ -function createMockFetch(): typeof fetch { - return async (input: RequestInfo | URL, init?: RequestInit): Promise => { - const url = - typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url; - const method = init?.method || "GET"; - - // Mock Deepgram API endpoints - if (url.includes("api.deepgram.com")) { - if (url.includes("/v1/listen") && method === "POST") { - // Check if it's a callback request (async) - const isCallbackRequest = url.includes("callback="); - - // Check if it's a URL-based or file-based request - const body = init?.body; - let isUrlRequest = false; - - if (typeof body === "string") { - try { - const parsed = JSON.parse(body); - isUrlRequest = parsed && parsed.url; - } catch { - // Not JSON - } - } - - let responseData; - if (isCallbackRequest) { - responseData = isUrlRequest ? mockAsyncListenUrlResponse : mockAsyncListenFileResponse; - } else { - responseData = isUrlRequest ? mockTranscribeUrlResponse : mockTranscribeFileResponse; - } - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - if (url.includes("/v1/speak") && method === "POST") { - return new Response(mockAudioBuffer, { - status: 200, - headers: new Headers(mockTTSHeaders), - }); - } - - if (url.includes("/v1/models") && method === "GET") { - // Check if it's a specific model request (has model ID in path) - const modelIdMatch = url.match(/\/v1\/models\/([^?]+)/); - const responseData = modelIdMatch ? mockGetModelResponse : mockGetAllModelsResponse; - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - if (url.includes("/v1/auth/grant") && method === "POST") { - // Handle the ttl_seconds parameter from the request body - const responseData = { ...mockGrantTokenResponse }; - - if (init?.body) { - try { - const requestBody = JSON.parse(init.body as string); - if (requestBody.ttl_seconds) { - // Update the expires_in value based on ttl_seconds - responseData.expires_in = requestBody.ttl_seconds; - } - } catch (e) { - // If parsing fails, use default response - } - } - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - if (url.includes("/v1/read") && method === "POST") { - // Check if it's a callback request (async) - const isCallbackRequest = url.includes("callback="); - - if (isCallbackRequest) { - // Check if it's a URL-based or text-based request for callback - const body = init?.body; - let isUrlRequest = false; - - if (typeof body === "string") { - try { - const parsed = JSON.parse(body); - isUrlRequest = parsed && parsed.url; - } catch { - // Not JSON - } - } - - const responseData = isUrlRequest ? mockAsyncReadUrlResponse : mockAsyncReadTextResponse; - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check if it's a URL-based or text-based request - const body = init?.body; - let isUrlRequest = false; - - if (typeof body === "string") { - try { - const parsed = JSON.parse(body); - isUrlRequest = parsed && parsed.url; - } catch { - // Not JSON - } - } - - const responseData = isUrlRequest ? mockAnalyzeUrlResponse : mockAnalyzeTextResponse; - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - if (url.includes("/onprem/distribution/credentials")) { - if (method === "GET") { - // Check if it's a specific credential request (has credential ID in path) - const credentialIdMatch = url.match(/\/credentials\/([^?]+)$/); - const responseData = credentialIdMatch - ? mockGetCredentialsResponse - : mockListCredentialsResponse; - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - if (method === "POST") { - return new Response(JSON.stringify(mockCreateCredentialsResponse), { - status: 201, - headers: { "content-type": "application/json" }, - }); - } - - if (method === "DELETE") { - return new Response(JSON.stringify(mockDeleteCredentialsResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - } - - if (url.includes("/v1/auth/token") && method === "GET") { - return new Response(JSON.stringify(mockGetTokenDetailsResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - if (url.includes("/v1/projects") && method === "GET") { - // Check for project keys endpoint - if (url.includes("/keys")) { - // Check if it's a specific key request (has key ID in path after /keys/) - const keyIdMatch = url.match(/\/keys\/([^?/]+)$/); - const responseData = keyIdMatch ? mockGetProjectKeyResponse : mockGetProjectKeysResponse; - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for project members endpoint - if (url.includes("/members")) { - // Check for member scopes endpoint - if (url.includes("/scopes")) { - return new Response(JSON.stringify(mockGetProjectMemberScopesResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - return new Response(JSON.stringify(mockGetProjectMembersResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for project balances endpoint - if (url.includes("/balances")) { - // Check if it's a specific balance request - const balanceIdMatch = url.match(/\/balances\/([^?/]+)$/); - const responseData = balanceIdMatch - ? mockGetProjectBalanceResponse - : mockGetProjectBalancesResponse; - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for project invites endpoint - if (url.includes("/invites")) { - return new Response(JSON.stringify(mockGetProjectInvitesResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for project usage requests endpoint - if (url.includes("/requests")) { - // Check if it's a specific request - const requestIdMatch = url.match(/\/requests\/([^?/]+)$/); - const responseData = requestIdMatch - ? mockGetProjectUsageRequestResponse - : mockGetProjectUsageRequestsResponse; - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for project usage summary endpoint - if (url.includes("/usage/fields")) { - return new Response(JSON.stringify(mockGetProjectUsageFieldsResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for project usage summary endpoint - if (url.includes("/usage")) { - return new Response(JSON.stringify(mockGetProjectUsageSummaryResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for project models endpoint - if (url.includes("/models")) { - // Check if it's a specific model request - const modelIdMatch = url.match(/\/models\/([^?/]+)$/); - const responseData = modelIdMatch - ? mockGetProjectModelResponse - : mockGetAllProjectModelsResponse; - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check if it's a specific project request (has project ID in path) - const projectIdMatch = url.match(/\/v1\/projects\/([^?/]+)$/); - const responseData = projectIdMatch ? mockGetProjectResponse : mockGetProjectsResponse; - - return new Response(JSON.stringify(responseData), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - if (url.includes("/v1/projects") && method === "POST") { - // Check for project key creation - if (url.includes("/keys")) { - return new Response(JSON.stringify(mockCreateProjectKeyResponse), { - status: 201, - headers: { "content-type": "application/json" }, - }); - } - - // Check for project invites - if (url.includes("/invites")) { - return new Response(JSON.stringify(mockSendProjectInviteResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - } - - if (url.includes("/v1/projects") && method === "PATCH") { - // Check for project updates - if (url.match(/\/v1\/projects\/[^/]+$/)) { - return new Response(JSON.stringify(mockUpdateProjectResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - } - - if (url.includes("/v1/projects") && method === "PUT") { - // Check for member scope updates - if (url.includes("/scopes")) { - return new Response(JSON.stringify(mockUpdateProjectMemberScopeResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - } - - if (url.includes("/v1/projects") && method === "DELETE") { - // Check for leave project (special case - returns JSON response) - if (url.includes("/leave")) { - return new Response(JSON.stringify(mockLeaveProjectResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for project deletion - if (url.match(/\/v1\/projects\/[^/]+$/)) { - return new Response(JSON.stringify(mockDeleteProjectResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for key deletion - if (url.includes("/keys/")) { - return new Response(JSON.stringify(mockDeleteProjectKeyResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for member removal - if (url.includes("/members/")) { - return new Response(JSON.stringify(mockRemoveProjectMemberResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - - // Check for invite deletion - if (url.includes("/invites/")) { - return new Response(JSON.stringify(mockDeleteProjectInviteResponse), { - status: 200, - headers: { "content-type": "application/json" }, - }); - } - } - } - - // If we get here, it's not a Deepgram API request we're mocking - throw new Error(`Network request blocked in offline test mode: ${method} ${url}`); - }; -} - -/** - * Sets up API mocks for e2e tests - * This allows tests to run without internet/API key requirements - * E2E tests use mocks by default, but can be toggled to real APIs - */ -export function setupApiMocks(): void { - // Check if we should use real APIs instead of mocks - if (process.env.DEEPGRAM_FORCE_REAL_API === "true") { - return; // Skip mock setup - use real APIs - } - - // Store original implementations - originalFetch = global.fetch; - - // Try to mock cross-fetch as well - try { - const crossFetch = require("cross-fetch"); - originalCrossFetch = crossFetch.default || crossFetch; - } catch (_e) { - // cross-fetch might not be available or loaded yet - } - - // Create our mock fetch - const mockFetch = createMockFetch(); - - // Override global fetch - global.fetch = mockFetch as any; - - // Also try to override cross-fetch - try { - const crossFetch = require("cross-fetch"); - if (crossFetch.default) { - crossFetch.default = mockFetch; - } else { - Object.assign(crossFetch, mockFetch); - } - } catch (_e) { - // Might not be available - } -} - -/** - * Cleans up all mocks after tests - */ -export function cleanupApiMocks(): void { - // Restore original fetch - if (originalFetch) { - global.fetch = originalFetch; - originalFetch = undefined; - } - - // Restore cross-fetch if we mocked it - if (originalCrossFetch) { - try { - const crossFetch = require("cross-fetch"); - if (crossFetch.default) { - crossFetch.default = originalCrossFetch; - } else { - Object.assign(crossFetch, originalCrossFetch); - } - originalCrossFetch = undefined; - } catch (_e) { - // Might not be available - } - } -} diff --git a/tests/__utils__/serializers.ts b/tests/__utils__/serializers.ts deleted file mode 100644 index cd47f06c..00000000 --- a/tests/__utils__/serializers.ts +++ /dev/null @@ -1,32 +0,0 @@ -/** - * Simple serializer that replaces values with type placeholders for non-deterministic testing - * Perfect for AI APIs where response content varies but structure should remain consistent - */ -export const structureOnlySerializer = { - test: (val: any) => val != null && typeof val === "object", - serialize: (val: any) => { - const replaceValues = (obj: any): any => { - if (obj === null) return null; - if (obj === undefined) return undefined; - if (typeof obj === "string") return ""; - if (typeof obj === "number") return ""; - if (typeof obj === "boolean") return ""; - - if (Array.isArray(obj)) { - return obj.length > 0 ? [replaceValues(obj[0])] : []; - } - - if (typeof obj === "object") { - const result: any = {}; - for (const key of Object.keys(obj).sort()) { - result[key] = replaceValues(obj[key]); - } - return result; - } - - return obj; - }; - - return JSON.stringify(replaceValues(val), null, 2); - }, -}; diff --git a/tests/__utils__/websocket-mocks.ts b/tests/__utils__/websocket-mocks.ts deleted file mode 100644 index 0072bd4b..00000000 --- a/tests/__utils__/websocket-mocks.ts +++ /dev/null @@ -1,365 +0,0 @@ -/* eslint-disable @typescript-eslint/no-unused-vars */ -import { SOCKET_STATES } from "../../src/lib/constants"; - -/** - * Mock WebSocket data for different live client scenarios - */ -export const mockWebSocketData = { - listen: { - metadata: { - type: "Metadata", - transaction_key: "deprecated", - request_id: "550e8400-e29b-41d4-a716-446655440000", - sha256: "abc123def456", - created: "2024-01-15T10:30:00Z", - duration: 120.5, - channels: 1, - }, - transcript: { - type: "Results", - channel_index: [0, 1], - duration: 2.5, - start: 0.0, - is_final: true, - channel: { - alternatives: [ - { - transcript: "Hello world from WebSocket test", - confidence: 0.95, - words: [ - { word: "Hello", start: 0.0, end: 0.5, confidence: 0.95 }, - { word: "world", start: 0.6, end: 1.0, confidence: 0.94 }, - { word: "from", start: 1.1, end: 1.3, confidence: 0.96 }, - { word: "WebSocket", start: 1.4, end: 1.8, confidence: 0.93 }, - { word: "test", start: 1.9, end: 2.2, confidence: 0.97 }, - ], - }, - ], - }, - }, - utteranceEnd: { - type: "UtteranceEnd", - channel: [0], - last_word_end: 2.5, - }, - speechStarted: { - type: "SpeechStarted", - channel: [0], - timestamp: 1.2, - }, - }, - speak: { - metadata: { - type: "Metadata", - request_id: "550e8400-e29b-41d4-a716-446655440001", - model_name: "aura-asteria-en", - model_uuid: "c0e51fb0-7b76-42f0-b8c0-8ad7a14fb5b5", - char_count: 25, - transfer_encoding: "chunked", - date: "Thu, 15 Aug 2024 17:22:02 GMT", - }, - warning: { - type: "Warning", - warn_code: "W001", - warn_msg: "Sample warning message from TTS", - }, - flushed: { - type: "Flushed", - }, - }, - agent: { - welcome: { - type: "Welcome", - request_id: "550e8400-e29b-41d4-a716-446655440002", - }, - conversationText: { - type: "ConversationText", - role: "user", - content: "Hello, how can you help me today?", - }, - agentThinking: { - type: "AgentThinking", - content: "Let me think about that...", - }, - functionCallRequest: { - type: "FunctionCallRequest", - functions: [ - { - id: "function-123", - name: "get_weather", - arguments: '{"location": "San Francisco", "units": "celsius"}', - client_side: true, - }, - ], - }, - agentStartedSpeaking: { - type: "AgentStartedSpeaking", - total_latency: 250, - tts_latency: 100, - ttt_latency: 150, - }, - agentAudioDone: { - type: "AgentAudioDone", - }, - }, -}; - -/** - * Mock audio data for testing binary WebSocket messages - */ -export const mockAudioData = new ArrayBuffer(1024); - -/** - * Event handler type for WebSocket events - */ -type EventHandler = (event?: any) => void; - -/** - * Mock WebSocket class that simulates WebSocket behavior for testing - */ -export class MockWebSocket { - public url: string; - public readyState: number = SOCKET_STATES.connecting; - public onopen: EventHandler | null = null; - public onclose: EventHandler | null = null; - public onerror: EventHandler | null = null; - public onmessage: EventHandler | null = null; - public binaryType: string = "arraybuffer"; - - private sendBuffer: any[] = []; - private messageQueue: any[] = []; - private isConnected = false; - - constructor(url: string, protocols?: string | string[], options?: any) { - this.url = url.toString(); - - // Simulate async connection - setTimeout(() => { - this.readyState = SOCKET_STATES.open; - this.isConnected = true; - if (this.onopen) { - this.onopen(); - } - }, 0); - } - - /** - * Mock send method that stores sent data for testing - */ - public send(data: string | ArrayBuffer | Blob): void { - if (this.readyState !== SOCKET_STATES.open) { - throw new Error("WebSocket is not open"); - } - this.sendBuffer.push(data); - } - - /** - * Mock close method - */ - public close(code?: number, reason?: string): void { - this.readyState = SOCKET_STATES.closing; - setTimeout(() => { - this.readyState = SOCKET_STATES.closed; - if (this.onclose) { - this.onclose({ code: code || 1000, reason: reason || "Normal closure" }); - } - }, 0); - } - - /** - * Simulate receiving a message (for testing) - */ - public simulateMessage(data: any): void { - if (this.onmessage && this.isConnected) { - const messageEvent = { - data: typeof data === "string" ? data : JSON.stringify(data), - type: "message", - }; - this.onmessage(messageEvent); - } - } - - /** - * Simulate receiving binary data (for testing) - */ - public simulateBinaryMessage(data: ArrayBuffer | Buffer): void { - if (this.onmessage && this.isConnected) { - const messageEvent = { - data: data instanceof Buffer ? data.buffer : data, - type: "message", - }; - this.onmessage(messageEvent); - } - } - - /** - * Simulate a connection error (for testing) - */ - public simulateError(message: string = "Connection error"): void { - if (this.onerror) { - this.onerror({ type: "error", message }); - } - } - - /** - * Get all messages that were sent (for testing assertions) - */ - public getSentMessages(): any[] { - return [...this.sendBuffer]; - } - - /** - * Clear the send buffer (for testing cleanup) - */ - public clearSentMessages(): void { - this.sendBuffer = []; - } - - /** - * Check if WebSocket is in a connected state - */ - public isOpen(): boolean { - return this.readyState === SOCKET_STATES.open; - } -} - -/** - * Creates a MockWebSocket constructor that can be used in tests - */ -export function createMockWebSocketConstructor(): typeof MockWebSocket { - return MockWebSocket; -} - -/** - * Helper function to create a mock WebSocket instance - */ -export function createMockWebSocket(url: string = "wss://api.deepgram.com"): MockWebSocket { - return new MockWebSocket(url); -} - -/** - * WebSocket scenario simulator for different test cases - */ -export class WebSocketScenario { - private mockWebSocket: MockWebSocket; - - constructor(mockWebSocket: MockWebSocket) { - this.mockWebSocket = mockWebSocket; - } - - /** - * Simulate a successful listen transcription scenario - */ - public async simulateListenTranscription(): Promise { - // Wait for connection - await this.waitForConnection(); - - // Send metadata first - this.mockWebSocket.simulateMessage(mockWebSocketData.listen.metadata); - - // Send speech started - this.mockWebSocket.simulateMessage(mockWebSocketData.listen.speechStarted); - - // Send transcript - this.mockWebSocket.simulateMessage(mockWebSocketData.listen.transcript); - - // Send utterance end - this.mockWebSocket.simulateMessage(mockWebSocketData.listen.utteranceEnd); - } - - /** - * Simulate a speak TTS scenario - */ - public async simulateSpeakTTS(): Promise { - // Wait for connection - await this.waitForConnection(); - - // Send metadata - this.mockWebSocket.simulateMessage(mockWebSocketData.speak.metadata); - - // Send audio data - this.mockWebSocket.simulateBinaryMessage(mockAudioData); - - // Send flushed - this.mockWebSocket.simulateMessage(mockWebSocketData.speak.flushed); - } - - /** - * Simulate an agent conversation scenario - */ - public async simulateAgentConversation(): Promise { - // Wait for connection - await this.waitForConnection(); - - // Send welcome - this.mockWebSocket.simulateMessage(mockWebSocketData.agent.welcome); - - // User speaks - this.mockWebSocket.simulateMessage(mockWebSocketData.agent.conversationText); - - // Agent thinks - this.mockWebSocket.simulateMessage(mockWebSocketData.agent.agentThinking); - - // Agent starts speaking - this.mockWebSocket.simulateMessage(mockWebSocketData.agent.agentStartedSpeaking); - - // Send audio - this.mockWebSocket.simulateBinaryMessage(mockAudioData); - - // Agent done - this.mockWebSocket.simulateMessage(mockWebSocketData.agent.agentAudioDone); - } - - /** - * Simulate a function call scenario - */ - public async simulateFunctionCall(): Promise { - // Wait for connection - await this.waitForConnection(); - - // Send welcome - this.mockWebSocket.simulateMessage(mockWebSocketData.agent.welcome); - - // Send function call request - this.mockWebSocket.simulateMessage(mockWebSocketData.agent.functionCallRequest); - } - - /** - * Wait for WebSocket connection to be established - */ - private async waitForConnection(): Promise { - return new Promise((resolve, reject) => { - if (this.mockWebSocket.isOpen()) { - resolve(); - return; - } - - let timeoutId: NodeJS.Timeout | null = null; - let intervalId: NodeJS.Timeout | null = null; - - // Set up timeout to reject if connection doesn't open within 5 seconds - timeoutId = setTimeout(() => { - if (intervalId) { - clearInterval(intervalId); - } - reject(new Error("WebSocket connection timeout: Connection did not open within 5 seconds")); - }, 5000); - - // Poll for connection with cleanup on success - const checkConnection = () => { - if (this.mockWebSocket.isOpen()) { - if (timeoutId) { - clearTimeout(timeoutId); - } - if (intervalId) { - clearInterval(intervalId); - } - resolve(); - } - }; - - // Start polling every 10ms - intervalId = setInterval(checkConnection, 10); - }); - } -} diff --git a/tests/custom.test.ts b/tests/custom.test.ts new file mode 100644 index 00000000..7f5e031c --- /dev/null +++ b/tests/custom.test.ts @@ -0,0 +1,13 @@ +/** + * This is a custom test file, if you wish to add more tests + * to your SDK. + * Be sure to mark this file in `.fernignore`. + * + * If you include example requests/responses in your fern definition, + * you will have tests automatically generated for you. + */ +describe("test", () => { + it("default", () => { + expect(true).toBe(true); + }); +}); diff --git a/tests/e2e/__mocks__/auth.ts b/tests/e2e/__mocks__/auth.ts deleted file mode 100644 index a7c032d6..00000000 --- a/tests/e2e/__mocks__/auth.ts +++ /dev/null @@ -1,9 +0,0 @@ -/** - * Mock response data for Auth API endpoints - */ - -export const mockGrantTokenResponse = { - access_token: - "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c", - expires_in: 28800, -}; diff --git a/tests/e2e/__mocks__/listen.ts b/tests/e2e/__mocks__/listen.ts deleted file mode 100644 index d761d74f..00000000 --- a/tests/e2e/__mocks__/listen.ts +++ /dev/null @@ -1,182 +0,0 @@ -/** - * Mock response data for Listen API endpoints - * Based on actual Deepgram API response structure - */ - -import type { AsyncPrerecordedResponse } from "../../../src/lib/types"; - -export const mockTranscribeFileResponse = { - metadata: { - transaction_key: "mock-transaction-key", - request_id: "mock-request-id-5678", - sha256: "mock-file-sha256-hash", - created: "2024-01-15T10:35:00.000Z", - duration: 25.933313, - channels: 1, - models: ["mock-model-uuid"], - model_info: { - "mock-model-uuid": { - name: "general-nova-3", - version: "2024-01-01.0", - arch: "nova-3", - }, - }, - }, - results: { - channels: [ - { - alternatives: [ - { - transcript: - "Yeah. As much as it's worth celebrating the first spacewalk with an all female team, I think many of us are looking forward to it just being normal. And I think if it signifies anything, it is to honor the women who came before us who were skilled and qualified and didn't get the same opportunities that we have today.", - confidence: 0.9983989, - words: [ - { - word: "yeah", - start: 0.0, - end: 0.48, - confidence: 0.99592936, - punctuated_word: "Yeah.", - }, - { - word: "as", - start: 0.48, - end: 0.64, - confidence: 0.994148, - punctuated_word: "As", - }, - { - word: "much", - start: 1.12, - end: 1.36, - confidence: 0.99942505, - punctuated_word: "much", - }, - // Truncated for brevity - this would contain all words - ], - paragraphs: { - transcript: - "Yeah. As much as it's worth celebrating the first spacewalk with an all female team, I think many of us are looking forward to it just being normal. And I think if it signifies anything, it is to honor the women who came before us who were skilled and qualified and didn't get the same opportunities that we have today.", - paragraphs: [ - { - sentences: [ - { - text: "Yeah.", - start: 0.0, - end: 0.48, - }, - { - text: "As much as it's worth celebrating the first spacewalk with an all female team, I think many of us are looking forward to it just being normal.", - start: 0.48, - end: 12.4, - }, - { - text: "And I think if it signifies anything, it is to honor the women who came before us who were skilled and qualified and didn't get the same opportunities that we have today.", - start: 12.795, - end: 25.355, - }, - ], - start: 0.0, - end: 25.355, - num_words: 62, - }, - ], - }, - }, - ], - }, - ], - }, -}; - -export const mockTranscribeUrlResponse = { - metadata: { - transaction_key: "mock-transaction-key", - request_id: "mock-request-id-1234", - sha256: "mock-sha256-hash", - created: "2024-01-15T10:30:00.000Z", - duration: 25.933313, - channels: 1, - models: ["mock-model-uuid"], - model_info: { - "mock-model-uuid": { - name: "general-nova-3", - version: "2024-01-01.0", - arch: "nova-3", - }, - }, - }, - results: { - channels: [ - { - alternatives: [ - { - transcript: - "Yeah. As much as it's worth celebrating the first spacewalk with an all female team, I think many of us are looking forward to it just being normal. And I think if it signifies anything, it is to honor the women who came before us who were skilled and qualified and didn't get the same opportunities that we have today.", - confidence: 0.9983989, - words: [ - { - word: "yeah", - start: 0.0, - end: 0.48, - confidence: 0.99592936, - punctuated_word: "Yeah.", - }, - { - word: "as", - start: 0.48, - end: 0.64, - confidence: 0.994148, - punctuated_word: "As", - }, - { - word: "much", - start: 1.12, - end: 1.36, - confidence: 0.99942505, - punctuated_word: "much", - }, - // Truncated for brevity - this would contain all words - ], - paragraphs: { - transcript: - "Yeah. As much as it's worth celebrating the first spacewalk with an all female team, I think many of us are looking forward to it just being normal. And I think if it signifies anything, it is to honor the women who came before us who were skilled and qualified and didn't get the same opportunities that we have today.", - paragraphs: [ - { - sentences: [ - { - text: "Yeah.", - start: 0.0, - end: 0.48, - }, - { - text: "As much as it's worth celebrating the first spacewalk with an all female team, I think many of us are looking forward to it just being normal.", - start: 0.48, - end: 12.4, - }, - { - text: "And I think if it signifies anything, it is to honor the women who came before us who were skilled and qualified and didn't get the same opportunities that we have today.", - start: 12.795, - end: 25.355, - }, - ], - start: 0.0, - end: 25.355, - num_words: 62, - }, - ], - }, - }, - ], - }, - ], - }, -}; - -export const mockAsyncListenUrlResponse: AsyncPrerecordedResponse = { - request_id: "async-550e8400-e29b-41d4-a716-446655440002", -}; - -export const mockAsyncListenFileResponse: AsyncPrerecordedResponse = { - request_id: "async-550e8400-e29b-41d4-a716-446655440003", -}; diff --git a/tests/e2e/__mocks__/manage.ts b/tests/e2e/__mocks__/manage.ts deleted file mode 100644 index 0ee7bad5..00000000 --- a/tests/e2e/__mocks__/manage.ts +++ /dev/null @@ -1,322 +0,0 @@ -/** - * Mock responses for Manage API endpoints - */ - -import type { - GetProjectsResponse, - GetProjectResponse, - MessageResponse, - GetProjectKeysResponse, - GetProjectKeyResponse, - CreateProjectKeyResponse, - GetProjectMembersResponse, - GetProjectMemberScopesResponse, - GetProjectInvitesResponse, - GetProjectUsageRequestsResponse, - GetProjectUsageRequestResponse, - GetProjectUsageSummaryResponse, - GetProjectUsageFieldsResponse, - GetProjectBalancesResponse, - GetProjectBalanceResponse, - GetModelsResponse, - GetModelResponse, - GetTokenDetailsResponse, - VoidResponse, -} from "../../../src/lib/types"; - -// Projects -export const mockGetProjectsResponse: GetProjectsResponse = { - projects: [ - { - project_id: "test-project-123", - name: "Test Project", - }, - { - project_id: "test-project-456", - name: "Another Project", - }, - ], -}; - -export const mockGetProjectResponse: GetProjectResponse = { - project_id: "test-project-123", - name: "Test Project", - company: "Test Company", -}; - -export const mockUpdateProjectResponse: MessageResponse = { - message: "Project updated successfully", -}; - -export const mockLeaveProjectResponse: MessageResponse = { - message: "Successfully left project", -}; - -// Keys -export const mockGetProjectKeysResponse: GetProjectKeysResponse = { - api_keys: [ - { - member: { - member_id: "test-member-123", - email: "test@example.com", - first_name: "Test", - last_name: "User", - }, - api_key: { - api_key_id: "test-key-123", - comment: "Test API key", - scopes: ["usage:write", "usage:read"], - created: "2024-01-01T00:00:00.000Z", - }, - }, - { - member: { - member_id: "test-member-456", - email: "another@example.com", - first_name: "Another", - last_name: "User", - }, - api_key: { - api_key_id: "test-key-456", - comment: "Another API key", - scopes: ["usage:read"], - created: "2024-01-02T00:00:00.000Z", - }, - }, - ], -}; - -export const mockGetProjectKeyResponse: GetProjectKeyResponse = { - member: { - member_id: "test-member-123", - email: "test@example.com", - first_name: "Test", - last_name: "User", - }, - api_key: { - api_key_id: "test-key-123", - comment: "Test API key", - scopes: ["usage:write", "usage:read"], - created: "2024-01-01T00:00:00.000Z", - }, -}; - -export const mockCreateProjectKeyResponse: CreateProjectKeyResponse = { - api_key_id: "test-key-new-789", - key: "ak_test_key_1234567890abcdef", - comment: "Test API key for e2e testing", - scopes: ["usage:write", "usage:read"], - created: "2024-01-01T00:00:00.000Z", -}; - -// Members -export const mockGetProjectMembersResponse: GetProjectMembersResponse = { - members: [ - { - member_id: "test-member-123", - email: "test@example.com", - first_name: "Test", - last_name: "User", - scopes: ["admin"], - }, - { - member_id: "test-member-456", - email: "another@example.com", - first_name: "Another", - last_name: "User", - scopes: ["member"], - }, - ], -}; - -export const mockGetProjectMemberScopesResponse: GetProjectMemberScopesResponse = { - scopes: ["member"], -}; - -export const mockUpdateProjectMemberScopeResponse: MessageResponse = { - message: "Member scope updated successfully", -}; - -// Invites -export const mockGetProjectInvitesResponse: GetProjectInvitesResponse = { - invites: [ - { - email: "invited@example.com", - scope: "member", - }, - ], -}; - -export const mockSendProjectInviteResponse: MessageResponse = { - message: "Invite sent successfully", -}; - -// Usage Requests -export const mockGetProjectUsageRequestsResponse: GetProjectUsageRequestsResponse = { - page: 0, - limit: 10, - requests: [ - { - request_id: "test-request-123", - created: "2024-01-01T00:00:00.000Z", - path: "/v1/listen", - api_key_id: "test-key-123", - response: { - code: 200, - completed: "2024-01-01T00:00:05.000Z", - details: { - usd: 0.0045, - duration: 30.5, - total_audio: 30.5, - channels: 1, - models: ["nova-2"], - method: "POST", - }, - }, - }, - { - request_id: "test-request-456", - created: "2024-01-01T01:00:00.000Z", - path: "/v1/speak", - api_key_id: "test-key-123", - response: { - code: 200, - completed: "2024-01-01T01:00:02.000Z", - details: { - usd: 0.002, - models: ["aura-thalia-en"], - method: "POST", - }, - }, - }, - ], -}; - -export const mockGetProjectUsageRequestResponse: GetProjectUsageRequestResponse = { - request_id: "test-request-123", - created: "2024-01-01T00:00:00.000Z", - path: "/v1/listen", - api_key_id: "test-key-123", - response: { - code: 200, - completed: "2024-01-01T00:00:05.000Z", - details: { - usd: 0.0045, - duration: 30.5, - total_audio: 30.5, - channels: 1, - models: ["nova-2"], - method: "POST", - }, - }, -}; - -export const mockGetProjectUsageSummaryResponse: GetProjectUsageSummaryResponse = { - start: "2024-01-01", - end: "2024-01-31", - resolution: { - units: "day", - amount: 1, - }, - results: [ - { - start: "2024-01-01", - end: "2024-01-31", - hours: 10.5, - total_hours: 10.5, - requests: 50, - }, - ], -}; - -export const mockGetProjectUsageFieldsResponse: GetProjectUsageFieldsResponse = { - tags: ["test", "production"], - models: [], - processing_methods: ["sync", "async"], - languages: ["en", "es", "fr"], - features: ["smart_format", "punctuate", "diarize"], -}; - -// Balances -export const mockGetProjectBalancesResponse: GetProjectBalancesResponse = { - balances: [ - { - balance_id: "test-balance-123", - amount: 100.5, - units: "usd", - purchase: "test-purchase-123", - }, - { - balance_id: "test-balance-456", - amount: 50.25, - units: "usd", - purchase: "test-purchase-456", - }, - ], -}; - -export const mockGetProjectBalanceResponse: GetProjectBalanceResponse = { - balance_id: "test-balance-123", - amount: 100.5, - units: "usd", - purchase: "test-purchase-123", -}; - -// Project-scoped Models (simplified) -export const mockGetAllProjectModelsResponse: GetModelsResponse = { - stt: [ - { - name: "nova-2", - canonical_name: "nova-2-general", - architecture: "nova-2", - languages: ["en"], - version: "2024-01-01", - uuid: "model-uuid-123", - }, - ], - tts: [ - { - name: "aura-thalia-en", - canonical_name: "aura-thalia-en", - architecture: "aura", - languages: ["en"], - version: "2024-01-01", - uuid: "model-uuid-456", - }, - ], -}; - -export const mockGetProjectModelResponse: GetModelResponse = { - name: "nova-2", - canonical_name: "nova-2-general", - architecture: "nova-2", - languages: ["en"], - version: "2024-01-01", - uuid: "model-uuid-123", -}; - -// Token Details -export const mockGetTokenDetailsResponse: GetTokenDetailsResponse = { - api_key_id: "test-key-123", - scopes: ["usage:write", "usage:read"], - created: "2024-01-01T00:00:00.000Z", -}; - -// Generic void/delete responses -export const mockDeleteProjectResponse: VoidResponse = { - error: null, -}; - -export const mockDeleteProjectKeyResponse: VoidResponse = { - error: null, -}; - -export const mockRemoveProjectMemberResponse: VoidResponse = { - error: null, -}; - -export const mockDeleteProjectInviteResponse: VoidResponse = { - error: null, -}; - -// Note: Other message responses already exist below in the file diff --git a/tests/e2e/__mocks__/models.ts b/tests/e2e/__mocks__/models.ts deleted file mode 100644 index 892f2f50..00000000 --- a/tests/e2e/__mocks__/models.ts +++ /dev/null @@ -1,63 +0,0 @@ -/** - * Mock response data for Models API endpoints - */ - -export const mockGetAllModelsResponse = { - stt: [ - { - name: "nova-2-general", - canonical_name: "nova-2-general", - architecture: "nova-2", - languages: ["en"], - version: "2024-01-09", - uuid: "f58fb2c5-4057-4aa2-a9a7-884ab2b25b48", - batch: true, - streaming: true, - metadata: { - tier: "nova", - }, - }, - { - name: "nova-2-phonecall", - canonical_name: "nova-2-phonecall", - architecture: "nova-2", - languages: ["en"], - version: "2024-01-09", - uuid: "a4c682e4-d5d8-4a2b-9e6c-f7e8d3a1b2c5", - batch: true, - streaming: true, - metadata: { - tier: "nova", - }, - }, - ], - tts: [ - { - name: "aura-2-thalia-en", - canonical_name: "aura-2-thalia-en", - architecture: "aura-2", - languages: ["en"], - version: "2024-01-09", - uuid: "b7d9a3f2-1c4e-5b8a-9d6f-2e3c1a7b4d9e", - metadata: { - tier: "aura", - }, - }, - ], -}; - -export const mockGetModelResponse = { - name: "nova-2-general", - canonical_name: "nova-2-general", - architecture: "nova-2", - languages: ["en"], - version: "2024-01-09", - uuid: "f58fb2c5-4057-4aa2-a9a7-884ab2b25b48", - batch: true, - streaming: true, - metadata: { - tier: "nova", - description: - "Nova-2 General is a powerful, fast, and accurate speech-to-text model for general use cases.", - }, -}; diff --git a/tests/e2e/__mocks__/read.ts b/tests/e2e/__mocks__/read.ts deleted file mode 100644 index f42dda1a..00000000 --- a/tests/e2e/__mocks__/read.ts +++ /dev/null @@ -1,133 +0,0 @@ -/** - * Mock response data for Read API endpoints - */ - -import type { AsyncAnalyzeResponse } from "../../../src/lib/types"; - -export const mockAnalyzeTextResponse = { - metadata: { - request_id: "mock-request-id-123", - created: "2024-01-09T10:00:00.000Z", - language: "en", - intents: { - model_uuid: "mock-intents-model-uuid", - model_name: "intent-classifier-v1", - model_metadata: {}, - }, - sentiment: { - model_uuid: "mock-sentiment-model-uuid", - model_name: "sentiment-analyzer-v1", - model_metadata: {}, - }, - summary: { - model_uuid: "mock-summary-model-uuid", - model_name: "text-summarizer-v1", - model_metadata: {}, - }, - }, - results: { - intents: { - segments: [ - { - text: "Hello world, this is a test.", - start_word: 0, - end_word: 6, - intents: [ - { - intent: "greeting", - confidence: 0.95, - }, - ], - }, - ], - }, - sentiments: { - segments: [ - { - text: "Hello world, this is a test.", - start_word: 0, - end_word: 6, - sentiment: "neutral", - sentiment_score: 0.0, - }, - ], - average: { - sentiment: "neutral", - sentiment_score: 0.0, - }, - }, - summary: { - short: "A simple test greeting message.", - }, - }, -}; - -export const mockAnalyzeUrlResponse = { - metadata: { - request_id: "mock-request-id-456", - created: "2024-01-09T10:00:00.000Z", - language: "en", - intents: { - model_uuid: "mock-intents-model-uuid", - model_name: "intent-classifier-v1", - model_metadata: {}, - }, - sentiment: { - model_uuid: "mock-sentiment-model-uuid", - model_name: "sentiment-analyzer-v1", - model_metadata: {}, - }, - summary: { - model_uuid: "mock-summary-model-uuid", - model_name: "text-summarizer-v1", - model_metadata: {}, - }, - }, - results: { - intents: { - segments: [ - { - text: "Content from URL source for analysis.", - start_word: 0, - end_word: 6, - intents: [ - { - intent: "informational", - confidence: 0.87, - }, - ], - }, - ], - }, - sentiments: { - segments: [ - { - text: "Content from URL source for analysis.", - start_word: 0, - end_word: 6, - sentiment: "neutral", - sentiment_score: 0.1, - }, - ], - average: { - sentiment: "neutral", - sentiment_score: 0.1, - }, - }, - summary: { - short: "Analysis of content from a URL source.", - }, - }, -}; - -export const mockAsyncAnalyzeResponse = { - request_id: "mock-async-request-id-789", -}; - -export const mockAsyncReadUrlResponse: AsyncAnalyzeResponse = { - request_id: "async-read-550e8400-e29b-41d4-a716-446655440004", -}; - -export const mockAsyncReadTextResponse: AsyncAnalyzeResponse = { - request_id: "async-read-550e8400-e29b-41d4-a716-446655440005", -}; diff --git a/tests/e2e/__mocks__/selfhosted.ts b/tests/e2e/__mocks__/selfhosted.ts deleted file mode 100644 index e378ee15..00000000 --- a/tests/e2e/__mocks__/selfhosted.ts +++ /dev/null @@ -1,66 +0,0 @@ -/** - * Mock response data for Self-hosted API endpoints - */ - -export const mockListCredentialsResponse = { - distribution_credentials: [ - { - member: { - member_id: "test-member-123", - email: "test@example.com", - }, - distribution_credentials: { - distribution_credentials_id: "test-credential-123", - comment: "Test credentials for development", - scopes: ["usage:write", "keys:read"], - provider: "test-provider", - created: "2024-01-09T10:00:00.000Z", - }, - }, - { - member: { - member_id: "test-member-456", - email: "prod@example.com", - }, - distribution_credentials: { - distribution_credentials_id: "test-credential-456", - comment: "Production credentials", - scopes: ["usage:write"], - provider: "prod-provider", - created: "2024-01-08T10:00:00.000Z", - }, - }, - ], -}; - -export const mockGetCredentialsResponse = { - member: { - member_id: "test-member-123", - email: "test@example.com", - }, - distribution_credentials: { - distribution_credentials_id: "test-credential-123", - comment: "Test credentials for development", - scopes: ["usage:write", "keys:read"], - provider: "test-provider", - created: "2024-01-09T10:00:00.000Z", - }, -}; - -export const mockCreateCredentialsResponse = { - member: { - member_id: "test-member-new", - email: "new@example.com", - }, - distribution_credentials: { - distribution_credentials_id: "test-credential-new-789", - comment: "Test credentials for e2e testing", - scopes: ["usage:write"], - provider: "test-provider", - created: "2024-01-09T11:00:00.000Z", - }, -}; - -export const mockDeleteCredentialsResponse = { - message: "Credentials successfully deleted", -}; diff --git a/tests/e2e/__mocks__/speak.ts b/tests/e2e/__mocks__/speak.ts deleted file mode 100644 index bcc9006b..00000000 --- a/tests/e2e/__mocks__/speak.ts +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Mock response for Speak API endpoint - * Based on actual Deepgram TTS API response structure - * Since TTS returns binary audio data, we'll simulate this with a mock buffer - */ - -// Create a mock audio buffer that simulates MP3 data -// This is just a minimal mock - real MP3 data would be much larger -export const mockAudioBuffer = Buffer.from([ - // MP3 header bytes (simplified mock) - 0xff, 0xfb, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Some mock audio data - 0x4c, 0x41, 0x4d, 0x45, 0x33, 0x2e, 0x31, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - // Add some more bytes to make it more realistic - 0x55, 0x55, 0x55, 0x55, 0xaa, 0xaa, 0xaa, 0xaa, -]); - -/** - * Mock headers that would be returned by the TTS API - */ -export const mockTTSHeaders = { - "content-type": "audio/mpeg", - "content-length": mockAudioBuffer.length.toString(), - "x-dg-model": "aura-2-thalia-en", - "x-dg-request-id": "mock-tts-request-id-1234", -} as const; diff --git a/tests/e2e/__snapshots__/auth-grant-token.test.ts.snap b/tests/e2e/__snapshots__/auth-grant-token.test.ts.snap deleted file mode 100644 index 1485e542..00000000 --- a/tests/e2e/__snapshots__/auth-grant-token.test.ts.snap +++ /dev/null @@ -1,8 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`auth grantToken E2E should generate a temporary access token: auth-grantToken-response-structure 1`] = ` -{ - "access_token": "", - "expires_in": "" -} -`; diff --git a/tests/e2e/__snapshots__/listen-transcribe-file-callback.test.ts.snap b/tests/e2e/__snapshots__/listen-transcribe-file-callback.test.ts.snap deleted file mode 100644 index 37906ff1..00000000 --- a/tests/e2e/__snapshots__/listen-transcribe-file-callback.test.ts.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`listen transcribeFileCallback E2E should transcribe file with callback and return async response: listen-transcribe-file-callback-response-structure 1`] = ` -{ - "error": null, - "result": { - "request_id": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/listen-transcribe-file.test.ts.snap b/tests/e2e/__snapshots__/listen-transcribe-file.test.ts.snap deleted file mode 100644 index 2a80afa1..00000000 --- a/tests/e2e/__snapshots__/listen-transcribe-file.test.ts.snap +++ /dev/null @@ -1,62 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`listen transcribeFile E2E should transcribe audio from file and match expected response structure: listen-transcribeFile-response-structure 1`] = ` -{ - "metadata": { - "channels": "", - "created": "", - "duration": "", - "model_info": { - "mock-model-uuid": { - "arch": "", - "name": "", - "version": "" - } - }, - "models": [ - "" - ], - "request_id": "", - "sha256": "", - "transaction_key": "" - }, - "results": { - "channels": [ - { - "alternatives": [ - { - "confidence": "", - "paragraphs": { - "paragraphs": [ - { - "end": "", - "num_words": "", - "sentences": [ - { - "end": "", - "start": "", - "text": "" - } - ], - "start": "" - } - ], - "transcript": "" - }, - "transcript": "", - "words": [ - { - "confidence": "", - "end": "", - "punctuated_word": "", - "start": "", - "word": "" - } - ] - } - ] - } - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/listen-transcribe-url-callback.test.ts.snap b/tests/e2e/__snapshots__/listen-transcribe-url-callback.test.ts.snap deleted file mode 100644 index 1c406824..00000000 --- a/tests/e2e/__snapshots__/listen-transcribe-url-callback.test.ts.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`listen transcribeUrlCallback E2E should transcribe URL with callback and return async response: listen-transcribe-url-callback-response-structure 1`] = ` -{ - "error": null, - "result": { - "request_id": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/listen-transcribe-url.test.ts.snap b/tests/e2e/__snapshots__/listen-transcribe-url.test.ts.snap deleted file mode 100644 index 77f31f4e..00000000 --- a/tests/e2e/__snapshots__/listen-transcribe-url.test.ts.snap +++ /dev/null @@ -1,62 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`listen transcribeUrl E2E should transcribe audio from URL and match expected response structure: listen-transcribeUrl-response-structure 1`] = ` -{ - "metadata": { - "channels": "", - "created": "", - "duration": "", - "model_info": { - "mock-model-uuid": { - "arch": "", - "name": "", - "version": "" - } - }, - "models": [ - "" - ], - "request_id": "", - "sha256": "", - "transaction_key": "" - }, - "results": { - "channels": [ - { - "alternatives": [ - { - "confidence": "", - "paragraphs": { - "paragraphs": [ - { - "end": "", - "num_words": "", - "sentences": [ - { - "end": "", - "start": "", - "text": "" - } - ], - "start": "" - } - ], - "transcript": "" - }, - "transcript": "", - "words": [ - { - "confidence": "", - "end": "", - "punctuated_word": "", - "start": "", - "word": "" - } - ] - } - ] - } - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-create-project-key.test.ts.snap b/tests/e2e/__snapshots__/manage-create-project-key.test.ts.snap deleted file mode 100644 index 347fc1d7..00000000 --- a/tests/e2e/__snapshots__/manage-create-project-key.test.ts.snap +++ /dev/null @@ -1,16 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage createProjectKey E2E should create a new API key for a specific project: manage-createProjectKey-response-structure 1`] = ` -{ - "error": null, - "result": { - "api_key_id": "", - "comment": "", - "created": "", - "key": "", - "scopes": [ - "" - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-all-models.test.ts.snap b/tests/e2e/__snapshots__/manage-get-all-models.test.ts.snap deleted file mode 100644 index f9d22c17..00000000 --- a/tests/e2e/__snapshots__/manage-get-all-models.test.ts.snap +++ /dev/null @@ -1,59 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getAllModels E2E should get all project models with basic options: manage-getAllModels-basic-response-structure 1`] = ` -{ - "stt": [ - { - "architecture": "", - "canonical_name": "", - "languages": [ - "" - ], - "name": "", - "uuid": "", - "version": "" - } - ], - "tts": [ - { - "architecture": "", - "canonical_name": "", - "languages": [ - "" - ], - "name": "", - "uuid": "", - "version": "" - } - ] -} -`; - -exports[`manage getAllModels E2E should get all project models with filtered options: manage-getAllModels-filtered-response-structure 1`] = ` -{ - "stt": [ - { - "architecture": "", - "canonical_name": "", - "languages": [ - "" - ], - "name": "", - "uuid": "", - "version": "" - } - ], - "tts": [ - { - "architecture": "", - "canonical_name": "", - "languages": [ - "" - ], - "name": "", - "uuid": "", - "version": "" - } - ] -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-model.test.ts.snap b/tests/e2e/__snapshots__/manage-get-model.test.ts.snap deleted file mode 100644 index b352c151..00000000 --- a/tests/e2e/__snapshots__/manage-get-model.test.ts.snap +++ /dev/null @@ -1,27 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getModel E2E should get a different project model: manage-getModel-tts-response-structure 1`] = ` -{ - "architecture": "", - "canonical_name": "", - "languages": [ - "" - ], - "name": "", - "uuid": "", - "version": "" -} -`; - -exports[`manage getModel E2E should get a specific project model: manage-getModel-stt-response-structure 1`] = ` -{ - "architecture": "", - "canonical_name": "", - "languages": [ - "" - ], - "name": "", - "uuid": "", - "version": "" -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-balance.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-balance.test.ts.snap deleted file mode 100644 index 24cfb38c..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-balance.test.ts.snap +++ /dev/null @@ -1,13 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectBalance E2E should retrieve a specific project balance by ID: manage-getProjectBalance-response-structure 1`] = ` -{ - "error": null, - "result": { - "amount": "", - "balance_id": "", - "purchase": "", - "units": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-balances.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-balances.test.ts.snap deleted file mode 100644 index 6ac4b536..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-balances.test.ts.snap +++ /dev/null @@ -1,17 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectBalances E2E should retrieve all project balances for a specific project: manage-getProjectBalances-response-structure 1`] = ` -{ - "error": null, - "result": { - "balances": [ - { - "amount": "", - "balance_id": "", - "purchase": "", - "units": "" - } - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-invites.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-invites.test.ts.snap deleted file mode 100644 index 2bd60d89..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-invites.test.ts.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectInvites E2E should retrieve all project invitations for a specific project: manage-getProjectInvites-response-structure 1`] = ` -{ - "error": null, - "result": { - "invites": [ - { - "email": "", - "scope": "" - } - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-key.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-key.test.ts.snap deleted file mode 100644 index 4011ae06..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-key.test.ts.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectKey E2E should retrieve a specific project key by ID: manage-getProjectKey-response-structure 1`] = ` -{ - "error": null, - "result": { - "api_key": { - "api_key_id": "", - "comment": "", - "created": "", - "scopes": [ - "" - ] - }, - "member": { - "email": "", - "first_name": "", - "last_name": "", - "member_id": "" - } - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-keys.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-keys.test.ts.snap deleted file mode 100644 index 64e1dfbf..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-keys.test.ts.snap +++ /dev/null @@ -1,27 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectKeys E2E should retrieve all project keys for a specific project: manage-getProjectKeys-response-structure 1`] = ` -{ - "error": null, - "result": { - "api_keys": [ - { - "api_key": { - "api_key_id": "", - "comment": "", - "created": "", - "scopes": [ - "" - ] - }, - "member": { - "email": "", - "first_name": "", - "last_name": "", - "member_id": "" - } - } - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-member-scopes.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-member-scopes.test.ts.snap deleted file mode 100644 index b303ff7a..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-member-scopes.test.ts.snap +++ /dev/null @@ -1,12 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectMemberScopes E2E should retrieve member scopes for a specific project member: manage-getProjectMemberScopes-response-structure 1`] = ` -{ - "error": null, - "result": { - "scopes": [ - "" - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-members.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-members.test.ts.snap deleted file mode 100644 index 69c25d66..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-members.test.ts.snap +++ /dev/null @@ -1,20 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectMembers E2E should retrieve all project members for a specific project: manage-getProjectMembers-response-structure 1`] = ` -{ - "error": null, - "result": { - "members": [ - { - "email": "", - "first_name": "", - "last_name": "", - "member_id": "", - "scopes": [ - "" - ] - } - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-usage-fields.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-usage-fields.test.ts.snap deleted file mode 100644 index 8b232681..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-usage-fields.test.ts.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectUsageFields E2E should retrieve usage fields for a specific project with basic options: manage-getProjectUsageFields-response-structure 1`] = ` -{ - "error": null, - "result": { - "features": [ - "" - ], - "languages": [ - "" - ], - "models": [], - "processing_methods": [ - "" - ], - "tags": [ - "" - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-usage-request.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-usage-request.test.ts.snap deleted file mode 100644 index 8f2294d9..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-usage-request.test.ts.snap +++ /dev/null @@ -1,27 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectUsageRequest E2E should retrieve a specific usage request by ID: manage-getProjectUsageRequest-response-structure 1`] = ` -{ - "error": null, - "result": { - "api_key_id": "", - "created": "", - "path": "", - "request_id": "", - "response": { - "code": "", - "completed": "", - "details": { - "channels": "", - "duration": "", - "method": "", - "models": [ - "" - ], - "total_audio": "", - "usd": "" - } - } - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-usage-requests.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-usage-requests.test.ts.snap deleted file mode 100644 index 7859d535..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-usage-requests.test.ts.snap +++ /dev/null @@ -1,33 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectUsageRequests E2E should retrieve usage requests for a specific project with basic options: manage-getProjectUsageRequests-response-structure 1`] = ` -{ - "error": null, - "result": { - "limit": "", - "page": "", - "requests": [ - { - "api_key_id": "", - "created": "", - "path": "", - "request_id": "", - "response": { - "code": "", - "completed": "", - "details": { - "channels": "", - "duration": "", - "method": "", - "models": [ - "" - ], - "total_audio": "", - "usd": "" - } - } - } - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project-usage-summary.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project-usage-summary.test.ts.snap deleted file mode 100644 index 577381a2..00000000 --- a/tests/e2e/__snapshots__/manage-get-project-usage-summary.test.ts.snap +++ /dev/null @@ -1,24 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjectUsageSummary E2E should retrieve usage summary for a specific project with basic options: manage-getProjectUsageSummary-response-structure 1`] = ` -{ - "error": null, - "result": { - "end": "", - "resolution": { - "amount": "", - "units": "" - }, - "results": [ - { - "end": "", - "hours": "", - "requests": "", - "start": "", - "total_hours": "" - } - ], - "start": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-project.test.ts.snap b/tests/e2e/__snapshots__/manage-get-project.test.ts.snap deleted file mode 100644 index f3354099..00000000 --- a/tests/e2e/__snapshots__/manage-get-project.test.ts.snap +++ /dev/null @@ -1,12 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProject E2E should retrieve a specific project by ID: manage-getProject-response-structure 1`] = ` -{ - "error": null, - "result": { - "company": "", - "name": "", - "project_id": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-projects.test.ts.snap b/tests/e2e/__snapshots__/manage-get-projects.test.ts.snap deleted file mode 100644 index 506dc02d..00000000 --- a/tests/e2e/__snapshots__/manage-get-projects.test.ts.snap +++ /dev/null @@ -1,15 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getProjects E2E should retrieve all projects for the authenticated user: manage-getProjects-response-structure 1`] = ` -{ - "error": null, - "result": { - "projects": [ - { - "name": "", - "project_id": "" - } - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-get-token-details.test.ts.snap b/tests/e2e/__snapshots__/manage-get-token-details.test.ts.snap deleted file mode 100644 index 9fddca15..00000000 --- a/tests/e2e/__snapshots__/manage-get-token-details.test.ts.snap +++ /dev/null @@ -1,14 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage getTokenDetails E2E should retrieve token details for the authenticated user: manage-getTokenDetails-response-structure 1`] = ` -{ - "error": null, - "result": { - "api_key_id": "", - "created": "", - "scopes": [ - "" - ] - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-leave-project.test.ts.snap b/tests/e2e/__snapshots__/manage-leave-project.test.ts.snap deleted file mode 100644 index d2d2009c..00000000 --- a/tests/e2e/__snapshots__/manage-leave-project.test.ts.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage leaveProject E2E should leave a project: manage-leaveProject-response-structure 1`] = ` -{ - "message": "" -} -`; diff --git a/tests/e2e/__snapshots__/manage-send-project-invite.test.ts.snap b/tests/e2e/__snapshots__/manage-send-project-invite.test.ts.snap deleted file mode 100644 index d57806d0..00000000 --- a/tests/e2e/__snapshots__/manage-send-project-invite.test.ts.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage sendProjectInvite E2E should send a project invitation to a single email: manage-sendProjectInvite-response-structure 1`] = ` -{ - "error": null, - "result": { - "message": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-update-project-member-scope.test.ts.snap b/tests/e2e/__snapshots__/manage-update-project-member-scope.test.ts.snap deleted file mode 100644 index 4105150c..00000000 --- a/tests/e2e/__snapshots__/manage-update-project-member-scope.test.ts.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage updateProjectMemberScope E2E should update a project member's scope: manage-updateProjectMemberScope-response-structure 1`] = ` -{ - "error": null, - "result": { - "message": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/manage-update-project.test.ts.snap b/tests/e2e/__snapshots__/manage-update-project.test.ts.snap deleted file mode 100644 index 479b0fa6..00000000 --- a/tests/e2e/__snapshots__/manage-update-project.test.ts.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`manage updateProject E2E should update a project with new details: manage-updateProject-response-structure 1`] = ` -{ - "error": null, - "result": { - "message": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/models-get-all.test.ts.snap b/tests/e2e/__snapshots__/models-get-all.test.ts.snap deleted file mode 100644 index 850c322b..00000000 --- a/tests/e2e/__snapshots__/models-get-all.test.ts.snap +++ /dev/null @@ -1,38 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`models getAll E2E should retrieve all available models: models-getAll-response-structure 1`] = ` -{ - "stt": [ - { - "architecture": "", - "batch": "", - "canonical_name": "", - "languages": [ - "" - ], - "metadata": { - "tier": "" - }, - "name": "", - "streaming": "", - "uuid": "", - "version": "" - } - ], - "tts": [ - { - "architecture": "", - "canonical_name": "", - "languages": [ - "" - ], - "metadata": { - "tier": "" - }, - "name": "", - "uuid": "", - "version": "" - } - ] -} -`; diff --git a/tests/e2e/__snapshots__/models-get-model.test.ts.snap b/tests/e2e/__snapshots__/models-get-model.test.ts.snap deleted file mode 100644 index 99a0984c..00000000 --- a/tests/e2e/__snapshots__/models-get-model.test.ts.snap +++ /dev/null @@ -1,20 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`models getModel E2E should retrieve specific model information: models-getModel-response-structure 1`] = ` -{ - "architecture": "", - "batch": "", - "canonical_name": "", - "languages": [ - "" - ], - "metadata": { - "description": "", - "tier": "" - }, - "name": "", - "streaming": "", - "uuid": "", - "version": "" -} -`; diff --git a/tests/e2e/__snapshots__/read-analyze-text-callback.test.ts.snap b/tests/e2e/__snapshots__/read-analyze-text-callback.test.ts.snap deleted file mode 100644 index 009dcf83..00000000 --- a/tests/e2e/__snapshots__/read-analyze-text-callback.test.ts.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`read analyzeTextCallback E2E should analyze text with callback and return async response: read-analyze-text-callback-response-structure 1`] = ` -{ - "error": null, - "result": { - "request_id": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/read-analyze-text.test.ts.snap b/tests/e2e/__snapshots__/read-analyze-text.test.ts.snap deleted file mode 100644 index dc7b90b0..00000000 --- a/tests/e2e/__snapshots__/read-analyze-text.test.ts.snap +++ /dev/null @@ -1,61 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`read analyzeText E2E should analyze text synchronously: read-analyzeText-response-structure 1`] = ` -{ - "metadata": { - "created": "", - "intents": { - "model_metadata": {}, - "model_name": "", - "model_uuid": "" - }, - "language": "", - "request_id": "", - "sentiment": { - "model_metadata": {}, - "model_name": "", - "model_uuid": "" - }, - "summary": { - "model_metadata": {}, - "model_name": "", - "model_uuid": "" - } - }, - "results": { - "intents": { - "segments": [ - { - "end_word": "", - "intents": [ - { - "confidence": "", - "intent": "" - } - ], - "start_word": "", - "text": "" - } - ] - }, - "sentiments": { - "average": { - "sentiment": "", - "sentiment_score": "" - }, - "segments": [ - { - "end_word": "", - "sentiment": "", - "sentiment_score": "", - "start_word": "", - "text": "" - } - ] - }, - "summary": { - "short": "" - } - } -} -`; diff --git a/tests/e2e/__snapshots__/read-analyze-url-callback.test.ts.snap b/tests/e2e/__snapshots__/read-analyze-url-callback.test.ts.snap deleted file mode 100644 index 3d6f1426..00000000 --- a/tests/e2e/__snapshots__/read-analyze-url-callback.test.ts.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`read analyzeUrlCallback E2E should analyze URL with callback and return async response: read-analyze-url-callback-response-structure 1`] = ` -{ - "error": null, - "result": { - "request_id": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/read-analyze-url.test.ts.snap b/tests/e2e/__snapshots__/read-analyze-url.test.ts.snap deleted file mode 100644 index abb6fc5f..00000000 --- a/tests/e2e/__snapshots__/read-analyze-url.test.ts.snap +++ /dev/null @@ -1,61 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`read analyzeUrl E2E should analyze URL source synchronously: read-analyzeUrl-response-structure 1`] = ` -{ - "metadata": { - "created": "", - "intents": { - "model_metadata": {}, - "model_name": "", - "model_uuid": "" - }, - "language": "", - "request_id": "", - "sentiment": { - "model_metadata": {}, - "model_name": "", - "model_uuid": "" - }, - "summary": { - "model_metadata": {}, - "model_name": "", - "model_uuid": "" - } - }, - "results": { - "intents": { - "segments": [ - { - "end_word": "", - "intents": [ - { - "confidence": "", - "intent": "" - } - ], - "start_word": "", - "text": "" - } - ] - }, - "sentiments": { - "average": { - "sentiment": "", - "sentiment_score": "" - }, - "segments": [ - { - "end_word": "", - "sentiment": "", - "sentiment_score": "", - "start_word": "", - "text": "" - } - ] - }, - "summary": { - "short": "" - } - } -} -`; diff --git a/tests/e2e/__snapshots__/selfhosted-create-credentials.test.ts.snap b/tests/e2e/__snapshots__/selfhosted-create-credentials.test.ts.snap deleted file mode 100644 index 85c7e330..00000000 --- a/tests/e2e/__snapshots__/selfhosted-create-credentials.test.ts.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`selfhosted createCredentials E2E should create new self-hosted credentials: selfhosted-createCredentials-response-structure 1`] = ` -{ - "distribution_credentials": { - "comment": "", - "created": "", - "distribution_credentials_id": "", - "provider": "", - "scopes": [ - "" - ] - }, - "member": { - "email": "", - "member_id": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/selfhosted-delete-credentials.test.ts.snap b/tests/e2e/__snapshots__/selfhosted-delete-credentials.test.ts.snap deleted file mode 100644 index 2dd4566b..00000000 --- a/tests/e2e/__snapshots__/selfhosted-delete-credentials.test.ts.snap +++ /dev/null @@ -1,7 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`selfhosted deleteCredentials E2E should delete self-hosted credentials: selfhosted-deleteCredentials-response-structure 1`] = ` -{ - "message": "" -} -`; diff --git a/tests/e2e/__snapshots__/selfhosted-get-credentials.test.ts.snap b/tests/e2e/__snapshots__/selfhosted-get-credentials.test.ts.snap deleted file mode 100644 index 2bb675fa..00000000 --- a/tests/e2e/__snapshots__/selfhosted-get-credentials.test.ts.snap +++ /dev/null @@ -1,19 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`selfhosted getCredentials E2E should retrieve specific self-hosted credentials: selfhosted-getCredentials-response-structure 1`] = ` -{ - "distribution_credentials": { - "comment": "", - "created": "", - "distribution_credentials_id": "", - "provider": "", - "scopes": [ - "" - ] - }, - "member": { - "email": "", - "member_id": "" - } -} -`; diff --git a/tests/e2e/__snapshots__/selfhosted-list-credentials.test.ts.snap b/tests/e2e/__snapshots__/selfhosted-list-credentials.test.ts.snap deleted file mode 100644 index bc7b3ef8..00000000 --- a/tests/e2e/__snapshots__/selfhosted-list-credentials.test.ts.snap +++ /dev/null @@ -1,23 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`selfhosted listCredentials E2E should list self-hosted credentials: selfhosted-listCredentials-response-structure 1`] = ` -{ - "distribution_credentials": [ - { - "distribution_credentials": { - "comment": "", - "created": "", - "distribution_credentials_id": "", - "provider": "", - "scopes": [ - "" - ] - }, - "member": { - "email": "", - "member_id": "" - } - } - ] -} -`; diff --git a/tests/e2e/__snapshots__/speak-request.test.ts.snap b/tests/e2e/__snapshots__/speak-request.test.ts.snap deleted file mode 100644 index 57513a96..00000000 --- a/tests/e2e/__snapshots__/speak-request.test.ts.snap +++ /dev/null @@ -1,10 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`speak request E2E should generate speech from text and return audio data: speak-request-response-headers 1`] = ` -{ - "content-length": "", - "content-type": "", - "x-dg-model": "", - "x-dg-request-id": "" -} -`; diff --git a/tests/e2e/agent-live-connection.test.ts b/tests/e2e/agent-live-connection.test.ts deleted file mode 100644 index cc515762..00000000 --- a/tests/e2e/agent-live-connection.test.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { AgentLiveClient } from "../../src/packages/AgentLiveClient"; -import { AgentEvents } from "../../src/lib/enums/AgentEvents"; -import { CONNECTION_STATE } from "../../src/lib/constants"; -import { MockWebSocket, WebSocketScenario, mockWebSocketData } from "../__utils__/websocket-mocks"; - -// Helper to wait for events -function waitForEvent(emitter: any, eventName: string, timeout = 2000): Promise { - return new Promise((resolve, reject) => { - const timer = setTimeout(() => { - reject(new Error(`Event '${eventName}' did not fire within ${timeout}ms`)); - }, timeout); - - emitter.once(eventName, (data: any) => { - clearTimeout(timer); - resolve(data); - }); - }); -} - -// Helper to collect multiple events -function collectEvents(emitter: any, eventNames: string[], timeout = 3000): Promise { - return new Promise((resolve, reject) => { - const results: any[] = []; - const received = new Set(); - - const timer = setTimeout(() => { - reject( - new Error( - `Not all events received within ${timeout}ms. Missing: ${eventNames.filter( - (name) => !received.has(name) - )}` - ) - ); - }, timeout); - - eventNames.forEach((eventName) => { - emitter.on(eventName, (data: any) => { - if (!received.has(eventName)) { - received.add(eventName); - results.push({ event: eventName, data }); - - if (received.size === eventNames.length) { - clearTimeout(timer); - resolve(results); - } - } - }); - }); - }); -} - -describe("agent live connection E2E", () => { - let mockWebSocketInstance: MockWebSocket; - let client: AgentLiveClient; - - // Custom WebSocket constructor that captures the instance - const createMockWebSocketConstructor = () => { - return class MockWebSocketConstructor extends MockWebSocket { - constructor(url: string, protocols?: string | string[], options?: any) { - super(url, protocols, options); - // Store instance for test access - mockWebSocketInstance = this as MockWebSocket; - } - }; - }; - - beforeEach(() => { - const MockWebSocketConstructor = createMockWebSocketConstructor(); - - client = new AgentLiveClient({ - key: "test-api-key", - global: { - websocket: { - // @ts-expect-error - Using mock for testing - client: MockWebSocketConstructor, - }, - }, - }); - }); - - afterEach(() => { - if (client) { - client.disconnect(); - } - }); - - it("should handle complete agent conversation workflow", async () => { - await waitForEvent(client, AgentEvents.Open); - - expect(client.connectionState()).toBe(CONNECTION_STATE.Open); - expect(mockWebSocketInstance.url).toContain("agent"); - - // Set up event collectors for conversation workflow - const eventsPromise = collectEvents(client, [ - AgentEvents.Welcome, - AgentEvents.ConversationText, - AgentEvents.AgentThinking, - AgentEvents.AgentStartedSpeaking, - AgentEvents.Audio, - AgentEvents.AgentAudioDone, - ]); - - // Simulate complete conversation - const scenario = new WebSocketScenario(mockWebSocketInstance); - await scenario.simulateAgentConversation(); - - const events = await eventsPromise; - expect(events).toHaveLength(6); - - const eventMap = events.reduce((acc, { event, data }) => { - acc[event] = data; - return acc; - }, {}); - - expect(eventMap[AgentEvents.Welcome]).toEqual(mockWebSocketData.agent.welcome); - expect(eventMap[AgentEvents.ConversationText]).toEqual( - mockWebSocketData.agent.conversationText - ); - expect(eventMap[AgentEvents.AgentThinking]).toEqual(mockWebSocketData.agent.agentThinking); - expect(eventMap[AgentEvents.AgentStartedSpeaking]).toEqual( - mockWebSocketData.agent.agentStartedSpeaking - ); - expect(eventMap[AgentEvents.Audio]).toBeInstanceOf(Buffer); - expect(eventMap[AgentEvents.AgentAudioDone]).toEqual(mockWebSocketData.agent.agentAudioDone); - }); - - it("should handle function call interaction workflow", async () => { - await waitForEvent(client, AgentEvents.Open); - - // Set up event collectors for function call scenario - const eventsPromise = collectEvents(client, [ - AgentEvents.Welcome, - AgentEvents.FunctionCallRequest, - ]); - - // Simulate function call scenario - const scenario = new WebSocketScenario(mockWebSocketInstance); - await scenario.simulateFunctionCall(); - - const events = await eventsPromise; - expect(events).toHaveLength(2); - - const functionCallEvent = events.find((e) => e.event === AgentEvents.FunctionCallRequest); - expect(functionCallEvent.data).toEqual(mockWebSocketData.agent.functionCallRequest); - expect(functionCallEvent.data.functions).toHaveLength(1); - expect(functionCallEvent.data.functions[0].name).toBe("get_weather"); - }); - - it("should handle bidirectional audio communication", async () => { - await waitForEvent(client, AgentEvents.Open); - - // Simulate sending user audio to agent - const userAudio1 = new ArrayBuffer(1024); - const userAudio2 = new ArrayBuffer(2048); - - client.send(userAudio1); - client.send(userAudio2); - - // Send keepAlive during conversation - client.keepAlive(); - - const sentMessages = mockWebSocketInstance.getSentMessages(); - expect(sentMessages).toContain(userAudio1); - expect(sentMessages).toContain(userAudio2); - expect(sentMessages).toContain(JSON.stringify({ type: "KeepAlive" })); - }); -}); diff --git a/tests/e2e/auth-grant-token.test.ts b/tests/e2e/auth-grant-token.test.ts deleted file mode 100644 index 0d51a9c4..00000000 --- a/tests/e2e/auth-grant-token.test.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { createClient } from "../../src/index"; -import { AuthRestClient } from "../../src/packages/AuthRestClient"; -import { DeepgramError } from "../../src/lib/errors"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; - -describe("auth grantToken E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should generate a temporary access token", async () => { - const { result, error } = await deepgram.auth.grantToken(); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - // Type guard to ensure result is not null for subsequent operations - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot - expect(result).toMatchSnapshot("auth-grantToken-response-structure"); - - // Essential structural validation - expect(result).toHaveProperty("access_token"); - expect(result).toHaveProperty("expires_in"); - - // Verify data types and format - expect(typeof result.access_token).toBe("string"); - expect(typeof result.expires_in).toBe("number"); - - // Verify access token is a non-empty string (should be JWT format in real API) - expect(result.access_token.length).toBeGreaterThan(0); - - // Verify expires_in is a positive number (typically in seconds) - expect(result.expires_in).toBeGreaterThan(0); - }, 30000); - - it("should handle custom endpoint for token generation", async () => { - const customEndpoint = ":version/auth/grant"; - const { result, error } = await deepgram.auth.grantToken({}, customEndpoint); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Verify the response structure is consistent - expect(result).toHaveProperty("access_token"); - expect(result).toHaveProperty("expires_in"); - expect(typeof result.access_token).toBe("string"); - expect(typeof result.expires_in).toBe("number"); - }, 30000); - - it("should generate token with custom ttl_seconds", async () => { - const { result, error } = await deepgram.auth.grantToken({ ttl_seconds: 60 }); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Verify the response structure is consistent - expect(result).toHaveProperty("access_token"); - expect(result).toHaveProperty("expires_in"); - expect(typeof result.access_token).toBe("string"); - expect(typeof result.expires_in).toBe("number"); - - // Verify access token is a non-empty string - expect(result.access_token.length).toBeGreaterThan(0); - expect(result.expires_in).toBeGreaterThan(0); - }, 30000); - - it("should handle ttl_seconds with custom endpoint", async () => { - const customEndpoint = ":version/auth/grant"; - const { result, error } = await deepgram.auth.grantToken({ ttl_seconds: 120 }, customEndpoint); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Verify the response structure is consistent - expect(result).toHaveProperty("access_token"); - expect(result).toHaveProperty("expires_in"); - expect(typeof result.access_token).toBe("string"); - expect(typeof result.expires_in).toBe("number"); - }, 30000); - - it("should handle empty options object (backward compatibility)", async () => { - const { result, error } = await deepgram.auth.grantToken({}); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Verify the response structure is consistent - expect(result).toHaveProperty("access_token"); - expect(result).toHaveProperty("expires_in"); - expect(typeof result.access_token).toBe("string"); - expect(typeof result.expires_in).toBe("number"); - }, 30000); - - it("should handle DeepgramError and return it in response", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const authClient = new AuthRestClient({ key: apiKey }); - - // Mock the post method to throw a DeepgramError - const mockError = new DeepgramError("Test DeepgramError"); - jest.spyOn(authClient as any, "post").mockRejectedValue(mockError); - - const { result, error } = await authClient.grantToken(); - - expect(result).toBeNull(); - expect(error).toBe(mockError); - expect(error).toBeInstanceOf(DeepgramError); - - // Clean up spy - jest.restoreAllMocks(); - }); - - it("should re-throw non-DeepgramError", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const authClient = new AuthRestClient({ key: apiKey }); - - // Mock the post method to throw a regular Error - const mockError = new Error("Network error"); - jest.spyOn(authClient as any, "post").mockRejectedValue(mockError); - - await expect(authClient.grantToken()).rejects.toThrow("Network error"); - await expect(authClient.grantToken()).rejects.toThrow(Error); - - // Clean up spy - jest.restoreAllMocks(); - }); -}); diff --git a/tests/e2e/listen-live-connection.test.ts b/tests/e2e/listen-live-connection.test.ts deleted file mode 100644 index b20f6563..00000000 --- a/tests/e2e/listen-live-connection.test.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { ListenLiveClient } from "../../src/packages/ListenLiveClient"; -import { LiveTranscriptionEvents } from "../../src/lib/enums/LiveTranscriptionEvents"; -import { CONNECTION_STATE } from "../../src/lib/constants"; -import { MockWebSocket, WebSocketScenario, mockWebSocketData } from "../__utils__/websocket-mocks"; - -// Helper to wait for events -function waitForEvent(emitter: any, eventName: string, timeout = 2000): Promise { - return new Promise((resolve, reject) => { - const timer = setTimeout(() => { - reject(new Error(`Event '${eventName}' did not fire within ${timeout}ms`)); - }, timeout); - - emitter.once(eventName, (data: any) => { - clearTimeout(timer); - resolve(data); - }); - }); -} - -// Helper to collect multiple events -function collectEvents(emitter: any, eventNames: string[], timeout = 3000): Promise { - return new Promise((resolve, reject) => { - const results: any[] = []; - const received = new Set(); - - const timer = setTimeout(() => { - reject( - new Error( - `Not all events received within ${timeout}ms. Missing: ${eventNames.filter( - (name) => !received.has(name) - )}` - ) - ); - }, timeout); - - eventNames.forEach((eventName) => { - emitter.on(eventName, (data: any) => { - if (!received.has(eventName)) { - received.add(eventName); - results.push({ event: eventName, data }); - - if (received.size === eventNames.length) { - clearTimeout(timer); - resolve(results); - } - } - }); - }); - }); -} - -describe("listen live connection E2E", () => { - let mockWebSocketInstance: MockWebSocket; - let client: ListenLiveClient; - - // Custom WebSocket constructor that captures the instance - const createMockWebSocketConstructor = () => { - return class MockWebSocketConstructor extends MockWebSocket { - constructor(url: string, protocols?: string | string[], options?: any) { - super(url, protocols, options); - // Store instance for test access - mockWebSocketInstance = this as MockWebSocket; - } - }; - }; - - beforeEach(() => { - const MockWebSocketConstructor = createMockWebSocketConstructor(); - - client = new ListenLiveClient({ - key: "test-api-key", - global: { - websocket: { - // @ts-expect-error - Using mock for testing - client: MockWebSocketConstructor, - }, - }, - }); - }); - - afterEach(() => { - if (client) { - client.disconnect(); - } - }); - - it("should establish WebSocket connection and handle full transcription workflow", async () => { - // Wait for connection to establish - const connectionPromise = waitForEvent(client, LiveTranscriptionEvents.Open); - await connectionPromise; - - expect(client.connectionState()).toBe(CONNECTION_STATE.Open); - expect(mockWebSocketInstance.url).toContain("listen"); - expect(mockWebSocketInstance.isOpen()).toBe(true); - - // Set up event collectors for the full workflow - const eventsPromise = collectEvents(client, [ - LiveTranscriptionEvents.Metadata, - LiveTranscriptionEvents.SpeechStarted, - LiveTranscriptionEvents.Transcript, - LiveTranscriptionEvents.UtteranceEnd, - ]); - - // Simulate a complete transcription session - const scenario = new WebSocketScenario(mockWebSocketInstance); - await scenario.simulateListenTranscription(); - - // Verify all events were received in order - const events = await eventsPromise; - expect(events).toHaveLength(4); - - const eventMap = events.reduce((acc, { event, data }) => { - acc[event] = data; - return acc; - }, {}); - - expect(eventMap[LiveTranscriptionEvents.Metadata]).toEqual(mockWebSocketData.listen.metadata); - expect(eventMap[LiveTranscriptionEvents.SpeechStarted]).toEqual( - mockWebSocketData.listen.speechStarted - ); - expect(eventMap[LiveTranscriptionEvents.Transcript]).toEqual( - mockWebSocketData.listen.transcript - ); - expect(eventMap[LiveTranscriptionEvents.UtteranceEnd]).toEqual( - mockWebSocketData.listen.utteranceEnd - ); - }); - - it("should handle real-time audio streaming simulation", async () => { - await waitForEvent(client, LiveTranscriptionEvents.Open); - - // Simulate sending audio chunks - const audioChunk1 = new ArrayBuffer(1024); - const audioChunk2 = new ArrayBuffer(2048); - const audioChunk3 = new ArrayBuffer(512); - - client.send(audioChunk1); - client.send(audioChunk2); - client.send(audioChunk3); - - const sentMessages = mockWebSocketInstance.getSentMessages(); - expect(sentMessages).toContain(audioChunk1); - expect(sentMessages).toContain(audioChunk2); - expect(sentMessages).toContain(audioChunk3); - expect(sentMessages).toHaveLength(3); - }); - - it("should handle connection interruption and recovery", async () => { - await waitForEvent(client, LiveTranscriptionEvents.Open); - - // Simulate connection loss - const closePromise = waitForEvent(client, LiveTranscriptionEvents.Close); - mockWebSocketInstance.close(1006, "Connection lost"); - - const closeEvent = await closePromise; - expect(closeEvent.code).toBe(1006); - expect(client.connectionState()).toBe(CONNECTION_STATE.Closed); - - // Verify reconnect capability exists - expect(typeof client.reconnect).toBe("function"); - }); - - it("should handle keepAlive mechanism for long sessions", async () => { - await waitForEvent(client, LiveTranscriptionEvents.Open); - - // Simulate periodic keepAlive calls - client.keepAlive(); - client.keepAlive(); - client.keepAlive(); - - const sentMessages = mockWebSocketInstance.getSentMessages(); - const keepAliveMessages = sentMessages.filter( - (msg) => msg === JSON.stringify({ type: "KeepAlive" }) - ); - expect(keepAliveMessages).toHaveLength(3); - }); - - it("should handle graceful session termination", async () => { - await waitForEvent(client, LiveTranscriptionEvents.Open); - - // Send close stream request - client.requestClose(); - - const sentMessages = mockWebSocketInstance.getSentMessages(); - expect(sentMessages).toContain(JSON.stringify({ type: "CloseStream" })); - - // Disconnect the client - client.disconnect(); - - // Check final connection state - expect(client.connectionState()).toBe(CONNECTION_STATE.Closed); - }); -}); diff --git a/tests/e2e/listen-transcribe-file-callback.test.ts b/tests/e2e/listen-transcribe-file-callback.test.ts deleted file mode 100644 index 8d9886bc..00000000 --- a/tests/e2e/listen-transcribe-file-callback.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { callbackUrls, testAudioFiles, transcriptionOptions } from "../__fixtures__/listen"; -import type { DeepgramResponse, AsyncPrerecordedResponse } from "../../src/lib/types"; -import { CallbackUrl } from "../../src/lib/helpers"; -import { readFileSync } from "fs"; -import { resolve } from "path"; - -describe("listen transcribeFileCallback E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should transcribe file with callback and return async response", async () => { - const audioFile = readFileSync( - resolve(__dirname, "..", "__fixtures__", testAudioFiles.spacewalk) - ); - - const response: DeepgramResponse = - await deepgram.listen.prerecorded.transcribeFileCallback( - audioFile, - new CallbackUrl(callbackUrls.webhook), - transcriptionOptions.basic - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("request_id"); - expect(typeof response.result.request_id).toBe("string"); - expect(response.result.request_id.length).toBeGreaterThan(0); - } - - expect(response).toMatchSnapshot("listen-transcribe-file-callback-response-structure"); - }); - - it("should handle enhanced options with callback", async () => { - const audioFile = readFileSync( - resolve(__dirname, "..", "__fixtures__", testAudioFiles.spacewalk) - ); - - const response: DeepgramResponse = - await deepgram.listen.prerecorded.transcribeFileCallback( - audioFile, - new CallbackUrl(callbackUrls.testEndpoint), - transcriptionOptions.enhanced - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.request_id).toBeDefined(); - expect(typeof response.result.request_id).toBe("string"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/listen-transcribe-file.test.ts b/tests/e2e/listen-transcribe-file.test.ts deleted file mode 100644 index d55ff5c3..00000000 --- a/tests/e2e/listen-transcribe-file.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testAudioFiles, commonTranscriptionOptions } from "../__fixtures__/listen"; -import * as fs from "fs"; -import * as path from "path"; - -describe("listen transcribeFile E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should transcribe audio from file and match expected response structure", async () => { - const audioFilePath = path.join(__dirname, "../__fixtures__", testAudioFiles.spacewalk); - - // Verify the test file exists - expect(fs.existsSync(audioFilePath)).toBe(true); - - // Read the audio file - const audioBuffer = fs.readFileSync(audioFilePath); - - const { result, error } = await deepgram.listen.prerecorded.transcribeFile( - audioBuffer, - commonTranscriptionOptions - ); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - // Type guard to ensure result is not null for subsequent operations - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot (using custom serializer for non-deterministic content) - expect(result).toMatchSnapshot("listen-transcribeFile-response-structure"); - - // Essential structural validation - verify we have the required properties - expect(result.metadata).toBeDefined(); - expect(result.results).toBeDefined(); - expect(Array.isArray(result.results.channels)).toBe(true); - expect(result.results.channels.length).toBeGreaterThan(0); - - // Verify we got actual transcription content - const transcript = result.results.channels[0]?.alternatives?.[0]?.transcript; - expect(transcript).toBeTruthy(); - expect(typeof transcript).toBe("string"); - expect(transcript.length).toBeGreaterThan(0); - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/listen-transcribe-url-callback.test.ts b/tests/e2e/listen-transcribe-url-callback.test.ts deleted file mode 100644 index 73044bce..00000000 --- a/tests/e2e/listen-transcribe-url-callback.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { callbackUrls, urlSources, transcriptionOptions } from "../__fixtures__/listen"; -import type { DeepgramResponse, AsyncPrerecordedResponse } from "../../src/lib/types"; -import { CallbackUrl } from "../../src/lib/helpers"; - -describe("listen transcribeUrlCallback E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should transcribe URL with callback and return async response", async () => { - const response: DeepgramResponse = - await deepgram.listen.prerecorded.transcribeUrlCallback( - urlSources.spacewalk, - new CallbackUrl(callbackUrls.webhook), - transcriptionOptions.basic - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("request_id"); - expect(typeof response.result.request_id).toBe("string"); - expect(response.result.request_id.length).toBeGreaterThan(0); - } - - expect(response).toMatchSnapshot("listen-transcribe-url-callback-response-structure"); - }); - - it("should handle enhanced options with callback", async () => { - const response: DeepgramResponse = - await deepgram.listen.prerecorded.transcribeUrlCallback( - urlSources.spacewalk, - new CallbackUrl(callbackUrls.testEndpoint), - transcriptionOptions.enhanced - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.request_id).toBeDefined(); - expect(typeof response.result.request_id).toBe("string"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/listen-transcribe-url.test.ts b/tests/e2e/listen-transcribe-url.test.ts deleted file mode 100644 index 54ad0c8b..00000000 --- a/tests/e2e/listen-transcribe-url.test.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { urlSources, commonTranscriptionOptions } from "../__fixtures__/listen"; - -describe("listen transcribeUrl E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should transcribe audio from URL and match expected response structure", async () => { - const { result, error } = await deepgram.listen.prerecorded.transcribeUrl( - urlSources.spacewalk, - commonTranscriptionOptions - ); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - // Type guard to ensure result is not null for subsequent operations - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot (using custom serializer for non-deterministic content) - expect(result).toMatchSnapshot("listen-transcribeUrl-response-structure"); - - // Essential structural validation - verify we have the required properties - expect(result.metadata).toBeDefined(); - expect(result.results).toBeDefined(); - expect(Array.isArray(result.results.channels)).toBe(true); - expect(result.results.channels.length).toBeGreaterThan(0); - - // Verify we got actual transcription content - const transcript = result.results.channels[0]?.alternatives?.[0]?.transcript; - expect(transcript).toBeTruthy(); - expect(typeof transcript).toBe("string"); - expect(transcript.length).toBeGreaterThan(0); - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-create-project-key.test.ts b/tests/e2e/manage-create-project-key.test.ts deleted file mode 100644 index 95c59268..00000000 --- a/tests/e2e/manage-create-project-key.test.ts +++ /dev/null @@ -1,86 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, keyOptions } from "../__fixtures__/manage"; -import type { DeepgramResponse, CreateProjectKeyResponse } from "../../src/lib/types"; - -describe("manage createProjectKey E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should create a new API key for a specific project", async () => { - const response: DeepgramResponse = - await deepgram.manage.createProjectKey(testProjectIds.primary, keyOptions.create); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("api_key_id"); - expect(response.result).toHaveProperty("key"); - expect(response.result).toHaveProperty("comment"); - expect(response.result).toHaveProperty("scopes"); - expect(response.result).toHaveProperty("created"); - - expect(typeof response.result.api_key_id).toBe("string"); - expect(typeof response.result.key).toBe("string"); - expect(typeof response.result.comment).toBe("string"); - expect(typeof response.result.created).toBe("string"); - expect(Array.isArray(response.result.scopes)).toBe(true); - - // Verify the key has the correct format (starts with "ak_") - expect(response.result.key).toMatch(/^ak_/); - } - - expect(response).toMatchSnapshot("manage-createProjectKey-response-structure"); - }); - - it("should create a minimal API key with just comment", async () => { - const response: DeepgramResponse = - await deepgram.manage.createProjectKey(testProjectIds.primary, keyOptions.createMinimal); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("api_key_id"); - expect(response.result).toHaveProperty("key"); - expect(response.result).toHaveProperty("comment"); - expect(typeof response.result.comment).toBe("string"); - } - }); - - it("should handle custom endpoint for createProjectKey", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/keys`; - const response: DeepgramResponse = - await deepgram.manage.createProjectKey( - testProjectIds.primary, - keyOptions.create, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("api_key_id"); - expect(response.result).toHaveProperty("key"); - expect(response.result.key).toMatch(/^ak_/); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-delete-project-invite.test.ts b/tests/e2e/manage-delete-project-invite.test.ts deleted file mode 100644 index dbf90dd8..00000000 --- a/tests/e2e/manage-delete-project-invite.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { createClient } from "../../src/index"; -import { setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testEmails } from "../__fixtures__/manage"; - -describe("manage deleteProjectInvite E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - setupApiMocks(); - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - }); - - afterAll(() => { - cleanupApiMocks(); - }); - - it("should delete a project invite", async () => { - const { error } = await deepgram.manage.deleteProjectInvite( - testProjectIds.primary, - testEmails.toDelete - ); - - expect(error).toBeNull(); - }); -}); diff --git a/tests/e2e/manage-delete-project-key.test.ts b/tests/e2e/manage-delete-project-key.test.ts deleted file mode 100644 index ac7183bb..00000000 --- a/tests/e2e/manage-delete-project-key.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { createClient } from "../../src/index"; -import { setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testKeyIds } from "../__fixtures__/manage"; - -describe("manage deleteProjectKey E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - setupApiMocks(); - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - }); - - afterAll(() => { - cleanupApiMocks(); - }); - - it("should delete a project key", async () => { - const { error } = await deepgram.manage.deleteProjectKey( - testProjectIds.primary, - testKeyIds.toDelete - ); - - expect(error).toBeNull(); - }); -}); diff --git a/tests/e2e/manage-delete-project.test.ts b/tests/e2e/manage-delete-project.test.ts deleted file mode 100644 index 441d75b2..00000000 --- a/tests/e2e/manage-delete-project.test.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { createClient } from "../../src/index"; -import { setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds } from "../__fixtures__/manage"; - -describe("manage deleteProject E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - setupApiMocks(); - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - }); - - afterAll(() => { - cleanupApiMocks(); - }); - - it("should delete a project", async () => { - const { error } = await deepgram.manage.deleteProject(testProjectIds.toDelete); - - expect(error).toBeNull(); - }); -}); diff --git a/tests/e2e/manage-get-all-models.test.ts b/tests/e2e/manage-get-all-models.test.ts deleted file mode 100644 index 56828b39..00000000 --- a/tests/e2e/manage-get-all-models.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, modelOptions } from "../__fixtures__/manage"; - -describe("manage getAllModels E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - setupApiMocks(); - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - cleanupApiMocks(); - }); - - it("should get all project models with basic options", async () => { - const { result, error } = await deepgram.manage.getAllModels( - testProjectIds.primary, - modelOptions.basic - ); - - expect(error).toBeNull(); - expect(result).toMatchSnapshot("manage-getAllModels-basic-response-structure"); - }); - - it("should get all project models with filtered options", async () => { - const { result, error } = await deepgram.manage.getAllModels( - testProjectIds.primary, - modelOptions.withFilters - ); - - expect(error).toBeNull(); - expect(result).toMatchSnapshot("manage-getAllModels-filtered-response-structure"); - }); -}); diff --git a/tests/e2e/manage-get-model.test.ts b/tests/e2e/manage-get-model.test.ts deleted file mode 100644 index 41151602..00000000 --- a/tests/e2e/manage-get-model.test.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testModelIds } from "../__fixtures__/manage"; - -describe("manage getModel E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - setupApiMocks(); - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - cleanupApiMocks(); - }); - - it("should get a specific project model", async () => { - const { result, error } = await deepgram.manage.getModel( - testProjectIds.primary, - testModelIds.sttModel - ); - - expect(error).toBeNull(); - expect(result).toMatchSnapshot("manage-getModel-stt-response-structure"); - }); - - it("should get a different project model", async () => { - const { result, error } = await deepgram.manage.getModel( - testProjectIds.primary, - testModelIds.ttsModel - ); - - expect(error).toBeNull(); - expect(result).toMatchSnapshot("manage-getModel-tts-response-structure"); - }); -}); diff --git a/tests/e2e/manage-get-project-balance.test.ts b/tests/e2e/manage-get-project-balance.test.ts deleted file mode 100644 index 8ff02684..00000000 --- a/tests/e2e/manage-get-project-balance.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testBalanceIds } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectBalanceResponse } from "../../src/lib/types"; - -describe("manage getProjectBalance E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve a specific project balance by ID", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectBalance(testProjectIds.primary, testBalanceIds.balance1); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("balance_id"); - expect(response.result).toHaveProperty("amount"); - expect(response.result).toHaveProperty("units"); - expect(response.result).toHaveProperty("purchase"); - - expect(typeof response.result.balance_id).toBe("string"); - expect(typeof response.result.amount).toBe("number"); - expect(typeof response.result.units).toBe("string"); - expect(typeof response.result.purchase).toBe("string"); - } - - expect(response).toMatchSnapshot("manage-getProjectBalance-response-structure"); - }); - - it("should handle custom endpoint for getProjectBalance", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/balances/${testBalanceIds.balance1}`; - const response: DeepgramResponse = - await deepgram.manage.getProjectBalance( - testProjectIds.primary, - testBalanceIds.balance1, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("balance_id"); - expect(response.result).toHaveProperty("amount"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-balances.test.ts b/tests/e2e/manage-get-project-balances.test.ts deleted file mode 100644 index d1a4e301..00000000 --- a/tests/e2e/manage-get-project-balances.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectBalancesResponse } from "../../src/lib/types"; - -describe("manage getProjectBalances E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve all project balances for a specific project", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectBalances(testProjectIds.primary); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("balances"); - expect(Array.isArray(response.result.balances)).toBe(true); - - // Verify balance structure if any balances exist - if (response.result.balances.length > 0) { - const balance = response.result.balances[0]; - expect(balance).toHaveProperty("balance_id"); - expect(balance).toHaveProperty("amount"); - expect(balance).toHaveProperty("units"); - expect(balance).toHaveProperty("purchase"); - - expect(typeof balance.balance_id).toBe("string"); - expect(typeof balance.amount).toBe("number"); - expect(typeof balance.units).toBe("string"); - expect(typeof balance.purchase).toBe("string"); - } - } - - expect(response).toMatchSnapshot("manage-getProjectBalances-response-structure"); - }); - - it("should handle custom endpoint for getProjectBalances", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/balances`; - const response: DeepgramResponse = - await deepgram.manage.getProjectBalances(testProjectIds.primary, customEndpoint); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.balances).toBeDefined(); - expect(Array.isArray(response.result.balances)).toBe(true); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-invites.test.ts b/tests/e2e/manage-get-project-invites.test.ts deleted file mode 100644 index d60a4794..00000000 --- a/tests/e2e/manage-get-project-invites.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectInvitesResponse } from "../../src/lib/types"; - -describe("manage getProjectInvites E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve all project invitations for a specific project", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectInvites(testProjectIds.primary); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("invites"); - expect(Array.isArray(response.result.invites)).toBe(true); - - // Verify invite structure if any invites exist - if (response.result.invites.length > 0) { - const invite = response.result.invites[0]; - expect(invite).toHaveProperty("email"); - expect(invite).toHaveProperty("scope"); - - expect(typeof invite.email).toBe("string"); - expect(typeof invite.scope).toBe("string"); - } - } - - expect(response).toMatchSnapshot("manage-getProjectInvites-response-structure"); - }); - - it("should handle custom endpoint for getProjectInvites", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/invites`; - const response: DeepgramResponse = - await deepgram.manage.getProjectInvites(testProjectIds.primary, customEndpoint); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.invites).toBeDefined(); - expect(Array.isArray(response.result.invites)).toBe(true); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-key.test.ts b/tests/e2e/manage-get-project-key.test.ts deleted file mode 100644 index 9abcffb1..00000000 --- a/tests/e2e/manage-get-project-key.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testKeyIds } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectKeyResponse } from "../../src/lib/types"; - -describe("manage getProjectKey E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve a specific project key by ID", async () => { - const response: DeepgramResponse = await deepgram.manage.getProjectKey( - testProjectIds.primary, - testKeyIds.key1 - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("member"); - expect(response.result).toHaveProperty("api_key"); - - expect(response.result.member).toHaveProperty("member_id"); - expect(response.result.member).toHaveProperty("email"); - - expect(response.result.api_key).toHaveProperty("api_key_id"); - expect(response.result.api_key).toHaveProperty("comment"); - expect(response.result.api_key).toHaveProperty("scopes"); - expect(response.result.api_key).toHaveProperty("created"); - - expect(Array.isArray(response.result.api_key.scopes)).toBe(true); - } - - expect(response).toMatchSnapshot("manage-getProjectKey-response-structure"); - }); - - it("should handle custom endpoint for getProjectKey", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/keys/${testKeyIds.key1}`; - const response: DeepgramResponse = await deepgram.manage.getProjectKey( - testProjectIds.primary, - testKeyIds.key1, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("member"); - expect(response.result).toHaveProperty("api_key"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-keys.test.ts b/tests/e2e/manage-get-project-keys.test.ts deleted file mode 100644 index 63eeb05b..00000000 --- a/tests/e2e/manage-get-project-keys.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectKeysResponse } from "../../src/lib/types"; - -describe("manage getProjectKeys E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve all project keys for a specific project", async () => { - const response: DeepgramResponse = await deepgram.manage.getProjectKeys( - testProjectIds.primary - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("api_keys"); - expect(Array.isArray(response.result.api_keys)).toBe(true); - - // Verify key structure if any keys exist - if (response.result.api_keys.length > 0) { - const key = response.result.api_keys[0]; - expect(key).toHaveProperty("member"); - expect(key).toHaveProperty("api_key"); - - expect(key.member).toHaveProperty("member_id"); - expect(key.member).toHaveProperty("email"); - - expect(key.api_key).toHaveProperty("api_key_id"); - expect(key.api_key).toHaveProperty("comment"); - expect(key.api_key).toHaveProperty("scopes"); - expect(key.api_key).toHaveProperty("created"); - - expect(Array.isArray(key.api_key.scopes)).toBe(true); - } - } - - expect(response).toMatchSnapshot("manage-getProjectKeys-response-structure"); - }); - - it("should handle custom endpoint for getProjectKeys", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/keys`; - const response: DeepgramResponse = await deepgram.manage.getProjectKeys( - testProjectIds.primary, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.api_keys).toBeDefined(); - expect(Array.isArray(response.result.api_keys)).toBe(true); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-member-scopes.test.ts b/tests/e2e/manage-get-project-member-scopes.test.ts deleted file mode 100644 index 57c0365f..00000000 --- a/tests/e2e/manage-get-project-member-scopes.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testMemberIds } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectMemberScopesResponse } from "../../src/lib/types"; - -describe("manage getProjectMemberScopes E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve member scopes for a specific project member", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectMemberScopes(testProjectIds.primary, testMemberIds.member1); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("scopes"); - expect(Array.isArray(response.result.scopes)).toBe(true); - - // Verify scope values if any scopes exist - if (response.result.scopes.length > 0) { - response.result.scopes.forEach((scope) => { - expect(typeof scope).toBe("string"); - }); - } - } - - expect(response).toMatchSnapshot("manage-getProjectMemberScopes-response-structure"); - }); - - it("should handle custom endpoint for getProjectMemberScopes", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/members/${testMemberIds.member1}/scopes`; - const response: DeepgramResponse = - await deepgram.manage.getProjectMemberScopes( - testProjectIds.primary, - testMemberIds.member1, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.scopes).toBeDefined(); - expect(Array.isArray(response.result.scopes)).toBe(true); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-members.test.ts b/tests/e2e/manage-get-project-members.test.ts deleted file mode 100644 index 8b2dcd6d..00000000 --- a/tests/e2e/manage-get-project-members.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectMembersResponse } from "../../src/lib/types"; - -describe("manage getProjectMembers E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve all project members for a specific project", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectMembers(testProjectIds.primary); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("members"); - expect(Array.isArray(response.result.members)).toBe(true); - - // Verify member structure if any members exist - if (response.result.members.length > 0) { - const member = response.result.members[0]; - expect(member).toHaveProperty("member_id"); - expect(member).toHaveProperty("email"); - expect(member).toHaveProperty("first_name"); - expect(member).toHaveProperty("last_name"); - expect(member).toHaveProperty("scopes"); - - expect(typeof member.member_id).toBe("string"); - expect(typeof member.email).toBe("string"); - expect(Array.isArray(member.scopes)).toBe(true); - } - } - - expect(response).toMatchSnapshot("manage-getProjectMembers-response-structure"); - }); - - it("should handle custom endpoint for getProjectMembers", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/members`; - const response: DeepgramResponse = - await deepgram.manage.getProjectMembers(testProjectIds.primary, customEndpoint); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.members).toBeDefined(); - expect(Array.isArray(response.result.members)).toBe(true); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-usage-fields.test.ts b/tests/e2e/manage-get-project-usage-fields.test.ts deleted file mode 100644 index 81b5e50d..00000000 --- a/tests/e2e/manage-get-project-usage-fields.test.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, usageFieldsOptions } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectUsageFieldsResponse } from "../../src/lib/types"; - -describe("manage getProjectUsageFields E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve usage fields for a specific project with basic options", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageFields(testProjectIds.primary, usageFieldsOptions.basic); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("tags"); - expect(response.result).toHaveProperty("models"); - expect(response.result).toHaveProperty("processing_methods"); - expect(response.result).toHaveProperty("languages"); - expect(response.result).toHaveProperty("features"); - - expect(Array.isArray(response.result.tags)).toBe(true); - expect(Array.isArray(response.result.models)).toBe(true); - expect(Array.isArray(response.result.processing_methods)).toBe(true); - expect(Array.isArray(response.result.languages)).toBe(true); - expect(Array.isArray(response.result.features)).toBe(true); - } - - expect(response).toMatchSnapshot("manage-getProjectUsageFields-response-structure"); - }); - - it("should handle usage fields with filters", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageFields( - testProjectIds.primary, - usageFieldsOptions.withFilters - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.tags).toBeDefined(); - expect(Array.isArray(response.result.tags)).toBe(true); - } - }); - - it("should handle custom endpoint for getProjectUsageFields", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/usage/fields`; - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageFields( - testProjectIds.primary, - usageFieldsOptions.basic, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.tags).toBeDefined(); - expect(Array.isArray(response.result.tags)).toBe(true); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-usage-request.test.ts b/tests/e2e/manage-get-project-usage-request.test.ts deleted file mode 100644 index c2120e52..00000000 --- a/tests/e2e/manage-get-project-usage-request.test.ts +++ /dev/null @@ -1,74 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testRequestIds } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectUsageRequestResponse } from "../../src/lib/types"; - -describe("manage getProjectUsageRequest E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve a specific usage request by ID", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageRequest(testProjectIds.primary, testRequestIds.request1); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("request_id"); - expect(response.result).toHaveProperty("created"); - expect(response.result).toHaveProperty("path"); - expect(response.result).toHaveProperty("api_key_id"); - expect(response.result).toHaveProperty("response"); - - expect(typeof response.result.request_id).toBe("string"); - expect(typeof response.result.created).toBe("string"); - expect(typeof response.result.path).toBe("string"); - expect(typeof response.result.api_key_id).toBe("string"); - expect(typeof response.result.response).toBe("object"); - - // Verify response details - if (response.result.response) { - expect(response.result.response).toHaveProperty("code"); - expect(response.result.response).toHaveProperty("completed"); - expect(response.result.response).toHaveProperty("details"); - } - } - - expect(response).toMatchSnapshot("manage-getProjectUsageRequest-response-structure"); - }); - - it("should handle custom endpoint for getProjectUsageRequest", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/requests/${testRequestIds.request1}`; - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageRequest( - testProjectIds.primary, - testRequestIds.request1, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("request_id"); - expect(response.result).toHaveProperty("path"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-usage-requests.test.ts b/tests/e2e/manage-get-project-usage-requests.test.ts deleted file mode 100644 index f1947190..00000000 --- a/tests/e2e/manage-get-project-usage-requests.test.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, usageRequestOptions } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectUsageRequestsResponse } from "../../src/lib/types"; - -describe("manage getProjectUsageRequests E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve usage requests for a specific project with basic options", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageRequests( - testProjectIds.primary, - usageRequestOptions.basic - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("page"); - expect(response.result).toHaveProperty("limit"); - expect(response.result).toHaveProperty("requests"); - expect(Array.isArray(response.result.requests)).toBe(true); - - // Verify request structure if any requests exist - if (response.result.requests.length > 0) { - const request = response.result.requests[0]; - expect(request).toHaveProperty("request_id"); - expect(request).toHaveProperty("created"); - expect(request).toHaveProperty("path"); - expect(request).toHaveProperty("api_key_id"); - expect(request).toHaveProperty("response"); - - expect(typeof request.request_id).toBe("string"); - expect(typeof request.created).toBe("string"); - expect(typeof request.path).toBe("string"); - expect(typeof request.api_key_id).toBe("string"); - expect(typeof request.response).toBe("object"); - } - } - - expect(response).toMatchSnapshot("manage-getProjectUsageRequests-response-structure"); - }); - - it("should handle usage requests with limit and pagination", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageRequests( - testProjectIds.primary, - usageRequestOptions.withPagination - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.requests).toBeDefined(); - expect(Array.isArray(response.result.requests)).toBe(true); - expect(typeof response.result.page).toBe("number"); - expect(typeof response.result.limit).toBe("number"); - } - }); - - it("should handle custom endpoint for getProjectUsageRequests", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/requests`; - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageRequests( - testProjectIds.primary, - usageRequestOptions.basic, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.requests).toBeDefined(); - expect(Array.isArray(response.result.requests)).toBe(true); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project-usage-summary.test.ts b/tests/e2e/manage-get-project-usage-summary.test.ts deleted file mode 100644 index 853ceb47..00000000 --- a/tests/e2e/manage-get-project-usage-summary.test.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, usageSummaryOptions } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectUsageSummaryResponse } from "../../src/lib/types"; - -describe("manage getProjectUsageSummary E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve usage summary for a specific project with basic options", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageSummary( - testProjectIds.primary, - usageSummaryOptions.basic - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("start"); - expect(response.result).toHaveProperty("end"); - expect(response.result).toHaveProperty("resolution"); - expect(response.result).toHaveProperty("results"); - - expect(typeof response.result.start).toBe("string"); - expect(typeof response.result.end).toBe("string"); - expect(Array.isArray(response.result.results)).toBe(true); - - // Verify result structure if any results exist - if (response.result.results.length > 0) { - const result = response.result.results[0]; - expect(result).toHaveProperty("start"); - expect(result).toHaveProperty("end"); - expect(result).toHaveProperty("hours"); - expect(result).toHaveProperty("requests"); - } - } - - expect(response).toMatchSnapshot("manage-getProjectUsageSummary-response-structure"); - }); - - it("should handle usage summary with filters", async () => { - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageSummary( - testProjectIds.primary, - usageSummaryOptions.withFilters - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.results).toBeDefined(); - expect(Array.isArray(response.result.results)).toBe(true); - } - }); - - it("should handle custom endpoint for getProjectUsageSummary", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/usage`; - const response: DeepgramResponse = - await deepgram.manage.getProjectUsageSummary( - testProjectIds.primary, - usageSummaryOptions.basic, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.results).toBeDefined(); - expect(Array.isArray(response.result.results)).toBe(true); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-project.test.ts b/tests/e2e/manage-get-project.test.ts deleted file mode 100644 index 362e7899..00000000 --- a/tests/e2e/manage-get-project.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds } from "../__fixtures__/manage"; -import type { DeepgramResponse, GetProjectResponse } from "../../src/lib/types"; - -describe("manage getProject E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve a specific project by ID", async () => { - const response: DeepgramResponse = await deepgram.manage.getProject( - testProjectIds.primary - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("project_id"); - expect(response.result).toHaveProperty("name"); - expect(response.result).toHaveProperty("company"); - expect(typeof response.result.project_id).toBe("string"); - expect(typeof response.result.name).toBe("string"); - expect(typeof response.result.company).toBe("string"); - } - - expect(response).toMatchSnapshot("manage-getProject-response-structure"); - }); - - it("should handle custom endpoint for getProject", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}`; - const response: DeepgramResponse = await deepgram.manage.getProject( - testProjectIds.primary, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("project_id"); - expect(response.result).toHaveProperty("name"); - expect(response.result).toHaveProperty("company"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-projects.test.ts b/tests/e2e/manage-get-projects.test.ts deleted file mode 100644 index 38e2e1c9..00000000 --- a/tests/e2e/manage-get-projects.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import type { DeepgramResponse, GetProjectsResponse } from "../../src/lib/types"; - -describe("manage getProjects E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve all projects for the authenticated user", async () => { - const response: DeepgramResponse = await deepgram.manage.getProjects(); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("projects"); - expect(Array.isArray(response.result.projects)).toBe(true); - - // Verify project structure if any projects exist - if (response.result.projects.length > 0) { - const project = response.result.projects[0]; - expect(project).toHaveProperty("project_id"); - expect(project).toHaveProperty("name"); - expect(typeof project.project_id).toBe("string"); - expect(typeof project.name).toBe("string"); - } - } - - expect(response).toMatchSnapshot("manage-getProjects-response-structure"); - }); - - it("should handle custom endpoint for getProjects", async () => { - const customEndpoint = ":version/projects"; - const response: DeepgramResponse = await deepgram.manage.getProjects( - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.projects).toBeDefined(); - expect(Array.isArray(response.result.projects)).toBe(true); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-get-token-details.test.ts b/tests/e2e/manage-get-token-details.test.ts deleted file mode 100644 index e6e0487b..00000000 --- a/tests/e2e/manage-get-token-details.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import type { DeepgramResponse, GetTokenDetailsResponse } from "../../src/lib/types"; - -describe("manage getTokenDetails E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve token details for the authenticated user", async () => { - const response: DeepgramResponse = - await deepgram.manage.getTokenDetails(); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("api_key_id"); - expect(response.result).toHaveProperty("scopes"); - expect(response.result).toHaveProperty("created"); - - expect(typeof response.result.api_key_id).toBe("string"); - expect(Array.isArray(response.result.scopes)).toBe(true); - expect(typeof response.result.created).toBe("string"); - } - - expect(response).toMatchSnapshot("manage-getTokenDetails-response-structure"); - }); - - it("should handle custom endpoint for getTokenDetails", async () => { - const customEndpoint = ":version/auth/token"; - const response: DeepgramResponse = - await deepgram.manage.getTokenDetails(customEndpoint); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("api_key_id"); - expect(response.result).toHaveProperty("scopes"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-leave-project.test.ts b/tests/e2e/manage-leave-project.test.ts deleted file mode 100644 index ca80e99b..00000000 --- a/tests/e2e/manage-leave-project.test.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds } from "../__fixtures__/manage"; - -describe("manage leaveProject E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - setupApiMocks(); - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - cleanupApiMocks(); - }); - - it("should leave a project", async () => { - const { result, error } = await deepgram.manage.leaveProject(testProjectIds.primary); - - expect(error).toBeNull(); - expect(result).toMatchSnapshot("manage-leaveProject-response-structure"); - }); -}); diff --git a/tests/e2e/manage-remove-project-member.test.ts b/tests/e2e/manage-remove-project-member.test.ts deleted file mode 100644 index 4535fa95..00000000 --- a/tests/e2e/manage-remove-project-member.test.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { createClient } from "../../src/index"; -import { setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testMemberIds } from "../__fixtures__/manage"; - -describe("manage removeProjectMember E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - setupApiMocks(); - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - }); - - afterAll(() => { - cleanupApiMocks(); - }); - - it("should remove a project member", async () => { - const { error } = await deepgram.manage.removeProjectMember( - testProjectIds.primary, - testMemberIds.toRemove - ); - - expect(error).toBeNull(); - }); -}); diff --git a/tests/e2e/manage-send-project-invite.test.ts b/tests/e2e/manage-send-project-invite.test.ts deleted file mode 100644 index 2fb8d988..00000000 --- a/tests/e2e/manage-send-project-invite.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, inviteOptions } from "../__fixtures__/manage"; -import type { DeepgramResponse, MessageResponse } from "../../src/lib/types"; - -describe("manage sendProjectInvite E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should send a project invitation to a single email", async () => { - const response: DeepgramResponse = await deepgram.manage.sendProjectInvite( - testProjectIds.primary, - inviteOptions.single - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("message"); - expect(typeof response.result.message).toBe("string"); - } - - expect(response).toMatchSnapshot("manage-sendProjectInvite-response-structure"); - }); - - it("should send project invitations to multiple emails", async () => { - const response: DeepgramResponse = await deepgram.manage.sendProjectInvite( - testProjectIds.primary, - inviteOptions.multiple - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("message"); - } - }); - - it("should handle custom endpoint for sendProjectInvite", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/invites`; - const response: DeepgramResponse = await deepgram.manage.sendProjectInvite( - testProjectIds.primary, - inviteOptions.single, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-update-project-member-scope.test.ts b/tests/e2e/manage-update-project-member-scope.test.ts deleted file mode 100644 index ecbc0467..00000000 --- a/tests/e2e/manage-update-project-member-scope.test.ts +++ /dev/null @@ -1,78 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testMemberIds, memberScopeOptions } from "../__fixtures__/manage"; -import type { DeepgramResponse, MessageResponse } from "../../src/lib/types"; - -describe("manage updateProjectMemberScope E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should update a project member's scope", async () => { - const response: DeepgramResponse = - await deepgram.manage.updateProjectMemberScope( - testProjectIds.primary, - testMemberIds.member1, - memberScopeOptions.update - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("message"); - expect(typeof response.result.message).toBe("string"); - } - - expect(response).toMatchSnapshot("manage-updateProjectMemberScope-response-structure"); - }); - - it("should update a member scope to admin", async () => { - const response: DeepgramResponse = - await deepgram.manage.updateProjectMemberScope( - testProjectIds.primary, - testMemberIds.member2, - memberScopeOptions.updateAdmin - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("message"); - } - }); - - it("should handle custom endpoint for updateProjectMemberScope", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}/members/${testMemberIds.member1}/scopes`; - const response: DeepgramResponse = - await deepgram.manage.updateProjectMemberScope( - testProjectIds.primary, - testMemberIds.member1, - memberScopeOptions.update, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("message"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/manage-update-project.test.ts b/tests/e2e/manage-update-project.test.ts deleted file mode 100644 index 874fdd7a..00000000 --- a/tests/e2e/manage-update-project.test.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, projectOptions } from "../__fixtures__/manage"; -import type { DeepgramResponse, MessageResponse } from "../../src/lib/types"; - -describe("manage updateProject E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should update a project with new details", async () => { - const response: DeepgramResponse = await deepgram.manage.updateProject( - testProjectIds.primary, - projectOptions.update - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("message"); - expect(typeof response.result.message).toBe("string"); - } - - expect(response).toMatchSnapshot("manage-updateProject-response-structure"); - }); - - it("should handle custom endpoint for updateProject", async () => { - const customEndpoint = `:version/projects/${testProjectIds.primary}`; - const response: DeepgramResponse = await deepgram.manage.updateProject( - testProjectIds.primary, - projectOptions.update, - customEndpoint - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("message"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/models-get-all.test.ts b/tests/e2e/models-get-all.test.ts deleted file mode 100644 index 3983582e..00000000 --- a/tests/e2e/models-get-all.test.ts +++ /dev/null @@ -1,122 +0,0 @@ -import { createClient } from "../../src/index"; -import { ModelsRestClient } from "../../src/packages/ModelsRestClient"; -import { DeepgramError } from "../../src/lib/errors"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; - -describe("models getAll E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve all available models", async () => { - const { result, error } = await deepgram.models.getAll(); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - // Type guard to ensure result is not null for subsequent operations - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot - expect(result).toMatchSnapshot("models-getAll-response-structure"); - - // Essential structural validation - expect(result).toHaveProperty("stt"); - expect(result).toHaveProperty("tts"); - expect(Array.isArray(result.stt)).toBe(true); - expect(Array.isArray(result.tts)).toBe(true); - - // Verify STT models have required properties - if (result.stt.length > 0) { - const sttModel = result.stt[0]; - expect(sttModel).toHaveProperty("name"); - expect(sttModel).toHaveProperty("canonical_name"); - expect(sttModel).toHaveProperty("architecture"); - expect(sttModel).toHaveProperty("languages"); - expect(sttModel).toHaveProperty("uuid"); - expect(Array.isArray(sttModel.languages)).toBe(true); - } - - // Verify TTS models have required properties - if (result.tts.length > 0) { - const ttsModel = result.tts[0]; - expect(ttsModel).toHaveProperty("name"); - expect(ttsModel).toHaveProperty("canonical_name"); - expect(ttsModel).toHaveProperty("architecture"); - expect(ttsModel).toHaveProperty("languages"); - expect(ttsModel).toHaveProperty("uuid"); - expect(Array.isArray(ttsModel.languages)).toBe(true); - } - }, 30000); - - it("should handle model options and filters", async () => { - const options = { - include_outdated: false, - }; - - const { result, error } = await deepgram.models.getAll(":version/models", options); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Verify the request was successful - expect(result).toHaveProperty("stt"); - expect(result).toHaveProperty("tts"); - }, 30000); - - it("should handle DeepgramError and return it in response", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const modelsClient = new ModelsRestClient({ key: apiKey }); - - // Mock the get method to throw a DeepgramError - const mockError = new DeepgramError("Test DeepgramError"); - jest.spyOn(modelsClient as any, "get").mockRejectedValue(mockError); - - const { result, error } = await modelsClient.getAll(); - - expect(result).toBeNull(); - expect(error).toBe(mockError); - expect(error).toBeInstanceOf(DeepgramError); - - // Clean up spy - jest.restoreAllMocks(); - }); - - it("should re-throw non-DeepgramError", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const modelsClient = new ModelsRestClient({ key: apiKey }); - - // Mock the get method to throw a regular Error - const mockError = new Error("Network error"); - jest.spyOn(modelsClient as any, "get").mockRejectedValue(mockError); - - await expect(modelsClient.getAll()).rejects.toThrow("Network error"); - await expect(modelsClient.getAll()).rejects.toThrow(Error); - - // Clean up spy - jest.restoreAllMocks(); - }); -}); diff --git a/tests/e2e/models-get-model.test.ts b/tests/e2e/models-get-model.test.ts deleted file mode 100644 index 7c4a1b0f..00000000 --- a/tests/e2e/models-get-model.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { createClient } from "../../src/index"; -import { ModelsRestClient } from "../../src/packages/ModelsRestClient"; -import { DeepgramError } from "../../src/lib/errors"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testModelIds } from "../__fixtures__/models"; - -describe("models getModel E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve specific model information", async () => { - const { result, error } = await deepgram.models.getModel(testModelIds.nova); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - // Type guard to ensure result is not null for subsequent operations - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot - expect(result).toMatchSnapshot("models-getModel-response-structure"); - - // Essential structural validation - expect(result).toHaveProperty("name"); - expect(result).toHaveProperty("canonical_name"); - expect(result).toHaveProperty("architecture"); - expect(result).toHaveProperty("languages"); - expect(result).toHaveProperty("uuid"); - expect(result).toHaveProperty("version"); - - // Verify data types - expect(typeof result.name).toBe("string"); - expect(typeof result.canonical_name).toBe("string"); - expect(typeof result.architecture).toBe("string"); - expect(Array.isArray(result.languages)).toBe(true); - expect(typeof result.uuid).toBe("string"); - expect(typeof result.version).toBe("string"); - - // Verify languages array contains strings - if (result.languages) { - result.languages.forEach((lang) => { - expect(typeof lang).toBe("string"); - }); - } - }, 30000); - - it("should handle DeepgramError and return it in response", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const modelsClient = new ModelsRestClient({ key: apiKey }); - - // Mock the get method to throw a DeepgramError - const mockError = new DeepgramError("Test DeepgramError"); - jest.spyOn(modelsClient as any, "get").mockRejectedValue(mockError); - - const { result, error } = await modelsClient.getModel(testModelIds.nova); - - expect(result).toBeNull(); - expect(error).toBe(mockError); - expect(error).toBeInstanceOf(DeepgramError); - - // Clean up spy - jest.restoreAllMocks(); - }); - - it("should re-throw non-DeepgramError", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const modelsClient = new ModelsRestClient({ key: apiKey }); - - // Mock the get method to throw a regular Error - const mockError = new Error("Network error"); - jest.spyOn(modelsClient as any, "get").mockRejectedValue(mockError); - - await expect(modelsClient.getModel(testModelIds.nova)).rejects.toThrow("Network error"); - await expect(modelsClient.getModel(testModelIds.nova)).rejects.toThrow(Error); - - // Clean up spy - jest.restoreAllMocks(); - }); -}); diff --git a/tests/e2e/read-analyze-text-callback.test.ts b/tests/e2e/read-analyze-text-callback.test.ts deleted file mode 100644 index f053f12d..00000000 --- a/tests/e2e/read-analyze-text-callback.test.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { callbackUrls, testReadSources, commonAnalysisOptions } from "../__fixtures__/read"; -import type { DeepgramResponse, AsyncAnalyzeResponse } from "../../src/lib/types"; -import { CallbackUrl } from "../../src/lib/helpers"; - -describe("read analyzeTextCallback E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should analyze text with callback and return async response", async () => { - const response: DeepgramResponse = - await deepgram.read.analyzeTextCallback( - testReadSources.sentimentText, - new CallbackUrl(callbackUrls.webhook), - commonAnalysisOptions - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("request_id"); - expect(typeof response.result.request_id).toBe("string"); - expect(response.result.request_id.length).toBeGreaterThan(0); - } - - expect(response).toMatchSnapshot("read-analyze-text-callback-response-structure"); - }); - - it("should handle simple text analysis with callback", async () => { - const response: DeepgramResponse = - await deepgram.read.analyzeTextCallback( - testReadSources.simpleText, - new CallbackUrl(callbackUrls.testEndpoint), - { sentiment: true, summarize: true } - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.request_id).toBeDefined(); - expect(typeof response.result.request_id).toBe("string"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/read-analyze-text.test.ts b/tests/e2e/read-analyze-text.test.ts deleted file mode 100644 index a6cdf159..00000000 --- a/tests/e2e/read-analyze-text.test.ts +++ /dev/null @@ -1,172 +0,0 @@ -import { createClient } from "../../src/index"; -import { ReadRestClient } from "../../src/packages/ReadRestClient"; -import { DeepgramError } from "../../src/lib/errors"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testReadSources, commonAnalysisOptions } from "../__fixtures__/read"; - -describe("read analyzeText E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should analyze text synchronously", async () => { - const { result, error } = await deepgram.read.analyzeText( - testReadSources.simpleText, - commonAnalysisOptions - ); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - // Type guard to ensure result is not null for subsequent operations - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot - expect(result).toMatchSnapshot("read-analyzeText-response-structure"); - - // Essential structural validation - expect(result).toHaveProperty("metadata"); - expect(result).toHaveProperty("results"); - - // Verify metadata structure - expect(result.metadata).toHaveProperty("request_id"); - expect(result.metadata).toHaveProperty("created"); - expect(typeof result.metadata.request_id).toBe("string"); - expect(typeof result.metadata.created).toBe("string"); - - // Verify results structure based on requested analysis options - if (commonAnalysisOptions.sentiment) { - expect(result.results).toHaveProperty("sentiments"); - if (result.results.sentiments) { - expect(result.results.sentiments).toHaveProperty("segments"); - expect(Array.isArray(result.results.sentiments.segments)).toBe(true); - } - } - - if (commonAnalysisOptions.intents) { - expect(result.results).toHaveProperty("intents"); - if (result.results.intents) { - expect(result.results.intents).toHaveProperty("segments"); - expect(Array.isArray(result.results.intents.segments)).toBe(true); - } - } - - if (commonAnalysisOptions.summarize) { - expect(result.results).toHaveProperty("summary"); - } - }, 30000); - - it("should analyze text with different analysis options", async () => { - const sentimentOnlyOptions = { - sentiment: true, - language: "en", - }; - - const { result, error } = await deepgram.read.analyzeText( - testReadSources.sentimentText, - sentimentOnlyOptions - ); - - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - expect(result).toHaveProperty("results"); - - // Should have sentiment analysis since it was requested - expect(result.results).toHaveProperty("sentiments"); - - // Verify sentiment structure - const sentiments = result.results.sentiments; - if (sentiments) { - expect(sentiments).toHaveProperty("segments"); - expect(Array.isArray(sentiments.segments)).toBe(true); - - if (sentiments.segments.length > 0) { - const segment = sentiments.segments[0]; - expect(segment).toHaveProperty("sentiment"); - expect(segment).toHaveProperty("sentiment_score"); - expect(typeof segment.sentiment).toBe("string"); - expect(typeof segment.sentiment_score).toBe("number"); - } - } - }, 30000); - - it("should reject synchronous analysis with callback option", async () => { - const optionsWithCallback = { - ...commonAnalysisOptions, - callback: "https://example.com/callback", - }; - - const { result, error } = await deepgram.read.analyzeText( - testReadSources.simpleText, - optionsWithCallback - ); - - // Should return an error, not throw - expect(result).toBeNull(); - expect(error).toBeTruthy(); - expect(error?.message).toContain("Callback cannot be provided as an option to a synchronous"); - }, 30000); - - it("should handle DeepgramError and return it in response", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const readClient = new ReadRestClient({ key: apiKey }); - - // Mock the post method to throw a DeepgramError - const mockError = new DeepgramError("Test DeepgramError"); - jest.spyOn(readClient as any, "post").mockRejectedValue(mockError); - - const { result, error } = await readClient.analyzeText( - testReadSources.simpleText, - commonAnalysisOptions - ); - - expect(result).toBeNull(); - expect(error).toBe(mockError); - expect(error).toBeInstanceOf(DeepgramError); - - // Clean up spy - jest.restoreAllMocks(); - }); - - it("should re-throw non-DeepgramError", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const readClient = new ReadRestClient({ key: apiKey }); - - // Mock the post method to throw a regular Error - const mockError = new Error("Network error"); - jest.spyOn(readClient as any, "post").mockRejectedValue(mockError); - - await expect( - readClient.analyzeText(testReadSources.simpleText, commonAnalysisOptions) - ).rejects.toThrow("Network error"); - await expect( - readClient.analyzeText(testReadSources.simpleText, commonAnalysisOptions) - ).rejects.toThrow(Error); - - // Clean up spy - jest.restoreAllMocks(); - }); -}); diff --git a/tests/e2e/read-analyze-url-callback.test.ts b/tests/e2e/read-analyze-url-callback.test.ts deleted file mode 100644 index 3c05b9c6..00000000 --- a/tests/e2e/read-analyze-url-callback.test.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { callbackUrls, testReadSources, commonAnalysisOptions } from "../__fixtures__/read"; -import type { DeepgramResponse, AsyncAnalyzeResponse } from "../../src/lib/types"; -import { CallbackUrl } from "../../src/lib/helpers"; - -describe("read analyzeUrlCallback E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should analyze URL with callback and return async response", async () => { - const response: DeepgramResponse = await deepgram.read.analyzeUrlCallback( - testReadSources.urlSource, - new CallbackUrl(callbackUrls.webhook), - commonAnalysisOptions - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result).toHaveProperty("request_id"); - expect(typeof response.result.request_id).toBe("string"); - expect(response.result.request_id.length).toBeGreaterThan(0); - } - - expect(response).toMatchSnapshot("read-analyze-url-callback-response-structure"); - }); - - it("should handle basic analysis options with callback", async () => { - const response: DeepgramResponse = await deepgram.read.analyzeUrlCallback( - testReadSources.urlSource, - new CallbackUrl(callbackUrls.testEndpoint), - { sentiment: true } - ); - - expect(response.error).toBeNull(); - expect(response.result).toBeDefined(); - - if (response.result) { - expect(response.result.request_id).toBeDefined(); - expect(typeof response.result.request_id).toBe("string"); - } - }, 30000); // 30 second timeout for API call -}); diff --git a/tests/e2e/read-analyze-url.test.ts b/tests/e2e/read-analyze-url.test.ts deleted file mode 100644 index 3be73a73..00000000 --- a/tests/e2e/read-analyze-url.test.ts +++ /dev/null @@ -1,94 +0,0 @@ -import { createClient } from "../../src/index"; -import { ReadRestClient } from "../../src/packages/ReadRestClient"; -import { DeepgramError } from "../../src/lib/errors"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testReadSources, commonAnalysisOptions } from "../__fixtures__/read"; - -describe("read analyzeUrl E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should analyze URL source synchronously", async () => { - const { result, error } = await deepgram.read.analyzeUrl( - testReadSources.urlSource, - commonAnalysisOptions - ); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot - expect(result).toMatchSnapshot("read-analyzeUrl-response-structure"); - - // Essential structural validation - expect(result).toHaveProperty("metadata"); - expect(result).toHaveProperty("results"); - - expect(result.metadata).toHaveProperty("request_id"); - expect(typeof result.metadata.request_id).toBe("string"); - - // Verify analysis results are present - expect(result.results).toBeTruthy(); - }, 30000); - - it("should handle DeepgramError and return it in response", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const readClient = new ReadRestClient({ key: apiKey }); - - // Mock the post method to throw a DeepgramError - const mockError = new DeepgramError("Test DeepgramError"); - jest.spyOn(readClient as any, "post").mockRejectedValue(mockError); - - const { result, error } = await readClient.analyzeUrl( - testReadSources.urlSource, - commonAnalysisOptions - ); - - expect(result).toBeNull(); - expect(error).toBe(mockError); - expect(error).toBeInstanceOf(DeepgramError); - - // Clean up spy - jest.restoreAllMocks(); - }); - - it("should re-throw non-DeepgramError", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const readClient = new ReadRestClient({ key: apiKey }); - - // Mock the post method to throw a regular Error - const mockError = new Error("Network error"); - jest.spyOn(readClient as any, "post").mockRejectedValue(mockError); - - await expect( - readClient.analyzeUrl(testReadSources.urlSource, commonAnalysisOptions) - ).rejects.toThrow("Network error"); - await expect( - readClient.analyzeUrl(testReadSources.urlSource, commonAnalysisOptions) - ).rejects.toThrow(Error); - - // Clean up spy - jest.restoreAllMocks(); - }); -}); diff --git a/tests/e2e/selfhosted-create-credentials.test.ts b/tests/e2e/selfhosted-create-credentials.test.ts deleted file mode 100644 index 6dd7c40b..00000000 --- a/tests/e2e/selfhosted-create-credentials.test.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testCredentials } from "../__fixtures__/selfhosted"; - -describe("selfhosted createCredentials E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should create new self-hosted credentials", async () => { - const { result, error } = await deepgram.selfhosted.createCredentials( - testProjectIds.primary, - testCredentials.createOptions - ); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot - expect(result).toMatchSnapshot("selfhosted-createCredentials-response-structure"); - - // Essential structural validation - expect(result).toHaveProperty("member"); - expect(result).toHaveProperty("distribution_credentials"); - - const credData = result.distribution_credentials; - expect(credData).toHaveProperty("distribution_credentials_id"); - expect(credData).toHaveProperty("comment"); - expect(credData).toHaveProperty("scopes"); - expect(credData).toHaveProperty("provider"); - expect(credData).toHaveProperty("created"); - - // Verify the created credentials match our input - expect(credData.comment).toBe(testCredentials.createOptions.comment); - expect(credData.scopes).toEqual(testCredentials.createOptions.scopes); - }, 30000); -}); diff --git a/tests/e2e/selfhosted-delete-credentials.test.ts b/tests/e2e/selfhosted-delete-credentials.test.ts deleted file mode 100644 index 15a0e7a7..00000000 --- a/tests/e2e/selfhosted-delete-credentials.test.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testCredentials } from "../__fixtures__/selfhosted"; - -describe("selfhosted deleteCredentials E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should delete self-hosted credentials", async () => { - const { result, error } = await deepgram.selfhosted.deleteCredentials( - testProjectIds.primary, - testCredentials.credentialId - ); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot - expect(result).toMatchSnapshot("selfhosted-deleteCredentials-response-structure"); - - // Essential structural validation - expect(result).toHaveProperty("message"); - expect(typeof result.message).toBe("string"); - expect(result.message.length).toBeGreaterThan(0); - }, 30000); -}); diff --git a/tests/e2e/selfhosted-get-credentials.test.ts b/tests/e2e/selfhosted-get-credentials.test.ts deleted file mode 100644 index aa04835a..00000000 --- a/tests/e2e/selfhosted-get-credentials.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { createClient } from "../../src/index"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds, testCredentials } from "../__fixtures__/selfhosted"; - -describe("selfhosted getCredentials E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should retrieve specific self-hosted credentials", async () => { - const { result, error } = await deepgram.selfhosted.getCredentials( - testProjectIds.primary, - testCredentials.credentialId - ); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot - expect(result).toMatchSnapshot("selfhosted-getCredentials-response-structure"); - - // Essential structural validation - expect(result).toHaveProperty("member"); - expect(result).toHaveProperty("distribution_credentials"); - - expect(result.member).toHaveProperty("member_id"); - expect(result.member).toHaveProperty("email"); - - const credData = result.distribution_credentials; - expect(credData).toHaveProperty("distribution_credentials_id"); - expect(credData).toHaveProperty("comment"); - expect(credData).toHaveProperty("scopes"); - expect(credData).toHaveProperty("provider"); - expect(credData).toHaveProperty("created"); - - // Verify data types - expect(typeof credData.distribution_credentials_id).toBe("string"); - expect(typeof credData.comment).toBe("string"); - expect(Array.isArray(credData.scopes)).toBe(true); - expect(typeof credData.provider).toBe("string"); - expect(typeof credData.created).toBe("string"); - - // Verify scopes array contains strings - credData.scopes.forEach((scope) => { - expect(typeof scope).toBe("string"); - }); - }, 30000); -}); diff --git a/tests/e2e/selfhosted-list-credentials.test.ts b/tests/e2e/selfhosted-list-credentials.test.ts deleted file mode 100644 index 3a880af9..00000000 --- a/tests/e2e/selfhosted-list-credentials.test.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { createClient } from "../../src/index"; -import { SelfHostedRestClient } from "../../src/packages/SelfHostedRestClient"; -import { DeepgramError } from "../../src/lib/errors"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testProjectIds } from "../__fixtures__/selfhosted"; - -describe("selfhosted listCredentials E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should list self-hosted credentials", async () => { - const { result, error } = await deepgram.selfhosted.listCredentials(testProjectIds.primary); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - // Type guard to ensure result is not null for subsequent operations - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Test the structure with snapshot - expect(result).toMatchSnapshot("selfhosted-listCredentials-response-structure"); - - // Essential structural validation - expect(result).toHaveProperty("distribution_credentials"); - expect(Array.isArray(result.distribution_credentials)).toBe(true); - - // Verify credentials structure if any exist - if (result.distribution_credentials.length > 0) { - const credential = result.distribution_credentials[0]; - expect(credential).toHaveProperty("member"); - expect(credential).toHaveProperty("distribution_credentials"); - - expect(credential.member).toHaveProperty("member_id"); - expect(credential.member).toHaveProperty("email"); - - const credData = credential.distribution_credentials; - expect(credData).toHaveProperty("distribution_credentials_id"); - expect(credData).toHaveProperty("comment"); - expect(credData).toHaveProperty("scopes"); - expect(credData).toHaveProperty("provider"); - expect(credData).toHaveProperty("created"); - - expect(Array.isArray(credData.scopes)).toBe(true); - } - }, 30000); - - it("should handle different endpoint configurations", async () => { - const customEndpoint = ":version/projects/:projectId/onprem/distribution/credentials"; - - const { result, error } = await deepgram.selfhosted.listCredentials( - testProjectIds.secondary, - customEndpoint - ); - - // Verify no error occurred - expect(error).toBeNull(); - expect(result).toBeTruthy(); - - if (!result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Verify the request was successful - expect(result).toHaveProperty("distribution_credentials"); - expect(Array.isArray(result.distribution_credentials)).toBe(true); - }, 30000); - - it("should handle DeepgramError and return it in response", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const selfhostedClient = new SelfHostedRestClient({ key: apiKey }); - - // Mock the get method to throw a DeepgramError - const mockError = new DeepgramError("Test DeepgramError"); - jest.spyOn(selfhostedClient as any, "get").mockRejectedValue(mockError); - - const { result, error } = await selfhostedClient.listCredentials(testProjectIds.primary); - - expect(result).toBeNull(); - expect(error).toBe(mockError); - expect(error).toBeInstanceOf(DeepgramError); - - // Clean up spy - jest.restoreAllMocks(); - }); - - it("should re-throw non-DeepgramError", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const selfhostedClient = new SelfHostedRestClient({ key: apiKey }); - - // Mock the get method to throw a regular Error - const mockError = new Error("Network error"); - jest.spyOn(selfhostedClient as any, "get").mockRejectedValue(mockError); - - await expect(selfhostedClient.listCredentials(testProjectIds.primary)).rejects.toThrow( - "Network error" - ); - await expect(selfhostedClient.listCredentials(testProjectIds.primary)).rejects.toThrow(Error); - - // Clean up spy - jest.restoreAllMocks(); - }); -}); diff --git a/tests/e2e/speak-live-connection.test.ts b/tests/e2e/speak-live-connection.test.ts deleted file mode 100644 index 4c843f51..00000000 --- a/tests/e2e/speak-live-connection.test.ts +++ /dev/null @@ -1,166 +0,0 @@ -import { SpeakLiveClient } from "../../src/packages/SpeakLiveClient"; -import { LiveTTSEvents } from "../../src/lib/enums/LiveTTSEvents"; -import { CONNECTION_STATE } from "../../src/lib/constants"; -import { MockWebSocket, WebSocketScenario, mockWebSocketData } from "../__utils__/websocket-mocks"; - -// Helper to wait for events -function waitForEvent(emitter: any, eventName: string, timeout = 2000): Promise { - return new Promise((resolve, reject) => { - const timer = setTimeout(() => { - reject(new Error(`Event '${eventName}' did not fire within ${timeout}ms`)); - }, timeout); - - emitter.once(eventName, (data: any) => { - clearTimeout(timer); - resolve(data); - }); - }); -} - -// Helper to collect multiple events -function collectEvents(emitter: any, eventNames: string[], timeout = 3000): Promise { - return new Promise((resolve, reject) => { - const results: any[] = []; - const received = new Set(); - - const timer = setTimeout(() => { - reject( - new Error( - `Not all events received within ${timeout}ms. Missing: ${eventNames.filter( - (name) => !received.has(name) - )}` - ) - ); - }, timeout); - - eventNames.forEach((eventName) => { - emitter.on(eventName, (data: any) => { - if (!received.has(eventName)) { - received.add(eventName); - results.push({ event: eventName, data }); - - if (received.size === eventNames.length) { - clearTimeout(timer); - resolve(results); - } - } - }); - }); - }); -} - -describe("speak live connection E2E", () => { - let mockWebSocketInstance: MockWebSocket; - let client: SpeakLiveClient; - - // Custom WebSocket constructor that captures the instance - const createMockWebSocketConstructor = () => { - return class MockWebSocketConstructor extends MockWebSocket { - constructor(url: string, protocols?: string | string[], options?: any) { - super(url, protocols, options); - // Store instance for test access - mockWebSocketInstance = this as MockWebSocket; - } - }; - }; - - beforeEach(() => { - const MockWebSocketConstructor = createMockWebSocketConstructor(); - - client = new SpeakLiveClient({ - key: "test-api-key", - global: { - websocket: { - // @ts-expect-error - Using mock for testing - client: MockWebSocketConstructor, - }, - }, - }); - }); - - afterEach(() => { - if (client) { - client.disconnect(); - } - }); - - it("should handle complete TTS synthesis workflow", async () => { - await waitForEvent(client, LiveTTSEvents.Open); - - expect(client.connectionState()).toBe(CONNECTION_STATE.Open); - expect(mockWebSocketInstance.url).toContain("speak"); - - // Set up event collectors for TTS workflow - const eventsPromise = collectEvents(client, [ - LiveTTSEvents.Metadata, - LiveTTSEvents.Audio, - LiveTTSEvents.Flushed, - ]); - - // Simulate TTS synthesis - const scenario = new WebSocketScenario(mockWebSocketInstance); - await scenario.simulateSpeakTTS(); - - const events = await eventsPromise; - expect(events).toHaveLength(3); - - const eventMap = events.reduce((acc, { event, data }) => { - acc[event] = data; - return acc; - }, {}); - - expect(eventMap[LiveTTSEvents.Metadata]).toEqual(mockWebSocketData.speak.metadata); - expect(eventMap[LiveTTSEvents.Audio]).toBeInstanceOf(Buffer); - expect(eventMap[LiveTTSEvents.Flushed]).toEqual(mockWebSocketData.speak.flushed); - }); - - it("should handle streaming text-to-speech session", async () => { - await waitForEvent(client, LiveTTSEvents.Open); - - // Simulate streaming text input - const texts = [ - "Hello, this is the first sentence.", - "This is the second sentence to synthesize.", - "And here's the final sentence.", - ]; - - texts.forEach((text) => { - client.sendText(text); - }); - - // Flush to get all audio - client.flush(); - - const sentMessages = mockWebSocketInstance.getSentMessages(); - - // Verify all text messages were sent - texts.forEach((text) => { - expect(sentMessages).toContain(JSON.stringify({ type: "Speak", text })); - }); - - // Verify flush was sent - expect(sentMessages).toContain(JSON.stringify({ type: "Flush" })); - }); - - it("should handle TTS session with multiple operations", async () => { - await waitForEvent(client, LiveTTSEvents.Open); - - // Simulate complex TTS session - client.sendText("Start of message"); - client.sendText("Middle part"); - client.flush(); // Get audio for first part - client.clear(); // Clear buffer - client.sendText("New message after clear"); - client.requestClose(); // End session - - const sentMessages = mockWebSocketInstance.getSentMessages(); - expect(sentMessages).toContain(JSON.stringify({ type: "Speak", text: "Start of message" })); - expect(sentMessages).toContain(JSON.stringify({ type: "Speak", text: "Middle part" })); - expect(sentMessages).toContain(JSON.stringify({ type: "Flush" })); - expect(sentMessages).toContain(JSON.stringify({ type: "Clear" })); - expect(sentMessages).toContain( - JSON.stringify({ type: "Speak", text: "New message after clear" }) - ); - expect(sentMessages).toContain(JSON.stringify({ type: "Close" })); - }); -}); diff --git a/tests/e2e/speak-request.test.ts b/tests/e2e/speak-request.test.ts deleted file mode 100644 index e8dab8e5..00000000 --- a/tests/e2e/speak-request.test.ts +++ /dev/null @@ -1,194 +0,0 @@ -import { createClient } from "../../src/index"; -import { SpeakRestClient } from "../../src/packages/SpeakRestClient"; -import { structureOnlySerializer, setupApiMocks, cleanupApiMocks } from "../__utils__"; -import { testTextSources, commonTTSOptions } from "../__fixtures__/speak"; - -describe("speak request E2E", () => { - let deepgram: ReturnType; - - beforeAll(() => { - // Set up API mocks (only active when not updating snapshots) - setupApiMocks(); - - // Use mock API key when mocking, real one when updating snapshots - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - deepgram = createClient(apiKey); - - // Add our custom serializer - expect.addSnapshotSerializer(structureOnlySerializer); - }); - - afterAll(() => { - // Clean up mocks - cleanupApiMocks(); - }); - - it("should generate speech from text and return audio data", async () => { - const speakClient = await deepgram.speak.request(testTextSources.greeting, commonTTSOptions); - - // Verify we got a response - expect(speakClient).toBeTruthy(); - expect(speakClient.result).toBeTruthy(); - - // Type guard to ensure result is not null for subsequent operations - if (!speakClient.result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - // Verify the response structure - expect(speakClient.result.ok).toBe(true); - expect(speakClient.result.status).toBe(200); - - // Verify we can get the audio stream - const audioStream = await speakClient.getStream(); - expect(audioStream).toBeTruthy(); - - // Verify headers contain expected TTS metadata - const headers = await speakClient.getHeaders(); - expect(headers).toBeTruthy(); - expect(headers.get("content-type")).toContain("audio/"); - - // Check for Deepgram-specific headers (if present) - const contentLength = headers.get("content-length"); - if (contentLength) { - expect(parseInt(contentLength)).toBeGreaterThan(0); - } - - // Test the structure with snapshot - const headerObj = Object.fromEntries(headers.entries()); - expect(headerObj).toMatchSnapshot("speak-request-response-headers"); - - // Verify audio stream is readable - expect(audioStream).toBeInstanceOf(ReadableStream); - }, 30000); // 30 second timeout for API call - - it("should handle different TTS options", async () => { - const speakClient = await deepgram.speak.request(testTextSources.longText, { - model: "aura-2-thalia-en", - encoding: "linear16", - sample_rate: 48000, - }); - - // Verify we got a response with the configured options - expect(speakClient).toBeTruthy(); - expect(speakClient.result).toBeTruthy(); - - if (!speakClient.result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - expect(speakClient.result.ok).toBe(true); - expect(speakClient.result.status).toBe(200); - - // Verify audio stream is available - const audioStream = await speakClient.getStream(); - expect(audioStream).toBeTruthy(); - expect(audioStream).toBeInstanceOf(ReadableStream); - - // Verify headers - const headers = await speakClient.getHeaders(); - expect(headers).toBeTruthy(); - expect(headers.get("content-type")).toBeTruthy(); - }, 30000); - - it("should handle multiline text input", async () => { - const speakClient = await deepgram.speak.request(testTextSources.multiline, commonTTSOptions); - - // Verify we got a response - expect(speakClient).toBeTruthy(); - expect(speakClient.result).toBeTruthy(); - - if (!speakClient.result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - expect(speakClient.result.ok).toBe(true); - - // Verify we can access the audio data - const audioStream = await speakClient.getStream(); - expect(audioStream).toBeTruthy(); - - const headers = await speakClient.getHeaders(); - expect(headers).toBeTruthy(); - expect(headers.get("content-type")).toContain("audio/"); - }, 30000); - - it("should reject empty text source", async () => { - // Empty text should be rejected by the client validation - await expect(deepgram.speak.request({ text: "" }, commonTTSOptions)).rejects.toThrow( - "Unknown transcription source type" - ); - }, 30000); - - it("should handle various audio encodings", async () => { - const encodingTests = [ - { encoding: "mp3" as const }, - { encoding: "linear16" as const, sample_rate: 48000 }, - { encoding: "opus" as const }, - ]; - - for (const options of encodingTests) { - const speakClient = await deepgram.speak.request( - { text: "Testing encoding: " + options.encoding }, - { - model: "aura-2-thalia-en", - ...options, - } - ); - - expect(speakClient).toBeTruthy(); - expect(speakClient.result).toBeTruthy(); - - if (!speakClient.result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - expect(speakClient.result.ok).toBe(true); - - const audioStream = await speakClient.getStream(); - expect(audioStream).toBeTruthy(); - } - }, 30000); - - it("should preserve special characters and punctuation", async () => { - const specialTextSource = { - text: "Hello! How are you? I'm fine. Testing 123, $50.00, and émojis 🎵", - }; - - const speakClient = await deepgram.speak.request(specialTextSource, commonTTSOptions); - - expect(speakClient).toBeTruthy(); - expect(speakClient.result).toBeTruthy(); - - if (!speakClient.result) { - throw new Error("Result should not be null after toBeTruthy check"); - } - - expect(speakClient.result.ok).toBe(true); - - const audioStream = await speakClient.getStream(); - expect(audioStream).toBeTruthy(); - - const headers = await speakClient.getHeaders(); - expect(headers).toBeTruthy(); - expect(headers.get("content-type")).toContain("audio/"); - }, 30000); - - it("should throw error when trying to getStream before making a request", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const speakClient = new SpeakRestClient({ key: apiKey }); - - await expect(speakClient.getStream()).rejects.toThrow( - "Tried to get stream before making request" - ); - }); - - it("should throw error when trying to getHeaders before making a request", async () => { - const apiKey = process.env.DEEPGRAM_API_KEY || "mock-api-key"; - const speakClient = new SpeakRestClient({ key: apiKey }); - - await expect(speakClient.getHeaders()).rejects.toThrow( - "Tried to get headers before making request" - ); - }); -}); diff --git a/tests/mock-server/MockServer.ts b/tests/mock-server/MockServer.ts new file mode 100644 index 00000000..6e258f17 --- /dev/null +++ b/tests/mock-server/MockServer.ts @@ -0,0 +1,29 @@ +import { RequestHandlerOptions } from "msw"; +import type { SetupServer } from "msw/node"; + +import { mockEndpointBuilder } from "./mockEndpointBuilder"; + +export interface MockServerOptions { + baseUrl: string; + server: SetupServer; +} + +export class MockServer { + private readonly server: SetupServer; + public readonly baseUrl: string; + + constructor({ baseUrl, server }: MockServerOptions) { + this.baseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl; + this.server = server; + } + + public mockEndpoint(options?: RequestHandlerOptions): ReturnType { + const builder = mockEndpointBuilder({ + once: options?.once, + onBuild: (handler) => { + this.server.use(handler); + }, + }).baseUrl(this.baseUrl); + return builder; + } +} diff --git a/tests/mock-server/MockServerPool.ts b/tests/mock-server/MockServerPool.ts new file mode 100644 index 00000000..81608069 --- /dev/null +++ b/tests/mock-server/MockServerPool.ts @@ -0,0 +1,106 @@ +import { setupServer } from "msw/node"; + +import { fromJson, toJson } from "../../src/core/json"; +import { MockServer } from "./MockServer"; +import { randomBaseUrl } from "./randomBaseUrl"; + +const mswServer = setupServer(); +interface MockServerOptions { + baseUrl?: string; +} + +async function formatHttpRequest(request: Request, id?: string): Promise { + try { + const clone = request.clone(); + const headers = [...clone.headers.entries()].map(([k, v]) => `${k}: ${v}`).join("\n"); + + let body = ""; + try { + const contentType = clone.headers.get("content-type"); + if (contentType?.includes("application/json")) { + body = toJson(fromJson(await clone.text()), undefined, 2); + } else if (clone.body) { + body = await clone.text(); + } + } catch (e) { + body = "(unable to parse body)"; + } + + const title = id ? `### Request ${id} ###\n` : ""; + const firstLine = `${title}${request.method} ${request.url.toString()} HTTP/1.1`; + + return `\n${firstLine}\n${headers}\n\n${body || "(no body)"}\n`; + } catch (e) { + return `Error formatting request: ${e}`; + } +} + +async function formatHttpResponse(response: Response, id?: string): Promise { + try { + const clone = response.clone(); + const headers = [...clone.headers.entries()].map(([k, v]) => `${k}: ${v}`).join("\n"); + + let body = ""; + try { + const contentType = clone.headers.get("content-type"); + if (contentType?.includes("application/json")) { + body = toJson(fromJson(await clone.text()), undefined, 2); + } else if (clone.body) { + body = await clone.text(); + } + } catch (e) { + body = "(unable to parse body)"; + } + + const title = id ? `### Response for ${id} ###\n` : ""; + const firstLine = `${title}HTTP/1.1 ${response.status} ${response.statusText}`; + + return `\n${firstLine}\n${headers}\n\n${body || "(no body)"}\n`; + } catch (e) { + return `Error formatting response: ${e}`; + } +} + +class MockServerPool { + private servers: MockServer[] = []; + + public createServer(options?: Partial): MockServer { + const baseUrl = options?.baseUrl || randomBaseUrl(); + const server = new MockServer({ baseUrl, server: mswServer }); + this.servers.push(server); + return server; + } + + public getServers(): MockServer[] { + return [...this.servers]; + } + + public listen(): void { + const onUnhandledRequest = process.env.LOG_LEVEL === "debug" ? "warn" : "bypass"; + mswServer.listen({ onUnhandledRequest }); + + if (process.env.LOG_LEVEL === "debug") { + mswServer.events.on("request:start", async ({ request, requestId }) => { + const formattedRequest = await formatHttpRequest(request, requestId); + console.debug("request:start\n" + formattedRequest); + }); + + mswServer.events.on("request:unhandled", async ({ request, requestId }) => { + const formattedRequest = await formatHttpRequest(request, requestId); + console.debug("request:unhandled\n" + formattedRequest); + }); + + mswServer.events.on("response:mocked", async ({ request, response, requestId }) => { + const formattedResponse = await formatHttpResponse(response, requestId); + console.debug("response:mocked\n" + formattedResponse); + }); + } + } + + public close(): void { + this.servers = []; + mswServer.close(); + } +} + +export const mockServerPool = new MockServerPool(); diff --git a/tests/mock-server/mockEndpointBuilder.ts b/tests/mock-server/mockEndpointBuilder.ts new file mode 100644 index 00000000..88368d4d --- /dev/null +++ b/tests/mock-server/mockEndpointBuilder.ts @@ -0,0 +1,215 @@ +import { DefaultBodyType, HttpHandler, HttpResponse, HttpResponseResolver, http } from "msw"; + +import { url } from "../../src/core"; +import { toJson } from "../../src/core/json"; +import { withHeaders } from "./withHeaders"; +import { withJson } from "./withJson"; + +type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head"; + +interface MethodStage { + baseUrl(baseUrl: string): MethodStage; + all(path: string): RequestHeadersStage; + get(path: string): RequestHeadersStage; + post(path: string): RequestHeadersStage; + put(path: string): RequestHeadersStage; + delete(path: string): RequestHeadersStage; + patch(path: string): RequestHeadersStage; + options(path: string): RequestHeadersStage; + head(path: string): RequestHeadersStage; +} + +interface RequestHeadersStage extends RequestBodyStage, ResponseStage { + header(name: string, value: string): RequestHeadersStage; + headers(headers: Record): RequestBodyStage; +} + +interface RequestBodyStage extends ResponseStage { + jsonBody(body: unknown): ResponseStage; +} + +interface ResponseStage { + respondWith(): ResponseStatusStage; +} +interface ResponseStatusStage { + statusCode(statusCode: number): ResponseHeaderStage; +} + +interface ResponseHeaderStage extends ResponseBodyStage, BuildStage { + header(name: string, value: string): ResponseHeaderStage; + headers(headers: Record): ResponseHeaderStage; +} + +interface ResponseBodyStage { + jsonBody(body: unknown): BuildStage; +} + +interface BuildStage { + build(): HttpHandler; +} + +export interface HttpHandlerBuilderOptions { + onBuild?: (handler: HttpHandler) => void; + once?: boolean; +} + +class RequestBuilder implements MethodStage, RequestHeadersStage, RequestBodyStage, ResponseStage { + private method: HttpMethod = "get"; + private _baseUrl: string = ""; + private path: string = "/"; + private readonly predicates: ((resolver: HttpResponseResolver) => HttpResponseResolver)[] = []; + private readonly handlerOptions?: HttpHandlerBuilderOptions; + + constructor(options?: HttpHandlerBuilderOptions) { + this.handlerOptions = options; + } + + baseUrl(baseUrl: string): MethodStage { + this._baseUrl = baseUrl; + return this; + } + + all(path: string): RequestHeadersStage { + this.method = "all"; + this.path = path; + return this; + } + + get(path: string): RequestHeadersStage { + this.method = "get"; + this.path = path; + return this; + } + + post(path: string): RequestHeadersStage { + this.method = "post"; + this.path = path; + return this; + } + + put(path: string): RequestHeadersStage { + this.method = "put"; + this.path = path; + return this; + } + + delete(path: string): RequestHeadersStage { + this.method = "delete"; + this.path = path; + return this; + } + + patch(path: string): RequestHeadersStage { + this.method = "patch"; + this.path = path; + return this; + } + + options(path: string): RequestHeadersStage { + this.method = "options"; + this.path = path; + return this; + } + + head(path: string): RequestHeadersStage { + this.method = "head"; + this.path = path; + return this; + } + + header(name: string, value: string): RequestHeadersStage { + this.predicates.push((resolver) => withHeaders({ [name]: value }, resolver)); + return this; + } + + headers(headers: Record): RequestBodyStage { + this.predicates.push((resolver) => withHeaders(headers, resolver)); + return this; + } + + jsonBody(body: unknown): ResponseStage { + if (body === undefined) { + throw new Error("Undefined is not valid JSON. Do not call jsonBody if you want an empty body."); + } + this.predicates.push((resolver) => withJson(body, resolver)); + return this; + } + + respondWith(): ResponseStatusStage { + return new ResponseBuilder(this.method, this.buildUrl(), this.predicates, this.handlerOptions); + } + + private buildUrl(): string { + return url.join(this._baseUrl, this.path); + } +} + +class ResponseBuilder implements ResponseStatusStage, ResponseHeaderStage, ResponseBodyStage, BuildStage { + private readonly method: HttpMethod; + private readonly url: string; + private readonly requestPredicates: ((resolver: HttpResponseResolver) => HttpResponseResolver)[]; + private readonly handlerOptions?: HttpHandlerBuilderOptions; + + private responseStatusCode: number = 200; + private responseHeaders: Record = {}; + private responseBody: DefaultBodyType = undefined; + + constructor( + method: HttpMethod, + url: string, + requestPredicates: ((resolver: HttpResponseResolver) => HttpResponseResolver)[], + options?: HttpHandlerBuilderOptions, + ) { + this.method = method; + this.url = url; + this.requestPredicates = requestPredicates; + this.handlerOptions = options; + } + + public statusCode(code: number): ResponseHeaderStage { + this.responseStatusCode = code; + return this; + } + + public header(name: string, value: string): ResponseHeaderStage { + this.responseHeaders[name] = value; + return this; + } + + public headers(headers: Record): ResponseHeaderStage { + this.responseHeaders = { ...this.responseHeaders, ...headers }; + return this; + } + + public jsonBody(body: unknown): BuildStage { + if (body === undefined) { + throw new Error("Undefined is not valid JSON. Do not call jsonBody if you expect an empty body."); + } + this.responseBody = toJson(body); + return this; + } + + public build(): HttpHandler { + const responseResolver: HttpResponseResolver = () => { + const response = new HttpResponse(this.responseBody, { + status: this.responseStatusCode, + headers: this.responseHeaders, + }); + // if no Content-Type header is set, delete the default text content type that is set + if (Object.keys(this.responseHeaders).some((key) => key.toLowerCase() === "content-type") === false) { + response.headers.delete("Content-Type"); + } + return response; + }; + + const finalResolver = this.requestPredicates.reduceRight((acc, predicate) => predicate(acc), responseResolver); + + const handler = http[this.method](this.url, finalResolver, this.handlerOptions); + this.handlerOptions?.onBuild?.(handler); + return handler; + } +} + +export function mockEndpointBuilder(options?: HttpHandlerBuilderOptions): MethodStage { + return new RequestBuilder(options); +} diff --git a/tests/mock-server/randomBaseUrl.ts b/tests/mock-server/randomBaseUrl.ts new file mode 100644 index 00000000..031aa640 --- /dev/null +++ b/tests/mock-server/randomBaseUrl.ts @@ -0,0 +1,4 @@ +export function randomBaseUrl(): string { + const randomString = Math.random().toString(36).substring(2, 15); + return `http://${randomString}.localhost`; +} diff --git a/tests/mock-server/setup.ts b/tests/mock-server/setup.ts new file mode 100644 index 00000000..c216d607 --- /dev/null +++ b/tests/mock-server/setup.ts @@ -0,0 +1,10 @@ +import { afterAll, beforeAll } from "@jest/globals"; + +import { mockServerPool } from "./MockServerPool"; + +beforeAll(() => { + mockServerPool.listen(); +}); +afterAll(() => { + mockServerPool.close(); +}); diff --git a/tests/mock-server/withHeaders.ts b/tests/mock-server/withHeaders.ts new file mode 100644 index 00000000..e77c837d --- /dev/null +++ b/tests/mock-server/withHeaders.ts @@ -0,0 +1,70 @@ +import { HttpResponseResolver, passthrough } from "msw"; + +/** + * Creates a request matcher that validates if request headers match specified criteria + * @param expectedHeaders - Headers to match against + * @param resolver - Response resolver to execute if headers match + */ +export function withHeaders( + expectedHeaders: Record boolean)>, + resolver: HttpResponseResolver, +): HttpResponseResolver { + return (args) => { + const { request } = args; + const { headers } = request; + + const mismatches: Record< + string, + { actual: string | null; expected: string | RegExp | ((value: string) => boolean) } + > = {}; + + for (const [key, expectedValue] of Object.entries(expectedHeaders)) { + const actualValue = headers.get(key); + + if (actualValue === null) { + mismatches[key] = { actual: null, expected: expectedValue }; + continue; + } + + if (typeof expectedValue === "function") { + if (!expectedValue(actualValue)) { + mismatches[key] = { actual: actualValue, expected: expectedValue }; + } + } else if (expectedValue instanceof RegExp) { + if (!expectedValue.test(actualValue)) { + mismatches[key] = { actual: actualValue, expected: expectedValue }; + } + } else if (expectedValue !== actualValue) { + mismatches[key] = { actual: actualValue, expected: expectedValue }; + } + } + + if (Object.keys(mismatches).length > 0) { + const formattedMismatches = formatHeaderMismatches(mismatches); + console.error("Header mismatch:", formattedMismatches); + return passthrough(); + } + + return resolver(args); + }; +} + +function formatHeaderMismatches( + mismatches: Record boolean) }>, +): Record { + const formatted: Record = {}; + + for (const [key, { actual, expected }] of Object.entries(mismatches)) { + formatted[key] = { + actual, + expected: + expected instanceof RegExp + ? expected.toString() + : typeof expected === "function" + ? "[Function]" + : expected, + }; + } + + return formatted; +} diff --git a/tests/mock-server/withJson.ts b/tests/mock-server/withJson.ts new file mode 100644 index 00000000..03f585de --- /dev/null +++ b/tests/mock-server/withJson.ts @@ -0,0 +1,158 @@ +import { HttpResponseResolver, passthrough } from "msw"; + +import { fromJson, toJson } from "../../src/core/json"; + +/** + * Creates a request matcher that validates if the request JSON body exactly matches the expected object + * @param expectedBody - The exact body object to match against + * @param resolver - Response resolver to execute if body matches + */ +export function withJson(expectedBody: unknown, resolver: HttpResponseResolver): HttpResponseResolver { + return async (args) => { + const { request } = args; + + let clonedRequest: Request; + let bodyText: string | undefined; + let actualBody: unknown; + try { + clonedRequest = request.clone(); + bodyText = await clonedRequest.text(); + if (bodyText === "") { + console.error("Request body is empty, expected a JSON object."); + return passthrough(); + } + actualBody = fromJson(bodyText); + } catch (error) { + console.error(`Error processing request body:\n\tError: ${error}\n\tBody: ${bodyText}`); + return passthrough(); + } + + const mismatches = findMismatches(actualBody, expectedBody); + if (Object.keys(mismatches).filter((key) => !key.startsWith("pagination.")).length > 0) { + console.error("JSON body mismatch:", toJson(mismatches, undefined, 2)); + return passthrough(); + } + + return resolver(args); + }; +} + +function findMismatches(actual: any, expected: any): Record { + const mismatches: Record = {}; + + if (typeof actual !== typeof expected) { + if (areEquivalent(actual, expected)) { + return {}; + } + return { value: { actual, expected } }; + } + + if (typeof actual !== "object" || actual === null || expected === null) { + if (actual !== expected) { + if (areEquivalent(actual, expected)) { + return {}; + } + return { value: { actual, expected } }; + } + return {}; + } + + if (Array.isArray(actual) && Array.isArray(expected)) { + if (actual.length !== expected.length) { + return { length: { actual: actual.length, expected: expected.length } }; + } + + const arrayMismatches: Record = {}; + for (let i = 0; i < actual.length; i++) { + const itemMismatches = findMismatches(actual[i], expected[i]); + if (Object.keys(itemMismatches).length > 0) { + for (const [mismatchKey, mismatchValue] of Object.entries(itemMismatches)) { + arrayMismatches[`[${i}]${mismatchKey === "value" ? "" : "." + mismatchKey}`] = mismatchValue; + } + } + } + return arrayMismatches; + } + + const actualKeys = Object.keys(actual); + const expectedKeys = Object.keys(expected); + + const allKeys = new Set([...actualKeys, ...expectedKeys]); + + for (const key of allKeys) { + if (!expectedKeys.includes(key)) { + if (actual[key] === undefined) { + continue; // Skip undefined values in actual + } + mismatches[key] = { actual: actual[key], expected: undefined }; + } else if (!actualKeys.includes(key)) { + if (expected[key] === undefined) { + continue; // Skip undefined values in expected + } + mismatches[key] = { actual: undefined, expected: expected[key] }; + } else if ( + typeof actual[key] === "object" && + actual[key] !== null && + typeof expected[key] === "object" && + expected[key] !== null + ) { + const nestedMismatches = findMismatches(actual[key], expected[key]); + if (Object.keys(nestedMismatches).length > 0) { + for (const [nestedKey, nestedValue] of Object.entries(nestedMismatches)) { + mismatches[`${key}${nestedKey === "value" ? "" : "." + nestedKey}`] = nestedValue; + } + } + } else if (actual[key] !== expected[key]) { + if (areEquivalent(actual[key], expected[key])) { + continue; + } + mismatches[key] = { actual: actual[key], expected: expected[key] }; + } + } + + return mismatches; +} + +function areEquivalent(actual: unknown, expected: unknown): boolean { + if (actual === expected) { + return true; + } + if (isEquivalentBigInt(actual, expected)) { + return true; + } + if (isEquivalentDatetime(actual, expected)) { + return true; + } + return false; +} + +function isEquivalentBigInt(actual: unknown, expected: unknown) { + if (typeof actual === "number") { + actual = BigInt(actual); + } + if (typeof expected === "number") { + expected = BigInt(expected); + } + if (typeof actual === "bigint" && typeof expected === "bigint") { + return actual === expected; + } + return false; +} + +function isEquivalentDatetime(str1: unknown, str2: unknown): boolean { + if (typeof str1 !== "string" || typeof str2 !== "string") { + return false; + } + const isoDatePattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/; + if (!isoDatePattern.test(str1) || !isoDatePattern.test(str2)) { + return false; + } + + try { + const date1 = new Date(str1).getTime(); + const date2 = new Date(str2).getTime(); + return date1 === date2; + } catch { + return false; + } +} diff --git a/tests/setup.ts b/tests/setup.ts deleted file mode 100644 index 7b0c83a2..00000000 --- a/tests/setup.ts +++ /dev/null @@ -1,46 +0,0 @@ -import "jest"; -import dotenv from "dotenv"; - -/** - * Test Setup for Deepgram JS SDK - * - * IMPORTANT: AI transcription services are non-deterministic! - * The same audio file may produce different (but valid) transcriptions on different calls. - * Our tests focus on structural validation and quality metrics rather than exact content matching. - */ - -// Load environment variables from .env file -dotenv.config(); - -// Global test setup -beforeAll(() => { - // Set test environment variables - process.env.NODE_ENV = "test"; - - // Configure environment for better offline testing - // This helps ensure tests don't accidentally make real network calls - if (!process.env.DEEPGRAM_API_KEY) { - process.env.DEEPGRAM_API_KEY = "mock-api-key-for-testing"; - } - - // Mock console methods for cleaner test output (optional) - if (process.env.JEST_SILENT !== "false") { - jest.spyOn(console, "log").mockImplementation(() => {}); - jest.spyOn(console, "warn").mockImplementation(() => {}); - jest.spyOn(console, "error").mockImplementation(() => {}); - } -}); - -afterAll(async () => { - // Restore console methods - jest.restoreAllMocks(); - - // Force close HTTP connections to prevent Jest hanging - // This addresses the TLSWRAP handles that keep Jest from exiting - if (typeof global.gc === "function") { - global.gc(); - } - - // Give a small delay to allow cleanup - await new Promise((resolve) => setTimeout(resolve, 100)); -}); diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 00000000..10185ed2 --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": null, + "rootDir": "..", + "baseUrl": ".." + }, + "include": ["../src", "../tests"], + "exclude": [] +} diff --git a/tests/unit/constants.test.ts b/tests/unit/constants.test.ts deleted file mode 100644 index ae492947..00000000 --- a/tests/unit/constants.test.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { - DEFAULT_HEADERS, - DEFAULT_URL, - DEFAULT_OPTIONS, - SOCKET_STATES, - CONNECTION_STATE, -} from "../../src/lib/constants"; - -describe("Unit Tests - Constants and Configuration", () => { - describe("DEFAULT_HEADERS", () => { - it("should have required headers with correct structure", () => { - expect(DEFAULT_HEADERS["Content-Type"]).toBe("application/json"); - expect(DEFAULT_HEADERS["X-Client-Info"]).toMatch( - /@deepgram\/sdk; (browser|server); v[\d.-]+/ - ); - expect(DEFAULT_HEADERS["User-Agent"]).toMatch( - /@deepgram\/sdk\/[\d.-]+(automated)? (node\/[\d.]+|bun\/[\d.]+|javascript)/ - ); - }); - - it("should have all required header fields", () => { - expect(DEFAULT_HEADERS).toHaveProperty("Content-Type"); - expect(DEFAULT_HEADERS["Content-Type"]).toBeTruthy(); - - expect(DEFAULT_HEADERS).toHaveProperty("X-Client-Info"); - expect(DEFAULT_HEADERS["X-Client-Info"]).toBeTruthy(); - - expect(DEFAULT_HEADERS).toHaveProperty("User-Agent"); - expect(DEFAULT_HEADERS["User-Agent"]).toBeTruthy(); - }); - }); - - describe("DEFAULT_URL and DEFAULT_OPTIONS", () => { - it("should have correct default URL", () => { - expect(DEFAULT_URL).toBe("https://api.deepgram.com"); - }); - - it("should have properly structured DEFAULT_OPTIONS", () => { - expect(DEFAULT_OPTIONS).toHaveProperty("global"); - expect(DEFAULT_OPTIONS).toHaveProperty("agent"); - - // Global options structure - expect(DEFAULT_OPTIONS.global).toHaveProperty("fetch"); - expect(DEFAULT_OPTIONS.global).toHaveProperty("websocket"); - expect(DEFAULT_OPTIONS.global?.fetch).toHaveProperty("options"); - expect(DEFAULT_OPTIONS.global?.websocket).toHaveProperty("options"); - - // Agent options structure - expect(DEFAULT_OPTIONS.agent).toHaveProperty("fetch"); - expect(DEFAULT_OPTIONS.agent).toHaveProperty("websocket"); - expect(DEFAULT_OPTIONS.agent?.fetch).toHaveProperty("options"); - expect(DEFAULT_OPTIONS.agent?.websocket).toHaveProperty("options"); - }); - - it("should have correct URLs in options", () => { - expect(DEFAULT_OPTIONS.global?.fetch?.options?.url).toBe("https://api.deepgram.com"); - expect(DEFAULT_OPTIONS.global?.websocket?.options?.url).toBe("wss://api.deepgram.com"); - expect(DEFAULT_OPTIONS.agent?.fetch?.options?.url).toBe("https://api.deepgram.com"); - expect(DEFAULT_OPTIONS.agent?.websocket?.options?.url).toBe("wss://agent.deepgram.com"); - }); - - it("should include headers in options", () => { - expect(DEFAULT_OPTIONS.global?.fetch?.options?.headers).toEqual(DEFAULT_HEADERS); - expect(DEFAULT_OPTIONS.global?.websocket?.options?._nodeOnlyHeaders).toEqual(DEFAULT_HEADERS); - expect(DEFAULT_OPTIONS.agent?.fetch?.options?.headers).toEqual(DEFAULT_HEADERS); - expect(DEFAULT_OPTIONS.agent?.websocket?.options?._nodeOnlyHeaders).toEqual(DEFAULT_HEADERS); - }); - }); - - describe("Enums", () => { - it("should have correct SOCKET_STATES values", () => { - expect(SOCKET_STATES.connecting).toBe(0); - expect(SOCKET_STATES.open).toBe(1); - expect(SOCKET_STATES.closing).toBe(2); - expect(SOCKET_STATES.closed).toBe(3); - }); - - it("should have correct CONNECTION_STATE values", () => { - expect(CONNECTION_STATE.Connecting).toBe("connecting"); - expect(CONNECTION_STATE.Open).toBe("open"); - expect(CONNECTION_STATE.Closing).toBe("closing"); - expect(CONNECTION_STATE.Closed).toBe("closed"); - }); - - it("should have all expected enum members", () => { - const expectedSocketStates = ["connecting", "open", "closing", "closed"]; - const expectedConnectionStates = ["Connecting", "Open", "Closing", "Closed"]; - - expectedSocketStates.forEach((state) => { - expect(SOCKET_STATES).toHaveProperty(state); - }); - - expectedConnectionStates.forEach((state) => { - expect(CONNECTION_STATE).toHaveProperty(state); - }); - }); - }); -}); diff --git a/tests/unit/fetch-utilities.test.ts b/tests/unit/fetch-utilities.test.ts deleted file mode 100644 index cfc1f25a..00000000 --- a/tests/unit/fetch-utilities.test.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { resolveHeadersConstructor } from "../../src/lib/helpers"; -import { resolveFetch, fetchWithAuth, resolveResponse } from "../../src/lib/fetch"; - -describe("Unit Tests - Fetch Utilities", () => { - describe("resolveHeadersConstructor", () => { - it("should return a valid Headers constructor", () => { - const HeadersConstructor = resolveHeadersConstructor(); - - expect(typeof HeadersConstructor).toBe("function"); - - // Should be able to create a Headers instance - const headers = new HeadersConstructor(); - expect(headers).toBeDefined(); - - // Should be able to set and get headers - headers.set("Content-Type", "application/json"); - expect(headers.get("Content-Type")).toBe("application/json"); - }); - }); - - describe("resolveFetch", () => { - it("should return the custom fetch when provided", () => { - const customFetch = jest.fn(); - const resolved = resolveFetch(customFetch); - - expect(typeof resolved).toBe("function"); - - // Should use the custom fetch when called - resolved("test-url", {}); - expect(customFetch).toHaveBeenCalledWith("test-url", {}); - }); - - it("should return a working fetch function when no custom fetch provided", () => { - const resolved = resolveFetch(); - - expect(typeof resolved).toBe("function"); - // Function should be callable (we can't easily test actual network calls in unit tests) - }); - - it("should handle fetch arguments correctly", () => { - const customFetch = jest.fn().mockResolvedValue({ ok: true }); - const resolved = resolveFetch(customFetch); - - const url = "https://api.example.com/test"; - const options = { method: "POST", body: "test data" }; - - resolved(url, options); - - expect(customFetch).toHaveBeenCalledWith(url, options); - }); - }); - - describe("fetchWithAuth", () => { - it("should add Authorization header when not present", async () => { - const mockFetch = jest.fn().mockResolvedValue({ ok: true }); - const apiKey = "test-api-key"; - const authenticatedFetch = fetchWithAuth({ apiKey, customFetch: mockFetch }); - - await authenticatedFetch("https://api.example.com/test", {}); - - expect(mockFetch).toHaveBeenCalledWith( - "https://api.example.com/test", - expect.objectContaining({ - headers: expect.any(Object), - }) - ); - - const callArgs = mockFetch.mock.calls[0][1]; - const headers = callArgs.headers; - expect(headers.get("Authorization")).toBe("Token test-api-key"); - }); - - it("should not override existing Authorization header", async () => { - const mockFetch = jest.fn().mockResolvedValue({ ok: true }); - const apiKey = "test-api-key"; - const authenticatedFetch = fetchWithAuth({ apiKey, customFetch: mockFetch }); - - const existingHeaders = new Headers(); - existingHeaders.set("Authorization", "Bearer existing-token"); - - await authenticatedFetch("https://api.example.com/test", { - headers: existingHeaders, - }); - - const callArgs = mockFetch.mock.calls[0][1]; - const headers = callArgs.headers; - expect(headers.get("Authorization")).toBe("Bearer existing-token"); - }); - - it("should preserve other headers", async () => { - const mockFetch = jest.fn().mockResolvedValue({ ok: true }); - const apiKey = "test-api-key"; - const authenticatedFetch = fetchWithAuth({ apiKey, customFetch: mockFetch }); - - const headers = { "Content-Type": "application/json", "X-Custom": "value" }; - - await authenticatedFetch("https://api.example.com/test", { headers }); - - const callArgs = mockFetch.mock.calls[0][1]; - const resultHeaders = callArgs.headers; - expect(resultHeaders.get("Content-Type")).toBe("application/json"); - expect(resultHeaders.get("X-Custom")).toBe("value"); - expect(resultHeaders.get("Authorization")).toBe("Token test-api-key"); - }); - }); - - describe("resolveResponse", () => { - it("should return a valid Response constructor", async () => { - const ResponseConstructor = await resolveResponse(); - - expect(typeof ResponseConstructor).toBe("function"); - expect(ResponseConstructor.name).toBe("Response"); - - // Should be able to create a Response instance - const response = new ResponseConstructor("test body", { status: 200 }); - expect(response).toBeDefined(); - expect(response.status).toBe(200); - }); - }); -}); diff --git a/tests/unit/fetcher/Fetcher.test.ts b/tests/unit/fetcher/Fetcher.test.ts new file mode 100644 index 00000000..f983f08a --- /dev/null +++ b/tests/unit/fetcher/Fetcher.test.ts @@ -0,0 +1,256 @@ +import fs from "fs"; +import stream from "stream"; +import { join } from "path"; + +import { Fetcher, fetcherImpl } from "../../../src/core/fetcher/Fetcher"; +import type { BinaryResponse } from "../../../src/core"; + +describe("Test fetcherImpl", () => { + it("should handle successful request", async () => { + const mockArgs: Fetcher.Args = { + url: "https://httpbin.org/post", + method: "POST", + headers: { "X-Test": "x-test-header" }, + body: { data: "test" }, + contentType: "application/json", + requestType: "json", + responseType: "json", + }; + + global.fetch = jest.fn().mockResolvedValue( + new Response(JSON.stringify({ data: "test" }), { + status: 200, + statusText: "OK", + }), + ); + + const result = await fetcherImpl(mockArgs); + expect(result.ok).toBe(true); + if (result.ok) { + expect(result.body).toEqual({ data: "test" }); + } + + expect(global.fetch).toHaveBeenCalledWith( + "https://httpbin.org/post", + expect.objectContaining({ + method: "POST", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + body: JSON.stringify({ data: "test" }), + }), + ); + }); + + it("should send octet stream", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "POST", + headers: { "X-Test": "x-test-header" }, + contentType: "application/octet-stream", + requestType: "bytes", + responseType: "json", + body: fs.createReadStream(join(__dirname, "test-file.txt")), + }; + + global.fetch = jest.fn().mockResolvedValue( + new Response(JSON.stringify({ data: "test" }), { + status: 200, + statusText: "OK", + }), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "POST", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + body: expect.any(fs.ReadStream), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + expect(result.body).toEqual({ data: "test" }); + } + }); + + it("should receive file as stream", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + responseType: "binary-response", + }; + + global.fetch = jest.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.stream).toBe("function"); + const stream = body.stream(); + expect(stream).toBeInstanceOf(ReadableStream); + const reader = stream.getReader(); + const { value } = await reader.read(); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(value); + expect(streamContent).toBe("This is a test file!\n"); + expect(body.bodyUsed).toBe(true); + } + }); + + it("should receive file as blob", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + responseType: "binary-response", + }; + + global.fetch = jest.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.blob).toBe("function"); + const blob = await body.blob(); + expect(blob).toBeInstanceOf(Blob); + const reader = blob.stream().getReader(); + const { value } = await reader.read(); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(value); + expect(streamContent).toBe("This is a test file!\n"); + expect(body.bodyUsed).toBe(true); + } + }); + + it("should receive file as arraybuffer", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + responseType: "binary-response", + }; + + global.fetch = jest.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.arrayBuffer).toBe("function"); + const arrayBuffer = await body.arrayBuffer(); + expect(arrayBuffer).toBeInstanceOf(ArrayBuffer); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(new Uint8Array(arrayBuffer)); + expect(streamContent).toBe("This is a test file!\n"); + expect(body.bodyUsed).toBe(true); + } + }); + + it("should receive file as bytes", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + responseType: "binary-response", + }; + + global.fetch = jest.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.objectContaining({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.bytes).toBe("function"); + if (!body.bytes) { + return; + } + const bytes = await body.bytes(); + expect(bytes).toBeInstanceOf(Uint8Array); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(bytes); + expect(streamContent).toBe("This is a test file!\n"); + expect(body.bodyUsed).toBe(true); + } + }); +}); diff --git a/tests/unit/fetcher/HttpResponsePromise.test.ts b/tests/unit/fetcher/HttpResponsePromise.test.ts new file mode 100644 index 00000000..2216a33e --- /dev/null +++ b/tests/unit/fetcher/HttpResponsePromise.test.ts @@ -0,0 +1,143 @@ +import { beforeEach, describe, expect, it, jest } from "@jest/globals"; + +import { HttpResponsePromise } from "../../../src/core/fetcher/HttpResponsePromise"; +import { RawResponse, WithRawResponse } from "../../../src/core/fetcher/RawResponse"; + +describe("HttpResponsePromise", () => { + const mockRawResponse: RawResponse = { + headers: new Headers(), + redirected: false, + status: 200, + statusText: "OK", + type: "basic" as ResponseType, + url: "https://example.com", + }; + const mockData = { id: "123", name: "test" }; + const mockWithRawResponse: WithRawResponse = { + data: mockData, + rawResponse: mockRawResponse, + }; + + describe("fromFunction", () => { + it("should create an HttpResponsePromise from a function", async () => { + const mockFn = jest + .fn<(arg1: string, arg2: string) => Promise>>() + .mockResolvedValue(mockWithRawResponse); + + const responsePromise = HttpResponsePromise.fromFunction(mockFn, "arg1", "arg2"); + + const result = await responsePromise; + expect(result).toEqual(mockData); + expect(mockFn).toHaveBeenCalledWith("arg1", "arg2"); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("fromPromise", () => { + it("should create an HttpResponsePromise from a promise", async () => { + const promise = Promise.resolve(mockWithRawResponse); + + const responsePromise = HttpResponsePromise.fromPromise(promise); + + const result = await responsePromise; + expect(result).toEqual(mockData); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("fromExecutor", () => { + it("should create an HttpResponsePromise from an executor function", async () => { + const responsePromise = HttpResponsePromise.fromExecutor((resolve) => { + resolve(mockWithRawResponse); + }); + + const result = await responsePromise; + expect(result).toEqual(mockData); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("fromResult", () => { + it("should create an HttpResponsePromise from a result", async () => { + const responsePromise = HttpResponsePromise.fromResult(mockWithRawResponse); + + const result = await responsePromise; + expect(result).toEqual(mockData); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("Promise methods", () => { + let responsePromise: HttpResponsePromise; + + beforeEach(() => { + responsePromise = HttpResponsePromise.fromResult(mockWithRawResponse); + }); + + it("should support then() method", async () => { + const result = await responsePromise.then((data) => ({ + ...data, + modified: true, + })); + + expect(result).toEqual({ + ...mockData, + modified: true, + }); + }); + + it("should support catch() method", async () => { + const errorResponsePromise = HttpResponsePromise.fromExecutor((_, reject) => { + reject(new Error("Test error")); + }); + + const catchSpy = jest.fn(); + await errorResponsePromise.catch(catchSpy); + + expect(catchSpy).toHaveBeenCalled(); + const error = catchSpy.mock.calls[0]?.[0]; + expect(error).toBeInstanceOf(Error); + expect((error as Error).message).toBe("Test error"); + }); + + it("should support finally() method", async () => { + const finallySpy = jest.fn(); + await responsePromise.finally(finallySpy); + + expect(finallySpy).toHaveBeenCalled(); + }); + }); + + describe("withRawResponse", () => { + it("should return both data and raw response", async () => { + const responsePromise = HttpResponsePromise.fromResult(mockWithRawResponse); + + const result = await responsePromise.withRawResponse(); + + expect(result).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); +}); diff --git a/tests/unit/fetcher/RawResponse.test.ts b/tests/unit/fetcher/RawResponse.test.ts new file mode 100644 index 00000000..9ccd5e1e --- /dev/null +++ b/tests/unit/fetcher/RawResponse.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "@jest/globals"; + +import { toRawResponse } from "../../../src/core/fetcher/RawResponse"; + +describe("RawResponse", () => { + describe("toRawResponse", () => { + it("should convert Response to RawResponse by removing body, bodyUsed, and ok properties", () => { + const mockHeaders = new Headers({ "content-type": "application/json" }); + const mockResponse = { + body: "test body", + bodyUsed: false, + ok: true, + headers: mockHeaders, + redirected: false, + status: 200, + statusText: "OK", + type: "basic" as ResponseType, + url: "https://example.com", + }; + + const result = toRawResponse(mockResponse as unknown as Response); + + expect("body" in result).toBe(false); + expect("bodyUsed" in result).toBe(false); + expect("ok" in result).toBe(false); + expect(result.headers).toBe(mockHeaders); + expect(result.redirected).toBe(false); + expect(result.status).toBe(200); + expect(result.statusText).toBe("OK"); + expect(result.type).toBe("basic"); + expect(result.url).toBe("https://example.com"); + }); + }); +}); diff --git a/tests/unit/fetcher/createRequestUrl.test.ts b/tests/unit/fetcher/createRequestUrl.test.ts new file mode 100644 index 00000000..06e03b2c --- /dev/null +++ b/tests/unit/fetcher/createRequestUrl.test.ts @@ -0,0 +1,160 @@ +import { createRequestUrl } from "../../../src/core/fetcher/createRequestUrl"; + +describe("Test createRequestUrl", () => { + it("should return the base URL when no query parameters are provided", () => { + const baseUrl = "https://api.example.com"; + expect(createRequestUrl(baseUrl)).toBe(baseUrl); + }); + + it("should append simple query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { key: "value", another: "param" }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?key=value&another=param"); + }); + + it("should handle array query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { items: ["a", "b", "c"] }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?items=a&items=b&items=c"); + }); + + it("should handle object query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { filter: { name: "John", age: 30 } }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?filter%5Bname%5D=John&filter%5Bage%5D=30", + ); + }); + + it("should handle mixed types of query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + simple: "value", + array: ["x", "y"], + object: { key: "value" }, + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?simple=value&array=x&array=y&object%5Bkey%5D=value", + ); + }); + + it("should handle empty query parameters object", () => { + const baseUrl = "https://api.example.com"; + expect(createRequestUrl(baseUrl, {})).toBe(baseUrl); + }); + + it("should encode special characters in query parameters", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { special: "a&b=c d" }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?special=a%26b%3Dc%20d"); + }); + + // Additional tests for edge cases and different value types + it("should handle numeric values", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { count: 42, price: 19.99, active: 1, inactive: 0 }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?count=42&price=19.99&active=1&inactive=0", + ); + }); + + it("should handle boolean values", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { enabled: true, disabled: false }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?enabled=true&disabled=false"); + }); + + it("should handle null and undefined values", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + valid: "value", + nullValue: null, + undefinedValue: undefined, + emptyString: "", + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?valid=value&nullValue=&emptyString=", + ); + }); + + it("should handle deeply nested objects", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + user: { + profile: { + name: "John", + settings: { theme: "dark" }, + }, + }, + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?user%5Bprofile%5D%5Bname%5D=John&user%5Bprofile%5D%5Bsettings%5D%5Btheme%5D=dark", + ); + }); + + it("should handle arrays of objects", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + users: [ + { name: "John", age: 30 }, + { name: "Jane", age: 25 }, + ], + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?users%5Bname%5D=John&users%5Bage%5D=30&users%5Bname%5D=Jane&users%5Bage%5D=25", + ); + }); + + it("should handle mixed arrays", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + mixed: ["string", 42, true, { key: "value" }], + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?mixed=string&mixed=42&mixed=true&mixed%5Bkey%5D=value", + ); + }); + + it("should handle empty arrays", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { emptyArray: [] }; + expect(createRequestUrl(baseUrl, queryParams)).toBe(baseUrl); + }); + + it("should handle empty objects", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { emptyObject: {} }; + expect(createRequestUrl(baseUrl, queryParams)).toBe(baseUrl); + }); + + it("should handle special characters in keys", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { "key with spaces": "value", "key[with]brackets": "value" }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?key%20with%20spaces=value&key%5Bwith%5Dbrackets=value", + ); + }); + + it("should handle URL with existing query parameters", () => { + const baseUrl = "https://api.example.com?existing=param"; + const queryParams = { new: "value" }; + expect(createRequestUrl(baseUrl, queryParams)).toBe("https://api.example.com?existing=param?new=value"); + }); + + it("should handle complex nested structures", () => { + const baseUrl = "https://api.example.com"; + const queryParams = { + filters: { + status: ["active", "pending"], + category: { + type: "electronics", + subcategories: ["phones", "laptops"], + }, + }, + sort: { field: "name", direction: "asc" }, + }; + expect(createRequestUrl(baseUrl, queryParams)).toBe( + "https://api.example.com?filters%5Bstatus%5D=active&filters%5Bstatus%5D=pending&filters%5Bcategory%5D%5Btype%5D=electronics&filters%5Bcategory%5D%5Bsubcategories%5D=phones&filters%5Bcategory%5D%5Bsubcategories%5D=laptops&sort%5Bfield%5D=name&sort%5Bdirection%5D=asc", + ); + }); +}); diff --git a/tests/unit/fetcher/getRequestBody.test.ts b/tests/unit/fetcher/getRequestBody.test.ts new file mode 100644 index 00000000..e864c8b5 --- /dev/null +++ b/tests/unit/fetcher/getRequestBody.test.ts @@ -0,0 +1,65 @@ +import { getRequestBody } from "../../../src/core/fetcher/getRequestBody"; +import { RUNTIME } from "../../../src/core/runtime"; + +describe("Test getRequestBody", () => { + it("should stringify body if not FormData in Node environment", async () => { + if (RUNTIME.type === "node") { + const body = { key: "value" }; + const result = await getRequestBody({ + body, + type: "json", + }); + expect(result).toBe('{"key":"value"}'); + } + }); + + it("should return FormData in browser environment", async () => { + if (RUNTIME.type === "browser") { + const formData = new FormData(); + formData.append("key", "value"); + const result = await getRequestBody({ + body: formData, + type: "file", + }); + expect(result).toBe(formData); + } + }); + + it("should stringify body if not FormData in browser environment", async () => { + if (RUNTIME.type === "browser") { + const body = { key: "value" }; + const result = await getRequestBody({ + body, + type: "json", + }); + expect(result).toBe('{"key":"value"}'); + } + }); + + it("should return the Uint8Array", async () => { + const input = new Uint8Array([1, 2, 3]); + const result = await getRequestBody({ + body: input, + type: "bytes", + }); + expect(result).toBe(input); + }); + + it("should return the input for content-type 'application/x-www-form-urlencoded'", async () => { + const input = "key=value&another=param"; + const result = await getRequestBody({ + body: input, + type: "other", + }); + expect(result).toBe(input); + }); + + it("should JSON stringify objects", async () => { + const input = { key: "value" }; + const result = await getRequestBody({ + body: input, + type: "json", + }); + expect(result).toBe('{"key":"value"}'); + }); +}); diff --git a/tests/unit/fetcher/getResponseBody.test.ts b/tests/unit/fetcher/getResponseBody.test.ts new file mode 100644 index 00000000..400782f5 --- /dev/null +++ b/tests/unit/fetcher/getResponseBody.test.ts @@ -0,0 +1,77 @@ +import { RUNTIME } from "../../../src/core/runtime"; +import { getResponseBody } from "../../../src/core/fetcher/getResponseBody"; + +describe("Test getResponseBody", () => { + it("should handle blob response type", async () => { + const mockBlob = new Blob(["test"], { type: "text/plain" }); + const mockResponse = new Response(mockBlob); + const result = await getResponseBody(mockResponse, "blob"); + // @ts-expect-error + expect(result.constructor.name).toBe("Blob"); + }); + + it("should handle sse response type", async () => { + if (RUNTIME.type === "node") { + const mockStream = new ReadableStream(); + const mockResponse = new Response(mockStream); + const result = await getResponseBody(mockResponse, "sse"); + expect(result).toBe(mockStream); + } + }); + + it("should handle streaming response type", async () => { + // Create a ReadableStream with some test data + const encoder = new TextEncoder(); + const testData = "test stream data"; + const mockStream = new ReadableStream({ + start(controller) { + controller.enqueue(encoder.encode(testData)); + controller.close(); + }, + }); + + const mockResponse = new Response(mockStream); + const result = (await getResponseBody(mockResponse, "streaming")) as ReadableStream; + + expect(result).toBeInstanceOf(ReadableStream); + + // Read and verify the stream content + const reader = result.getReader(); + const decoder = new TextDecoder(); + const { value } = await reader.read(); + const streamContent = decoder.decode(value); + expect(streamContent).toBe(testData); + }); + + it("should handle text response type", async () => { + const mockResponse = new Response("test text"); + const result = await getResponseBody(mockResponse, "text"); + expect(result).toBe("test text"); + }); + + it("should handle JSON response", async () => { + const mockJson = { key: "value" }; + const mockResponse = new Response(JSON.stringify(mockJson)); + const result = await getResponseBody(mockResponse); + expect(result).toEqual(mockJson); + }); + + it("should handle empty response", async () => { + const mockResponse = new Response(""); + const result = await getResponseBody(mockResponse); + expect(result).toBeUndefined(); + }); + + it("should handle non-JSON response", async () => { + const mockResponse = new Response("invalid json"); + const result = await getResponseBody(mockResponse); + expect(result).toEqual({ + ok: false, + error: { + reason: "non-json", + statusCode: 200, + rawBody: "invalid json", + }, + }); + }); +}); diff --git a/tests/unit/fetcher/makeRequest.test.ts b/tests/unit/fetcher/makeRequest.test.ts new file mode 100644 index 00000000..43ed9d11 --- /dev/null +++ b/tests/unit/fetcher/makeRequest.test.ts @@ -0,0 +1,53 @@ +import { makeRequest } from "../../../src/core/fetcher/makeRequest"; + +describe("Test makeRequest", () => { + const mockPostUrl = "https://httpbin.org/post"; + const mockGetUrl = "https://httpbin.org/get"; + const mockHeaders = { "Content-Type": "application/json" }; + const mockBody = JSON.stringify({ key: "value" }); + + let mockFetch: jest.Mock; + + beforeEach(() => { + mockFetch = jest.fn(); + mockFetch.mockResolvedValue(new Response(JSON.stringify({ test: "successful" }), { status: 200 })); + }); + + it("should handle POST request correctly", async () => { + const response = await makeRequest(mockFetch, mockPostUrl, "POST", mockHeaders, mockBody); + const responseBody = await response.json(); + expect(responseBody).toEqual({ test: "successful" }); + expect(mockFetch).toHaveBeenCalledTimes(1); + const [calledUrl, calledOptions] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe(mockPostUrl); + expect(calledOptions).toEqual( + expect.objectContaining({ + method: "POST", + headers: mockHeaders, + body: mockBody, + credentials: undefined, + }), + ); + expect(calledOptions.signal).toBeDefined(); + expect(calledOptions.signal).toBeInstanceOf(AbortSignal); + }); + + it("should handle GET request correctly", async () => { + const response = await makeRequest(mockFetch, mockGetUrl, "GET", mockHeaders, undefined); + const responseBody = await response.json(); + expect(responseBody).toEqual({ test: "successful" }); + expect(mockFetch).toHaveBeenCalledTimes(1); + const [calledUrl, calledOptions] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe(mockGetUrl); + expect(calledOptions).toEqual( + expect.objectContaining({ + method: "GET", + headers: mockHeaders, + body: undefined, + credentials: undefined, + }), + ); + expect(calledOptions.signal).toBeDefined(); + expect(calledOptions.signal).toBeInstanceOf(AbortSignal); + }); +}); diff --git a/tests/unit/fetcher/requestWithRetries.test.ts b/tests/unit/fetcher/requestWithRetries.test.ts new file mode 100644 index 00000000..6f9426fc --- /dev/null +++ b/tests/unit/fetcher/requestWithRetries.test.ts @@ -0,0 +1,235 @@ +import { requestWithRetries } from "../../../src/core/fetcher/requestWithRetries"; + +describe("requestWithRetries", () => { + let mockFetch: jest.Mock; + let originalMathRandom: typeof Math.random; + let setTimeoutSpy: jest.SpyInstance; + + beforeEach(() => { + mockFetch = jest.fn(); + originalMathRandom = Math.random; + + // Mock Math.random for consistent jitter + Math.random = jest.fn(() => 0.5); + + jest.useFakeTimers({ doNotFake: ["nextTick"] }); + }); + + afterEach(() => { + Math.random = originalMathRandom; + jest.clearAllMocks(); + jest.clearAllTimers(); + }); + + it("should retry on retryable status codes", async () => { + setTimeoutSpy = jest.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const retryableStatuses = [408, 429, 500, 502]; + let callCount = 0; + + mockFetch.mockImplementation(async () => { + if (callCount < retryableStatuses.length) { + return new Response("", { status: retryableStatuses[callCount++] }); + } + return new Response("", { status: 200 }); + }); + + const responsePromise = requestWithRetries(() => mockFetch(), retryableStatuses.length); + await jest.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(retryableStatuses.length + 1); + expect(response.status).toBe(200); + }); + + it("should respect maxRetries limit", async () => { + setTimeoutSpy = jest.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const maxRetries = 2; + mockFetch.mockResolvedValue(new Response("", { status: 500 })); + + const responsePromise = requestWithRetries(() => mockFetch(), maxRetries); + await jest.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(maxRetries + 1); + expect(response.status).toBe(500); + }); + + it("should not retry on success status codes", async () => { + setTimeoutSpy = jest.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const successStatuses = [200, 201, 202]; + + for (const status of successStatuses) { + mockFetch.mockReset(); + setTimeoutSpy.mockClear(); + mockFetch.mockResolvedValueOnce(new Response("", { status })); + + const responsePromise = requestWithRetries(() => mockFetch(), 3); + await jest.runAllTimersAsync(); + await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(1); + expect(setTimeoutSpy).not.toHaveBeenCalled(); + } + }); + + it("should apply correct exponential backoff with jitter", async () => { + setTimeoutSpy = jest.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch.mockResolvedValue(new Response("", { status: 500 })); + const maxRetries = 3; + const expectedDelays = [1000, 2000, 4000]; + + const responsePromise = requestWithRetries(() => mockFetch(), maxRetries); + await jest.runAllTimersAsync(); + await responsePromise; + + // Verify setTimeout calls + expect(setTimeoutSpy).toHaveBeenCalledTimes(expectedDelays.length); + + expectedDelays.forEach((delay, index) => { + expect(setTimeoutSpy).toHaveBeenNthCalledWith(index + 1, expect.any(Function), delay); + }); + + expect(mockFetch).toHaveBeenCalledTimes(maxRetries + 1); + }); + + it("should handle concurrent retries independently", async () => { + setTimeoutSpy = jest.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce(new Response("", { status: 500 })) + .mockResolvedValueOnce(new Response("", { status: 500 })) + .mockResolvedValueOnce(new Response("", { status: 200 })) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const promise1 = requestWithRetries(() => mockFetch(), 1); + const promise2 = requestWithRetries(() => mockFetch(), 1); + + await jest.runAllTimersAsync(); + const [response1, response2] = await Promise.all([promise1, promise2]); + + expect(response1.status).toBe(200); + expect(response2.status).toBe(200); + }); + + it("should respect retry-after header with seconds value", async () => { + setTimeoutSpy = jest.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ "retry-after": "5" }), + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await jest.runAllTimersAsync(); + const response = await responsePromise; + + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 5000); // 5 seconds = 5000ms + expect(response.status).toBe(200); + }); + + it("should respect retry-after header with HTTP date value", async () => { + setTimeoutSpy = jest.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const futureDate = new Date(Date.now() + 3000); // 3 seconds from now + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ "retry-after": futureDate.toUTCString() }), + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await jest.runAllTimersAsync(); + const response = await responsePromise; + + // Should use the date-based delay (approximately 3000ms, but with jitter) + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), expect.any(Number)); + const actualDelay = setTimeoutSpy.mock.calls[0][1]; + expect(actualDelay).toBeGreaterThan(2000); + expect(actualDelay).toBeLessThan(4000); + expect(response.status).toBe(200); + }); + + it("should respect x-ratelimit-reset header", async () => { + setTimeoutSpy = jest.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const resetTime = Math.floor((Date.now() + 4000) / 1000); // 4 seconds from now in Unix timestamp + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ "x-ratelimit-reset": resetTime.toString() }), + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await jest.runAllTimersAsync(); + const response = await responsePromise; + + // Should use the x-ratelimit-reset delay (approximately 4000ms, but with positive jitter) + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), expect.any(Number)); + const actualDelay = setTimeoutSpy.mock.calls[0][1]; + expect(actualDelay).toBeGreaterThan(3000); + expect(actualDelay).toBeLessThan(6000); + expect(response.status).toBe(200); + }); + + it("should cap delay at MAX_RETRY_DELAY for large header values", async () => { + setTimeoutSpy = jest.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ "retry-after": "120" }), // 120 seconds = 120000ms > MAX_RETRY_DELAY (60000ms) + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await jest.runAllTimersAsync(); + const response = await responsePromise; + + // Should be capped at MAX_RETRY_DELAY (60000ms) with jitter applied + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 60000); // Exactly MAX_RETRY_DELAY since jitter with 0.5 random keeps it at 60000 + expect(response.status).toBe(200); + }); +}); diff --git a/tests/unit/fetcher/signals.test.ts b/tests/unit/fetcher/signals.test.ts new file mode 100644 index 00000000..9cabfa07 --- /dev/null +++ b/tests/unit/fetcher/signals.test.ts @@ -0,0 +1,69 @@ +import { anySignal, getTimeoutSignal } from "../../../src/core/fetcher/signals"; + +describe("Test getTimeoutSignal", () => { + beforeEach(() => { + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.useRealTimers(); + }); + + it("should return an object with signal and abortId", () => { + const { signal, abortId } = getTimeoutSignal(1000); + + expect(signal).toBeDefined(); + expect(abortId).toBeDefined(); + expect(signal).toBeInstanceOf(AbortSignal); + expect(signal.aborted).toBe(false); + }); + + it("should create a signal that aborts after the specified timeout", () => { + const timeoutMs = 5000; + const { signal } = getTimeoutSignal(timeoutMs); + + expect(signal.aborted).toBe(false); + + jest.advanceTimersByTime(timeoutMs - 1); + expect(signal.aborted).toBe(false); + + jest.advanceTimersByTime(1); + expect(signal.aborted).toBe(true); + }); +}); + +describe("Test anySignal", () => { + it("should return an AbortSignal", () => { + const signal = anySignal(new AbortController().signal); + expect(signal).toBeInstanceOf(AbortSignal); + }); + + it("should abort when any of the input signals is aborted", () => { + const controller1 = new AbortController(); + const controller2 = new AbortController(); + const signal = anySignal(controller1.signal, controller2.signal); + + expect(signal.aborted).toBe(false); + controller1.abort(); + expect(signal.aborted).toBe(true); + }); + + it("should handle an array of signals", () => { + const controller1 = new AbortController(); + const controller2 = new AbortController(); + const signal = anySignal([controller1.signal, controller2.signal]); + + expect(signal.aborted).toBe(false); + controller2.abort(); + expect(signal.aborted).toBe(true); + }); + + it("should abort immediately if one of the input signals is already aborted", () => { + const controller1 = new AbortController(); + const controller2 = new AbortController(); + controller1.abort(); + + const signal = anySignal(controller1.signal, controller2.signal); + expect(signal.aborted).toBe(true); + }); +}); diff --git a/tests/unit/fetcher/test-file.txt b/tests/unit/fetcher/test-file.txt new file mode 100644 index 00000000..c66d471e --- /dev/null +++ b/tests/unit/fetcher/test-file.txt @@ -0,0 +1 @@ +This is a test file! diff --git a/tests/unit/file/file.test.ts b/tests/unit/file/file.test.ts new file mode 100644 index 00000000..0bc7c879 --- /dev/null +++ b/tests/unit/file/file.test.ts @@ -0,0 +1,540 @@ +import fs from "fs"; +import { join } from "path"; +import { Readable } from "stream"; +import { toBinaryUploadRequest, Uploadable } from "../../../src/core/file/index"; + +describe("toBinaryUploadRequest", () => { + const TEST_FILE_PATH = join(__dirname, "test-file.txt"); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe("Buffer input", () => { + it("should handle Buffer with all metadata", async () => { + const buffer = Buffer.from("test data"); + const input: Uploadable.WithMetadata = { + data: buffer, + filename: "test.txt", + contentType: "text/plain", + contentLength: 42, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test.txt"', + "Content-Type": "text/plain", + "Content-Length": "42", + }); + }); + + it("should handle Buffer without metadata", async () => { + const buffer = Buffer.from("test data"); + const input: Uploadable.WithMetadata = { + data: buffer, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Length": "9", // buffer.length + }); + }); + + it("should handle Buffer passed directly", async () => { + const buffer = Buffer.from("test data"); + + const result = await toBinaryUploadRequest(buffer); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Length": "9", // buffer.length + }); + }); + }); + + describe("ArrayBuffer input", () => { + it("should handle ArrayBuffer with metadata", async () => { + const arrayBuffer = new ArrayBuffer(10); + const input: Uploadable.WithMetadata = { + data: arrayBuffer, + filename: "data.bin", + contentType: "application/octet-stream", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(arrayBuffer); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="data.bin"', + "Content-Type": "application/octet-stream", + "Content-Length": "10", // arrayBuffer.byteLength + }); + }); + + it("should handle ArrayBuffer passed directly", async () => { + const arrayBuffer = new ArrayBuffer(10); + + const result = await toBinaryUploadRequest(arrayBuffer); + + expect(result.body).toBe(arrayBuffer); + expect(result.headers).toEqual({ + "Content-Length": "10", // arrayBuffer.byteLength + }); + }); + }); + + describe("Uint8Array input", () => { + it("should handle Uint8Array with metadata", async () => { + const uint8Array = new Uint8Array([1, 2, 3, 4, 5]); + const input: Uploadable.WithMetadata = { + data: uint8Array, + filename: "bytes.bin", + contentType: "application/octet-stream", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(uint8Array); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="bytes.bin"', + "Content-Type": "application/octet-stream", + "Content-Length": "5", // uint8Array.byteLength + }); + }); + + it("should handle Uint8Array passed directly", async () => { + const uint8Array = new Uint8Array([1, 2, 3, 4, 5]); + + const result = await toBinaryUploadRequest(uint8Array); + + expect(result.body).toBe(uint8Array); + expect(result.headers).toEqual({ + "Content-Length": "5", // uint8Array.byteLength + }); + }); + }); + + describe("Blob input", () => { + it("should handle Blob with metadata", async () => { + const blob = new Blob(["test content"], { type: "text/plain" }); + const input: Uploadable.WithMetadata = { + data: blob, + filename: "override.txt", + contentType: "text/html", // Override blob's type + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(blob); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="override.txt"', + "Content-Type": "text/html", // Should use provided contentType + "Content-Length": "12", // blob.size + }); + }); + + it("should handle Blob with intrinsic type", async () => { + const blob = new Blob(["test content"], { type: "application/json" }); + const input: Uploadable.WithMetadata = { + data: blob, + filename: "data.json", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(blob); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="data.json"', + "Content-Type": "application/json", // Should use blob's type + "Content-Length": "12", // blob.size + }); + }); + + it("should handle Blob passed directly", async () => { + const blob = new Blob(["test content"], { type: "text/plain" }); + + const result = await toBinaryUploadRequest(blob); + + expect(result.body).toBe(blob); + expect(result.headers).toEqual({ + "Content-Type": "text/plain", // Should use blob's type + "Content-Length": "12", // blob.size + }); + }); + }); + + describe("File input", () => { + it("should handle File with metadata", async () => { + const file = new File(["file content"], "original.txt", { type: "text/plain" }); + const input: Uploadable.WithMetadata = { + data: file, + filename: "renamed.txt", + contentType: "text/html", // Override file's type + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(file); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="renamed.txt"', + "Content-Type": "text/html", // Should use provided contentType + "Content-Length": "12", // file.size + }); + }); + + it("should handle File with intrinsic properties", async () => { + const file = new File(["file content"], "test.json", { type: "application/json" }); + const input: Uploadable.WithMetadata = { + data: file, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(file); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test.json"', // Should use file's name + "Content-Type": "application/json", // Should use file's type + "Content-Length": "12", // file.size + }); + }); + + it("should handle File passed directly", async () => { + const file = new File(["file content"], "direct.txt", { type: "text/plain" }); + + const result = await toBinaryUploadRequest(file); + + expect(result.body).toBe(file); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="direct.txt"', + "Content-Type": "text/plain", + "Content-Length": "12", // file.size + }); + }); + }); + + describe("ReadableStream input", () => { + it("should handle ReadableStream with metadata", async () => { + const stream = new ReadableStream({ + start(controller) { + controller.enqueue(new TextEncoder().encode("stream data")); + controller.close(); + }, + }); + const input: Uploadable.WithMetadata = { + data: stream, + filename: "stream.txt", + contentType: "text/plain", + contentLength: 100, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(stream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="stream.txt"', + "Content-Type": "text/plain", + "Content-Length": "100", // Should use provided contentLength + }); + }); + + it("should handle ReadableStream without size", async () => { + const stream = new ReadableStream({ + start(controller) { + controller.enqueue(new TextEncoder().encode("stream data")); + controller.close(); + }, + }); + const input: Uploadable.WithMetadata = { + data: stream, + filename: "stream.txt", + contentType: "text/plain", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(stream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="stream.txt"', + "Content-Type": "text/plain", + // No Content-Length header since it cannot be determined from ReadableStream + }); + }); + + it("should handle ReadableStream passed directly", async () => { + const stream = new ReadableStream({ + start(controller) { + controller.enqueue(new TextEncoder().encode("stream data")); + controller.close(); + }, + }); + + const result = await toBinaryUploadRequest(stream); + + expect(result.body).toBe(stream); + expect(result.headers).toEqual({ + // No headers since no metadata provided and cannot be determined + }); + }); + }); + + describe("Node.js Readable stream input", () => { + it("should handle Readable stream with metadata", async () => { + const readable = new Readable({ + read() { + this.push("readable data"); + this.push(null); + }, + }); + const input: Uploadable.WithMetadata = { + data: readable, + filename: "readable.txt", + contentType: "text/plain", + contentLength: 50, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(readable); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="readable.txt"', + "Content-Type": "text/plain", + "Content-Length": "50", // Should use provided contentLength + }); + }); + + it("should handle Readable stream without size", async () => { + const readable = new Readable({ + read() { + this.push("readable data"); + this.push(null); + }, + }); + const input: Uploadable.WithMetadata = { + data: readable, + filename: "readable.txt", + contentType: "text/plain", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(readable); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="readable.txt"', + "Content-Type": "text/plain", + // No Content-Length header since it cannot be determined from Readable + }); + }); + + it("should handle Readable stream passed directly", async () => { + const readable = new Readable({ + read() { + this.push("readable data"); + this.push(null); + }, + }); + + const result = await toBinaryUploadRequest(readable); + + expect(result.body).toBe(readable); + expect(result.headers).toEqual({ + // No headers since no metadata provided and cannot be determined + }); + }); + }); + + describe("File path input (FromPath type)", () => { + it("should handle file path with all metadata", async () => { + const input: Uploadable.FromPath = { + path: TEST_FILE_PATH, + filename: "custom.txt", + contentType: "text/html", + contentLength: 42, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBeInstanceOf(fs.ReadStream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="custom.txt"', + "Content-Type": "text/html", + "Content-Length": "42", // Should use provided contentLength + }); + }); + + it("should handle file path with minimal metadata", async () => { + const input: Uploadable.FromPath = { + path: TEST_FILE_PATH, + contentType: "text/plain", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBeInstanceOf(fs.ReadStream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test-file.txt"', // Should extract from path + "Content-Type": "text/plain", + "Content-Length": "21", // Should determine from file system (test file is 21 bytes) + }); + }); + + it("should handle file path with no metadata", async () => { + const input: Uploadable.FromPath = { + path: TEST_FILE_PATH, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBeInstanceOf(fs.ReadStream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test-file.txt"', // Should extract from path + "Content-Length": "21", // Should determine from file system (test file is 21 bytes) + }); + }); + + it("should handle Windows-style paths", async () => { + const input: Uploadable.FromPath = { + path: "C:\\Users\\test\\file.txt", + }; + + // Mock fs methods to avoid actual file system access + const mockStats = { size: 123 }; + const mockReadStream = {} as fs.ReadStream; + + const createReadStreamSpy = jest.spyOn(fs, "createReadStream").mockReturnValue(mockReadStream); + const statSpy = jest.spyOn(fs.promises, "stat").mockResolvedValue(mockStats as fs.Stats); + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(mockReadStream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="file.txt"', // Should extract from Windows path + "Content-Length": "123", + }); + + // Restore mocks + createReadStreamSpy.mockRestore(); + statSpy.mockRestore(); + }); + + it("should handle file path when fs is not available", async () => { + const input: Uploadable.FromPath = { + path: TEST_FILE_PATH, + }; + + // Mock import to simulate environment without fs + const originalImport = jest.requireActual("fs"); + jest.doMock("fs", () => null); + + await expect(toBinaryUploadRequest(input)).rejects.toThrow( + "File path uploads are not supported in this environment.", + ); + + // Restore fs + jest.doMock("fs", () => originalImport); + }); + }); + + describe("ArrayBufferView input", () => { + it("should handle ArrayBufferView with metadata", async () => { + const arrayBuffer = new ArrayBuffer(10); + const arrayBufferView = new Int8Array(arrayBuffer); + const input: Uploadable.WithMetadata = { + data: arrayBufferView, + filename: "view.bin", + contentType: "application/octet-stream", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(arrayBufferView); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="view.bin"', + "Content-Type": "application/octet-stream", + "Content-Length": "10", // arrayBufferView.byteLength + }); + }); + + it("should handle ArrayBufferView passed directly", async () => { + const arrayBuffer = new ArrayBuffer(10); + const arrayBufferView = new Int8Array(arrayBuffer); + + const result = await toBinaryUploadRequest(arrayBufferView); + + expect(result.body).toBe(arrayBufferView); + expect(result.headers).toEqual({ + "Content-Length": "10", // arrayBufferView.byteLength + }); + }); + }); + + describe("Edge cases", () => { + it("should handle empty headers when no metadata is available", async () => { + const buffer = Buffer.from(""); + const input: Uploadable.WithMetadata = { + data: buffer, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Length": "0", + }); + }); + + it("should handle zero contentLength", async () => { + const buffer = Buffer.from("test"); + const input: Uploadable.WithMetadata = { + data: buffer, + contentLength: 0, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Length": "0", // Should use provided 0 + }); + }); + + it("should handle null filename", async () => { + const buffer = Buffer.from("test"); + const input: Uploadable.WithMetadata = { + data: buffer, + filename: undefined, + contentType: "text/plain", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Type": "text/plain", + "Content-Length": "4", + // No Content-Disposition since filename is undefined + }); + }); + + it("should handle null contentType", async () => { + const buffer = Buffer.from("test"); + const input: Uploadable.WithMetadata = { + data: buffer, + filename: "test.txt", + contentType: undefined, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test.txt"', + "Content-Length": "4", + // No Content-Type since contentType is undefined + }); + }); + }); +}); diff --git a/tests/unit/file/test-file.txt b/tests/unit/file/test-file.txt new file mode 100644 index 00000000..c66d471e --- /dev/null +++ b/tests/unit/file/test-file.txt @@ -0,0 +1 @@ +This is a test file! diff --git a/tests/unit/live-client-connection-state.test.ts b/tests/unit/live-client-connection-state.test.ts deleted file mode 100644 index 78bf9a5d..00000000 --- a/tests/unit/live-client-connection-state.test.ts +++ /dev/null @@ -1,369 +0,0 @@ -import { ListenLiveClient } from "../../src/packages/ListenLiveClient"; -import { SpeakLiveClient } from "../../src/packages/SpeakLiveClient"; -import { AgentLiveClient } from "../../src/packages/AgentLiveClient"; -import { CONNECTION_STATE, SOCKET_STATES } from "../../src/lib/constants"; -import { LiveTranscriptionEvents } from "../../src/lib/enums/LiveTranscriptionEvents"; - -describe("Unit Tests - Live Client Connection State", () => { - describe("Connection State Management", () => { - let client: ListenLiveClient; - let mockConnection: any; - - beforeEach(() => { - // Mock the connection object - mockConnection = { - readyState: SOCKET_STATES.connecting, - send: jest.fn(), - close: jest.fn(), - onopen: null, - onclose: null, - onerror: null, - onmessage: null, - }; - - // Create a mock WebSocket constructor - const MockWebSocket = jest.fn().mockImplementation(() => mockConnection); - - // Create client with mocked transport - client = new ListenLiveClient({ - key: "test-key", - global: { - websocket: { - // @ts-expect-error - bypassing TypeScript for testing - client: MockWebSocket, - }, - }, - }); - }); - - afterEach(() => { - if (client) { - client.disconnect(); - } - }); - - it("should report correct connection state during lifecycle", () => { - // Initially connecting - expect(client.connectionState()).toBe(CONNECTION_STATE.Connecting); - - // Simulate connection open - mockConnection.readyState = SOCKET_STATES.open; - expect(client.connectionState()).toBe(CONNECTION_STATE.Open); - - // Simulate connection closing - mockConnection.readyState = SOCKET_STATES.closing; - expect(client.connectionState()).toBe(CONNECTION_STATE.Closing); - - // Simulate connection closed - mockConnection.readyState = SOCKET_STATES.closed; - expect(client.connectionState()).toBe(CONNECTION_STATE.Closed); - }); - - it("should correctly report if connected", () => { - // Not connected initially - expect(client.isConnected()).toBe(false); - - // Connected when open - mockConnection.readyState = SOCKET_STATES.open; - expect(client.isConnected()).toBe(true); - - // Not connected when closing - mockConnection.readyState = SOCKET_STATES.closing; - expect(client.isConnected()).toBe(false); - }); - - it("should provide ready state access", () => { - mockConnection.readyState = SOCKET_STATES.open; - expect(client.getReadyState()).toBe(SOCKET_STATES.open); - - mockConnection.readyState = SOCKET_STATES.closed; - expect(client.getReadyState()).toBe(SOCKET_STATES.closed); - }); - - it("should handle disconnection properly", () => { - mockConnection.readyState = SOCKET_STATES.open; - - client.disconnect(); - - expect(mockConnection.close).toHaveBeenCalled(); - }); - - it("should handle disconnection with code and reason", () => { - mockConnection.readyState = SOCKET_STATES.open; - - client.disconnect(1000, "Test closure"); - - expect(mockConnection.close).toHaveBeenCalledWith(1000, "Test closure"); - }); - - it("should have reconnect function available", () => { - expect(typeof client.reconnect).toBe("function"); - }); - }); - - describe("ListenLiveClient Specific Functionality", () => { - let client: ListenLiveClient; - let mockConnection: any; - - beforeEach(() => { - mockConnection = { - readyState: SOCKET_STATES.open, - send: jest.fn(), - close: jest.fn(), - onopen: null, - onclose: null, - onerror: null, - onmessage: null, - }; - - const MockWebSocket = jest.fn().mockImplementation(() => mockConnection); - - client = new ListenLiveClient({ - key: "test-key", - global: { - websocket: { - // @ts-expect-error - bypassing TypeScript for testing - client: MockWebSocket, - }, - }, - }); - }); - - afterEach(() => { - client.disconnect(); - }); - - it("should send audio data correctly", () => { - const audioData = new ArrayBuffer(1024); - client.send(audioData); - - expect(mockConnection.send).toHaveBeenCalledWith(audioData); - }); - - it("should send string data correctly", () => { - const textData = "test message"; - client.send(textData); - - expect(mockConnection.send).toHaveBeenCalledWith(textData); - }); - - it("should buffer messages when not connected", () => { - mockConnection.readyState = SOCKET_STATES.connecting; - - const audioData = new ArrayBuffer(512); - client.send(audioData); - - // Should not send immediately when not connected - expect(mockConnection.send).not.toHaveBeenCalled(); - }); - - it("should send keepAlive messages", () => { - client.keepAlive(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "KeepAlive" })); - }); - - it("should send close stream requests", () => { - client.requestClose(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "CloseStream" })); - }); - - it("should use finish method (deprecated)", () => { - client.finish(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "CloseStream" })); - }); - }); - - describe("SpeakLiveClient Specific Functionality", () => { - let client: SpeakLiveClient; - let mockConnection: any; - - beforeEach(() => { - mockConnection = { - readyState: SOCKET_STATES.open, - send: jest.fn(), - close: jest.fn(), - onopen: null, - onclose: null, - onerror: null, - onmessage: null, - }; - - const MockWebSocket = jest.fn().mockImplementation(() => mockConnection); - - client = new SpeakLiveClient({ - key: "test-key", - global: { - websocket: { - // @ts-expect-error - bypassing TypeScript for testing - client: MockWebSocket, - }, - }, - }); - }); - - afterEach(() => { - client.disconnect(); - }); - - it("should send text for TTS synthesis", () => { - const text = "Hello, this is a test."; - client.sendText(text); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "Speak", text })); - }); - - it("should send flush commands", () => { - client.flush(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "Flush" })); - }); - - it("should send clear commands", () => { - client.clear(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "Clear" })); - }); - - it("should send close requests", () => { - client.requestClose(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "Close" })); - }); - }); - - describe("AgentLiveClient Specific Functionality", () => { - let client: AgentLiveClient; - let mockConnection: any; - - beforeEach(() => { - mockConnection = { - readyState: SOCKET_STATES.open, - send: jest.fn(), - close: jest.fn(), - onopen: null, - onclose: null, - onerror: null, - onmessage: null, - }; - - const MockWebSocket = jest.fn().mockImplementation(() => mockConnection); - - client = new AgentLiveClient({ - key: "test-key", - global: { - websocket: { - // @ts-expect-error - bypassing TypeScript for testing - client: MockWebSocket, - }, - }, - }); - }); - - afterEach(() => { - client.disconnect(); - }); - - it("should send keepAlive messages", () => { - client.keepAlive(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "KeepAlive" })); - }); - - it("should send audio data", () => { - const audioData = new ArrayBuffer(1024); - client.send(audioData); - - expect(mockConnection.send).toHaveBeenCalledWith(audioData); - }); - - it("should handle namespace correctly", () => { - expect(client.namespace).toBe("agent"); - }); - }); - - describe("Error Handling", () => { - let client: ListenLiveClient; - let mockConnection: any; - - beforeEach(() => { - mockConnection = { - readyState: SOCKET_STATES.open, - send: jest.fn(), - close: jest.fn(), - onopen: null, - onclose: null, - onerror: null, - onmessage: null, - }; - - const MockWebSocket = jest.fn().mockImplementation(() => mockConnection); - - client = new ListenLiveClient({ - key: "test-key", - global: { - websocket: { - // @ts-expect-error - bypassing TypeScript for testing - client: MockWebSocket, - }, - }, - }); - - client.setupConnection(); - }); - - afterEach(() => { - client.disconnect(); - }); - - it("should handle empty blob data gracefully", async () => { - const logSpy = jest.spyOn(client as any, "log").mockImplementation(); - - const emptyBlob = new Blob([]); - client.send(emptyBlob); - - // Wait for async blob processing - await new Promise((resolve) => setTimeout(resolve, 0)); - - expect(logSpy).toHaveBeenCalledWith("warn", "skipping `send` for zero-byte blob", emptyBlob); - expect(mockConnection.send).not.toHaveBeenCalled(); - - logSpy.mockRestore(); - }); - - it("should handle zero-byte ArrayBuffer gracefully", () => { - const logSpy = jest.spyOn(client as any, "log").mockImplementation(); - - const emptyBuffer = new ArrayBuffer(0); - client.send(emptyBuffer); - - expect(logSpy).toHaveBeenCalledWith( - "warn", - "skipping `send` for zero-byte payload", - emptyBuffer - ); - expect(mockConnection.send).not.toHaveBeenCalled(); - - logSpy.mockRestore(); - }); - - it("should handle connection errors gracefully", () => { - const errorSpy = jest.fn(); - client.on(LiveTranscriptionEvents.Error, errorSpy); - - const errorEvent = { type: "error", message: "Connection failed" }; - mockConnection.onerror(errorEvent); - - expect(errorSpy).toHaveBeenCalledWith( - expect.objectContaining({ - type: "error", - message: expect.stringContaining("Connection failed"), - error: expect.any(Object), - readyState: expect.any(Number), - }) - ); - }); - }); -}); diff --git a/tests/unit/live-client-message-handling.test.ts b/tests/unit/live-client-message-handling.test.ts deleted file mode 100644 index a6af8b95..00000000 --- a/tests/unit/live-client-message-handling.test.ts +++ /dev/null @@ -1,686 +0,0 @@ -import { ListenLiveClient } from "../../src/packages/ListenLiveClient"; -import { SpeakLiveClient } from "../../src/packages/SpeakLiveClient"; -import { AgentLiveClient } from "../../src/packages/AgentLiveClient"; -import { LiveTranscriptionEvents } from "../../src/lib/enums/LiveTranscriptionEvents"; -import { LiveTTSEvents } from "../../src/lib/enums/LiveTTSEvents"; -import { AgentEvents } from "../../src/lib/enums/AgentEvents"; -import { SOCKET_STATES } from "../../src/lib/constants"; - -describe("Unit Tests - Live Client Message Handling", () => { - describe("ListenLiveClient Message Handling", () => { - let client: ListenLiveClient; - let mockConnection: any; - - beforeEach(() => { - // Mock the connection object - mockConnection = { - readyState: SOCKET_STATES.open, - send: jest.fn(), - close: jest.fn(), - onopen: null, - onclose: null, - onerror: null, - onmessage: null, - }; - - // Create a mock WebSocket constructor - const MockWebSocket = jest.fn().mockImplementation(() => mockConnection); - - // Create client with minimal options - client = new ListenLiveClient({ - key: "test-key", - global: { - websocket: { - client: MockWebSocket as any, // Use custom transport to avoid real connections - }, - }, - }); - - // The constructor already calls connect, so just setup the connection - client.setupConnection(); - }); - - it("should emit Open event when connection opens", () => { - const openSpy = jest.fn(); - client.on(LiveTranscriptionEvents.Open, openSpy); - - // Simulate connection open - mockConnection.onopen(); - - expect(openSpy).toHaveBeenCalledWith(client); - }); - - it("should emit Close event when connection closes", () => { - const closeSpy = jest.fn(); - const closeEvent = { code: 1000, reason: "Normal closure" }; - client.on(LiveTranscriptionEvents.Close, closeSpy); - - // Simulate connection close - mockConnection.onclose(closeEvent); - - expect(closeSpy).toHaveBeenCalledWith(closeEvent); - }); - - it("should emit Error event when connection errors", () => { - const errorSpy = jest.fn(); - const errorEvent = { type: "error", message: "Connection failed" }; - client.on(LiveTranscriptionEvents.Error, errorSpy); - - // Simulate connection error - mockConnection.onerror(errorEvent); - - expect(errorSpy).toHaveBeenCalledWith( - expect.objectContaining({ - type: "error", - message: expect.stringContaining("Connection failed"), - error: expect.any(Object), - readyState: expect.any(Number), - }) - ); - }); - - it("should handle Transcript messages correctly", () => { - const transcriptSpy = jest.fn(); - client.on(LiveTranscriptionEvents.Transcript, transcriptSpy); - - const transcriptData = { - type: "Results", - channel_index: [0, 1], - duration: 2.5, - start: 0.0, - is_final: true, - channel: { - alternatives: [ - { - transcript: "Hello world", - confidence: 0.95, - words: [ - { word: "Hello", start: 0.0, end: 0.5, confidence: 0.95 }, - { word: "world", start: 0.6, end: 1.0, confidence: 0.94 }, - ], - }, - ], - }, - }; - - // Simulate receiving transcript message - const messageEvent = { data: JSON.stringify(transcriptData) }; - mockConnection.onmessage(messageEvent); - - expect(transcriptSpy).toHaveBeenCalledWith(transcriptData); - }); - - it("should handle Metadata messages correctly", () => { - const metadataSpy = jest.fn(); - client.on(LiveTranscriptionEvents.Metadata, metadataSpy); - - const metadataData = { - type: "Metadata", - transaction_key: "deprecated", - request_id: "550e8400-e29b-41d4-a716-446655440002", - sha256: "abc123", - created: "2024-01-15T10:30:00Z", - duration: 120.5, - channels: 1, - }; - - // Simulate receiving metadata message - const messageEvent = { data: JSON.stringify(metadataData) }; - mockConnection.onmessage(messageEvent); - - expect(metadataSpy).toHaveBeenCalledWith(metadataData); - }); - - it("should handle UtteranceEnd messages correctly", () => { - const utteranceEndSpy = jest.fn(); - client.on(LiveTranscriptionEvents.UtteranceEnd, utteranceEndSpy); - - const utteranceEndData = { - type: "UtteranceEnd", - channel: [0], - last_word_end: 2.5, - }; - - // Simulate receiving utterance end message - const messageEvent = { data: JSON.stringify(utteranceEndData) }; - mockConnection.onmessage(messageEvent); - - expect(utteranceEndSpy).toHaveBeenCalledWith(utteranceEndData); - }); - - it("should handle SpeechStarted messages correctly", () => { - const speechStartedSpy = jest.fn(); - client.on(LiveTranscriptionEvents.SpeechStarted, speechStartedSpy); - - const speechStartedData = { - type: "SpeechStarted", - channel: [0], - timestamp: 1.2, - }; - - // Simulate receiving speech started message - const messageEvent = { data: JSON.stringify(speechStartedData) }; - mockConnection.onmessage(messageEvent); - - expect(speechStartedSpy).toHaveBeenCalledWith(speechStartedData); - }); - - it("should emit Unhandled event for unknown message types", () => { - const unhandledSpy = jest.fn(); - client.on(LiveTranscriptionEvents.Unhandled, unhandledSpy); - - const unknownData = { - type: "UnknownMessageType", - data: "some data", - }; - - // Simulate receiving unknown message - const messageEvent = { data: JSON.stringify(unknownData) }; - mockConnection.onmessage(messageEvent); - - expect(unhandledSpy).toHaveBeenCalledWith(unknownData); - }); - - it("should emit Error event for malformed JSON messages", () => { - const errorSpy = jest.fn(); - client.on(LiveTranscriptionEvents.Error, errorSpy); - - // Simulate receiving malformed JSON - const messageEvent = { data: "invalid json {" }; - mockConnection.onmessage(messageEvent); - - expect(errorSpy).toHaveBeenCalledWith( - expect.objectContaining({ - event: messageEvent, - message: "Unable to parse `data` as JSON.", - error: expect.any(Error), - }) - ); - }); - - it("should send keepAlive message correctly", () => { - client.keepAlive(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "KeepAlive" })); - }); - - it("should send requestClose message correctly", () => { - client.requestClose(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "CloseStream" })); - }); - }); - - describe("SpeakLiveClient Message Handling", () => { - let client: SpeakLiveClient; - let mockConnection: any; - - beforeEach(() => { - // Mock the connection object - mockConnection = { - readyState: SOCKET_STATES.open, - send: jest.fn(), - close: jest.fn(), - onopen: null, - onclose: null, - onerror: null, - onmessage: null, - }; - - // Create a mock WebSocket constructor - const MockWebSocket = jest.fn().mockImplementation(() => mockConnection); - - // Create client with minimal options - client = new SpeakLiveClient({ - key: "test-key", - global: { - websocket: { - client: MockWebSocket as any, // Use custom transport to avoid real connections - }, - }, - }); - - // The constructor already calls connect, so just setup the connection - client.setupConnection(); - }); - - it("should emit Open event when connection opens", () => { - const openSpy = jest.fn(); - client.on(LiveTTSEvents.Open, openSpy); - - // Simulate connection open - mockConnection.onopen(); - - expect(openSpy).toHaveBeenCalledWith(client); - }); - - it("should handle Metadata messages correctly", () => { - const metadataSpy = jest.fn(); - client.on(LiveTTSEvents.Metadata, metadataSpy); - - const metadataData = { - type: "Metadata", - request_id: "550e8400-e29b-41d4-a716-446655440003", - model_name: "aura-asteria-en", - model_uuid: "c0e51fb0-7b76-42f0-b8c0-8ad7a14fb5b5", - char_count: 25, - transfer_encoding: "chunked", - date: "Thu, 15 Aug 2024 17:22:02 GMT", - }; - - // Simulate receiving metadata message - const messageEvent = { data: JSON.stringify(metadataData) }; - mockConnection.onmessage(messageEvent); - - expect(metadataSpy).toHaveBeenCalledWith(metadataData); - }); - - it("should handle Flushed messages correctly", () => { - const flushedSpy = jest.fn(); - client.on(LiveTTSEvents.Flushed, flushedSpy); - - const flushedData = { - type: "Flushed", - }; - - // Simulate receiving flushed message - const messageEvent = { data: JSON.stringify(flushedData) }; - mockConnection.onmessage(messageEvent); - - expect(flushedSpy).toHaveBeenCalledWith(flushedData); - }); - - it("should handle Warning messages correctly", () => { - const warningSpy = jest.fn(); - client.on(LiveTTSEvents.Warning, warningSpy); - - const warningData = { - type: "Warning", - warn_code: "W001", - warn_msg: "Sample warning message", - }; - - // Simulate receiving warning message - const messageEvent = { data: JSON.stringify(warningData) }; - mockConnection.onmessage(messageEvent); - - expect(warningSpy).toHaveBeenCalledWith(warningData); - }); - - it("should handle binary audio data correctly", () => { - const audioSpy = jest.fn(); - client.on(LiveTTSEvents.Audio, audioSpy); - - const audioBuffer = new ArrayBuffer(1024); - const messageEvent = { data: audioBuffer }; - mockConnection.onmessage(messageEvent); - - expect(audioSpy).toHaveBeenCalledWith(Buffer.from(audioBuffer)); - }); - - it("should handle Blob audio data correctly", () => { - const audioSpy = jest.fn(); - client.on(LiveTTSEvents.Audio, audioSpy); - - const audioData = new Uint8Array([1, 2, 3, 4]); - const blob = new Blob([audioData]); - - // Mock blob.arrayBuffer() - blob.arrayBuffer = jest.fn().mockResolvedValue(audioData.buffer); - - const messageEvent = { data: blob }; - mockConnection.onmessage(messageEvent); - - // Wait for async arrayBuffer processing - return new Promise((resolve) => { - setTimeout(() => { - expect(audioSpy).toHaveBeenCalledWith(Buffer.from(audioData.buffer)); - resolve(undefined); - }, 0); - }); - }); - - it("should emit Unhandled event for unknown message types", () => { - const unhandledSpy = jest.fn(); - client.on(LiveTTSEvents.Unhandled, unhandledSpy); - - const unknownData = { - type: "UnknownMessageType", - data: "some data", - }; - - // Simulate receiving unknown message - const messageEvent = { data: JSON.stringify(unknownData) }; - mockConnection.onmessage(messageEvent); - - expect(unhandledSpy).toHaveBeenCalledWith(unknownData); - }); - - it("should send text correctly", () => { - const text = "Hello, this is a test message."; - client.sendText(text); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "Speak", text })); - }); - - it("should send flush correctly", () => { - client.flush(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "Flush" })); - }); - }); - - describe("AgentLiveClient Message Handling", () => { - let client: AgentLiveClient; - let mockConnection: any; - - beforeEach(() => { - // Mock the connection object - mockConnection = { - readyState: SOCKET_STATES.open, - send: jest.fn(), - close: jest.fn(), - onopen: null, - onclose: null, - onerror: null, - onmessage: null, - }; - - // Create a mock WebSocket constructor - const MockWebSocket = jest.fn().mockImplementation(() => mockConnection); - - // Create client with minimal options - client = new AgentLiveClient({ - key: "test-key", - global: { - websocket: { - client: MockWebSocket as any, // Use custom transport to avoid real connections - }, - }, - }); - - // The constructor already calls connect, so just setup the connection - client.setupConnection(); - }); - - it("should emit Open event when connection opens", () => { - const openSpy = jest.fn(); - client.on(AgentEvents.Open, openSpy); - - // Simulate connection open - mockConnection.onopen(); - - expect(openSpy).toHaveBeenCalledWith(client); - }); - - it("should handle Welcome messages correctly", () => { - const welcomeSpy = jest.fn(); - client.on(AgentEvents.Welcome, welcomeSpy); - - const welcomeData = { - type: "Welcome", - request_id: "550e8400-e29b-41d4-a716-446655440004", - }; - - // Simulate receiving welcome message - const messageEvent = { data: JSON.stringify(welcomeData) }; - mockConnection.onmessage(messageEvent); - - expect(welcomeSpy).toHaveBeenCalledWith(welcomeData); - }); - - it("should handle ConversationText messages correctly", () => { - const conversationTextSpy = jest.fn(); - client.on(AgentEvents.ConversationText, conversationTextSpy); - - const conversationTextData = { - type: "ConversationText", - role: "user", - content: "Hello, how are you?", - }; - - // Simulate receiving conversation text message - const messageEvent = { data: JSON.stringify(conversationTextData) }; - mockConnection.onmessage(messageEvent); - - expect(conversationTextSpy).toHaveBeenCalledWith(conversationTextData); - }); - - it("should handle FunctionCallRequest messages correctly", () => { - const functionCallSpy = jest.fn(); - client.on(AgentEvents.FunctionCallRequest, functionCallSpy); - - const functionCallData = { - type: "FunctionCallRequest", - functions: [ - { - id: "function-1", - name: "get_weather", - arguments: '{"location": "New York"}', - client_side: true, - }, - ], - }; - - // Simulate receiving function call request - const messageEvent = { data: JSON.stringify(functionCallData) }; - mockConnection.onmessage(messageEvent); - - expect(functionCallSpy).toHaveBeenCalledWith(functionCallData); - }); - - it("should handle AgentStartedSpeaking messages correctly", () => { - const agentStartedSpy = jest.fn(); - client.on(AgentEvents.AgentStartedSpeaking, agentStartedSpy); - - const agentStartedData = { - type: "AgentStartedSpeaking", - total_latency: 250, - tts_latency: 100, - ttt_latency: 150, - }; - - // Simulate receiving agent started speaking message - const messageEvent = { data: JSON.stringify(agentStartedData) }; - mockConnection.onmessage(messageEvent); - - expect(agentStartedSpy).toHaveBeenCalledWith(agentStartedData); - }); - - it("should handle binary audio data correctly", () => { - const audioSpy = jest.fn(); - client.on(AgentEvents.Audio, audioSpy); - - const audioBuffer = new ArrayBuffer(2048); - const messageEvent = { data: audioBuffer }; - mockConnection.onmessage(messageEvent); - - expect(audioSpy).toHaveBeenCalledWith(Buffer.from(audioBuffer)); - }); - - it("should emit Unhandled event for unknown message types", () => { - const unhandledSpy = jest.fn(); - client.on(AgentEvents.Unhandled, unhandledSpy); - - const unknownData = { - type: "UnknownMessageType", - data: "some data", - }; - - // Simulate receiving unknown message - const messageEvent = { data: JSON.stringify(unknownData) }; - mockConnection.onmessage(messageEvent); - - expect(unhandledSpy).toHaveBeenCalledWith(unknownData); - }); - - it("should handle messages with unknown data types correctly", () => { - const errorSpy = jest.fn(); - client.on(AgentEvents.Error, errorSpy); - - // Simulate receiving message with unknown data type - const unknownDataType = { some: "weird data type" }; - const messageEvent = { data: unknownDataType }; - mockConnection.onmessage(messageEvent); - - expect(errorSpy).toHaveBeenCalledWith( - expect.objectContaining({ - event: messageEvent, - message: "Received unknown data type.", - }) - ); - }); - - it("should send keepAlive message correctly", () => { - client.keepAlive(); - - expect(mockConnection.send).toHaveBeenCalledWith(JSON.stringify({ type: "KeepAlive" })); - }); - - describe("speak provider configuration", () => { - it("should accept single provider", () => { - const config = { - audio: { input: { encoding: "linear16", sample_rate: 16000 } }, - agent: { - speak: { - provider: { type: "deepgram", model: "aura-2-zeus-en" }, - }, - }, - }; - - client.configure(config); - expect(mockConnection.send).toHaveBeenCalledWith( - JSON.stringify({ type: "Settings", ...config }) - ); - }); - - it("should accept array of providers", () => { - const config = { - audio: { input: { encoding: "linear16", sample_rate: 16000 } }, - agent: { - speak: [ - { provider: { type: "deepgram", model: "aura-2-zeus-en" } }, - { - provider: { type: "openai", model: "tts-1", voice: "shimmer" }, - endpoint: { url: "https://api.openai.com/v1/audio/speech", headers: { auth: "key" } } - }, - ], - }, - }; - - client.configure(config); - expect(mockConnection.send).toHaveBeenCalledWith( - JSON.stringify({ type: "Settings", ...config }) - ); - }); - }); - - describe("mips_opt_out configuration", () => { - it("should accept mips_opt_out as true", () => { - const config = { - audio: { input: { encoding: "linear16", sample_rate: 16000 } }, - mips_opt_out: true, - agent: { - language: "en", - speak: { - provider: { type: "deepgram", model: "aura-2-zeus-en" }, - }, - }, - }; - - client.configure(config); - expect(mockConnection.send).toHaveBeenCalledWith( - JSON.stringify({ type: "Settings", ...config }) - ); - }); - - it("should accept mips_opt_out as false", () => { - const config = { - audio: { input: { encoding: "linear16", sample_rate: 16000 } }, - mips_opt_out: false, - agent: { - language: "en", - speak: { - provider: { type: "deepgram", model: "aura-2-zeus-en" }, - }, - }, - }; - - client.configure(config); - expect(mockConnection.send).toHaveBeenCalledWith( - JSON.stringify({ type: "Settings", ...config }) - ); - }); - - it("should work without mips_opt_out (default behavior)", () => { - const config = { - audio: { input: { encoding: "linear16", sample_rate: 16000 } }, - agent: { - language: "en", - speak: { - provider: { type: "deepgram", model: "aura-2-zeus-en" }, - }, - }, - }; - - client.configure(config); - expect(mockConnection.send).toHaveBeenCalledWith( - JSON.stringify({ type: "Settings", ...config }) - ); - }); - }); - - describe("updateSpeak method", () => { - it("should update with single provider", () => { - const provider = { provider: { type: "deepgram", model: "aura-2-zeus-en" } }; - - client.updateSpeak(provider); - expect(mockConnection.send).toHaveBeenCalledWith( - JSON.stringify({ type: "UpdateSpeak", speak: provider }) - ); - }); - - it("should update with array of providers", () => { - const providers = [ - { provider: { type: "deepgram", model: "aura-2-zeus-en" } }, - { provider: { type: "openai", model: "tts-1", voice: "shimmer" } }, - ]; - - client.updateSpeak(providers); - expect(mockConnection.send).toHaveBeenCalledWith( - JSON.stringify({ type: "UpdateSpeak", speak: providers }) - ); - }); - }); - - describe("injectUserMessage method", () => { - it("should send injectUserMessage correctly", () => { - const content = "Hello! Can you hear me?"; - client.injectUserMessage(content); - - expect(mockConnection.send).toHaveBeenCalledWith( - JSON.stringify({ type: "InjectUserMessage", content }) - ); - }); - - it("should send injectUserMessage with different content types", () => { - const testCases = [ - "What's the weather like today?", - "Simple greeting", - "Multi-line\nmessage content", - "", // Edge case: empty string - ]; - - testCases.forEach((content) => { - jest.clearAllMocks(); // Reset mock between test cases - - client.injectUserMessage(content); - - expect(mockConnection.send).toHaveBeenCalledWith( - JSON.stringify({ type: "InjectUserMessage", content }) - ); - }); - }); - }); - }); -}); diff --git a/tests/unit/object-utilities.test.ts b/tests/unit/object-utilities.test.ts deleted file mode 100644 index 8e8f3ebf..00000000 --- a/tests/unit/object-utilities.test.ts +++ /dev/null @@ -1,120 +0,0 @@ -import { applyDefaults, appendSearchParams } from "../../src/lib/helpers"; - -describe("Unit Tests - Object Manipulation Utilities", () => { - describe("applyDefaults", () => { - it("should merge options with defaults correctly", () => { - const defaults = { punctuate: true, smart_format: false, language: "en-US" }; - const options = { language: "es-ES", model: "nova-2" }; - - const result = applyDefaults(options, defaults) as any; - - // Options should override defaults - expect(result.language).toBe("es-ES"); - expect(result.model).toBe("nova-2"); - - // Defaults should be preserved when not overridden - expect(result.punctuate).toBe(true); - expect(result.smart_format).toBe(false); - }); - - it("should handle empty options", () => { - const defaults = { punctuate: true, smart_format: false }; - const result = applyDefaults({}, defaults); - - expect(result).toEqual(defaults); - }); - - it("should handle empty defaults", () => { - const options = { language: "en-US", model: "nova-2" }; - const result = applyDefaults(options, {}); - - expect(result).toEqual(options); - }); - - it("should handle nested objects", () => { - const defaults = { - nested: { deep: "default", other: "property" }, - simple: "value", - }; - const options = { - nested: { deep: "override" }, - new: "property", - }; - - const result = applyDefaults(options, defaults) as any; - - expect(result.nested.deep).toBe("override"); - expect(result.nested.other).toBe("property"); - expect(result.simple).toBe("value"); - expect(result.new).toBe("property"); - }); - - it("should handle undefined inputs", () => { - const defaults = { punctuate: true }; - - const result1 = applyDefaults(undefined, defaults); - expect(result1).toEqual(defaults); - - const result2 = applyDefaults({ language: "en" }, undefined); - expect(result2).toEqual({ language: "en" }); - }); - }); - - describe("appendSearchParams", () => { - it("should handle string parameters", () => { - const searchParams = new URLSearchParams(); - appendSearchParams(searchParams, { language: "en-US", model: "nova-2" }); - - expect(searchParams.get("language")).toBe("en-US"); - expect(searchParams.get("model")).toBe("nova-2"); - }); - - it("should handle boolean parameters", () => { - const searchParams = new URLSearchParams(); - appendSearchParams(searchParams, { punctuate: true, smart_format: false }); - - expect(searchParams.get("punctuate")).toBe("true"); - expect(searchParams.get("smart_format")).toBe("false"); - }); - - it("should handle number parameters", () => { - const searchParams = new URLSearchParams(); - appendSearchParams(searchParams, { confidence: 0.8, alternatives: 3 }); - - expect(searchParams.get("confidence")).toBe("0.8"); - expect(searchParams.get("alternatives")).toBe("3"); - }); - - it("should handle array parameters", () => { - const searchParams = new URLSearchParams(); - appendSearchParams(searchParams, { keywords: ["hello", "world", "test"] }); - - const keywords = searchParams.getAll("keywords"); - expect(keywords).toEqual(["hello", "world", "test"]); - }); - - it("should handle mixed parameter types", () => { - const searchParams = new URLSearchParams(); - const options = { - keywords: ["hello", "world"], - language: "en-US", - punctuate: true, - confidence: 0.9, - }; - - appendSearchParams(searchParams, options); - - expect(searchParams.getAll("keywords")).toEqual(["hello", "world"]); - expect(searchParams.get("language")).toBe("en-US"); - expect(searchParams.get("punctuate")).toBe("true"); - expect(searchParams.get("confidence")).toBe("0.9"); - }); - - it("should handle empty options", () => { - const searchParams = new URLSearchParams(); - appendSearchParams(searchParams, {}); - - expect(searchParams.toString()).toBe(""); - }); - }); -}); diff --git a/tests/unit/options-transformation.test.ts b/tests/unit/options-transformation.test.ts deleted file mode 100644 index c97306a2..00000000 --- a/tests/unit/options-transformation.test.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { convertLegacyOptions } from "../../src/lib/helpers"; - -describe("Unit Tests - Options Transformation Utilities", () => { - describe("convertLegacyOptions", () => { - it("should convert _experimentalCustomFetch to global.fetch.client", () => { - const customFetch = jest.fn(); - const options = { _experimentalCustomFetch: customFetch }; - - const result = convertLegacyOptions(options as any); - - expect(result.global?.fetch?.client).toBe(customFetch); - }); - - it("should convert restProxy.url to global.fetch.options.proxy.url", () => { - const options = { restProxy: { url: "https://proxy.example.com" } }; - - const result = convertLegacyOptions(options as any); - - expect(result.global?.fetch?.options?.proxy?.url).toBe("https://proxy.example.com"); - }); - - it("should convert global.url to both fetch and websocket options", () => { - const options = { global: { url: "https://custom-api.deepgram.com" } }; - - const result = convertLegacyOptions(options); - - expect(result.global?.fetch?.options?.url).toBe("https://custom-api.deepgram.com"); - expect(result.global?.websocket?.options?.url).toBe("https://custom-api.deepgram.com"); - }); - - it("should convert global.headers to both fetch and websocket options", () => { - const customHeaders = { "Custom-Header": "value", Another: "header" }; - const options = { global: { headers: customHeaders } }; - - const result = convertLegacyOptions(options); - - expect(result.global?.fetch?.options?.headers).toEqual(customHeaders); - expect(result.global?.websocket?.options?._nodeOnlyHeaders).toEqual(customHeaders); - }); - - it("should handle combined legacy options", () => { - const customFetch = jest.fn(); - const customHeaders = { "X-Custom": "header" }; - const options = { - _experimentalCustomFetch: customFetch, - restProxy: { url: "https://proxy.example.com" }, - global: { - url: "https://custom-api.deepgram.com", - headers: customHeaders, - }, - }; - - const result = convertLegacyOptions(options as any); - - // Should have all conversions - expect(result.global?.fetch?.client).toBe(customFetch); - expect(result.global?.fetch?.options?.proxy?.url).toBe("https://proxy.example.com"); - expect(result.global?.fetch?.options?.url).toBe("https://custom-api.deepgram.com"); - expect(result.global?.fetch?.options?.headers).toEqual(customHeaders); - expect(result.global?.websocket?.options?.url).toBe("https://custom-api.deepgram.com"); - expect(result.global?.websocket?.options?._nodeOnlyHeaders).toEqual(customHeaders); - }); - - it("should return empty object when no legacy options provided", () => { - const result = convertLegacyOptions({}); - - // Should have some structure from the merge operations - expect(typeof result).toBe("object"); - }); - - it("should preserve existing options", () => { - const existingOptions = { - global: { - fetch: { - options: { - url: "https://existing.com", - }, - }, - }, - }; - const options = { - ...existingOptions, - _experimentalCustomFetch: jest.fn(), - }; - - const result = convertLegacyOptions(options as any); - - // Should preserve existing URL while adding new fetch client - expect(result.global?.fetch?.options?.url).toBe("https://existing.com"); - expect(result.global?.fetch?.client).toBeDefined(); - }); - }); -}); diff --git a/tests/unit/string-utilities.test.ts b/tests/unit/string-utilities.test.ts deleted file mode 100644 index 65cf9614..00000000 --- a/tests/unit/string-utilities.test.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { stripTrailingSlash, convertProtocolToWs } from "../../src/lib/helpers"; - -describe("Unit Tests - String and URL Utilities", () => { - describe("stripTrailingSlash", () => { - it("should remove trailing slash from URLs", () => { - expect(stripTrailingSlash("https://api.deepgram.com/")).toBe("https://api.deepgram.com"); - expect(stripTrailingSlash("https://api.deepgram.com/v1/")).toBe( - "https://api.deepgram.com/v1" - ); - expect(stripTrailingSlash("path/")).toBe("path"); - expect(stripTrailingSlash("/")).toBe(""); - }); - - it("should not modify URLs without trailing slash", () => { - expect(stripTrailingSlash("https://api.deepgram.com")).toBe("https://api.deepgram.com"); - expect(stripTrailingSlash("https://api.deepgram.com/v1")).toBe("https://api.deepgram.com/v1"); - expect(stripTrailingSlash("path")).toBe("path"); - }); - - it("should handle empty string", () => { - expect(stripTrailingSlash("")).toBe(""); - }); - - it("should only remove one trailing slash", () => { - expect(stripTrailingSlash("https://api.deepgram.com//")).toBe("https://api.deepgram.com/"); - }); - }); - - describe("convertProtocolToWs", () => { - it("should convert HTTP to WebSocket protocols", () => { - expect(convertProtocolToWs("https://api.deepgram.com")).toBe("wss://api.deepgram.com"); - expect(convertProtocolToWs("http://api.deepgram.com")).toBe("ws://api.deepgram.com"); - }); - - it("should handle uppercase protocols", () => { - expect(convertProtocolToWs("HTTPS://API.DEEPGRAM.COM")).toBe("wss://api.deepgram.com"); - expect(convertProtocolToWs("HTTP://API.DEEPGRAM.COM")).toBe("ws://api.deepgram.com"); - }); - - it("should not modify WebSocket protocols", () => { - expect(convertProtocolToWs("wss://already-websocket.com")).toBe( - "wss://already-websocket.com" - ); - expect(convertProtocolToWs("ws://already-websocket.com")).toBe("ws://already-websocket.com"); - }); - - it("should handle mixed case protocols", () => { - expect(convertProtocolToWs("Http://example.com")).toBe("ws://example.com"); - expect(convertProtocolToWs("Https://example.com")).toBe("wss://example.com"); - }); - - it("should handle protocols without authority", () => { - expect(convertProtocolToWs("http:example")).toBe("ws:example"); - expect(convertProtocolToWs("https:example")).toBe("wss:example"); - }); - }); -}); diff --git a/tests/unit/type-guards.test.ts b/tests/unit/type-guards.test.ts deleted file mode 100644 index 91622ac8..00000000 --- a/tests/unit/type-guards.test.ts +++ /dev/null @@ -1,194 +0,0 @@ -import { - isUrlSource, - isTextSource, - isFileSource, - isLiveSchema, - isDeepgramClientOptions, -} from "../../src/lib/helpers"; -import { Readable } from "node:stream"; - -describe("Unit Tests - Type Guards and Validators", () => { - describe("isUrlSource", () => { - it("should identify URL sources correctly", () => { - // Valid URL sources - expect(isUrlSource({ url: "https://dpgr.am/spacewalk.wav" })).toBe(true); - expect(isUrlSource({ url: "file://local.wav" })).toBe(true); - expect(isUrlSource({ url: "" })).toBe(false); // Empty string should be false - - // Invalid sources - expect(isUrlSource({ text: "This is not a URL source" } as any)).toBe(false); - expect(isUrlSource({ buffer: Buffer.from("fake audio") } as any)).toBe(false); - expect(isUrlSource({ invalidProperty: "value" } as any)).toBe(false); - expect(isUrlSource({} as any)).toBe(false); - expect(isUrlSource(null as any)).toBe(false); - expect(isUrlSource(undefined as any)).toBe(false); - }); - }); - - describe("isTextSource", () => { - it("should identify text sources correctly", () => { - // Valid text sources - expect(isTextSource({ text: "This is a text source" })).toBe(true); - expect(isTextSource({ text: "Multi-line\ntext content" })).toBe(true); - - // Empty string should be falsy - expect(isTextSource({ text: "" })).toBe(false); - - // Invalid sources - expect(isTextSource({ url: "https://dpgr.am/spacewalk.wav" } as any)).toBe(false); - expect(isTextSource({ invalidProperty: "value" } as any)).toBe(false); - expect(isTextSource({} as any)).toBe(false); - expect(isTextSource(null as any)).toBe(false); - expect(isTextSource(undefined as any)).toBe(false); - }); - }); - - describe("isFileSource", () => { - it("should identify file sources correctly", () => { - const buffer = Buffer.from("fake audio data"); - const readable = new Readable({ - read() { - this.push("audio data"); - this.push(null); - }, - }); - - // Valid file sources - expect(isFileSource(buffer)).toBe(true); - expect(isFileSource(readable)).toBe(true); - - // Invalid sources - expect(isFileSource({ url: "https://dpgr.am/spacewalk.wav" } as any)).toBe(false); - expect(isFileSource({ text: "This is text" } as any)).toBe(false); - expect(isFileSource("string data" as any)).toBe(false); - expect(isFileSource({} as any)).toBe(false); - expect(isFileSource(null as any)).toBe(false); - expect(isFileSource(undefined as any)).toBe(false); - expect(isFileSource(123 as any)).toBe(false); - expect(isFileSource([] as any)).toBe(false); - }); - }); - - describe("isLiveSchema", () => { - it("should identify live schema correctly", () => { - // Valid live schemas - expect(isLiveSchema({ interim_results: true })).toBe(true); - expect(isLiveSchema({ interim_results: false })).toBe(true); - expect(isLiveSchema({ interim_results: true, language: "en-US" })).toBe(true); - - // Invalid schemas - interim_results must be defined - expect(isLiveSchema({ language: "en-US", model: "nova-2" })).toBe(false); - expect(isLiveSchema({})).toBe(false); - expect(isLiveSchema(null)).toBe(false); - expect(isLiveSchema(undefined)).toBe(false); - expect(isLiveSchema("not an object")).toBe(false); - expect(isLiveSchema(123)).toBe(false); - }); - }); - - describe("isDeepgramClientOptions", () => { - it("should identify Deepgram client options correctly", () => { - // Valid client options - expect(isDeepgramClientOptions({ global: { url: "https://api.deepgram.com" } })).toBe(true); - expect(isDeepgramClientOptions({ global: {} })).toBe(true); - expect(isDeepgramClientOptions({ global: { headers: { Custom: "Header" } } })).toBe(true); - - // Invalid options - global property must be defined - expect(isDeepgramClientOptions({ apiKey: "test-key" })).toBe(false); - expect(isDeepgramClientOptions({})).toBe(false); - expect(isDeepgramClientOptions(null)).toBe(false); - expect(isDeepgramClientOptions(undefined)).toBe(false); - expect(isDeepgramClientOptions("not an object")).toBe(false); - expect(isDeepgramClientOptions(123)).toBe(false); - }); - }); -}); - -describe("isFileSource with duck-typed stream detection", () => { - let isBrowserMock: jest.SpyInstance; - - beforeEach(() => { - // Import and mock the isBrowser function - const runtime = require("../../src/lib/runtime"); // eslint-disable-line @typescript-eslint/no-require-imports - isBrowserMock = jest.spyOn(runtime, "isBrowser"); - }); - - afterEach(() => { - isBrowserMock.mockRestore(); - }); - - describe("in Node.js environment", () => { - beforeEach(() => { - isBrowserMock.mockReturnValue(false); - }); - - it("should detect objects with all required stream properties", () => { - const streamLikeObject = { - pipe: jest.fn(), - read: jest.fn(), - _readableState: { flowing: null, ended: false }, - }; - - expect(isFileSource(streamLikeObject as any)).toBe(true); - }); - - it("should reject objects missing pipe method", () => { - const invalidStream = { - read: jest.fn(), - _readableState: {}, - }; - - expect(isFileSource(invalidStream as any)).toBe(false); - }); - - it("should reject objects missing read method", () => { - const invalidStream = { - pipe: jest.fn(), - _readableState: {}, - }; - - expect(isFileSource(invalidStream as any)).toBe(false); - }); - - it("should reject objects missing _readableState", () => { - const invalidStream = { - pipe: jest.fn(), - read: jest.fn(), - }; - - expect(isFileSource(invalidStream as any)).toBe(false); - }); - - it("should reject objects where methods are not functions", () => { - const invalidStream = { - pipe: "not a function", - read: jest.fn(), - _readableState: {}, - }; - - expect(isFileSource(invalidStream as any)).toBe(false); - }); - }); - - describe("in browser environment", () => { - beforeEach(() => { - isBrowserMock.mockReturnValue(true); - }); - - it("should always return false for stream-like objects", () => { - const streamLikeObject = { - pipe: jest.fn(), - read: jest.fn(), - _readableState: {}, - }; - - // Even with all properties, should return false in browser - expect(isFileSource(streamLikeObject as any)).toBe(false); - }); - - it("should still detect Buffer objects", () => { - const buffer = Buffer.from("test data"); - expect(isFileSource(buffer)).toBe(true); - }); - }); -}); diff --git a/tests/unit/url-builders.test.ts b/tests/unit/url-builders.test.ts deleted file mode 100644 index 8e9f0401..00000000 --- a/tests/unit/url-builders.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -import { buildRequestUrl } from "../../src/lib/helpers"; - -describe("Unit Tests - URL Building Utilities", () => { - describe("buildRequestUrl", () => { - it("should build URLs with string base URL", () => { - const url = buildRequestUrl("v1/listen", "https://api.deepgram.com", { - language: "en-US", - model: "nova-2", - }); - - expect(url.href).toBe("https://api.deepgram.com/v1/listen?language=en-US&model=nova-2"); - expect(url.searchParams.get("language")).toBe("en-US"); - expect(url.searchParams.get("model")).toBe("nova-2"); - }); - - it("should build URLs with URL object base", () => { - const baseUrl = new URL("https://api.deepgram.com"); - const url = buildRequestUrl("v1/listen", baseUrl, { punctuate: true, smart_format: false }); - - expect(url.href).toBe("https://api.deepgram.com/v1/listen?punctuate=true&smart_format=false"); - expect(url.searchParams.get("punctuate")).toBe("true"); - expect(url.searchParams.get("smart_format")).toBe("false"); - }); - - it("should handle array parameters", () => { - const url = buildRequestUrl("v1/speak", "https://api.deepgram.com", { - keywords: ["hello", "world"], - }); - - expect(url.searchParams.getAll("keywords")).toEqual(["hello", "world"]); - expect(url.href).toBe("https://api.deepgram.com/v1/speak?keywords=hello&keywords=world"); - }); - - it("should handle empty options", () => { - const url = buildRequestUrl("v1/listen", "https://api.deepgram.com", {}); - - expect(url.href).toBe("https://api.deepgram.com/v1/listen"); - expect(url.search).toBe(""); - }); - - it("should handle numeric parameters", () => { - const url = buildRequestUrl("v1/listen", "https://api.deepgram.com", { - confidence: 0.8, - alternatives: 3, - }); - - expect(url.searchParams.get("confidence")).toBe("0.8"); - expect(url.searchParams.get("alternatives")).toBe("3"); - }); - - it("should handle boolean parameters", () => { - const url = buildRequestUrl("v1/listen", "https://api.deepgram.com", { - interim_results: true, - endpointing: false, - }); - - expect(url.searchParams.get("interim_results")).toBe("true"); - expect(url.searchParams.get("endpointing")).toBe("false"); - }); - - it("should preserve base URL path", () => { - const url = buildRequestUrl("listen", "https://api.deepgram.com/v1/", { language: "en-US" }); - - expect(url.pathname).toBe("/v1/listen"); - expect(url.href).toBe("https://api.deepgram.com/v1/listen?language=en-US"); - }); - }); -}); diff --git a/tests/unit/url/join.test.ts b/tests/unit/url/join.test.ts new file mode 100644 index 00000000..984cfe67 --- /dev/null +++ b/tests/unit/url/join.test.ts @@ -0,0 +1,120 @@ +import { join } from "../../../src/core/url/index"; + +describe("join", () => { + describe("basic functionality", () => { + it("should return empty string for empty base", () => { + expect(join("")).toBe(""); + expect(join("", "path")).toBe(""); + }); + + it("should handle single segment", () => { + expect(join("base", "segment")).toBe("base/segment"); + expect(join("base/", "segment")).toBe("base/segment"); + expect(join("base", "/segment")).toBe("base/segment"); + expect(join("base/", "/segment")).toBe("base/segment"); + }); + + it("should handle multiple segments", () => { + expect(join("base", "path1", "path2", "path3")).toBe("base/path1/path2/path3"); + expect(join("base/", "/path1/", "/path2/", "/path3/")).toBe("base/path1/path2/path3/"); + }); + }); + + describe("URL handling", () => { + it("should handle absolute URLs", () => { + expect(join("https://example.com", "api", "v1")).toBe("https://example.com/api/v1"); + expect(join("https://example.com/", "/api/", "/v1/")).toBe("https://example.com/api/v1/"); + expect(join("https://example.com/base", "api", "v1")).toBe("https://example.com/base/api/v1"); + }); + + it("should preserve URL query parameters and fragments", () => { + expect(join("https://example.com?query=1", "api")).toBe("https://example.com/api?query=1"); + expect(join("https://example.com#fragment", "api")).toBe("https://example.com/api#fragment"); + expect(join("https://example.com?query=1#fragment", "api")).toBe( + "https://example.com/api?query=1#fragment", + ); + }); + + it("should handle different protocols", () => { + expect(join("http://example.com", "api")).toBe("http://example.com/api"); + expect(join("ftp://example.com", "files")).toBe("ftp://example.com/files"); + expect(join("ws://example.com", "socket")).toBe("ws://example.com/socket"); + }); + + it("should fallback to path joining for malformed URLs", () => { + expect(join("not-a-url://", "path")).toBe("not-a-url:///path"); + }); + }); + + describe("edge cases", () => { + it("should handle empty segments", () => { + expect(join("base", "", "path")).toBe("base/path"); + expect(join("base", null as any, "path")).toBe("base/path"); + expect(join("base", undefined as any, "path")).toBe("base/path"); + }); + + it("should handle segments with only slashes", () => { + expect(join("base", "/", "path")).toBe("base/path"); + expect(join("base", "//", "path")).toBe("base/path"); + }); + + it("should handle base paths with trailing slashes", () => { + expect(join("base/", "path")).toBe("base/path"); + }); + + it("should handle complex nested paths", () => { + expect(join("api/v1/", "/users/", "/123/", "/profile")).toBe("api/v1/users/123/profile"); + }); + }); + + describe("real-world scenarios", () => { + it("should handle API endpoint construction", () => { + const baseUrl = "https://api.example.com/v1"; + expect(join(baseUrl, "users", "123", "posts")).toBe("https://api.example.com/v1/users/123/posts"); + }); + + it("should handle file path construction", () => { + expect(join("/var/www", "html", "assets", "images")).toBe("/var/www/html/assets/images"); + }); + + it("should handle relative path construction", () => { + expect(join("../parent", "child", "grandchild")).toBe("../parent/child/grandchild"); + }); + + it("should handle Windows-style paths", () => { + expect(join("C:\\Users", "Documents", "file.txt")).toBe("C:\\Users/Documents/file.txt"); + }); + }); + + describe("performance scenarios", () => { + it("should handle many segments efficiently", () => { + const segments = Array(100).fill("segment"); + const result = join("base", ...segments); + expect(result).toBe("base/" + segments.join("/")); + }); + + it("should handle long URLs", () => { + const longPath = "a".repeat(1000); + expect(join("https://example.com", longPath)).toBe(`https://example.com/${longPath}`); + }); + }); + + describe("trailing slash preservation", () => { + it("should preserve trailing slash on final result when base has trailing slash and no segments", () => { + expect(join("https://api.example.com/")).toBe("https://api.example.com/"); + expect(join("https://api.example.com/v1/")).toBe("https://api.example.com/v1/"); + }); + + it("should preserve trailing slash when last segment has trailing slash", () => { + expect(join("https://api.example.com", "users/")).toBe("https://api.example.com/users/"); + expect(join("api/v1", "users/")).toBe("api/v1/users/"); + }); + + it("should preserve trailing slash with multiple segments where last has trailing slash", () => { + expect(join("https://api.example.com", "v1", "collections/")).toBe( + "https://api.example.com/v1/collections/", + ); + expect(join("base", "path1", "path2/")).toBe("base/path1/path2/"); + }); + }); +}); diff --git a/tests/unit/url/qs.test.ts b/tests/unit/url/qs.test.ts new file mode 100644 index 00000000..80e7e044 --- /dev/null +++ b/tests/unit/url/qs.test.ts @@ -0,0 +1,187 @@ +import { toQueryString } from "../../../src/core/url/index"; + +describe("Test qs toQueryString", () => { + describe("Basic functionality", () => { + it("should return empty string for null/undefined", () => { + expect(toQueryString(null)).toBe(""); + expect(toQueryString(undefined)).toBe(""); + }); + + it("should return empty string for primitive values", () => { + expect(toQueryString("hello")).toBe(""); + expect(toQueryString(42)).toBe(""); + expect(toQueryString(true)).toBe(""); + expect(toQueryString(false)).toBe(""); + }); + + it("should handle empty objects", () => { + expect(toQueryString({})).toBe(""); + }); + + it("should handle simple key-value pairs", () => { + const obj = { name: "John", age: 30 }; + expect(toQueryString(obj)).toBe("name=John&age=30"); + }); + }); + + describe("Array handling", () => { + it("should handle arrays with indices format (default)", () => { + const obj = { items: ["a", "b", "c"] }; + expect(toQueryString(obj)).toBe("items%5B0%5D=a&items%5B1%5D=b&items%5B2%5D=c"); + }); + + it("should handle arrays with repeat format", () => { + const obj = { items: ["a", "b", "c"] }; + expect(toQueryString(obj, { arrayFormat: "repeat" })).toBe("items=a&items=b&items=c"); + }); + + it("should handle empty arrays", () => { + const obj = { items: [] }; + expect(toQueryString(obj)).toBe(""); + }); + + it("should handle arrays with mixed types", () => { + const obj = { mixed: ["string", 42, true, false] }; + expect(toQueryString(obj)).toBe("mixed%5B0%5D=string&mixed%5B1%5D=42&mixed%5B2%5D=true&mixed%5B3%5D=false"); + }); + + it("should handle arrays with objects", () => { + const obj = { users: [{ name: "John" }, { name: "Jane" }] }; + expect(toQueryString(obj)).toBe("users%5B0%5D%5Bname%5D=John&users%5B1%5D%5Bname%5D=Jane"); + }); + + it("should handle arrays with objects in repeat format", () => { + const obj = { users: [{ name: "John" }, { name: "Jane" }] }; + expect(toQueryString(obj, { arrayFormat: "repeat" })).toBe("users%5Bname%5D=John&users%5Bname%5D=Jane"); + }); + }); + + describe("Nested objects", () => { + it("should handle nested objects", () => { + const obj = { user: { name: "John", age: 30 } }; + expect(toQueryString(obj)).toBe("user%5Bname%5D=John&user%5Bage%5D=30"); + }); + + it("should handle deeply nested objects", () => { + const obj = { user: { profile: { name: "John", settings: { theme: "dark" } } } }; + expect(toQueryString(obj)).toBe( + "user%5Bprofile%5D%5Bname%5D=John&user%5Bprofile%5D%5Bsettings%5D%5Btheme%5D=dark", + ); + }); + + it("should handle empty nested objects", () => { + const obj = { user: {} }; + expect(toQueryString(obj)).toBe(""); + }); + }); + + describe("Encoding", () => { + it("should encode by default", () => { + const obj = { name: "John Doe", email: "john@example.com" }; + expect(toQueryString(obj)).toBe("name=John%20Doe&email=john%40example.com"); + }); + + it("should not encode when encode is false", () => { + const obj = { name: "John Doe", email: "john@example.com" }; + expect(toQueryString(obj, { encode: false })).toBe("name=John Doe&email=john@example.com"); + }); + + it("should encode special characters in keys", () => { + const obj = { "user name": "John", "email[primary]": "john@example.com" }; + expect(toQueryString(obj)).toBe("user%20name=John&email%5Bprimary%5D=john%40example.com"); + }); + + it("should not encode special characters in keys when encode is false", () => { + const obj = { "user name": "John", "email[primary]": "john@example.com" }; + expect(toQueryString(obj, { encode: false })).toBe("user name=John&email[primary]=john@example.com"); + }); + }); + + describe("Mixed scenarios", () => { + it("should handle complex nested structures", () => { + const obj = { + filters: { + status: ["active", "pending"], + category: { + type: "electronics", + subcategories: ["phones", "laptops"], + }, + }, + sort: { field: "name", direction: "asc" }, + }; + expect(toQueryString(obj)).toBe( + "filters%5Bstatus%5D%5B0%5D=active&filters%5Bstatus%5D%5B1%5D=pending&filters%5Bcategory%5D%5Btype%5D=electronics&filters%5Bcategory%5D%5Bsubcategories%5D%5B0%5D=phones&filters%5Bcategory%5D%5Bsubcategories%5D%5B1%5D=laptops&sort%5Bfield%5D=name&sort%5Bdirection%5D=asc", + ); + }); + + it("should handle complex nested structures with repeat format", () => { + const obj = { + filters: { + status: ["active", "pending"], + category: { + type: "electronics", + subcategories: ["phones", "laptops"], + }, + }, + sort: { field: "name", direction: "asc" }, + }; + expect(toQueryString(obj, { arrayFormat: "repeat" })).toBe( + "filters%5Bstatus%5D=active&filters%5Bstatus%5D=pending&filters%5Bcategory%5D%5Btype%5D=electronics&filters%5Bcategory%5D%5Bsubcategories%5D=phones&filters%5Bcategory%5D%5Bsubcategories%5D=laptops&sort%5Bfield%5D=name&sort%5Bdirection%5D=asc", + ); + }); + + it("should handle arrays with null/undefined values", () => { + const obj = { items: ["a", null, "c", undefined, "e"] }; + expect(toQueryString(obj)).toBe("items%5B0%5D=a&items%5B1%5D=&items%5B2%5D=c&items%5B4%5D=e"); + }); + + it("should handle objects with null/undefined values", () => { + const obj = { name: "John", age: null, email: undefined, active: true }; + expect(toQueryString(obj)).toBe("name=John&age=&active=true"); + }); + }); + + describe("Edge cases", () => { + it("should handle numeric keys", () => { + const obj = { "0": "zero", "1": "one" }; + expect(toQueryString(obj)).toBe("0=zero&1=one"); + }); + + it("should handle boolean values in objects", () => { + const obj = { enabled: true, disabled: false }; + expect(toQueryString(obj)).toBe("enabled=true&disabled=false"); + }); + + it("should handle empty strings", () => { + const obj = { name: "", description: "test" }; + expect(toQueryString(obj)).toBe("name=&description=test"); + }); + + it("should handle zero values", () => { + const obj = { count: 0, price: 0.0 }; + expect(toQueryString(obj)).toBe("count=0&price=0"); + }); + + it("should handle arrays with empty strings", () => { + const obj = { items: ["a", "", "c"] }; + expect(toQueryString(obj)).toBe("items%5B0%5D=a&items%5B1%5D=&items%5B2%5D=c"); + }); + }); + + describe("Options combinations", () => { + it("should respect both arrayFormat and encode options", () => { + const obj = { items: ["a & b", "c & d"] }; + expect(toQueryString(obj, { arrayFormat: "repeat", encode: false })).toBe("items=a & b&items=c & d"); + }); + + it("should use default options when none provided", () => { + const obj = { items: ["a", "b"] }; + expect(toQueryString(obj)).toBe("items%5B0%5D=a&items%5B1%5D=b"); + }); + + it("should merge provided options with defaults", () => { + const obj = { items: ["a", "b"], name: "John Doe" }; + expect(toQueryString(obj, { encode: false })).toBe("items[0]=a&items[1]=b&name=John Doe"); + }); + }); +}); diff --git a/tests/wire/.gitkeep b/tests/wire/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/tests/wire/agent/v1/settings/think/models.test.ts b/tests/wire/agent/v1/settings/think/models.test.ts new file mode 100644 index 00000000..7386b405 --- /dev/null +++ b/tests/wire/agent/v1/settings/think/models.test.ts @@ -0,0 +1,58 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../../src/Client"; +import * as Deepgram from "../../../../../../src/api/index"; + +describe("Models", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { models: [{ id: "gpt-5", name: "name", provider: "open_ai" }] }; + server + .mockEndpoint() + .get("/v1/agent/settings/think/models") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.agent.v1.settings.think.models.list(); + expect(response).toEqual({ + models: [ + { + id: "gpt-5", + name: "name", + provider: "open_ai", + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/agent/settings/think/models") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.agent.v1.settings.think.models.list(); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/auth/v1/tokens.test.ts b/tests/wire/auth/v1/tokens.test.ts new file mode 100644 index 00000000..680e7345 --- /dev/null +++ b/tests/wire/auth/v1/tokens.test.ts @@ -0,0 +1,62 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../src/Client"; +import * as Deepgram from "../../../../src/api/index"; + +describe("Tokens", () => { + test("grant (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = {}; + const rawResponseBody = { + access_token: + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U", + expires_in: 30, + }; + server + .mockEndpoint() + .post("/v1/auth/grant") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.auth.v1.tokens.grant(); + expect(response).toEqual({ + access_token: + "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U", + expires_in: 30, + }); + }); + + test("grant (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { ttl_seconds: undefined }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/auth/grant") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.auth.v1.tokens.grant({ + ttl_seconds: undefined, + }); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/listen/v1/media.test.ts b/tests/wire/listen/v1/media.test.ts new file mode 100644 index 00000000..4fe05a80 --- /dev/null +++ b/tests/wire/listen/v1/media.test.ts @@ -0,0 +1,208 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../src/Client"; +import * as Deepgram from "../../../../src/api/index"; + +describe("Media", () => { + test("transcribeUrl (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { url: "https://dpgr.am/spacewalk.wav" }; + const rawResponseBody = { + metadata: { + request_id: "a847f427-4ad5-4d67-9b95-db801e58251c", + sha256: "154e291ecfa8be6ab8343560bcc109008fa7853eb5372533e8efdefc9b504c33", + created: "2024-05-12T18:57:13Z", + duration: 25.933313, + channels: 1, + models: ["30089e05-99d1-4376-b32e-c263170674af"], + model_info: { + "30089e05-99d1-4376-b32e-c263170674af": { + name: "2-general-nova", + version: "2024-01-09.29447", + arch: "nova-2", + }, + }, + summary_info: { + model_uuid: "67875a7f-c9c4-48a0-aa55-5bdb8a91c34a", + input_tokens: 95, + output_tokens: 63, + }, + sentiment_info: { + model_uuid: "80ab3179-d113-4254-bd6b-4a2f96498695", + input_tokens: 105, + output_tokens: 105, + }, + topics_info: { + model_uuid: "80ab3179-d113-4254-bd6b-4a2f96498695", + input_tokens: 105, + output_tokens: 7, + }, + intents_info: { + model_uuid: "80ab3179-d113-4254-bd6b-4a2f96498695", + input_tokens: 105, + output_tokens: 4, + }, + tags: ["test"], + }, + results: { + channels: [{}], + utterances: [{}], + summary: { + result: "success", + short: "Speaker 0 discusses the significance of the first all-female spacewalk with an all-female team, stating that it is a tribute to the skilled and qualified women who were denied opportunities in the past.", + }, + sentiments: { + segments: [ + { + text: "Yeah. As as much as, um, it's worth celebrating, uh, the first, uh, spacewalk, um, with an all-female team, I think many of us are looking forward to it just being normal. And, um, I think if it signifies anything, it is, uh, to honor the the women who came before us who, um, were skilled and qualified, um, and didn't get the the same opportunities that we have today.", + start_word: 0, + end_word: 69, + sentiment: "positive", + sentiment_score: 0.5810546875, + }, + ], + average: { sentiment: "positive", sentiment_score: 0.5810185185185185 }, + }, + }, + }; + server + .mockEndpoint() + .post("/v1/listen") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.listen.v1.media.transcribeUrl({ + callback: "callback", + callback_method: "POST", + extra: "extra", + sentiment: true, + summarize: "v2", + tag: "tag", + topics: true, + custom_topic: "custom_topic", + custom_topic_mode: "extended", + intents: true, + custom_intent: "custom_intent", + custom_intent_mode: "extended", + detect_entities: true, + detect_language: true, + diarize: true, + dictation: true, + encoding: "linear16", + filler_words: true, + keywords: "keywords", + language: "language", + measurements: true, + model: "nova-3", + multichannel: true, + numerals: true, + paragraphs: true, + profanity_filter: true, + punctuate: true, + redact: "redact", + replace: "replace", + search: "search", + smart_format: true, + utterances: true, + utt_split: 1.1, + version: "latest", + mip_opt_out: true, + url: "https://dpgr.am/spacewalk.wav", + }); + expect(response).toEqual({ + metadata: { + request_id: "a847f427-4ad5-4d67-9b95-db801e58251c", + sha256: "154e291ecfa8be6ab8343560bcc109008fa7853eb5372533e8efdefc9b504c33", + created: "2024-05-12T18:57:13Z", + duration: 25.933313, + channels: 1, + models: ["30089e05-99d1-4376-b32e-c263170674af"], + model_info: { + "30089e05-99d1-4376-b32e-c263170674af": { + name: "2-general-nova", + version: "2024-01-09.29447", + arch: "nova-2", + }, + }, + summary_info: { + model_uuid: "67875a7f-c9c4-48a0-aa55-5bdb8a91c34a", + input_tokens: 95, + output_tokens: 63, + }, + sentiment_info: { + model_uuid: "80ab3179-d113-4254-bd6b-4a2f96498695", + input_tokens: 105, + output_tokens: 105, + }, + topics_info: { + model_uuid: "80ab3179-d113-4254-bd6b-4a2f96498695", + input_tokens: 105, + output_tokens: 7, + }, + intents_info: { + model_uuid: "80ab3179-d113-4254-bd6b-4a2f96498695", + input_tokens: 105, + output_tokens: 4, + }, + tags: ["test"], + }, + results: { + channels: [{}], + utterances: [{}], + summary: { + result: "success", + short: "Speaker 0 discusses the significance of the first all-female spacewalk with an all-female team, stating that it is a tribute to the skilled and qualified women who were denied opportunities in the past.", + }, + sentiments: { + segments: [ + { + text: "Yeah. As as much as, um, it's worth celebrating, uh, the first, uh, spacewalk, um, with an all-female team, I think many of us are looking forward to it just being normal. And, um, I think if it signifies anything, it is, uh, to honor the the women who came before us who, um, were skilled and qualified, um, and didn't get the the same opportunities that we have today.", + start_word: 0, + end_word: 69, + sentiment: "positive", + sentiment_score: 0.5810546875, + }, + ], + average: { + sentiment: "positive", + sentiment_score: 0.5810185185185185, + }, + }, + }, + }); + }); + + test("transcribeUrl (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { url: "url" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/listen") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.listen.v1.media.transcribeUrl({ + url: "url", + }); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/models.test.ts b/tests/wire/manage/v1/models.test.ts new file mode 100644 index 00000000..c551eb2c --- /dev/null +++ b/tests/wire/manage/v1/models.test.ts @@ -0,0 +1,163 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../src/Client"; +import * as Deepgram from "../../../../src/api/index"; + +describe("Models", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + stt: [ + { + name: "nova-3", + canonical_name: "nova-3", + architecture: "base", + languages: ["en", "en-us"], + version: "2021-11-10.1", + uuid: "6b28e919-8427-4f32-9847-492e2efd7daf", + batch: true, + streaming: true, + formatted_output: true, + }, + ], + tts: [ + { + name: "zeus", + canonical_name: "aura-2-zeus-en", + architecture: "aura-2", + languages: ["en", "en-US"], + version: "2025-04-07.0", + uuid: "2baf189d-91ac-481d-b6d1-750888667b31", + metadata: { + accent: "American", + age: "Adult", + color: "#C58DFF", + image: "https://static.deepgram.com/examples/avatars/zeus.jpg", + sample: "https://static.deepgram.com/examples/Aura-2-zeus.wav", + }, + }, + ], + }; + server.mockEndpoint().get("/v1/models").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.manage.v1.models.list({ + include_outdated: true, + }); + expect(response).toEqual({ + stt: [ + { + name: "nova-3", + canonical_name: "nova-3", + architecture: "base", + languages: ["en", "en-us"], + version: "2021-11-10.1", + uuid: "6b28e919-8427-4f32-9847-492e2efd7daf", + batch: true, + streaming: true, + formatted_output: true, + }, + ], + tts: [ + { + name: "zeus", + canonical_name: "aura-2-zeus-en", + architecture: "aura-2", + languages: ["en", "en-US"], + version: "2025-04-07.0", + uuid: "2baf189d-91ac-481d-b6d1-750888667b31", + metadata: { + accent: "American", + age: "Adult", + color: "#C58DFF", + image: "https://static.deepgram.com/examples/avatars/zeus.jpg", + sample: "https://static.deepgram.com/examples/Aura-2-zeus.wav", + }, + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/models").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.manage.v1.models.list(); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + name: "general", + canonical_name: "enhanced-general", + architecture: "polaris", + languages: ["en", "en-us"], + version: "2022-05-18.1", + uuid: "c7226e9e-ae1c-4057-ae2a-a71a6b0dc588", + batch: true, + streaming: true, + formatted_output: false, + }; + server + .mockEndpoint() + .get("/v1/models/af6e9977-99f6-4d8f-b6f5-dfdf6fb6e291") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.models.get("af6e9977-99f6-4d8f-b6f5-dfdf6fb6e291"); + expect(response).toEqual({ + name: "general", + canonical_name: "enhanced-general", + architecture: "polaris", + languages: ["en", "en-us"], + version: "2022-05-18.1", + uuid: "c7226e9e-ae1c-4057-ae2a-a71a6b0dc588", + batch: true, + streaming: true, + formatted_output: false, + }); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/models/model_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.models.get("model_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects.test.ts b/tests/wire/manage/v1/projects.test.ts new file mode 100644 index 00000000..20d53c63 --- /dev/null +++ b/tests/wire/manage/v1/projects.test.ts @@ -0,0 +1,226 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../src/Client"; +import * as Deepgram from "../../../../src/api/index"; + +describe("Projects", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { projects: [{ project_id: "project_id", name: "name" }] }; + server.mockEndpoint().get("/v1/projects").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.manage.v1.projects.list(); + expect(response).toEqual({ + projects: [ + { + project_id: "project_id", + name: "name", + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server.mockEndpoint().get("/v1/projects").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.manage.v1.projects.list(); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { project_id: "project_id", mip_opt_out: true, name: "name" }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.get("123456-7890-1234-5678-901234", { + limit: 1.1, + page: 1.1, + }); + expect(response).toEqual({ + project_id: "project_id", + mip_opt_out: true, + name: "name", + }); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.get("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("delete (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { message: "message" }; + server + .mockEndpoint() + .delete("/v1/projects/123456-7890-1234-5678-901234") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.delete("123456-7890-1234-5678-901234"); + expect(response).toEqual({ + message: "message", + }); + }); + + test("delete (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/projects/project_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.delete("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("update (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = {}; + const rawResponseBody = { message: "Successfully updated project info." }; + server + .mockEndpoint() + .patch("/v1/projects/123456-7890-1234-5678-901234") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.update("123456-7890-1234-5678-901234"); + expect(response).toEqual({ + message: "Successfully updated project info.", + }); + }); + + test("update (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { name: undefined }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .patch("/v1/projects/project_id") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.update("project_id", { + name: undefined, + }); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("leave (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { message: "message" }; + server + .mockEndpoint() + .delete("/v1/projects/123456-7890-1234-5678-901234/leave") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.leave("123456-7890-1234-5678-901234"); + expect(response).toEqual({ + message: "message", + }); + }); + + test("leave (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/projects/project_id/leave") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.leave("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/billing/balances.test.ts b/tests/wire/manage/v1/projects/billing/balances.test.ts new file mode 100644 index 00000000..7f4c9aba --- /dev/null +++ b/tests/wire/manage/v1/projects/billing/balances.test.ts @@ -0,0 +1,117 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../../src/Client"; +import * as Deepgram from "../../../../../../src/api/index"; + +describe("Balances", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + balances: [ + { balance_id: "balance_id", amount: 1.1, units: "units", purchase_order_id: "purchase_order_id" }, + ], + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/balances") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.billing.balances.list("123456-7890-1234-5678-901234"); + expect(response).toEqual({ + balances: [ + { + balance_id: "balance_id", + amount: 1.1, + units: "units", + purchase_order_id: "purchase_order_id", + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/balances") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.billing.balances.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + balance_id: "balance_id", + amount: 1.1, + units: "units", + purchase_order_id: "purchase_order_id", + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/balances/123456-7890-1234-5678-901234") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.billing.balances.get( + "123456-7890-1234-5678-901234", + "123456-7890-1234-5678-901234", + ); + expect(response).toEqual({ + balance_id: "balance_id", + amount: 1.1, + units: "units", + purchase_order_id: "purchase_order_id", + }); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/balances/balance_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.billing.balances.get("project_id", "balance_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/billing/breakdown.test.ts b/tests/wire/manage/v1/projects/billing/breakdown.test.ts new file mode 100644 index 00000000..2bfbcc76 --- /dev/null +++ b/tests/wire/manage/v1/projects/billing/breakdown.test.ts @@ -0,0 +1,78 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../../src/Client"; +import * as Deepgram from "../../../../../../src/api/index"; + +describe("Breakdown", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + start: "2025-01-16", + end: "2025-01-23", + resolution: { units: "day", amount: 1 }, + results: [{ dollars: 0.25, grouping: { start: "2025-01-16", end: "2025-01-16" } }], + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/billing/breakdown") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.billing.breakdown.list("123456-7890-1234-5678-901234", { + start: "start", + end: "end", + accessor: "12345678-1234-1234-1234-123456789012", + deployment: "hosted", + tag: "tag1", + line_item: "streaming::nova-3", + }); + expect(response).toEqual({ + start: "2025-01-16", + end: "2025-01-23", + resolution: { + units: "day", + amount: 1, + }, + results: [ + { + dollars: 0.25, + grouping: { + start: "2025-01-16", + end: "2025-01-16", + }, + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/billing/breakdown") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.billing.breakdown.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/billing/purchases.test.ts b/tests/wire/manage/v1/projects/billing/purchases.test.ts new file mode 100644 index 00000000..c7496ae6 --- /dev/null +++ b/tests/wire/manage/v1/projects/billing/purchases.test.ts @@ -0,0 +1,74 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../../src/Client"; +import * as Deepgram from "../../../../../../src/api/index"; + +describe("Purchases", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + orders: [ + { + order_id: "025e19ba-b6d9-4a04-9f99-4fe715aca5f1", + expiration: "2026-03-04T00:00:00Z", + created: "2023-02-21T21:13:40Z", + amount: 150, + units: "usd", + order_type: "promotional", + }, + ], + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/purchases") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.billing.purchases.list("123456-7890-1234-5678-901234", { + limit: 1.1, + }); + expect(response).toEqual({ + orders: [ + { + order_id: "025e19ba-b6d9-4a04-9f99-4fe715aca5f1", + expiration: "2026-03-04T00:00:00Z", + created: "2023-02-21T21:13:40Z", + amount: 150, + units: "usd", + order_type: "promotional", + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/purchases") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.billing.purchases.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/keys.test.ts b/tests/wire/manage/v1/projects/keys.test.ts new file mode 100644 index 00000000..74f0a94a --- /dev/null +++ b/tests/wire/manage/v1/projects/keys.test.ts @@ -0,0 +1,258 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../src/Client"; +import * as Deepgram from "../../../../../src/api/index"; + +describe("Keys", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + api_keys: [ + { + member: { member_id: "1000-2000-3000-4000", email: "john@test.com" }, + api_key: { + api_key_id: "1234567890abcdef1234567890abcdef", + comment: "A comment", + created: "2021-01-01T00:00:00Z", + }, + }, + ], + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/keys") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.keys.list("123456-7890-1234-5678-901234", { + status: "active", + }); + expect(response).toEqual({ + api_keys: [ + { + member: { + member_id: "1000-2000-3000-4000", + email: "john@test.com", + }, + api_key: { + api_key_id: "1234567890abcdef1234567890abcdef", + comment: "A comment", + created: "2021-01-01T00:00:00Z", + }, + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/keys") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.keys.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("create (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + api_key_id: "api_key_id", + key: "key", + comment: "comment", + scopes: ["scopes", "scopes"], + tags: ["tags", "tags"], + expiration_date: "2024-01-15T09:30:00Z", + }; + server + .mockEndpoint() + .post("/v1/projects/project_id/keys") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.keys.create("project_id", { + key: "value", + }); + expect(response).toEqual({ + api_key_id: "api_key_id", + key: "key", + comment: "comment", + scopes: ["scopes", "scopes"], + tags: ["tags", "tags"], + expiration_date: "2024-01-15T09:30:00Z", + }); + }); + + test("create (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/projects/project_id/keys") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.keys.create("project_id", { + key: "value", + }); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + item: { + member: { + member_id: "1000-2000-3000-4000", + email: "john@test.com", + first_name: "John", + last_name: "Doe", + api_key: { + api_key_id: "1000-2000-3000-4000", + comment: "A comment", + expiration_date: "2021-01-01T00:00:00Z", + created: "2021-01-01T00:00:00Z", + }, + }, + }, + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/keys/123456789012345678901234") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.keys.get( + "123456-7890-1234-5678-901234", + "123456789012345678901234", + ); + expect(response).toEqual({ + item: { + member: { + member_id: "1000-2000-3000-4000", + email: "john@test.com", + first_name: "John", + last_name: "Doe", + api_key: { + api_key_id: "1000-2000-3000-4000", + comment: "A comment", + expiration_date: "2021-01-01T00:00:00Z", + created: "2021-01-01T00:00:00Z", + }, + }, + }, + }); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/keys/key_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.keys.get("project_id", "key_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("delete (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { message: "message" }; + server + .mockEndpoint() + .delete("/v1/projects/123456-7890-1234-5678-901234/keys/123456789012345678901234") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.keys.delete( + "123456-7890-1234-5678-901234", + "123456789012345678901234", + ); + expect(response).toEqual({ + message: "message", + }); + }); + + test("delete (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/projects/project_id/keys/key_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.keys.delete("project_id", "key_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/members.test.ts b/tests/wire/manage/v1/projects/members.test.ts new file mode 100644 index 00000000..97a03175 --- /dev/null +++ b/tests/wire/manage/v1/projects/members.test.ts @@ -0,0 +1,103 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../src/Client"; +import * as Deepgram from "../../../../../src/api/index"; + +describe("Members", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { members: [{ member_id: "member_id", email: "email" }] }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/members") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.members.list("123456-7890-1234-5678-901234"); + expect(response).toEqual({ + members: [ + { + member_id: "member_id", + email: "email", + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/members") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.members.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("delete (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { message: "message" }; + server + .mockEndpoint() + .delete("/v1/projects/123456-7890-1234-5678-901234/members/123456789012345678901234") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.members.delete( + "123456-7890-1234-5678-901234", + "123456789012345678901234", + ); + expect(response).toEqual({ + message: "message", + }); + }); + + test("delete (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/projects/project_id/members/member_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.members.delete("project_id", "member_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/members/invites.test.ts b/tests/wire/manage/v1/projects/members/invites.test.ts new file mode 100644 index 00000000..5376bc88 --- /dev/null +++ b/tests/wire/manage/v1/projects/members/invites.test.ts @@ -0,0 +1,154 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../../src/Client"; +import * as Deepgram from "../../../../../../src/api/index"; + +describe("Invites", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { invites: [{ email: "email", scope: "scope" }] }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/invites") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.members.invites.list("123456-7890-1234-5678-901234"); + expect(response).toEqual({ + invites: [ + { + email: "email", + scope: "scope", + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/invites") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.members.invites.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("create (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { email: "email", scope: "scope" }; + const rawResponseBody = { message: "message" }; + server + .mockEndpoint() + .post("/v1/projects/123456-7890-1234-5678-901234/invites") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.members.invites.create("123456-7890-1234-5678-901234", { + email: "email", + scope: "scope", + }); + expect(response).toEqual({ + message: "message", + }); + }); + + test("create (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { email: "email", scope: "scope" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/projects/project_id/invites") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.members.invites.create("project_id", { + email: "email", + scope: "scope", + }); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("delete (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { message: "message" }; + server + .mockEndpoint() + .delete("/v1/projects/123456-7890-1234-5678-901234/invites/john.doe%40example.com") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.members.invites.delete( + "123456-7890-1234-5678-901234", + "john.doe@example.com", + ); + expect(response).toEqual({ + message: "message", + }); + }); + + test("delete (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/projects/project_id/invites/email") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.members.invites.delete("project_id", "email"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/members/scopes.test.ts b/tests/wire/manage/v1/projects/members/scopes.test.ts new file mode 100644 index 00000000..e0532b41 --- /dev/null +++ b/tests/wire/manage/v1/projects/members/scopes.test.ts @@ -0,0 +1,108 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../../src/Client"; +import * as Deepgram from "../../../../../../src/api/index"; + +describe("Scopes", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { scopes: ["scopes"] }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/members/123456789012345678901234/scopes") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.members.scopes.list( + "123456-7890-1234-5678-901234", + "123456789012345678901234", + ); + expect(response).toEqual({ + scopes: ["scopes"], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/members/member_id/scopes") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.members.scopes.list("project_id", "member_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("update (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { scope: "admin" }; + const rawResponseBody = { message: "message" }; + server + .mockEndpoint() + .put("/v1/projects/123456-7890-1234-5678-901234/members/123456789012345678901234/scopes") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.members.scopes.update( + "123456-7890-1234-5678-901234", + "123456789012345678901234", + { + scope: "admin", + }, + ); + expect(response).toEqual({ + message: "message", + }); + }); + + test("update (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { scope: "scope" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .put("/v1/projects/project_id/members/member_id/scopes") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.members.scopes.update("project_id", "member_id", { + scope: "scope", + }); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/models.test.ts b/tests/wire/manage/v1/projects/models.test.ts new file mode 100644 index 00000000..fbf0a0ee --- /dev/null +++ b/tests/wire/manage/v1/projects/models.test.ts @@ -0,0 +1,178 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../src/Client"; +import * as Deepgram from "../../../../../src/api/index"; + +describe("Models", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + stt: [ + { + name: "nova-3", + canonical_name: "nova-3", + architecture: "base", + languages: ["en", "en-us"], + version: "2021-11-10.1", + uuid: "6b28e919-8427-4f32-9847-492e2efd7daf", + batch: true, + streaming: true, + formatted_output: true, + }, + ], + tts: [ + { + name: "zeus", + canonical_name: "aura-2-zeus-en", + architecture: "aura-2", + languages: ["en", "en-US"], + version: "2025-04-07.0", + uuid: "2baf189d-91ac-481d-b6d1-750888667b31", + metadata: { + accent: "American", + age: "Adult", + color: "#C58DFF", + image: "https://static.deepgram.com/examples/avatars/zeus.jpg", + sample: "https://static.deepgram.com/examples/Aura-2-zeus.wav", + }, + }, + ], + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/models") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.models.list("123456-7890-1234-5678-901234", { + include_outdated: true, + }); + expect(response).toEqual({ + stt: [ + { + name: "nova-3", + canonical_name: "nova-3", + architecture: "base", + languages: ["en", "en-us"], + version: "2021-11-10.1", + uuid: "6b28e919-8427-4f32-9847-492e2efd7daf", + batch: true, + streaming: true, + formatted_output: true, + }, + ], + tts: [ + { + name: "zeus", + canonical_name: "aura-2-zeus-en", + architecture: "aura-2", + languages: ["en", "en-US"], + version: "2025-04-07.0", + uuid: "2baf189d-91ac-481d-b6d1-750888667b31", + metadata: { + accent: "American", + age: "Adult", + color: "#C58DFF", + image: "https://static.deepgram.com/examples/avatars/zeus.jpg", + sample: "https://static.deepgram.com/examples/Aura-2-zeus.wav", + }, + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/models") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.models.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + name: "general", + canonical_name: "enhanced-general", + architecture: "polaris", + languages: ["en", "en-us"], + version: "2022-05-18.1", + uuid: "c7226e9e-ae1c-4057-ae2a-a71a6b0dc588", + batch: true, + streaming: true, + formatted_output: false, + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/models/af6e9977-99f6-4d8f-b6f5-dfdf6fb6e291") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.models.get( + "123456-7890-1234-5678-901234", + "af6e9977-99f6-4d8f-b6f5-dfdf6fb6e291", + ); + expect(response).toEqual({ + name: "general", + canonical_name: "enhanced-general", + architecture: "polaris", + languages: ["en", "en-us"], + version: "2022-05-18.1", + uuid: "c7226e9e-ae1c-4057-ae2a-a71a6b0dc588", + batch: true, + streaming: true, + formatted_output: false, + }); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/models/model_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.models.get("project_id", "model_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/requests.test.ts b/tests/wire/manage/v1/projects/requests.test.ts new file mode 100644 index 00000000..00f5d796 --- /dev/null +++ b/tests/wire/manage/v1/projects/requests.test.ts @@ -0,0 +1,165 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../src/Client"; +import * as Deepgram from "../../../../../src/api/index"; + +describe("Requests", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + page: 1.1, + limit: 1.1, + requests: [ + { + request_id: "request_id", + project_uuid: "project_uuid", + created: "2024-01-15T09:30:00Z", + path: "path", + api_key_id: "api_key_id", + response: { key: "value" }, + code: 1.1, + deployment: "deployment", + callback: "callback", + }, + ], + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/requests") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.requests.list("123456-7890-1234-5678-901234", { + start: "2024-01-15T09:30:00Z", + end: "2024-01-15T09:30:00Z", + limit: 1.1, + page: 1.1, + accessor: "12345678-1234-1234-1234-123456789012", + request_id: "12345678-1234-1234-1234-123456789012", + deployment: "hosted", + endpoint: "listen", + method: "sync", + status: "succeeded", + }); + expect(response).toEqual({ + page: 1.1, + limit: 1.1, + requests: [ + { + request_id: "request_id", + project_uuid: "project_uuid", + created: "2024-01-15T09:30:00Z", + path: "path", + api_key_id: "api_key_id", + response: { + key: "value", + }, + code: 1.1, + deployment: "deployment", + callback: "callback", + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/requests") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.requests.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + request: { + request_id: "request_id", + project_uuid: "project_uuid", + created: "2024-01-15T09:30:00Z", + path: "path", + api_key_id: "api_key_id", + response: { key: "value" }, + code: 1.1, + deployment: "deployment", + callback: "callback", + }, + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/requests/123456-7890-1234-5678-901234") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.requests.get( + "123456-7890-1234-5678-901234", + "123456-7890-1234-5678-901234", + ); + expect(response).toEqual({ + request: { + request_id: "request_id", + project_uuid: "project_uuid", + created: "2024-01-15T09:30:00Z", + path: "path", + api_key_id: "api_key_id", + response: { + key: "value", + }, + code: 1.1, + deployment: "deployment", + callback: "callback", + }, + }); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/requests/request_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.requests.get("project_id", "request_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/usage.test.ts b/tests/wire/manage/v1/projects/usage.test.ts new file mode 100644 index 00000000..294fce60 --- /dev/null +++ b/tests/wire/manage/v1/projects/usage.test.ts @@ -0,0 +1,102 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../src/Client"; +import * as Deepgram from "../../../../../src/api/index"; + +describe("Usage", () => { + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { start: "2024-10-16", end: "2024-10-23", resolution: { units: "day", amount: 1 } }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/usage") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.usage.get("123456-7890-1234-5678-901234", { + start: "start", + end: "end", + accessor: "12345678-1234-1234-1234-123456789012", + alternatives: true, + callback_method: true, + callback: true, + channels: true, + custom_intent_mode: true, + custom_intent: true, + custom_topic_mode: true, + custom_topic: true, + deployment: "hosted", + detect_entities: true, + detect_language: true, + diarize: true, + dictation: true, + encoding: true, + endpoint: "listen", + extra: true, + filler_words: true, + intents: true, + keyterm: true, + keywords: true, + language: true, + measurements: true, + method: "sync", + model: "6f548761-c9c0-429a-9315-11a1d28499c8", + multichannel: true, + numerals: true, + paragraphs: true, + profanity_filter: true, + punctuate: true, + redact: true, + replace: true, + sample_rate: true, + search: true, + sentiment: true, + smart_format: true, + summarize: true, + tag: "tag1", + topics: true, + utt_split: true, + utterances: true, + version: true, + }); + expect(response).toEqual({ + start: "2024-10-16", + end: "2024-10-23", + resolution: { + units: "day", + amount: 1, + }, + }); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/usage") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.usage.get("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/usage/breakdown.test.ts b/tests/wire/manage/v1/projects/usage/breakdown.test.ts new file mode 100644 index 00000000..3f3a4636 --- /dev/null +++ b/tests/wire/manage/v1/projects/usage/breakdown.test.ts @@ -0,0 +1,134 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../../src/Client"; +import * as Deepgram from "../../../../../../src/api/index"; + +describe("Breakdown", () => { + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + start: "2025-01-16", + end: "2025-01-23", + resolution: { units: "day", amount: 1 }, + results: [ + { + hours: 1619.7242069444444, + total_hours: 1621.7395791666668, + agent_hours: 41.33564388888889, + tokens_in: 0, + tokens_out: 0, + tts_characters: 9158866, + requests: 373381, + grouping: { start: "2025-01-16", end: "2025-01-16" }, + }, + ], + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/usage/breakdown") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.usage.breakdown.get("123456-7890-1234-5678-901234", { + start: "start", + end: "end", + grouping: "accessor", + accessor: "12345678-1234-1234-1234-123456789012", + alternatives: true, + callback_method: true, + callback: true, + channels: true, + custom_intent_mode: true, + custom_intent: true, + custom_topic_mode: true, + custom_topic: true, + deployment: "hosted", + detect_entities: true, + detect_language: true, + diarize: true, + dictation: true, + encoding: true, + endpoint: "listen", + extra: true, + filler_words: true, + intents: true, + keyterm: true, + keywords: true, + language: true, + measurements: true, + method: "sync", + model: "6f548761-c9c0-429a-9315-11a1d28499c8", + multichannel: true, + numerals: true, + paragraphs: true, + profanity_filter: true, + punctuate: true, + redact: true, + replace: true, + sample_rate: true, + search: true, + sentiment: true, + smart_format: true, + summarize: true, + tag: "tag1", + topics: true, + utt_split: true, + utterances: true, + version: true, + }); + expect(response).toEqual({ + start: "2025-01-16", + end: "2025-01-23", + resolution: { + units: "day", + amount: 1, + }, + results: [ + { + hours: 1619.7242069444444, + total_hours: 1621.7395791666668, + agent_hours: 41.33564388888889, + tokens_in: 0, + tokens_out: 0, + tts_characters: 9158866, + requests: 373381, + grouping: { + start: "2025-01-16", + end: "2025-01-16", + }, + }, + ], + }); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/usage/breakdown") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.usage.breakdown.get("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/manage/v1/projects/usage/fields.test.ts b/tests/wire/manage/v1/projects/usage/fields.test.ts new file mode 100644 index 00000000..39cf7c73 --- /dev/null +++ b/tests/wire/manage/v1/projects/usage/fields.test.ts @@ -0,0 +1,77 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../../../src/Client"; +import * as Deepgram from "../../../../../../src/api/index"; + +describe("Fields", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + tags: ["tag=dev", "tag=production"], + models: [ + { + name: "2-medical-nova", + language: "en-MY", + version: "2024-05-31.13574", + model_id: "1234567890-12345-67890", + }, + ], + processing_methods: ["sync", "streaming"], + features: ["alternatives", "detect_entities", "detect_language"], + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/usage/fields") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.manage.v1.projects.usage.fields.list("123456-7890-1234-5678-901234", { + start: "start", + end: "end", + }); + expect(response).toEqual({ + tags: ["tag=dev", "tag=production"], + models: [ + { + name: "2-medical-nova", + language: "en-MY", + version: "2024-05-31.13574", + model_id: "1234567890-12345-67890", + }, + ], + processing_methods: ["sync", "streaming"], + features: ["alternatives", "detect_entities", "detect_language"], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/usage/fields") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.manage.v1.projects.usage.fields.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/read/v1/text.test.ts b/tests/wire/read/v1/text.test.ts new file mode 100644 index 00000000..fad5dcda --- /dev/null +++ b/tests/wire/read/v1/text.test.ts @@ -0,0 +1,119 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../src/Client"; +import * as Deepgram from "../../../../src/api/index"; + +describe("Text", () => { + test("analyze (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { url: "url" }; + const rawResponseBody = { + metadata: { + metadata: { + request_id: "d04af392-db11-4c1d-83e1-20e34f0b8999", + created: "2024-11-18T23:47:44Z", + language: "en", + }, + }, + results: { + sentiments: { + segments: [ + { + text: "Yeah. As as much as, um, it's worth celebrating, uh, the first, uh, spacewalk, um, with an all-female team, I think many of us are looking forward to it just being normal. And, um, I think if it signifies anything, it is, uh, to honor the the women who came before us who, um, were skilled and qualified, um, and didn't get the the same opportunities that we have today.", + start_word: 0, + end_word: 69, + sentiment: "positive", + sentiment_score: 0.5810546875, + }, + ], + average: { sentiment: "positive", sentiment_score: 0.5810185185185185 }, + }, + }, + }; + server + .mockEndpoint() + .post("/v1/read") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.read.v1.text.analyze({ + callback: "callback", + callback_method: "POST", + sentiment: true, + summarize: "v2", + tag: "tag", + topics: true, + custom_topic: "custom_topic", + custom_topic_mode: "extended", + intents: true, + custom_intent: "custom_intent", + custom_intent_mode: "extended", + language: "language", + body: { + url: "url", + }, + }); + expect(response).toEqual({ + metadata: { + metadata: { + request_id: "d04af392-db11-4c1d-83e1-20e34f0b8999", + created: "2024-11-18T23:47:44Z", + language: "en", + }, + }, + results: { + sentiments: { + segments: [ + { + text: "Yeah. As as much as, um, it's worth celebrating, uh, the first, uh, spacewalk, um, with an all-female team, I think many of us are looking forward to it just being normal. And, um, I think if it signifies anything, it is, uh, to honor the the women who came before us who, um, were skilled and qualified, um, and didn't get the the same opportunities that we have today.", + start_word: 0, + end_word: 69, + sentiment: "positive", + sentiment_score: 0.5810546875, + }, + ], + average: { + sentiment: "positive", + sentiment_score: 0.5810185185185185, + }, + }, + }, + }); + }); + + test("analyze (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { url: "url" }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/read") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.read.v1.text.analyze({ + body: { + url: "url", + }, + }); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tests/wire/selfHosted/v1/distributionCredentials.test.ts b/tests/wire/selfHosted/v1/distributionCredentials.test.ts new file mode 100644 index 00000000..0d60da6b --- /dev/null +++ b/tests/wire/selfHosted/v1/distributionCredentials.test.ts @@ -0,0 +1,284 @@ +/** + * This file was auto-generated by Fern from our API Definition. + */ + +import { mockServerPool } from "../../../mock-server/MockServerPool"; +import { DeepgramClient } from "../../../../src/Client"; +import * as Deepgram from "../../../../src/api/index"; + +describe("DistributionCredentials", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + distribution_credentials: [ + { + member: { member_id: "3376abcd-8e5e-49d3-92d4-876d3a4f0363", email: "email@example.com" }, + distribution_credentials: { + distribution_credentials_id: "8b36cfd0-472f-4a21-833f-2d6343c3a2f3", + provider: "quay", + comment: "My Self-Hosted Distribution Credentials", + scopes: ["self-hosted:product:api", "self-hosted:product:engine"], + created: "2023-06-28T15:36:59Z", + }, + }, + ], + }; + server + .mockEndpoint() + .get("/v1/projects/123456-7890-1234-5678-901234/self-hosted/distribution/credentials") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.selfHosted.v1.distributionCredentials.list("123456-7890-1234-5678-901234"); + expect(response).toEqual({ + distribution_credentials: [ + { + member: { + member_id: "3376abcd-8e5e-49d3-92d4-876d3a4f0363", + email: "email@example.com", + }, + distribution_credentials: { + distribution_credentials_id: "8b36cfd0-472f-4a21-833f-2d6343c3a2f3", + provider: "quay", + comment: "My Self-Hosted Distribution Credentials", + scopes: ["self-hosted:product:api", "self-hosted:product:engine"], + created: "2023-06-28T15:36:59Z", + }, + }, + ], + }); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/self-hosted/distribution/credentials") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.selfHosted.v1.distributionCredentials.list("project_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("create (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = {}; + const rawResponseBody = { + member: { member_id: "c7b9b131-73f3-11d9-8665-0b00d2e44b83", email: "email@example.com" }, + distribution_credentials: { + distribution_credentials_id: "82c32c10-53b2-4d23-993f-864b3d44502a", + provider: "quay", + comment: "My Self-Hosted Distribution Credentials", + scopes: ["self-hosted:product:api", "self-hosted:product:engine"], + created: "2023-06-28T15:36:59Z", + }, + }; + server + .mockEndpoint() + .post("/v1/projects/123456-7890-1234-5678-901234/self-hosted/distribution/credentials") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.selfHosted.v1.distributionCredentials.create("123456-7890-1234-5678-901234", { + provider: "quay", + }); + expect(response).toEqual({ + member: { + member_id: "c7b9b131-73f3-11d9-8665-0b00d2e44b83", + email: "email@example.com", + }, + distribution_credentials: { + distribution_credentials_id: "82c32c10-53b2-4d23-993f-864b3d44502a", + provider: "quay", + comment: "My Self-Hosted Distribution Credentials", + scopes: ["self-hosted:product:api", "self-hosted:product:engine"], + created: "2023-06-28T15:36:59Z", + }, + }); + }); + + test("create (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + const rawRequestBody = { comment: undefined }; + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .post("/v1/projects/project_id/self-hosted/distribution/credentials") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.selfHosted.v1.distributionCredentials.create("project_id", { + comment: undefined, + }); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + member: { member_id: "c7b9b131-73f3-11d9-8665-0b00d2e44b83", email: "email@example.com" }, + distribution_credentials: { + distribution_credentials_id: "82c32c10-53b2-4d23-993f-864b3d44502a", + provider: "quay", + comment: "My Self-Hosted Distribution Credentials", + scopes: ["self-hosted:product:api", "self-hosted:product:engine"], + created: "2023-06-28T15:36:59Z", + }, + }; + server + .mockEndpoint() + .get( + "/v1/projects/123456-7890-1234-5678-901234/self-hosted/distribution/credentials/8b36cfd0-472f-4a21-833f-2d6343c3a2f3", + ) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.selfHosted.v1.distributionCredentials.get( + "123456-7890-1234-5678-901234", + "8b36cfd0-472f-4a21-833f-2d6343c3a2f3", + ); + expect(response).toEqual({ + member: { + member_id: "c7b9b131-73f3-11d9-8665-0b00d2e44b83", + email: "email@example.com", + }, + distribution_credentials: { + distribution_credentials_id: "82c32c10-53b2-4d23-993f-864b3d44502a", + provider: "quay", + comment: "My Self-Hosted Distribution Credentials", + scopes: ["self-hosted:product:api", "self-hosted:product:engine"], + created: "2023-06-28T15:36:59Z", + }, + }); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .get("/v1/projects/project_id/self-hosted/distribution/credentials/distribution_credentials_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.selfHosted.v1.distributionCredentials.get("project_id", "distribution_credentials_id"); + }).rejects.toThrow(Deepgram.BadRequestError); + }); + + test("delete (1)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { + member: { member_id: "c7b9b131-73f3-11d9-8665-0b00d2e44b83", email: "email@example.com" }, + distribution_credentials: { + distribution_credentials_id: "82c32c10-53b2-4d23-993f-864b3d44502a", + provider: "quay", + comment: "My Self-Hosted Distribution Credentials", + scopes: ["self-hosted:product:api", "self-hosted:product:engine"], + created: "2023-06-28T15:36:59Z", + }, + }; + server + .mockEndpoint() + .delete( + "/v1/projects/123456-7890-1234-5678-901234/self-hosted/distribution/credentials/8b36cfd0-472f-4a21-833f-2d6343c3a2f3", + ) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.selfHosted.v1.distributionCredentials.delete( + "123456-7890-1234-5678-901234", + "8b36cfd0-472f-4a21-833f-2d6343c3a2f3", + ); + expect(response).toEqual({ + member: { + member_id: "c7b9b131-73f3-11d9-8665-0b00d2e44b83", + email: "email@example.com", + }, + distribution_credentials: { + distribution_credentials_id: "82c32c10-53b2-4d23-993f-864b3d44502a", + provider: "quay", + comment: "My Self-Hosted Distribution Credentials", + scopes: ["self-hosted:product:api", "self-hosted:product:engine"], + created: "2023-06-28T15:36:59Z", + }, + }); + }); + + test("delete (2)", async () => { + const server = mockServerPool.createServer(); + const client = new DeepgramClient({ + apiKey: "test", + environment: { base: server.baseUrl, production: server.baseUrl, agent: server.baseUrl }, + }); + + const rawResponseBody = { key: "value" }; + server + .mockEndpoint() + .delete("/v1/projects/project_id/self-hosted/distribution/credentials/distribution_credentials_id") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.selfHosted.v1.distributionCredentials.delete( + "project_id", + "distribution_credentials_id", + ); + }).rejects.toThrow(Deepgram.BadRequestError); + }); +}); diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 00000000..c75083dc --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "extendedDiagnostics": true, + "strict": true, + "target": "ES6", + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "declaration": true, + "outDir": "dist", + "rootDir": "src", + "baseUrl": "src" + }, + "include": ["src"], + "exclude": [] +} diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 00000000..5c11446f --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "CommonJS", + "outDir": "dist/cjs" + }, + "include": ["src"], + "exclude": [] +} diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 00000000..95a5eb73 --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "esnext", + "outDir": "dist/esm" + }, + "include": ["src"], + "exclude": [] +} diff --git a/tsconfig.json b/tsconfig.json index c48bfd9b..d77fdf00 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,22 +1,3 @@ { - "include": ["src", "tests/types"], - "exclude": ["node_modules/**/*.ts"], - "compilerOptions": { - "declaration": true, - "declarationMap": true, - "module": "CommonJS", - "outDir": "dist/main", - "rootDir": "src", - "sourceMap": true, - "target": "ES2015", - - "strict": true, - - "esModuleInterop": true, - "moduleResolution": "Node", - - "forceConsistentCasingInFileNames": true, - "stripInternal": true, - "allowSyntheticDefaultImports": true - } + "extends": "./tsconfig.cjs.json" } diff --git a/tsconfig.module.json b/tsconfig.module.json deleted file mode 100644 index 8726ca43..00000000 --- a/tsconfig.module.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "./tsconfig", - "compilerOptions": { - "module": "ES2020", - "outDir": "dist/module" - } -} diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index 503c9582..00000000 --- a/webpack.config.js +++ /dev/null @@ -1,36 +0,0 @@ -/* eslint-env node */ -/* eslint-disable @typescript-eslint/no-var-requires, @typescript-eslint/no-require-imports */ - -const path = require("path"); - -module.exports = { - entry: "./src/index.ts", - output: { - path: path.resolve(__dirname, "dist/umd"), - filename: "deepgram.js", - library: { - type: "umd", - name: "deepgram", - }, - }, - module: { - rules: [ - { - test: /\.ts$/, - loader: "ts-loader", - options: { - transpileOnly: true, - }, - }, - ], - }, - resolve: { - extensions: [".ts", ".js", ".json"], - fallback: { - stream: require.resolve("stream-browserify"), - buffer: require.resolve("buffer"), - util: require.resolve("util"), - url: require.resolve("url"), - }, - }, -}; diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 00000000..af10758f --- /dev/null +++ b/yarn.lock @@ -0,0 +1,3228 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" + integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== + dependencies: + "@babel/helper-validator-identifier" "^7.27.1" + js-tokens "^4.0.0" + picocolors "^1.1.1" + +"@babel/compat-data@^7.27.2": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.4.tgz#96fdf1af1b8859c8474ab39c295312bfb7c24b04" + integrity sha512-YsmSKC29MJwf0gF8Rjjrg5LQCmyh+j/nD8/eP7f+BeoQTKYqs9RoWbjGOdy0+1Ekr68RJZMUOPVQaQisnIo4Rw== + +"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.4.tgz#12a550b8794452df4c8b084f95003bce1742d496" + integrity sha512-2BCOP7TN8M+gVDj7/ht3hsaO/B/n5oDbiAyyvnRlNOs+u1o+JWNYTQrmpuNp1/Wq2gcFrI01JAW+paEKDMx/CA== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.3" + "@babel/helper-compilation-targets" "^7.27.2" + "@babel/helper-module-transforms" "^7.28.3" + "@babel/helpers" "^7.28.4" + "@babel/parser" "^7.28.4" + "@babel/template" "^7.27.2" + "@babel/traverse" "^7.28.4" + "@babel/types" "^7.28.4" + "@jridgewell/remapping" "^2.3.5" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + +"@babel/generator@^7.28.3", "@babel/generator@^7.7.2": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.3.tgz#9626c1741c650cbac39121694a0f2d7451b8ef3e" + integrity sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw== + dependencies: + "@babel/parser" "^7.28.3" + "@babel/types" "^7.28.2" + "@jridgewell/gen-mapping" "^0.3.12" + "@jridgewell/trace-mapping" "^0.3.28" + jsesc "^3.0.2" + +"@babel/helper-compilation-targets@^7.27.2": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" + integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== + dependencies: + "@babel/compat-data" "^7.27.2" + "@babel/helper-validator-option" "^7.27.1" + browserslist "^4.24.0" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-globals@^7.28.0": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" + integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== + +"@babel/helper-module-imports@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" + integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== + dependencies: + "@babel/traverse" "^7.27.1" + "@babel/types" "^7.27.1" + +"@babel/helper-module-transforms@^7.28.3": + version "7.28.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6" + integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== + dependencies: + "@babel/helper-module-imports" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + "@babel/traverse" "^7.28.3" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" + integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== + +"@babel/helper-string-parser@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" + integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== + +"@babel/helper-validator-identifier@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz#a7054dcc145a967dd4dc8fee845a57c1316c9df8" + integrity sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow== + +"@babel/helper-validator-option@^7.27.1": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" + integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== + +"@babel/helpers@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.4.tgz#fe07274742e95bdf7cf1443593eeb8926ab63827" + integrity sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w== + dependencies: + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.4" + +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.23.9", "@babel/parser@^7.27.2", "@babel/parser@^7.28.3", "@babel/parser@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.4.tgz#da25d4643532890932cc03f7705fe19637e03fa8" + integrity sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg== + dependencies: + "@babel/types" "^7.28.4" + +"@babel/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-class-properties@^7.12.13": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + +"@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-import-attributes@^7.24.7": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07" + integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-syntax-import-meta@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-jsx@^7.7.2": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" + integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + +"@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-top-level-await@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + +"@babel/plugin-syntax-typescript@^7.7.2": + version "7.27.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18" + integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.27.1" + +"@babel/template@^7.27.2", "@babel/template@^7.3.3": + version "7.27.2" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" + integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/parser" "^7.27.2" + "@babel/types" "^7.27.1" + +"@babel/traverse@^7.27.1", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.4.tgz#8d456101b96ab175d487249f60680221692b958b" + integrity sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ== + dependencies: + "@babel/code-frame" "^7.27.1" + "@babel/generator" "^7.28.3" + "@babel/helper-globals" "^7.28.0" + "@babel/parser" "^7.28.4" + "@babel/template" "^7.27.2" + "@babel/types" "^7.28.4" + debug "^4.3.1" + +"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.3.3": + version "7.28.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.4.tgz#0a4e618f4c60a7cd6c11cb2d48060e4dbe38ac3a" + integrity sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q== + dependencies: + "@babel/helper-string-parser" "^7.27.1" + "@babel/helper-validator-identifier" "^7.27.1" + +"@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + +"@bundled-es-modules/cookie@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/cookie/-/cookie-2.0.1.tgz#b41376af6a06b3e32a15241d927b840a9b4de507" + integrity sha512-8o+5fRPLNbjbdGRRmJj3h6Hh1AQJf2dk3qQ/5ZFb+PXkRNiSoMGGUKlsgLfrxneb72axVJyIYji64E2+nNfYyw== + dependencies: + cookie "^0.7.2" + +"@bundled-es-modules/statuses@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@bundled-es-modules/statuses/-/statuses-1.0.1.tgz#761d10f44e51a94902c4da48675b71a76cc98872" + integrity sha512-yn7BklA5acgcBr+7w064fGV+SGIFySjCKpqjcWgBAIfrAkY+4GQTJJHQMeT3V/sgz23VTEVV8TtOmkvJAhFVfg== + dependencies: + statuses "^2.0.1" + +"@inquirer/ansi@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@inquirer/ansi/-/ansi-1.0.0.tgz#29525c673caf36c12e719712830705b9c31f0462" + integrity sha512-JWaTfCxI1eTmJ1BIv86vUfjVatOdxwD0DAVKYevY8SazeUUZtW+tNbsdejVO1GYE0GXJW1N1ahmiC3TFd+7wZA== + +"@inquirer/confirm@^5.0.0": + version "5.1.18" + resolved "https://registry.yarnpkg.com/@inquirer/confirm/-/confirm-5.1.18.tgz#0b76e5082d834c0e3528023705b867fc1222d535" + integrity sha512-MilmWOzHa3Ks11tzvuAmFoAd/wRuaP3SwlT1IZhyMke31FKLxPiuDWcGXhU+PKveNOpAc4axzAgrgxuIJJRmLw== + dependencies: + "@inquirer/core" "^10.2.2" + "@inquirer/type" "^3.0.8" + +"@inquirer/core@^10.2.2": + version "10.2.2" + resolved "https://registry.yarnpkg.com/@inquirer/core/-/core-10.2.2.tgz#d31eb50ba0c76b26e7703c2c0d1d0518144c23ab" + integrity sha512-yXq/4QUnk4sHMtmbd7irwiepjB8jXU0kkFRL4nr/aDBA2mDz13cMakEWdDwX3eSCTkk03kwcndD1zfRAIlELxA== + dependencies: + "@inquirer/ansi" "^1.0.0" + "@inquirer/figures" "^1.0.13" + "@inquirer/type" "^3.0.8" + cli-width "^4.1.0" + mute-stream "^2.0.0" + signal-exit "^4.1.0" + wrap-ansi "^6.2.0" + yoctocolors-cjs "^2.1.2" + +"@inquirer/figures@^1.0.13": + version "1.0.13" + resolved "https://registry.yarnpkg.com/@inquirer/figures/-/figures-1.0.13.tgz#ad0afd62baab1c23175115a9b62f511b6a751e45" + integrity sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw== + +"@inquirer/type@^3.0.8": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@inquirer/type/-/type-3.0.8.tgz#efc293ba0ed91e90e6267f1aacc1c70d20b8b4e8" + integrity sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + +"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + +"@jest/console@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" + integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + +"@jest/core@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" + integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== + dependencies: + "@jest/console" "^29.7.0" + "@jest/reporters" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + ci-info "^3.2.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^29.7.0" + jest-config "^29.7.0" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-resolve-dependencies "^29.7.0" + jest-runner "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + jest-watcher "^29.7.0" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + +"@jest/environment@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" + integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== + dependencies: + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + +"@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + +"@jest/expect@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" + integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== + dependencies: + expect "^29.7.0" + jest-snapshot "^29.7.0" + +"@jest/fake-timers@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" + integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== + dependencies: + "@jest/types" "^29.6.3" + "@sinonjs/fake-timers" "^10.0.2" + "@types/node" "*" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +"@jest/globals@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" + integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/types" "^29.6.3" + jest-mock "^29.7.0" + +"@jest/reporters@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" + integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^6.0.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + jest-worker "^29.7.0" + slash "^3.0.0" + string-length "^4.0.1" + strip-ansi "^6.0.0" + v8-to-istanbul "^9.0.1" + +"@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + +"@jest/source-map@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" + integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.18" + callsites "^3.0.0" + graceful-fs "^4.2.9" + +"@jest/test-result@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" + integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== + dependencies: + "@jest/console" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + +"@jest/test-sequencer@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" + integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== + dependencies: + "@jest/test-result" "^29.7.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + slash "^3.0.0" + +"@jest/transform@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" + integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== + dependencies: + "@babel/core" "^7.11.6" + "@jest/types" "^29.6.3" + "@jridgewell/trace-mapping" "^0.3.18" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^2.0.0" + fast-json-stable-stringify "^2.1.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + write-file-atomic "^4.0.2" + +"@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" + integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/remapping@^2.3.5": + version "2.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" + integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.24" + +"@jridgewell/resolve-uri@^3.1.0": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" + integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== + +"@jridgewell/source-map@^0.3.3": + version "0.3.11" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" + integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== + dependencies: + "@jridgewell/gen-mapping" "^0.3.5" + "@jridgewell/trace-mapping" "^0.3.25" + +"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.5" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" + integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== + +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": + version "0.3.31" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" + integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + +"@mswjs/interceptors@^0.39.1": + version "0.39.6" + resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.39.6.tgz#44094a578f20da4749d1a0eaf3cdb7973604004b" + integrity sha512-bndDP83naYYkfayr/qhBHMhk0YGwS1iv6vaEGcr0SQbO0IZtbOPqjKjds/WcG+bJA+1T5vCx6kprKOzn5Bg+Vw== + dependencies: + "@open-draft/deferred-promise" "^2.2.0" + "@open-draft/logger" "^0.3.0" + "@open-draft/until" "^2.0.0" + is-node-process "^1.2.0" + outvariant "^1.4.3" + strict-event-emitter "^0.5.1" + +"@open-draft/deferred-promise@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz#4a822d10f6f0e316be4d67b4d4f8c9a124b073bd" + integrity sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA== + +"@open-draft/logger@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@open-draft/logger/-/logger-0.3.0.tgz#2b3ab1242b360aa0adb28b85f5d7da1c133a0954" + integrity sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ== + dependencies: + is-node-process "^1.2.0" + outvariant "^1.4.0" + +"@open-draft/until@^2.0.0", "@open-draft/until@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@open-draft/until/-/until-2.1.0.tgz#0acf32f470af2ceaf47f095cdecd40d68666efda" + integrity sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg== + +"@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + +"@sinonjs/commons@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" + integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== + dependencies: + type-detect "4.0.8" + +"@sinonjs/fake-timers@^10.0.2": + version "10.3.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" + integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== + dependencies: + "@sinonjs/commons" "^3.0.0" + +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + +"@types/babel__core@^7.1.14": + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + +"@types/babel__generator@*": + version "7.27.0" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9" + integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== + dependencies: + "@babel/types" "^7.0.0" + +"@types/babel__template@*": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + +"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": + version "7.28.0" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz#07d713d6cce0d265c9849db0cbe62d3f61f36f74" + integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q== + dependencies: + "@babel/types" "^7.28.2" + +"@types/cookie@^0.6.0": + version "0.6.0" + resolved "https://registry.yarnpkg.com/@types/cookie/-/cookie-0.6.0.tgz#eac397f28bf1d6ae0ae081363eca2f425bedf0d5" + integrity sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA== + +"@types/eslint-scope@^3.7.7": + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + +"@types/eslint@*": + version "9.6.1" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" + integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + +"@types/estree@*", "@types/estree@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" + integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== + +"@types/graceful-fs@^4.1.3": + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== + dependencies: + "@types/node" "*" + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== + +"@types/istanbul-lib-report@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== + dependencies: + "@types/istanbul-lib-report" "*" + +"@types/jest@^29.5.14": + version "29.5.14" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.14.tgz#2b910912fa1d6856cadcd0c1f95af7df1d6049e5" + integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + +"@types/jsdom@^20.0.0": + version "20.0.1" + resolved "https://registry.yarnpkg.com/@types/jsdom/-/jsdom-20.0.1.tgz#07c14bc19bd2f918c1929541cdaacae894744808" + integrity sha512-d0r18sZPmMQr1eG35u12FZfhIXNrnsPU/g5wvRKCUf/tOGilKKwYMYGqh33BNR6ba+2gkHw1EUiHoN3mn7E5IQ== + dependencies: + "@types/node" "*" + "@types/tough-cookie" "*" + parse5 "^7.0.0" + +"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== + +"@types/node@*": + version "24.5.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.5.2.tgz#52ceb83f50fe0fcfdfbd2a9fab6db2e9e7ef6446" + integrity sha512-FYxk1I7wPv3K2XBaoyH2cTnocQEu8AOZ60hPbsyukMPLv5/5qr7V1i8PLHdl6Zf87I+xZXFvPCXYjiTFq+YSDQ== + dependencies: + undici-types "~7.12.0" + +"@types/node@^18.19.70": + version "18.19.127" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.127.tgz#7c2e47fa79ad7486134700514d4a975c4607f09d" + integrity sha512-gSjxjrnKXML/yo0BO099uPixMqfpJU0TKYjpfLU7TrtA2WWDki412Np/RSTPRil1saKBhvVVKzVx/p/6p94nVA== + dependencies: + undici-types "~5.26.4" + +"@types/stack-utils@^2.0.0": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== + +"@types/statuses@^2.0.4": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/statuses/-/statuses-2.0.6.tgz#66748315cc9a96d63403baa8671b2c124f8633aa" + integrity sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA== + +"@types/tough-cookie@*": + version "4.0.5" + resolved "https://registry.yarnpkg.com/@types/tough-cookie/-/tough-cookie-4.0.5.tgz#cb6e2a691b70cb177c6e3ae9c1d2e8b2ea8cd304" + integrity sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA== + +"@types/yargs-parser@*": + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== + +"@types/yargs@^17.0.8": + version "17.0.33" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.33.tgz#8c32303da83eec050a84b3c7ae7b9f922d13e32d" + integrity sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA== + dependencies: + "@types/yargs-parser" "*" + +"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" + integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== + dependencies: + "@webassemblyjs/helper-numbers" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + +"@webassemblyjs/floating-point-hex-parser@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" + integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== + +"@webassemblyjs/helper-api-error@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" + integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== + +"@webassemblyjs/helper-buffer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" + integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== + +"@webassemblyjs/helper-numbers@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" + integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.13.2" + "@webassemblyjs/helper-api-error" "1.13.2" + "@xtuc/long" "4.2.2" + +"@webassemblyjs/helper-wasm-bytecode@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" + integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== + +"@webassemblyjs/helper-wasm-section@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" + integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/wasm-gen" "1.14.1" + +"@webassemblyjs/ieee754@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" + integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== + dependencies: + "@xtuc/ieee754" "^1.2.0" + +"@webassemblyjs/leb128@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" + integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== + dependencies: + "@xtuc/long" "4.2.2" + +"@webassemblyjs/utf8@1.13.2": + version "1.13.2" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" + integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== + +"@webassemblyjs/wasm-edit@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" + integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/helper-wasm-section" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-opt" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + "@webassemblyjs/wast-printer" "1.14.1" + +"@webassemblyjs/wasm-gen@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" + integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" + +"@webassemblyjs/wasm-opt@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" + integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-buffer" "1.14.1" + "@webassemblyjs/wasm-gen" "1.14.1" + "@webassemblyjs/wasm-parser" "1.14.1" + +"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" + integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@webassemblyjs/helper-api-error" "1.13.2" + "@webassemblyjs/helper-wasm-bytecode" "1.13.2" + "@webassemblyjs/ieee754" "1.13.2" + "@webassemblyjs/leb128" "1.13.2" + "@webassemblyjs/utf8" "1.13.2" + +"@webassemblyjs/wast-printer@1.14.1": + version "1.14.1" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" + integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== + dependencies: + "@webassemblyjs/ast" "1.14.1" + "@xtuc/long" "4.2.2" + +"@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + +"@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + +abab@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + +acorn-globals@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-7.0.1.tgz#0dbf05c44fa7c94332914c02066d5beff62c40c3" + integrity sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q== + dependencies: + acorn "^8.1.0" + acorn-walk "^8.0.2" + +acorn-import-phases@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" + integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== + +acorn-walk@^8.0.2: + version "8.3.4" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.4.tgz#794dd169c3977edf4ba4ea47583587c5866236b7" + integrity sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g== + dependencies: + acorn "^8.11.0" + +acorn@^8.1.0, acorn@^8.11.0, acorn@^8.15.0, acorn@^8.8.1: + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== + +agent-base@6: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + +ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + +ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@^8.0.0, ajv@^8.9.0: + version "8.17.1" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" + integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== + dependencies: + fast-deep-equal "^3.1.3" + fast-uri "^3.0.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + +ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +anymatch@^3.0.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +babel-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" + integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== + dependencies: + "@jest/transform" "^29.7.0" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^29.6.3" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + +babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-jest-hoist@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" + integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.1.14" + "@types/babel__traverse" "^7.0.6" + +babel-preset-current-node-syntax@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz#20730d6cdc7dda5d89401cab10ac6a32067acde6" + integrity sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-import-attributes" "^7.24.7" + "@babel/plugin-syntax-import-meta" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + +babel-preset-jest@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" + integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== + dependencies: + babel-plugin-jest-hoist "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +baseline-browser-mapping@^2.8.3: + version "2.8.6" + resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.8.6.tgz#c37dea4291ed8d01682f85661dbe87967028642e" + integrity sha512-wrH5NNqren/QMtKUEEJf7z86YjfqW/2uw3IL3/xpqZUC95SSVIFXYQeeGjL6FT/X68IROu6RMehZQS5foy2BXw== + +brace-expansion@^1.1.7: + version "1.1.12" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" + integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== + dependencies: + fill-range "^7.1.1" + +browserslist@^4.24.0: + version "4.26.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.26.2.tgz#7db3b3577ec97f1140a52db4936654911078cef3" + integrity sha512-ECFzp6uFOSB+dcZ5BK/IBaGWssbSYBHvuMeMt3MMFyhI0Z8SqGgEkBLARgpRH3hutIgPVsALcMwbDrJqPxQ65A== + dependencies: + baseline-browser-mapping "^2.8.3" + caniuse-lite "^1.0.30001741" + electron-to-chromium "^1.5.218" + node-releases "^2.0.21" + update-browserslist-db "^1.1.3" + +bs-logger@^0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" + integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== + dependencies: + es-errors "^1.3.0" + function-bind "^1.1.2" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +caniuse-lite@^1.0.30001741: + version "1.0.30001743" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001743.tgz#50ff91a991220a1ee2df5af00650dd5c308ea7cd" + integrity sha512-e6Ojr7RV14Un7dz6ASD0aZDmQPT/A+eZU+nuTNfjqmRrmkmQlnTNWH0SKmqagx9PeW87UVqapSurtAXifmtdmw== + +chalk@^4.0.0, chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + +chrome-trace-event@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" + integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== + +ci-info@^3.2.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + +cjs-module-lexer@^1.0.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" + integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== + +cli-width@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-4.1.0.tgz#42daac41d3c254ef38ad8ac037672130173691c5" + integrity sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ== + +cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + +collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + +cookie@^0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" + integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== + +create-jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" + integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-config "^29.7.0" + jest-util "^29.7.0" + prompts "^2.0.1" + +cross-spawn@^7.0.3: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cssom@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" + integrity sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw== + +cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + +cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + +data-urls@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-3.0.2.tgz#9cf24a477ae22bcef5cd5f6f0bfbc1d2d3be9143" + integrity sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ== + dependencies: + abab "^2.0.6" + whatwg-mimetype "^3.0.0" + whatwg-url "^11.0.0" + +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: + version "4.4.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" + integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== + dependencies: + ms "^2.1.3" + +decimal.js@^10.4.2: + version "10.6.0" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.6.0.tgz#e649a43e3ab953a72192ff5983865e509f37ed9a" + integrity sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg== + +dedent@^1.0.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.0.tgz#c1f9445335f0175a96587be245a282ff451446ca" + integrity sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ== + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + +diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + +domexception@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-4.0.0.tgz#4ad1be56ccadc86fc76d033353999a8037d03673" + integrity sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw== + dependencies: + webidl-conversions "^7.0.0" + +dunder-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" + integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== + dependencies: + call-bind-apply-helpers "^1.0.1" + es-errors "^1.3.0" + gopd "^1.2.0" + +electron-to-chromium@^1.5.218: + version "1.5.221" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.221.tgz#bd98014b2a247701c4ebd713080448d539545d79" + integrity sha512-/1hFJ39wkW01ogqSyYoA4goOXOtMRy6B+yvA1u42nnsEGtHzIzmk93aPISumVQeblj47JUHLC9coCjUxb1EvtQ== + +emittery@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" + integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.3: + version "5.18.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz#9b5f4c5c076b8787c78fe540392ce76a88855b44" + integrity sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +entities@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.1.tgz#c28c34a43379ca7f61d074130b2f5f7020a30694" + integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g== + +error-ex@^1.3.1: + version "1.3.4" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.4.tgz#b3a8d8bb6f92eecc1629e3e27d3c8607a8a32414" + integrity sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ== + dependencies: + is-arrayish "^0.2.1" + +es-define-property@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" + integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== + +es-errors@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" + integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== + +es-module-lexer@^1.2.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" + integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== + +es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" + integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== + dependencies: + es-errors "^1.3.0" + +es-set-tostringtag@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" + integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== + dependencies: + es-errors "^1.3.0" + get-intrinsic "^1.2.6" + has-tostringtag "^1.0.2" + hasown "^2.0.2" + +escalade@^3.1.1, escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== + +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionalDependencies: + source-map "~0.6.1" + +eslint-scope@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +events@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + +expect@^29.0.0, expect@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + +fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-uri@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" + integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== + +fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + +fill-range@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" + integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== + dependencies: + to-regex-range "^5.0.1" + +find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +form-data@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4" + integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + es-set-tostringtag "^2.1.0" + hasown "^2.0.2" + mime-types "^2.1.12" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@^2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-intrinsic@^1.2.6: + version "1.3.0" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" + integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== + dependencies: + call-bind-apply-helpers "^1.0.2" + es-define-property "^1.0.1" + es-errors "^1.3.0" + es-object-atoms "^1.1.1" + function-bind "^1.1.2" + get-proto "^1.0.1" + gopd "^1.2.0" + has-symbols "^1.1.0" + hasown "^2.0.2" + math-intrinsics "^1.1.0" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" + integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== + dependencies: + dunder-proto "^1.0.1" + es-object-atoms "^1.0.0" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + +glob@^7.1.3, glob@^7.1.4: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +gopd@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" + integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== + +graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphql@^16.8.1: + version "16.11.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.11.0.tgz#96d17f66370678027fdf59b2d4c20b4efaa8a633" + integrity sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw== + +handlebars@^4.7.8: + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.2" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has-symbols@^1.0.3, has-symbols@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" + integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== + +has-tostringtag@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" + integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== + dependencies: + has-symbols "^1.0.3" + +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +headers-polyfill@^4.0.2: + version "4.0.3" + resolved "https://registry.yarnpkg.com/headers-polyfill/-/headers-polyfill-4.0.3.tgz#922a0155de30ecc1f785bcf04be77844ca95ad07" + integrity sha512-IScLbePpkvO846sIwOtOTDjutRMWdXdJmXdMvk6gCBHxFO8d+QKOQedyZSxFTTFYRSmlgSTDtXqqq4pcenBXLQ== + +html-encoding-sniffer@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz#2cb1a8cf0db52414776e5b2a7a04d5dd98158de9" + integrity sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA== + dependencies: + whatwg-encoding "^2.0.0" + +html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + +https-proxy-agent@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + +iconv-lite@0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +import-local@^3.0.2: + version "3.2.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" + integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + +is-core-module@^2.16.0: + version "2.16.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" + integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== + dependencies: + hasown "^2.0.2" + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + +is-node-process@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-node-process/-/is-node-process-1.2.0.tgz#ea02a1b90ddb3934a19aea414e88edef7e11d134" + integrity sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw== + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== + +istanbul-lib-instrument@^5.0.4: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + +istanbul-lib-instrument@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" + integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== + dependencies: + "@babel/core" "^7.23.9" + "@babel/parser" "^7.23.9" + "@istanbuljs/schema" "^0.1.3" + istanbul-lib-coverage "^3.2.0" + semver "^7.5.4" + +istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + +istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + +istanbul-reports@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.2.0.tgz#cb4535162b5784aa623cee21a7252cf2c807ac93" + integrity sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + +jest-changed-files@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" + integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== + dependencies: + execa "^5.0.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + +jest-circus@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" + integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/expect" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^1.0.0" + is-generator-fn "^2.0.0" + jest-each "^29.7.0" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-runtime "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + p-limit "^3.1.0" + pretty-format "^29.7.0" + pure-rand "^6.0.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-cli@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" + integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== + dependencies: + "@jest/core" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + chalk "^4.0.0" + create-jest "^29.7.0" + exit "^0.1.2" + import-local "^3.0.2" + jest-config "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + yargs "^17.3.1" + +jest-config@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" + integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== + dependencies: + "@babel/core" "^7.11.6" + "@jest/test-sequencer" "^29.7.0" + "@jest/types" "^29.6.3" + babel-jest "^29.7.0" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-circus "^29.7.0" + jest-environment-node "^29.7.0" + jest-get-type "^29.6.3" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-runner "^29.7.0" + jest-util "^29.7.0" + jest-validate "^29.7.0" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^29.7.0" + slash "^3.0.0" + strip-json-comments "^3.1.1" + +jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-docblock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" + integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== + dependencies: + detect-newline "^3.0.0" + +jest-each@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" + integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== + dependencies: + "@jest/types" "^29.6.3" + chalk "^4.0.0" + jest-get-type "^29.6.3" + jest-util "^29.7.0" + pretty-format "^29.7.0" + +jest-environment-jsdom@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.7.0.tgz#d206fa3551933c3fd519e5dfdb58a0f5139a837f" + integrity sha512-k9iQbsf9OyOfdzWH8HDmrRT0gSIcX+FLNW7IQq94tFX0gynPwqDTW0Ho6iMVNjGz/nb+l/vW3dWM2bbLLpkbXA== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/jsdom" "^20.0.0" + "@types/node" "*" + jest-mock "^29.7.0" + jest-util "^29.7.0" + jsdom "^20.0.0" + +jest-environment-node@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" + integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-mock "^29.7.0" + jest-util "^29.7.0" + +jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + +jest-haste-map@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" + integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== + dependencies: + "@jest/types" "^29.6.3" + "@types/graceful-fs" "^4.1.3" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^29.6.3" + jest-util "^29.7.0" + jest-worker "^29.7.0" + micromatch "^4.0.4" + walker "^1.0.8" + optionalDependencies: + fsevents "^2.3.2" + +jest-leak-detector@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" + integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== + dependencies: + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + +jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + +jest-mock@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" + integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + jest-util "^29.7.0" + +jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + +jest-regex-util@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" + integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== + +jest-resolve-dependencies@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" + integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== + dependencies: + jest-regex-util "^29.6.3" + jest-snapshot "^29.7.0" + +jest-resolve@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" + integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== + dependencies: + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-pnp-resolver "^1.2.2" + jest-util "^29.7.0" + jest-validate "^29.7.0" + resolve "^1.20.0" + resolve.exports "^2.0.0" + slash "^3.0.0" + +jest-runner@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" + integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== + dependencies: + "@jest/console" "^29.7.0" + "@jest/environment" "^29.7.0" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.13.1" + graceful-fs "^4.2.9" + jest-docblock "^29.7.0" + jest-environment-node "^29.7.0" + jest-haste-map "^29.7.0" + jest-leak-detector "^29.7.0" + jest-message-util "^29.7.0" + jest-resolve "^29.7.0" + jest-runtime "^29.7.0" + jest-util "^29.7.0" + jest-watcher "^29.7.0" + jest-worker "^29.7.0" + p-limit "^3.1.0" + source-map-support "0.5.13" + +jest-runtime@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" + integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== + dependencies: + "@jest/environment" "^29.7.0" + "@jest/fake-timers" "^29.7.0" + "@jest/globals" "^29.7.0" + "@jest/source-map" "^29.6.3" + "@jest/test-result" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^29.7.0" + jest-message-util "^29.7.0" + jest-mock "^29.7.0" + jest-regex-util "^29.6.3" + jest-resolve "^29.7.0" + jest-snapshot "^29.7.0" + jest-util "^29.7.0" + slash "^3.0.0" + strip-bom "^4.0.0" + +jest-snapshot@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" + integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== + dependencies: + "@babel/core" "^7.11.6" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-jsx" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/types" "^7.3.3" + "@jest/expect-utils" "^29.7.0" + "@jest/transform" "^29.7.0" + "@jest/types" "^29.6.3" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^29.7.0" + graceful-fs "^4.2.9" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + natural-compare "^1.4.0" + pretty-format "^29.7.0" + semver "^7.5.3" + +jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + +jest-validate@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" + integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== + dependencies: + "@jest/types" "^29.6.3" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^29.6.3" + leven "^3.1.0" + pretty-format "^29.7.0" + +jest-watcher@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" + integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== + dependencies: + "@jest/test-result" "^29.7.0" + "@jest/types" "^29.6.3" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.13.1" + jest-util "^29.7.0" + string-length "^4.0.1" + +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest-worker@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" + integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== + dependencies: + "@types/node" "*" + jest-util "^29.7.0" + merge-stream "^2.0.0" + supports-color "^8.0.0" + +jest@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" + integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== + dependencies: + "@jest/core" "^29.7.0" + "@jest/types" "^29.6.3" + import-local "^3.0.2" + jest-cli "^29.7.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsdom@^20.0.0: + version "20.0.3" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-20.0.3.tgz#886a41ba1d4726f67a8858028c99489fed6ad4db" + integrity sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ== + dependencies: + abab "^2.0.6" + acorn "^8.8.1" + acorn-globals "^7.0.0" + cssom "^0.5.0" + cssstyle "^2.3.0" + data-urls "^3.0.2" + decimal.js "^10.4.2" + domexception "^4.0.0" + escodegen "^2.0.0" + form-data "^4.0.0" + html-encoding-sniffer "^3.0.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.1" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.2" + parse5 "^7.1.1" + saxes "^6.0.0" + symbol-tree "^3.2.4" + tough-cookie "^4.1.2" + w3c-xmlserializer "^4.0.0" + webidl-conversions "^7.0.0" + whatwg-encoding "^2.0.0" + whatwg-mimetype "^3.0.0" + whatwg-url "^11.0.0" + ws "^8.11.0" + xml-name-validator "^4.0.0" + +jsesc@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" + integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== + +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + +json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + +json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + +make-error@^1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + +math-intrinsics@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" + integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +micromatch@^4.0.0, micromatch@^4.0.4: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12, mime-types@^2.1.27: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +minimatch@^3.0.4, minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimist@^1.2.5: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +msw@^2.8.4: + version "2.11.2" + resolved "https://registry.yarnpkg.com/msw/-/msw-2.11.2.tgz#622d83855f456a5f93b1528f6eb6f4c0114623c3" + integrity sha512-MI54hLCsrMwiflkcqlgYYNJJddY5/+S0SnONvhv1owOplvqohKSQyGejpNdUGyCwgs4IH7PqaNbPw/sKOEze9Q== + dependencies: + "@bundled-es-modules/cookie" "^2.0.1" + "@bundled-es-modules/statuses" "^1.0.1" + "@inquirer/confirm" "^5.0.0" + "@mswjs/interceptors" "^0.39.1" + "@open-draft/deferred-promise" "^2.2.0" + "@open-draft/until" "^2.1.0" + "@types/cookie" "^0.6.0" + "@types/statuses" "^2.0.4" + graphql "^16.8.1" + headers-polyfill "^4.0.2" + is-node-process "^1.2.0" + outvariant "^1.4.3" + path-to-regexp "^6.3.0" + picocolors "^1.1.1" + rettime "^0.7.0" + strict-event-emitter "^0.5.1" + tough-cookie "^6.0.0" + type-fest "^4.26.1" + yargs "^17.7.2" + +mute-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-2.0.0.tgz#a5446fc0c512b71c83c44d908d5c7b7b4c493b2b" + integrity sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-releases@^2.0.21: + version "2.0.21" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.21.tgz#f59b018bc0048044be2d4c4c04e4c8b18160894c" + integrity sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw== + +normalize-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + +nwsapi@^2.2.2: + version "2.2.22" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.22.tgz#109f9530cda6c156d6a713cdf5939e9f0de98b9d" + integrity sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +outvariant@^1.4.0, outvariant@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/outvariant/-/outvariant-1.4.3.tgz#221c1bfc093e8fec7075497e7799fdbf43d14873" + integrity sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA== + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + +parse5@^7.0.0, parse5@^7.1.1: + version "7.3.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.3.0.tgz#d7e224fa72399c7a175099f45fc2ad024b05ec05" + integrity sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw== + dependencies: + entities "^6.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-to-regexp@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-6.3.0.tgz#2b6a26a337737a8e1416f9272ed0766b1c0389f4" + integrity sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ== + +picocolors@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" + integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== + +picomatch@^2.0.4, picomatch@^2.2.3, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pirates@^4.0.4: + version "4.0.7" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" + integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== + +pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +prettier@^3.4.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.6.2.tgz#ccda02a1003ebbb2bfda6f83a074978f608b9393" + integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ== + +pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + +prompts@^2.0.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +psl@^1.1.33: + version "1.15.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.15.0.tgz#bdace31896f1d97cec6a79e8224898ce93d974c6" + integrity sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w== + dependencies: + punycode "^2.3.1" + +punycode@^2.1.1, punycode@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + +pure-rand@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.1.0.tgz#d173cf23258231976ccbdb05247c9787957604f2" + integrity sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA== + +querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +react-is@^18.0.0: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + +resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve.exports@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.3.tgz#41955e6f1b4013b7586f873749a635dea07ebe3f" + integrity sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A== + +resolve@^1.20.0: + version "1.22.10" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" + integrity sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w== + dependencies: + is-core-module "^2.16.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rettime@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/rettime/-/rettime-0.7.0.tgz#c040f1a65e396eaa4b8346dd96ed937edc79d96f" + integrity sha512-LPRKoHnLKd/r3dVxcwO7vhCW+orkOGj9ViueosEBK6ie89CijnfRlhaDhHq/3Hxu4CkWQtxwlBG0mzTQY6uQjw== + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +saxes@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" + integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== + dependencies: + xmlchars "^2.2.0" + +schema-utils@^4.3.0, schema-utils@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.2.tgz#0c10878bf4a73fd2b1dfd14b9462b26788c806ae" + integrity sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + +semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.3.4, semver@^7.5.3, semver@^7.5.4, semver@^7.7.2: + version "7.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + +serialize-javascript@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" + integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== + dependencies: + randombytes "^2.1.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +signal-exit@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-support@0.5.13: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +source-map@^0.7.4: + version "0.7.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.6.tgz#a3658ab87e5b6429c8a1f3ba0083d4c61ca3ef02" + integrity sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + +stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + +statuses@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + +strict-event-emitter@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz#1602ece81c51574ca39c6815e09f1a3e8550bd93" + integrity sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ== + +string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + +string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + +tapable@^2.1.1, tapable@^2.2.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.3.tgz#4b67b635b2d97578a06a2713d2f04800c237e99b" + integrity sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg== + +terser-webpack-plugin@^5.3.11: + version "5.3.14" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz#9031d48e57ab27567f02ace85c7d690db66c3e06" + integrity sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw== + dependencies: + "@jridgewell/trace-mapping" "^0.3.25" + jest-worker "^27.4.5" + schema-utils "^4.3.0" + serialize-javascript "^6.0.2" + terser "^5.31.1" + +terser@^5.31.1: + version "5.44.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.44.0.tgz#ebefb8e5b8579d93111bfdfc39d2cf63879f4a82" + integrity sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.15.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + +tldts-core@^7.0.14: + version "7.0.14" + resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-7.0.14.tgz#eb49edf8a39a37a2372ffc22f82d6ac725ace6cd" + integrity sha512-viZGNK6+NdluOJWwTO9olaugx0bkKhscIdriQQ+lNNhwitIKvb+SvhbYgnCz6j9p7dX3cJntt4agQAKMXLjJ5g== + +tldts@^7.0.5: + version "7.0.14" + resolved "https://registry.yarnpkg.com/tldts/-/tldts-7.0.14.tgz#5dc352e087c12978b7d1d36d8a346496e04dca72" + integrity sha512-lMNHE4aSI3LlkMUMicTmAG3tkkitjOQGDTFboPJwAg2kJXKP1ryWEyqujktg5qhrFZOkk5YFzgkxg3jErE+i5w== + dependencies: + tldts-core "^7.0.14" + +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tough-cookie@^4.1.2: + version "4.1.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" + integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" + +tough-cookie@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-6.0.0.tgz#11e418b7864a2c0d874702bc8ce0f011261940e5" + integrity sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w== + dependencies: + tldts "^7.0.5" + +tr46@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-3.0.0.tgz#555c4e297a950617e8eeddef633c87d4d9d6cbf9" + integrity sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA== + dependencies: + punycode "^2.1.1" + +ts-jest@^29.3.4: + version "29.4.3" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.4.3.tgz#23264489bebb5b3e2c7966dbf6788e960f244f7c" + integrity sha512-KTWbK2Wot8VXargsLoxhSoEQ9OyMdzQXQoUDeIulWu2Tf7gghuBHeg+agZqVLdTOHhQHVKAaeuctBDRkhWE7hg== + dependencies: + bs-logger "^0.2.6" + fast-json-stable-stringify "^2.1.0" + handlebars "^4.7.8" + json5 "^2.2.3" + lodash.memoize "^4.1.2" + make-error "^1.3.6" + semver "^7.7.2" + type-fest "^4.41.0" + yargs-parser "^21.1.1" + +ts-loader@^9.5.1: + version "9.5.4" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.4.tgz#44b571165c10fb5a90744aa5b7e119233c4f4585" + integrity sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.0.0" + micromatch "^4.0.0" + semver "^7.3.4" + source-map "^0.7.4" + +type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +type-fest@^4.26.1, type-fest@^4.41.0: + version "4.41.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" + integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== + +typescript@~5.7.2: + version "5.7.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.3.tgz#919b44a7dbb8583a9b856d162be24a54bf80073e" + integrity sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw== + +uglify-js@^3.1.4: + version "3.19.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" + integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +undici-types@~7.12.0: + version "7.12.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.12.0.tgz#15c5c7475c2a3ba30659529f5cdb4674b622fafb" + integrity sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ== + +universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + +update-browserslist-db@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz#348377dd245216f9e7060ff50b15a1b740b75420" + integrity sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw== + dependencies: + escalade "^3.2.0" + picocolors "^1.1.1" + +url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + +v8-to-istanbul@^9.0.1: + version "9.3.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" + integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" + +w3c-xmlserializer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073" + integrity sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw== + dependencies: + xml-name-validator "^4.0.0" + +walker@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +watchpack@^2.4.1: + version "2.4.4" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947" + integrity sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +webidl-conversions@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-7.0.0.tgz#256b4e1882be7debbf01d05f0aa2039778ea080a" + integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== + +webpack-sources@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" + integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== + +webpack@^5.97.1: + version "5.101.3" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.101.3.tgz#3633b2375bb29ea4b06ffb1902734d977bc44346" + integrity sha512-7b0dTKR3Ed//AD/6kkx/o7duS8H3f1a4w3BYpIriX4BzIhjkn4teo05cptsxvLesHFKK5KObnadmCHBwGc+51A== + dependencies: + "@types/eslint-scope" "^3.7.7" + "@types/estree" "^1.0.8" + "@types/json-schema" "^7.0.15" + "@webassemblyjs/ast" "^1.14.1" + "@webassemblyjs/wasm-edit" "^1.14.1" + "@webassemblyjs/wasm-parser" "^1.14.1" + acorn "^8.15.0" + acorn-import-phases "^1.0.3" + browserslist "^4.24.0" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.17.3" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.11" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^4.3.2" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.11" + watchpack "^2.4.1" + webpack-sources "^3.3.3" + +whatwg-encoding@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz#e7635f597fd87020858626805a2729fa7698ac53" + integrity sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg== + dependencies: + iconv-lite "0.6.3" + +whatwg-mimetype@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz#5fa1a7623867ff1af6ca3dc72ad6b8a4208beba7" + integrity sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q== + +whatwg-url@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-11.0.0.tgz#0a849eebb5faf2119b901bb76fd795c2848d4018" + integrity sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ== + dependencies: + tr46 "^3.0.0" + webidl-conversions "^7.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +write-file-atomic@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" + integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^3.0.7" + +ws@^8.11.0: + version "8.18.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" + integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== + +xml-name-validator@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-4.0.0.tgz#79a006e2e63149a8600f15430f0a4725d1524835" + integrity sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw== + +xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + +yargs@^17.3.1, yargs@^17.7.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +yoctocolors-cjs@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz#7e4964ea8ec422b7a40ac917d3a344cfd2304baa" + integrity sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==