diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 61d002b8..2722edf6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,6 +6,7 @@ on: pull_request: branches: - master + - next jobs: lint: @@ -21,11 +22,30 @@ jobs: with: node-version: '18' - - name: Install dependencies - run: yarn install + - name: Bootstrap + run: ./scripts/bootstrap - name: Check types run: ./scripts/lint + + build: + name: build + runs-on: ubuntu-latest + + + steps: + - uses: actions/checkout@v4 + + - name: Set up Node + uses: actions/setup-node@v4 + with: + node-version: '18' + + - name: Bootstrap + run: ./scripts/bootstrap + + - name: Check build + run: ./scripts/build test: name: test runs-on: ubuntu-latest diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml index 79da5707..7994d1b0 100644 --- a/.github/workflows/release-doctor.yml +++ b/.github/workflows/release-doctor.yml @@ -1,6 +1,8 @@ name: Release Doctor on: pull_request: + branches: + - master workflow_dispatch: jobs: @@ -17,3 +19,4 @@ jobs: bash ./bin/check-release-environment env: NPM_TOKEN: ${{ secrets.MUX_NPM_TOKEN || secrets.NPM_TOKEN }} + diff --git a/.gitignore b/.gitignore index 9a5858a7..d98d51a8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,10 @@ +.prism.log node_modules yarn-error.log codegen.log Brewfile.lock.json dist -/deno +dist-deno /*.tgz .idea/ diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 6139450a..92856693 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "8.8.0" + ".": "9.0.0" } diff --git a/.stats.yml b/.stats.yml index f83fa025..d4e14fb0 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ -configured_endpoints: 97 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mux%2Fmux-b1c7a231d90814e227c4a339a6760d1b05b04b874ffc7763affbad6a2c11d418.yml +configured_endpoints: 88 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mux%2Fmux-5bc9dec57cc47596441c1af33503b43275966e117bb43d2d6c3c5301a1644330.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e607e31..dcf751a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,55 @@ # Changelog +## 9.0.0 (2024-11-14) + +Full Changelog: [v8.8.0...v9.0.0](https://github.com/muxinc/mux-node-sdk/compare/v8.8.0...v9.0.0) + +### Breaking Changes +* Remove support for Spaces + +### Features +* Add support for View Dropped Percentage and `view_dropped` in Mux Data. +* Add support for signing multiple tokens (with various `aud` types) for signed playback policies in a single call. +* Add support for `premium` assets in Mux Video. [Read more here](https://www.mux.com/blog/one-size-does-not-fit-all-introducing-premium-video-quality-for-mux-video). +* Add full support for DRM for Mux Video. [Read more here](https://www.mux.com/blog/introducing-drm-the-latest-tool-in-protecting-your-content-on-mux). +* Add support for updating `master_access` settings on live streams. +* Add support for user agent-based Playback Restrictions. +* **client:** send retry count header ([#493](https://github.com/muxinc/mux-node-sdk/issues/493)) ([f202eef](https://github.com/muxinc/mux-node-sdk/commit/f202eef237847862097850bb4387452df762bce6)) + +### Deprecations +* Deprecate `encoding_tier` in favor of `video_quality` (to support `premium` assets) + +### Bug Fixes +* add missing types for encoding tier, generated subtitles settings and multi-track audio ([#319](https://github.com/muxinc/mux-node-sdk/issues/319)) ([16d20ad](https://github.com/muxinc/mux-node-sdk/commit/16d20ad310a6dbff4b4cf5fbce17a4cea72e2b4c)) +* add resolution_tier and max_resolution_tier ([#314](https://github.com/muxinc/mux-node-sdk/issues/314)) ([ff1586b](https://github.com/muxinc/mux-node-sdk/commit/ff1586b4503ab943c0c0682c2f4d15705ca7248b)) +* allow git imports for pnpm ([#412](https://github.com/muxinc/mux-node-sdk/issues/412)) ([d7f6e32](https://github.com/muxinc/mux-node-sdk/commit/d7f6e32c8e7affa18fbd2e0aa7d78e744c868f11)) +* **client:** correct File construction from node-fetch Responses ([#478](https://github.com/muxinc/mux-node-sdk/issues/478)) ([37cc57c](https://github.com/muxinc/mux-node-sdk/commit/37cc57c0c0fea5228529be15cfcbb3691f23f65f)) +* **client:** correctly send deno version header ([#356](https://github.com/muxinc/mux-node-sdk/issues/356)) ([3b59a43](https://github.com/muxinc/mux-node-sdk/commit/3b59a434662af71d04e9bc123d89e23919663fb7)) +* **compat:** remove ReadableStream polyfill redundant since node v16 ([#460](https://github.com/muxinc/mux-node-sdk/issues/460)) ([66b4d45](https://github.com/muxinc/mux-node-sdk/commit/66b4d45a42f4324cdfda08b9675a47cdc648ecb5)) +* correct response type for generate subtitles ([#385](https://github.com/muxinc/mux-node-sdk/issues/385)) ([5b05c0c](https://github.com/muxinc/mux-node-sdk/commit/5b05c0cb86913bd98b8f504cfdb1b900ea85efae)) +* **errors:** pass message through to APIConnectionError ([#486](https://github.com/muxinc/mux-node-sdk/issues/486)) ([56485cc](https://github.com/muxinc/mux-node-sdk/commit/56485ccaf60112ec0802afcea1f9700443c47da5)) +* handle process.env being undefined in debug func ([#354](https://github.com/muxinc/mux-node-sdk/issues/354)) ([e90a964](https://github.com/muxinc/mux-node-sdk/commit/e90a9646f4c1f729861c4e46d1c77ec2eb8846e4)) +* **internal:** make toFile use input file's options ([#350](https://github.com/muxinc/mux-node-sdk/issues/350)) ([0f8c319](https://github.com/muxinc/mux-node-sdk/commit/0f8c319611c939abf31559d5338dacc2026e18ae)) +* package.json & yarn.lock to reduce vulnerabilities ([bd8af62](https://github.com/muxinc/mux-node-sdk/commit/bd8af62afa6bc7fe2fe43969fcfa2b86cf4a6b7e)) +* **package:** revert recent client file change ([#394](https://github.com/muxinc/mux-node-sdk/issues/394)) ([f520093](https://github.com/muxinc/mux-node-sdk/commit/f52009351aa21640d0aadb53d2e182a0d1da001f)) +* remove lingering file ([6014f6f](https://github.com/muxinc/mux-node-sdk/commit/6014f6fecf578a466913fcc1a8a74be901055f88)) +* **shims:** export JWT shims for bun ([#369](https://github.com/muxinc/mux-node-sdk/issues/369)) ([84833ab](https://github.com/muxinc/mux-node-sdk/commit/84833ab802b3b1c7aeee4e58af63ddcc4b35f9f1)) +* **types:** remove leftover polyfill usage ([#492](https://github.com/muxinc/mux-node-sdk/issues/492)) ([6d7f768](https://github.com/muxinc/mux-node-sdk/commit/6d7f76858dccefc61e31096209b7979d45614406)) +* update casing for "drm" ([#425](https://github.com/muxinc/mux-node-sdk/issues/425)) ([34cf334](https://github.com/muxinc/mux-node-sdk/commit/34cf33429db0f9e76dd16378725a60019f4dbdda)) +* **uploads:** avoid making redundant memory copies ([#483](https://github.com/muxinc/mux-node-sdk/issues/483)) ([f24c5bd](https://github.com/muxinc/mux-node-sdk/commit/f24c5bd629c947335ca57ca7fd7b3559cd5c5d6c)) +* use relative paths ([#458](https://github.com/muxinc/mux-node-sdk/issues/458)) ([96adde9](https://github.com/muxinc/mux-node-sdk/commit/96adde9d26599001ae82349eaad43f810250bf2c)) + +### Documentation + +* add jwt helpers, webhooks, and version upgrade content back to readme ([#342](https://github.com/muxinc/mux-node-sdk/issues/342)) ([f339b9e](https://github.com/muxinc/mux-node-sdk/commit/f339b9e542e4d74055a14b84a7d2c68741f34101)) +* add release steps ([2432cf8](https://github.com/muxinc/mux-node-sdk/commit/2432cf824e05031c332ebbfd4ec94c5365e12e0f)) +* add upgrade to v8 guide back in ([5837819](https://github.com/muxinc/mux-node-sdk/commit/58378196949b91f8a966eb04c498d5dc24bc851b)) +* fix typo in CONTRIBUTING.md ([#347](https://github.com/muxinc/mux-node-sdk/issues/347)) ([59af6cd](https://github.com/muxinc/mux-node-sdk/commit/59af6cdbdea2084effec55dd6ae30fbf80cff0ec)) +* **readme:** add bundle size badge ([#409](https://github.com/muxinc/mux-node-sdk/issues/409)) ([ce5c0d7](https://github.com/muxinc/mux-node-sdk/commit/ce5c0d73d52790d6986ec9276c8f6d39fb6c3523)) +* **readme:** consistent use of sentence case in headings ([#351](https://github.com/muxinc/mux-node-sdk/issues/351)) ([fc5fdbf](https://github.com/muxinc/mux-node-sdk/commit/fc5fdbf56f66fa5dd01018d0f62be9f50978588f)) +* **readme:** document how to make undocumented requests ([#353](https://github.com/muxinc/mux-node-sdk/issues/353)) ([abdba1e](https://github.com/muxinc/mux-node-sdk/commit/abdba1e3aaee117d8dedfa0faf1281cdcce66549)) +* update CONTRIBUTING.md ([#488](https://github.com/muxinc/mux-node-sdk/issues/488)) ([f1bc68d](https://github.com/muxinc/mux-node-sdk/commit/f1bc68d07aaaf7512ab363cc9f2c72755bc5b4c1)) + ## 8.8.0 (2024-06-14) Full Changelog: [v8.7.1...v8.8.0](https://github.com/muxinc/mux-node-sdk/compare/v8.7.1...v8.8.0) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8caca971..4645e0eb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,24 +5,24 @@ Other package managers may work but are not officially supported for development To set up the repository, run: -```bash -yarn -yarn build +```sh +$ yarn +$ yarn build ``` This will install all the required dependencies and build output files to `dist/`. ## Modifying/Adding code -Most of the SDK is generated code, and any modified code will be overridden on the next generation. The -`src/lib/` and `examples/` directories are exceptions and will never be overridden. +Most of the SDK is generated code. Modifications to code will be persisted between generations, but may +result in merge conflicts between manual patches and changes from the generator. The generator will never +modify the contents of the `src/lib/` and `examples/` directories. ## Adding and running examples -All files in the `examples/` directory are not modified by the Stainless generator and can be freely edited or -added to. +All files in the `examples/` directory are not modified by the generator and can be freely edited or added to. -```bash +```ts // add an example to examples/.ts #!/usr/bin/env -S npm run tsn -T @@ -41,38 +41,38 @@ If you’d like to use the repository from source, you can either install from g To install via git: -```bash -npm install git+ssh://git@github.com:muxinc/mux-node-sdk.git +```sh +$ npm install git+ssh://git@github.com:muxinc/mux-node-sdk.git ``` Alternatively, to link a local copy of the repo: -```bash +```sh # Clone -git clone https://www.github.com/muxinc/mux-node-sdk -cd mux-node-sdk +$ git clone https://www.github.com/muxinc/mux-node-sdk +$ cd mux-node-sdk # With yarn -yarn link -cd ../my-package -yarn link @mux/mux-node +$ yarn link +$ cd ../my-package +$ yarn link @mux/mux-node # With pnpm -pnpm link --global -cd ../my-package -pnpm link -—global @mux/mux-node +$ pnpm link --global +$ cd ../my-package +$ pnpm link -—global @mux/mux-node ``` ## Running tests Most tests require you to [set up a mock server](https://github.com/stoplightio/prism) against the OpenAPI spec to run the tests. -```bash -npx prism mock path/to/your/openapi.yml +```sh +$ npx prism mock path/to/your/openapi.yml ``` -```bash -yarn run test +```sh +$ yarn run test ``` ## Linting and formatting @@ -82,14 +82,14 @@ This repository uses [prettier](https://www.npmjs.com/package/prettier) and To lint: -```bash -yarn lint +```sh +$ yarn lint ``` To format and fix all lint issues automatically: -```bash -yarn fix +```sh +$ yarn fix ``` ## Publishing and releases diff --git a/README.md b/README.md index 267f10e5..d645befa 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This library provides convenient access to the Mux REST API from server-side Typ > [!NOTE] > In February 2024 this SDK was updated to Version 8.0. For upgrading to 8.x see [UPGRADE_8.x.md](https://github.com/muxinc/mux-node-sdk/blob/master/UPGRADE_8.x.md) -The REST API documentation can be found [on docs.mux.com](https://docs.mux.com). The full API of this library can be found in [api.md](api.md). +The REST API documentation can be found on [docs.mux.com](https://docs.mux.com). The full API of this library can be found in [api.md](api.md). ## Installation @@ -23,13 +23,13 @@ The full API of this library can be found in [api.md](api.md). ```js import Mux from '@mux/mux-node'; -const mux = new Mux({ +const client = new Mux({ tokenId: process.env['MUX_TOKEN_ID'], // This is the default and can be omitted tokenSecret: process.env['MUX_TOKEN_SECRET'], // This is the default and can be omitted }); async function main() { - const asset = await mux.video.assets.create({ + const asset = await client.video.assets.create({ input: [{ url: 'https://storage.googleapis.com/muxdemofiles/mux-video-intro.mp4' }], }); @@ -47,7 +47,7 @@ This library includes TypeScript definitions for all request params and response ```ts import Mux from '@mux/mux-node'; -const mux = new Mux({ +const client = new Mux({ tokenId: process.env['MUX_TOKEN_ID'], // This is the default and can be omitted tokenSecret: process.env['MUX_TOKEN_SECRET'], // This is the default and can be omitted }); @@ -56,7 +56,7 @@ async function main() { const params: Mux.Video.AssetCreateParams = { input: [{ url: 'https://storage.googleapis.com/muxdemofiles/mux-video-intro.mp4' }], }; - const asset: Mux.Video.Asset = await mux.video.assets.create(params); + const asset: Mux.Video.Asset = await client.video.assets.create(params); } main(); @@ -106,6 +106,57 @@ const statsToken = mux.jwt.signViewerCounts('some-live-stream-id', { // https://stats.mux.com/counts?token={statsToken} ``` +### Signing multiple JWTs at once +In cases you need multiple tokens, like when using Mux Player, things can get unwieldy pretty quickly. For example, +```tsx +const playbackToken = await mux.jwt.signPlaybackId(id, { + expiration: "1d", + type: "playback" +}) +const thumbnailToken = await mux.jwt.signPlaybackId(id, { + expiration: "1d", + type: "thumbnail", +}) +const storyboardToken = await mux.jwt.signPlaybackId(id, { + expiration: "1d", + type: "storyboard" +}) +const drmToken = await mux.jwt.signPlaybackId(id, { + expiration: "1d", + type: "drm_license" +}) + + +``` + +To simplify this use-case, you can provide multiple types to `signPlaybackId` to recieve multiple tokens. These tokens are provided in a format that Mux Player can take as props: +```tsx +// { "playback-token", "thumbnail-token", "storyboard-token", "drm-token" } +const tokens = await mux.jwt.signPlaybackId(id, { + expiration: "1d", + type: ["playback", "thumbnail", "storyboard", "drm_license"] +}) + + +``` + +If you would like to provide params to a single token (e.g., if you would like to have a thumbnail `time`), you can provide `[type, typeParams]` instead of `type`: +```tsx +const tokens = await mux.jwt.signPlaybackId(id, { + expiration: "1d", + type: ["playback", ["thumbnail", { time: 2 }], "storyboard", "drm_license"] +}) +``` + ## Parsing Webhook payloads To validate that the given payload was sent by Mux and parse the webhook payload for use in your application, @@ -231,7 +282,7 @@ a subclass of `APIError` will be thrown: ```ts async function main() { - const liveStream = await mux.video.liveStreams.create().catch(async (err) => { + const liveStream = await client.video.liveStreams.create().catch(async (err) => { if (err instanceof Mux.APIError) { console.log(err.status); // 400 console.log(err.name); // BadRequestError @@ -269,12 +320,12 @@ You can use the `maxRetries` option to configure or disable this: ```js // Configure the default for all requests: -const mux = new Mux({ +const client = new Mux({ maxRetries: 0, // default is 2 }); // Or, configure per-request: -await mux.video.assets.retrieve('t02rm...', { +await client.video.assets.retrieve('t02rm...', { maxRetries: 5, }); ``` @@ -286,12 +337,12 @@ Requests time out after 1 minute by default. You can configure this with a `time ```ts // Configure the default for all requests: -const mux = new Mux({ +const client = new Mux({ timeout: 20 * 1000, // 20 seconds (default is 1 minute) }); // Override per-request: -await mux.video.assets.retrieve('t02rm...', { +await client.video.assets.retrieve('t02rm...', { timeout: 5 * 1000, }); ``` @@ -303,30 +354,30 @@ Note that requests which time out will be [retried twice by default](#retries). ## Auto-pagination List methods in the Mux API are paginated. -You can use `for await … of` syntax to iterate through items across all pages: +You can use the `for await … of` syntax to iterate through items across all pages: ```ts async function fetchAllVideoDeliveryUsages(params) { const allVideoDeliveryUsages = []; // Automatically fetches more pages as needed. - for await (const deliveryReport of mux.video.deliveryUsage.list()) { + for await (const deliveryReport of client.video.deliveryUsage.list()) { allVideoDeliveryUsages.push(deliveryReport); } return allVideoDeliveryUsages; } ``` -Alternatively, you can make request a single page at a time: +Alternatively, you can request a single page at a time: ```ts -let page = await mux.video.deliveryUsage.list(); +let page = await client.video.deliveryUsage.list(); for (const deliveryReport of page.data) { console.log(deliveryReport); } // Convenience methods are provided for manually paginating: while (page.hasNextPage()) { - page = page.getNextPage(); + page = await page.getNextPage(); // ... } ``` @@ -341,15 +392,15 @@ You can also use the `.withResponse()` method to get the raw `Response` along wi ```ts -const mux = new Mux(); +const client = new Mux(); -const response = await mux.video.assets +const response = await client.video.assets .create({ input: [{ url: 'https://storage.googleapis.com/muxdemofiles/mux-video-intro.mp4' }] }) .asResponse(); console.log(response.headers.get('X-My-Header')); console.log(response.statusText); // access the underlying Response object -const { data: asset, response: raw } = await mux.video.assets +const { data: asset, response: raw } = await client.video.assets .create({ input: [{ url: 'https://storage.googleapis.com/muxdemofiles/mux-video-intro.mp4' }] }) .withResponse(); console.log(raw.headers.get('X-My-Header')); @@ -452,12 +503,12 @@ import http from 'http'; import { HttpsProxyAgent } from 'https-proxy-agent'; // Configure the default for all requests: -const mux = new Mux({ +const client = new Mux({ httpAgent: new HttpsProxyAgent(process.env.PROXY_URL), }); // Override per-request: -await mux.video.assets.retrieve('t02rm...', { +await client.video.assets.retrieve('t02rm...', { httpAgent: new http.Agent({ keepAlive: false }), }); ``` @@ -480,6 +531,7 @@ TypeScript >= 4.5 is supported. The following runtimes are supported: +- Web browsers (Up-to-date Chrome, Firefox, Safari, Edge, and more) - Node.js 18 LTS or later ([non-EOL](https://endoflife.date/nodejs)) versions. - Deno v1.28.0 or higher, using `import Mux from "npm:@mux/mux-node"`. - Bun 1.0 or later. @@ -491,3 +543,7 @@ The following runtimes are supported: Note that React Native is not supported at this time. If you are interested in other runtime environments, please open or upvote an issue on GitHub. + +## Contributing + +See [the contributing documentation](./CONTRIBUTING.md). diff --git a/api.md b/api.md index 9f3f5cc1..14c3e4dc 100644 --- a/api.md +++ b/api.md @@ -99,32 +99,6 @@ Methods: - client.video.playbackRestrictions.updateReferrer(playbackRestrictionId, { ...params }) -> PlaybackRestriction - client.video.playbackRestrictions.updateUserAgent(playbackRestrictionId, { ...params }) -> PlaybackRestriction -## Spaces - -Types: - -- Broadcast -- BroadcastLayout -- BroadcastResolution -- BroadcastResponse -- BroadcastStatus -- Space -- SpaceResponse -- SpaceStatus -- SpaceType - -Methods: - -- client.video.spaces.create({ ...params }) -> Space -- client.video.spaces.retrieve(spaceId) -> Space -- client.video.spaces.list({ ...params }) -> SpacesBasePage -- client.video.spaces.delete(spaceId) -> void -- client.video.spaces.createBroadcast(spaceId, { ...params }) -> Broadcast -- client.video.spaces.deleteBroadcast(spaceId, broadcastId) -> void -- client.video.spaces.retrieveBroadcast(spaceId, broadcastId) -> Broadcast -- client.video.spaces.startBroadcast(spaceId, broadcastId) -> void -- client.video.spaces.stopBroadcast(spaceId, broadcastId) -> void - ## TranscriptionVocabularies Types: @@ -385,15 +359,6 @@ Types: - VideoLiveStreamSimulcastTargetErroredWebhookEvent - VideoLiveStreamSimulcastTargetDeletedWebhookEvent - VideoLiveStreamSimulcastTargetUpdatedWebhookEvent -- VideoSpaceCreatedWebhookEvent -- VideoSpaceDeletedWebhookEvent -- VideoSpaceActiveWebhookEvent -- VideoSpaceIdleWebhookEvent -- VideoSpaceUpdatedWebhookEvent -- VideoSpaceBroadcastCreatedWebhookEvent -- VideoSpaceBroadcastIdleWebhookEvent -- VideoSpaceBroadcastActiveWebhookEvent -- VideoSpaceBroadcastDeletedWebhookEvent - VideoDeliveryHighTrafficWebhookEvent - UnwrapWebhookEvent @@ -402,7 +367,7 @@ Methods: - client.webhooks.unwrap(body, headers, secret) -> UnwrapWebhookEvent - client.webhooks.verifySignature(body, headers, secret) -> void -# Jwt +# JWT Methods: diff --git a/bin/check-release-environment b/bin/check-release-environment index dad893e5..6978b230 100644 --- a/bin/check-release-environment +++ b/bin/check-release-environment @@ -19,3 +19,4 @@ if [[ lenErrors -gt 0 ]]; then fi echo "The environment is ready to push releases!" + diff --git a/bin/publish-npm b/bin/publish-npm index 4d6c9f35..4c21181b 100644 --- a/bin/publish-npm +++ b/bin/publish-npm @@ -2,8 +2,24 @@ set -eux -npm config set //registry.npmjs.org/:_authToken $NPM_TOKEN +npm config set '//registry.npmjs.org/:_authToken' "$NPM_TOKEN" +# Build the project yarn build + +# Navigate to the dist directory cd dist -yarn publish --access public + +# Get the version from package.json +VERSION="$(node -p "require('./package.json').version")" + +# Extract the pre-release tag if it exists +if [[ "$VERSION" =~ -([a-zA-Z]+) ]]; then + # Extract the part before any dot in the pre-release identifier + TAG="${BASH_REMATCH[1]}" +else + TAG="latest" +fi + +# Publish with the appropriate tag +yarn publish --access public --tag "$TAG" diff --git a/deno_tests/api-resources/jwt.test.ts b/deno_tests/api-resources/jwt.test.ts index 38e5b8fb..08a990d5 100644 --- a/deno_tests/api-resources/jwt.test.ts +++ b/deno_tests/api-resources/jwt.test.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. import Mux from '../../deno/mod.ts'; -import { TypeClaim, DataTypeClaim } from '../../deno/util/jwt-types.ts'; +import { TypeClaim, DataTypeClaim, TypeToken } from '../../deno/util/jwt-types.ts'; import { jwtVerify, importJWK, importPKCS8 } from 'https://deno.land/x/jose@v4.14.4/index.ts'; import { assertObjectMatch } from 'https://deno.land/std@0.197.0/testing/asserts.ts'; import { publicJwk, privatePkcs1, privatePkcs8 } from '../../tests/api-resources/rsaKeys.ts'; @@ -199,3 +199,77 @@ Deno.test(async function signViewerCounts() { }, ); }); + +Deno.test('signPlaybackId multiple types returns same tokens as multiple single calls', async () => { + const id = 'abcdefgh'; + const expiration = '1d'; + + const playbackToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'video', + }); + const thumbnailToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'thumbnail', + }); + const storyboardToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'storyboard', + }); + const drmToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'drm_license', + }); + const gifToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'gif', + }); + const statsToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'stats', + }); + + const tokens = await mux.jwt.signPlaybackId(id, { + expiration, + type: ['video', 'thumbnail', 'storyboard', 'drm_license', 'gif', 'stats'], + }); + + assertEquals(tokens[TypeToken.video], playbackToken); + assertEquals(tokens[TypeToken.thumbnail], thumbnailToken); + assertEquals(tokens[TypeToken.storyboard], storyboardToken); + assertEquals(tokens[TypeToken.drm_license], drmToken); + assertEquals(tokens[TypeToken.gif], gifToken); + assertEquals(tokens[TypeToken.stats], statsToken); +}); + +Deno.test( + 'signPlaybackId multiple types with params returns same tokens as multiple single calls', + async () => { + const id = 'abcdefgh'; + const expiration = '1d'; + + const playbackToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'video', + }); + const thumbnailParams = { time: '2' }; + const thumbnailToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'thumbnail', + params: thumbnailParams, + }); + const storyboardToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'storyboard', + }); + + const tokens = await mux.jwt.signPlaybackId(id, { + expiration, + type: ['video', ['thumbnail', thumbnailParams], 'storyboard'], + }); + + assertEquals(tokens[TypeToken.video], playbackToken); + assertEquals(tokens[TypeToken.thumbnail], thumbnailToken); + assertEquals(tokens[TypeToken.storyboard], storyboardToken); + }, +); diff --git a/package.json b/package.json index a5baaa24..6ec10c3e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mux/mux-node", - "version": "8.8.0", + "version": "9.0.0", "description": "The official TypeScript library for the Mux API", "author": "Mux ", "types": "dist/index.d.ts", @@ -10,7 +10,7 @@ "license": "Apache-2.0", "packageManager": "yarn@1.22.22", "files": [ - "*" + "**/*" ], "private": false, "scripts": { @@ -21,20 +21,17 @@ "prepare": "if ./scripts/utils/check-is-in-git-install.sh; then ./scripts/build; fi", "tsn": "ts-node -r tsconfig-paths/register", "lint": "./scripts/lint", - "fix": "eslint --fix --ext ts,js ." + "fix": "./scripts/format" }, "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", - "@types/qs": "^6.9.7", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "jose": "^4.14.4", - "node-fetch": "^2.6.7", - "qs": "^6.10.3", - "web-streams-polyfill": "^3.2.1" + "node-fetch": "^2.6.7" }, "devDependencies": { "@swc/core": "^1.3.102", @@ -45,10 +42,10 @@ "eslint": "^8.49.0", "eslint-plugin-prettier": "^5.0.1", "eslint-plugin-unused-imports": "^3.0.0", + "iconv-lite": "^0.6.3", "jest": "^29.4.0", "prettier": "^3.0.0", "ts-jest": "^29.1.0", - "ts-morph": "^19.0.0", "ts-node": "^10.5.0", "tsc-multi": "^1.1.0", "tsconfig-paths": "^4.0.0", diff --git a/scripts/build b/scripts/build index 8881680f..f46b7e6e 100755 --- a/scripts/build +++ b/scripts/build @@ -50,7 +50,7 @@ node scripts/utils/postprocess-files.cjs (cd dist && node -e 'require("@mux/mux-node")') (cd dist && node -e 'import("@mux/mux-node")' --input-type=module) -if command -v deno &> /dev/null && [ -e ./scripts/build-deno ] +if [ -e ./scripts/build-deno ] then ./scripts/build-deno fi diff --git a/scripts/format b/scripts/format index d297e762..a6bb9d03 100755 --- a/scripts/format +++ b/scripts/format @@ -5,4 +5,4 @@ set -e cd "$(dirname "$0")/.." echo "==> Running eslint --fix" -./node_modules/.bin/eslint --fix --ext ts,js . +ESLINT_USE_FLAT_CONFIG="false" ./node_modules/.bin/eslint --fix --ext ts,js . diff --git a/scripts/lint b/scripts/lint index 6b0e5dc3..6ba75dfb 100755 --- a/scripts/lint +++ b/scripts/lint @@ -5,4 +5,7 @@ set -e cd "$(dirname "$0")/.." echo "==> Running eslint" -./node_modules/.bin/eslint --ext ts,js . +ESLINT_USE_FLAT_CONFIG="false" ./node_modules/.bin/eslint --ext ts,js . + +echo "==> Running tsc" +./node_modules/.bin/tsc --noEmit diff --git a/scripts/mock b/scripts/mock index fe89a1d0..d2814ae6 100755 --- a/scripts/mock +++ b/scripts/mock @@ -21,7 +21,7 @@ echo "==> Starting mock server with URL ${URL}" # Run prism mock on the given spec if [ "$1" == "--daemon" ]; then - npm exec --package=@stoplight/prism-cli@~5.8 -- prism mock "$URL" &> .prism.log & + npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL" &> .prism.log & # Wait for server to come online echo -n "Waiting for server" @@ -37,5 +37,5 @@ if [ "$1" == "--daemon" ]; then echo else - npm exec --package=@stoplight/prism-cli@~5.8 -- prism mock "$URL" + npm exec --package=@stainless-api/prism-cli@5.8.5 -- prism mock "$URL" fi diff --git a/src/_shims/node-runtime.ts b/src/_shims/node-runtime.ts index a9c42ebe..ab9f2ab5 100644 --- a/src/_shims/node-runtime.ts +++ b/src/_shims/node-runtime.ts @@ -13,9 +13,7 @@ import { Readable } from 'node:stream'; import { type RequestOptions } from '../core'; import { MultipartBody } from './MultipartBody'; import { type Shims } from './registry'; - -// @ts-ignore (this package does not have proper export maps for this export) -import { ReadableStream } from 'web-streams-polyfill/dist/ponyfill.es2018.js'; +import { ReadableStream } from 'node:stream/web'; type FileFromPathOptions = Omit; diff --git a/src/_shims/node-types.d.ts b/src/_shims/node-types.d.ts index b31698f7..c159e5fa 100644 --- a/src/_shims/node-types.d.ts +++ b/src/_shims/node-types.d.ts @@ -7,7 +7,7 @@ import * as fd from 'formdata-node'; export { type Agent } from 'node:http'; export { type Readable } from 'node:stream'; export { type ReadStream as FsReadStream } from 'node:fs'; -export { ReadableStream } from 'web-streams-polyfill'; +export { ReadableStream } from 'node:stream/web'; export const fetch: typeof nf.default; diff --git a/src/core.ts b/src/core.ts index 13a1531c..790e1848 100644 --- a/src/core.ts +++ b/src/core.ts @@ -84,8 +84,10 @@ export class APIPromise extends Promise { }); } - _thenUnwrap(transform: (data: T) => U): APIPromise { - return new APIPromise(this.responsePromise, async (props) => transform(await this.parseResponse(props))); + _thenUnwrap(transform: (data: T, props: APIResponseProps) => U): APIPromise { + return new APIPromise(this.responsePromise, async (props) => + transform(await this.parseResponse(props), props), + ); } /** @@ -262,7 +264,10 @@ export abstract class APIClient { return null; } - buildRequest(options: FinalRequestOptions): { req: RequestInit; url: string; timeout: number } { + buildRequest( + options: FinalRequestOptions, + { retryCount = 0 }: { retryCount?: number } = {}, + ): { req: RequestInit; url: string; timeout: number } { const { method, path, query, headers: headers = {} } = options; const body = @@ -292,7 +297,7 @@ export abstract class APIClient { headers[this.idempotencyHeader] = options.idempotencyKey; } - const reqHeaders = this.buildHeaders({ options, headers, contentLength }); + const reqHeaders = this.buildHeaders({ options, headers, contentLength, retryCount }); const req: RequestInit = { method, @@ -311,10 +316,12 @@ export abstract class APIClient { options, headers, contentLength, + retryCount, }: { options: FinalRequestOptions; headers: Record; contentLength: string | null | undefined; + retryCount: number; }): Record { const reqHeaders: Record = {}; if (contentLength) { @@ -330,6 +337,16 @@ export abstract class APIClient { delete reqHeaders['content-type']; } + // Don't set the retry count header if it was already set or removed through default headers or by the + // caller. We check `defaultHeaders` and `headers`, which can contain nulls, instead of `reqHeaders` to + // account for the removal case. + if ( + getHeader(defaultHeaders, 'x-stainless-retry-count') === undefined && + getHeader(headers, 'x-stainless-retry-count') === undefined + ) { + reqHeaders['x-stainless-retry-count'] = String(retryCount); + } + this.validateHeaders(reqHeaders, headers); return reqHeaders; @@ -365,7 +382,7 @@ export abstract class APIClient { error: Object | undefined, message: string | undefined, headers: Headers | undefined, - ) { + ): APIError { return APIError.generate(status, error, message, headers); } @@ -381,13 +398,14 @@ export abstract class APIClient { retriesRemaining: number | null, ): Promise { const options = await optionsInput; + const maxRetries = options.maxRetries ?? this.maxRetries; if (retriesRemaining == null) { - retriesRemaining = options.maxRetries ?? this.maxRetries; + retriesRemaining = maxRetries; } await this.prepareOptions(options); - const { req, url, timeout } = this.buildRequest(options); + const { req, url, timeout } = this.buildRequest(options, { retryCount: maxRetries - retriesRemaining }); await this.prepareRequest(req, { url, options }); @@ -636,9 +654,9 @@ export abstract class AbstractPage implements AsyncIterable { return await this.#client.requestAPIList(this.constructor as any, nextOptions); } - async *iterPages() { + async *iterPages(): AsyncGenerator { // eslint-disable-next-line @typescript-eslint/no-this-alias - let page: AbstractPage = this; + let page: this = this; yield page; while (page.hasNextPage()) { page = await page.getNextPage(); @@ -646,7 +664,7 @@ export abstract class AbstractPage implements AsyncIterable { } } - async *[Symbol.asyncIterator]() { + async *[Symbol.asyncIterator](): AsyncGenerator { for await (const page of this.iterPages()) { for (const item of page.getPaginatedItems()) { yield item; @@ -689,7 +707,7 @@ export class PagePromise< * console.log(item) * } */ - async *[Symbol.asyncIterator]() { + async *[Symbol.asyncIterator](): AsyncGenerator { const page = await this; for await (const item of page) { yield item; @@ -959,6 +977,11 @@ const validatePositiveInteger = (name: string, n: unknown): number => { export const castToError = (err: any): Error => { if (err instanceof Error) return err; + if (typeof err === 'object' && err !== null) { + try { + return new Error(JSON.stringify(err)); + } catch {} + } return new Error(err); }; @@ -1096,7 +1119,15 @@ export const isHeadersProtocol = (headers: any): headers is HeadersProtocol => { return typeof headers?.get === 'function'; }; -export const getRequiredHeader = (headers: HeadersLike, header: string): string => { +export const getRequiredHeader = (headers: HeadersLike | Headers, header: string): string => { + const foundHeader = getHeader(headers, header); + if (foundHeader === undefined) { + throw new Error(`Could not find ${header} header`); + } + return foundHeader; +}; + +export const getHeader = (headers: HeadersLike | Headers, header: string): string | undefined => { const lowerCasedHeader = header.toLowerCase(); if (isHeadersProtocol(headers)) { // to deal with the case where the header looks like Stainless-Event-Id @@ -1122,7 +1153,7 @@ export const getRequiredHeader = (headers: HeadersLike, header: string): string } } - throw new Error(`Could not find ${header} header`); + return undefined; }; /** diff --git a/src/error.ts b/src/error.ts index c28e6f25..764b9185 100644 --- a/src/error.ts +++ b/src/error.ts @@ -47,9 +47,9 @@ export class APIError extends MuxError { errorResponse: Object | undefined, message: string | undefined, headers: Headers | undefined, - ) { + ): APIError { if (!status) { - return new APIConnectionError({ cause: castToError(errorResponse) }); + return new APIConnectionError({ message, cause: castToError(errorResponse) }); } const error = errorResponse as Record; @@ -101,7 +101,7 @@ export class APIUserAbortError extends APIError { export class APIConnectionError extends APIError { override readonly status: undefined = undefined; - constructor({ message, cause }: { message?: string; cause?: Error | undefined }) { + constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) { super(undefined, undefined, message || 'Connection error.', undefined); // in some environments the 'cause' property is already declared // @ts-ignore diff --git a/src/index.ts b/src/index.ts index 4c7c0a3b..486c4a54 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,12 +1,22 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. +import { type Agent } from './_shims/index'; +import * as qs from './internal/qs'; import * as Core from './core'; import * as Errors from './error'; -import { type Agent } from './_shims/index'; +import * as Pagination from './pagination'; +import { + type BasePageParams, + BasePageResponse, + type PageWithTotalParams, + PageWithTotalResponse, +} from './pagination'; import * as Uploads from './uploads'; -import * as qs from 'qs'; -import * as Pagination from '@mux/mux-node/pagination'; -import * as API from '@mux/mux-node/resources/index'; +import * as API from './resources/index'; +import { Webhooks } from './resources/webhooks'; +import { Data } from './resources/data/data'; +import { System } from './resources/system/system'; +import { Video } from './resources/video/video'; export interface ClientOptions { /** @@ -91,7 +101,9 @@ export interface ClientOptions { defaultQuery?: Core.DefaultQuery; } -/** API Client for interfacing with the Mux API. */ +/** + * API Client for interfacing with the Mux API. + */ export class Mux extends Core.APIClient { tokenId: string; tokenSecret: string; @@ -154,6 +166,7 @@ export class Mux extends Core.APIClient { maxRetries: options.maxRetries, fetch: options.fetch, }); + this._options = options; this.tokenId = tokenId; @@ -199,6 +212,7 @@ export class Mux extends Core.APIClient { } static Mux = this; + static DEFAULT_TIMEOUT = 60000; // 1 minute static MuxError = Errors.MuxError; static APIError = Errors.APIError; @@ -218,7 +232,38 @@ export class Mux extends Core.APIClient { static fileFromPath = Uploads.fileFromPath; } -export const { +Mux.Video = Video; +Mux.Data = Data; +Mux.System = System; +Mux.Webhooks = Webhooks; +export declare namespace Mux { + export type RequestOptions = Core.RequestOptions; + + export import PageWithTotal = Pagination.PageWithTotal; + export { + type PageWithTotalParams as PageWithTotalParams, + type PageWithTotalResponse as PageWithTotalResponse, + }; + + export import BasePage = Pagination.BasePage; + export { type BasePageParams as BasePageParams, type BasePageResponse as BasePageResponse }; + + export { Video as Video }; + + export { Data as Data }; + + export { System as System }; + + export { Webhooks as Webhooks }; + + export import Jwt = API.Jwt; + + export type PlaybackID = API.PlaybackID; + export type PlaybackPolicy = API.PlaybackPolicy; +} + +export { toFile, fileFromPath } from './uploads'; +export { MuxError, APIError, APIConnectionError, @@ -232,87 +277,6 @@ export const { InternalServerError, PermissionDeniedError, UnprocessableEntityError, -} = Errors; - -export import toFile = Uploads.toFile; -export import fileFromPath = Uploads.fileFromPath; - -export namespace Mux { - export import RequestOptions = Core.RequestOptions; - - export import PageWithTotal = Pagination.PageWithTotal; - export import PageWithTotalParams = Pagination.PageWithTotalParams; - export import PageWithTotalResponse = Pagination.PageWithTotalResponse; - - export import BasePage = Pagination.BasePage; - export import BasePageParams = Pagination.BasePageParams; - export import BasePageResponse = Pagination.BasePageResponse; - - export import Video = API.Video; - - export import Data = API.Data; - - export import System = API.System; - - export import Webhooks = API.Webhooks; - export import BaseWebhookEvent = API.BaseWebhookEvent; - export import VideoAssetCreatedWebhookEvent = API.VideoAssetCreatedWebhookEvent; - export import VideoAssetReadyWebhookEvent = API.VideoAssetReadyWebhookEvent; - export import VideoAssetErroredWebhookEvent = API.VideoAssetErroredWebhookEvent; - export import VideoAssetUpdatedWebhookEvent = API.VideoAssetUpdatedWebhookEvent; - export import VideoAssetDeletedWebhookEvent = API.VideoAssetDeletedWebhookEvent; - export import VideoAssetLiveStreamCompletedWebhookEvent = API.VideoAssetLiveStreamCompletedWebhookEvent; - export import VideoAssetStaticRenditionsReadyWebhookEvent = API.VideoAssetStaticRenditionsReadyWebhookEvent; - export import VideoAssetStaticRenditionsPreparingWebhookEvent = API.VideoAssetStaticRenditionsPreparingWebhookEvent; - export import VideoAssetStaticRenditionsDeletedWebhookEvent = API.VideoAssetStaticRenditionsDeletedWebhookEvent; - export import VideoAssetStaticRenditionsErroredWebhookEvent = API.VideoAssetStaticRenditionsErroredWebhookEvent; - export import VideoAssetMasterReadyWebhookEvent = API.VideoAssetMasterReadyWebhookEvent; - export import VideoAssetMasterPreparingWebhookEvent = API.VideoAssetMasterPreparingWebhookEvent; - export import VideoAssetMasterDeletedWebhookEvent = API.VideoAssetMasterDeletedWebhookEvent; - export import VideoAssetMasterErroredWebhookEvent = API.VideoAssetMasterErroredWebhookEvent; - export import VideoAssetTrackCreatedWebhookEvent = API.VideoAssetTrackCreatedWebhookEvent; - export import VideoAssetTrackReadyWebhookEvent = API.VideoAssetTrackReadyWebhookEvent; - export import VideoAssetTrackErroredWebhookEvent = API.VideoAssetTrackErroredWebhookEvent; - export import VideoAssetTrackDeletedWebhookEvent = API.VideoAssetTrackDeletedWebhookEvent; - export import VideoAssetWarningWebhookEvent = API.VideoAssetWarningWebhookEvent; - export import VideoUploadAssetCreatedWebhookEvent = API.VideoUploadAssetCreatedWebhookEvent; - export import VideoUploadCancelledWebhookEvent = API.VideoUploadCancelledWebhookEvent; - export import VideoUploadCreatedWebhookEvent = API.VideoUploadCreatedWebhookEvent; - export import VideoUploadErroredWebhookEvent = API.VideoUploadErroredWebhookEvent; - export import VideoLiveStreamCreatedWebhookEvent = API.VideoLiveStreamCreatedWebhookEvent; - export import VideoLiveStreamConnectedWebhookEvent = API.VideoLiveStreamConnectedWebhookEvent; - export import VideoLiveStreamRecordingWebhookEvent = API.VideoLiveStreamRecordingWebhookEvent; - export import VideoLiveStreamActiveWebhookEvent = API.VideoLiveStreamActiveWebhookEvent; - export import VideoLiveStreamDisconnectedWebhookEvent = API.VideoLiveStreamDisconnectedWebhookEvent; - export import VideoLiveStreamIdleWebhookEvent = API.VideoLiveStreamIdleWebhookEvent; - export import VideoLiveStreamUpdatedWebhookEvent = API.VideoLiveStreamUpdatedWebhookEvent; - export import VideoLiveStreamEnabledWebhookEvent = API.VideoLiveStreamEnabledWebhookEvent; - export import VideoLiveStreamDisabledWebhookEvent = API.VideoLiveStreamDisabledWebhookEvent; - export import VideoLiveStreamDeletedWebhookEvent = API.VideoLiveStreamDeletedWebhookEvent; - export import VideoLiveStreamWarningWebhookEvent = API.VideoLiveStreamWarningWebhookEvent; - export import VideoLiveStreamSimulcastTargetCreatedWebhookEvent = API.VideoLiveStreamSimulcastTargetCreatedWebhookEvent; - export import VideoLiveStreamSimulcastTargetIdleWebhookEvent = API.VideoLiveStreamSimulcastTargetIdleWebhookEvent; - export import VideoLiveStreamSimulcastTargetStartingWebhookEvent = API.VideoLiveStreamSimulcastTargetStartingWebhookEvent; - export import VideoLiveStreamSimulcastTargetBroadcastingWebhookEvent = API.VideoLiveStreamSimulcastTargetBroadcastingWebhookEvent; - export import VideoLiveStreamSimulcastTargetErroredWebhookEvent = API.VideoLiveStreamSimulcastTargetErroredWebhookEvent; - export import VideoLiveStreamSimulcastTargetDeletedWebhookEvent = API.VideoLiveStreamSimulcastTargetDeletedWebhookEvent; - export import VideoLiveStreamSimulcastTargetUpdatedWebhookEvent = API.VideoLiveStreamSimulcastTargetUpdatedWebhookEvent; - export import VideoSpaceCreatedWebhookEvent = API.VideoSpaceCreatedWebhookEvent; - export import VideoSpaceDeletedWebhookEvent = API.VideoSpaceDeletedWebhookEvent; - export import VideoSpaceActiveWebhookEvent = API.VideoSpaceActiveWebhookEvent; - export import VideoSpaceIdleWebhookEvent = API.VideoSpaceIdleWebhookEvent; - export import VideoSpaceUpdatedWebhookEvent = API.VideoSpaceUpdatedWebhookEvent; - export import VideoSpaceBroadcastCreatedWebhookEvent = API.VideoSpaceBroadcastCreatedWebhookEvent; - export import VideoSpaceBroadcastIdleWebhookEvent = API.VideoSpaceBroadcastIdleWebhookEvent; - export import VideoSpaceBroadcastActiveWebhookEvent = API.VideoSpaceBroadcastActiveWebhookEvent; - export import VideoSpaceBroadcastDeletedWebhookEvent = API.VideoSpaceBroadcastDeletedWebhookEvent; - export import VideoDeliveryHighTrafficWebhookEvent = API.VideoDeliveryHighTrafficWebhookEvent; - export import UnwrapWebhookEvent = API.UnwrapWebhookEvent; - - export import Jwt = API.Jwt; - - export import PlaybackID = API.PlaybackID; - export import PlaybackPolicy = API.PlaybackPolicy; -} +} from './error'; export default Mux; diff --git a/src/internal/qs/LICENSE.md b/src/internal/qs/LICENSE.md new file mode 100644 index 00000000..3fda1573 --- /dev/null +++ b/src/internal/qs/LICENSE.md @@ -0,0 +1,13 @@ +BSD 3-Clause License + +Copyright (c) 2014, Nathan LaFreniere and other [contributors](https://github.com/puruvj/neoqs/graphs/contributors) All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/internal/qs/README.md b/src/internal/qs/README.md new file mode 100644 index 00000000..67ae04ec --- /dev/null +++ b/src/internal/qs/README.md @@ -0,0 +1,3 @@ +# qs + +This is a vendored version of [neoqs](https://github.com/PuruVJ/neoqs) which is a TypeScript rewrite of [qs](https://github.com/ljharb/qs), a query string library. diff --git a/src/internal/qs/formats.ts b/src/internal/qs/formats.ts new file mode 100644 index 00000000..1cf9e2cd --- /dev/null +++ b/src/internal/qs/formats.ts @@ -0,0 +1,9 @@ +import type { Format } from './types'; + +export const default_format: Format = 'RFC3986'; +export const formatters: Record string> = { + RFC1738: (v: PropertyKey) => String(v).replace(/%20/g, '+'), + RFC3986: (v: PropertyKey) => String(v), +}; +export const RFC1738 = 'RFC1738'; +export const RFC3986 = 'RFC3986'; diff --git a/src/internal/qs/index.ts b/src/internal/qs/index.ts new file mode 100644 index 00000000..c3a3620d --- /dev/null +++ b/src/internal/qs/index.ts @@ -0,0 +1,13 @@ +import { default_format, formatters, RFC1738, RFC3986 } from './formats'; + +const formats = { + formatters, + RFC1738, + RFC3986, + default: default_format, +}; + +export { stringify } from './stringify'; +export { formats }; + +export type { DefaultDecoder, DefaultEncoder, Format, ParseOptions, StringifyOptions } from './types'; diff --git a/src/internal/qs/stringify.ts b/src/internal/qs/stringify.ts new file mode 100644 index 00000000..67497561 --- /dev/null +++ b/src/internal/qs/stringify.ts @@ -0,0 +1,388 @@ +import { encode, is_buffer, maybe_map } from './utils'; +import { default_format, formatters } from './formats'; +import type { NonNullableProperties, StringifyOptions } from './types'; + +const has = Object.prototype.hasOwnProperty; + +const array_prefix_generators = { + brackets(prefix: PropertyKey) { + return String(prefix) + '[]'; + }, + comma: 'comma', + indices(prefix: PropertyKey, key: string) { + return String(prefix) + '[' + key + ']'; + }, + repeat(prefix: PropertyKey) { + return String(prefix); + }, +}; + +const is_array = Array.isArray; +const push = Array.prototype.push; +const push_to_array = function (arr: any[], value_or_array: any) { + push.apply(arr, is_array(value_or_array) ? value_or_array : [value_or_array]); +}; + +const to_ISO = Date.prototype.toISOString; + +const defaults = { + addQueryPrefix: false, + allowDots: false, + allowEmptyArrays: false, + arrayFormat: 'indices', + charset: 'utf-8', + charsetSentinel: false, + delimiter: '&', + encode: true, + encodeDotInKeys: false, + encoder: encode, + encodeValuesOnly: false, + format: default_format, + formatter: formatters[default_format], + /** @deprecated */ + indices: false, + serializeDate(date) { + return to_ISO.call(date); + }, + skipNulls: false, + strictNullHandling: false, +} as NonNullableProperties; + +function is_non_nullish_primitive(v: unknown): v is string | number | boolean | symbol | bigint { + return ( + typeof v === 'string' || + typeof v === 'number' || + typeof v === 'boolean' || + typeof v === 'symbol' || + typeof v === 'bigint' + ); +} + +const sentinel = {}; + +function inner_stringify( + object: any, + prefix: PropertyKey, + generateArrayPrefix: StringifyOptions['arrayFormat'] | ((prefix: string, key: string) => string), + commaRoundTrip: boolean, + allowEmptyArrays: boolean, + strictNullHandling: boolean, + skipNulls: boolean, + encodeDotInKeys: boolean, + encoder: StringifyOptions['encoder'], + filter: StringifyOptions['filter'], + sort: StringifyOptions['sort'], + allowDots: StringifyOptions['allowDots'], + serializeDate: StringifyOptions['serializeDate'], + format: StringifyOptions['format'], + formatter: StringifyOptions['formatter'], + encodeValuesOnly: boolean, + charset: StringifyOptions['charset'], + sideChannel: WeakMap, +) { + let obj = object; + + let tmp_sc = sideChannel; + let step = 0; + let find_flag = false; + while ((tmp_sc = tmp_sc.get(sentinel)) !== void undefined && !find_flag) { + // Where object last appeared in the ref tree + const pos = tmp_sc.get(object); + step += 1; + if (typeof pos !== 'undefined') { + if (pos === step) { + throw new RangeError('Cyclic object value'); + } else { + find_flag = true; // Break while + } + } + if (typeof tmp_sc.get(sentinel) === 'undefined') { + step = 0; + } + } + + if (typeof filter === 'function') { + obj = filter(prefix, obj); + } else if (obj instanceof Date) { + obj = serializeDate?.(obj); + } else if (generateArrayPrefix === 'comma' && is_array(obj)) { + obj = maybe_map(obj, function (value) { + if (value instanceof Date) { + return serializeDate?.(value); + } + return value; + }); + } + + if (obj === null) { + if (strictNullHandling) { + return encoder && !encodeValuesOnly ? + // @ts-expect-error + encoder(prefix, defaults.encoder, charset, 'key', format) + : prefix; + } + + obj = ''; + } + + if (is_non_nullish_primitive(obj) || is_buffer(obj)) { + if (encoder) { + const key_value = + encodeValuesOnly ? prefix + // @ts-expect-error + : encoder(prefix, defaults.encoder, charset, 'key', format); + return [ + formatter?.(key_value) + + '=' + + // @ts-expect-error + formatter?.(encoder(obj, defaults.encoder, charset, 'value', format)), + ]; + } + return [formatter?.(prefix) + '=' + formatter?.(String(obj))]; + } + + const values: string[] = []; + + if (typeof obj === 'undefined') { + return values; + } + + let obj_keys; + if (generateArrayPrefix === 'comma' && is_array(obj)) { + // we need to join elements in + if (encodeValuesOnly && encoder) { + // @ts-expect-error values only + obj = maybe_map(obj, encoder); + } + obj_keys = [{ value: obj.length > 0 ? obj.join(',') || null : void undefined }]; + } else if (is_array(filter)) { + obj_keys = filter; + } else { + const keys = Object.keys(obj); + obj_keys = sort ? keys.sort(sort) : keys; + } + + const encoded_prefix = encodeDotInKeys ? String(prefix).replace(/\./g, '%2E') : String(prefix); + + const adjusted_prefix = + commaRoundTrip && is_array(obj) && obj.length === 1 ? encoded_prefix + '[]' : encoded_prefix; + + if (allowEmptyArrays && is_array(obj) && obj.length === 0) { + return adjusted_prefix + '[]'; + } + + for (let j = 0; j < obj_keys.length; ++j) { + const key = obj_keys[j]; + const value = + // @ts-ignore + typeof key === 'object' && typeof key.value !== 'undefined' ? key.value : obj[key as any]; + + if (skipNulls && value === null) { + continue; + } + + // @ts-ignore + const encoded_key = allowDots && encodeDotInKeys ? (key as any).replace(/\./g, '%2E') : key; + const key_prefix = + is_array(obj) ? + typeof generateArrayPrefix === 'function' ? + generateArrayPrefix(adjusted_prefix, encoded_key) + : adjusted_prefix + : adjusted_prefix + (allowDots ? '.' + encoded_key : '[' + encoded_key + ']'); + + sideChannel.set(object, step); + const valueSideChannel = new WeakMap(); + valueSideChannel.set(sentinel, sideChannel); + push_to_array( + values, + inner_stringify( + value, + key_prefix, + generateArrayPrefix, + commaRoundTrip, + allowEmptyArrays, + strictNullHandling, + skipNulls, + encodeDotInKeys, + // @ts-ignore + generateArrayPrefix === 'comma' && encodeValuesOnly && is_array(obj) ? null : encoder, + filter, + sort, + allowDots, + serializeDate, + format, + formatter, + encodeValuesOnly, + charset, + valueSideChannel, + ), + ); + } + + return values; +} + +function normalize_stringify_options( + opts: StringifyOptions = defaults, +): NonNullableProperties> & { indices?: boolean } { + if (typeof opts.allowEmptyArrays !== 'undefined' && typeof opts.allowEmptyArrays !== 'boolean') { + throw new TypeError('`allowEmptyArrays` option can only be `true` or `false`, when provided'); + } + + if (typeof opts.encodeDotInKeys !== 'undefined' && typeof opts.encodeDotInKeys !== 'boolean') { + throw new TypeError('`encodeDotInKeys` option can only be `true` or `false`, when provided'); + } + + if (opts.encoder !== null && typeof opts.encoder !== 'undefined' && typeof opts.encoder !== 'function') { + throw new TypeError('Encoder has to be a function.'); + } + + const charset = opts.charset || defaults.charset; + if (typeof opts.charset !== 'undefined' && opts.charset !== 'utf-8' && opts.charset !== 'iso-8859-1') { + throw new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined'); + } + + let format = default_format; + if (typeof opts.format !== 'undefined') { + if (!has.call(formatters, opts.format)) { + throw new TypeError('Unknown format option provided.'); + } + format = opts.format; + } + const formatter = formatters[format]; + + let filter = defaults.filter; + if (typeof opts.filter === 'function' || is_array(opts.filter)) { + filter = opts.filter; + } + + let arrayFormat: StringifyOptions['arrayFormat']; + if (opts.arrayFormat && opts.arrayFormat in array_prefix_generators) { + arrayFormat = opts.arrayFormat; + } else if ('indices' in opts) { + arrayFormat = opts.indices ? 'indices' : 'repeat'; + } else { + arrayFormat = defaults.arrayFormat; + } + + if ('commaRoundTrip' in opts && typeof opts.commaRoundTrip !== 'boolean') { + throw new TypeError('`commaRoundTrip` must be a boolean, or absent'); + } + + const allowDots = + typeof opts.allowDots === 'undefined' ? + !!opts.encodeDotInKeys === true ? + true + : defaults.allowDots + : !!opts.allowDots; + + return { + addQueryPrefix: typeof opts.addQueryPrefix === 'boolean' ? opts.addQueryPrefix : defaults.addQueryPrefix, + // @ts-ignore + allowDots: allowDots, + allowEmptyArrays: + typeof opts.allowEmptyArrays === 'boolean' ? !!opts.allowEmptyArrays : defaults.allowEmptyArrays, + arrayFormat: arrayFormat, + charset: charset, + charsetSentinel: + typeof opts.charsetSentinel === 'boolean' ? opts.charsetSentinel : defaults.charsetSentinel, + commaRoundTrip: !!opts.commaRoundTrip, + delimiter: typeof opts.delimiter === 'undefined' ? defaults.delimiter : opts.delimiter, + encode: typeof opts.encode === 'boolean' ? opts.encode : defaults.encode, + encodeDotInKeys: + typeof opts.encodeDotInKeys === 'boolean' ? opts.encodeDotInKeys : defaults.encodeDotInKeys, + encoder: typeof opts.encoder === 'function' ? opts.encoder : defaults.encoder, + encodeValuesOnly: + typeof opts.encodeValuesOnly === 'boolean' ? opts.encodeValuesOnly : defaults.encodeValuesOnly, + filter: filter, + format: format, + formatter: formatter, + serializeDate: typeof opts.serializeDate === 'function' ? opts.serializeDate : defaults.serializeDate, + skipNulls: typeof opts.skipNulls === 'boolean' ? opts.skipNulls : defaults.skipNulls, + // @ts-ignore + sort: typeof opts.sort === 'function' ? opts.sort : null, + strictNullHandling: + typeof opts.strictNullHandling === 'boolean' ? opts.strictNullHandling : defaults.strictNullHandling, + }; +} + +export function stringify(object: any, opts: StringifyOptions = {}) { + let obj = object; + const options = normalize_stringify_options(opts); + + let obj_keys: PropertyKey[] | undefined; + let filter; + + if (typeof options.filter === 'function') { + filter = options.filter; + obj = filter('', obj); + } else if (is_array(options.filter)) { + filter = options.filter; + obj_keys = filter; + } + + const keys: string[] = []; + + if (typeof obj !== 'object' || obj === null) { + return ''; + } + + const generateArrayPrefix = array_prefix_generators[options.arrayFormat]; + const commaRoundTrip = generateArrayPrefix === 'comma' && options.commaRoundTrip; + + if (!obj_keys) { + obj_keys = Object.keys(obj); + } + + if (options.sort) { + obj_keys.sort(options.sort); + } + + const sideChannel = new WeakMap(); + for (let i = 0; i < obj_keys.length; ++i) { + const key = obj_keys[i]!; + + if (options.skipNulls && obj[key] === null) { + continue; + } + push_to_array( + keys, + inner_stringify( + obj[key], + key, + // @ts-expect-error + generateArrayPrefix, + commaRoundTrip, + options.allowEmptyArrays, + options.strictNullHandling, + options.skipNulls, + options.encodeDotInKeys, + options.encode ? options.encoder : null, + options.filter, + options.sort, + options.allowDots, + options.serializeDate, + options.format, + options.formatter, + options.encodeValuesOnly, + options.charset, + sideChannel, + ), + ); + } + + const joined = keys.join(options.delimiter); + let prefix = options.addQueryPrefix === true ? '?' : ''; + + if (options.charsetSentinel) { + if (options.charset === 'iso-8859-1') { + // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark + prefix += 'utf8=%26%2310003%3B&'; + } else { + // encodeURIComponent('✓') + prefix += 'utf8=%E2%9C%93&'; + } + } + + return joined.length > 0 ? prefix + joined : ''; +} diff --git a/src/internal/qs/types.ts b/src/internal/qs/types.ts new file mode 100644 index 00000000..7c28dbb4 --- /dev/null +++ b/src/internal/qs/types.ts @@ -0,0 +1,71 @@ +export type Format = 'RFC1738' | 'RFC3986'; + +export type DefaultEncoder = (str: any, defaultEncoder?: any, charset?: string) => string; +export type DefaultDecoder = (str: string, decoder?: any, charset?: string) => string; + +export type BooleanOptional = boolean | undefined; + +export type StringifyBaseOptions = { + delimiter?: string; + allowDots?: boolean; + encodeDotInKeys?: boolean; + strictNullHandling?: boolean; + skipNulls?: boolean; + encode?: boolean; + encoder?: ( + str: any, + defaultEncoder: DefaultEncoder, + charset: string, + type: 'key' | 'value', + format?: Format, + ) => string; + filter?: Array | ((prefix: PropertyKey, value: any) => any); + arrayFormat?: 'indices' | 'brackets' | 'repeat' | 'comma'; + indices?: boolean; + sort?: ((a: PropertyKey, b: PropertyKey) => number) | null; + serializeDate?: (d: Date) => string; + format?: 'RFC1738' | 'RFC3986'; + formatter?: (str: PropertyKey) => string; + encodeValuesOnly?: boolean; + addQueryPrefix?: boolean; + charset?: 'utf-8' | 'iso-8859-1'; + charsetSentinel?: boolean; + allowEmptyArrays?: boolean; + commaRoundTrip?: boolean; +}; + +export type StringifyOptions = StringifyBaseOptions; + +export type ParseBaseOptions = { + comma?: boolean; + delimiter?: string | RegExp; + depth?: number | false; + decoder?: (str: string, defaultDecoder: DefaultDecoder, charset: string, type: 'key' | 'value') => any; + arrayLimit?: number; + parseArrays?: boolean; + plainObjects?: boolean; + allowPrototypes?: boolean; + allowSparse?: boolean; + parameterLimit?: number; + strictDepth?: boolean; + strictNullHandling?: boolean; + ignoreQueryPrefix?: boolean; + charset?: 'utf-8' | 'iso-8859-1'; + charsetSentinel?: boolean; + interpretNumericEntities?: boolean; + allowEmptyArrays?: boolean; + duplicates?: 'combine' | 'first' | 'last'; + allowDots?: boolean; + decodeDotInKeys?: boolean; +}; + +export type ParseOptions = ParseBaseOptions; + +export type ParsedQs = { + [key: string]: undefined | string | string[] | ParsedQs | ParsedQs[]; +}; + +// Type to remove null or undefined union from each property +export type NonNullableProperties = { + [K in keyof T]-?: Exclude; +}; diff --git a/src/internal/qs/utils.ts b/src/internal/qs/utils.ts new file mode 100644 index 00000000..113b18fb --- /dev/null +++ b/src/internal/qs/utils.ts @@ -0,0 +1,265 @@ +import { RFC1738 } from './formats'; +import type { DefaultEncoder, Format } from './types'; + +const has = Object.prototype.hasOwnProperty; +const is_array = Array.isArray; + +const hex_table = (() => { + const array = []; + for (let i = 0; i < 256; ++i) { + array.push('%' + ((i < 16 ? '0' : '') + i.toString(16)).toUpperCase()); + } + + return array; +})(); + +function compact_queue>(queue: Array<{ obj: T; prop: string }>) { + while (queue.length > 1) { + const item = queue.pop(); + if (!item) continue; + + const obj = item.obj[item.prop]; + + if (is_array(obj)) { + const compacted: unknown[] = []; + + for (let j = 0; j < obj.length; ++j) { + if (typeof obj[j] !== 'undefined') { + compacted.push(obj[j]); + } + } + + // @ts-ignore + item.obj[item.prop] = compacted; + } + } +} + +function array_to_object(source: any[], options: { plainObjects: boolean }) { + const obj = options && options.plainObjects ? Object.create(null) : {}; + for (let i = 0; i < source.length; ++i) { + if (typeof source[i] !== 'undefined') { + obj[i] = source[i]; + } + } + + return obj; +} + +export function merge( + target: any, + source: any, + options: { plainObjects?: boolean; allowPrototypes?: boolean } = {}, +) { + if (!source) { + return target; + } + + if (typeof source !== 'object') { + if (is_array(target)) { + target.push(source); + } else if (target && typeof target === 'object') { + if ( + (options && (options.plainObjects || options.allowPrototypes)) || + !has.call(Object.prototype, source) + ) { + target[source] = true; + } + } else { + return [target, source]; + } + + return target; + } + + if (!target || typeof target !== 'object') { + return [target].concat(source); + } + + let mergeTarget = target; + if (is_array(target) && !is_array(source)) { + // @ts-ignore + mergeTarget = array_to_object(target, options); + } + + if (is_array(target) && is_array(source)) { + source.forEach(function (item, i) { + if (has.call(target, i)) { + const targetItem = target[i]; + if (targetItem && typeof targetItem === 'object' && item && typeof item === 'object') { + target[i] = merge(targetItem, item, options); + } else { + target.push(item); + } + } else { + target[i] = item; + } + }); + return target; + } + + return Object.keys(source).reduce(function (acc, key) { + const value = source[key]; + + if (has.call(acc, key)) { + acc[key] = merge(acc[key], value, options); + } else { + acc[key] = value; + } + return acc; + }, mergeTarget); +} + +export function assign_single_source(target: any, source: any) { + return Object.keys(source).reduce(function (acc, key) { + acc[key] = source[key]; + return acc; + }, target); +} + +export function decode(str: string, _: any, charset: string) { + const strWithoutPlus = str.replace(/\+/g, ' '); + if (charset === 'iso-8859-1') { + // unescape never throws, no try...catch needed: + return strWithoutPlus.replace(/%[0-9a-f]{2}/gi, unescape); + } + // utf-8 + try { + return decodeURIComponent(strWithoutPlus); + } catch (e) { + return strWithoutPlus; + } +} + +const limit = 1024; + +export const encode: ( + str: any, + defaultEncoder: DefaultEncoder, + charset: string, + type: 'key' | 'value', + format: Format, +) => string = (str, _defaultEncoder, charset, _kind, format: Format) => { + // This code was originally written by Brian White for the io.js core querystring library. + // It has been adapted here for stricter adherence to RFC 3986 + if (str.length === 0) { + return str; + } + + let string = str; + if (typeof str === 'symbol') { + string = Symbol.prototype.toString.call(str); + } else if (typeof str !== 'string') { + string = String(str); + } + + if (charset === 'iso-8859-1') { + return escape(string).replace(/%u[0-9a-f]{4}/gi, function ($0) { + return '%26%23' + parseInt($0.slice(2), 16) + '%3B'; + }); + } + + let out = ''; + for (let j = 0; j < string.length; j += limit) { + const segment = string.length >= limit ? string.slice(j, j + limit) : string; + const arr = []; + + for (let i = 0; i < segment.length; ++i) { + let c = segment.charCodeAt(i); + if ( + c === 0x2d || // - + c === 0x2e || // . + c === 0x5f || // _ + c === 0x7e || // ~ + (c >= 0x30 && c <= 0x39) || // 0-9 + (c >= 0x41 && c <= 0x5a) || // a-z + (c >= 0x61 && c <= 0x7a) || // A-Z + (format === RFC1738 && (c === 0x28 || c === 0x29)) // ( ) + ) { + arr[arr.length] = segment.charAt(i); + continue; + } + + if (c < 0x80) { + arr[arr.length] = hex_table[c]; + continue; + } + + if (c < 0x800) { + arr[arr.length] = hex_table[0xc0 | (c >> 6)]! + hex_table[0x80 | (c & 0x3f)]; + continue; + } + + if (c < 0xd800 || c >= 0xe000) { + arr[arr.length] = + hex_table[0xe0 | (c >> 12)]! + hex_table[0x80 | ((c >> 6) & 0x3f)] + hex_table[0x80 | (c & 0x3f)]; + continue; + } + + i += 1; + c = 0x10000 + (((c & 0x3ff) << 10) | (segment.charCodeAt(i) & 0x3ff)); + + arr[arr.length] = + hex_table[0xf0 | (c >> 18)]! + + hex_table[0x80 | ((c >> 12) & 0x3f)] + + hex_table[0x80 | ((c >> 6) & 0x3f)] + + hex_table[0x80 | (c & 0x3f)]; + } + + out += arr.join(''); + } + + return out; +}; + +export function compact(value: any) { + const queue = [{ obj: { o: value }, prop: 'o' }]; + const refs = []; + + for (let i = 0; i < queue.length; ++i) { + const item = queue[i]; + // @ts-ignore + const obj = item.obj[item.prop]; + + const keys = Object.keys(obj); + for (let j = 0; j < keys.length; ++j) { + const key = keys[j]!; + const val = obj[key]; + if (typeof val === 'object' && val !== null && refs.indexOf(val) === -1) { + queue.push({ obj: obj, prop: key }); + refs.push(val); + } + } + } + + compact_queue(queue); + + return value; +} + +export function is_regexp(obj: any) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; +} + +export function is_buffer(obj: any) { + if (!obj || typeof obj !== 'object') { + return false; + } + + return !!(obj.constructor && obj.constructor.isBuffer && obj.constructor.isBuffer(obj)); +} + +export function combine(a: any, b: any) { + return [].concat(a, b); +} + +export function maybe_map(val: T[], fn: (v: T) => T) { + if (is_array(val)) { + const mapped = []; + for (let i = 0; i < val.length; i += 1) { + mapped.push(fn(val[i]!)); + } + return mapped; + } + return fn(val); +} diff --git a/src/resources/data/data.ts b/src/resources/data/data.ts index 3f3b81b1..437fd727 100644 --- a/src/resources/data/data.ts +++ b/src/resources/data/data.ts @@ -1,15 +1,72 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '@mux/mux-node/resource'; -import * as DimensionsAPI from '@mux/mux-node/resources/data/dimensions'; -import * as ErrorsAPI from '@mux/mux-node/resources/data/errors'; -import * as ExportsAPI from '@mux/mux-node/resources/data/exports'; -import * as FiltersAPI from '@mux/mux-node/resources/data/filters'; -import * as IncidentsAPI from '@mux/mux-node/resources/data/incidents'; -import * as MetricsAPI from '@mux/mux-node/resources/data/metrics'; -import * as RealTimeAPI from '@mux/mux-node/resources/data/real-time'; -import * as VideoViewsAPI from '@mux/mux-node/resources/data/video-views'; -import * as MonitoringAPI from '@mux/mux-node/resources/data/monitoring/monitoring'; +import { APIResource } from '../../resource'; +import * as DimensionsAPI from './dimensions'; +import { + DimensionListValuesParams, + DimensionValue, + DimensionValuesBasePage, + Dimensions, + DimensionsResponse, +} from './dimensions'; +import * as ErrorsAPI from './errors'; +import { ErrorListParams, Errors, ErrorsResponse } from './errors'; +import * as ExportsAPI from './exports'; +import { Exports, ExportsResponse, VideoViewExportsResponse } from './exports'; +import * as FiltersAPI from './filters'; +import { + FilterListValuesParams, + FilterValue, + FilterValuesBasePage, + Filters, + FiltersResponse, +} from './filters'; +import * as IncidentsAPI from './incidents'; +import { + Incident, + IncidentListParams, + IncidentListRelatedParams, + IncidentResponse, + Incidents, + IncidentsBasePage, +} from './incidents'; +import * as MetricsAPI from './metrics'; +import { + AllMetricValuesResponse, + BreakdownValue, + BreakdownValuesBasePage, + InsightsResponse, + MetricGetInsightsParams, + MetricGetOverallValuesParams, + MetricGetTimeseriesParams, + MetricListBreakdownValuesParams, + MetricListParams, + MetricTimeseriesDataResponse, + Metrics, + OverallValuesResponse, +} from './metrics'; +import * as RealTimeAPI from './real-time'; +import { + RealTime, + RealTimeBreakdownResponse, + RealTimeDimensionsResponse, + RealTimeHistogramTimeseriesResponse, + RealTimeMetricsResponse, + RealTimeRetrieveBreakdownParams, + RealTimeRetrieveHistogramTimeseriesParams, + RealTimeRetrieveTimeseriesParams, + RealTimeTimeseriesResponse, +} from './real-time'; +import * as VideoViewsAPI from './video-views'; +import { + AbridgedVideoView, + AbridgedVideoViewsBasePage, + VideoViewListParams, + VideoViewResponse, + VideoViews, +} from './video-views'; +import * as MonitoringAPI from './monitoring/monitoring'; +import { Monitoring, MonitoringListDimensionsResponse } from './monitoring/monitoring'; export class Data extends APIResource { dimensions: DimensionsAPI.Dimensions = new DimensionsAPI.Dimensions(this._client); @@ -23,55 +80,92 @@ export class Data extends APIResource { videoViews: VideoViewsAPI.VideoViews = new VideoViewsAPI.VideoViews(this._client); } -export namespace Data { - export import Dimensions = DimensionsAPI.Dimensions; - export import DimensionValue = DimensionsAPI.DimensionValue; - export import DimensionsResponse = DimensionsAPI.DimensionsResponse; - export import DimensionValuesBasePage = DimensionsAPI.DimensionValuesBasePage; - export import DimensionListValuesParams = DimensionsAPI.DimensionListValuesParams; - export import Monitoring = MonitoringAPI.Monitoring; - export import MonitoringListDimensionsResponse = MonitoringAPI.MonitoringListDimensionsResponse; - export import Errors = ErrorsAPI.Errors; - export import ErrorsResponse = ErrorsAPI.ErrorsResponse; - export import ErrorListParams = ErrorsAPI.ErrorListParams; - export import Exports = ExportsAPI.Exports; - export import ExportsResponse = ExportsAPI.ExportsResponse; - export import VideoViewExportsResponse = ExportsAPI.VideoViewExportsResponse; - export import Filters = FiltersAPI.Filters; - export import FilterValue = FiltersAPI.FilterValue; - export import FiltersResponse = FiltersAPI.FiltersResponse; - export import FilterValuesBasePage = FiltersAPI.FilterValuesBasePage; - export import FilterListValuesParams = FiltersAPI.FilterListValuesParams; - export import Incidents = IncidentsAPI.Incidents; - export import Incident = IncidentsAPI.Incident; - export import IncidentResponse = IncidentsAPI.IncidentResponse; - export import IncidentsBasePage = IncidentsAPI.IncidentsBasePage; - export import IncidentListParams = IncidentsAPI.IncidentListParams; - export import IncidentListRelatedParams = IncidentsAPI.IncidentListRelatedParams; - export import Metrics = MetricsAPI.Metrics; - export import AllMetricValuesResponse = MetricsAPI.AllMetricValuesResponse; - export import BreakdownValue = MetricsAPI.BreakdownValue; - export import InsightsResponse = MetricsAPI.InsightsResponse; - export import MetricTimeseriesDataResponse = MetricsAPI.MetricTimeseriesDataResponse; - export import OverallValuesResponse = MetricsAPI.OverallValuesResponse; - export import BreakdownValuesBasePage = MetricsAPI.BreakdownValuesBasePage; - export import MetricListParams = MetricsAPI.MetricListParams; - export import MetricGetInsightsParams = MetricsAPI.MetricGetInsightsParams; - export import MetricGetOverallValuesParams = MetricsAPI.MetricGetOverallValuesParams; - export import MetricGetTimeseriesParams = MetricsAPI.MetricGetTimeseriesParams; - export import MetricListBreakdownValuesParams = MetricsAPI.MetricListBreakdownValuesParams; - export import RealTime = RealTimeAPI.RealTime; - export import RealTimeBreakdownResponse = RealTimeAPI.RealTimeBreakdownResponse; - export import RealTimeDimensionsResponse = RealTimeAPI.RealTimeDimensionsResponse; - export import RealTimeHistogramTimeseriesResponse = RealTimeAPI.RealTimeHistogramTimeseriesResponse; - export import RealTimeMetricsResponse = RealTimeAPI.RealTimeMetricsResponse; - export import RealTimeTimeseriesResponse = RealTimeAPI.RealTimeTimeseriesResponse; - export import RealTimeRetrieveBreakdownParams = RealTimeAPI.RealTimeRetrieveBreakdownParams; - export import RealTimeRetrieveHistogramTimeseriesParams = RealTimeAPI.RealTimeRetrieveHistogramTimeseriesParams; - export import RealTimeRetrieveTimeseriesParams = RealTimeAPI.RealTimeRetrieveTimeseriesParams; - export import VideoViews = VideoViewsAPI.VideoViews; - export import AbridgedVideoView = VideoViewsAPI.AbridgedVideoView; - export import VideoViewResponse = VideoViewsAPI.VideoViewResponse; - export import AbridgedVideoViewsBasePage = VideoViewsAPI.AbridgedVideoViewsBasePage; - export import VideoViewListParams = VideoViewsAPI.VideoViewListParams; +Data.Dimensions = Dimensions; +Data.DimensionValuesBasePage = DimensionValuesBasePage; +Data.Monitoring = Monitoring; +Data.Errors = Errors; +Data.Exports = Exports; +Data.Filters = Filters; +Data.FilterValuesBasePage = FilterValuesBasePage; +Data.Incidents = Incidents; +Data.IncidentsBasePage = IncidentsBasePage; +Data.Metrics = Metrics; +Data.BreakdownValuesBasePage = BreakdownValuesBasePage; +Data.RealTime = RealTime; +Data.VideoViews = VideoViews; +Data.AbridgedVideoViewsBasePage = AbridgedVideoViewsBasePage; + +export declare namespace Data { + export { + Dimensions as Dimensions, + type DimensionValue as DimensionValue, + type DimensionsResponse as DimensionsResponse, + DimensionValuesBasePage as DimensionValuesBasePage, + type DimensionListValuesParams as DimensionListValuesParams, + }; + + export { + Monitoring as Monitoring, + type MonitoringListDimensionsResponse as MonitoringListDimensionsResponse, + }; + + export { Errors as Errors, type ErrorsResponse as ErrorsResponse, type ErrorListParams as ErrorListParams }; + + export { + Exports as Exports, + type ExportsResponse as ExportsResponse, + type VideoViewExportsResponse as VideoViewExportsResponse, + }; + + export { + Filters as Filters, + type FilterValue as FilterValue, + type FiltersResponse as FiltersResponse, + FilterValuesBasePage as FilterValuesBasePage, + type FilterListValuesParams as FilterListValuesParams, + }; + + export { + Incidents as Incidents, + type Incident as Incident, + type IncidentResponse as IncidentResponse, + IncidentsBasePage as IncidentsBasePage, + type IncidentListParams as IncidentListParams, + type IncidentListRelatedParams as IncidentListRelatedParams, + }; + + export { + Metrics as Metrics, + type AllMetricValuesResponse as AllMetricValuesResponse, + type BreakdownValue as BreakdownValue, + type InsightsResponse as InsightsResponse, + type MetricTimeseriesDataResponse as MetricTimeseriesDataResponse, + type OverallValuesResponse as OverallValuesResponse, + BreakdownValuesBasePage as BreakdownValuesBasePage, + type MetricListParams as MetricListParams, + type MetricGetInsightsParams as MetricGetInsightsParams, + type MetricGetOverallValuesParams as MetricGetOverallValuesParams, + type MetricGetTimeseriesParams as MetricGetTimeseriesParams, + type MetricListBreakdownValuesParams as MetricListBreakdownValuesParams, + }; + + export { + RealTime as RealTime, + type RealTimeBreakdownResponse as RealTimeBreakdownResponse, + type RealTimeDimensionsResponse as RealTimeDimensionsResponse, + type RealTimeHistogramTimeseriesResponse as RealTimeHistogramTimeseriesResponse, + type RealTimeMetricsResponse as RealTimeMetricsResponse, + type RealTimeTimeseriesResponse as RealTimeTimeseriesResponse, + type RealTimeRetrieveBreakdownParams as RealTimeRetrieveBreakdownParams, + type RealTimeRetrieveHistogramTimeseriesParams as RealTimeRetrieveHistogramTimeseriesParams, + type RealTimeRetrieveTimeseriesParams as RealTimeRetrieveTimeseriesParams, + }; + + export { + VideoViews as VideoViews, + type AbridgedVideoView as AbridgedVideoView, + type VideoViewResponse as VideoViewResponse, + AbridgedVideoViewsBasePage as AbridgedVideoViewsBasePage, + type VideoViewListParams as VideoViewListParams, + }; } diff --git a/src/resources/data/dimensions.ts b/src/resources/data/dimensions.ts index 22db7320..51fb79d0 100644 --- a/src/resources/data/dimensions.ts +++ b/src/resources/data/dimensions.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as DimensionsAPI from '@mux/mux-node/resources/data/dimensions'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class Dimensions extends APIResource { /** @@ -91,7 +90,7 @@ export interface DimensionListValuesParams extends BasePageParams { * * Possible filterable metrics are the same as the set of metric ids, with the * exceptions of `exits_before_video_start`, `unique_viewers`, - * `video_startup_failure_percentage`, and `views`. + * `video_startup_failure_percentage`, `view_dropped_percentage`, and `views`. * * Example: * @@ -111,9 +110,13 @@ export interface DimensionListValuesParams extends BasePageParams { timeframe?: Array; } -export namespace Dimensions { - export import DimensionValue = DimensionsAPI.DimensionValue; - export import DimensionsResponse = DimensionsAPI.DimensionsResponse; - export import DimensionValuesBasePage = DimensionsAPI.DimensionValuesBasePage; - export import DimensionListValuesParams = DimensionsAPI.DimensionListValuesParams; +Dimensions.DimensionValuesBasePage = DimensionValuesBasePage; + +export declare namespace Dimensions { + export { + type DimensionValue as DimensionValue, + type DimensionsResponse as DimensionsResponse, + DimensionValuesBasePage as DimensionValuesBasePage, + type DimensionListValuesParams as DimensionListValuesParams, + }; } diff --git a/src/resources/data/errors.ts b/src/resources/data/errors.ts index 524e0e2a..16bb2d9a 100644 --- a/src/resources/data/errors.ts +++ b/src/resources/data/errors.ts @@ -1,9 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as ErrorsAPI from '@mux/mux-node/resources/data/errors'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; export class Errors extends APIResource { /** @@ -101,7 +100,7 @@ export interface ErrorListParams { * * Possible filterable metrics are the same as the set of metric ids, with the * exceptions of `exits_before_video_start`, `unique_viewers`, - * `video_startup_failure_percentage`, and `views`. + * `video_startup_failure_percentage`, `view_dropped_percentage`, and `views`. * * Example: * @@ -121,7 +120,6 @@ export interface ErrorListParams { timeframe?: Array; } -export namespace Errors { - export import ErrorsResponse = ErrorsAPI.ErrorsResponse; - export import ErrorListParams = ErrorsAPI.ErrorListParams; +export declare namespace Errors { + export { type ErrorsResponse as ErrorsResponse, type ErrorListParams as ErrorListParams }; } diff --git a/src/resources/data/exports.ts b/src/resources/data/exports.ts index c8493906..56704b34 100644 --- a/src/resources/data/exports.ts +++ b/src/resources/data/exports.ts @@ -1,8 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import * as ExportsAPI from '@mux/mux-node/resources/data/exports'; +import { APIResource } from '../../resource'; +import * as Core from '../../core'; export class Exports extends APIResource { /** @@ -47,7 +46,9 @@ export namespace VideoViewExportsResponse { } } -export namespace Exports { - export import ExportsResponse = ExportsAPI.ExportsResponse; - export import VideoViewExportsResponse = ExportsAPI.VideoViewExportsResponse; +export declare namespace Exports { + export { + type ExportsResponse as ExportsResponse, + type VideoViewExportsResponse as VideoViewExportsResponse, + }; } diff --git a/src/resources/data/filters.ts b/src/resources/data/filters.ts index 283599cb..1d953b9c 100644 --- a/src/resources/data/filters.ts +++ b/src/resources/data/filters.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as FiltersAPI from '@mux/mux-node/resources/data/filters'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class Filters extends APIResource { /** @@ -88,9 +87,13 @@ export interface FilterListValuesParams extends BasePageParams { timeframe?: Array; } -export namespace Filters { - export import FilterValue = FiltersAPI.FilterValue; - export import FiltersResponse = FiltersAPI.FiltersResponse; - export import FilterValuesBasePage = FiltersAPI.FilterValuesBasePage; - export import FilterListValuesParams = FiltersAPI.FilterListValuesParams; +Filters.FilterValuesBasePage = FilterValuesBasePage; + +export declare namespace Filters { + export { + type FilterValue as FilterValue, + type FiltersResponse as FiltersResponse, + FilterValuesBasePage as FilterValuesBasePage, + type FilterListValuesParams as FilterListValuesParams, + }; } diff --git a/src/resources/data/incidents.ts b/src/resources/data/incidents.ts index 727b1c3f..6f2bcbae 100644 --- a/src/resources/data/incidents.ts +++ b/src/resources/data/incidents.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as IncidentsAPI from '@mux/mux-node/resources/data/incidents'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class Incidents extends APIResource { /** @@ -187,10 +186,14 @@ export interface IncidentListRelatedParams extends BasePageParams { order_direction?: 'asc' | 'desc'; } -export namespace Incidents { - export import Incident = IncidentsAPI.Incident; - export import IncidentResponse = IncidentsAPI.IncidentResponse; - export import IncidentsBasePage = IncidentsAPI.IncidentsBasePage; - export import IncidentListParams = IncidentsAPI.IncidentListParams; - export import IncidentListRelatedParams = IncidentsAPI.IncidentListRelatedParams; +Incidents.IncidentsBasePage = IncidentsBasePage; + +export declare namespace Incidents { + export { + type Incident as Incident, + type IncidentResponse as IncidentResponse, + IncidentsBasePage as IncidentsBasePage, + type IncidentListParams as IncidentListParams, + type IncidentListRelatedParams as IncidentListRelatedParams, + }; } diff --git a/src/resources/data/index.ts b/src/resources/data/index.ts index 20323c67..d0690680 100644 --- a/src/resources/data/index.ts +++ b/src/resources/data/index.ts @@ -1,60 +1,60 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { - AbridgedVideoView, - VideoViewResponse, - VideoViewListParams, AbridgedVideoViewsBasePage, VideoViews, + type AbridgedVideoView, + type VideoViewResponse, + type VideoViewListParams, } from './video-views'; export { - AllMetricValuesResponse, - BreakdownValue, - InsightsResponse, - MetricTimeseriesDataResponse, - OverallValuesResponse, - MetricListParams, - MetricGetInsightsParams, - MetricGetOverallValuesParams, - MetricGetTimeseriesParams, - MetricListBreakdownValuesParams, BreakdownValuesBasePage, Metrics, + type AllMetricValuesResponse, + type BreakdownValue, + type InsightsResponse, + type MetricTimeseriesDataResponse, + type OverallValuesResponse, + type MetricListParams, + type MetricGetInsightsParams, + type MetricGetOverallValuesParams, + type MetricGetTimeseriesParams, + type MetricListBreakdownValuesParams, } from './metrics'; export { Data } from './data'; export { - DimensionValue, - DimensionsResponse, - DimensionListValuesParams, DimensionValuesBasePage, Dimensions, + type DimensionValue, + type DimensionsResponse, + type DimensionListValuesParams, } from './dimensions'; -export { ErrorsResponse, ErrorListParams, Errors } from './errors'; -export { ExportsResponse, VideoViewExportsResponse, Exports } from './exports'; +export { Errors, type ErrorsResponse, type ErrorListParams } from './errors'; +export { Exports, type ExportsResponse, type VideoViewExportsResponse } from './exports'; export { - FilterValue, - FiltersResponse, - FilterListValuesParams, FilterValuesBasePage, Filters, + type FilterValue, + type FiltersResponse, + type FilterListValuesParams, } from './filters'; export { - Incident, - IncidentResponse, - IncidentListParams, - IncidentListRelatedParams, IncidentsBasePage, Incidents, + type Incident, + type IncidentResponse, + type IncidentListParams, + type IncidentListRelatedParams, } from './incidents'; -export { MonitoringListDimensionsResponse, Monitoring } from './monitoring/index'; +export { Monitoring, type MonitoringListDimensionsResponse } from './monitoring/index'; export { - RealTimeBreakdownResponse, - RealTimeDimensionsResponse, - RealTimeHistogramTimeseriesResponse, - RealTimeMetricsResponse, - RealTimeTimeseriesResponse, - RealTimeRetrieveBreakdownParams, - RealTimeRetrieveHistogramTimeseriesParams, - RealTimeRetrieveTimeseriesParams, RealTime, + type RealTimeBreakdownResponse, + type RealTimeDimensionsResponse, + type RealTimeHistogramTimeseriesResponse, + type RealTimeMetricsResponse, + type RealTimeTimeseriesResponse, + type RealTimeRetrieveBreakdownParams, + type RealTimeRetrieveHistogramTimeseriesParams, + type RealTimeRetrieveTimeseriesParams, } from './real-time'; diff --git a/src/resources/data/metrics.ts b/src/resources/data/metrics.ts index c49cf316..d1386809 100644 --- a/src/resources/data/metrics.ts +++ b/src/resources/data/metrics.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as MetricsAPI from '@mux/mux-node/resources/data/metrics'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class Metrics extends APIResource { /** @@ -77,7 +76,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', query?: MetricGetInsightsParams, options?: Core.RequestOptions, ): Core.APIPromise; @@ -131,7 +131,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', options?: Core.RequestOptions, ): Core.APIPromise; getInsights( @@ -184,7 +185,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', query: MetricGetInsightsParams | Core.RequestOptions = {}, options?: Core.RequestOptions, ): Core.APIPromise { @@ -248,7 +250,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', query?: MetricGetOverallValuesParams, options?: Core.RequestOptions, ): Core.APIPromise; @@ -302,7 +305,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', options?: Core.RequestOptions, ): Core.APIPromise; getOverallValues( @@ -355,7 +359,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', query: MetricGetOverallValuesParams | Core.RequestOptions = {}, options?: Core.RequestOptions, ): Core.APIPromise { @@ -426,7 +431,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', query?: MetricGetTimeseriesParams, options?: Core.RequestOptions, ): Core.APIPromise; @@ -480,7 +486,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', options?: Core.RequestOptions, ): Core.APIPromise; getTimeseries( @@ -533,7 +540,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', query: MetricGetTimeseriesParams | Core.RequestOptions = {}, options?: Core.RequestOptions, ): Core.APIPromise { @@ -596,7 +604,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', query?: MetricListBreakdownValuesParams, options?: Core.RequestOptions, ): Core.PagePromise; @@ -650,7 +659,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', options?: Core.RequestOptions, ): Core.PagePromise; listBreakdownValues( @@ -703,7 +713,8 @@ export class Metrics extends APIResource { | 'view_content_startup_time' | 'ad_preroll_startup_time' | 'ad_watch_time' - | 'view_content_watch_time', + | 'view_content_watch_time' + | 'view_dropped_percentage', query: MetricListBreakdownValuesParams | Core.RequestOptions = {}, options?: Core.RequestOptions, ): Core.PagePromise { @@ -930,7 +941,8 @@ export interface MetricListParams { | 'viewer_device_name' | 'viewer_user_id' | 'ad_playback_failure' - | 'content_playback_failure'; + | 'content_playback_failure' + | 'view_dropped'; /** * Limit the results to rows that match conditions from provided key:value pairs. @@ -953,7 +965,7 @@ export interface MetricListParams { * * Possible filterable metrics are the same as the set of metric ids, with the * exceptions of `exits_before_video_start`, `unique_viewers`, - * `video_startup_failure_percentage`, and `views`. + * `video_startup_failure_percentage`, `view_dropped_percentage`, and `views`. * * Example: * @@ -996,7 +1008,28 @@ export interface MetricGetInsightsParams { /** * Measurement for the provided metric. If omitted, the default for the metric will - * be used. + * be used. The default measurement for each metric is: "sum" : `ad_attempt_count`, + * `ad_break_count`, `ad_break_error_count`, `ad_error_count`, + * `ad_impression_count`, `playing_time` "median" : `ad_preroll_startup_time`, + * `ad_watch_time`, `aggregate_startup_time`, `content_startup_time`, + * `content_watch_time`, `max_downscale_percentage`, `max_upscale_percentage`, + * `page_load_time`, `player_average_live_latency`, `player_startup_time`, + * `rebuffer_count`, `rebuffer_duration`, `requests_for_first_preroll`, + * `video_startup_preroll_load_time`, `video_startup_preroll_request_time`, + * `video_startup_time`, `view_average_request_latency`, + * `view_average_request_throughput`, `view_max_request_latency`, + * `weighted_average_bitrate` "avg" : `ad_break_error_percentage`, + * `ad_error_percentage`, `ad_exit_before_start_count`, + * `ad_exit_before_start_percentage`, `ad_playback_failure_percentage`, + * `ad_startup_error_count`, `ad_startup_error_percentage`, + * `content_playback_failure_percentage`, `downscale_percentage`, + * `exits_before_video_start`, `playback_business_exception_percentage`, + * `playback_failure_percentage`, `playback_success_score`, `rebuffer_frequency`, + * `rebuffer_percentage`, `seek_latency`, `smoothness_score`, `startup_time_score`, + * `upscale_percentage`, `video_quality_score`, + * `video_startup_business_exception_percentage`, + * `video_startup_failure_percentage`, `view_dropped_percentage`, + * `viewer_experience_score` "count" : `started_views`, `unique_viewers` */ measurement?: '95th' | 'median' | 'avg' | 'count' | 'sum'; @@ -1006,7 +1039,7 @@ export interface MetricGetInsightsParams { * * Possible filterable metrics are the same as the set of metric ids, with the * exceptions of `exits_before_video_start`, `unique_viewers`, - * `video_startup_failure_percentage`, and `views`. + * `video_startup_failure_percentage`, `view_dropped_percentage`, and `views`. * * Example: * @@ -1049,7 +1082,28 @@ export interface MetricGetOverallValuesParams { /** * Measurement for the provided metric. If omitted, the default for the metric will - * be used. + * be used. The default measurement for each metric is: "sum" : `ad_attempt_count`, + * `ad_break_count`, `ad_break_error_count`, `ad_error_count`, + * `ad_impression_count`, `playing_time` "median" : `ad_preroll_startup_time`, + * `ad_watch_time`, `aggregate_startup_time`, `content_startup_time`, + * `content_watch_time`, `max_downscale_percentage`, `max_upscale_percentage`, + * `page_load_time`, `player_average_live_latency`, `player_startup_time`, + * `rebuffer_count`, `rebuffer_duration`, `requests_for_first_preroll`, + * `video_startup_preroll_load_time`, `video_startup_preroll_request_time`, + * `video_startup_time`, `view_average_request_latency`, + * `view_average_request_throughput`, `view_max_request_latency`, + * `weighted_average_bitrate` "avg" : `ad_break_error_percentage`, + * `ad_error_percentage`, `ad_exit_before_start_count`, + * `ad_exit_before_start_percentage`, `ad_playback_failure_percentage`, + * `ad_startup_error_count`, `ad_startup_error_percentage`, + * `content_playback_failure_percentage`, `downscale_percentage`, + * `exits_before_video_start`, `playback_business_exception_percentage`, + * `playback_failure_percentage`, `playback_success_score`, `rebuffer_frequency`, + * `rebuffer_percentage`, `seek_latency`, `smoothness_score`, `startup_time_score`, + * `upscale_percentage`, `video_quality_score`, + * `video_startup_business_exception_percentage`, + * `video_startup_failure_percentage`, `view_dropped_percentage`, + * `viewer_experience_score` "count" : `started_views`, `unique_viewers` */ measurement?: '95th' | 'median' | 'avg' | 'count' | 'sum'; @@ -1059,7 +1113,7 @@ export interface MetricGetOverallValuesParams { * * Possible filterable metrics are the same as the set of metric ids, with the * exceptions of `exits_before_video_start`, `unique_viewers`, - * `video_startup_failure_percentage`, and `views`. + * `video_startup_failure_percentage`, `view_dropped_percentage`, and `views`. * * Example: * @@ -1110,7 +1164,28 @@ export interface MetricGetTimeseriesParams { /** * Measurement for the provided metric. If omitted, the default for the metric will - * be used. + * be used. The default measurement for each metric is: "sum" : `ad_attempt_count`, + * `ad_break_count`, `ad_break_error_count`, `ad_error_count`, + * `ad_impression_count`, `playing_time` "median" : `ad_preroll_startup_time`, + * `ad_watch_time`, `aggregate_startup_time`, `content_startup_time`, + * `content_watch_time`, `max_downscale_percentage`, `max_upscale_percentage`, + * `page_load_time`, `player_average_live_latency`, `player_startup_time`, + * `rebuffer_count`, `rebuffer_duration`, `requests_for_first_preroll`, + * `video_startup_preroll_load_time`, `video_startup_preroll_request_time`, + * `video_startup_time`, `view_average_request_latency`, + * `view_average_request_throughput`, `view_max_request_latency`, + * `weighted_average_bitrate` "avg" : `ad_break_error_percentage`, + * `ad_error_percentage`, `ad_exit_before_start_count`, + * `ad_exit_before_start_percentage`, `ad_playback_failure_percentage`, + * `ad_startup_error_count`, `ad_startup_error_percentage`, + * `content_playback_failure_percentage`, `downscale_percentage`, + * `exits_before_video_start`, `playback_business_exception_percentage`, + * `playback_failure_percentage`, `playback_success_score`, `rebuffer_frequency`, + * `rebuffer_percentage`, `seek_latency`, `smoothness_score`, `startup_time_score`, + * `upscale_percentage`, `video_quality_score`, + * `video_startup_business_exception_percentage`, + * `video_startup_failure_percentage`, `view_dropped_percentage`, + * `viewer_experience_score` "count" : `started_views`, `unique_viewers` */ measurement?: '95th' | 'median' | 'avg' | 'count' | 'sum'; @@ -1120,7 +1195,7 @@ export interface MetricGetTimeseriesParams { * * Possible filterable metrics are the same as the set of metric ids, with the * exceptions of `exits_before_video_start`, `unique_viewers`, - * `video_startup_failure_percentage`, and `views`. + * `video_startup_failure_percentage`, `view_dropped_percentage`, and `views`. * * Example: * @@ -1227,11 +1302,33 @@ export interface MetricListBreakdownValuesParams extends BasePageParams { | 'viewer_device_name' | 'viewer_user_id' | 'ad_playback_failure' - | 'content_playback_failure'; + | 'content_playback_failure' + | 'view_dropped'; /** * Measurement for the provided metric. If omitted, the default for the metric will - * be used. + * be used. The default measurement for each metric is: "sum" : `ad_attempt_count`, + * `ad_break_count`, `ad_break_error_count`, `ad_error_count`, + * `ad_impression_count`, `playing_time` "median" : `ad_preroll_startup_time`, + * `ad_watch_time`, `aggregate_startup_time`, `content_startup_time`, + * `content_watch_time`, `max_downscale_percentage`, `max_upscale_percentage`, + * `page_load_time`, `player_average_live_latency`, `player_startup_time`, + * `rebuffer_count`, `rebuffer_duration`, `requests_for_first_preroll`, + * `video_startup_preroll_load_time`, `video_startup_preroll_request_time`, + * `video_startup_time`, `view_average_request_latency`, + * `view_average_request_throughput`, `view_max_request_latency`, + * `weighted_average_bitrate` "avg" : `ad_break_error_percentage`, + * `ad_error_percentage`, `ad_exit_before_start_count`, + * `ad_exit_before_start_percentage`, `ad_playback_failure_percentage`, + * `ad_startup_error_count`, `ad_startup_error_percentage`, + * `content_playback_failure_percentage`, `downscale_percentage`, + * `exits_before_video_start`, `playback_business_exception_percentage`, + * `playback_failure_percentage`, `playback_success_score`, `rebuffer_frequency`, + * `rebuffer_percentage`, `seek_latency`, `smoothness_score`, `startup_time_score`, + * `upscale_percentage`, `video_quality_score`, + * `video_startup_business_exception_percentage`, + * `video_startup_failure_percentage`, `view_dropped_percentage`, + * `viewer_experience_score` "count" : `started_views`, `unique_viewers` */ measurement?: '95th' | 'median' | 'avg' | 'count' | 'sum'; @@ -1241,7 +1338,7 @@ export interface MetricListBreakdownValuesParams extends BasePageParams { * * Possible filterable metrics are the same as the set of metric ids, with the * exceptions of `exits_before_video_start`, `unique_viewers`, - * `video_startup_failure_percentage`, and `views`. + * `video_startup_failure_percentage`, `view_dropped_percentage`, and `views`. * * Example: * @@ -1271,16 +1368,20 @@ export interface MetricListBreakdownValuesParams extends BasePageParams { timeframe?: Array; } -export namespace Metrics { - export import AllMetricValuesResponse = MetricsAPI.AllMetricValuesResponse; - export import BreakdownValue = MetricsAPI.BreakdownValue; - export import InsightsResponse = MetricsAPI.InsightsResponse; - export import MetricTimeseriesDataResponse = MetricsAPI.MetricTimeseriesDataResponse; - export import OverallValuesResponse = MetricsAPI.OverallValuesResponse; - export import BreakdownValuesBasePage = MetricsAPI.BreakdownValuesBasePage; - export import MetricListParams = MetricsAPI.MetricListParams; - export import MetricGetInsightsParams = MetricsAPI.MetricGetInsightsParams; - export import MetricGetOverallValuesParams = MetricsAPI.MetricGetOverallValuesParams; - export import MetricGetTimeseriesParams = MetricsAPI.MetricGetTimeseriesParams; - export import MetricListBreakdownValuesParams = MetricsAPI.MetricListBreakdownValuesParams; +Metrics.BreakdownValuesBasePage = BreakdownValuesBasePage; + +export declare namespace Metrics { + export { + type AllMetricValuesResponse as AllMetricValuesResponse, + type BreakdownValue as BreakdownValue, + type InsightsResponse as InsightsResponse, + type MetricTimeseriesDataResponse as MetricTimeseriesDataResponse, + type OverallValuesResponse as OverallValuesResponse, + BreakdownValuesBasePage as BreakdownValuesBasePage, + type MetricListParams as MetricListParams, + type MetricGetInsightsParams as MetricGetInsightsParams, + type MetricGetOverallValuesParams as MetricGetOverallValuesParams, + type MetricGetTimeseriesParams as MetricGetTimeseriesParams, + type MetricListBreakdownValuesParams as MetricListBreakdownValuesParams, + }; } diff --git a/src/resources/data/monitoring/index.ts b/src/resources/data/monitoring/index.ts index 88d5e244..7a1b41e6 100644 --- a/src/resources/data/monitoring/index.ts +++ b/src/resources/data/monitoring/index.ts @@ -1,15 +1,15 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { - MetricListResponse, - MetricGetBreakdownResponse, - MetricGetBreakdownTimeseriesResponse, - MetricGetHistogramTimeseriesResponse, - MetricGetTimeseriesResponse, - MetricGetBreakdownParams, - MetricGetBreakdownTimeseriesParams, - MetricGetHistogramTimeseriesParams, - MetricGetTimeseriesParams, Metrics, + type MetricListResponse, + type MetricGetBreakdownResponse, + type MetricGetBreakdownTimeseriesResponse, + type MetricGetHistogramTimeseriesResponse, + type MetricGetTimeseriesResponse, + type MetricGetBreakdownParams, + type MetricGetBreakdownTimeseriesParams, + type MetricGetHistogramTimeseriesParams, + type MetricGetTimeseriesParams, } from './metrics'; -export { MonitoringListDimensionsResponse, Monitoring } from './monitoring'; +export { Monitoring, type MonitoringListDimensionsResponse } from './monitoring'; diff --git a/src/resources/data/monitoring/metrics.ts b/src/resources/data/monitoring/metrics.ts index e16d90a0..6e78c367 100644 --- a/src/resources/data/monitoring/metrics.ts +++ b/src/resources/data/monitoring/metrics.ts @@ -1,9 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as MetricsAPI from '@mux/mux-node/resources/data/monitoring/metrics'; +import { APIResource } from '../../../resource'; +import { isRequestOptions } from '../../../core'; +import * as Core from '../../../core'; export class Metrics extends APIResource { /** @@ -463,14 +462,16 @@ export interface MetricGetTimeseriesParams { timestamp?: number; } -export namespace Metrics { - export import MetricListResponse = MetricsAPI.MetricListResponse; - export import MetricGetBreakdownResponse = MetricsAPI.MetricGetBreakdownResponse; - export import MetricGetBreakdownTimeseriesResponse = MetricsAPI.MetricGetBreakdownTimeseriesResponse; - export import MetricGetHistogramTimeseriesResponse = MetricsAPI.MetricGetHistogramTimeseriesResponse; - export import MetricGetTimeseriesResponse = MetricsAPI.MetricGetTimeseriesResponse; - export import MetricGetBreakdownParams = MetricsAPI.MetricGetBreakdownParams; - export import MetricGetBreakdownTimeseriesParams = MetricsAPI.MetricGetBreakdownTimeseriesParams; - export import MetricGetHistogramTimeseriesParams = MetricsAPI.MetricGetHistogramTimeseriesParams; - export import MetricGetTimeseriesParams = MetricsAPI.MetricGetTimeseriesParams; +export declare namespace Metrics { + export { + type MetricListResponse as MetricListResponse, + type MetricGetBreakdownResponse as MetricGetBreakdownResponse, + type MetricGetBreakdownTimeseriesResponse as MetricGetBreakdownTimeseriesResponse, + type MetricGetHistogramTimeseriesResponse as MetricGetHistogramTimeseriesResponse, + type MetricGetTimeseriesResponse as MetricGetTimeseriesResponse, + type MetricGetBreakdownParams as MetricGetBreakdownParams, + type MetricGetBreakdownTimeseriesParams as MetricGetBreakdownTimeseriesParams, + type MetricGetHistogramTimeseriesParams as MetricGetHistogramTimeseriesParams, + type MetricGetTimeseriesParams as MetricGetTimeseriesParams, + }; } diff --git a/src/resources/data/monitoring/monitoring.ts b/src/resources/data/monitoring/monitoring.ts index d1d4acd1..a873725a 100644 --- a/src/resources/data/monitoring/monitoring.ts +++ b/src/resources/data/monitoring/monitoring.ts @@ -1,9 +1,20 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import * as MonitoringAPI from '@mux/mux-node/resources/data/monitoring/monitoring'; -import * as MetricsAPI from '@mux/mux-node/resources/data/monitoring/metrics'; +import { APIResource } from '../../../resource'; +import * as Core from '../../../core'; +import * as MetricsAPI from './metrics'; +import { + MetricGetBreakdownParams, + MetricGetBreakdownResponse, + MetricGetBreakdownTimeseriesParams, + MetricGetBreakdownTimeseriesResponse, + MetricGetHistogramTimeseriesParams, + MetricGetHistogramTimeseriesResponse, + MetricGetTimeseriesParams, + MetricGetTimeseriesResponse, + MetricListResponse, + Metrics, +} from './metrics'; export class Monitoring extends APIResource { metrics: MetricsAPI.Metrics = new MetricsAPI.Metrics(this._client); @@ -32,16 +43,21 @@ export namespace MonitoringListDimensionsResponse { } } -export namespace Monitoring { - export import MonitoringListDimensionsResponse = MonitoringAPI.MonitoringListDimensionsResponse; - export import Metrics = MetricsAPI.Metrics; - export import MetricListResponse = MetricsAPI.MetricListResponse; - export import MetricGetBreakdownResponse = MetricsAPI.MetricGetBreakdownResponse; - export import MetricGetBreakdownTimeseriesResponse = MetricsAPI.MetricGetBreakdownTimeseriesResponse; - export import MetricGetHistogramTimeseriesResponse = MetricsAPI.MetricGetHistogramTimeseriesResponse; - export import MetricGetTimeseriesResponse = MetricsAPI.MetricGetTimeseriesResponse; - export import MetricGetBreakdownParams = MetricsAPI.MetricGetBreakdownParams; - export import MetricGetBreakdownTimeseriesParams = MetricsAPI.MetricGetBreakdownTimeseriesParams; - export import MetricGetHistogramTimeseriesParams = MetricsAPI.MetricGetHistogramTimeseriesParams; - export import MetricGetTimeseriesParams = MetricsAPI.MetricGetTimeseriesParams; +Monitoring.Metrics = Metrics; + +export declare namespace Monitoring { + export { type MonitoringListDimensionsResponse as MonitoringListDimensionsResponse }; + + export { + Metrics as Metrics, + type MetricListResponse as MetricListResponse, + type MetricGetBreakdownResponse as MetricGetBreakdownResponse, + type MetricGetBreakdownTimeseriesResponse as MetricGetBreakdownTimeseriesResponse, + type MetricGetHistogramTimeseriesResponse as MetricGetHistogramTimeseriesResponse, + type MetricGetTimeseriesResponse as MetricGetTimeseriesResponse, + type MetricGetBreakdownParams as MetricGetBreakdownParams, + type MetricGetBreakdownTimeseriesParams as MetricGetBreakdownTimeseriesParams, + type MetricGetHistogramTimeseriesParams as MetricGetHistogramTimeseriesParams, + type MetricGetTimeseriesParams as MetricGetTimeseriesParams, + }; } diff --git a/src/resources/data/real-time.ts b/src/resources/data/real-time.ts index 9483832b..13f90fb0 100644 --- a/src/resources/data/real-time.ts +++ b/src/resources/data/real-time.ts @@ -1,9 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as RealTimeAPI from '@mux/mux-node/resources/data/real-time'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; export class RealTime extends APIResource { /** @@ -348,13 +347,15 @@ export interface RealTimeRetrieveTimeseriesParams { timestamp?: number; } -export namespace RealTime { - export import RealTimeBreakdownResponse = RealTimeAPI.RealTimeBreakdownResponse; - export import RealTimeDimensionsResponse = RealTimeAPI.RealTimeDimensionsResponse; - export import RealTimeHistogramTimeseriesResponse = RealTimeAPI.RealTimeHistogramTimeseriesResponse; - export import RealTimeMetricsResponse = RealTimeAPI.RealTimeMetricsResponse; - export import RealTimeTimeseriesResponse = RealTimeAPI.RealTimeTimeseriesResponse; - export import RealTimeRetrieveBreakdownParams = RealTimeAPI.RealTimeRetrieveBreakdownParams; - export import RealTimeRetrieveHistogramTimeseriesParams = RealTimeAPI.RealTimeRetrieveHistogramTimeseriesParams; - export import RealTimeRetrieveTimeseriesParams = RealTimeAPI.RealTimeRetrieveTimeseriesParams; +export declare namespace RealTime { + export { + type RealTimeBreakdownResponse as RealTimeBreakdownResponse, + type RealTimeDimensionsResponse as RealTimeDimensionsResponse, + type RealTimeHistogramTimeseriesResponse as RealTimeHistogramTimeseriesResponse, + type RealTimeMetricsResponse as RealTimeMetricsResponse, + type RealTimeTimeseriesResponse as RealTimeTimeseriesResponse, + type RealTimeRetrieveBreakdownParams as RealTimeRetrieveBreakdownParams, + type RealTimeRetrieveHistogramTimeseriesParams as RealTimeRetrieveHistogramTimeseriesParams, + type RealTimeRetrieveTimeseriesParams as RealTimeRetrieveTimeseriesParams, + }; } diff --git a/src/resources/data/video-views.ts b/src/resources/data/video-views.ts index dc5ec067..95d583a7 100644 --- a/src/resources/data/video-views.ts +++ b/src/resources/data/video-views.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as VideoViewsAPI from '@mux/mux-node/resources/data/video-views'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class VideoViews extends APIResource { /** @@ -332,6 +331,8 @@ export namespace VideoViewResponse { view_drm_type: string | null; + view_dropped: boolean; + view_dropped_frame_count: number | null; view_end: string; @@ -447,7 +448,7 @@ export interface VideoViewListParams extends BasePageParams { * * Possible filterable metrics are the same as the set of metric ids, with the * exceptions of `exits_before_video_start`, `unique_viewers`, - * `video_startup_failure_percentage`, and `views`. + * `video_startup_failure_percentage`, `view_dropped_percentage`, and `views`. * * Example: * @@ -478,9 +479,13 @@ export interface VideoViewListParams extends BasePageParams { viewer_id?: string; } -export namespace VideoViews { - export import AbridgedVideoView = VideoViewsAPI.AbridgedVideoView; - export import VideoViewResponse = VideoViewsAPI.VideoViewResponse; - export import AbridgedVideoViewsBasePage = VideoViewsAPI.AbridgedVideoViewsBasePage; - export import VideoViewListParams = VideoViewsAPI.VideoViewListParams; +VideoViews.AbridgedVideoViewsBasePage = AbridgedVideoViewsBasePage; + +export declare namespace VideoViews { + export { + type AbridgedVideoView as AbridgedVideoView, + type VideoViewResponse as VideoViewResponse, + AbridgedVideoViewsBasePage as AbridgedVideoViewsBasePage, + type VideoViewListParams as VideoViewListParams, + }; } diff --git a/src/resources/index.ts b/src/resources/index.ts index 5317c946..658848df 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -1,63 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export * from './shared'; -export { - BaseWebhookEvent, - VideoAssetCreatedWebhookEvent, - VideoAssetReadyWebhookEvent, - VideoAssetErroredWebhookEvent, - VideoAssetUpdatedWebhookEvent, - VideoAssetDeletedWebhookEvent, - VideoAssetLiveStreamCompletedWebhookEvent, - VideoAssetStaticRenditionsReadyWebhookEvent, - VideoAssetStaticRenditionsPreparingWebhookEvent, - VideoAssetStaticRenditionsDeletedWebhookEvent, - VideoAssetStaticRenditionsErroredWebhookEvent, - VideoAssetMasterReadyWebhookEvent, - VideoAssetMasterPreparingWebhookEvent, - VideoAssetMasterDeletedWebhookEvent, - VideoAssetMasterErroredWebhookEvent, - VideoAssetTrackCreatedWebhookEvent, - VideoAssetTrackReadyWebhookEvent, - VideoAssetTrackErroredWebhookEvent, - VideoAssetTrackDeletedWebhookEvent, - VideoAssetWarningWebhookEvent, - VideoUploadAssetCreatedWebhookEvent, - VideoUploadCancelledWebhookEvent, - VideoUploadCreatedWebhookEvent, - VideoUploadErroredWebhookEvent, - VideoLiveStreamCreatedWebhookEvent, - VideoLiveStreamConnectedWebhookEvent, - VideoLiveStreamRecordingWebhookEvent, - VideoLiveStreamActiveWebhookEvent, - VideoLiveStreamDisconnectedWebhookEvent, - VideoLiveStreamIdleWebhookEvent, - VideoLiveStreamUpdatedWebhookEvent, - VideoLiveStreamEnabledWebhookEvent, - VideoLiveStreamDisabledWebhookEvent, - VideoLiveStreamDeletedWebhookEvent, - VideoLiveStreamWarningWebhookEvent, - VideoLiveStreamSimulcastTargetCreatedWebhookEvent, - VideoLiveStreamSimulcastTargetIdleWebhookEvent, - VideoLiveStreamSimulcastTargetStartingWebhookEvent, - VideoLiveStreamSimulcastTargetBroadcastingWebhookEvent, - VideoLiveStreamSimulcastTargetErroredWebhookEvent, - VideoLiveStreamSimulcastTargetDeletedWebhookEvent, - VideoLiveStreamSimulcastTargetUpdatedWebhookEvent, - VideoSpaceCreatedWebhookEvent, - VideoSpaceDeletedWebhookEvent, - VideoSpaceActiveWebhookEvent, - VideoSpaceIdleWebhookEvent, - VideoSpaceUpdatedWebhookEvent, - VideoSpaceBroadcastCreatedWebhookEvent, - VideoSpaceBroadcastIdleWebhookEvent, - VideoSpaceBroadcastActiveWebhookEvent, - VideoSpaceBroadcastDeletedWebhookEvent, - VideoDeliveryHighTrafficWebhookEvent, - UnwrapWebhookEvent, - Webhooks, -} from './webhooks'; export { Data } from './data/data'; export { Jwt } from './jwt'; export { System } from './system/system'; export { Video } from './video/video'; +export { Webhooks } from './webhooks'; diff --git a/src/resources/jwt.ts b/src/resources/jwt.ts index 68c67778..a761fe25 100644 --- a/src/resources/jwt.ts +++ b/src/resources/jwt.ts @@ -4,18 +4,45 @@ import { APIResource } from '@mux/mux-node/resource'; import * as jwt from '@mux/mux-node/_shims/auto/jwt'; import { type SignOptions, - type MuxJWTSignOptions, TypeClaim, DataTypeClaim, + TypeToken, + type MuxJWTSignOptions, + type MuxJWTSignOptionsMultiple, + type Tokens, + isMuxJWTSignOptionsMultiple, } from '@mux/mux-node/util/jwt-types'; export class Jwt extends APIResource { + async signPlaybackId( + playbackId: string, + config?: MuxJWTSignOptions, + ): Promise; + + async signPlaybackId( + playbackId: string, + config?: MuxJWTSignOptionsMultiple, + ): Promise; + /** - * Creates a new token to be used with a signed Playback ID + * Creates a new token or tokens to be used with a signed Playback ID */ async signPlaybackId( playbackId: string, - config: MuxJWTSignOptions = {}, + config: + | MuxJWTSignOptions + | MuxJWTSignOptionsMultiple = {}, + ): Promise { + if (isMuxJWTSignOptionsMultiple(config)) { + return this.signPlaybackIdMultipleTypes(playbackId, config); + } else { + return this.signPlaybackIdSingleType(playbackId, config); + } + } + + private async signPlaybackIdSingleType( + playbackId: string, + config: MuxJWTSignOptions, ): Promise { const claim = TypeClaim[config.type ?? 'video']; if (!claim) { @@ -34,6 +61,43 @@ export class Jwt extends APIResource { return jwt.sign(config.params ?? {}, await jwt.getPrivateKey(this._client, config), tokenOptions); } + private async signPlaybackIdMultipleTypes( + playbackId: string, + config: MuxJWTSignOptionsMultiple, + ): Promise { + const tokens: Tokens = {}; + + for (const typeOption of config.type) { + let type: keyof typeof TypeClaim; + let params: Record | undefined; + + if (Array.isArray(typeOption)) { + [type, params] = typeOption; + } else { + type = typeOption; + params = undefined; + } + + const singleConfig = { + ...config, + type, + params: { + ...config.params, + ...params, + }, + }; + + const token = await this.signPlaybackIdSingleType(playbackId, singleConfig); + + const tokenKey = TypeToken[type]; + if (tokenKey) { + tokens[tokenKey] = token; + } + } + + return tokens; + } + /** * Creates a new token for a license for playing back DRM'd video content */ diff --git a/src/resources/shared.ts b/src/resources/shared.ts index 35d57151..a89b156c 100644 --- a/src/resources/shared.ts +++ b/src/resources/shared.ts @@ -14,6 +14,9 @@ export interface PlaybackID { * `https://stream.mux.com/${PLAYBACK_ID}?token={TOKEN}`. See * [Secure video playback](https://docs.mux.com/guides/secure-video-playback) for * details about creating tokens. + * + * - `drm` playback IDs are protected with DRM technologies. + * [See DRM documentation for more details](https://docs.mux.com/guides/protect-videos-with-drm). */ policy: PlaybackPolicy; @@ -32,5 +35,8 @@ export interface PlaybackID { * `https://stream.mux.com/${PLAYBACK_ID}?token={TOKEN}`. See * [Secure video playback](https://docs.mux.com/guides/secure-video-playback) for * details about creating tokens. + * + * - `drm` playback IDs are protected with DRM technologies. + * [See DRM documentation for more details](https://docs.mux.com/guides/protect-videos-with-drm). */ export type PlaybackPolicy = 'public' | 'signed' | 'drm'; diff --git a/src/resources/system/index.ts b/src/resources/system/index.ts index ce520afa..bd073f8e 100644 --- a/src/resources/system/index.ts +++ b/src/resources/system/index.ts @@ -1,10 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { - SigningKey, - SigningKeyResponse, - SigningKeyListParams, SigningKeysBasePage, SigningKeys, + type SigningKey, + type SigningKeyResponse, + type SigningKeyListParams, } from './signing-keys'; export { System } from './system'; diff --git a/src/resources/system/signing-keys.ts b/src/resources/system/signing-keys.ts index 7ff0abae..f319db00 100644 --- a/src/resources/system/signing-keys.ts +++ b/src/resources/system/signing-keys.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as SigningKeysAPI from '@mux/mux-node/resources/system/signing-keys'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class SigningKeys extends APIResource { /** @@ -89,9 +88,13 @@ export interface SigningKeyResponse { export interface SigningKeyListParams extends BasePageParams {} -export namespace SigningKeys { - export import SigningKey = SigningKeysAPI.SigningKey; - export import SigningKeyResponse = SigningKeysAPI.SigningKeyResponse; - export import SigningKeysBasePage = SigningKeysAPI.SigningKeysBasePage; - export import SigningKeyListParams = SigningKeysAPI.SigningKeyListParams; +SigningKeys.SigningKeysBasePage = SigningKeysBasePage; + +export declare namespace SigningKeys { + export { + type SigningKey as SigningKey, + type SigningKeyResponse as SigningKeyResponse, + SigningKeysBasePage as SigningKeysBasePage, + type SigningKeyListParams as SigningKeyListParams, + }; } diff --git a/src/resources/system/system.ts b/src/resources/system/system.ts index b13d3087..2fba8eaf 100644 --- a/src/resources/system/system.ts +++ b/src/resources/system/system.ts @@ -1,16 +1,28 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '@mux/mux-node/resource'; -import * as SigningKeysAPI from '@mux/mux-node/resources/system/signing-keys'; +import { APIResource } from '../../resource'; +import * as SigningKeysAPI from './signing-keys'; +import { + SigningKey, + SigningKeyListParams, + SigningKeyResponse, + SigningKeys, + SigningKeysBasePage, +} from './signing-keys'; export class System extends APIResource { signingKeys: SigningKeysAPI.SigningKeys = new SigningKeysAPI.SigningKeys(this._client); } -export namespace System { - export import SigningKeys = SigningKeysAPI.SigningKeys; - export import SigningKey = SigningKeysAPI.SigningKey; - export import SigningKeyResponse = SigningKeysAPI.SigningKeyResponse; - export import SigningKeysBasePage = SigningKeysAPI.SigningKeysBasePage; - export import SigningKeyListParams = SigningKeysAPI.SigningKeyListParams; +System.SigningKeys = SigningKeys; +System.SigningKeysBasePage = SigningKeysBasePage; + +export declare namespace System { + export { + SigningKeys as SigningKeys, + type SigningKey as SigningKey, + type SigningKeyResponse as SigningKeyResponse, + SigningKeysBasePage as SigningKeysBasePage, + type SigningKeyListParams as SigningKeyListParams, + }; } diff --git a/src/resources/video/assets.ts b/src/resources/video/assets.ts index 7ba59f52..9460f327 100644 --- a/src/resources/video/assets.ts +++ b/src/resources/video/assets.ts @@ -1,11 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as AssetsAPI from '@mux/mux-node/resources/video/assets'; -import * as Shared from '@mux/mux-node/resources/shared'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import * as Shared from '../shared'; +import { BasePage, type BasePageParams } from '../../pagination'; export class Assets extends APIResource { /** @@ -226,11 +225,12 @@ export interface Asset { created_at: string; /** - * The encoding tier informs the cost, quality, and available platform features for - * the asset. By default the `smart` encoding tier is used. - * [See the guide for more details.](https://docs.mux.com/guides/use-encoding-tiers) + * @deprecated: This field is deprecated. Please use `video_quality` instead. The + * encoding tier informs the cost, quality, and available platform features for the + * asset. The default encoding tier for an account can be set in the Mux Dashboard. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) */ - encoding_tier: 'smart' | 'baseline'; + encoding_tier: 'smart' | 'baseline' | 'premium'; master_access: 'temporary' | 'none'; @@ -384,6 +384,14 @@ export interface Asset { * when the asset is created from a direct upload. */ upload_id?: string; + + /** + * The video quality controls the cost, quality, and available platform features + * for the asset. The default video quality for an account can be set in the Mux + * Dashboard. This field replaces the deprecated `encoding_tier` value. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) + */ + video_quality?: 'basic' | 'plus' | 'premium'; } export namespace Asset { @@ -567,17 +575,18 @@ export namespace Asset { export interface AssetOptions { /** * An array of playback policy objects that you want applied to this asset and - * available through `playback_ids`. `advanced_playback_policy` must be used + * available through `playback_ids`. `advanced_playback_policies` must be used * instead of `playback_policy` when creating a DRM playback ID. */ - advanced_playback_policy?: Array; + advanced_playback_policies?: Array; /** - * The encoding tier informs the cost, quality, and available platform features for - * the asset. By default the `smart` encoding tier is used. - * [See the guide for more details.](https://docs.mux.com/guides/use-encoding-tiers) + * @deprecated: This field is deprecated. Please use `video_quality` instead. The + * encoding tier informs the cost, quality, and available platform features for the + * asset. The default encoding tier for an account can be set in the Mux Dashboard. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) */ - encoding_tier?: 'smart' | 'baseline'; + encoding_tier?: 'smart' | 'baseline' | 'premium'; /** * An array of objects that each describe an input file to be used to create the @@ -667,6 +676,14 @@ export interface AssetOptions { * limited to 10 seconds, deleted after 24 hrs. */ test?: boolean; + + /** + * The video quality controls the cost, quality, and available platform features + * for the asset. The default video quality for an account can be set in the Mux + * Dashboard. This field replaces the deprecated `encoding_tier` value. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) + */ + video_quality?: 'basic' | 'plus' | 'premium'; } export namespace AssetOptions { @@ -685,6 +702,9 @@ export namespace AssetOptions { * `https://stream.mux.com/${PLAYBACK_ID}?token={TOKEN}`. See * [Secure video playback](https://docs.mux.com/guides/secure-video-playback) for * details about creating tokens. + * + * - `drm` playback IDs are protected with DRM technologies. + * [See DRM documentation for more details](https://docs.mux.com/guides/protect-videos-with-drm). */ policy?: Shared.PlaybackPolicy; } @@ -1294,17 +1314,18 @@ export interface AssetCreateParams { /** * An array of playback policy objects that you want applied to this asset and - * available through `playback_ids`. `advanced_playback_policy` must be used + * available through `playback_ids`. `advanced_playback_policies` must be used * instead of `playback_policy` when creating a DRM playback ID. */ - advanced_playback_policy?: Array; + advanced_playback_policies?: Array; /** - * The encoding tier informs the cost, quality, and available platform features for - * the asset. By default the `smart` encoding tier is used. - * [See the guide for more details.](https://docs.mux.com/guides/use-encoding-tiers) + * This field is deprecated. Please use `video_quality` instead. The encoding tier + * informs the cost, quality, and available platform features for the asset. The + * default encoding tier for an account can be set in the Mux Dashboard. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) */ - encoding_tier?: 'smart' | 'baseline'; + encoding_tier?: 'smart' | 'baseline' | 'premium'; /** * Specify what level (if any) of support for master access. Master access can be @@ -1384,6 +1405,14 @@ export interface AssetCreateParams { * limited to 10 seconds, deleted after 24 hrs. */ test?: boolean; + + /** + * The video quality controls the cost, quality, and available platform features + * for the asset. The default video quality for an account can be set in the Mux + * Dashboard. This field replaces the deprecated `encoding_tier` value. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) + */ + video_quality?: 'basic' | 'plus' | 'premium'; } export namespace AssetCreateParams { @@ -1615,6 +1644,9 @@ export namespace AssetCreateParams { * `https://stream.mux.com/${PLAYBACK_ID}?token={TOKEN}`. See * [Secure video playback](https://docs.mux.com/guides/secure-video-playback) for * details about creating tokens. + * + * - `drm` playback IDs are protected with DRM technologies. + * [See DRM documentation for more details](https://docs.mux.com/guides/protect-videos-with-drm). */ policy?: Shared.PlaybackPolicy; } @@ -1655,6 +1687,9 @@ export interface AssetCreatePlaybackIDParams { * `https://stream.mux.com/${PLAYBACK_ID}?token={TOKEN}`. See * [Secure video playback](https://docs.mux.com/guides/secure-video-playback) for * details about creating tokens. + * + * - `drm` playback IDs are protected with DRM technologies. + * [See DRM documentation for more details](https://docs.mux.com/guides/protect-videos-with-drm). */ policy?: Shared.PlaybackPolicy; } @@ -1786,21 +1821,25 @@ export interface AssetUpdateMP4SupportParams { mp4_support: 'standard' | 'none' | 'capped-1080p' | 'audio-only' | 'audio-only,capped-1080p'; } -export namespace Assets { - export import Asset = AssetsAPI.Asset; - export import AssetOptions = AssetsAPI.AssetOptions; - export import AssetResponse = AssetsAPI.AssetResponse; - export import InputInfo = AssetsAPI.InputInfo; - export import Track = AssetsAPI.Track; - export import AssetGenerateSubtitlesResponse = AssetsAPI.AssetGenerateSubtitlesResponse; - export import AssetRetrieveInputInfoResponse = AssetsAPI.AssetRetrieveInputInfoResponse; - export import AssetsBasePage = AssetsAPI.AssetsBasePage; - export import AssetCreateParams = AssetsAPI.AssetCreateParams; - export import AssetUpdateParams = AssetsAPI.AssetUpdateParams; - export import AssetListParams = AssetsAPI.AssetListParams; - export import AssetCreatePlaybackIDParams = AssetsAPI.AssetCreatePlaybackIDParams; - export import AssetCreateTrackParams = AssetsAPI.AssetCreateTrackParams; - export import AssetGenerateSubtitlesParams = AssetsAPI.AssetGenerateSubtitlesParams; - export import AssetUpdateMasterAccessParams = AssetsAPI.AssetUpdateMasterAccessParams; - export import AssetUpdateMP4SupportParams = AssetsAPI.AssetUpdateMP4SupportParams; +Assets.AssetsBasePage = AssetsBasePage; + +export declare namespace Assets { + export { + type Asset as Asset, + type AssetOptions as AssetOptions, + type AssetResponse as AssetResponse, + type InputInfo as InputInfo, + type Track as Track, + type AssetGenerateSubtitlesResponse as AssetGenerateSubtitlesResponse, + type AssetRetrieveInputInfoResponse as AssetRetrieveInputInfoResponse, + AssetsBasePage as AssetsBasePage, + type AssetCreateParams as AssetCreateParams, + type AssetUpdateParams as AssetUpdateParams, + type AssetListParams as AssetListParams, + type AssetCreatePlaybackIDParams as AssetCreatePlaybackIDParams, + type AssetCreateTrackParams as AssetCreateTrackParams, + type AssetGenerateSubtitlesParams as AssetGenerateSubtitlesParams, + type AssetUpdateMasterAccessParams as AssetUpdateMasterAccessParams, + type AssetUpdateMP4SupportParams as AssetUpdateMP4SupportParams, + }; } diff --git a/src/resources/video/delivery-usage.ts b/src/resources/video/delivery-usage.ts index 9493aaa5..b377eb87 100644 --- a/src/resources/video/delivery-usage.ts +++ b/src/resources/video/delivery-usage.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as DeliveryUsageAPI from '@mux/mux-node/resources/video/delivery-usage'; -import { PageWithTotal, type PageWithTotalParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { PageWithTotal, type PageWithTotalParams } from '../../pagination'; export class DeliveryUsage extends APIResource { /** @@ -39,10 +38,11 @@ export interface DeliveryReport { asset_duration: number; /** + * @deprecated: This field is deprecated. Please use `asset_video_quality` instead. * The encoding tier that the asset was ingested at. - * [See the encoding tiers guide for more details.](https://docs.mux.com/guides/use-encoding-tiers) + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) */ - asset_encoding_tier: 'smart' | 'baseline'; + asset_encoding_tier: 'smart' | 'baseline' | 'premium'; /** * Unique identifier for the asset. @@ -76,6 +76,13 @@ export interface DeliveryReport { */ delivered_seconds_by_resolution: DeliveryReport.DeliveredSecondsByResolution; + /** + * The video quality that the asset was ingested at. This field replaces + * `asset_encoding_tier`. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) + */ + asset_video_quality?: 'basic' | 'plus' | 'premium'; + /** * If exists, time at which the asset was deleted. Measured in seconds since the * Unix epoch. @@ -155,8 +162,12 @@ export interface DeliveryUsageListParams extends PageWithTotalParams { timeframe?: Array; } -export namespace DeliveryUsage { - export import DeliveryReport = DeliveryUsageAPI.DeliveryReport; - export import DeliveryReportsPageWithTotal = DeliveryUsageAPI.DeliveryReportsPageWithTotal; - export import DeliveryUsageListParams = DeliveryUsageAPI.DeliveryUsageListParams; +DeliveryUsage.DeliveryReportsPageWithTotal = DeliveryReportsPageWithTotal; + +export declare namespace DeliveryUsage { + export { + type DeliveryReport as DeliveryReport, + DeliveryReportsPageWithTotal as DeliveryReportsPageWithTotal, + type DeliveryUsageListParams as DeliveryUsageListParams, + }; } diff --git a/src/resources/video/drm-configurations.ts b/src/resources/video/drm-configurations.ts index 3be3bba8..11f603d0 100644 --- a/src/resources/video/drm-configurations.ts +++ b/src/resources/video/drm-configurations.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as DRMConfigurationsAPI from '@mux/mux-node/resources/video/drm-configurations'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class DRMConfigurations extends APIResource { /** @@ -51,8 +50,12 @@ export interface DRMConfiguration { export interface DRMConfigurationListParams extends BasePageParams {} -export namespace DRMConfigurations { - export import DRMConfiguration = DRMConfigurationsAPI.DRMConfiguration; - export import DRMConfigurationsBasePage = DRMConfigurationsAPI.DRMConfigurationsBasePage; - export import DRMConfigurationListParams = DRMConfigurationsAPI.DRMConfigurationListParams; +DRMConfigurations.DRMConfigurationsBasePage = DRMConfigurationsBasePage; + +export declare namespace DRMConfigurations { + export { + type DRMConfiguration as DRMConfiguration, + DRMConfigurationsBasePage as DRMConfigurationsBasePage, + type DRMConfigurationListParams as DRMConfigurationListParams, + }; } diff --git a/src/resources/video/index.ts b/src/resources/video/index.ts index ef336a7c..417040ef 100644 --- a/src/resources/video/index.ts +++ b/src/resources/video/index.ts @@ -1,105 +1,89 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. export { - Asset, - AssetOptions, - AssetResponse, - InputInfo, - Track, - AssetGenerateSubtitlesResponse, - AssetRetrieveInputInfoResponse, - AssetCreateParams, - AssetUpdateParams, - AssetListParams, - AssetCreatePlaybackIDParams, - AssetCreateTrackParams, - AssetGenerateSubtitlesParams, - AssetUpdateMasterAccessParams, - AssetUpdateMP4SupportParams, AssetsBasePage, Assets, + type Asset, + type AssetOptions, + type AssetResponse, + type InputInfo, + type Track, + type AssetGenerateSubtitlesResponse, + type AssetRetrieveInputInfoResponse, + type AssetCreateParams, + type AssetUpdateParams, + type AssetListParams, + type AssetCreatePlaybackIDParams, + type AssetCreateTrackParams, + type AssetGenerateSubtitlesParams, + type AssetUpdateMasterAccessParams, + type AssetUpdateMP4SupportParams, } from './assets'; export { - Broadcast, - BroadcastLayout, - BroadcastResolution, - BroadcastResponse, - BroadcastStatus, - Space, - SpaceResponse, - SpaceStatus, - SpaceType, - SpaceCreateParams, - SpaceListParams, - SpaceCreateBroadcastParams, - SpacesBasePage, - Spaces, -} from './spaces'; -export { - DRMConfiguration, - DRMConfigurationListParams, DRMConfigurationsBasePage, DRMConfigurations, + type DRMConfiguration, + type DRMConfigurationListParams, } from './drm-configurations'; export { - DeliveryReport, - DeliveryUsageListParams, DeliveryReportsPageWithTotal, DeliveryUsage, + type DeliveryReport, + type DeliveryUsageListParams, } from './delivery-usage'; export { - LiveStream, - SimulcastTarget, - LiveStreamCreateParams, - LiveStreamUpdateParams, - LiveStreamListParams, - LiveStreamCreatePlaybackIDParams, - LiveStreamCreateSimulcastTargetParams, - LiveStreamUpdateEmbeddedSubtitlesParams, - LiveStreamUpdateGeneratedSubtitlesParams, LiveStreamsBasePage, LiveStreams, + type LiveStream, + type SimulcastTarget, + type LiveStreamCreateParams, + type LiveStreamUpdateParams, + type LiveStreamListParams, + type LiveStreamCreatePlaybackIDParams, + type LiveStreamCreateSimulcastTargetParams, + type LiveStreamUpdateEmbeddedSubtitlesParams, + type LiveStreamUpdateGeneratedSubtitlesParams, } from './live-streams'; -export { PlaybackIDRetrieveResponse, PlaybackIDs } from './playback-ids'; +export { PlaybackIDs, type PlaybackIDRetrieveResponse } from './playback-ids'; export { - PlaybackRestriction, - PlaybackRestrictionResponse, - PlaybackRestrictionCreateParams, - PlaybackRestrictionListParams, - PlaybackRestrictionUpdateReferrerParams, - PlaybackRestrictionUpdateUserAgentParams, PlaybackRestrictionsBasePage, PlaybackRestrictions, + type PlaybackRestriction, + type PlaybackRestrictionResponse, + type PlaybackRestrictionCreateParams, + type PlaybackRestrictionListParams, + type PlaybackRestrictionUpdateReferrerParams, + type PlaybackRestrictionUpdateUserAgentParams, } from './playback-restrictions'; export { - TranscriptionVocabulary, - TranscriptionVocabularyResponse, - TranscriptionVocabularyCreateParams, - TranscriptionVocabularyUpdateParams, - TranscriptionVocabularyListParams, TranscriptionVocabulariesBasePage, TranscriptionVocabularies, + type TranscriptionVocabulary, + type TranscriptionVocabularyResponse, + type TranscriptionVocabularyCreateParams, + type TranscriptionVocabularyUpdateParams, + type TranscriptionVocabularyListParams, } from './transcription-vocabularies'; export { - Upload, - UploadResponse, - UploadCreateParams, - UploadListParams, UploadsBasePage, Uploads, + type Upload, + type UploadResponse, + type UploadCreateParams, + type UploadListParams, } from './uploads'; export { Video } from './video'; export { - WebInputCreateResponse, - WebInputRetrieveResponse, - WebInputListResponse, - WebInputLaunchResponse, - WebInputReloadResponse, - WebInputShutdownResponse, - WebInputUpdateURLResponse, - WebInputCreateParams, - WebInputListParams, - WebInputUpdateURLParams, WebInputListResponsesBasePage, WebInputs, + type WebInputCreateResponse, + type WebInputRetrieveResponse, + type WebInputListResponse, + type WebInputLaunchResponse, + type WebInputReloadResponse, + type WebInputShutdownResponse, + type WebInputUpdateURLResponse, + type WebInputCreateParams, + type WebInputListParams, + type WebInputUpdateURLParams, } from './web-inputs'; diff --git a/src/resources/video/live-streams.ts b/src/resources/video/live-streams.ts index 2cd8a25c..e170f083 100644 --- a/src/resources/video/live-streams.ts +++ b/src/resources/video/live-streams.ts @@ -1,12 +1,11 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as LiveStreamsAPI from '@mux/mux-node/resources/video/live-streams'; -import * as Shared from '@mux/mux-node/resources/shared'; -import * as AssetsAPI from '@mux/mux-node/resources/video/assets'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import * as Shared from '../shared'; +import * as AssetsAPI from './assets'; +import { BasePage, type BasePageParams } from '../../pagination'; export class LiveStreams extends APIResource { /** @@ -573,10 +572,10 @@ export interface SimulcastTarget { export interface LiveStreamCreateParams { /** * An array of playback policy objects that you want applied to this asset and - * available through `playback_ids`. `advanced_playback_policy` must be used + * available through `playback_ids`. `advanced_playback_policies` must be used * instead of `playback_policy` when creating a DRM playback ID. */ - advanced_playback_policy?: Array; + advanced_playback_policies?: Array; /** * Force the live stream to only process the audio track when the value is set to @@ -705,6 +704,9 @@ export namespace LiveStreamCreateParams { * `https://stream.mux.com/${PLAYBACK_ID}?token={TOKEN}`. See * [Secure video playback](https://docs.mux.com/guides/secure-video-playback) for * details about creating tokens. + * + * - `drm` playback IDs are protected with DRM technologies. + * [See DRM documentation for more details](https://docs.mux.com/guides/protect-videos-with-drm). */ policy?: Shared.PlaybackPolicy; } @@ -803,7 +805,7 @@ export interface LiveStreamUpdateParams { /** * Updates the new asset settings to use to generate a new asset for this live - * stream. Only the `mp4_support` setting may be updated. + * stream. Only the `mp4_support` and `master_access` settings may be updated. */ new_asset_settings?: LiveStreamUpdateParams.NewAssetSettings; @@ -853,9 +855,14 @@ export interface LiveStreamUpdateParams { export namespace LiveStreamUpdateParams { /** * Updates the new asset settings to use to generate a new asset for this live - * stream. Only the `mp4_support` setting may be updated. + * stream. Only the `mp4_support` and `master_access` settings may be updated. */ export interface NewAssetSettings { + /** + * Add or remove access to the master version of the video. + */ + master_access?: 'temporary' | 'none'; + /** * Specify what level of support for mp4 playback should be added to new assets * generated from this live stream. @@ -907,6 +914,9 @@ export interface LiveStreamCreatePlaybackIDParams { * `https://stream.mux.com/${PLAYBACK_ID}?token={TOKEN}`. See * [Secure video playback](https://docs.mux.com/guides/secure-video-playback) for * details about creating tokens. + * + * - `drm` playback IDs are protected with DRM technologies. + * [See DRM documentation for more details](https://docs.mux.com/guides/protect-videos-with-drm). */ policy?: Shared.PlaybackPolicy; } @@ -1007,15 +1017,19 @@ export namespace LiveStreamUpdateGeneratedSubtitlesParams { } } -export namespace LiveStreams { - export import LiveStream = LiveStreamsAPI.LiveStream; - export import SimulcastTarget = LiveStreamsAPI.SimulcastTarget; - export import LiveStreamsBasePage = LiveStreamsAPI.LiveStreamsBasePage; - export import LiveStreamCreateParams = LiveStreamsAPI.LiveStreamCreateParams; - export import LiveStreamUpdateParams = LiveStreamsAPI.LiveStreamUpdateParams; - export import LiveStreamListParams = LiveStreamsAPI.LiveStreamListParams; - export import LiveStreamCreatePlaybackIDParams = LiveStreamsAPI.LiveStreamCreatePlaybackIDParams; - export import LiveStreamCreateSimulcastTargetParams = LiveStreamsAPI.LiveStreamCreateSimulcastTargetParams; - export import LiveStreamUpdateEmbeddedSubtitlesParams = LiveStreamsAPI.LiveStreamUpdateEmbeddedSubtitlesParams; - export import LiveStreamUpdateGeneratedSubtitlesParams = LiveStreamsAPI.LiveStreamUpdateGeneratedSubtitlesParams; +LiveStreams.LiveStreamsBasePage = LiveStreamsBasePage; + +export declare namespace LiveStreams { + export { + type LiveStream as LiveStream, + type SimulcastTarget as SimulcastTarget, + LiveStreamsBasePage as LiveStreamsBasePage, + type LiveStreamCreateParams as LiveStreamCreateParams, + type LiveStreamUpdateParams as LiveStreamUpdateParams, + type LiveStreamListParams as LiveStreamListParams, + type LiveStreamCreatePlaybackIDParams as LiveStreamCreatePlaybackIDParams, + type LiveStreamCreateSimulcastTargetParams as LiveStreamCreateSimulcastTargetParams, + type LiveStreamUpdateEmbeddedSubtitlesParams as LiveStreamUpdateEmbeddedSubtitlesParams, + type LiveStreamUpdateGeneratedSubtitlesParams as LiveStreamUpdateGeneratedSubtitlesParams, + }; } diff --git a/src/resources/video/playback-ids.ts b/src/resources/video/playback-ids.ts index 1caa59ce..28951f8f 100644 --- a/src/resources/video/playback-ids.ts +++ b/src/resources/video/playback-ids.ts @@ -1,9 +1,8 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import * as PlaybackIDsAPI from '@mux/mux-node/resources/video/playback-ids'; -import * as Shared from '@mux/mux-node/resources/shared'; +import { APIResource } from '../../resource'; +import * as Core from '../../core'; +import * as Shared from '../shared'; export class PlaybackIDs extends APIResource { /** @@ -38,6 +37,9 @@ export interface PlaybackIDRetrieveResponse { * `https://stream.mux.com/${PLAYBACK_ID}?token={TOKEN}`. See * [Secure video playback](https://docs.mux.com/guides/secure-video-playback) for * details about creating tokens. + * + * - `drm` playback IDs are protected with DRM technologies. + * [See DRM documentation for more details](https://docs.mux.com/guides/protect-videos-with-drm). */ policy: Shared.PlaybackPolicy; } @@ -59,6 +61,6 @@ export namespace PlaybackIDRetrieveResponse { } } -export namespace PlaybackIDs { - export import PlaybackIDRetrieveResponse = PlaybackIDsAPI.PlaybackIDRetrieveResponse; +export declare namespace PlaybackIDs { + export { type PlaybackIDRetrieveResponse as PlaybackIDRetrieveResponse }; } diff --git a/src/resources/video/playback-restrictions.ts b/src/resources/video/playback-restrictions.ts index c8ca5fed..27925349 100644 --- a/src/resources/video/playback-restrictions.ts +++ b/src/resources/video/playback-restrictions.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as PlaybackRestrictionsAPI from '@mux/mux-node/resources/video/playback-restrictions'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class PlaybackRestrictions extends APIResource { /** @@ -280,12 +279,16 @@ export interface PlaybackRestrictionUpdateUserAgentParams { allow_no_user_agent: boolean; } -export namespace PlaybackRestrictions { - export import PlaybackRestriction = PlaybackRestrictionsAPI.PlaybackRestriction; - export import PlaybackRestrictionResponse = PlaybackRestrictionsAPI.PlaybackRestrictionResponse; - export import PlaybackRestrictionsBasePage = PlaybackRestrictionsAPI.PlaybackRestrictionsBasePage; - export import PlaybackRestrictionCreateParams = PlaybackRestrictionsAPI.PlaybackRestrictionCreateParams; - export import PlaybackRestrictionListParams = PlaybackRestrictionsAPI.PlaybackRestrictionListParams; - export import PlaybackRestrictionUpdateReferrerParams = PlaybackRestrictionsAPI.PlaybackRestrictionUpdateReferrerParams; - export import PlaybackRestrictionUpdateUserAgentParams = PlaybackRestrictionsAPI.PlaybackRestrictionUpdateUserAgentParams; +PlaybackRestrictions.PlaybackRestrictionsBasePage = PlaybackRestrictionsBasePage; + +export declare namespace PlaybackRestrictions { + export { + type PlaybackRestriction as PlaybackRestriction, + type PlaybackRestrictionResponse as PlaybackRestrictionResponse, + PlaybackRestrictionsBasePage as PlaybackRestrictionsBasePage, + type PlaybackRestrictionCreateParams as PlaybackRestrictionCreateParams, + type PlaybackRestrictionListParams as PlaybackRestrictionListParams, + type PlaybackRestrictionUpdateReferrerParams as PlaybackRestrictionUpdateReferrerParams, + type PlaybackRestrictionUpdateUserAgentParams as PlaybackRestrictionUpdateUserAgentParams, + }; } diff --git a/src/resources/video/spaces.ts b/src/resources/video/spaces.ts deleted file mode 100644 index 5c8906bd..00000000 --- a/src/resources/video/spaces.ts +++ /dev/null @@ -1,425 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as SpacesAPI from '@mux/mux-node/resources/video/spaces'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; - -export class Spaces extends APIResource { - /** - * Create a new space. Spaces are used to build - * [real-time video applications.](https://mux.com/real-time-video) - * - * @deprecated Mux Real-Time Video has been sunset and is unavailable for new usage. - * Existing access will end on December 31, 2023. - * We [recommend migrating your application to our partner, LiveKit](https://livekit.io/mux-livekit). - */ - create(body: SpaceCreateParams, options?: Core.RequestOptions): Core.APIPromise { - return ( - this._client.post('/video/v1/spaces', { body, ...options }) as Core.APIPromise<{ data: Space }> - )._thenUnwrap((obj) => obj.data); - } - - /** - * Retrieves the details of a space that has previously been created. Supply the - * unique space ID that was returned from your create space request, and Mux will - * return the information about the corresponding space. The same information is - * returned when creating a space. - * - * @deprecated Mux Real-Time Video has been sunset and is unavailable for new usage. - * Existing access will end on December 31, 2023. - * We [recommend migrating your application to our partner, LiveKit](https://livekit.io/mux-livekit). - */ - retrieve(spaceId: string, options?: Core.RequestOptions): Core.APIPromise { - return ( - this._client.get(`/video/v1/spaces/${spaceId}`, options) as Core.APIPromise<{ data: Space }> - )._thenUnwrap((obj) => obj.data); - } - - /** - * List all spaces in the current environment. - * - * @deprecated Mux Real-Time Video has been sunset and is unavailable for new usage. - * Existing access will end on December 31, 2023. - * We [recommend migrating your application to our partner, LiveKit](https://livekit.io/mux-livekit). - */ - list(query?: SpaceListParams, options?: Core.RequestOptions): Core.PagePromise; - list(options?: Core.RequestOptions): Core.PagePromise; - list( - query: SpaceListParams | Core.RequestOptions = {}, - options?: Core.RequestOptions, - ): Core.PagePromise { - if (isRequestOptions(query)) { - return this.list({}, query); - } - return this._client.getAPIList('/video/v1/spaces', SpacesBasePage, { query, ...options }); - } - - /** - * Deletes a space. Spaces can only be deleted when `idle`. - * - * @deprecated Mux Real-Time Video has been sunset and is unavailable for new usage. - * Existing access will end on December 31, 2023. - * We [recommend migrating your application to our partner, LiveKit](https://livekit.io/mux-livekit). - */ - delete(spaceId: string, options?: Core.RequestOptions): Core.APIPromise { - return this._client.delete(`/video/v1/spaces/${spaceId}`, { - ...options, - headers: { Accept: '*/*', ...options?.headers }, - }); - } - - /** - * Creates a new broadcast. Broadcasts are used to create composited versions of - * your space, which can be broadcast to live streams. **Note:** By default only a - * single broadcast destination can be specified. Contact Mux support if you need - * more. - * - * @deprecated Mux Real-Time Video has been sunset and is unavailable for new usage. - * Existing access will end on December 31, 2023. - * We [recommend migrating your application to our partner, LiveKit](https://livekit.io/mux-livekit). - */ - createBroadcast( - spaceId: string, - body: SpaceCreateBroadcastParams, - options?: Core.RequestOptions, - ): Core.APIPromise { - return ( - this._client.post(`/video/v1/spaces/${spaceId}/broadcasts`, { body, ...options }) as Core.APIPromise<{ - data: Broadcast; - }> - )._thenUnwrap((obj) => obj.data); - } - - /** - * Deletes a single broadcast of a specific space. Broadcasts can only be deleted - * when `idle`. - * - * @deprecated Mux Real-Time Video has been sunset and is unavailable for new usage. - * Existing access will end on December 31, 2023. - * We [recommend migrating your application to our partner, LiveKit](https://livekit.io/mux-livekit). - */ - deleteBroadcast( - spaceId: string, - broadcastId: string, - options?: Core.RequestOptions, - ): Core.APIPromise { - return this._client.delete(`/video/v1/spaces/${spaceId}/broadcasts/${broadcastId}`, { - ...options, - headers: { Accept: '*/*', ...options?.headers }, - }); - } - - /** - * Retrieves the details of a broadcast of a specific space. - * - * @deprecated Mux Real-Time Video has been sunset and is unavailable for new usage. - * Existing access will end on December 31, 2023. - * We [recommend migrating your application to our partner, LiveKit](https://livekit.io/mux-livekit). - */ - retrieveBroadcast( - spaceId: string, - broadcastId: string, - options?: Core.RequestOptions, - ): Core.APIPromise { - return ( - this._client.get(`/video/v1/spaces/${spaceId}/broadcasts/${broadcastId}`, options) as Core.APIPromise<{ - data: Broadcast; - }> - )._thenUnwrap((obj) => obj.data); - } - - /** - * Starts broadcasting a space to the associated destination. Broadcasts can only - * be started when the space is `active` (when there are participants connected). - * - * @deprecated Mux Real-Time Video has been sunset and is unavailable for new usage. - * Existing access will end on December 31, 2023. - * We [recommend migrating your application to our partner, LiveKit](https://livekit.io/mux-livekit). - */ - startBroadcast(spaceId: string, broadcastId: string, options?: Core.RequestOptions): Core.APIPromise { - return this._client.post(`/video/v1/spaces/${spaceId}/broadcasts/${broadcastId}/start`, { - ...options, - headers: { Accept: '*/*', ...options?.headers }, - }); - } - - /** - * Stops broadcasting a space, causing the destination live stream to become idle. - * This API also automatically calls `complete` on the destination live stream. - * Broadcasts are also automatically stopped when a space becomes idle. - * - * @deprecated Mux Real-Time Video has been sunset and is unavailable for new usage. - * Existing access will end on December 31, 2023. - * We [recommend migrating your application to our partner, LiveKit](https://livekit.io/mux-livekit). - */ - stopBroadcast(spaceId: string, broadcastId: string, options?: Core.RequestOptions): Core.APIPromise { - return this._client.post(`/video/v1/spaces/${spaceId}/broadcasts/${broadcastId}/stop`, { - ...options, - headers: { Accept: '*/*', ...options?.headers }, - }); - } -} - -export class SpacesBasePage extends BasePage {} - -export interface Broadcast { - /** - * Unique identifier for the broadcast. Max 255 characters. - */ - id: string; - - /** - * The layout used when broadcasting the space. - * - * The `gallery` layout will show participants in a grid that automatically resizes - * each participant’s stream to best fit up to 10 participants in the window. The - * `active-speaker` layout will show only the current active speaker, without a - * border. The `crop` layout uses as much of the available space as possible to - * show the participant's stream. - * - * Defaults to `gallery` if not set. - */ - layout: BroadcastLayout; - - /** - * The ID of the live stream that the broadcast will be sent to. - */ - live_stream_id: string; - - /** - * The resolution of the composited video sent to the live stream. Defaults to - * `1920x1080` if not set. - */ - resolution: BroadcastResolution; - - /** - * The status of the broadcast. You can start and stop broadcasts with the `start` - * and `stop` APIs. - */ - status: BroadcastStatus; - - /** - * URL of an image to display as the background of the broadcast. Its dimensions - * should match the provided resolution. - */ - background?: string; - - /** - * Arbitrary user-supplied metadata that will be included in the broadcast details - * and related webhooks. Max: 255 characters. - */ - passthrough?: string; -} - -/** - * The layout used when broadcasting the space. - * - * The `gallery` layout will show participants in a grid that automatically resizes - * each participant’s stream to best fit up to 10 participants in the window. The - * `active-speaker` layout will show only the current active speaker, without a - * border. The `crop` layout uses as much of the available space as possible to - * show the participant's stream. - * - * Defaults to `gallery` if not set. - */ -export type BroadcastLayout = 'gallery' | 'active-speaker' | 'crop'; - -/** - * The resolution of the composited video sent to the live stream. Defaults to - * `1920x1080` if not set. - */ -export type BroadcastResolution = - | '1920x1080' - | '1280x720' - | '1080x1920' - | '720x1280' - | '1080x1080' - | '720x720'; - -export interface BroadcastResponse { - data: Broadcast; -} - -/** - * The status of the broadcast. You can start and stop broadcasts with the `start` - * and `stop` APIs. - */ -export type BroadcastStatus = 'idle' | 'active'; - -export interface Space { - /** - * Unique identifier for the space. Max 255 characters. - */ - id: string; - - /** - * Time the space was created, defined as a Unix timestamp (seconds since epoch). - */ - created_at: string; - - /** - * The status of the space. Spaces are `idle` when there are no participants - * connected, and `active` when there are participants connected. - */ - status: SpaceStatus; - - /** - * Specify the network architecture of the space. In `server` spaces, all video - * travels through Mux's video infrastructure. Defaults to `server` if not set. - */ - type: SpaceType; - - /** - * Unique identifier for the current lifecycle of the space. Only set when the - * space is `active` and is set to a new value each time the space transitions from - * `idle` to `active`. This value is useful for logging and debugging issues. Max - * 255 characters. - */ - active_session_id?: string; - - /** - * An array of broadcast destinations. - */ - broadcasts?: Array; - - /** - * Arbitrary user-supplied metadata that will be included in the space details and - * related webhooks. Max: 255 characters. - */ - passthrough?: string; -} - -export interface SpaceResponse { - data: Space; -} - -/** - * The status of the space. Spaces are `idle` when there are no participants - * connected, and `active` when there are participants connected. - */ -export type SpaceStatus = 'idle' | 'active'; - -/** - * Specify the network architecture of the space. In `server` spaces, all video - * travels through Mux's video infrastructure. Defaults to `server` if not set. - */ -export type SpaceType = 'server'; - -export interface SpaceCreateParams { - /** - * An array of broadcast destinations you want to stream the space to. **Note:** By - * default only a single broadcast destination can be specified. Contact Mux - * support if you need more. - */ - broadcasts?: Array; - - /** - * Arbitrary user-supplied metadata that will be included in the space details and - * related webhooks. Max: 255 characters. - */ - passthrough?: string; - - /** - * Specify the network architecture of the space. In `server` spaces, all video - * travels through Mux's video infrastructure. Defaults to `server` if not set. - */ - type?: SpaceType; -} - -export namespace SpaceCreateParams { - export interface Broadcast { - /** - * The ID of the live stream that you want to broadcast to. - */ - live_stream_id: string; - - /** - * URL of an image to display as the background of the broadcast. Its dimensions - * should match the provided resolution. - */ - background?: string; - - /** - * The layout used when broadcasting the space. - * - * The `gallery` layout will show participants in a grid that automatically resizes - * each participant’s stream to best fit up to 10 participants in the window. The - * `active-speaker` layout will show only the current active speaker, without a - * border. The `crop` layout uses as much of the available space as possible to - * show the participant's stream. - * - * Defaults to `gallery` if not set. - */ - layout?: SpacesAPI.BroadcastLayout; - - /** - * Arbitrary user-supplied metadata that will be included in the broadcast details - * and related webhooks. Max: 255 characters. - */ - passthrough?: string; - - /** - * The resolution of the composited video sent to the live stream. Defaults to - * `1920x1080` if not set. - */ - resolution?: SpacesAPI.BroadcastResolution; - } -} - -export interface SpaceListParams extends BasePageParams {} - -export interface SpaceCreateBroadcastParams { - /** - * The ID of the live stream that you want to broadcast to. - */ - live_stream_id: string; - - /** - * URL of an image to display as the background of the broadcast. Its dimensions - * should match the provided resolution. - */ - background?: string; - - /** - * The layout used when broadcasting the space. - * - * The `gallery` layout will show participants in a grid that automatically resizes - * each participant’s stream to best fit up to 10 participants in the window. The - * `active-speaker` layout will show only the current active speaker, without a - * border. The `crop` layout uses as much of the available space as possible to - * show the participant's stream. - * - * Defaults to `gallery` if not set. - */ - layout?: BroadcastLayout; - - /** - * Arbitrary user-supplied metadata that will be included in the broadcast details - * and related webhooks. Max: 255 characters. - */ - passthrough?: string; - - /** - * The resolution of the composited video sent to the live stream. Defaults to - * `1920x1080` if not set. - */ - resolution?: BroadcastResolution; -} - -export namespace Spaces { - export import Broadcast = SpacesAPI.Broadcast; - export import BroadcastLayout = SpacesAPI.BroadcastLayout; - export import BroadcastResolution = SpacesAPI.BroadcastResolution; - export import BroadcastResponse = SpacesAPI.BroadcastResponse; - export import BroadcastStatus = SpacesAPI.BroadcastStatus; - export import Space = SpacesAPI.Space; - export import SpaceResponse = SpacesAPI.SpaceResponse; - export import SpaceStatus = SpacesAPI.SpaceStatus; - export import SpaceType = SpacesAPI.SpaceType; - export import SpacesBasePage = SpacesAPI.SpacesBasePage; - export import SpaceCreateParams = SpacesAPI.SpaceCreateParams; - export import SpaceListParams = SpacesAPI.SpaceListParams; - export import SpaceCreateBroadcastParams = SpacesAPI.SpaceCreateBroadcastParams; -} diff --git a/src/resources/video/transcription-vocabularies.ts b/src/resources/video/transcription-vocabularies.ts index e72d540d..c7bfa618 100644 --- a/src/resources/video/transcription-vocabularies.ts +++ b/src/resources/video/transcription-vocabularies.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as TranscriptionVocabulariesAPI from '@mux/mux-node/resources/video/transcription-vocabularies'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class TranscriptionVocabularies extends APIResource { /** @@ -184,11 +183,15 @@ export interface TranscriptionVocabularyUpdateParams { export interface TranscriptionVocabularyListParams extends BasePageParams {} -export namespace TranscriptionVocabularies { - export import TranscriptionVocabulary = TranscriptionVocabulariesAPI.TranscriptionVocabulary; - export import TranscriptionVocabularyResponse = TranscriptionVocabulariesAPI.TranscriptionVocabularyResponse; - export import TranscriptionVocabulariesBasePage = TranscriptionVocabulariesAPI.TranscriptionVocabulariesBasePage; - export import TranscriptionVocabularyCreateParams = TranscriptionVocabulariesAPI.TranscriptionVocabularyCreateParams; - export import TranscriptionVocabularyUpdateParams = TranscriptionVocabulariesAPI.TranscriptionVocabularyUpdateParams; - export import TranscriptionVocabularyListParams = TranscriptionVocabulariesAPI.TranscriptionVocabularyListParams; +TranscriptionVocabularies.TranscriptionVocabulariesBasePage = TranscriptionVocabulariesBasePage; + +export declare namespace TranscriptionVocabularies { + export { + type TranscriptionVocabulary as TranscriptionVocabulary, + type TranscriptionVocabularyResponse as TranscriptionVocabularyResponse, + TranscriptionVocabulariesBasePage as TranscriptionVocabulariesBasePage, + type TranscriptionVocabularyCreateParams as TranscriptionVocabularyCreateParams, + type TranscriptionVocabularyUpdateParams as TranscriptionVocabularyUpdateParams, + type TranscriptionVocabularyListParams as TranscriptionVocabularyListParams, + }; } diff --git a/src/resources/video/uploads.ts b/src/resources/video/uploads.ts index 4ddf9697..981e56e1 100644 --- a/src/resources/video/uploads.ts +++ b/src/resources/video/uploads.ts @@ -1,11 +1,10 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as UploadsAPI from '@mux/mux-node/resources/video/uploads'; -import * as AssetsAPI from '@mux/mux-node/resources/video/assets'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import * as AssetsAPI from './assets'; +import { BasePage, type BasePageParams } from '../../pagination'; export class Uploads extends APIResource { /** @@ -147,10 +146,14 @@ export interface UploadCreateParams { export interface UploadListParams extends BasePageParams {} -export namespace Uploads { - export import Upload = UploadsAPI.Upload; - export import UploadResponse = UploadsAPI.UploadResponse; - export import UploadsBasePage = UploadsAPI.UploadsBasePage; - export import UploadCreateParams = UploadsAPI.UploadCreateParams; - export import UploadListParams = UploadsAPI.UploadListParams; +Uploads.UploadsBasePage = UploadsBasePage; + +export declare namespace Uploads { + export { + type Upload as Upload, + type UploadResponse as UploadResponse, + UploadsBasePage as UploadsBasePage, + type UploadCreateParams as UploadCreateParams, + type UploadListParams as UploadListParams, + }; } diff --git a/src/resources/video/video.ts b/src/resources/video/video.ts index 9851008c..64cd65ef 100644 --- a/src/resources/video/video.ts +++ b/src/resources/video/video.ts @@ -1,16 +1,101 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '@mux/mux-node/resource'; -import * as AssetsAPI from '@mux/mux-node/resources/video/assets'; -import * as DeliveryUsageAPI from '@mux/mux-node/resources/video/delivery-usage'; -import * as DRMConfigurationsAPI from '@mux/mux-node/resources/video/drm-configurations'; -import * as LiveStreamsAPI from '@mux/mux-node/resources/video/live-streams'; -import * as PlaybackIDsAPI from '@mux/mux-node/resources/video/playback-ids'; -import * as PlaybackRestrictionsAPI from '@mux/mux-node/resources/video/playback-restrictions'; -import * as SpacesAPI from '@mux/mux-node/resources/video/spaces'; -import * as TranscriptionVocabulariesAPI from '@mux/mux-node/resources/video/transcription-vocabularies'; -import * as UploadsAPI from '@mux/mux-node/resources/video/uploads'; -import * as WebInputsAPI from '@mux/mux-node/resources/video/web-inputs'; +import { APIResource } from '../../resource'; +import * as AssetsAPI from './assets'; +import { + Asset, + AssetCreateParams, + AssetCreatePlaybackIDParams, + AssetCreateTrackParams, + AssetGenerateSubtitlesParams, + AssetGenerateSubtitlesResponse, + AssetListParams, + AssetOptions, + AssetResponse, + AssetRetrieveInputInfoResponse, + AssetUpdateMP4SupportParams, + AssetUpdateMasterAccessParams, + AssetUpdateParams, + Assets, + AssetsBasePage, + InputInfo, + Track, +} from './assets'; +import * as DeliveryUsageAPI from './delivery-usage'; +import { + DeliveryReport, + DeliveryReportsPageWithTotal, + DeliveryUsage, + DeliveryUsageListParams, +} from './delivery-usage'; +import * as DRMConfigurationsAPI from './drm-configurations'; +import { + DRMConfiguration, + DRMConfigurationListParams, + DRMConfigurations, + DRMConfigurationsBasePage, +} from './drm-configurations'; +import * as LiveStreamsAPI from './live-streams'; +import { + LiveStream, + LiveStreamCreateParams, + LiveStreamCreatePlaybackIDParams, + LiveStreamCreateSimulcastTargetParams, + LiveStreamListParams, + LiveStreamUpdateEmbeddedSubtitlesParams, + LiveStreamUpdateGeneratedSubtitlesParams, + LiveStreamUpdateParams, + LiveStreams, + LiveStreamsBasePage, + SimulcastTarget, +} from './live-streams'; +import * as PlaybackIDsAPI from './playback-ids'; +import { PlaybackIDRetrieveResponse, PlaybackIDs } from './playback-ids'; +import * as PlaybackRestrictionsAPI from './playback-restrictions'; +import { + PlaybackRestriction, + PlaybackRestrictionCreateParams, + PlaybackRestrictionListParams, + PlaybackRestrictionResponse, + PlaybackRestrictionUpdateReferrerParams, + PlaybackRestrictionUpdateUserAgentParams, + PlaybackRestrictions, + PlaybackRestrictionsBasePage, +} from './playback-restrictions'; +import * as TranscriptionVocabulariesAPI from './transcription-vocabularies'; +import { + TranscriptionVocabularies, + TranscriptionVocabulariesBasePage, + TranscriptionVocabulary, + TranscriptionVocabularyCreateParams, + TranscriptionVocabularyListParams, + TranscriptionVocabularyResponse, + TranscriptionVocabularyUpdateParams, +} from './transcription-vocabularies'; +import * as UploadsAPI from './uploads'; +import { + Upload, + UploadCreateParams, + UploadListParams, + UploadResponse, + Uploads, + UploadsBasePage, +} from './uploads'; +import * as WebInputsAPI from './web-inputs'; +import { + WebInputCreateParams, + WebInputCreateResponse, + WebInputLaunchResponse, + WebInputListParams, + WebInputListResponse, + WebInputListResponsesBasePage, + WebInputReloadResponse, + WebInputRetrieveResponse, + WebInputShutdownResponse, + WebInputUpdateURLParams, + WebInputUpdateURLResponse, + WebInputs, +} from './web-inputs'; export class Video extends APIResource { assets: AssetsAPI.Assets = new AssetsAPI.Assets(this._client); @@ -19,7 +104,6 @@ export class Video extends APIResource { playbackIds: PlaybackIDsAPI.PlaybackIDs = new PlaybackIDsAPI.PlaybackIDs(this._client); playbackRestrictions: PlaybackRestrictionsAPI.PlaybackRestrictions = new PlaybackRestrictionsAPI.PlaybackRestrictions(this._client); - spaces: SpacesAPI.Spaces = new SpacesAPI.Spaces(this._client); transcriptionVocabularies: TranscriptionVocabulariesAPI.TranscriptionVocabularies = new TranscriptionVocabulariesAPI.TranscriptionVocabularies(this._client); uploads: UploadsAPI.Uploads = new UploadsAPI.Uploads(this._client); @@ -29,90 +113,117 @@ export class Video extends APIResource { ); } -export namespace Video { - export import Assets = AssetsAPI.Assets; - export import Asset = AssetsAPI.Asset; - export import AssetOptions = AssetsAPI.AssetOptions; - export import AssetResponse = AssetsAPI.AssetResponse; - export import InputInfo = AssetsAPI.InputInfo; - export import Track = AssetsAPI.Track; - export import AssetGenerateSubtitlesResponse = AssetsAPI.AssetGenerateSubtitlesResponse; - export import AssetRetrieveInputInfoResponse = AssetsAPI.AssetRetrieveInputInfoResponse; - export import AssetsBasePage = AssetsAPI.AssetsBasePage; - export import AssetCreateParams = AssetsAPI.AssetCreateParams; - export import AssetUpdateParams = AssetsAPI.AssetUpdateParams; - export import AssetListParams = AssetsAPI.AssetListParams; - export import AssetCreatePlaybackIDParams = AssetsAPI.AssetCreatePlaybackIDParams; - export import AssetCreateTrackParams = AssetsAPI.AssetCreateTrackParams; - export import AssetGenerateSubtitlesParams = AssetsAPI.AssetGenerateSubtitlesParams; - export import AssetUpdateMasterAccessParams = AssetsAPI.AssetUpdateMasterAccessParams; - export import AssetUpdateMP4SupportParams = AssetsAPI.AssetUpdateMP4SupportParams; - export import DeliveryUsage = DeliveryUsageAPI.DeliveryUsage; - export import DeliveryReport = DeliveryUsageAPI.DeliveryReport; - export import DeliveryReportsPageWithTotal = DeliveryUsageAPI.DeliveryReportsPageWithTotal; - export import DeliveryUsageListParams = DeliveryUsageAPI.DeliveryUsageListParams; - export import LiveStreams = LiveStreamsAPI.LiveStreams; - export import LiveStream = LiveStreamsAPI.LiveStream; - export import SimulcastTarget = LiveStreamsAPI.SimulcastTarget; - export import LiveStreamsBasePage = LiveStreamsAPI.LiveStreamsBasePage; - export import LiveStreamCreateParams = LiveStreamsAPI.LiveStreamCreateParams; - export import LiveStreamUpdateParams = LiveStreamsAPI.LiveStreamUpdateParams; - export import LiveStreamListParams = LiveStreamsAPI.LiveStreamListParams; - export import LiveStreamCreatePlaybackIDParams = LiveStreamsAPI.LiveStreamCreatePlaybackIDParams; - export import LiveStreamCreateSimulcastTargetParams = LiveStreamsAPI.LiveStreamCreateSimulcastTargetParams; - export import LiveStreamUpdateEmbeddedSubtitlesParams = LiveStreamsAPI.LiveStreamUpdateEmbeddedSubtitlesParams; - export import LiveStreamUpdateGeneratedSubtitlesParams = LiveStreamsAPI.LiveStreamUpdateGeneratedSubtitlesParams; - export import PlaybackIDs = PlaybackIDsAPI.PlaybackIDs; - export import PlaybackIDRetrieveResponse = PlaybackIDsAPI.PlaybackIDRetrieveResponse; - export import PlaybackRestrictions = PlaybackRestrictionsAPI.PlaybackRestrictions; - export import PlaybackRestriction = PlaybackRestrictionsAPI.PlaybackRestriction; - export import PlaybackRestrictionResponse = PlaybackRestrictionsAPI.PlaybackRestrictionResponse; - export import PlaybackRestrictionsBasePage = PlaybackRestrictionsAPI.PlaybackRestrictionsBasePage; - export import PlaybackRestrictionCreateParams = PlaybackRestrictionsAPI.PlaybackRestrictionCreateParams; - export import PlaybackRestrictionListParams = PlaybackRestrictionsAPI.PlaybackRestrictionListParams; - export import PlaybackRestrictionUpdateReferrerParams = PlaybackRestrictionsAPI.PlaybackRestrictionUpdateReferrerParams; - export import PlaybackRestrictionUpdateUserAgentParams = PlaybackRestrictionsAPI.PlaybackRestrictionUpdateUserAgentParams; - export import Spaces = SpacesAPI.Spaces; - export import Broadcast = SpacesAPI.Broadcast; - export import BroadcastLayout = SpacesAPI.BroadcastLayout; - export import BroadcastResolution = SpacesAPI.BroadcastResolution; - export import BroadcastResponse = SpacesAPI.BroadcastResponse; - export import BroadcastStatus = SpacesAPI.BroadcastStatus; - export import Space = SpacesAPI.Space; - export import SpaceResponse = SpacesAPI.SpaceResponse; - export import SpaceStatus = SpacesAPI.SpaceStatus; - export import SpaceType = SpacesAPI.SpaceType; - export import SpacesBasePage = SpacesAPI.SpacesBasePage; - export import SpaceCreateParams = SpacesAPI.SpaceCreateParams; - export import SpaceListParams = SpacesAPI.SpaceListParams; - export import SpaceCreateBroadcastParams = SpacesAPI.SpaceCreateBroadcastParams; - export import TranscriptionVocabularies = TranscriptionVocabulariesAPI.TranscriptionVocabularies; - export import TranscriptionVocabulary = TranscriptionVocabulariesAPI.TranscriptionVocabulary; - export import TranscriptionVocabularyResponse = TranscriptionVocabulariesAPI.TranscriptionVocabularyResponse; - export import TranscriptionVocabulariesBasePage = TranscriptionVocabulariesAPI.TranscriptionVocabulariesBasePage; - export import TranscriptionVocabularyCreateParams = TranscriptionVocabulariesAPI.TranscriptionVocabularyCreateParams; - export import TranscriptionVocabularyUpdateParams = TranscriptionVocabulariesAPI.TranscriptionVocabularyUpdateParams; - export import TranscriptionVocabularyListParams = TranscriptionVocabulariesAPI.TranscriptionVocabularyListParams; - export import Uploads = UploadsAPI.Uploads; - export import Upload = UploadsAPI.Upload; - export import UploadResponse = UploadsAPI.UploadResponse; - export import UploadsBasePage = UploadsAPI.UploadsBasePage; - export import UploadCreateParams = UploadsAPI.UploadCreateParams; - export import UploadListParams = UploadsAPI.UploadListParams; - export import WebInputs = WebInputsAPI.WebInputs; - export import WebInputCreateResponse = WebInputsAPI.WebInputCreateResponse; - export import WebInputRetrieveResponse = WebInputsAPI.WebInputRetrieveResponse; - export import WebInputListResponse = WebInputsAPI.WebInputListResponse; - export import WebInputLaunchResponse = WebInputsAPI.WebInputLaunchResponse; - export import WebInputReloadResponse = WebInputsAPI.WebInputReloadResponse; - export import WebInputShutdownResponse = WebInputsAPI.WebInputShutdownResponse; - export import WebInputUpdateURLResponse = WebInputsAPI.WebInputUpdateURLResponse; - export import WebInputListResponsesBasePage = WebInputsAPI.WebInputListResponsesBasePage; - export import WebInputCreateParams = WebInputsAPI.WebInputCreateParams; - export import WebInputListParams = WebInputsAPI.WebInputListParams; - export import WebInputUpdateURLParams = WebInputsAPI.WebInputUpdateURLParams; - export import DRMConfigurations = DRMConfigurationsAPI.DRMConfigurations; - export import DRMConfiguration = DRMConfigurationsAPI.DRMConfiguration; - export import DRMConfigurationsBasePage = DRMConfigurationsAPI.DRMConfigurationsBasePage; - export import DRMConfigurationListParams = DRMConfigurationsAPI.DRMConfigurationListParams; +Video.Assets = Assets; +Video.AssetsBasePage = AssetsBasePage; +Video.DeliveryUsage = DeliveryUsage; +Video.DeliveryReportsPageWithTotal = DeliveryReportsPageWithTotal; +Video.LiveStreams = LiveStreams; +Video.LiveStreamsBasePage = LiveStreamsBasePage; +Video.PlaybackIDs = PlaybackIDs; +Video.PlaybackRestrictions = PlaybackRestrictions; +Video.PlaybackRestrictionsBasePage = PlaybackRestrictionsBasePage; +Video.TranscriptionVocabularies = TranscriptionVocabularies; +Video.TranscriptionVocabulariesBasePage = TranscriptionVocabulariesBasePage; +Video.Uploads = Uploads; +Video.UploadsBasePage = UploadsBasePage; +Video.WebInputs = WebInputs; +Video.WebInputListResponsesBasePage = WebInputListResponsesBasePage; +Video.DRMConfigurations = DRMConfigurations; +Video.DRMConfigurationsBasePage = DRMConfigurationsBasePage; + +export declare namespace Video { + export { + Assets as Assets, + type Asset as Asset, + type AssetOptions as AssetOptions, + type AssetResponse as AssetResponse, + type InputInfo as InputInfo, + type Track as Track, + type AssetGenerateSubtitlesResponse as AssetGenerateSubtitlesResponse, + type AssetRetrieveInputInfoResponse as AssetRetrieveInputInfoResponse, + AssetsBasePage as AssetsBasePage, + type AssetCreateParams as AssetCreateParams, + type AssetUpdateParams as AssetUpdateParams, + type AssetListParams as AssetListParams, + type AssetCreatePlaybackIDParams as AssetCreatePlaybackIDParams, + type AssetCreateTrackParams as AssetCreateTrackParams, + type AssetGenerateSubtitlesParams as AssetGenerateSubtitlesParams, + type AssetUpdateMasterAccessParams as AssetUpdateMasterAccessParams, + type AssetUpdateMP4SupportParams as AssetUpdateMP4SupportParams, + }; + + export { + DeliveryUsage as DeliveryUsage, + type DeliveryReport as DeliveryReport, + DeliveryReportsPageWithTotal as DeliveryReportsPageWithTotal, + type DeliveryUsageListParams as DeliveryUsageListParams, + }; + + export { + LiveStreams as LiveStreams, + type LiveStream as LiveStream, + type SimulcastTarget as SimulcastTarget, + LiveStreamsBasePage as LiveStreamsBasePage, + type LiveStreamCreateParams as LiveStreamCreateParams, + type LiveStreamUpdateParams as LiveStreamUpdateParams, + type LiveStreamListParams as LiveStreamListParams, + type LiveStreamCreatePlaybackIDParams as LiveStreamCreatePlaybackIDParams, + type LiveStreamCreateSimulcastTargetParams as LiveStreamCreateSimulcastTargetParams, + type LiveStreamUpdateEmbeddedSubtitlesParams as LiveStreamUpdateEmbeddedSubtitlesParams, + type LiveStreamUpdateGeneratedSubtitlesParams as LiveStreamUpdateGeneratedSubtitlesParams, + }; + + export { PlaybackIDs as PlaybackIDs, type PlaybackIDRetrieveResponse as PlaybackIDRetrieveResponse }; + + export { + PlaybackRestrictions as PlaybackRestrictions, + type PlaybackRestriction as PlaybackRestriction, + type PlaybackRestrictionResponse as PlaybackRestrictionResponse, + PlaybackRestrictionsBasePage as PlaybackRestrictionsBasePage, + type PlaybackRestrictionCreateParams as PlaybackRestrictionCreateParams, + type PlaybackRestrictionListParams as PlaybackRestrictionListParams, + type PlaybackRestrictionUpdateReferrerParams as PlaybackRestrictionUpdateReferrerParams, + type PlaybackRestrictionUpdateUserAgentParams as PlaybackRestrictionUpdateUserAgentParams, + }; + + export { + TranscriptionVocabularies as TranscriptionVocabularies, + type TranscriptionVocabulary as TranscriptionVocabulary, + type TranscriptionVocabularyResponse as TranscriptionVocabularyResponse, + TranscriptionVocabulariesBasePage as TranscriptionVocabulariesBasePage, + type TranscriptionVocabularyCreateParams as TranscriptionVocabularyCreateParams, + type TranscriptionVocabularyUpdateParams as TranscriptionVocabularyUpdateParams, + type TranscriptionVocabularyListParams as TranscriptionVocabularyListParams, + }; + + export { + Uploads as Uploads, + type Upload as Upload, + type UploadResponse as UploadResponse, + UploadsBasePage as UploadsBasePage, + type UploadCreateParams as UploadCreateParams, + type UploadListParams as UploadListParams, + }; + + export { + WebInputs as WebInputs, + type WebInputCreateResponse as WebInputCreateResponse, + type WebInputRetrieveResponse as WebInputRetrieveResponse, + type WebInputListResponse as WebInputListResponse, + type WebInputLaunchResponse as WebInputLaunchResponse, + type WebInputReloadResponse as WebInputReloadResponse, + type WebInputShutdownResponse as WebInputShutdownResponse, + type WebInputUpdateURLResponse as WebInputUpdateURLResponse, + WebInputListResponsesBasePage as WebInputListResponsesBasePage, + type WebInputCreateParams as WebInputCreateParams, + type WebInputListParams as WebInputListParams, + type WebInputUpdateURLParams as WebInputUpdateURLParams, + }; + + export { + DRMConfigurations as DRMConfigurations, + type DRMConfiguration as DRMConfiguration, + DRMConfigurationsBasePage as DRMConfigurationsBasePage, + type DRMConfigurationListParams as DRMConfigurationListParams, + }; } diff --git a/src/resources/video/web-inputs.ts b/src/resources/video/web-inputs.ts index eaed386c..a56ec7cb 100644 --- a/src/resources/video/web-inputs.ts +++ b/src/resources/video/web-inputs.ts @@ -1,10 +1,9 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import * as Core from '@mux/mux-node/core'; -import { APIResource } from '@mux/mux-node/resource'; -import { isRequestOptions } from '@mux/mux-node/core'; -import * as WebInputsAPI from '@mux/mux-node/resources/video/web-inputs'; -import { BasePage, type BasePageParams } from '@mux/mux-node/pagination'; +import { APIResource } from '../../resource'; +import { isRequestOptions } from '../../core'; +import * as Core from '../../core'; +import { BasePage, type BasePageParams } from '../../pagination'; export class WebInputs extends APIResource { /** @@ -383,16 +382,20 @@ export interface WebInputUpdateURLParams { url: string; } -export namespace WebInputs { - export import WebInputCreateResponse = WebInputsAPI.WebInputCreateResponse; - export import WebInputRetrieveResponse = WebInputsAPI.WebInputRetrieveResponse; - export import WebInputListResponse = WebInputsAPI.WebInputListResponse; - export import WebInputLaunchResponse = WebInputsAPI.WebInputLaunchResponse; - export import WebInputReloadResponse = WebInputsAPI.WebInputReloadResponse; - export import WebInputShutdownResponse = WebInputsAPI.WebInputShutdownResponse; - export import WebInputUpdateURLResponse = WebInputsAPI.WebInputUpdateURLResponse; - export import WebInputListResponsesBasePage = WebInputsAPI.WebInputListResponsesBasePage; - export import WebInputCreateParams = WebInputsAPI.WebInputCreateParams; - export import WebInputListParams = WebInputsAPI.WebInputListParams; - export import WebInputUpdateURLParams = WebInputsAPI.WebInputUpdateURLParams; +WebInputs.WebInputListResponsesBasePage = WebInputListResponsesBasePage; + +export declare namespace WebInputs { + export { + type WebInputCreateResponse as WebInputCreateResponse, + type WebInputRetrieveResponse as WebInputRetrieveResponse, + type WebInputListResponse as WebInputListResponse, + type WebInputLaunchResponse as WebInputLaunchResponse, + type WebInputReloadResponse as WebInputReloadResponse, + type WebInputShutdownResponse as WebInputShutdownResponse, + type WebInputUpdateURLResponse as WebInputUpdateURLResponse, + WebInputListResponsesBasePage as WebInputListResponsesBasePage, + type WebInputCreateParams as WebInputCreateParams, + type WebInputListParams as WebInputListParams, + type WebInputUpdateURLParams as WebInputUpdateURLParams, + }; } diff --git a/src/resources/webhooks.ts b/src/resources/webhooks.ts index 3b0b0c56..c8272a26 100644 --- a/src/resources/webhooks.ts +++ b/src/resources/webhooks.ts @@ -1,13 +1,11 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '@mux/mux-node/resource'; +import { APIResource } from '../resource'; import crypto from 'crypto'; import { getRequiredHeader, HeadersLike } from '@mux/mux-node/core'; -import * as WebhooksAPI from '@mux/mux-node/resources/webhooks'; -import * as AssetsAPI from '@mux/mux-node/resources/video/assets'; -import * as LiveStreamsAPI from '@mux/mux-node/resources/video/live-streams'; -import * as SpacesAPI from '@mux/mux-node/resources/video/spaces'; -import * as UploadsAPI from '@mux/mux-node/resources/video/uploads'; +import * as AssetsAPI from './video/assets'; +import * as LiveStreamsAPI from './video/live-streams'; +import * as UploadsAPI from './video/uploads'; export class Webhooks extends APIResource { /** @@ -511,60 +509,6 @@ export interface VideoLiveStreamSimulcastTargetUpdatedWebhookEvent extends BaseW type: 'video.live_stream.simulcast_target.updated'; } -export interface VideoSpaceCreatedWebhookEvent extends BaseWebhookEvent { - data: SpacesAPI.Space; - - type: 'video.space.created'; -} - -export interface VideoSpaceDeletedWebhookEvent extends BaseWebhookEvent { - data: SpacesAPI.Space; - - type: 'video.space.deleted'; -} - -export interface VideoSpaceActiveWebhookEvent extends BaseWebhookEvent { - data: SpacesAPI.Space; - - type: 'video.space.active'; -} - -export interface VideoSpaceIdleWebhookEvent extends BaseWebhookEvent { - data: SpacesAPI.Space; - - type: 'video.space.idle'; -} - -export interface VideoSpaceUpdatedWebhookEvent extends BaseWebhookEvent { - data: SpacesAPI.Space; - - type: 'video.space.updated'; -} - -export interface VideoSpaceBroadcastCreatedWebhookEvent extends BaseWebhookEvent { - data: SpacesAPI.Broadcast; - - type: 'video.space.broadcast.created'; -} - -export interface VideoSpaceBroadcastIdleWebhookEvent extends BaseWebhookEvent { - data: SpacesAPI.Broadcast; - - type: 'video.space.broadcast.idle'; -} - -export interface VideoSpaceBroadcastActiveWebhookEvent extends BaseWebhookEvent { - data: SpacesAPI.Broadcast; - - type: 'video.space.broadcast.active'; -} - -export interface VideoSpaceBroadcastDeletedWebhookEvent extends BaseWebhookEvent { - data: SpacesAPI.Broadcast; - - type: 'video.space.broadcast.deleted'; -} - export interface VideoDeliveryHighTrafficWebhookEvent extends BaseWebhookEvent { data: VideoDeliveryHighTrafficWebhookEvent.Data; @@ -592,6 +536,13 @@ export namespace VideoDeliveryHighTrafficWebhookEvent { */ asset_duration?: number; + /** + * @deprecated: This field is deprecated. Please use `asset_video_quality` instead. + * The encoding tier that the asset was ingested at. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) + */ + asset_encoding_tier?: 'smart' | 'baseline' | 'premium'; + /** * Unique identifier for the asset. */ @@ -608,6 +559,13 @@ export namespace VideoDeliveryHighTrafficWebhookEvent { */ asset_state?: 'ready' | 'errored' | 'deleted'; + /** + * The video quality that the asset was ingested at. This field replaces + * `asset_encoding_tier`. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) + */ + asset_video_quality?: 'basic' | 'plus' | 'premium'; + /** * Time at which the asset was created. Measured in seconds since the Unix epoch. */ @@ -725,69 +683,4 @@ export type UnwrapWebhookEvent = | VideoLiveStreamSimulcastTargetErroredWebhookEvent | VideoLiveStreamSimulcastTargetDeletedWebhookEvent | VideoLiveStreamSimulcastTargetUpdatedWebhookEvent - | VideoSpaceCreatedWebhookEvent - | VideoSpaceDeletedWebhookEvent - | VideoSpaceActiveWebhookEvent - | VideoSpaceIdleWebhookEvent - | VideoSpaceUpdatedWebhookEvent - | VideoSpaceBroadcastCreatedWebhookEvent - | VideoSpaceBroadcastIdleWebhookEvent - | VideoSpaceBroadcastActiveWebhookEvent - | VideoSpaceBroadcastDeletedWebhookEvent | VideoDeliveryHighTrafficWebhookEvent; - -export namespace Webhooks { - export import BaseWebhookEvent = WebhooksAPI.BaseWebhookEvent; - export import VideoAssetCreatedWebhookEvent = WebhooksAPI.VideoAssetCreatedWebhookEvent; - export import VideoAssetReadyWebhookEvent = WebhooksAPI.VideoAssetReadyWebhookEvent; - export import VideoAssetErroredWebhookEvent = WebhooksAPI.VideoAssetErroredWebhookEvent; - export import VideoAssetUpdatedWebhookEvent = WebhooksAPI.VideoAssetUpdatedWebhookEvent; - export import VideoAssetDeletedWebhookEvent = WebhooksAPI.VideoAssetDeletedWebhookEvent; - export import VideoAssetLiveStreamCompletedWebhookEvent = WebhooksAPI.VideoAssetLiveStreamCompletedWebhookEvent; - export import VideoAssetStaticRenditionsReadyWebhookEvent = WebhooksAPI.VideoAssetStaticRenditionsReadyWebhookEvent; - export import VideoAssetStaticRenditionsPreparingWebhookEvent = WebhooksAPI.VideoAssetStaticRenditionsPreparingWebhookEvent; - export import VideoAssetStaticRenditionsDeletedWebhookEvent = WebhooksAPI.VideoAssetStaticRenditionsDeletedWebhookEvent; - export import VideoAssetStaticRenditionsErroredWebhookEvent = WebhooksAPI.VideoAssetStaticRenditionsErroredWebhookEvent; - export import VideoAssetMasterReadyWebhookEvent = WebhooksAPI.VideoAssetMasterReadyWebhookEvent; - export import VideoAssetMasterPreparingWebhookEvent = WebhooksAPI.VideoAssetMasterPreparingWebhookEvent; - export import VideoAssetMasterDeletedWebhookEvent = WebhooksAPI.VideoAssetMasterDeletedWebhookEvent; - export import VideoAssetMasterErroredWebhookEvent = WebhooksAPI.VideoAssetMasterErroredWebhookEvent; - export import VideoAssetTrackCreatedWebhookEvent = WebhooksAPI.VideoAssetTrackCreatedWebhookEvent; - export import VideoAssetTrackReadyWebhookEvent = WebhooksAPI.VideoAssetTrackReadyWebhookEvent; - export import VideoAssetTrackErroredWebhookEvent = WebhooksAPI.VideoAssetTrackErroredWebhookEvent; - export import VideoAssetTrackDeletedWebhookEvent = WebhooksAPI.VideoAssetTrackDeletedWebhookEvent; - export import VideoAssetWarningWebhookEvent = WebhooksAPI.VideoAssetWarningWebhookEvent; - export import VideoUploadAssetCreatedWebhookEvent = WebhooksAPI.VideoUploadAssetCreatedWebhookEvent; - export import VideoUploadCancelledWebhookEvent = WebhooksAPI.VideoUploadCancelledWebhookEvent; - export import VideoUploadCreatedWebhookEvent = WebhooksAPI.VideoUploadCreatedWebhookEvent; - export import VideoUploadErroredWebhookEvent = WebhooksAPI.VideoUploadErroredWebhookEvent; - export import VideoLiveStreamCreatedWebhookEvent = WebhooksAPI.VideoLiveStreamCreatedWebhookEvent; - export import VideoLiveStreamConnectedWebhookEvent = WebhooksAPI.VideoLiveStreamConnectedWebhookEvent; - export import VideoLiveStreamRecordingWebhookEvent = WebhooksAPI.VideoLiveStreamRecordingWebhookEvent; - export import VideoLiveStreamActiveWebhookEvent = WebhooksAPI.VideoLiveStreamActiveWebhookEvent; - export import VideoLiveStreamDisconnectedWebhookEvent = WebhooksAPI.VideoLiveStreamDisconnectedWebhookEvent; - export import VideoLiveStreamIdleWebhookEvent = WebhooksAPI.VideoLiveStreamIdleWebhookEvent; - export import VideoLiveStreamUpdatedWebhookEvent = WebhooksAPI.VideoLiveStreamUpdatedWebhookEvent; - export import VideoLiveStreamEnabledWebhookEvent = WebhooksAPI.VideoLiveStreamEnabledWebhookEvent; - export import VideoLiveStreamDisabledWebhookEvent = WebhooksAPI.VideoLiveStreamDisabledWebhookEvent; - export import VideoLiveStreamDeletedWebhookEvent = WebhooksAPI.VideoLiveStreamDeletedWebhookEvent; - export import VideoLiveStreamWarningWebhookEvent = WebhooksAPI.VideoLiveStreamWarningWebhookEvent; - export import VideoLiveStreamSimulcastTargetCreatedWebhookEvent = WebhooksAPI.VideoLiveStreamSimulcastTargetCreatedWebhookEvent; - export import VideoLiveStreamSimulcastTargetIdleWebhookEvent = WebhooksAPI.VideoLiveStreamSimulcastTargetIdleWebhookEvent; - export import VideoLiveStreamSimulcastTargetStartingWebhookEvent = WebhooksAPI.VideoLiveStreamSimulcastTargetStartingWebhookEvent; - export import VideoLiveStreamSimulcastTargetBroadcastingWebhookEvent = WebhooksAPI.VideoLiveStreamSimulcastTargetBroadcastingWebhookEvent; - export import VideoLiveStreamSimulcastTargetErroredWebhookEvent = WebhooksAPI.VideoLiveStreamSimulcastTargetErroredWebhookEvent; - export import VideoLiveStreamSimulcastTargetDeletedWebhookEvent = WebhooksAPI.VideoLiveStreamSimulcastTargetDeletedWebhookEvent; - export import VideoLiveStreamSimulcastTargetUpdatedWebhookEvent = WebhooksAPI.VideoLiveStreamSimulcastTargetUpdatedWebhookEvent; - export import VideoSpaceCreatedWebhookEvent = WebhooksAPI.VideoSpaceCreatedWebhookEvent; - export import VideoSpaceDeletedWebhookEvent = WebhooksAPI.VideoSpaceDeletedWebhookEvent; - export import VideoSpaceActiveWebhookEvent = WebhooksAPI.VideoSpaceActiveWebhookEvent; - export import VideoSpaceIdleWebhookEvent = WebhooksAPI.VideoSpaceIdleWebhookEvent; - export import VideoSpaceUpdatedWebhookEvent = WebhooksAPI.VideoSpaceUpdatedWebhookEvent; - export import VideoSpaceBroadcastCreatedWebhookEvent = WebhooksAPI.VideoSpaceBroadcastCreatedWebhookEvent; - export import VideoSpaceBroadcastIdleWebhookEvent = WebhooksAPI.VideoSpaceBroadcastIdleWebhookEvent; - export import VideoSpaceBroadcastActiveWebhookEvent = WebhooksAPI.VideoSpaceBroadcastActiveWebhookEvent; - export import VideoSpaceBroadcastDeletedWebhookEvent = WebhooksAPI.VideoSpaceBroadcastDeletedWebhookEvent; - export import VideoDeliveryHighTrafficWebhookEvent = WebhooksAPI.VideoDeliveryHighTrafficWebhookEvent; - export import UnwrapWebhookEvent = WebhooksAPI.UnwrapWebhookEvent; -} diff --git a/src/uploads.ts b/src/uploads.ts index 081827c9..8fd2154d 100644 --- a/src/uploads.ts +++ b/src/uploads.ts @@ -107,21 +107,28 @@ export async function toFile( // If it's a promise, resolve it. value = await value; - // Use the file's options if there isn't one provided - options ??= isFileLike(value) ? { lastModified: value.lastModified, type: value.type } : {}; + // If we've been given a `File` we don't need to do anything + if (isFileLike(value)) { + return value; + } if (isResponseLike(value)) { const blob = await value.blob(); name ||= new URL(value.url).pathname.split(/[\\/]/).pop() ?? 'unknown_file'; - return new File([blob as any], name, options); + // we need to convert the `Blob` into an array buffer because the `Blob` class + // that `node-fetch` defines is incompatible with the web standard which results + // in `new File` interpreting it as a string instead of binary data. + const data = isBlobLike(blob) ? [(await blob.arrayBuffer()) as any] : [blob]; + + return new File(data, name, options); } const bits = await getBytes(value); name ||= getName(value) ?? 'unknown_file'; - if (!options.type) { + if (!options?.type) { const type = (bits[0] as any)?.type; if (typeof type === 'string') { options = { ...options, type }; diff --git a/src/util/jwt-types.ts b/src/util/jwt-types.ts index b3a6afe7..5a6915ea 100644 --- a/src/util/jwt-types.ts +++ b/src/util/jwt-types.ts @@ -34,15 +34,6 @@ export interface JwtHeader { x5c?: string | string[] | undefined; } -export interface MuxJWTSignOptions { - keyId?: string; - keySecret?: string | PrivateKey; - keyFilePath?: string; - type?: Type; - expiration?: string; - params?: Record; -} - export enum TypeClaim { video = 'v', thumbnail = 't', @@ -51,6 +42,36 @@ export enum TypeClaim { stats = 'playback_id', drm_license = 'd', } +export enum TypeToken { + video = 'playback-token', + thumbnail = 'thumbnail-token', + storyboard = 'storyboard-token', + drm_license = 'drm-token', + gif = 'gif-token', // Not supported by Mux Player + stats = 'stats-token', // Not supported by Mux Player +} +export type TypeTokenValues = (typeof TypeToken)[keyof typeof TypeToken]; +export type Tokens = Partial>; +// ['thumbnail', { time: 2 }] +export type TypeWithParams = [Type, MuxJWTSignOptions['params']]; + +interface MuxJWTSignOptionsBase { + keyId?: string; + keySecret?: string | PrivateKey; + keyFilePath?: string; + type?: Type | Array>; + expiration?: string; + params?: Record; +} +export interface MuxJWTSignOptions extends MuxJWTSignOptionsBase { + type?: Type; +} +export interface MuxJWTSignOptionsMultiple extends MuxJWTSignOptionsBase { + type: Array>; +} +export const isMuxJWTSignOptionsMultiple = ( + config: MuxJWTSignOptions | MuxJWTSignOptionsMultiple, +): config is MuxJWTSignOptionsMultiple => Array.isArray(config.type); export enum DataTypeClaim { video = 'video_id', diff --git a/src/version.ts b/src/version.ts index 1eaae8e0..b0a42860 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '8.8.0'; // x-release-please-version +export const VERSION = '9.0.0'; // x-release-please-version diff --git a/tests/api-resources/data/dimensions.test.ts b/tests/api-resources/data/dimensions.test.ts index a9ac1943..1fb76b31 100644 --- a/tests/api-resources/data/dimensions.test.ts +++ b/tests/api-resources/data/dimensions.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource dimensions', () => { test('list', async () => { - const responsePromise = mux.data.dimensions.list(); + const responsePromise = client.data.dimensions.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,13 +23,13 @@ describe('resource dimensions', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.dimensions.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.dimensions.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); test('listValues', async () => { - const responsePromise = mux.data.dimensions.listValues('abcd1234'); + const responsePromise = client.data.dimensions.listValues('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -42,14 +42,14 @@ describe('resource dimensions', () => { test('listValues: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.dimensions.listValues('abcd1234', { path: '/_stainless_unknown_path' }), + client.data.dimensions.listValues('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('listValues: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.dimensions.listValues( + client.data.dimensions.listValues( 'abcd1234', { filters: ['string', 'string', 'string'], diff --git a/tests/api-resources/data/errors.test.ts b/tests/api-resources/data/errors.test.ts index 5ac15119..e58581f0 100644 --- a/tests/api-resources/data/errors.test.ts +++ b/tests/api-resources/data/errors.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource errors', () => { test('list', async () => { - const responsePromise = mux.data.errors.list(); + const responsePromise = client.data.errors.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,7 +23,7 @@ describe('resource errors', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.errors.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.errors.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -31,7 +31,7 @@ describe('resource errors', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.errors.list( + client.data.errors.list( { filters: ['string', 'string', 'string'], metric_filters: ['string', 'string', 'string'], diff --git a/tests/api-resources/data/exports.test.ts b/tests/api-resources/data/exports.test.ts index 17aec44e..254c503b 100644 --- a/tests/api-resources/data/exports.test.ts +++ b/tests/api-resources/data/exports.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource exports', () => { test('listVideoViews', async () => { - const responsePromise = mux.data.exports.listVideoViews(); + const responsePromise = client.data.exports.listVideoViews(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,7 +23,7 @@ describe('resource exports', () => { test('listVideoViews: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.exports.listVideoViews({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.exports.listVideoViews({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); diff --git a/tests/api-resources/data/filters.test.ts b/tests/api-resources/data/filters.test.ts index 6bc418bb..7acb4cf1 100644 --- a/tests/api-resources/data/filters.test.ts +++ b/tests/api-resources/data/filters.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource filters', () => { test('listValues', async () => { - const responsePromise = mux.data.filters.listValues('abcd1234'); + const responsePromise = client.data.filters.listValues('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -24,14 +24,14 @@ describe('resource filters', () => { test('listValues: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.filters.listValues('abcd1234', { path: '/_stainless_unknown_path' }), + client.data.filters.listValues('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('listValues: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.filters.listValues( + client.data.filters.listValues( 'abcd1234', { filters: ['string', 'string', 'string'], diff --git a/tests/api-resources/data/incidents.test.ts b/tests/api-resources/data/incidents.test.ts index 71add2d9..539b86fc 100644 --- a/tests/api-resources/data/incidents.test.ts +++ b/tests/api-resources/data/incidents.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource incidents', () => { test('retrieve', async () => { - const responsePromise = mux.data.incidents.retrieve('abcd1234'); + const responsePromise = client.data.incidents.retrieve('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -24,12 +24,12 @@ describe('resource incidents', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.incidents.retrieve('abcd1234', { path: '/_stainless_unknown_path' }), + client.data.incidents.retrieve('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('list', async () => { - const responsePromise = mux.data.incidents.list(); + const responsePromise = client.data.incidents.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -41,7 +41,7 @@ describe('resource incidents', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.incidents.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.incidents.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -49,7 +49,7 @@ describe('resource incidents', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.incidents.list( + client.data.incidents.list( { limit: 0, order_by: 'negative_impact', @@ -64,7 +64,7 @@ describe('resource incidents', () => { }); test('listRelated', async () => { - const responsePromise = mux.data.incidents.listRelated('abcd1234'); + const responsePromise = client.data.incidents.listRelated('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -77,14 +77,14 @@ describe('resource incidents', () => { test('listRelated: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.incidents.listRelated('abcd1234', { path: '/_stainless_unknown_path' }), + client.data.incidents.listRelated('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('listRelated: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.incidents.listRelated( + client.data.incidents.listRelated( 'abcd1234', { limit: 0, order_by: 'negative_impact', order_direction: 'asc', page: 0 }, { path: '/_stainless_unknown_path' }, diff --git a/tests/api-resources/data/metrics.test.ts b/tests/api-resources/data/metrics.test.ts index fe4bc2d3..b1b16b97 100644 --- a/tests/api-resources/data/metrics.test.ts +++ b/tests/api-resources/data/metrics.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource metrics', () => { test('list', async () => { - const responsePromise = mux.data.metrics.list(); + const responsePromise = client.data.metrics.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,7 +23,7 @@ describe('resource metrics', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.metrics.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.metrics.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -31,13 +31,13 @@ describe('resource metrics', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.metrics.list( + client.data.metrics.list( { dimension: 'asn', filters: ['string', 'string', 'string'], metric_filters: ['string', 'string', 'string'], timeframe: ['string', 'string', 'string'], - value: 'string', + value: 'value', }, { path: '/_stainless_unknown_path' }, ), @@ -45,7 +45,7 @@ describe('resource metrics', () => { }); test('getInsights', async () => { - const responsePromise = mux.data.metrics.getInsights('video_startup_time'); + const responsePromise = client.data.metrics.getInsights('aggregate_startup_time'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -58,15 +58,15 @@ describe('resource metrics', () => { test('getInsights: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.metrics.getInsights('video_startup_time', { path: '/_stainless_unknown_path' }), + client.data.metrics.getInsights('aggregate_startup_time', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('getInsights: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.metrics.getInsights( - 'video_startup_time', + client.data.metrics.getInsights( + 'aggregate_startup_time', { filters: ['string', 'string', 'string'], measurement: '95th', @@ -80,7 +80,7 @@ describe('resource metrics', () => { }); test('getOverallValues', async () => { - const responsePromise = mux.data.metrics.getOverallValues('video_startup_time'); + const responsePromise = client.data.metrics.getOverallValues('aggregate_startup_time'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -93,15 +93,15 @@ describe('resource metrics', () => { test('getOverallValues: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.metrics.getOverallValues('video_startup_time', { path: '/_stainless_unknown_path' }), + client.data.metrics.getOverallValues('aggregate_startup_time', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('getOverallValues: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.metrics.getOverallValues( - 'video_startup_time', + client.data.metrics.getOverallValues( + 'aggregate_startup_time', { filters: ['string', 'string', 'string'], measurement: '95th', @@ -114,7 +114,7 @@ describe('resource metrics', () => { }); test('getTimeseries', async () => { - const responsePromise = mux.data.metrics.getTimeseries('video_startup_time'); + const responsePromise = client.data.metrics.getTimeseries('aggregate_startup_time'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -127,15 +127,15 @@ describe('resource metrics', () => { test('getTimeseries: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.metrics.getTimeseries('video_startup_time', { path: '/_stainless_unknown_path' }), + client.data.metrics.getTimeseries('aggregate_startup_time', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('getTimeseries: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.metrics.getTimeseries( - 'video_startup_time', + client.data.metrics.getTimeseries( + 'aggregate_startup_time', { filters: ['string', 'string', 'string'], group_by: 'minute', @@ -150,7 +150,7 @@ describe('resource metrics', () => { }); test('listBreakdownValues', async () => { - const responsePromise = mux.data.metrics.listBreakdownValues('video_startup_time'); + const responsePromise = client.data.metrics.listBreakdownValues('aggregate_startup_time'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -163,15 +163,15 @@ describe('resource metrics', () => { test('listBreakdownValues: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.metrics.listBreakdownValues('video_startup_time', { path: '/_stainless_unknown_path' }), + client.data.metrics.listBreakdownValues('aggregate_startup_time', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('listBreakdownValues: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.metrics.listBreakdownValues( - 'video_startup_time', + client.data.metrics.listBreakdownValues( + 'aggregate_startup_time', { filters: ['string', 'string', 'string'], group_by: 'asn', diff --git a/tests/api-resources/data/monitoring/metrics.test.ts b/tests/api-resources/data/monitoring/metrics.test.ts index 98096289..cd195ac4 100644 --- a/tests/api-resources/data/monitoring/metrics.test.ts +++ b/tests/api-resources/data/monitoring/metrics.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource metrics', () => { test('list', async () => { - const responsePromise = mux.data.monitoring.metrics.list(); + const responsePromise = client.data.monitoring.metrics.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,13 +23,13 @@ describe('resource metrics', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.monitoring.metrics.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.monitoring.metrics.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); test('getBreakdown', async () => { - const responsePromise = mux.data.monitoring.metrics.getBreakdown('current-concurrent-viewers'); + const responsePromise = client.data.monitoring.metrics.getBreakdown('current-concurrent-viewers'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -42,7 +42,7 @@ describe('resource metrics', () => { test('getBreakdown: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.monitoring.metrics.getBreakdown('current-concurrent-viewers', { + client.data.monitoring.metrics.getBreakdown('current-concurrent-viewers', { path: '/_stainless_unknown_path', }), ).rejects.toThrow(Mux.NotFoundError); @@ -51,7 +51,7 @@ describe('resource metrics', () => { test('getBreakdown: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.monitoring.metrics.getBreakdown( + client.data.monitoring.metrics.getBreakdown( 'current-concurrent-viewers', { dimension: 'asn', @@ -66,7 +66,9 @@ describe('resource metrics', () => { }); test('getBreakdownTimeseries', async () => { - const responsePromise = mux.data.monitoring.metrics.getBreakdownTimeseries('current-concurrent-viewers'); + const responsePromise = client.data.monitoring.metrics.getBreakdownTimeseries( + 'current-concurrent-viewers', + ); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -79,7 +81,7 @@ describe('resource metrics', () => { test('getBreakdownTimeseries: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.monitoring.metrics.getBreakdownTimeseries('current-concurrent-viewers', { + client.data.monitoring.metrics.getBreakdownTimeseries('current-concurrent-viewers', { path: '/_stainless_unknown_path', }), ).rejects.toThrow(Mux.NotFoundError); @@ -88,7 +90,7 @@ describe('resource metrics', () => { test('getBreakdownTimeseries: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.monitoring.metrics.getBreakdownTimeseries( + client.data.monitoring.metrics.getBreakdownTimeseries( 'current-concurrent-viewers', { dimension: 'asn', @@ -104,7 +106,7 @@ describe('resource metrics', () => { }); test('getHistogramTimeseries', async () => { - const responsePromise = mux.data.monitoring.metrics.getHistogramTimeseries('video-startup-time'); + const responsePromise = client.data.monitoring.metrics.getHistogramTimeseries('video-startup-time'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -117,7 +119,7 @@ describe('resource metrics', () => { test('getHistogramTimeseries: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.monitoring.metrics.getHistogramTimeseries('video-startup-time', { + client.data.monitoring.metrics.getHistogramTimeseries('video-startup-time', { path: '/_stainless_unknown_path', }), ).rejects.toThrow(Mux.NotFoundError); @@ -126,7 +128,7 @@ describe('resource metrics', () => { test('getHistogramTimeseries: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.monitoring.metrics.getHistogramTimeseries( + client.data.monitoring.metrics.getHistogramTimeseries( 'video-startup-time', { filters: ['string', 'string', 'string'] }, { path: '/_stainless_unknown_path' }, @@ -135,7 +137,7 @@ describe('resource metrics', () => { }); test('getTimeseries', async () => { - const responsePromise = mux.data.monitoring.metrics.getTimeseries('current-concurrent-viewers'); + const responsePromise = client.data.monitoring.metrics.getTimeseries('current-concurrent-viewers'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -148,7 +150,7 @@ describe('resource metrics', () => { test('getTimeseries: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.monitoring.metrics.getTimeseries('current-concurrent-viewers', { + client.data.monitoring.metrics.getTimeseries('current-concurrent-viewers', { path: '/_stainless_unknown_path', }), ).rejects.toThrow(Mux.NotFoundError); @@ -157,7 +159,7 @@ describe('resource metrics', () => { test('getTimeseries: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.monitoring.metrics.getTimeseries( + client.data.monitoring.metrics.getTimeseries( 'current-concurrent-viewers', { filters: ['string', 'string', 'string'], timestamp: 0 }, { path: '/_stainless_unknown_path' }, diff --git a/tests/api-resources/data/monitoring/monitoring.test.ts b/tests/api-resources/data/monitoring/monitoring.test.ts index b955038d..0f49f648 100644 --- a/tests/api-resources/data/monitoring/monitoring.test.ts +++ b/tests/api-resources/data/monitoring/monitoring.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource monitoring', () => { test('listDimensions', async () => { - const responsePromise = mux.data.monitoring.listDimensions(); + const responsePromise = client.data.monitoring.listDimensions(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,7 +23,7 @@ describe('resource monitoring', () => { test('listDimensions: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.monitoring.listDimensions({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.monitoring.listDimensions({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); diff --git a/tests/api-resources/data/real-time.test.ts b/tests/api-resources/data/real-time.test.ts index be5580e8..1c6a50b7 100644 --- a/tests/api-resources/data/real-time.test.ts +++ b/tests/api-resources/data/real-time.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource realTime', () => { test('listDimensions', async () => { - const responsePromise = mux.data.realTime.listDimensions(); + const responsePromise = client.data.realTime.listDimensions(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,13 +23,13 @@ describe('resource realTime', () => { test('listDimensions: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.realTime.listDimensions({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.realTime.listDimensions({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); test('listMetrics', async () => { - const responsePromise = mux.data.realTime.listMetrics(); + const responsePromise = client.data.realTime.listMetrics(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -41,13 +41,13 @@ describe('resource realTime', () => { test('listMetrics: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.realTime.listMetrics({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.realTime.listMetrics({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); test('retrieveBreakdown', async () => { - const responsePromise = mux.data.realTime.retrieveBreakdown('current-concurrent-viewers'); + const responsePromise = client.data.realTime.retrieveBreakdown('current-concurrent-viewers'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -60,14 +60,16 @@ describe('resource realTime', () => { test('retrieveBreakdown: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.realTime.retrieveBreakdown('current-concurrent-viewers', { path: '/_stainless_unknown_path' }), + client.data.realTime.retrieveBreakdown('current-concurrent-viewers', { + path: '/_stainless_unknown_path', + }), ).rejects.toThrow(Mux.NotFoundError); }); test('retrieveBreakdown: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.realTime.retrieveBreakdown( + client.data.realTime.retrieveBreakdown( 'current-concurrent-viewers', { dimension: 'asn', @@ -82,7 +84,7 @@ describe('resource realTime', () => { }); test('retrieveHistogramTimeseries', async () => { - const responsePromise = mux.data.realTime.retrieveHistogramTimeseries('video-startup-time'); + const responsePromise = client.data.realTime.retrieveHistogramTimeseries('video-startup-time'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -95,7 +97,7 @@ describe('resource realTime', () => { test('retrieveHistogramTimeseries: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.realTime.retrieveHistogramTimeseries('video-startup-time', { + client.data.realTime.retrieveHistogramTimeseries('video-startup-time', { path: '/_stainless_unknown_path', }), ).rejects.toThrow(Mux.NotFoundError); @@ -104,7 +106,7 @@ describe('resource realTime', () => { test('retrieveHistogramTimeseries: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.realTime.retrieveHistogramTimeseries( + client.data.realTime.retrieveHistogramTimeseries( 'video-startup-time', { filters: ['string', 'string', 'string'] }, { path: '/_stainless_unknown_path' }, @@ -113,7 +115,7 @@ describe('resource realTime', () => { }); test('retrieveTimeseries', async () => { - const responsePromise = mux.data.realTime.retrieveTimeseries('current-concurrent-viewers'); + const responsePromise = client.data.realTime.retrieveTimeseries('current-concurrent-viewers'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -126,7 +128,7 @@ describe('resource realTime', () => { test('retrieveTimeseries: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.realTime.retrieveTimeseries('current-concurrent-viewers', { + client.data.realTime.retrieveTimeseries('current-concurrent-viewers', { path: '/_stainless_unknown_path', }), ).rejects.toThrow(Mux.NotFoundError); @@ -135,7 +137,7 @@ describe('resource realTime', () => { test('retrieveTimeseries: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.realTime.retrieveTimeseries( + client.data.realTime.retrieveTimeseries( 'current-concurrent-viewers', { filters: ['string', 'string', 'string'], timestamp: 0 }, { path: '/_stainless_unknown_path' }, diff --git a/tests/api-resources/data/video-views.test.ts b/tests/api-resources/data/video-views.test.ts index d13edef0..ca7707a6 100644 --- a/tests/api-resources/data/video-views.test.ts +++ b/tests/api-resources/data/video-views.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource videoViews', () => { test('retrieve', async () => { - const responsePromise = mux.data.videoViews.retrieve('abcd1234'); + const responsePromise = client.data.videoViews.retrieve('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -24,12 +24,12 @@ describe('resource videoViews', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.videoViews.retrieve('abcd1234', { path: '/_stainless_unknown_path' }), + client.data.videoViews.retrieve('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('list', async () => { - const responsePromise = mux.data.videoViews.list(); + const responsePromise = client.data.videoViews.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -41,7 +41,7 @@ describe('resource videoViews', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.data.videoViews.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.data.videoViews.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -49,7 +49,7 @@ describe('resource videoViews', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.data.videoViews.list( + client.data.videoViews.list( { error_id: 0, filters: ['string', 'string', 'string'], @@ -58,7 +58,7 @@ describe('resource videoViews', () => { order_direction: 'asc', page: 0, timeframe: ['string', 'string', 'string'], - viewer_id: 'string', + viewer_id: 'viewer_id', }, { path: '/_stainless_unknown_path' }, ), diff --git a/tests/api-resources/jwt.test.ts b/tests/api-resources/jwt.test.ts index f35484b6..51d8735e 100644 --- a/tests/api-resources/jwt.test.ts +++ b/tests/api-resources/jwt.test.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. import Mux from '@mux/mux-node'; -import { TypeClaim, DataTypeClaim } from '@mux/mux-node/util/jwt-types'; +import { TypeClaim, DataTypeClaim, TypeToken } from '@mux/mux-node/util/jwt-types'; import { decodeJwt, jwtVerify, importJWK, importPKCS8 } from 'jose'; import { publicJwk, privatePkcs1, privatePkcs8 } from './rsaKeys'; import crypto from 'crypto'; @@ -277,4 +277,75 @@ describe('resource jwt', () => { sub: 'abcdefgh', }); }); + + test('signPlaybackId multiple types returns same tokens as multiple single calls', async () => { + const id = 'abcdefgh'; + const expiration = '1d'; + + const playbackToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'video', + }); + const thumbnailToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'thumbnail', + }); + const storyboardToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'storyboard', + }); + const drmToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'drm_license', + }); + const gifToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'gif', + }); + const statsToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'stats', + }); + + const tokens = await mux.jwt.signPlaybackId(id, { + expiration, + type: ['video', 'thumbnail', 'storyboard', 'drm_license', 'gif', 'stats'], + }); + + expect(tokens[TypeToken.video]).toEqual(playbackToken); + expect(tokens[TypeToken.thumbnail]).toEqual(thumbnailToken); + expect(tokens[TypeToken.storyboard]).toEqual(storyboardToken); + expect(tokens[TypeToken.drm_license]).toEqual(drmToken); + expect(tokens[TypeToken.gif]).toEqual(gifToken); + expect(tokens[TypeToken.stats]).toEqual(statsToken); + }); + + test('signPlaybackId multiple types with params returns same tokens as multiple single calls', async () => { + const id = 'abcdefgh'; + const expiration = '1d'; + + const playbackToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'video', + }); + const thumbnailParams = { time: '2' }; + const thumbnailToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'thumbnail', + params: thumbnailParams, + }); + const storyboardToken = await mux.jwt.signPlaybackId(id, { + expiration, + type: 'storyboard', + }); + + const tokens = await mux.jwt.signPlaybackId(id, { + expiration, + type: ['video', ['thumbnail', thumbnailParams], 'storyboard'], + }); + + expect(tokens[TypeToken.video]).toEqual(playbackToken); + expect(tokens[TypeToken.thumbnail]).toEqual(thumbnailToken); + expect(tokens[TypeToken.storyboard]).toEqual(storyboardToken); + }); }); diff --git a/tests/api-resources/system/signing-keys.test.ts b/tests/api-resources/system/signing-keys.test.ts index 7d557c77..d9acad9e 100644 --- a/tests/api-resources/system/signing-keys.test.ts +++ b/tests/api-resources/system/signing-keys.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource signingKeys', () => { test('create', async () => { - const responsePromise = mux.system.signingKeys.create(); + const responsePromise = client.system.signingKeys.create(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,13 +23,13 @@ describe('resource signingKeys', () => { test('create: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.system.signingKeys.create({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.system.signingKeys.create({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); test('retrieve', async () => { - const responsePromise = mux.system.signingKeys.retrieve('string'); + const responsePromise = client.system.signingKeys.retrieve('SIGNING_KEY_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -42,12 +42,12 @@ describe('resource signingKeys', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.system.signingKeys.retrieve('string', { path: '/_stainless_unknown_path' }), + client.system.signingKeys.retrieve('SIGNING_KEY_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('list', async () => { - const responsePromise = mux.system.signingKeys.list(); + const responsePromise = client.system.signingKeys.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -59,7 +59,7 @@ describe('resource signingKeys', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.system.signingKeys.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.system.signingKeys.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -67,12 +67,12 @@ describe('resource signingKeys', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.system.signingKeys.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), + client.system.signingKeys.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('delete', async () => { - const responsePromise = mux.system.signingKeys.delete('string'); + const responsePromise = client.system.signingKeys.delete('SIGNING_KEY_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -85,7 +85,7 @@ describe('resource signingKeys', () => { test('delete: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.system.signingKeys.delete('string', { path: '/_stainless_unknown_path' }), + client.system.signingKeys.delete('SIGNING_KEY_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); }); diff --git a/tests/api-resources/video/assets.test.ts b/tests/api-resources/video/assets.test.ts index 8757df82..9fee9b2b 100644 --- a/tests/api-resources/video/assets.test.ts +++ b/tests/api-resources/video/assets.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource assets', () => { test('create: only required params', async () => { - const responsePromise = mux.video.assets.create({ input: [{}] }); + const responsePromise = client.video.assets.create({ input: [{}] }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -22,53 +22,54 @@ describe('resource assets', () => { }); test('create: required and optional params', async () => { - const response = await mux.video.assets.create({ + const response = await client.video.assets.create({ input: [ { - url: 'https://muxed.s3.amazonaws.com/leds.mp4', + closed_captions: true, + end_time: 0, + generated_subtitles: [ + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + ], + language_code: 'language_code', + name: 'name', overlay_settings: { - vertical_align: 'top', - vertical_margin: 'string', + height: 'height', horizontal_align: 'left', - horizontal_margin: 'string', - width: 'string', - height: 'string', - opacity: 'string', + horizontal_margin: 'horizontal_margin', + opacity: 'opacity', + vertical_align: 'top', + vertical_margin: 'vertical_margin', + width: 'width', }, - generated_subtitles: [ - { name: 'string', passthrough: 'string', language_code: 'en' }, - { name: 'string', passthrough: 'string', language_code: 'en' }, - { name: 'string', passthrough: 'string', language_code: 'en' }, - ], + passthrough: 'passthrough', start_time: 0, - end_time: 0, - type: 'video', text_type: 'subtitles', - language_code: 'string', - name: 'string', - closed_captions: true, - passthrough: 'string', + type: 'video', + url: 'https://muxed.s3.amazonaws.com/leds.mp4', }, ], - advanced_playback_policy: [ - { policy: 'public', drm_configuration_id: 'string' }, - { policy: 'public', drm_configuration_id: 'string' }, - { policy: 'public', drm_configuration_id: 'string' }, + advanced_playback_policies: [ + { drm_configuration_id: 'drm_configuration_id', policy: 'public' }, + { drm_configuration_id: 'drm_configuration_id', policy: 'public' }, + { drm_configuration_id: 'drm_configuration_id', policy: 'public' }, ], - encoding_tier: 'baseline', + encoding_tier: 'smart', master_access: 'none', max_resolution_tier: '1080p', mp4_support: 'none', normalize_audio: true, - passthrough: 'string', + passthrough: 'passthrough', per_title_encode: true, playback_policy: ['public'], test: true, + video_quality: 'basic', }); }); test('retrieve', async () => { - const responsePromise = mux.video.assets.retrieve('string'); + const responsePromise = client.video.assets.retrieve('ASSET_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -80,13 +81,13 @@ describe('resource assets', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.assets.retrieve('string', { path: '/_stainless_unknown_path' })).rejects.toThrow( - Mux.NotFoundError, - ); + await expect( + client.video.assets.retrieve('ASSET_ID', { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(Mux.NotFoundError); }); test('update', async () => { - const responsePromise = mux.video.assets.update('string', {}); + const responsePromise = client.video.assets.update('ASSET_ID', {}); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -97,7 +98,7 @@ describe('resource assets', () => { }); test('list', async () => { - const responsePromise = mux.video.assets.list(); + const responsePromise = client.video.assets.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -109,7 +110,7 @@ describe('resource assets', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.assets.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.video.assets.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -117,15 +118,15 @@ describe('resource assets', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.assets.list( - { limit: 0, live_stream_id: 'string', page: 0, upload_id: 'string' }, + client.video.assets.list( + { limit: 0, live_stream_id: 'live_stream_id', page: 0, upload_id: 'upload_id' }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Mux.NotFoundError); }); test('delete', async () => { - const responsePromise = mux.video.assets.delete('string'); + const responsePromise = client.video.assets.delete('ASSET_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -137,13 +138,13 @@ describe('resource assets', () => { test('delete: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.assets.delete('string', { path: '/_stainless_unknown_path' })).rejects.toThrow( - Mux.NotFoundError, - ); + await expect( + client.video.assets.delete('ASSET_ID', { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(Mux.NotFoundError); }); test('createPlaybackId', async () => { - const responsePromise = mux.video.assets.createPlaybackId('string', {}); + const responsePromise = client.video.assets.createPlaybackId('ASSET_ID', {}); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -154,7 +155,7 @@ describe('resource assets', () => { }); test('createTrack: only required params', async () => { - const responsePromise = mux.video.assets.createTrack('string', { + const responsePromise = client.video.assets.createTrack('ASSET_ID', { language_code: 'en-US', type: 'text', url: 'https://example.com/myVideo_en.srt', @@ -169,7 +170,7 @@ describe('resource assets', () => { }); test('createTrack: required and optional params', async () => { - const response = await mux.video.assets.createTrack('string', { + const response = await client.video.assets.createTrack('ASSET_ID', { language_code: 'en-US', type: 'text', url: 'https://example.com/myVideo_en.srt', @@ -181,7 +182,7 @@ describe('resource assets', () => { }); test('deletePlaybackId', async () => { - const responsePromise = mux.video.assets.deletePlaybackId('string', 'string'); + const responsePromise = client.video.assets.deletePlaybackId('ASSET_ID', 'PLAYBACK_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -194,12 +195,12 @@ describe('resource assets', () => { test('deletePlaybackId: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.assets.deletePlaybackId('string', 'string', { path: '/_stainless_unknown_path' }), + client.video.assets.deletePlaybackId('ASSET_ID', 'PLAYBACK_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('deleteTrack', async () => { - const responsePromise = mux.video.assets.deleteTrack('string', 'string'); + const responsePromise = client.video.assets.deleteTrack('ASSET_ID', 'TRACK_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -212,12 +213,12 @@ describe('resource assets', () => { test('deleteTrack: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.assets.deleteTrack('string', 'string', { path: '/_stainless_unknown_path' }), + client.video.assets.deleteTrack('ASSET_ID', 'TRACK_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('generateSubtitles: only required params', async () => { - const responsePromise = mux.video.assets.generateSubtitles('string', 'string', { + const responsePromise = client.video.assets.generateSubtitles('ASSET_ID', 'TRACK_ID', { generated_subtitles: [{}], }); const rawResponse = await responsePromise.asResponse(); @@ -230,15 +231,15 @@ describe('resource assets', () => { }); test('generateSubtitles: required and optional params', async () => { - const response = await mux.video.assets.generateSubtitles('string', 'string', { + const response = await client.video.assets.generateSubtitles('ASSET_ID', 'TRACK_ID', { generated_subtitles: [ - { name: 'English (generated)', passthrough: 'English (generated)', language_code: 'en' }, + { language_code: 'en', name: 'English (generated)', passthrough: 'English (generated)' }, ], }); }); test('retrieveInputInfo', async () => { - const responsePromise = mux.video.assets.retrieveInputInfo('string'); + const responsePromise = client.video.assets.retrieveInputInfo('ASSET_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -251,12 +252,12 @@ describe('resource assets', () => { test('retrieveInputInfo: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.assets.retrieveInputInfo('string', { path: '/_stainless_unknown_path' }), + client.video.assets.retrieveInputInfo('ASSET_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('retrievePlaybackId', async () => { - const responsePromise = mux.video.assets.retrievePlaybackId('string', 'string'); + const responsePromise = client.video.assets.retrievePlaybackId('ASSET_ID', 'PLAYBACK_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -269,12 +270,14 @@ describe('resource assets', () => { test('retrievePlaybackId: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.assets.retrievePlaybackId('string', 'string', { path: '/_stainless_unknown_path' }), + client.video.assets.retrievePlaybackId('ASSET_ID', 'PLAYBACK_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('updateMasterAccess: only required params', async () => { - const responsePromise = mux.video.assets.updateMasterAccess('string', { master_access: 'temporary' }); + const responsePromise = client.video.assets.updateMasterAccess('ASSET_ID', { + master_access: 'temporary', + }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -285,11 +288,11 @@ describe('resource assets', () => { }); test('updateMasterAccess: required and optional params', async () => { - const response = await mux.video.assets.updateMasterAccess('string', { master_access: 'temporary' }); + const response = await client.video.assets.updateMasterAccess('ASSET_ID', { master_access: 'temporary' }); }); test('updateMP4Support: only required params', async () => { - const responsePromise = mux.video.assets.updateMP4Support('string', { mp4_support: 'capped-1080p' }); + const responsePromise = client.video.assets.updateMP4Support('ASSET_ID', { mp4_support: 'standard' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -300,6 +303,6 @@ describe('resource assets', () => { }); test('updateMP4Support: required and optional params', async () => { - const response = await mux.video.assets.updateMP4Support('string', { mp4_support: 'capped-1080p' }); + const response = await client.video.assets.updateMP4Support('ASSET_ID', { mp4_support: 'standard' }); }); }); diff --git a/tests/api-resources/video/delivery-usage.test.ts b/tests/api-resources/video/delivery-usage.test.ts index 5bfdc4ec..f1c846f7 100644 --- a/tests/api-resources/video/delivery-usage.test.ts +++ b/tests/api-resources/video/delivery-usage.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource deliveryUsage', () => { test('list', async () => { - const responsePromise = mux.video.deliveryUsage.list(); + const responsePromise = client.video.deliveryUsage.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,7 +23,7 @@ describe('resource deliveryUsage', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.deliveryUsage.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.video.deliveryUsage.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -31,11 +31,11 @@ describe('resource deliveryUsage', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.deliveryUsage.list( + client.video.deliveryUsage.list( { - asset_id: 'string', + asset_id: 'asset_id', limit: 0, - live_stream_id: 'string', + live_stream_id: 'live_stream_id', page: 0, timeframe: ['string', 'string', 'string'], }, diff --git a/tests/api-resources/video/drm-configurations.test.ts b/tests/api-resources/video/drm-configurations.test.ts index 93e021c5..0b85f926 100644 --- a/tests/api-resources/video/drm-configurations.test.ts +++ b/tests/api-resources/video/drm-configurations.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource drmConfigurations', () => { test('retrieve', async () => { - const responsePromise = mux.video.drmConfigurations.retrieve('string'); + const responsePromise = client.video.drmConfigurations.retrieve('DRM_CONFIGURATION_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -24,12 +24,12 @@ describe('resource drmConfigurations', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.drmConfigurations.retrieve('string', { path: '/_stainless_unknown_path' }), + client.video.drmConfigurations.retrieve('DRM_CONFIGURATION_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('list', async () => { - const responsePromise = mux.video.drmConfigurations.list(); + const responsePromise = client.video.drmConfigurations.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -41,7 +41,7 @@ describe('resource drmConfigurations', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.drmConfigurations.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.video.drmConfigurations.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -49,7 +49,7 @@ describe('resource drmConfigurations', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.drmConfigurations.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), + client.video.drmConfigurations.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); }); diff --git a/tests/api-resources/video/live-streams.test.ts b/tests/api-resources/video/live-streams.test.ts index 7a3df02e..f13c4868 100644 --- a/tests/api-resources/video/live-streams.test.ts +++ b/tests/api-resources/video/live-streams.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource liveStreams', () => { test('create', async () => { - const responsePromise = mux.video.liveStreams.create({}); + const responsePromise = client.video.liveStreams.create({}); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -22,7 +22,7 @@ describe('resource liveStreams', () => { }); test('retrieve', async () => { - const responsePromise = mux.video.liveStreams.retrieve('string'); + const responsePromise = client.video.liveStreams.retrieve('LIVE_STREAM_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -35,12 +35,12 @@ describe('resource liveStreams', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.retrieve('string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.retrieve('LIVE_STREAM_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('update', async () => { - const responsePromise = mux.video.liveStreams.update('string', {}); + const responsePromise = client.video.liveStreams.update('LIVE_STREAM_ID', {}); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -51,7 +51,7 @@ describe('resource liveStreams', () => { }); test('list', async () => { - const responsePromise = mux.video.liveStreams.list(); + const responsePromise = client.video.liveStreams.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -63,7 +63,7 @@ describe('resource liveStreams', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.liveStreams.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.video.liveStreams.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -71,15 +71,15 @@ describe('resource liveStreams', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.list( - { limit: 0, page: 0, status: 'active', stream_key: 'string' }, + client.video.liveStreams.list( + { limit: 0, page: 0, status: 'active', stream_key: 'stream_key' }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Mux.NotFoundError); }); test('delete', async () => { - const responsePromise = mux.video.liveStreams.delete('string'); + const responsePromise = client.video.liveStreams.delete('LIVE_STREAM_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -92,12 +92,12 @@ describe('resource liveStreams', () => { test('delete: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.delete('string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.delete('LIVE_STREAM_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('complete', async () => { - const responsePromise = mux.video.liveStreams.complete('string'); + const responsePromise = client.video.liveStreams.complete('LIVE_STREAM_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -110,12 +110,12 @@ describe('resource liveStreams', () => { test('complete: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.complete('string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.complete('LIVE_STREAM_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('createPlaybackId', async () => { - const responsePromise = mux.video.liveStreams.createPlaybackId('string', {}); + const responsePromise = client.video.liveStreams.createPlaybackId('LIVE_STREAM_ID', {}); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -126,7 +126,7 @@ describe('resource liveStreams', () => { }); test('createSimulcastTarget: only required params', async () => { - const responsePromise = mux.video.liveStreams.createSimulcastTarget('string', { + const responsePromise = client.video.liveStreams.createSimulcastTarget('LIVE_STREAM_ID', { url: 'rtmp://live.example.com/app', }); const rawResponse = await responsePromise.asResponse(); @@ -139,7 +139,7 @@ describe('resource liveStreams', () => { }); test('createSimulcastTarget: required and optional params', async () => { - const response = await mux.video.liveStreams.createSimulcastTarget('string', { + const response = await client.video.liveStreams.createSimulcastTarget('LIVE_STREAM_ID', { url: 'rtmp://live.example.com/app', passthrough: 'Example', stream_key: 'abcdefgh', @@ -147,7 +147,7 @@ describe('resource liveStreams', () => { }); test('deletePlaybackId', async () => { - const responsePromise = mux.video.liveStreams.deletePlaybackId('string', 'string'); + const responsePromise = client.video.liveStreams.deletePlaybackId('LIVE_STREAM_ID', 'PLAYBACK_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -160,12 +160,17 @@ describe('resource liveStreams', () => { test('deletePlaybackId: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.deletePlaybackId('string', 'string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.deletePlaybackId('LIVE_STREAM_ID', 'PLAYBACK_ID', { + path: '/_stainless_unknown_path', + }), ).rejects.toThrow(Mux.NotFoundError); }); test('deleteSimulcastTarget', async () => { - const responsePromise = mux.video.liveStreams.deleteSimulcastTarget('string', 'string'); + const responsePromise = client.video.liveStreams.deleteSimulcastTarget( + 'LIVE_STREAM_ID', + 'SIMULCAST_TARGET_ID', + ); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -178,12 +183,14 @@ describe('resource liveStreams', () => { test('deleteSimulcastTarget: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.deleteSimulcastTarget('string', 'string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.deleteSimulcastTarget('LIVE_STREAM_ID', 'SIMULCAST_TARGET_ID', { + path: '/_stainless_unknown_path', + }), ).rejects.toThrow(Mux.NotFoundError); }); test('disable', async () => { - const responsePromise = mux.video.liveStreams.disable('string'); + const responsePromise = client.video.liveStreams.disable('LIVE_STREAM_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -196,12 +203,12 @@ describe('resource liveStreams', () => { test('disable: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.disable('string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.disable('LIVE_STREAM_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('enable', async () => { - const responsePromise = mux.video.liveStreams.enable('string'); + const responsePromise = client.video.liveStreams.enable('LIVE_STREAM_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -214,12 +221,12 @@ describe('resource liveStreams', () => { test('enable: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.enable('string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.enable('LIVE_STREAM_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('resetStreamKey', async () => { - const responsePromise = mux.video.liveStreams.resetStreamKey('string'); + const responsePromise = client.video.liveStreams.resetStreamKey('LIVE_STREAM_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -232,12 +239,12 @@ describe('resource liveStreams', () => { test('resetStreamKey: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.resetStreamKey('string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.resetStreamKey('LIVE_STREAM_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('retrievePlaybackId', async () => { - const responsePromise = mux.video.liveStreams.retrievePlaybackId('string', 'string'); + const responsePromise = client.video.liveStreams.retrievePlaybackId('LIVE_STREAM_ID', 'PLAYBACK_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -250,12 +257,17 @@ describe('resource liveStreams', () => { test('retrievePlaybackId: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.retrievePlaybackId('string', 'string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.retrievePlaybackId('LIVE_STREAM_ID', 'PLAYBACK_ID', { + path: '/_stainless_unknown_path', + }), ).rejects.toThrow(Mux.NotFoundError); }); test('retrieveSimulcastTarget', async () => { - const responsePromise = mux.video.liveStreams.retrieveSimulcastTarget('string', 'string'); + const responsePromise = client.video.liveStreams.retrieveSimulcastTarget( + 'LIVE_STREAM_ID', + 'SIMULCAST_TARGET_ID', + ); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -268,12 +280,14 @@ describe('resource liveStreams', () => { test('retrieveSimulcastTarget: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.liveStreams.retrieveSimulcastTarget('string', 'string', { path: '/_stainless_unknown_path' }), + client.video.liveStreams.retrieveSimulcastTarget('LIVE_STREAM_ID', 'SIMULCAST_TARGET_ID', { + path: '/_stainless_unknown_path', + }), ).rejects.toThrow(Mux.NotFoundError); }); test('updateEmbeddedSubtitles', async () => { - const responsePromise = mux.video.liveStreams.updateEmbeddedSubtitles('string', {}); + const responsePromise = client.video.liveStreams.updateEmbeddedSubtitles('LIVE_STREAM_ID', {}); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -284,7 +298,7 @@ describe('resource liveStreams', () => { }); test('updateGeneratedSubtitles', async () => { - const responsePromise = mux.video.liveStreams.updateGeneratedSubtitles('string', {}); + const responsePromise = client.video.liveStreams.updateGeneratedSubtitles('LIVE_STREAM_ID', {}); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; diff --git a/tests/api-resources/video/playback-ids.test.ts b/tests/api-resources/video/playback-ids.test.ts index 35ccaa2f..3ab176ef 100644 --- a/tests/api-resources/video/playback-ids.test.ts +++ b/tests/api-resources/video/playback-ids.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource playbackIds', () => { test('retrieve', async () => { - const responsePromise = mux.video.playbackIds.retrieve('string'); + const responsePromise = client.video.playbackIds.retrieve('PLAYBACK_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -24,7 +24,7 @@ describe('resource playbackIds', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.playbackIds.retrieve('string', { path: '/_stainless_unknown_path' }), + client.video.playbackIds.retrieve('PLAYBACK_ID', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); }); diff --git a/tests/api-resources/video/playback-restrictions.test.ts b/tests/api-resources/video/playback-restrictions.test.ts index b793e2f5..6e158192 100644 --- a/tests/api-resources/video/playback-restrictions.test.ts +++ b/tests/api-resources/video/playback-restrictions.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource playbackRestrictions', () => { test('create: only required params', async () => { - const responsePromise = mux.video.playbackRestrictions.create({ + const responsePromise = client.video.playbackRestrictions.create({ referrer: { allowed_domains: ['*.example.com'] }, user_agent: {}, }); @@ -25,14 +25,14 @@ describe('resource playbackRestrictions', () => { }); test('create: required and optional params', async () => { - const response = await mux.video.playbackRestrictions.create({ + const response = await client.video.playbackRestrictions.create({ referrer: { allowed_domains: ['*.example.com'], allow_no_referrer: true }, - user_agent: { allow_no_user_agent: false, allow_high_risk_user_agent: false }, + user_agent: { allow_high_risk_user_agent: false, allow_no_user_agent: false }, }); }); test('retrieve', async () => { - const responsePromise = mux.video.playbackRestrictions.retrieve('string'); + const responsePromise = client.video.playbackRestrictions.retrieve('PLAYBACK_RESTRICTION_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -45,12 +45,14 @@ describe('resource playbackRestrictions', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.playbackRestrictions.retrieve('string', { path: '/_stainless_unknown_path' }), + client.video.playbackRestrictions.retrieve('PLAYBACK_RESTRICTION_ID', { + path: '/_stainless_unknown_path', + }), ).rejects.toThrow(Mux.NotFoundError); }); test('list', async () => { - const responsePromise = mux.video.playbackRestrictions.list(); + const responsePromise = client.video.playbackRestrictions.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -62,20 +64,20 @@ describe('resource playbackRestrictions', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.playbackRestrictions.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( - Mux.NotFoundError, - ); + await expect( + client.video.playbackRestrictions.list({ path: '/_stainless_unknown_path' }), + ).rejects.toThrow(Mux.NotFoundError); }); test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.playbackRestrictions.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), + client.video.playbackRestrictions.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('delete', async () => { - const responsePromise = mux.video.playbackRestrictions.delete('string'); + const responsePromise = client.video.playbackRestrictions.delete('PLAYBACK_RESTRICTION_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -88,12 +90,14 @@ describe('resource playbackRestrictions', () => { test('delete: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.playbackRestrictions.delete('string', { path: '/_stainless_unknown_path' }), + client.video.playbackRestrictions.delete('PLAYBACK_RESTRICTION_ID', { + path: '/_stainless_unknown_path', + }), ).rejects.toThrow(Mux.NotFoundError); }); test('updateReferrer: only required params', async () => { - const responsePromise = mux.video.playbackRestrictions.updateReferrer('string', { + const responsePromise = client.video.playbackRestrictions.updateReferrer('PLAYBACK_RESTRICTION_ID', { allowed_domains: ['string', 'string', 'string'], }); const rawResponse = await responsePromise.asResponse(); @@ -106,14 +110,14 @@ describe('resource playbackRestrictions', () => { }); test('updateReferrer: required and optional params', async () => { - const response = await mux.video.playbackRestrictions.updateReferrer('string', { + const response = await client.video.playbackRestrictions.updateReferrer('PLAYBACK_RESTRICTION_ID', { allowed_domains: ['string', 'string', 'string'], allow_no_referrer: true, }); }); test('updateUserAgent: only required params', async () => { - const responsePromise = mux.video.playbackRestrictions.updateUserAgent('string', { + const responsePromise = client.video.playbackRestrictions.updateUserAgent('PLAYBACK_RESTRICTION_ID', { allow_high_risk_user_agent: false, allow_no_user_agent: false, }); @@ -127,7 +131,7 @@ describe('resource playbackRestrictions', () => { }); test('updateUserAgent: required and optional params', async () => { - const response = await mux.video.playbackRestrictions.updateUserAgent('string', { + const response = await client.video.playbackRestrictions.updateUserAgent('PLAYBACK_RESTRICTION_ID', { allow_high_risk_user_agent: false, allow_no_user_agent: false, }); diff --git a/tests/api-resources/video/spaces.test.ts b/tests/api-resources/video/spaces.test.ts deleted file mode 100644 index 9960d538..00000000 --- a/tests/api-resources/video/spaces.test.ts +++ /dev/null @@ -1,179 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import Mux from '@mux/mux-node'; -import { Response } from 'node-fetch'; - -const mux = new Mux({ - tokenId: 'my token id', - tokenSecret: 'my secret', - baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', -}); - -describe('resource spaces', () => { - test('create', async () => { - const responsePromise = mux.video.spaces.create({}); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('retrieve', async () => { - const responsePromise = mux.video.spaces.retrieve('string'); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('retrieve: request options instead of params are passed correctly', async () => { - // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.spaces.retrieve('string', { path: '/_stainless_unknown_path' })).rejects.toThrow( - Mux.NotFoundError, - ); - }); - - test('list', async () => { - const responsePromise = mux.video.spaces.list(); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('list: request options instead of params are passed correctly', async () => { - // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.spaces.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( - Mux.NotFoundError, - ); - }); - - test('list: request options and params are passed correctly', async () => { - // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect( - mux.video.spaces.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), - ).rejects.toThrow(Mux.NotFoundError); - }); - - test('delete', async () => { - const responsePromise = mux.video.spaces.delete('string'); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('delete: request options instead of params are passed correctly', async () => { - // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.spaces.delete('string', { path: '/_stainless_unknown_path' })).rejects.toThrow( - Mux.NotFoundError, - ); - }); - - test('createBroadcast: only required params', async () => { - const responsePromise = mux.video.spaces.createBroadcast('string', { - live_stream_id: 'GQ9025mPqzyjOy3kKQW006qKTqmULW9vFO', - }); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('createBroadcast: required and optional params', async () => { - const response = await mux.video.spaces.createBroadcast('string', { - live_stream_id: 'GQ9025mPqzyjOy3kKQW006qKTqmULW9vFO', - background: 'string', - layout: 'gallery', - passthrough: 'string', - resolution: '1920x1080', - }); - }); - - test('deleteBroadcast', async () => { - const responsePromise = mux.video.spaces.deleteBroadcast('string', 'string'); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('deleteBroadcast: request options instead of params are passed correctly', async () => { - // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect( - mux.video.spaces.deleteBroadcast('string', 'string', { path: '/_stainless_unknown_path' }), - ).rejects.toThrow(Mux.NotFoundError); - }); - - test('retrieveBroadcast', async () => { - const responsePromise = mux.video.spaces.retrieveBroadcast('string', 'string'); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('retrieveBroadcast: request options instead of params are passed correctly', async () => { - // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect( - mux.video.spaces.retrieveBroadcast('string', 'string', { path: '/_stainless_unknown_path' }), - ).rejects.toThrow(Mux.NotFoundError); - }); - - test('startBroadcast', async () => { - const responsePromise = mux.video.spaces.startBroadcast('string', 'string'); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('startBroadcast: request options instead of params are passed correctly', async () => { - // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect( - mux.video.spaces.startBroadcast('string', 'string', { path: '/_stainless_unknown_path' }), - ).rejects.toThrow(Mux.NotFoundError); - }); - - test('stopBroadcast', async () => { - const responsePromise = mux.video.spaces.stopBroadcast('string', 'string'); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('stopBroadcast: request options instead of params are passed correctly', async () => { - // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect( - mux.video.spaces.stopBroadcast('string', 'string', { path: '/_stainless_unknown_path' }), - ).rejects.toThrow(Mux.NotFoundError); - }); -}); diff --git a/tests/api-resources/video/transcription-vocabularies.test.ts b/tests/api-resources/video/transcription-vocabularies.test.ts index 0007de70..066a519d 100644 --- a/tests/api-resources/video/transcription-vocabularies.test.ts +++ b/tests/api-resources/video/transcription-vocabularies.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource transcriptionVocabularies', () => { test('create: only required params', async () => { - const responsePromise = mux.video.transcriptionVocabularies.create({ + const responsePromise = client.video.transcriptionVocabularies.create({ phrases: ['Mux', 'Live Stream', 'Playback ID', 'video encoding'], }); const rawResponse = await responsePromise.asResponse(); @@ -24,15 +24,15 @@ describe('resource transcriptionVocabularies', () => { }); test('create: required and optional params', async () => { - const response = await mux.video.transcriptionVocabularies.create({ + const response = await client.video.transcriptionVocabularies.create({ phrases: ['Mux', 'Live Stream', 'Playback ID', 'video encoding'], name: 'Mux API Vocabulary', - passthrough: 'string', + passthrough: 'passthrough', }); }); test('retrieve', async () => { - const responsePromise = mux.video.transcriptionVocabularies.retrieve('string'); + const responsePromise = client.video.transcriptionVocabularies.retrieve('TRANSCRIPTION_VOCABULARY_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -45,12 +45,14 @@ describe('resource transcriptionVocabularies', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.transcriptionVocabularies.retrieve('string', { path: '/_stainless_unknown_path' }), + client.video.transcriptionVocabularies.retrieve('TRANSCRIPTION_VOCABULARY_ID', { + path: '/_stainless_unknown_path', + }), ).rejects.toThrow(Mux.NotFoundError); }); test('update: only required params', async () => { - const responsePromise = mux.video.transcriptionVocabularies.update('string', { + const responsePromise = client.video.transcriptionVocabularies.update('TRANSCRIPTION_VOCABULARY_ID', { phrases: ['Mux', 'Live Stream', 'RTMP', 'Stream Key'], }); const rawResponse = await responsePromise.asResponse(); @@ -63,15 +65,15 @@ describe('resource transcriptionVocabularies', () => { }); test('update: required and optional params', async () => { - const response = await mux.video.transcriptionVocabularies.update('string', { + const response = await client.video.transcriptionVocabularies.update('TRANSCRIPTION_VOCABULARY_ID', { phrases: ['Mux', 'Live Stream', 'RTMP', 'Stream Key'], name: 'Mux API Vocabulary - Updated', - passthrough: 'string', + passthrough: 'passthrough', }); }); test('list', async () => { - const responsePromise = mux.video.transcriptionVocabularies.list(); + const responsePromise = client.video.transcriptionVocabularies.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -84,19 +86,22 @@ describe('resource transcriptionVocabularies', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.transcriptionVocabularies.list({ path: '/_stainless_unknown_path' }), + client.video.transcriptionVocabularies.list({ path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.transcriptionVocabularies.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), + client.video.transcriptionVocabularies.list( + { limit: 0, page: 0 }, + { path: '/_stainless_unknown_path' }, + ), ).rejects.toThrow(Mux.NotFoundError); }); test('delete', async () => { - const responsePromise = mux.video.transcriptionVocabularies.delete('string'); + const responsePromise = client.video.transcriptionVocabularies.delete('TRANSCRIPTION_VOCABULARY_ID'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -109,7 +114,9 @@ describe('resource transcriptionVocabularies', () => { test('delete: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.transcriptionVocabularies.delete('string', { path: '/_stainless_unknown_path' }), + client.video.transcriptionVocabularies.delete('TRANSCRIPTION_VOCABULARY_ID', { + path: '/_stainless_unknown_path', + }), ).rejects.toThrow(Mux.NotFoundError); }); }); diff --git a/tests/api-resources/video/uploads.test.ts b/tests/api-resources/video/uploads.test.ts index 2a4674b2..f360a449 100644 --- a/tests/api-resources/video/uploads.test.ts +++ b/tests/api-resources/video/uploads.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource uploads', () => { test('create: only required params', async () => { - const responsePromise = mux.video.uploads.create({ cors_origin: 'https://example.com/' }); + const responsePromise = client.video.uploads.create({ cors_origin: 'https://example.com/' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -22,100 +22,101 @@ describe('resource uploads', () => { }); test('create: required and optional params', async () => { - const response = await mux.video.uploads.create({ + const response = await client.video.uploads.create({ cors_origin: 'https://example.com/', new_asset_settings: { + advanced_playback_policies: [ + { drm_configuration_id: 'drm_configuration_id', policy: 'public' }, + { drm_configuration_id: 'drm_configuration_id', policy: 'public' }, + { drm_configuration_id: 'drm_configuration_id', policy: 'public' }, + ], + encoding_tier: 'smart', input: [ { - url: 'string', + closed_captions: true, + end_time: 0, + generated_subtitles: [ + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + ], + language_code: 'language_code', + name: 'name', overlay_settings: { - vertical_align: 'top', - vertical_margin: 'string', + height: 'height', horizontal_align: 'left', - horizontal_margin: 'string', - width: 'string', - height: 'string', - opacity: 'string', + horizontal_margin: 'horizontal_margin', + opacity: 'opacity', + vertical_align: 'top', + vertical_margin: 'vertical_margin', + width: 'width', }, - generated_subtitles: [ - { name: 'string', passthrough: 'string', language_code: 'en' }, - { name: 'string', passthrough: 'string', language_code: 'en' }, - { name: 'string', passthrough: 'string', language_code: 'en' }, - ], + passthrough: 'passthrough', start_time: 0, - end_time: 0, - type: 'video', text_type: 'subtitles', - language_code: 'string', - name: 'string', - closed_captions: true, - passthrough: 'string', + type: 'video', + url: 'url', }, { - url: 'string', + closed_captions: true, + end_time: 0, + generated_subtitles: [ + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + ], + language_code: 'language_code', + name: 'name', overlay_settings: { - vertical_align: 'top', - vertical_margin: 'string', + height: 'height', horizontal_align: 'left', - horizontal_margin: 'string', - width: 'string', - height: 'string', - opacity: 'string', + horizontal_margin: 'horizontal_margin', + opacity: 'opacity', + vertical_align: 'top', + vertical_margin: 'vertical_margin', + width: 'width', }, - generated_subtitles: [ - { name: 'string', passthrough: 'string', language_code: 'en' }, - { name: 'string', passthrough: 'string', language_code: 'en' }, - { name: 'string', passthrough: 'string', language_code: 'en' }, - ], + passthrough: 'passthrough', start_time: 0, - end_time: 0, - type: 'video', text_type: 'subtitles', - language_code: 'string', - name: 'string', - closed_captions: true, - passthrough: 'string', + type: 'video', + url: 'url', }, { - url: 'string', + closed_captions: true, + end_time: 0, + generated_subtitles: [ + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + { language_code: 'en', name: 'name', passthrough: 'passthrough' }, + ], + language_code: 'language_code', + name: 'name', overlay_settings: { - vertical_align: 'top', - vertical_margin: 'string', + height: 'height', horizontal_align: 'left', - horizontal_margin: 'string', - width: 'string', - height: 'string', - opacity: 'string', + horizontal_margin: 'horizontal_margin', + opacity: 'opacity', + vertical_align: 'top', + vertical_margin: 'vertical_margin', + width: 'width', }, - generated_subtitles: [ - { name: 'string', passthrough: 'string', language_code: 'en' }, - { name: 'string', passthrough: 'string', language_code: 'en' }, - { name: 'string', passthrough: 'string', language_code: 'en' }, - ], + passthrough: 'passthrough', start_time: 0, - end_time: 0, - type: 'video', text_type: 'subtitles', - language_code: 'string', - name: 'string', - closed_captions: true, - passthrough: 'string', + type: 'video', + url: 'url', }, ], - playback_policy: ['public'], - advanced_playback_policy: [ - { policy: 'public', drm_configuration_id: 'string' }, - { policy: 'public', drm_configuration_id: 'string' }, - { policy: 'public', drm_configuration_id: 'string' }, - ], - per_title_encode: true, - passthrough: 'string', - mp4_support: 'capped-1080p', - normalize_audio: true, master_access: 'none', - test: true, max_resolution_tier: '1080p', - encoding_tier: 'smart', + mp4_support: 'none', + normalize_audio: true, + passthrough: 'passthrough', + per_title_encode: true, + playback_policy: ['public'], + test: true, + video_quality: 'basic', }, test: true, timeout: 60, @@ -123,7 +124,7 @@ describe('resource uploads', () => { }); test('retrieve', async () => { - const responsePromise = mux.video.uploads.retrieve('abcd1234'); + const responsePromise = client.video.uploads.retrieve('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -136,12 +137,12 @@ describe('resource uploads', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.uploads.retrieve('abcd1234', { path: '/_stainless_unknown_path' }), + client.video.uploads.retrieve('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('list', async () => { - const responsePromise = mux.video.uploads.list(); + const responsePromise = client.video.uploads.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -153,7 +154,7 @@ describe('resource uploads', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.uploads.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.video.uploads.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -161,12 +162,12 @@ describe('resource uploads', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.uploads.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), + client.video.uploads.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('cancel', async () => { - const responsePromise = mux.video.uploads.cancel('abcd1234'); + const responsePromise = client.video.uploads.cancel('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -178,8 +179,8 @@ describe('resource uploads', () => { test('cancel: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.uploads.cancel('abcd1234', { path: '/_stainless_unknown_path' })).rejects.toThrow( - Mux.NotFoundError, - ); + await expect( + client.video.uploads.cancel('abcd1234', { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(Mux.NotFoundError); }); }); diff --git a/tests/api-resources/video/web-inputs.test.ts b/tests/api-resources/video/web-inputs.test.ts index 6a3c811a..6049b608 100644 --- a/tests/api-resources/video/web-inputs.test.ts +++ b/tests/api-resources/video/web-inputs.test.ts @@ -3,7 +3,7 @@ import Mux from '@mux/mux-node'; import { Response } from 'node-fetch'; -const mux = new Mux({ +const client = new Mux({ tokenId: 'my token id', tokenSecret: 'my secret', baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -11,7 +11,7 @@ const mux = new Mux({ describe('resource webInputs', () => { test('create: only required params', async () => { - const responsePromise = mux.video.webInputs.create({ + const responsePromise = client.video.webInputs.create({ live_stream_id: 'ZEBrNTpHC02iUah025KM3te6ylM7W4S4silsrFtUkn3Ag', url: 'https://example.com/hello.html', }); @@ -25,13 +25,13 @@ describe('resource webInputs', () => { }); test('create: required and optional params', async () => { - const response = await mux.video.webInputs.create({ + const response = await client.video.webInputs.create({ live_stream_id: 'ZEBrNTpHC02iUah025KM3te6ylM7W4S4silsrFtUkn3Ag', url: 'https://example.com/hello.html', - id: 'string', + id: 'id', auto_launch: true, - created_at: 'string', - passthrough: 'string', + created_at: 'created_at', + passthrough: 'passthrough', resolution: '1920x1080', status: 'idle', timeout: 0, @@ -39,7 +39,7 @@ describe('resource webInputs', () => { }); test('retrieve', async () => { - const responsePromise = mux.video.webInputs.retrieve('abcd1234'); + const responsePromise = client.video.webInputs.retrieve('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -52,12 +52,12 @@ describe('resource webInputs', () => { test('retrieve: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.webInputs.retrieve('abcd1234', { path: '/_stainless_unknown_path' }), + client.video.webInputs.retrieve('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('list', async () => { - const responsePromise = mux.video.webInputs.list(); + const responsePromise = client.video.webInputs.list(); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -69,7 +69,7 @@ describe('resource webInputs', () => { test('list: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error - await expect(mux.video.webInputs.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + await expect(client.video.webInputs.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( Mux.NotFoundError, ); }); @@ -77,12 +77,12 @@ describe('resource webInputs', () => { test('list: request options and params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.webInputs.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), + client.video.webInputs.list({ limit: 0, page: 0 }, { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('delete', async () => { - const responsePromise = mux.video.webInputs.delete('abcd1234'); + const responsePromise = client.video.webInputs.delete('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -95,12 +95,12 @@ describe('resource webInputs', () => { test('delete: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.webInputs.delete('abcd1234', { path: '/_stainless_unknown_path' }), + client.video.webInputs.delete('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('launch', async () => { - const responsePromise = mux.video.webInputs.launch('abcd1234'); + const responsePromise = client.video.webInputs.launch('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -113,12 +113,12 @@ describe('resource webInputs', () => { test('launch: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.webInputs.launch('abcd1234', { path: '/_stainless_unknown_path' }), + client.video.webInputs.launch('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('reload', async () => { - const responsePromise = mux.video.webInputs.reload('abcd1234'); + const responsePromise = client.video.webInputs.reload('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -131,12 +131,12 @@ describe('resource webInputs', () => { test('reload: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.webInputs.reload('abcd1234', { path: '/_stainless_unknown_path' }), + client.video.webInputs.reload('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('shutdown', async () => { - const responsePromise = mux.video.webInputs.shutdown('abcd1234'); + const responsePromise = client.video.webInputs.shutdown('abcd1234'); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -149,12 +149,12 @@ describe('resource webInputs', () => { test('shutdown: request options instead of params are passed correctly', async () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( - mux.video.webInputs.shutdown('abcd1234', { path: '/_stainless_unknown_path' }), + client.video.webInputs.shutdown('abcd1234', { path: '/_stainless_unknown_path' }), ).rejects.toThrow(Mux.NotFoundError); }); test('updateURL: only required params', async () => { - const responsePromise = mux.video.webInputs.updateURL('abcd1234', { + const responsePromise = client.video.webInputs.updateURL('abcd1234', { url: 'https://example.com/hello-there.html', }); const rawResponse = await responsePromise.asResponse(); @@ -167,7 +167,7 @@ describe('resource webInputs', () => { }); test('updateURL: required and optional params', async () => { - const response = await mux.video.webInputs.updateURL('abcd1234', { + const response = await client.video.webInputs.updateURL('abcd1234', { url: 'https://example.com/hello-there.html', }); }); diff --git a/tests/index.test.ts b/tests/index.test.ts index e802c5cf..ab42fae9 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -268,6 +268,138 @@ describe('retries', () => { expect(count).toEqual(3); }); + test('retry count header', async () => { + let count = 0; + let capturedRequest: RequestInit | undefined; + const testFetch = async (url: RequestInfo, init: RequestInit = {}): Promise => { + count++; + if (count <= 2) { + return new Response(undefined, { + status: 429, + headers: { + 'Retry-After': '0.1', + }, + }); + } + capturedRequest = init; + return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); + }; + + const client = new Mux({ + tokenId: 'my token id', + tokenSecret: 'my secret', + fetch: testFetch, + maxRetries: 4, + }); + + expect(await client.request({ path: '/foo', method: 'get' })).toEqual({ a: 1 }); + + expect((capturedRequest!.headers as Headers)['x-stainless-retry-count']).toEqual('2'); + expect(count).toEqual(3); + }); + + test('omit retry count header', async () => { + let count = 0; + let capturedRequest: RequestInit | undefined; + const testFetch = async (url: RequestInfo, init: RequestInit = {}): Promise => { + count++; + if (count <= 2) { + return new Response(undefined, { + status: 429, + headers: { + 'Retry-After': '0.1', + }, + }); + } + capturedRequest = init; + return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); + }; + const client = new Mux({ + tokenId: 'my token id', + tokenSecret: 'my secret', + fetch: testFetch, + maxRetries: 4, + }); + + expect( + await client.request({ + path: '/foo', + method: 'get', + headers: { 'X-Stainless-Retry-Count': null }, + }), + ).toEqual({ a: 1 }); + + expect(capturedRequest!.headers as Headers).not.toHaveProperty('x-stainless-retry-count'); + }); + + test('omit retry count header by default', async () => { + let count = 0; + let capturedRequest: RequestInit | undefined; + const testFetch = async (url: RequestInfo, init: RequestInit = {}): Promise => { + count++; + if (count <= 2) { + return new Response(undefined, { + status: 429, + headers: { + 'Retry-After': '0.1', + }, + }); + } + capturedRequest = init; + return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); + }; + const client = new Mux({ + tokenId: 'my token id', + tokenSecret: 'my secret', + fetch: testFetch, + maxRetries: 4, + defaultHeaders: { 'X-Stainless-Retry-Count': null }, + }); + + expect( + await client.request({ + path: '/foo', + method: 'get', + }), + ).toEqual({ a: 1 }); + + expect(capturedRequest!.headers as Headers).not.toHaveProperty('x-stainless-retry-count'); + }); + + test('overwrite retry count header', async () => { + let count = 0; + let capturedRequest: RequestInit | undefined; + const testFetch = async (url: RequestInfo, init: RequestInit = {}): Promise => { + count++; + if (count <= 2) { + return new Response(undefined, { + status: 429, + headers: { + 'Retry-After': '0.1', + }, + }); + } + capturedRequest = init; + return new Response(JSON.stringify({ a: 1 }), { headers: { 'Content-Type': 'application/json' } }); + }; + const client = new Mux({ + tokenId: 'my token id', + tokenSecret: 'my secret', + fetch: testFetch, + maxRetries: 4, + }); + + expect( + await client.request({ + path: '/foo', + method: 'get', + headers: { 'X-Stainless-Retry-Count': '42' }, + }), + ).toEqual({ a: 1 }); + + expect((capturedRequest!.headers as Headers)['x-stainless-retry-count']).toBe('42'); + }); + test('retry on 429 with retry-after', async () => { let count = 0; const testFetch = async (url: RequestInfo, { signal }: RequestInit = {}): Promise => { diff --git a/tests/qs/empty-keys-cases.ts b/tests/qs/empty-keys-cases.ts new file mode 100644 index 00000000..ea2c1b0a --- /dev/null +++ b/tests/qs/empty-keys-cases.ts @@ -0,0 +1,271 @@ +export const empty_test_cases = [ + { + input: '&', + with_empty_keys: {}, + stringify_output: { + brackets: '', + indices: '', + repeat: '', + }, + no_empty_keys: {}, + }, + { + input: '&&', + with_empty_keys: {}, + stringify_output: { + brackets: '', + indices: '', + repeat: '', + }, + no_empty_keys: {}, + }, + { + input: '&=', + with_empty_keys: { '': '' }, + stringify_output: { + brackets: '=', + indices: '=', + repeat: '=', + }, + no_empty_keys: {}, + }, + { + input: '&=&', + with_empty_keys: { '': '' }, + stringify_output: { + brackets: '=', + indices: '=', + repeat: '=', + }, + no_empty_keys: {}, + }, + { + input: '&=&=', + with_empty_keys: { '': ['', ''] }, + stringify_output: { + brackets: '[]=&[]=', + indices: '[0]=&[1]=', + repeat: '=&=', + }, + no_empty_keys: {}, + }, + { + input: '&=&=&', + with_empty_keys: { '': ['', ''] }, + stringify_output: { + brackets: '[]=&[]=', + indices: '[0]=&[1]=', + repeat: '=&=', + }, + no_empty_keys: {}, + }, + { + input: '=', + with_empty_keys: { '': '' }, + no_empty_keys: {}, + stringify_output: { + brackets: '=', + indices: '=', + repeat: '=', + }, + }, + { + input: '=&', + with_empty_keys: { '': '' }, + stringify_output: { + brackets: '=', + indices: '=', + repeat: '=', + }, + no_empty_keys: {}, + }, + { + input: '=&&&', + with_empty_keys: { '': '' }, + stringify_output: { + brackets: '=', + indices: '=', + repeat: '=', + }, + no_empty_keys: {}, + }, + { + input: '=&=&=&', + with_empty_keys: { '': ['', '', ''] }, + stringify_output: { + brackets: '[]=&[]=&[]=', + indices: '[0]=&[1]=&[2]=', + repeat: '=&=&=', + }, + no_empty_keys: {}, + }, + { + input: '=&a[]=b&a[1]=c', + with_empty_keys: { '': '', a: ['b', 'c'] }, + stringify_output: { + brackets: '=&a[]=b&a[]=c', + indices: '=&a[0]=b&a[1]=c', + repeat: '=&a=b&a=c', + }, + no_empty_keys: { a: ['b', 'c'] }, + }, + { + input: '=a', + with_empty_keys: { '': 'a' }, + no_empty_keys: {}, + stringify_output: { + brackets: '=a', + indices: '=a', + repeat: '=a', + }, + }, + { + input: 'a==a', + with_empty_keys: { a: '=a' }, + no_empty_keys: { a: '=a' }, + stringify_output: { + brackets: 'a==a', + indices: 'a==a', + repeat: 'a==a', + }, + }, + { + input: '=&a[]=b', + with_empty_keys: { '': '', a: ['b'] }, + stringify_output: { + brackets: '=&a[]=b', + indices: '=&a[0]=b', + repeat: '=&a=b', + }, + no_empty_keys: { a: ['b'] }, + }, + { + input: '=&a[]=b&a[]=c&a[2]=d', + with_empty_keys: { '': '', a: ['b', 'c', 'd'] }, + stringify_output: { + brackets: '=&a[]=b&a[]=c&a[]=d', + indices: '=&a[0]=b&a[1]=c&a[2]=d', + repeat: '=&a=b&a=c&a=d', + }, + no_empty_keys: { a: ['b', 'c', 'd'] }, + }, + { + input: '=a&=b', + with_empty_keys: { '': ['a', 'b'] }, + stringify_output: { + brackets: '[]=a&[]=b', + indices: '[0]=a&[1]=b', + repeat: '=a&=b', + }, + no_empty_keys: {}, + }, + { + input: '=a&foo=b', + with_empty_keys: { '': 'a', foo: 'b' }, + no_empty_keys: { foo: 'b' }, + stringify_output: { + brackets: '=a&foo=b', + indices: '=a&foo=b', + repeat: '=a&foo=b', + }, + }, + { + input: 'a[]=b&a=c&=', + with_empty_keys: { '': '', a: ['b', 'c'] }, + stringify_output: { + brackets: '=&a[]=b&a[]=c', + indices: '=&a[0]=b&a[1]=c', + repeat: '=&a=b&a=c', + }, + no_empty_keys: { a: ['b', 'c'] }, + }, + { + input: 'a[]=b&a=c&=', + with_empty_keys: { '': '', a: ['b', 'c'] }, + stringify_output: { + brackets: '=&a[]=b&a[]=c', + indices: '=&a[0]=b&a[1]=c', + repeat: '=&a=b&a=c', + }, + no_empty_keys: { a: ['b', 'c'] }, + }, + { + input: 'a[0]=b&a=c&=', + with_empty_keys: { '': '', a: ['b', 'c'] }, + stringify_output: { + brackets: '=&a[]=b&a[]=c', + indices: '=&a[0]=b&a[1]=c', + repeat: '=&a=b&a=c', + }, + no_empty_keys: { a: ['b', 'c'] }, + }, + { + input: 'a=b&a[]=c&=', + with_empty_keys: { '': '', a: ['b', 'c'] }, + stringify_output: { + brackets: '=&a[]=b&a[]=c', + indices: '=&a[0]=b&a[1]=c', + repeat: '=&a=b&a=c', + }, + no_empty_keys: { a: ['b', 'c'] }, + }, + { + input: 'a=b&a[0]=c&=', + with_empty_keys: { '': '', a: ['b', 'c'] }, + stringify_output: { + brackets: '=&a[]=b&a[]=c', + indices: '=&a[0]=b&a[1]=c', + repeat: '=&a=b&a=c', + }, + no_empty_keys: { a: ['b', 'c'] }, + }, + { + input: '[]=a&[]=b& []=1', + with_empty_keys: { '': ['a', 'b'], ' ': ['1'] }, + stringify_output: { + brackets: '[]=a&[]=b& []=1', + indices: '[0]=a&[1]=b& [0]=1', + repeat: '=a&=b& =1', + }, + no_empty_keys: { 0: 'a', 1: 'b', ' ': ['1'] }, + }, + { + input: '[0]=a&[1]=b&a[0]=1&a[1]=2', + with_empty_keys: { '': ['a', 'b'], a: ['1', '2'] }, + no_empty_keys: { 0: 'a', 1: 'b', a: ['1', '2'] }, + stringify_output: { + brackets: '[]=a&[]=b&a[]=1&a[]=2', + indices: '[0]=a&[1]=b&a[0]=1&a[1]=2', + repeat: '=a&=b&a=1&a=2', + }, + }, + { + input: '[deep]=a&[deep]=2', + with_empty_keys: { '': { deep: ['a', '2'] } }, + stringify_output: { + brackets: '[deep][]=a&[deep][]=2', + indices: '[deep][0]=a&[deep][1]=2', + repeat: '[deep]=a&[deep]=2', + }, + no_empty_keys: { deep: ['a', '2'] }, + }, + { + input: '%5B0%5D=a&%5B1%5D=b', + with_empty_keys: { '': ['a', 'b'] }, + stringify_output: { + brackets: '[]=a&[]=b', + indices: '[0]=a&[1]=b', + repeat: '=a&=b', + }, + no_empty_keys: { 0: 'a', 1: 'b' }, + }, +] satisfies { + input: string; + with_empty_keys: Record; + stringify_output: { + brackets: string; + indices: string; + repeat: string; + }; + no_empty_keys: Record; +}[]; diff --git a/tests/qs/stringify.test.ts b/tests/qs/stringify.test.ts new file mode 100644 index 00000000..fb24c153 --- /dev/null +++ b/tests/qs/stringify.test.ts @@ -0,0 +1,2232 @@ +import iconv from 'iconv-lite'; +import { stringify } from '@mux/mux-node/internal/qs'; +import { encode } from '@mux/mux-node/internal/qs/utils'; +import { StringifyOptions } from '@mux/mux-node/internal/qs/types'; +import { empty_test_cases } from './empty-keys-cases'; +import assert from 'assert'; + +describe('stringify()', function () { + test('stringifies a querystring object', function () { + expect(stringify({ a: 'b' })).toBe('a=b'); + expect(stringify({ a: 1 })).toBe('a=1'); + expect(stringify({ a: 1, b: 2 })).toBe('a=1&b=2'); + expect(stringify({ a: 'A_Z' })).toBe('a=A_Z'); + expect(stringify({ a: '€' })).toBe('a=%E2%82%AC'); + expect(stringify({ a: '' })).toBe('a=%EE%80%80'); + expect(stringify({ a: 'א' })).toBe('a=%D7%90'); + expect(stringify({ a: '𐐷' })).toBe('a=%F0%90%90%B7'); + }); + + test('stringifies falsy values', function () { + expect(stringify(undefined)).toBe(''); + expect(stringify(null)).toBe(''); + expect(stringify(null, { strictNullHandling: true })).toBe(''); + expect(stringify(false)).toBe(''); + expect(stringify(0)).toBe(''); + }); + + test('stringifies symbols', function () { + expect(stringify(Symbol.iterator)).toBe(''); + expect(stringify([Symbol.iterator])).toBe('0=Symbol%28Symbol.iterator%29'); + expect(stringify({ a: Symbol.iterator })).toBe('a=Symbol%28Symbol.iterator%29'); + expect(stringify({ a: [Symbol.iterator] }, { encodeValuesOnly: true, arrayFormat: 'brackets' })).toBe( + 'a[]=Symbol%28Symbol.iterator%29', + ); + }); + + test('stringifies bigints', function () { + var three = BigInt(3); + // @ts-expect-error + var encodeWithN = function (value, defaultEncoder, charset) { + var result = defaultEncoder(value, defaultEncoder, charset); + return typeof value === 'bigint' ? result + 'n' : result; + }; + + expect(stringify(three)).toBe(''); + expect(stringify([three])).toBe('0=3'); + expect(stringify([three], { encoder: encodeWithN })).toBe('0=3n'); + expect(stringify({ a: three })).toBe('a=3'); + expect(stringify({ a: three }, { encoder: encodeWithN })).toBe('a=3n'); + expect(stringify({ a: [three] }, { encodeValuesOnly: true, arrayFormat: 'brackets' })).toBe('a[]=3'); + expect( + stringify({ a: [three] }, { encodeValuesOnly: true, encoder: encodeWithN, arrayFormat: 'brackets' }), + ).toBe('a[]=3n'); + }); + + test('encodes dot in key of object when encodeDotInKeys and allowDots is provided', function () { + expect( + stringify({ 'name.obj': { first: 'John', last: 'Doe' } }, { allowDots: false, encodeDotInKeys: false }), + ).toBe('name.obj%5Bfirst%5D=John&name.obj%5Blast%5D=Doe'); + expect( + stringify({ 'name.obj': { first: 'John', last: 'Doe' } }, { allowDots: true, encodeDotInKeys: false }), + ).toBe('name.obj.first=John&name.obj.last=Doe'); + expect( + stringify({ 'name.obj': { first: 'John', last: 'Doe' } }, { allowDots: false, encodeDotInKeys: true }), + ).toBe('name%252Eobj%5Bfirst%5D=John&name%252Eobj%5Blast%5D=Doe'); + expect( + stringify({ 'name.obj': { first: 'John', last: 'Doe' } }, { allowDots: true, encodeDotInKeys: true }), + ).toBe('name%252Eobj.first=John&name%252Eobj.last=Doe'); + + // st.equal( + // stringify( + // { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + // { allowDots: false, encodeDotInKeys: false }, + // ), + // 'name.obj.subobject%5Bfirst.godly.name%5D=John&name.obj.subobject%5Blast%5D=Doe', + // 'with allowDots false and encodeDotInKeys false', + // ); + // st.equal( + // stringify( + // { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + // { allowDots: true, encodeDotInKeys: false }, + // ), + // 'name.obj.subobject.first.godly.name=John&name.obj.subobject.last=Doe', + // 'with allowDots false and encodeDotInKeys false', + // ); + // st.equal( + // stringify( + // { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + // { allowDots: false, encodeDotInKeys: true }, + // ), + // 'name%252Eobj%252Esubobject%5Bfirst.godly.name%5D=John&name%252Eobj%252Esubobject%5Blast%5D=Doe', + // 'with allowDots false and encodeDotInKeys true', + // ); + // st.equal( + // stringify( + // { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + // { allowDots: true, encodeDotInKeys: true }, + // ), + // 'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe', + // 'with allowDots true and encodeDotInKeys true', + // ); + expect( + stringify( + { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + { allowDots: false, encodeDotInKeys: false }, + ), + ).toBe('name.obj.subobject%5Bfirst.godly.name%5D=John&name.obj.subobject%5Blast%5D=Doe'); + expect( + stringify( + { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + { allowDots: true, encodeDotInKeys: false }, + ), + ).toBe('name.obj.subobject.first.godly.name=John&name.obj.subobject.last=Doe'); + expect( + stringify( + { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + { allowDots: false, encodeDotInKeys: true }, + ), + ).toBe('name%252Eobj%252Esubobject%5Bfirst.godly.name%5D=John&name%252Eobj%252Esubobject%5Blast%5D=Doe'); + expect( + stringify( + { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + { allowDots: true, encodeDotInKeys: true }, + ), + ).toBe('name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe'); + }); + + test('should encode dot in key of object, and automatically set allowDots to `true` when encodeDotInKeys is true and allowDots in undefined', function () { + // st.equal( + // stringify( + // { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + // { encodeDotInKeys: true }, + // ), + // 'name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe', + // 'with allowDots undefined and encodeDotInKeys true', + // ); + expect( + stringify( + { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + { encodeDotInKeys: true }, + ), + ).toBe('name%252Eobj%252Esubobject.first%252Egodly%252Ename=John&name%252Eobj%252Esubobject.last=Doe'); + }); + + test('should encode dot in key of object when encodeDotInKeys and allowDots is provided, and nothing else when encodeValuesOnly is provided', function () { + // st.equal( + // stringify( + // { 'name.obj': { first: 'John', last: 'Doe' } }, + // { + // encodeDotInKeys: true, + // allowDots: true, + // encodeValuesOnly: true, + // }, + // ), + // 'name%2Eobj.first=John&name%2Eobj.last=Doe', + // ); + expect( + stringify( + { 'name.obj': { first: 'John', last: 'Doe' } }, + { + encodeDotInKeys: true, + allowDots: true, + encodeValuesOnly: true, + }, + ), + ).toBe('name%2Eobj.first=John&name%2Eobj.last=Doe'); + + // st.equal( + // stringify( + // { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + // { allowDots: true, encodeDotInKeys: true, encodeValuesOnly: true }, + // ), + // 'name%2Eobj%2Esubobject.first%2Egodly%2Ename=John&name%2Eobj%2Esubobject.last=Doe', + // ); + expect( + stringify( + { 'name.obj.subobject': { 'first.godly.name': 'John', last: 'Doe' } }, + { allowDots: true, encodeDotInKeys: true, encodeValuesOnly: true }, + ), + ).toBe('name%2Eobj%2Esubobject.first%2Egodly%2Ename=John&name%2Eobj%2Esubobject.last=Doe'); + }); + + test('throws when `commaRoundTrip` is not a boolean', function () { + // st['throws']( + // function () { + // stringify({}, { commaRoundTrip: 'not a boolean' }); + // }, + // TypeError, + // 'throws when `commaRoundTrip` is not a boolean', + // ); + expect(() => { + // @ts-expect-error + stringify({}, { commaRoundTrip: 'not a boolean' }); + }).toThrow(TypeError); + }); + + test('throws when `encodeDotInKeys` is not a boolean', function () { + // st['throws'](function () { + // stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 'foobar' }); + // }, TypeError); + expect(() => { + // @ts-expect-error + stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 'foobar' }); + }).toThrow(TypeError); + + // st['throws'](function () { + // stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 0 }); + // }, TypeError); + expect(() => { + // @ts-expect-error + stringify({ a: [], b: 'zz' }, { encodeDotInKeys: 0 }); + }).toThrow(TypeError); + + // st['throws'](function () { + // stringify({ a: [], b: 'zz' }, { encodeDotInKeys: NaN }); + // }, TypeError); + expect(() => { + // @ts-expect-error + stringify({ a: [], b: 'zz' }, { encodeDotInKeys: NaN }); + }).toThrow(TypeError); + + // st['throws'](function () { + // stringify({ a: [], b: 'zz' }, { encodeDotInKeys: null }); + // }, TypeError); + expect(() => { + // @ts-expect-error + stringify({ a: [], b: 'zz' }, { encodeDotInKeys: null }); + }).toThrow(TypeError); + }); + + test('adds query prefix', function () { + // st.equal(stringify({ a: 'b' }, { addQueryPrefix: true }), '?a=b'); + expect(stringify({ a: 'b' }, { addQueryPrefix: true })).toBe('?a=b'); + }); + + test('with query prefix, outputs blank string given an empty object', function () { + // st.equal(stringify({}, { addQueryPrefix: true }), ''); + expect(stringify({}, { addQueryPrefix: true })).toBe(''); + }); + + test('stringifies nested falsy values', function () { + // st.equal(stringify({ a: { b: { c: null } } }), 'a%5Bb%5D%5Bc%5D='); + // st.equal( + // stringify({ a: { b: { c: null } } }, { strictNullHandling: true }), + // 'a%5Bb%5D%5Bc%5D', + // ); + // st.equal(stringify({ a: { b: { c: false } } }), 'a%5Bb%5D%5Bc%5D=false'); + expect(stringify({ a: { b: { c: null } } })).toBe('a%5Bb%5D%5Bc%5D='); + expect(stringify({ a: { b: { c: null } } }, { strictNullHandling: true })).toBe('a%5Bb%5D%5Bc%5D'); + expect(stringify({ a: { b: { c: false } } })).toBe('a%5Bb%5D%5Bc%5D=false'); + }); + + test('stringifies a nested object', function () { + // st.equal(stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c'); + // st.equal(stringify({ a: { b: { c: { d: 'e' } } } }), 'a%5Bb%5D%5Bc%5D%5Bd%5D=e'); + expect(stringify({ a: { b: 'c' } })).toBe('a%5Bb%5D=c'); + expect(stringify({ a: { b: { c: { d: 'e' } } } })).toBe('a%5Bb%5D%5Bc%5D%5Bd%5D=e'); + }); + + test('`allowDots` option: stringifies a nested object with dots notation', function () { + // st.equal(stringify({ a: { b: 'c' } }, { allowDots: true }), 'a.b=c'); + // st.equal(stringify({ a: { b: { c: { d: 'e' } } } }, { allowDots: true }), 'a.b.c.d=e'); + expect(stringify({ a: { b: 'c' } }, { allowDots: true })).toBe('a.b=c'); + expect(stringify({ a: { b: { c: { d: 'e' } } } }, { allowDots: true })).toBe('a.b.c.d=e'); + }); + + test('stringifies an array value', function () { + // st.equal( + // stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'indices' }), + // 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d', + // 'indices => indices', + // ); + // st.equal( + // stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'brackets' }), + // 'a%5B%5D=b&a%5B%5D=c&a%5B%5D=d', + // 'brackets => brackets', + // ); + // st.equal( + // stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'comma' }), + // 'a=b%2Cc%2Cd', + // 'comma => comma', + // ); + // st.equal( + // stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'comma', commaRoundTrip: true }), + // 'a=b%2Cc%2Cd', + // 'comma round trip => comma', + // ); + // st.equal( + // stringify({ a: ['b', 'c', 'd'] }), + // 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d', + // 'default => indices', + // ); + expect(stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'indices' })).toBe( + 'a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d', + ); + expect(stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'brackets' })).toBe( + 'a%5B%5D=b&a%5B%5D=c&a%5B%5D=d', + ); + expect(stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'comma' })).toBe('a=b%2Cc%2Cd'); + expect(stringify({ a: ['b', 'c', 'd'] }, { arrayFormat: 'comma', commaRoundTrip: true })).toBe( + 'a=b%2Cc%2Cd', + ); + expect(stringify({ a: ['b', 'c', 'd'] })).toBe('a%5B0%5D=b&a%5B1%5D=c&a%5B2%5D=d'); + }); + + test('`skipNulls` option', function () { + // st.equal( + // stringify({ a: 'b', c: null }, { skipNulls: true }), + // 'a=b', + // 'omits nulls when asked', + // ); + expect(stringify({ a: 'b', c: null }, { skipNulls: true })).toBe('a=b'); + + // st.equal( + // stringify({ a: { b: 'c', d: null } }, { skipNulls: true }), + // 'a%5Bb%5D=c', + // 'omits nested nulls when asked', + // ); + expect(stringify({ a: { b: 'c', d: null } }, { skipNulls: true })).toBe('a%5Bb%5D=c'); + }); + + test('omits array indices when asked', function () { + // st.equal(stringify({ a: ['b', 'c', 'd'] }, { indices: false }), 'a=b&a=c&a=d'); + expect(stringify({ a: ['b', 'c', 'd'] }, { indices: false })).toBe('a=b&a=c&a=d'); + }); + + test('omits object key/value pair when value is empty array', function () { + // st.equal(stringify({ a: [], b: 'zz' }), 'b=zz'); + expect(stringify({ a: [], b: 'zz' })).toBe('b=zz'); + }); + + test('should not omit object key/value pair when value is empty array and when asked', function () { + // st.equal(stringify({ a: [], b: 'zz' }), 'b=zz'); + // st.equal(stringify({ a: [], b: 'zz' }, { allowEmptyArrays: false }), 'b=zz'); + // st.equal(stringify({ a: [], b: 'zz' }, { allowEmptyArrays: true }), 'a[]&b=zz'); + expect(stringify({ a: [], b: 'zz' })).toBe('b=zz'); + expect(stringify({ a: [], b: 'zz' }, { allowEmptyArrays: false })).toBe('b=zz'); + expect(stringify({ a: [], b: 'zz' }, { allowEmptyArrays: true })).toBe('a[]&b=zz'); + }); + + test('should throw when allowEmptyArrays is not of type boolean', function () { + // st['throws'](function () { + // stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 'foobar' }); + // }, TypeError); + expect(() => { + // @ts-expect-error + stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 'foobar' }); + }).toThrow(TypeError); + + // st['throws'](function () { + // stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 0 }); + // }, TypeError); + expect(() => { + // @ts-expect-error + stringify({ a: [], b: 'zz' }, { allowEmptyArrays: 0 }); + }).toThrow(TypeError); + + // st['throws'](function () { + // stringify({ a: [], b: 'zz' }, { allowEmptyArrays: NaN }); + // }, TypeError); + expect(() => { + // @ts-expect-error + stringify({ a: [], b: 'zz' }, { allowEmptyArrays: NaN }); + }).toThrow(TypeError); + + // st['throws'](function () { + // stringify({ a: [], b: 'zz' }, { allowEmptyArrays: null }); + // }, TypeError); + expect(() => { + // @ts-expect-error + stringify({ a: [], b: 'zz' }, { allowEmptyArrays: null }); + }).toThrow(TypeError); + }); + + test('allowEmptyArrays + strictNullHandling', function () { + // st.equal( + // stringify({ testEmptyArray: [] }, { strictNullHandling: true, allowEmptyArrays: true }), + // 'testEmptyArray[]', + // ); + expect(stringify({ testEmptyArray: [] }, { strictNullHandling: true, allowEmptyArrays: true })).toBe( + 'testEmptyArray[]', + ); + }); + + describe('stringifies an array value with one item vs multiple items', function () { + test('non-array item', function () { + // s2t.equal( + // stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'indices' }), + // 'a=c', + // ); + // s2t.equal( + // stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), + // 'a=c', + // ); + // s2t.equal(stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'comma' }), 'a=c'); + // s2t.equal(stringify({ a: 'c' }, { encodeValuesOnly: true }), 'a=c'); + expect(stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'indices' })).toBe('a=c'); + expect(stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'brackets' })).toBe('a=c'); + expect(stringify({ a: 'c' }, { encodeValuesOnly: true, arrayFormat: 'comma' })).toBe('a=c'); + expect(stringify({ a: 'c' }, { encodeValuesOnly: true })).toBe('a=c'); + }); + + test('array with a single item', function () { + // s2t.equal( + // stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), + // 'a[0]=c', + // ); + // s2t.equal( + // stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), + // 'a[]=c', + // ); + // s2t.equal( + // stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), + // 'a=c', + // ); + // s2t.equal( + // stringify( + // { a: ['c'] }, + // { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }, + // ), + // 'a[]=c', + // ); // so it parses back as an array + // s2t.equal(stringify({ a: ['c'] }, { encodeValuesOnly: true }), 'a[0]=c'); + expect(stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'indices' })).toBe('a[0]=c'); + expect(stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' })).toBe('a[]=c'); + expect(stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma' })).toBe('a=c'); + expect( + stringify({ a: ['c'] }, { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }), + ).toBe('a[]=c'); + expect(stringify({ a: ['c'] }, { encodeValuesOnly: true })).toBe('a[0]=c'); + }); + + test('array with multiple items', function () { + // s2t.equal( + // stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), + // 'a[0]=c&a[1]=d', + // ); + // s2t.equal( + // stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), + // 'a[]=c&a[]=d', + // ); + // s2t.equal( + // stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), + // 'a=c,d', + // ); + // s2t.equal( + // stringify( + // { a: ['c', 'd'] }, + // { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }, + // ), + // 'a=c,d', + // ); + // s2t.equal(stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true }), 'a[0]=c&a[1]=d'); + expect(stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'indices' })).toBe( + 'a[0]=c&a[1]=d', + ); + expect(stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' })).toBe( + 'a[]=c&a[]=d', + ); + expect(stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma' })).toBe('a=c,d'); + expect( + stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }), + ).toBe('a=c,d'); + expect(stringify({ a: ['c', 'd'] }, { encodeValuesOnly: true })).toBe('a[0]=c&a[1]=d'); + }); + + test('array with multiple items with a comma inside', function () { + // s2t.equal( + // stringify({ a: ['c,d', 'e'] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), + // 'a=c%2Cd,e', + // ); + // s2t.equal(stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma' }), 'a=c%2Cd%2Ce'); + expect(stringify({ a: ['c,d', 'e'] }, { encodeValuesOnly: true, arrayFormat: 'comma' })).toBe( + 'a=c%2Cd,e', + ); + expect(stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma' })).toBe('a=c%2Cd%2Ce'); + + // s2t.equal( + // stringify( + // { a: ['c,d', 'e'] }, + // { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }, + // ), + // 'a=c%2Cd,e', + // ); + // s2t.equal( + // stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma', commaRoundTrip: true }), + // 'a=c%2Cd%2Ce', + // ); + expect( + stringify( + { a: ['c,d', 'e'] }, + { encodeValuesOnly: true, arrayFormat: 'comma', commaRoundTrip: true }, + ), + ).toBe('a=c%2Cd,e'); + expect(stringify({ a: ['c,d', 'e'] }, { arrayFormat: 'comma', commaRoundTrip: true })).toBe( + 'a=c%2Cd%2Ce', + ); + }); + }); + + test('stringifies a nested array value', function () { + expect(stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'indices' })).toBe( + 'a[b][0]=c&a[b][1]=d', + ); + expect(stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' })).toBe( + 'a[b][]=c&a[b][]=d', + ); + expect(stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true, arrayFormat: 'comma' })).toBe( + 'a[b]=c,d', + ); + expect(stringify({ a: { b: ['c', 'd'] } }, { encodeValuesOnly: true })).toBe('a[b][0]=c&a[b][1]=d'); + }); + + test('stringifies comma and empty array values', function () { + // st.equal( + // stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'indices' }), + // 'a[0]=,&a[1]=&a[2]=c,d%', + // ); + // st.equal( + // stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'brackets' }), + // 'a[]=,&a[]=&a[]=c,d%', + // ); + // st.equal( + // stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'comma' }), + // 'a=,,,c,d%', + // ); + // st.equal( + // stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'repeat' }), + // 'a=,&a=&a=c,d%', + // ); + expect(stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'indices' })).toBe( + 'a[0]=,&a[1]=&a[2]=c,d%', + ); + expect(stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'brackets' })).toBe( + 'a[]=,&a[]=&a[]=c,d%', + ); + expect(stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'comma' })).toBe('a=,,,c,d%'); + expect(stringify({ a: [',', '', 'c,d%'] }, { encode: false, arrayFormat: 'repeat' })).toBe( + 'a=,&a=&a=c,d%', + ); + + // st.equal( + // stringify( + // { a: [',', '', 'c,d%'] }, + // { encode: true, encodeValuesOnly: true, arrayFormat: 'indices' }, + // ), + // 'a[0]=%2C&a[1]=&a[2]=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: [',', '', 'c,d%'] }, + // { encode: true, encodeValuesOnly: true, arrayFormat: 'brackets' }, + // ), + // 'a[]=%2C&a[]=&a[]=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: [',', '', 'c,d%'] }, + // { encode: true, encodeValuesOnly: true, arrayFormat: 'comma' }, + // ), + // 'a=%2C,,c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: [',', '', 'c,d%'] }, + // { encode: true, encodeValuesOnly: true, arrayFormat: 'repeat' }, + // ), + // 'a=%2C&a=&a=c%2Cd%25', + // ); + expect( + stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'indices' }), + ).toBe('a%5B0%5D=%2C&a%5B1%5D=&a%5B2%5D=c%2Cd%25'); + expect( + stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'brackets' }), + ).toBe('a[]=%2C&a[]=&a[]=c%2Cd%25'); + expect( + stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'comma' }), + ).toBe('a=%2C%2C%2Cc%2Cd%25'); + expect( + stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }), + ).toBe('a=%2C&a=&a=c%2Cd%25'); + + // st.equal( + // stringify( + // { a: [',', '', 'c,d%'] }, + // { encode: true, encodeValuesOnly: false, arrayFormat: 'indices' }, + // ), + // 'a%5B0%5D=%2C&a%5B1%5D=&a%5B2%5D=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: [',', '', 'c,d%'] }, + // { encode: true, encodeValuesOnly: false, arrayFormat: 'brackets' }, + // ), + // 'a%5B%5D=%2C&a%5B%5D=&a%5B%5D=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: [',', '', 'c,d%'] }, + // { encode: true, encodeValuesOnly: false, arrayFormat: 'comma' }, + // ), + // 'a=%2C%2C%2Cc%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: [',', '', 'c,d%'] }, + // { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }, + // ), + // 'a=%2C&a=&a=c%2Cd%25', + // ); + expect( + stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }), + ).toBe('a=%2C&a=&a=c%2Cd%25'); + expect( + stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'indices' }), + ).toBe('a%5B0%5D=%2C&a%5B1%5D=&a%5B2%5D=c%2Cd%25'); + expect( + stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: true, arrayFormat: 'brackets' }), + ).toBe('a[]=%2C&a[]=&a[]=c%2Cd%25'); + expect( + stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'comma' }), + ).toBe('a=%2C%2C%2Cc%2Cd%25'); + expect( + stringify({ a: [',', '', 'c,d%'] }, { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }), + ).toBe('a=%2C&a=&a=c%2Cd%25'); + }); + + test('stringifies comma and empty non-array values', function () { + // st.equal( + // stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'indices' }), + // 'a=,&b=&c=c,d%', + // ); + // st.equal( + // stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'brackets' }), + // 'a=,&b=&c=c,d%', + // ); + // st.equal( + // stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'comma' }), + // 'a=,&b=&c=c,d%', + // ); + // st.equal( + // stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'repeat' }), + // 'a=,&b=&c=c,d%', + // ); + expect(stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'indices' })).toBe( + 'a=,&b=&c=c,d%', + ); + expect(stringify({ a: ',', b: '', c: 'c,d%' }, { encode: false, arrayFormat: 'brackets' })).toBe( + 'a=,&b=&c=c,d%', + ); + + // st.equal( + // stringify( + // { a: ',', b: '', c: 'c,d%' }, + // { encode: true, encodeValuesOnly: true, arrayFormat: 'indices' }, + // ), + // 'a=%2C&b=&c=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: ',', b: '', c: 'c,d%' }, + // { encode: true, encodeValuesOnly: true, arrayFormat: 'brackets' }, + // ), + // 'a=%2C&b=&c=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: ',', b: '', c: 'c,d%' }, + // { encode: true, encodeValuesOnly: true, arrayFormat: 'comma' }, + // ), + // 'a=%2C&b=&c=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: ',', b: '', c: 'c,d%' }, + // { encode: true, encodeValuesOnly: true, arrayFormat: 'repeat' }, + // ), + // 'a=%2C&b=&c=c%2Cd%25', + // ); + expect( + stringify( + { a: ',', b: '', c: 'c,d%' }, + { encode: true, encodeValuesOnly: true, arrayFormat: 'indices' }, + ), + ).toBe('a=%2C&b=&c=c%2Cd%25'); + expect( + stringify( + { a: ',', b: '', c: 'c,d%' }, + { encode: true, encodeValuesOnly: true, arrayFormat: 'brackets' }, + ), + ).toBe('a=%2C&b=&c=c%2Cd%25'); + expect( + stringify({ a: ',', b: '', c: 'c,d%' }, { encode: true, encodeValuesOnly: true, arrayFormat: 'comma' }), + ).toBe('a=%2C&b=&c=c%2Cd%25'); + expect( + stringify( + { a: ',', b: '', c: 'c,d%' }, + { encode: true, encodeValuesOnly: true, arrayFormat: 'repeat' }, + ), + ).toBe('a=%2C&b=&c=c%2Cd%25'); + + // st.equal( + // stringify( + // { a: ',', b: '', c: 'c,d%' }, + // { encode: true, encodeValuesOnly: false, arrayFormat: 'indices' }, + // ), + // 'a=%2C&b=&c=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: ',', b: '', c: 'c,d%' }, + // { encode: true, encodeValuesOnly: false, arrayFormat: 'brackets' }, + // ), + // 'a=%2C&b=&c=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: ',', b: '', c: 'c,d%' }, + // { encode: true, encodeValuesOnly: false, arrayFormat: 'comma' }, + // ), + // 'a=%2C&b=&c=c%2Cd%25', + // ); + // st.equal( + // stringify( + // { a: ',', b: '', c: 'c,d%' }, + // { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }, + // ), + // 'a=%2C&b=&c=c%2Cd%25', + // ); + expect( + stringify( + { a: ',', b: '', c: 'c,d%' }, + { encode: true, encodeValuesOnly: false, arrayFormat: 'indices' }, + ), + ).toBe('a=%2C&b=&c=c%2Cd%25'); + expect( + stringify( + { a: ',', b: '', c: 'c,d%' }, + { encode: true, encodeValuesOnly: false, arrayFormat: 'brackets' }, + ), + ).toBe('a=%2C&b=&c=c%2Cd%25'); + expect( + stringify( + { a: ',', b: '', c: 'c,d%' }, + { encode: true, encodeValuesOnly: false, arrayFormat: 'comma' }, + ), + ).toBe('a=%2C&b=&c=c%2Cd%25'); + expect( + stringify( + { a: ',', b: '', c: 'c,d%' }, + { encode: true, encodeValuesOnly: false, arrayFormat: 'repeat' }, + ), + ).toBe('a=%2C&b=&c=c%2Cd%25'); + }); + + test('stringifies a nested array value with dots notation', function () { + // st.equal( + // stringify( + // { a: { b: ['c', 'd'] } }, + // { allowDots: true, encodeValuesOnly: true, arrayFormat: 'indices' }, + // ), + // 'a.b[0]=c&a.b[1]=d', + // 'indices: stringifies with dots + indices', + // ); + // st.equal( + // stringify( + // { a: { b: ['c', 'd'] } }, + // { allowDots: true, encodeValuesOnly: true, arrayFormat: 'brackets' }, + // ), + // 'a.b[]=c&a.b[]=d', + // 'brackets: stringifies with dots + brackets', + // ); + // st.equal( + // stringify( + // { a: { b: ['c', 'd'] } }, + // { allowDots: true, encodeValuesOnly: true, arrayFormat: 'comma' }, + // ), + // 'a.b=c,d', + // 'comma: stringifies with dots + comma', + // ); + // st.equal( + // stringify({ a: { b: ['c', 'd'] } }, { allowDots: true, encodeValuesOnly: true }), + // 'a.b[0]=c&a.b[1]=d', + // 'default: stringifies with dots + indices', + // ); + expect( + stringify( + { a: { b: ['c', 'd'] } }, + { allowDots: true, encodeValuesOnly: true, arrayFormat: 'indices' }, + ), + ).toBe('a.b[0]=c&a.b[1]=d'); + expect( + stringify( + { a: { b: ['c', 'd'] } }, + { allowDots: true, encodeValuesOnly: true, arrayFormat: 'brackets' }, + ), + ).toBe('a.b[]=c&a.b[]=d'); + expect( + stringify({ a: { b: ['c', 'd'] } }, { allowDots: true, encodeValuesOnly: true, arrayFormat: 'comma' }), + ).toBe('a.b=c,d'); + expect(stringify({ a: { b: ['c', 'd'] } }, { allowDots: true, encodeValuesOnly: true })).toBe( + 'a.b[0]=c&a.b[1]=d', + ); + }); + + test('stringifies an object inside an array', function () { + // st.equal( + // stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices', encodeValuesOnly: true }), + // 'a[0][b]=c', + // 'indices => indices', + // ); + // st.equal( + // stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'repeat', encodeValuesOnly: true }), + // 'a[b]=c', + // 'repeat => repeat', + // ); + // st.equal( + // stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets', encodeValuesOnly: true }), + // 'a[][b]=c', + // 'brackets => brackets', + // ); + // st.equal( + // stringify({ a: [{ b: 'c' }] }, { encodeValuesOnly: true }), + // 'a[0][b]=c', + // 'default => indices', + // ); + expect(stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'indices', encodeValuesOnly: true })).toBe( + 'a[0][b]=c', + ); + expect(stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'repeat', encodeValuesOnly: true })).toBe('a[b]=c'); + expect(stringify({ a: [{ b: 'c' }] }, { arrayFormat: 'brackets', encodeValuesOnly: true })).toBe( + 'a[][b]=c', + ); + expect(stringify({ a: [{ b: 'c' }] }, { encodeValuesOnly: true })).toBe('a[0][b]=c'); + + // st.equal( + // stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices', encodeValuesOnly: true }), + // 'a[0][b][c][0]=1', + // 'indices => indices', + // ); + // st.equal( + // stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'repeat', encodeValuesOnly: true }), + // 'a[b][c]=1', + // 'repeat => repeat', + // ); + // st.equal( + // stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets', encodeValuesOnly: true }), + // 'a[][b][c][]=1', + // 'brackets => brackets', + // ); + // st.equal( + // stringify({ a: [{ b: { c: [1] } }] }, { encodeValuesOnly: true }), + // 'a[0][b][c][0]=1', + // 'default => indices', + // ); + expect(stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'indices', encodeValuesOnly: true })).toBe( + 'a[0][b][c][0]=1', + ); + expect(stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'repeat', encodeValuesOnly: true })).toBe( + 'a[b][c]=1', + ); + expect(stringify({ a: [{ b: { c: [1] } }] }, { arrayFormat: 'brackets', encodeValuesOnly: true })).toBe( + 'a[][b][c][]=1', + ); + expect(stringify({ a: [{ b: { c: [1] } }] }, { encodeValuesOnly: true })).toBe('a[0][b][c][0]=1'); + }); + + test('stringifies an array with mixed objects and primitives', function () { + // st.equal( + // stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), + // 'a[0][b]=1&a[1]=2&a[2]=3', + // 'indices => indices', + // ); + // st.equal( + // stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), + // 'a[][b]=1&a[]=2&a[]=3', + // 'brackets => brackets', + // ); + // st.equal( + // stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), + // '???', + // 'brackets => brackets', + // { skip: 'TODO: figure out what this should do' }, + // ); + // st.equal( + // stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true }), + // 'a[0][b]=1&a[1]=2&a[2]=3', + // 'default => indices', + // ); + expect(stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'indices' })).toBe( + 'a[0][b]=1&a[1]=2&a[2]=3', + ); + expect(stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'brackets' })).toBe( + 'a[][b]=1&a[]=2&a[]=3', + ); + // !Skipped: Figure out what this should do + // expect( + // stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true, arrayFormat: 'comma' }), + // ).toBe('???'); + expect(stringify({ a: [{ b: 1 }, 2, 3] }, { encodeValuesOnly: true })).toBe('a[0][b]=1&a[1]=2&a[2]=3'); + }); + + test('stringifies an object inside an array with dots notation', function () { + // st.equal( + // stringify({ a: [{ b: 'c' }] }, { allowDots: true, encode: false, arrayFormat: 'indices' }), + // 'a[0].b=c', + // 'indices => indices', + // ); + // st.equal( + // stringify( + // { a: [{ b: 'c' }] }, + // { allowDots: true, encode: false, arrayFormat: 'brackets' }, + // ), + // 'a[].b=c', + // 'brackets => brackets', + // ); + // st.equal( + // stringify({ a: [{ b: 'c' }] }, { allowDots: true, encode: false }), + // 'a[0].b=c', + // 'default => indices', + // ); + expect(stringify({ a: [{ b: 'c' }] }, { allowDots: true, encode: false, arrayFormat: 'indices' })).toBe( + 'a[0].b=c', + ); + expect(stringify({ a: [{ b: 'c' }] }, { allowDots: true, encode: false, arrayFormat: 'brackets' })).toBe( + 'a[].b=c', + ); + expect(stringify({ a: [{ b: 'c' }] }, { allowDots: true, encode: false })).toBe('a[0].b=c'); + + // st.equal( + // stringify( + // { a: [{ b: { c: [1] } }] }, + // { allowDots: true, encode: false, arrayFormat: 'indices' }, + // ), + // 'a[0].b.c[0]=1', + // 'indices => indices', + // ); + // st.equal( + // stringify( + // { a: [{ b: { c: [1] } }] }, + // { allowDots: true, encode: false, arrayFormat: 'brackets' }, + // ), + // 'a[].b.c[]=1', + // 'brackets => brackets', + // ); + // st.equal( + // stringify({ a: [{ b: { c: [1] } }] }, { allowDots: true, encode: false }), + // 'a[0].b.c[0]=1', + // 'default => indices', + // ); + expect( + stringify({ a: [{ b: { c: [1] } }] }, { allowDots: true, encode: false, arrayFormat: 'indices' }), + ).toBe('a[0].b.c[0]=1'); + expect( + stringify({ a: [{ b: { c: [1] } }] }, { allowDots: true, encode: false, arrayFormat: 'brackets' }), + ).toBe('a[].b.c[]=1'); + expect(stringify({ a: [{ b: { c: [1] } }] }, { allowDots: true, encode: false })).toBe('a[0].b.c[0]=1'); + }); + + test('does not omit object keys when indices = false', function () { + // st.equal(stringify({ a: [{ b: 'c' }] }, { indices: false }), 'a%5Bb%5D=c'); + expect(stringify({ a: [{ b: 'c' }] }, { indices: false })).toBe('a%5Bb%5D=c'); + }); + + test('uses indices notation for arrays when indices=true', function () { + // st.equal(stringify({ a: ['b', 'c'] }, { indices: true }), 'a%5B0%5D=b&a%5B1%5D=c'); + expect(stringify({ a: ['b', 'c'] }, { indices: true })).toBe('a%5B0%5D=b&a%5B1%5D=c'); + }); + + test('uses indices notation for arrays when no arrayFormat is specified', function () { + // st.equal(stringify({ a: ['b', 'c'] }), 'a%5B0%5D=b&a%5B1%5D=c'); + expect(stringify({ a: ['b', 'c'] })).toBe('a%5B0%5D=b&a%5B1%5D=c'); + }); + + test('uses indices notation for arrays when arrayFormat=indices', function () { + // st.equal(stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }), 'a%5B0%5D=b&a%5B1%5D=c'); + expect(stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })).toBe('a%5B0%5D=b&a%5B1%5D=c'); + }); + + test('uses repeat notation for arrays when arrayFormat=repeat', function () { + // st.equal(stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }), 'a=b&a=c'); + expect(stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })).toBe('a=b&a=c'); + }); + + test('uses brackets notation for arrays when arrayFormat=brackets', function () { + // st.equal(stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }), 'a%5B%5D=b&a%5B%5D=c'); + expect(stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })).toBe('a%5B%5D=b&a%5B%5D=c'); + }); + + test('stringifies a complicated object', function () { + // st.equal(stringify({ a: { b: 'c', d: 'e' } }), 'a%5Bb%5D=c&a%5Bd%5D=e'); + expect(stringify({ a: { b: 'c', d: 'e' } })).toBe('a%5Bb%5D=c&a%5Bd%5D=e'); + }); + + test('stringifies an empty value', function () { + // st.equal(stringify({ a: '' }), 'a='); + // st.equal(stringify({ a: null }, { strictNullHandling: true }), 'a'); + expect(stringify({ a: '' })).toBe('a='); + expect(stringify({ a: null }, { strictNullHandling: true })).toBe('a'); + + // st.equal(stringify({ a: '', b: '' }), 'a=&b='); + // st.equal(stringify({ a: null, b: '' }, { strictNullHandling: true }), 'a&b='); + expect(stringify({ a: '', b: '' })).toBe('a=&b='); + expect(stringify({ a: null, b: '' }, { strictNullHandling: true })).toBe('a&b='); + + // st.equal(stringify({ a: { b: '' } }), 'a%5Bb%5D='); + // st.equal(stringify({ a: { b: null } }, { strictNullHandling: true }), 'a%5Bb%5D'); + // st.equal(stringify({ a: { b: null } }, { strictNullHandling: false }), 'a%5Bb%5D='); + expect(stringify({ a: { b: '' } })).toBe('a%5Bb%5D='); + expect(stringify({ a: { b: null } }, { strictNullHandling: true })).toBe('a%5Bb%5D'); + expect(stringify({ a: { b: null } }, { strictNullHandling: false })).toBe('a%5Bb%5D='); + }); + + test('stringifies an empty array in different arrayFormat', function () { + // st.equal(stringify({ a: [], b: [null], c: 'c' }, { encode: false }), 'b[0]=&c=c'); + expect(stringify({ a: [], b: [null], c: 'c' }, { encode: false })).toBe('b[0]=&c=c'); + // arrayFormat default + // st.equal( + // stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices' }), + // 'b[0]=&c=c', + // ); + // st.equal( + // stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets' }), + // 'b[]=&c=c', + // ); + // st.equal( + // stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat' }), + // 'b=&c=c', + // ); + // st.equal( + // stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma' }), + // 'b=&c=c', + // ); + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'comma', commaRoundTrip: true }, + // ), + // 'b[]=&c=c', + // ); + expect(stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices' })).toBe( + 'b[0]=&c=c', + ); + expect(stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets' })).toBe( + 'b[]=&c=c', + ); + expect(stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat' })).toBe('b=&c=c'); + expect(stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma' })).toBe('b=&c=c'); + expect( + stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', commaRoundTrip: true }), + ).toBe('b[]=&c=c'); + + // with strictNullHandling + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'indices', strictNullHandling: true }, + // ), + // 'b[0]&c=c', + // ); + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'brackets', strictNullHandling: true }, + // ), + // 'b[]&c=c', + // ); + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'repeat', strictNullHandling: true }, + // ), + // 'b&c=c', + // ); + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'comma', strictNullHandling: true }, + // ), + // 'b&c=c', + // ); + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'comma', strictNullHandling: true, commaRoundTrip: true }, + // ), + // 'b[]&c=c', + // ); + + expect( + stringify( + { a: [], b: [null], c: 'c' }, + { encode: false, arrayFormat: 'indices', strictNullHandling: true }, + ), + ).toBe('b[0]&c=c'); + expect( + stringify( + { a: [], b: [null], c: 'c' }, + { encode: false, arrayFormat: 'brackets', strictNullHandling: true }, + ), + ).toBe('b[]&c=c'); + expect( + stringify( + { a: [], b: [null], c: 'c' }, + { encode: false, arrayFormat: 'repeat', strictNullHandling: true }, + ), + ).toBe('b&c=c'); + expect( + stringify( + { a: [], b: [null], c: 'c' }, + { encode: false, arrayFormat: 'comma', strictNullHandling: true }, + ), + ).toBe('b&c=c'); + expect( + stringify( + { a: [], b: [null], c: 'c' }, + { encode: false, arrayFormat: 'comma', strictNullHandling: true, commaRoundTrip: true }, + ), + ).toBe('b[]&c=c'); + + // with skipNulls + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'indices', skipNulls: true }, + // ), + // 'c=c', + // ); + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'brackets', skipNulls: true }, + // ), + // 'c=c', + // ); + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'repeat', skipNulls: true }, + // ), + // 'c=c', + // ); + // st.equal( + // stringify( + // { a: [], b: [null], c: 'c' }, + // { encode: false, arrayFormat: 'comma', skipNulls: true }, + // ), + // 'c=c', + // ); + expect( + stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'indices', skipNulls: true }), + ).toBe('c=c'); + expect( + stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'brackets', skipNulls: true }), + ).toBe('c=c'); + expect( + stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'repeat', skipNulls: true }), + ).toBe('c=c'); + expect( + stringify({ a: [], b: [null], c: 'c' }, { encode: false, arrayFormat: 'comma', skipNulls: true }), + ).toBe('c=c'); + }); + + test('stringifies a null object', function () { + var obj = Object.create(null); + obj.a = 'b'; + // st.equal(stringify(obj), 'a=b'); + expect(stringify(obj)).toBe('a=b'); + }); + + test('returns an empty string for invalid input', function () { + // st.equal(stringify(undefined), ''); + // st.equal(stringify(false), ''); + // st.equal(stringify(null), ''); + // st.equal(stringify(''), ''); + expect(stringify(undefined)).toBe(''); + expect(stringify(false)).toBe(''); + expect(stringify(null)).toBe(''); + expect(stringify('')).toBe(''); + }); + + test('stringifies an object with a null object as a child', function () { + var obj = { a: Object.create(null) }; + + obj.a.b = 'c'; + // st.equal(stringify(obj), 'a%5Bb%5D=c'); + expect(stringify(obj)).toBe('a%5Bb%5D=c'); + }); + + test('drops keys with a value of undefined', function () { + // st.equal(stringify({ a: undefined }), ''); + expect(stringify({ a: undefined })).toBe(''); + + // st.equal( + // stringify({ a: { b: undefined, c: null } }, { strictNullHandling: true }), + // 'a%5Bc%5D', + // ); + // st.equal( + // stringify({ a: { b: undefined, c: null } }, { strictNullHandling: false }), + // 'a%5Bc%5D=', + // ); + // st.equal(stringify({ a: { b: undefined, c: '' } }), 'a%5Bc%5D='); + expect(stringify({ a: { b: undefined, c: null } }, { strictNullHandling: true })).toBe('a%5Bc%5D'); + expect(stringify({ a: { b: undefined, c: null } }, { strictNullHandling: false })).toBe('a%5Bc%5D='); + expect(stringify({ a: { b: undefined, c: '' } })).toBe('a%5Bc%5D='); + }); + + test('url encodes values', function () { + // st.equal(stringify({ a: 'b c' }), 'a=b%20c'); + expect(stringify({ a: 'b c' })).toBe('a=b%20c'); + }); + + test('stringifies a date', function () { + var now = new Date(); + var str = 'a=' + encodeURIComponent(now.toISOString()); + // st.equal(stringify({ a: now }), str); + expect(stringify({ a: now })).toBe(str); + }); + + test('stringifies the weird object from qs', function () { + // st.equal( + // stringify({ 'my weird field': '~q1!2"\'w$5&7/z8)?' }), + // 'my%20weird%20field=~q1%212%22%27w%245%267%2Fz8%29%3F', + // ); + expect(stringify({ 'my weird field': '~q1!2"\'w$5&7/z8)?' })).toBe( + 'my%20weird%20field=~q1%212%22%27w%245%267%2Fz8%29%3F', + ); + }); + + // TODO: Investigate how to to intercept in vitest + // TODO(rob) + test('skips properties that are part of the object prototype', function () { + // st.intercept(Object.prototype, 'crash', { value: 'test' }); + // @ts-expect-error + Object.prototype.crash = 'test'; + + // st.equal(stringify({ a: 'b' }), 'a=b'); + // st.equal(stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c'); + expect(stringify({ a: 'b' })).toBe('a=b'); + expect(stringify({ a: { b: 'c' } })).toBe('a%5Bb%5D=c'); + }); + + test('stringifies boolean values', function () { + // st.equal(stringify({ a: true }), 'a=true'); + // st.equal(stringify({ a: { b: true } }), 'a%5Bb%5D=true'); + // st.equal(stringify({ b: false }), 'b=false'); + // st.equal(stringify({ b: { c: false } }), 'b%5Bc%5D=false'); + expect(stringify({ a: true })).toBe('a=true'); + expect(stringify({ a: { b: true } })).toBe('a%5Bb%5D=true'); + expect(stringify({ b: false })).toBe('b=false'); + expect(stringify({ b: { c: false } })).toBe('b%5Bc%5D=false'); + }); + + test('stringifies buffer values', function () { + // st.equal(stringify({ a: Buffer.from('test') }), 'a=test'); + // st.equal(stringify({ a: { b: Buffer.from('test') } }), 'a%5Bb%5D=test'); + }); + + test('stringifies an object using an alternative delimiter', function () { + // st.equal(stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d'); + expect(stringify({ a: 'b', c: 'd' }, { delimiter: ';' })).toBe('a=b;c=d'); + }); + + // We dont target environments which dont even have Buffer + // test('does not blow up when Buffer global is missing', function () { + // var restore = mockProperty(global, 'Buffer', { delete: true }); + + // var result = stringify({ a: 'b', c: 'd' }); + + // restore(); + + // st.equal(result, 'a=b&c=d'); + // st.end(); + // }); + + test('does not crash when parsing circular references', function () { + var a: any = {}; + a.b = a; + + // st['throws']( + // function () { + // stringify({ 'foo[bar]': 'baz', 'foo[baz]': a }); + // }, + // /RangeError: Cyclic object value/, + // 'cyclic values throw', + // ); + expect(() => { + stringify({ 'foo[bar]': 'baz', 'foo[baz]': a }); + }).toThrow('Cyclic object value'); + + var circular: any = { + a: 'value', + }; + circular.a = circular; + // st['throws']( + // function () { + // stringify(circular); + // }, + // /RangeError: Cyclic object value/, + // 'cyclic values throw', + // ); + expect(() => { + stringify(circular); + }).toThrow('Cyclic object value'); + + var arr = ['a']; + // st.doesNotThrow(function () { + // stringify({ x: arr, y: arr }); + // }, 'non-cyclic values do not throw'); + expect(() => { + stringify({ x: arr, y: arr }); + }).not.toThrow(); + }); + + test('non-circular duplicated references can still work', function () { + var hourOfDay = { + function: 'hour_of_day', + }; + + var p1 = { + function: 'gte', + arguments: [hourOfDay, 0], + }; + var p2 = { + function: 'lte', + arguments: [hourOfDay, 23], + }; + + // st.equal( + // stringify( + // { filters: { $and: [p1, p2] } }, + // { encodeValuesOnly: true, arrayFormat: 'indices' }, + // ), + // 'filters[$and][0][function]=gte&filters[$and][0][arguments][0][function]=hour_of_day&filters[$and][0][arguments][1]=0&filters[$and][1][function]=lte&filters[$and][1][arguments][0][function]=hour_of_day&filters[$and][1][arguments][1]=23', + // ); + // st.equal( + // stringify( + // { filters: { $and: [p1, p2] } }, + // { encodeValuesOnly: true, arrayFormat: 'brackets' }, + // ), + // 'filters[$and][][function]=gte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=0&filters[$and][][function]=lte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=23', + // ); + // st.equal( + // stringify( + // { filters: { $and: [p1, p2] } }, + // { encodeValuesOnly: true, arrayFormat: 'repeat' }, + // ), + // 'filters[$and][function]=gte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=0&filters[$and][function]=lte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=23', + // ); + expect( + stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'indices' }), + ).toBe( + 'filters[$and][0][function]=gte&filters[$and][0][arguments][0][function]=hour_of_day&filters[$and][0][arguments][1]=0&filters[$and][1][function]=lte&filters[$and][1][arguments][0][function]=hour_of_day&filters[$and][1][arguments][1]=23', + ); + expect( + stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), + ).toBe( + 'filters[$and][][function]=gte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=0&filters[$and][][function]=lte&filters[$and][][arguments][][function]=hour_of_day&filters[$and][][arguments][]=23', + ); + expect( + stringify({ filters: { $and: [p1, p2] } }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), + ).toBe( + 'filters[$and][function]=gte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=0&filters[$and][function]=lte&filters[$and][arguments][function]=hour_of_day&filters[$and][arguments]=23', + ); + }); + + test('selects properties when filter=array', function () { + // st.equal(stringify({ a: 'b' }, { filter: ['a'] }), 'a=b'); + // st.equal(stringify({ a: 1 }, { filter: [] }), ''); + expect(stringify({ a: 'b' }, { filter: ['a'] })).toBe('a=b'); + expect(stringify({ a: 1 }, { filter: [] })).toBe(''); + + // st.equal( + // stringify( + // { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, + // { filter: ['a', 'b', 0, 2], arrayFormat: 'indices' }, + // ), + // 'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3', + // 'indices => indices', + // ); + // st.equal( + // stringify( + // { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, + // { filter: ['a', 'b', 0, 2], arrayFormat: 'brackets' }, + // ), + // 'a%5Bb%5D%5B%5D=1&a%5Bb%5D%5B%5D=3', + // 'brackets => brackets', + // ); + // st.equal( + // stringify({ a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, { filter: ['a', 'b', 0, 2] }), + // 'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3', + // 'default => indices', + // ); + expect(stringify({ a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, { filter: ['a', 'b', 0, 2] })).toBe( + 'a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3', + ); + expect( + stringify( + { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, + { filter: ['a', 'b', 0, 2], arrayFormat: 'indices' }, + ), + ).toBe('a%5Bb%5D%5B0%5D=1&a%5Bb%5D%5B2%5D=3'); + expect( + stringify( + { a: { b: [1, 2, 3, 4], c: 'd' }, c: 'f' }, + { filter: ['a', 'b', 0, 2], arrayFormat: 'brackets' }, + ), + ).toBe('a%5Bb%5D%5B%5D=1&a%5Bb%5D%5B%5D=3'); + }); + + test('supports custom representations when filter=function', function () { + var calls = 0; + var obj = { a: 'b', c: 'd', e: { f: new Date(1257894000000) } }; + var filterFunc: StringifyOptions['filter'] = function (prefix, value) { + calls += 1; + if (calls === 1) { + // st.equal(prefix, '', 'prefix is empty'); + // st.equal(value, obj); + expect(prefix).toBe(''); + expect(value).toBe(obj); + } else if (prefix === 'c') { + return void 0; + } else if (value instanceof Date) { + // st.equal(prefix, 'e[f]'); + expect(prefix).toBe('e[f]'); + return value.getTime(); + } + return value; + }; + + // st.equal(stringify(obj, { filter: filterFunc }), 'a=b&e%5Bf%5D=1257894000000'); + // st.equal(calls, 5); + expect(stringify(obj, { filter: filterFunc })).toBe('a=b&e%5Bf%5D=1257894000000'); + expect(calls).toBe(5); + }); + + test('can disable uri encoding', function () { + // st.equal(stringify({ a: 'b' }, { encode: false }), 'a=b'); + // st.equal(stringify({ a: { b: 'c' } }, { encode: false }), 'a[b]=c'); + // st.equal( + // stringify({ a: 'b', c: null }, { strictNullHandling: true, encode: false }), + // 'a=b&c', + // ); + expect(stringify({ a: 'b' }, { encode: false })).toBe('a=b'); + expect(stringify({ a: { b: 'c' } }, { encode: false })).toBe('a[b]=c'); + expect(stringify({ a: 'b', c: null }, { strictNullHandling: true, encode: false })).toBe('a=b&c'); + }); + + test('can sort the keys', function () { + // @ts-expect-error + var sort: NonNullable = function (a: string, b: string) { + return a.localeCompare(b); + }; + // st.equal(stringify({ a: 'c', z: 'y', b: 'f' }, { sort: sort }), 'a=c&b=f&z=y'); + // st.equal( + // stringify({ a: 'c', z: { j: 'a', i: 'b' }, b: 'f' }, { sort: sort }), + // 'a=c&b=f&z%5Bi%5D=b&z%5Bj%5D=a', + // ); + expect(stringify({ a: 'c', z: 'y', b: 'f' }, { sort: sort })).toBe('a=c&b=f&z=y'); + expect(stringify({ a: 'c', z: { j: 'a', i: 'b' }, b: 'f' }, { sort: sort })).toBe( + 'a=c&b=f&z%5Bi%5D=b&z%5Bj%5D=a', + ); + }); + + test('can sort the keys at depth 3 or more too', function () { + // @ts-expect-error + var sort: NonNullable = function (a: string, b: string) { + return a.localeCompare(b); + }; + // st.equal( + // stringify( + // { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, + // { sort: sort, encode: false }, + // ), + // 'a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb', + // ); + // st.equal( + // stringify( + // { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, + // { sort: null, encode: false }, + // ), + // 'a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b', + // ); + expect( + stringify( + { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, + { sort: sort, encode: false }, + ), + ).toBe('a=a&b=b&z[zi][zia]=zia&z[zi][zib]=zib&z[zj][zja]=zja&z[zj][zjb]=zjb'); + expect( + stringify( + { a: 'a', z: { zj: { zjb: 'zjb', zja: 'zja' }, zi: { zib: 'zib', zia: 'zia' } }, b: 'b' }, + { sort: null, encode: false }, + ), + ).toBe('a=a&z[zj][zjb]=zjb&z[zj][zja]=zja&z[zi][zib]=zib&z[zi][zia]=zia&b=b'); + }); + + test('can stringify with custom encoding', function () { + // st.equal( + // stringify( + // { 県: '大阪府', '': '' }, + // { + // encoder: function (str) { + // if (str.length === 0) { + // return ''; + // } + // var buf = iconv.encode(str, 'shiftjis'); + // var result = []; + // for (var i = 0; i < buf.length; ++i) { + // result.push(buf.readUInt8(i).toString(16)); + // } + // return '%' + result.join('%'); + // }, + // }, + // ), + // '%8c%a7=%91%e5%8d%e3%95%7b&=', + // ); + expect( + stringify( + { 県: '大阪府', '': '' }, + { + encoder: function (str) { + if (str.length === 0) { + return ''; + } + var buf = iconv.encode(str, 'shiftjis'); + var result = []; + for (var i = 0; i < buf.length; ++i) { + result.push(buf.readUInt8(i).toString(16)); + } + return '%' + result.join('%'); + }, + }, + ), + ).toBe('%8c%a7=%91%e5%8d%e3%95%7b&='); + }); + + test('receives the default encoder as a second argument', function () { + // stringify( + // { a: 1, b: new Date(), c: true, d: [1] }, + // { + // encoder: function (str) { + // st.match(typeof str, /^(?:string|number|boolean)$/); + // return ''; + // }, + // }, + // ); + + stringify( + { a: 1, b: new Date(), c: true, d: [1] }, + { + encoder: function (str) { + // st.match(typeof str, /^(?:string|number|boolean)$/); + assert.match(typeof str, /^(?:string|number|boolean)$/); + return ''; + }, + }, + ); + }); + + test('receives the default encoder as a second argument', function () { + // stringify( + // { a: 1 }, + // { + // encoder: function (str, defaultEncoder) { + // st.equal(defaultEncoder, utils.encode); + // }, + // }, + // ); + + stringify( + { a: 1 }, + { + // @ts-ignore + encoder: function (_str, defaultEncoder) { + expect(defaultEncoder).toBe(encode); + }, + }, + ); + }); + + test('throws error with wrong encoder', function () { + // st['throws'](function () { + // stringify({}, { encoder: 'string' }); + // }, new TypeError('Encoder has to be a function.')); + // st.end(); + expect(() => { + // @ts-expect-error + stringify({}, { encoder: 'string' }); + }).toThrow(TypeError); + }); + + (typeof Buffer === 'undefined' ? test.skip : test)( + 'can use custom encoder for a buffer object', + function () { + // st.equal( + // stringify( + // { a: Buffer.from([1]) }, + // { + // encoder: function (buffer) { + // if (typeof buffer === 'string') { + // return buffer; + // } + // return String.fromCharCode(buffer.readUInt8(0) + 97); + // }, + // }, + // ), + // 'a=b', + // ); + expect( + stringify( + { a: Buffer.from([1]) }, + { + encoder: function (buffer) { + if (typeof buffer === 'string') { + return buffer; + } + return String.fromCharCode(buffer.readUInt8(0) + 97); + }, + }, + ), + ).toBe('a=b'); + + // st.equal( + // stringify( + // { a: Buffer.from('a b') }, + // { + // encoder: function (buffer) { + // return buffer; + // }, + // }, + // ), + // 'a=a b', + // ); + expect( + stringify( + { a: Buffer.from('a b') }, + { + encoder: function (buffer) { + return buffer; + }, + }, + ), + ).toBe('a=a b'); + }, + ); + + test('serializeDate option', function () { + var date = new Date(); + // st.equal( + // stringify({ a: date }), + // 'a=' + date.toISOString().replace(/:/g, '%3A'), + // 'default is toISOString', + // ); + expect(stringify({ a: date })).toBe('a=' + date.toISOString().replace(/:/g, '%3A')); + + var mutatedDate = new Date(); + mutatedDate.toISOString = function () { + throw new SyntaxError(); + }; + // st['throws'](function () { + // mutatedDate.toISOString(); + // }, SyntaxError); + expect(() => { + mutatedDate.toISOString(); + }).toThrow(SyntaxError); + // st.equal( + // stringify({ a: mutatedDate }), + // 'a=' + Date.prototype.toISOString.call(mutatedDate).replace(/:/g, '%3A'), + // 'toISOString works even when method is not locally present', + // ); + expect(stringify({ a: mutatedDate })).toBe( + 'a=' + Date.prototype.toISOString.call(mutatedDate).replace(/:/g, '%3A'), + ); + + var specificDate = new Date(6); + // st.equal( + // stringify( + // { a: specificDate }, + // { + // serializeDate: function (d) { + // return d.getTime() * 7; + // }, + // }, + // ), + // 'a=42', + // 'custom serializeDate function called', + // ); + expect( + stringify( + { a: specificDate }, + { + // @ts-ignore + serializeDate: function (d) { + return d.getTime() * 7; + }, + }, + ), + ).toBe('a=42'); + + // st.equal( + // stringify( + // { a: [date] }, + // { + // serializeDate: function (d) { + // return d.getTime(); + // }, + // arrayFormat: 'comma', + // }, + // ), + // 'a=' + date.getTime(), + // 'works with arrayFormat comma', + // ); + // st.equal( + // stringify( + // { a: [date] }, + // { + // serializeDate: function (d) { + // return d.getTime(); + // }, + // arrayFormat: 'comma', + // commaRoundTrip: true, + // }, + // ), + // 'a%5B%5D=' + date.getTime(), + // 'works with arrayFormat comma', + // ); + expect( + stringify( + { a: [date] }, + { + // @ts-expect-error + serializeDate: function (d) { + return d.getTime(); + }, + arrayFormat: 'comma', + }, + ), + ).toBe('a=' + date.getTime()); + expect( + stringify( + { a: [date] }, + { + // @ts-expect-error + serializeDate: function (d) { + return d.getTime(); + }, + arrayFormat: 'comma', + commaRoundTrip: true, + }, + ), + ).toBe('a%5B%5D=' + date.getTime()); + }); + + test('RFC 1738 serialization', function () { + // st.equal(stringify({ a: 'b c' }, { format: formats.RFC1738 }), 'a=b+c'); + // st.equal(stringify({ 'a b': 'c d' }, { format: formats.RFC1738 }), 'a+b=c+d'); + // st.equal( + // stringify({ 'a b': Buffer.from('a b') }, { format: formats.RFC1738 }), + // 'a+b=a+b', + // ); + expect(stringify({ a: 'b c' }, { format: 'RFC1738' })).toBe('a=b+c'); + expect(stringify({ 'a b': 'c d' }, { format: 'RFC1738' })).toBe('a+b=c+d'); + expect(stringify({ 'a b': Buffer.from('a b') }, { format: 'RFC1738' })).toBe('a+b=a+b'); + + // st.equal(stringify({ 'foo(ref)': 'bar' }, { format: formats.RFC1738 }), 'foo(ref)=bar'); + expect(stringify({ 'foo(ref)': 'bar' }, { format: 'RFC1738' })).toBe('foo(ref)=bar'); + }); + + test('RFC 3986 spaces serialization', function () { + // st.equal(stringify({ a: 'b c' }, { format: formats.RFC3986 }), 'a=b%20c'); + // st.equal(stringify({ 'a b': 'c d' }, { format: formats.RFC3986 }), 'a%20b=c%20d'); + // st.equal( + // stringify({ 'a b': Buffer.from('a b') }, { format: formats.RFC3986 }), + // 'a%20b=a%20b', + // ); + expect(stringify({ a: 'b c' }, { format: 'RFC3986' })).toBe('a=b%20c'); + expect(stringify({ 'a b': 'c d' }, { format: 'RFC3986' })).toBe('a%20b=c%20d'); + expect(stringify({ 'a b': Buffer.from('a b') }, { format: 'RFC3986' })).toBe('a%20b=a%20b'); + }); + + test('Backward compatibility to RFC 3986', function () { + // st.equal(stringify({ a: 'b c' }), 'a=b%20c'); + // st.equal(stringify({ 'a b': Buffer.from('a b') }), 'a%20b=a%20b'); + expect(stringify({ a: 'b c' })).toBe('a=b%20c'); + expect(stringify({ 'a b': Buffer.from('a b') })).toBe('a%20b=a%20b'); + }); + + test('Edge cases and unknown formats', function () { + ['UFO1234', false, 1234, null, {}, []].forEach(function (format) { + // st['throws'](function () { + // stringify({ a: 'b c' }, { format: format }); + // }, new TypeError('Unknown format option provided.')); + expect(() => { + // @ts-expect-error + stringify({ a: 'b c' }, { format: format }); + }).toThrow(TypeError); + }); + }); + + test('encodeValuesOnly', function () { + // st.equal( + // stringify( + // { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, + // { encodeValuesOnly: true, arrayFormat: 'indices' }, + // ), + // 'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h', + // 'encodeValuesOnly + indices', + // ); + // st.equal( + // stringify( + // { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, + // { encodeValuesOnly: true, arrayFormat: 'brackets' }, + // ), + // 'a=b&c[]=d&c[]=e%3Df&f[][]=g&f[][]=h', + // 'encodeValuesOnly + brackets', + // ); + // st.equal( + // stringify( + // { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, + // { encodeValuesOnly: true, arrayFormat: 'repeat' }, + // ), + // 'a=b&c=d&c=e%3Df&f=g&f=h', + // 'encodeValuesOnly + repeat', + // ); + expect( + stringify( + { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, + { encodeValuesOnly: true, arrayFormat: 'indices' }, + ), + ).toBe('a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h'); + expect( + stringify( + { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, + { encodeValuesOnly: true, arrayFormat: 'brackets' }, + ), + ).toBe('a=b&c[]=d&c[]=e%3Df&f[][]=g&f[][]=h'); + expect( + stringify( + { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, + { encodeValuesOnly: true, arrayFormat: 'repeat' }, + ), + ).toBe('a=b&c=d&c=e%3Df&f=g&f=h'); + + // st.equal( + // stringify({ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }, { arrayFormat: 'indices' }), + // 'a=b&c%5B0%5D=d&c%5B1%5D=e&f%5B0%5D%5B0%5D=g&f%5B1%5D%5B0%5D=h', + // 'no encodeValuesOnly + indices', + // ); + // st.equal( + // stringify({ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }, { arrayFormat: 'brackets' }), + // 'a=b&c%5B%5D=d&c%5B%5D=e&f%5B%5D%5B%5D=g&f%5B%5D%5B%5D=h', + // 'no encodeValuesOnly + brackets', + // ); + // st.equal( + // stringify({ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }, { arrayFormat: 'repeat' }), + // 'a=b&c=d&c=e&f=g&f=h', + // 'no encodeValuesOnly + repeat', + // ); + expect(stringify({ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }, { arrayFormat: 'indices' })).toBe( + 'a=b&c%5B0%5D=d&c%5B1%5D=e&f%5B0%5D%5B0%5D=g&f%5B1%5D%5B0%5D=h', + ); + expect(stringify({ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }, { arrayFormat: 'brackets' })).toBe( + 'a=b&c%5B%5D=d&c%5B%5D=e&f%5B%5D%5B%5D=g&f%5B%5D%5B%5D=h', + ); + expect(stringify({ a: 'b', c: ['d', 'e'], f: [['g'], ['h']] }, { arrayFormat: 'repeat' })).toBe( + 'a=b&c=d&c=e&f=g&f=h', + ); + }); + + test('encodeValuesOnly - strictNullHandling', function () { + // st.equal( + // stringify({ a: { b: null } }, { encodeValuesOnly: true, strictNullHandling: true }), + // 'a[b]', + // ); + expect(stringify({ a: { b: null } }, { encodeValuesOnly: true, strictNullHandling: true })).toBe('a[b]'); + }); + + test('throws if an invalid charset is specified', function () { + // st['throws'](function () { + // stringify({ a: 'b' }, { charset: 'foobar' }); + // }, new TypeError('The charset option must be either utf-8, iso-8859-1, or undefined')); + expect(() => { + // @ts-expect-error + stringify({ a: 'b' }, { charset: 'foobar' }); + }).toThrow(TypeError); + }); + + test('respects a charset of iso-8859-1', function () { + // st.equal(stringify({ æ: 'æ' }, { charset: 'iso-8859-1' }), '%E6=%E6'); + expect(stringify({ æ: 'æ' }, { charset: 'iso-8859-1' })).toBe('%E6=%E6'); + }); + + test('encodes unrepresentable chars as numeric entities in iso-8859-1 mode', function () { + // st.equal(stringify({ a: '☺' }, { charset: 'iso-8859-1' }), 'a=%26%239786%3B'); + expect(stringify({ a: '☺' }, { charset: 'iso-8859-1' })).toBe('a=%26%239786%3B'); + }); + + test('respects an explicit charset of utf-8 (the default)', function () { + // st.equal(stringify({ a: 'æ' }, { charset: 'utf-8' }), 'a=%C3%A6'); + expect(stringify({ a: 'æ' }, { charset: 'utf-8' })).toBe('a=%C3%A6'); + }); + + test('`charsetSentinel` option', function () { + // st.equal( + // stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'utf-8' }), + // 'utf8=%E2%9C%93&a=%C3%A6', + // 'adds the right sentinel when instructed to and the charset is utf-8', + // ); + expect(stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'utf-8' })).toBe( + 'utf8=%E2%9C%93&a=%C3%A6', + ); + + // st.equal( + // stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }), + // 'utf8=%26%2310003%3B&a=%E6', + // 'adds the right sentinel when instructed to and the charset is iso-8859-1', + // ); + expect(stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' })).toBe( + 'utf8=%26%2310003%3B&a=%E6', + ); + }); + + test('does not mutate the options argument', function () { + var options = {}; + stringify({}, options); + // st.deepEqual(options, {}); + expect(options).toEqual({}); + }); + + test('strictNullHandling works with custom filter', function () { + // @ts-expect-error + var filter = function (_prefix, value) { + return value; + }; + + var options = { strictNullHandling: true, filter: filter }; + // st.equal(stringify({ key: null }, options), 'key'); + expect(stringify({ key: null }, options)).toBe('key'); + }); + + test('strictNullHandling works with null serializeDate', function () { + var serializeDate = function () { + return null; + }; + var options = { strictNullHandling: true, serializeDate: serializeDate }; + var date = new Date(); + // st.equal(stringify({ key: date }, options), 'key'); + // @ts-expect-error + expect(stringify({ key: date }, options)).toBe('key'); + }); + + test('allows for encoding keys and values differently', function () { + // @ts-expect-error + var encoder = function (str, defaultEncoder, charset, type) { + if (type === 'key') { + return defaultEncoder(str, defaultEncoder, charset, type).toLowerCase(); + } + if (type === 'value') { + return defaultEncoder(str, defaultEncoder, charset, type).toUpperCase(); + } + throw 'this should never happen! type: ' + type; + }; + + // st.deepEqual(stringify({ KeY: 'vAlUe' }, { encoder: encoder }), 'key=VALUE'); + expect(stringify({ KeY: 'vAlUe' }, { encoder: encoder })).toBe('key=VALUE'); + }); + + test('objects inside arrays', function () { + var obj = { a: { b: { c: 'd', e: 'f' } } }; + var withArray = { a: { b: [{ c: 'd', e: 'f' }] } }; + + // st.equal( + // stringify(obj, { encode: false }), + // 'a[b][c]=d&a[b][e]=f', + // 'no array, no arrayFormat', + // ); + // st.equal( + // stringify(obj, { encode: false, arrayFormat: 'brackets' }), + // 'a[b][c]=d&a[b][e]=f', + // 'no array, bracket', + // ); + // st.equal( + // stringify(obj, { encode: false, arrayFormat: 'indices' }), + // 'a[b][c]=d&a[b][e]=f', + // 'no array, indices', + // ); + // st.equal( + // stringify(obj, { encode: false, arrayFormat: 'repeat' }), + // 'a[b][c]=d&a[b][e]=f', + // 'no array, repeat', + // ); + // st.equal( + // stringify(obj, { encode: false, arrayFormat: 'comma' }), + // 'a[b][c]=d&a[b][e]=f', + // 'no array, comma', + // ); + expect(stringify(obj, { encode: false })).toBe('a[b][c]=d&a[b][e]=f'); + expect(stringify(obj, { encode: false, arrayFormat: 'brackets' })).toBe('a[b][c]=d&a[b][e]=f'); + expect(stringify(obj, { encode: false, arrayFormat: 'indices' })).toBe('a[b][c]=d&a[b][e]=f'); + expect(stringify(obj, { encode: false, arrayFormat: 'repeat' })).toBe('a[b][c]=d&a[b][e]=f'); + expect(stringify(obj, { encode: false, arrayFormat: 'comma' })).toBe('a[b][c]=d&a[b][e]=f'); + + // st.equal( + // stringify(withArray, { encode: false }), + // 'a[b][0][c]=d&a[b][0][e]=f', + // 'array, no arrayFormat', + // ); + // st.equal( + // stringify(withArray, { encode: false, arrayFormat: 'brackets' }), + // 'a[b][][c]=d&a[b][][e]=f', + // 'array, bracket', + // ); + // st.equal( + // stringify(withArray, { encode: false, arrayFormat: 'indices' }), + // 'a[b][0][c]=d&a[b][0][e]=f', + // 'array, indices', + // ); + // st.equal( + // stringify(withArray, { encode: false, arrayFormat: 'repeat' }), + // 'a[b][c]=d&a[b][e]=f', + // 'array, repeat', + // ); + // st.equal( + // stringify(withArray, { encode: false, arrayFormat: 'comma' }), + // '???', + // 'array, comma', + // { skip: 'TODO: figure out what this should do' }, + // ); + expect(stringify(withArray, { encode: false })).toBe('a[b][0][c]=d&a[b][0][e]=f'); + expect(stringify(withArray, { encode: false, arrayFormat: 'brackets' })).toBe('a[b][][c]=d&a[b][][e]=f'); + expect(stringify(withArray, { encode: false, arrayFormat: 'indices' })).toBe('a[b][0][c]=d&a[b][0][e]=f'); + expect(stringify(withArray, { encode: false, arrayFormat: 'repeat' })).toBe('a[b][c]=d&a[b][e]=f'); + // !TODo: Figure out what this should do + // expect(stringify(withArray, { encode: false, arrayFormat: 'comma' })).toBe( + // 'a[b][c]=d&a[b][e]=f', + // ); + }); + + test('stringifies sparse arrays', function () { + // st.equal( + // stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), + // 'a[1]=2&a[4]=1', + // ); + // st.equal( + // stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), + // 'a[]=2&a[]=1', + // ); + // st.equal( + // stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), + // 'a=2&a=1', + // ); + expect(stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'indices' })).toBe( + 'a[1]=2&a[4]=1', + ); + expect(stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'brackets' })).toBe( + 'a[]=2&a[]=1', + ); + expect(stringify({ a: [, '2', , , '1'] }, { encodeValuesOnly: true, arrayFormat: 'repeat' })).toBe( + 'a=2&a=1', + ); + + // st.equal( + // stringify( + // { a: [, { b: [, , { c: '1' }] }] }, + // { encodeValuesOnly: true, arrayFormat: 'indices' }, + // ), + // 'a[1][b][2][c]=1', + // ); + // st.equal( + // stringify( + // { a: [, { b: [, , { c: '1' }] }] }, + // { encodeValuesOnly: true, arrayFormat: 'brackets' }, + // ), + // 'a[][b][][c]=1', + // ); + // st.equal( + // stringify( + // { a: [, { b: [, , { c: '1' }] }] }, + // { encodeValuesOnly: true, arrayFormat: 'repeat' }, + // ), + // 'a[b][c]=1', + // ); + expect( + stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), + ).toBe('a[1][b][2][c]=1'); + expect( + stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), + ).toBe('a[][b][][c]=1'); + expect( + stringify({ a: [, { b: [, , { c: '1' }] }] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), + ).toBe('a[b][c]=1'); + + // st.equal( + // stringify( + // { a: [, [, , [, , , { c: '1' }]]] }, + // { encodeValuesOnly: true, arrayFormat: 'indices' }, + // ), + // 'a[1][2][3][c]=1', + // ); + // st.equal( + // stringify( + // { a: [, [, , [, , , { c: '1' }]]] }, + // { encodeValuesOnly: true, arrayFormat: 'brackets' }, + // ), + // 'a[][][][c]=1', + // ); + // st.equal( + // stringify( + // { a: [, [, , [, , , { c: '1' }]]] }, + // { encodeValuesOnly: true, arrayFormat: 'repeat' }, + // ), + // 'a[c]=1', + // ); + expect( + stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), + ).toBe('a[1][2][3][c]=1'); + expect( + stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), + ).toBe('a[][][][c]=1'); + expect( + stringify({ a: [, [, , [, , , { c: '1' }]]] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), + ).toBe('a[c]=1'); + + // st.equal( + // stringify( + // { a: [, [, , [, , , { c: [, '1'] }]]] }, + // { encodeValuesOnly: true, arrayFormat: 'indices' }, + // ), + // 'a[1][2][3][c][1]=1', + // ); + // st.equal( + // stringify( + // { a: [, [, , [, , , { c: [, '1'] }]]] }, + // { encodeValuesOnly: true, arrayFormat: 'brackets' }, + // ), + // 'a[][][][c][]=1', + // ); + // st.equal( + // stringify( + // { a: [, [, , [, , , { c: [, '1'] }]]] }, + // { encodeValuesOnly: true, arrayFormat: 'repeat' }, + // ), + // 'a[c]=1', + // ); + expect( + stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'indices' }), + ).toBe('a[1][2][3][c][1]=1'); + expect( + stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'brackets' }), + ).toBe('a[][][][c][]=1'); + expect( + stringify({ a: [, [, , [, , , { c: [, '1'] }]]] }, { encodeValuesOnly: true, arrayFormat: 'repeat' }), + ).toBe('a[c]=1'); + }); + + test('encodes a very long string', function () { + var chars = []; + var expected = []; + for (var i = 0; i < 5e3; i++) { + chars.push(' ' + i); + + expected.push('%20' + i); + } + + var obj = { + foo: chars.join(''), + }; + + // st.equal( + // stringify(obj, { arrayFormat: 'bracket', charset: 'utf-8' }), + // 'foo=' + expected.join(''), + // ); + // @ts-expect-error + expect(stringify(obj, { arrayFormat: 'bracket', charset: 'utf-8' })).toBe('foo=' + expected.join('')); + }); +}); + +describe('stringifies empty keys', function () { + empty_test_cases.forEach(function (testCase) { + test('stringifies an object with empty string key with ' + testCase.input, function () { + // st.deepEqual( + // stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'indices' }), + // testCase.stringifyOutput.indices, + // 'test case: ' + testCase.input + ', indices', + // ); + // st.deepEqual( + // stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'brackets' }), + // testCase.stringifyOutput.brackets, + // 'test case: ' + testCase.input + ', brackets', + // ); + // st.deepEqual( + // stringify(testCase.withEmptyKeys, { encode: false, arrayFormat: 'repeat' }), + // testCase.stringifyOutput.repeat, + // 'test case: ' + testCase.input + ', repeat', + // ); + expect(stringify(testCase.with_empty_keys, { encode: false, arrayFormat: 'indices' })).toBe( + testCase.stringify_output.indices, + ); + expect(stringify(testCase.with_empty_keys, { encode: false, arrayFormat: 'brackets' })).toBe( + testCase.stringify_output.brackets, + ); + expect(stringify(testCase.with_empty_keys, { encode: false, arrayFormat: 'repeat' })).toBe( + testCase.stringify_output.repeat, + ); + }); + }); + + test('edge case with object/arrays', function () { + // st.deepEqual(stringify({ '': { '': [2, 3] } }, { encode: false }), '[][0]=2&[][1]=3'); + // st.deepEqual( + // stringify({ '': { '': [2, 3], a: 2 } }, { encode: false }), + // '[][0]=2&[][1]=3&[a]=2', + // ); + // st.deepEqual( + // stringify({ '': { '': [2, 3] } }, { encode: false, arrayFormat: 'indices' }), + // '[][0]=2&[][1]=3', + // ); + // st.deepEqual( + // stringify({ '': { '': [2, 3], a: 2 } }, { encode: false, arrayFormat: 'indices' }), + // '[][0]=2&[][1]=3&[a]=2', + // ); + expect(stringify({ '': { '': [2, 3] } }, { encode: false })).toBe('[][0]=2&[][1]=3'); + expect(stringify({ '': { '': [2, 3], a: 2 } }, { encode: false })).toBe('[][0]=2&[][1]=3&[a]=2'); + expect(stringify({ '': { '': [2, 3] } }, { encode: false, arrayFormat: 'indices' })).toBe( + '[][0]=2&[][1]=3', + ); + expect(stringify({ '': { '': [2, 3], a: 2 } }, { encode: false, arrayFormat: 'indices' })).toBe( + '[][0]=2&[][1]=3&[a]=2', + ); + }); +}); diff --git a/tests/qs/utils.test.ts b/tests/qs/utils.test.ts new file mode 100644 index 00000000..1ff53fdd --- /dev/null +++ b/tests/qs/utils.test.ts @@ -0,0 +1,169 @@ +import { combine, merge, is_buffer, assign_single_source } from '@mux/mux-node/internal/qs/utils'; + +describe('merge()', function () { + // t.deepEqual(merge(null, true), [null, true], 'merges true into null'); + expect(merge(null, true)).toEqual([null, true]); + + // t.deepEqual(merge(null, [42]), [null, 42], 'merges null into an array'); + expect(merge(null, [42])).toEqual([null, 42]); + + // t.deepEqual( + // merge({ a: 'b' }, { a: 'c' }), + // { a: ['b', 'c'] }, + // 'merges two objects with the same key', + // ); + expect(merge({ a: 'b' }, { a: 'c' })).toEqual({ a: ['b', 'c'] }); + + var oneMerged = merge({ foo: 'bar' }, { foo: { first: '123' } }); + // t.deepEqual( + // oneMerged, + // { foo: ['bar', { first: '123' }] }, + // 'merges a standalone and an object into an array', + // ); + expect(oneMerged).toEqual({ foo: ['bar', { first: '123' }] }); + + var twoMerged = merge({ foo: ['bar', { first: '123' }] }, { foo: { second: '456' } }); + // t.deepEqual( + // twoMerged, + // { foo: { 0: 'bar', 1: { first: '123' }, second: '456' } }, + // 'merges a standalone and two objects into an array', + // ); + expect(twoMerged).toEqual({ foo: { 0: 'bar', 1: { first: '123' }, second: '456' } }); + + var sandwiched = merge({ foo: ['bar', { first: '123', second: '456' }] }, { foo: 'baz' }); + // t.deepEqual( + // sandwiched, + // { foo: ['bar', { first: '123', second: '456' }, 'baz'] }, + // 'merges an object sandwiched by two standalones into an array', + // ); + expect(sandwiched).toEqual({ foo: ['bar', { first: '123', second: '456' }, 'baz'] }); + + var nestedArrays = merge({ foo: ['baz'] }, { foo: ['bar', 'xyzzy'] }); + // t.deepEqual(nestedArrays, { foo: ['baz', 'bar', 'xyzzy'] }); + expect(nestedArrays).toEqual({ foo: ['baz', 'bar', 'xyzzy'] }); + + var noOptionsNonObjectSource = merge({ foo: 'baz' }, 'bar'); + // t.deepEqual(noOptionsNonObjectSource, { foo: 'baz', bar: true }); + expect(noOptionsNonObjectSource).toEqual({ foo: 'baz', bar: true }); + + (typeof Object.defineProperty !== 'function' ? test.skip : test)( + 'avoids invoking array setters unnecessarily', + function () { + var setCount = 0; + var getCount = 0; + var observed: any[] = []; + Object.defineProperty(observed, 0, { + get: function () { + getCount += 1; + return { bar: 'baz' }; + }, + set: function () { + setCount += 1; + }, + }); + merge(observed, [null]); + // st.equal(setCount, 0); + // st.equal(getCount, 1); + expect(setCount).toEqual(0); + expect(getCount).toEqual(1); + observed[0] = observed[0]; // eslint-disable-line no-self-assign + // st.equal(setCount, 1); + // st.equal(getCount, 2); + expect(setCount).toEqual(1); + expect(getCount).toEqual(2); + }, + ); +}); + +test('assign()', function () { + var target = { a: 1, b: 2 }; + var source = { b: 3, c: 4 }; + var result = assign_single_source(target, source); + + expect(result).toEqual(target); + expect(target).toEqual({ a: 1, b: 3, c: 4 }); + expect(source).toEqual({ b: 3, c: 4 }); +}); + +describe('combine()', function () { + test('both arrays', function () { + var a = [1]; + var b = [2]; + var combined = combine(a, b); + + // st.deepEqual(a, [1], 'a is not mutated'); + // st.deepEqual(b, [2], 'b is not mutated'); + // st.notEqual(a, combined, 'a !== combined'); + // st.notEqual(b, combined, 'b !== combined'); + // st.deepEqual(combined, [1, 2], 'combined is a + b'); + expect(a).toEqual([1]); + expect(b).toEqual([2]); + expect(combined).toEqual([1, 2]); + expect(a).not.toEqual(combined); + expect(b).not.toEqual(combined); + }); + + test('one array, one non-array', function () { + var aN = 1; + var a = [aN]; + var bN = 2; + var b = [bN]; + + var combinedAnB = combine(aN, b); + // st.deepEqual(b, [bN], 'b is not mutated'); + // st.notEqual(aN, combinedAnB, 'aN + b !== aN'); + // st.notEqual(a, combinedAnB, 'aN + b !== a'); + // st.notEqual(bN, combinedAnB, 'aN + b !== bN'); + // st.notEqual(b, combinedAnB, 'aN + b !== b'); + // st.deepEqual([1, 2], combinedAnB, 'first argument is array-wrapped when not an array'); + expect(b).toEqual([bN]); + expect(combinedAnB).not.toEqual(aN); + expect(combinedAnB).not.toEqual(a); + expect(combinedAnB).not.toEqual(bN); + expect(combinedAnB).not.toEqual(b); + expect(combinedAnB).toEqual([1, 2]); + + var combinedABn = combine(a, bN); + // st.deepEqual(a, [aN], 'a is not mutated'); + // st.notEqual(aN, combinedABn, 'a + bN !== aN'); + // st.notEqual(a, combinedABn, 'a + bN !== a'); + // st.notEqual(bN, combinedABn, 'a + bN !== bN'); + // st.notEqual(b, combinedABn, 'a + bN !== b'); + // st.deepEqual([1, 2], combinedABn, 'second argument is array-wrapped when not an array'); + expect(a).toEqual([aN]); + expect(combinedABn).not.toEqual(aN); + expect(combinedABn).not.toEqual(a); + expect(combinedABn).not.toEqual(bN); + expect(combinedABn).not.toEqual(b); + expect(combinedABn).toEqual([1, 2]); + }); + + test('neither is an array', function () { + var combined = combine(1, 2); + // st.notEqual(1, combined, '1 + 2 !== 1'); + // st.notEqual(2, combined, '1 + 2 !== 2'); + // st.deepEqual([1, 2], combined, 'both arguments are array-wrapped when not an array'); + expect(combined).not.toEqual(1); + expect(combined).not.toEqual(2); + expect(combined).toEqual([1, 2]); + }); +}); + +test('is_buffer()', function () { + for (const x of [null, undefined, true, false, '', 'abc', 42, 0, NaN, {}, [], function () {}, /a/g]) { + // t.equal(is_buffer(x), false, inspect(x) + ' is not a buffer'); + expect(is_buffer(x)).toEqual(false); + } + + var fakeBuffer = { constructor: Buffer }; + // t.equal(is_buffer(fakeBuffer), false, 'fake buffer is not a buffer'); + expect(is_buffer(fakeBuffer)).toEqual(false); + + var saferBuffer = Buffer.from('abc'); + // t.equal(is_buffer(saferBuffer), true, 'SaferBuffer instance is a buffer'); + expect(is_buffer(saferBuffer)).toEqual(true); + + var buffer = Buffer.from('abc'); + // t.equal(is_buffer(buffer), true, 'real Buffer instance is a buffer'); + expect(is_buffer(buffer)).toEqual(true); +}); diff --git a/tests/stringifyQuery.test.ts b/tests/stringifyQuery.test.ts index 48e79160..7f5aa9ed 100644 --- a/tests/stringifyQuery.test.ts +++ b/tests/stringifyQuery.test.ts @@ -1,8 +1,10 @@ -import { APIClient } from '@mux/mux-node/core'; +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -const { stringifyQuery } = APIClient.prototype as any; +import { Mux } from '@mux/mux-node'; -describe('APIClient.stringifyQuery', () => { +const { stringifyQuery } = Mux.prototype as any; + +describe(stringifyQuery, () => { for (const [input, expected] of [ [{ a: '1', b: 2, c: true }, 'a=1&b=2&c=true'], [{ a: null, b: false, c: undefined }, 'a=&b=false'], @@ -18,9 +20,4 @@ describe('APIClient.stringifyQuery', () => { expect(stringifyQuery(input)).toEqual(expected); }); } - for (const value of [[], {}, new Date()]) { - it(`${JSON.stringify(value)} -> `, () => { - expect(() => stringifyQuery({ value })).toThrow(`Cannot stringify type ${typeof value}`); - }); - } }); diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts index 94a4c9c0..ee7e6269 100644 --- a/tests/uploads.test.ts +++ b/tests/uploads.test.ts @@ -54,4 +54,12 @@ describe('toFile', () => { const file = await toFile(input); expect(file.name).toEqual('uploads.test.ts'); }); + + it('does not copy File objects', async () => { + const input = new File(['foo'], 'input.jsonl', { type: 'jsonl' }); + const file = await toFile(input); + expect(file).toBe(input); + expect(file.name).toEqual('input.jsonl'); + expect(file.type).toBe('jsonl'); + }); }); diff --git a/tsconfig.deno.json b/tsconfig.deno.json index c0b4b776..849e070d 100644 --- a/tsconfig.deno.json +++ b/tsconfig.deno.json @@ -1,19 +1,14 @@ { "extends": "./tsconfig.json", - "include": ["deno"], + "include": ["dist-deno"], "exclude": [], "compilerOptions": { - "rootDir": "./deno", + "rootDir": "./dist-deno", "lib": ["es2020", "DOM"], - "paths": { - "@mux/mux-node/_shims/auto/*": ["deno/_shims/auto/*-deno"], - "@mux/mux-node/*": ["deno/*"], - "@mux/mux-node": ["deno/index.ts"], - }, "noEmit": true, "declaration": true, "declarationMap": true, - "outDir": "deno", + "outDir": "dist-deno", "pretty": true, "sourceMap": true } diff --git a/tsconfig.json b/tsconfig.json index eb744119..be6aeded 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -11,7 +11,7 @@ "paths": { "@mux/mux-node/_shims/auto/*": ["src/_shims/auto/*-node"], "@mux/mux-node/*": ["src/*"], - "@mux/mux-node": ["src/index.ts"], + "@mux/mux-node": ["src/index.ts"] }, "noEmit": true, @@ -32,6 +32,7 @@ "noUncheckedIndexedAccess": true, "noImplicitOverride": true, "noPropertyAccessFromIndexSignature": true, + "isolatedModules": false, "skipLibCheck": true } diff --git a/yarn.lock b/yarn.lock index 47ed65ff..60a04a50 100644 --- a/yarn.lock +++ b/yarn.lock @@ -322,9 +322,9 @@ eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.5.1": - version "4.9.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.0.tgz#7ccb5f58703fa61ffdcbf39e2c604a109e781162" - integrity sha512-zJmuCWj2VLBt4c25CfBIbMZLGLyhkvs7LznyVX5HfpzeocThgIj5XQK4L+g3U36mMcx8bPMhGyPpwCATamC4jQ== + version "4.11.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" + integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== "@eslint-community/regexpp@^4.6.1": version "4.6.2" @@ -759,16 +759,6 @@ dependencies: "@swc/counter" "^0.1.3" -"@ts-morph/common@~0.20.0": - version "0.20.0" - resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.20.0.tgz#3f161996b085ba4519731e4d24c35f6cba5b80af" - integrity sha512-7uKjByfbPpwuzkstL3L5MQyuXPSKdoNG93Fmi2JoDcTf3pEP731JdRFAduRVkOs8oqxPsXKA+ScrWkdQ8t/I+Q== - dependencies: - fast-glob "^3.2.12" - minimatch "^7.4.3" - mkdirp "^2.1.6" - path-browserify "^1.0.1" - "@tsconfig/node10@^1.0.7": version "1.0.8" resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.8.tgz#c1e4e80d6f964fbecb3359c43bd48b40f7cadad9" @@ -857,9 +847,9 @@ pretty-format "^29.0.0" "@types/json-schema@^7.0.12": - version "7.0.13" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85" - integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ== + 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-fetch@^2.6.4": version "2.6.4" @@ -881,15 +871,10 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== -"@types/qs@^6.9.7": - version "6.9.15" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.15.tgz#adde8a060ec9c305a82de1babc1056e73bd64dce" - integrity sha512-uXHQKES6DQKKCLh441Xv/dwxOq1TVS3JPUMlEqoEglvlhR6Mxnlew/Xq/LRVHpLyk7iK3zODe1qYHIMltO7XGg== - "@types/semver@^7.5.0": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.3.tgz#9a726e116beb26c24f1ccd6850201e1246122e04" - integrity sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw== + version "7.5.8" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" + integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== "@types/stack-utils@^2.0.0": version "2.0.3" @@ -909,15 +894,15 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^6.7.0": - version "6.7.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.3.tgz#d98046e9f7102d49a93d944d413c6055c47fafd7" - integrity sha512-vntq452UHNltxsaaN+L9WyuMch8bMd9CqJ3zhzTPXXidwbf5mqqKCVXEuvRZUqLJSTLeWE65lQwyXsRGnXkCTA== + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" + integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== dependencies: "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.7.3" - "@typescript-eslint/type-utils" "6.7.3" - "@typescript-eslint/utils" "6.7.3" - "@typescript-eslint/visitor-keys" "6.7.3" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/type-utils" "6.21.0" + "@typescript-eslint/utils" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" graphemer "^1.4.0" ignore "^5.2.4" @@ -926,71 +911,72 @@ ts-api-utils "^1.0.1" "@typescript-eslint/parser@^6.7.0": - version "6.7.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.7.3.tgz#aaf40092a32877439e5957e18f2d6a91c82cc2fd" - integrity sha512-TlutE+iep2o7R8Lf+yoer3zU6/0EAUc8QIBB3GYBc1KGz4c4TRm83xwXUZVPlZ6YCLss4r77jbu6j3sendJoiQ== - dependencies: - "@typescript-eslint/scope-manager" "6.7.3" - "@typescript-eslint/types" "6.7.3" - "@typescript-eslint/typescript-estree" "6.7.3" - "@typescript-eslint/visitor-keys" "6.7.3" + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" + integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== + dependencies: + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.7.3": - version "6.7.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.7.3.tgz#07e5709c9bdae3eaf216947433ef97b3b8b7d755" - integrity sha512-wOlo0QnEou9cHO2TdkJmzF7DFGvAKEnB82PuPNHpT8ZKKaZu6Bm63ugOTn9fXNJtvuDPanBc78lGUGGytJoVzQ== +"@typescript-eslint/scope-manager@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" + integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== dependencies: - "@typescript-eslint/types" "6.7.3" - "@typescript-eslint/visitor-keys" "6.7.3" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" -"@typescript-eslint/type-utils@6.7.3": - version "6.7.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.7.3.tgz#c2c165c135dda68a5e70074ade183f5ad68f3400" - integrity sha512-Fc68K0aTDrKIBvLnKTZ5Pf3MXK495YErrbHb1R6aTpfK5OdSFj0rVN7ib6Tx6ePrZ2gsjLqr0s98NG7l96KSQw== +"@typescript-eslint/type-utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" + integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== dependencies: - "@typescript-eslint/typescript-estree" "6.7.3" - "@typescript-eslint/utils" "6.7.3" + "@typescript-eslint/typescript-estree" "6.21.0" + "@typescript-eslint/utils" "6.21.0" debug "^4.3.4" ts-api-utils "^1.0.1" -"@typescript-eslint/types@6.7.3": - version "6.7.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.7.3.tgz#0402b5628a63f24f2dc9d4a678e9a92cc50ea3e9" - integrity sha512-4g+de6roB2NFcfkZb439tigpAMnvEIg3rIjWQ+EM7IBaYt/CdJt6em9BJ4h4UpdgaBWdmx2iWsafHTrqmgIPNw== +"@typescript-eslint/types@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" + integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== -"@typescript-eslint/typescript-estree@6.7.3": - version "6.7.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.3.tgz#ec5bb7ab4d3566818abaf0e4a8fa1958561b7279" - integrity sha512-YLQ3tJoS4VxLFYHTw21oe1/vIZPRqAO91z6Uv0Ss2BKm/Ag7/RVQBcXTGcXhgJMdA4U+HrKuY5gWlJlvoaKZ5g== +"@typescript-eslint/typescript-estree@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" + integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== dependencies: - "@typescript-eslint/types" "6.7.3" - "@typescript-eslint/visitor-keys" "6.7.3" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/visitor-keys" "6.21.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" + minimatch "9.0.3" semver "^7.5.4" ts-api-utils "^1.0.1" -"@typescript-eslint/utils@6.7.3": - version "6.7.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.7.3.tgz#96c655816c373135b07282d67407cb577f62e143" - integrity sha512-vzLkVder21GpWRrmSR9JxGZ5+ibIUSudXlW52qeKpzUEQhRSmyZiVDDj3crAth7+5tmN1ulvgKaCU2f/bPRCzg== +"@typescript-eslint/utils@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" + integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" "@types/json-schema" "^7.0.12" "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.7.3" - "@typescript-eslint/types" "6.7.3" - "@typescript-eslint/typescript-estree" "6.7.3" + "@typescript-eslint/scope-manager" "6.21.0" + "@typescript-eslint/types" "6.21.0" + "@typescript-eslint/typescript-estree" "6.21.0" semver "^7.5.4" -"@typescript-eslint/visitor-keys@6.7.3": - version "6.7.3" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.3.tgz#83809631ca12909bd2083558d2f93f5747deebb2" - integrity sha512-HEVXkU9IB+nk9o63CeICMHxFWbHWr3E1mpilIQBe9+7L/lH97rleFLVtYsfnWB+JVMaiFnEaxvknvmIzX+CqVg== +"@typescript-eslint/visitor-keys@6.21.0": + version "6.21.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" + integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== dependencies: - "@typescript-eslint/types" "6.7.3" + "@typescript-eslint/types" "6.21.0" eslint-visitor-keys "^3.4.1" abort-controller@^3.0.0: @@ -1205,12 +1191,12 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" -braces@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== +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.0.1" + fill-range "^7.1.1" browserslist@^4.22.2: version "4.22.2" @@ -1248,17 +1234,6 @@ bundle-name@^3.0.0: dependencies: run-applescript "^5.0.0" -call-bind@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9" - integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - set-function-length "^1.2.1" - callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -1330,11 +1305,6 @@ co@^4.6.0: resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== -code-block-writer@^12.0.0: - version "12.0.0" - resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-12.0.0.tgz#4dd58946eb4234105aff7f0035977b2afdc2a770" - integrity sha512-q4dMFMlXtKR3XNBHyMHt/3pwYNA69EDk00lloMOaaUMKPUXBw6lpXtbu3MMVG6/uOihGnRDOlkyqsONEUj60+w== - 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" @@ -1408,13 +1378,20 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: +debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +debug@^4.3.4: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + dedent@^1.0.0: version "1.5.1" resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" @@ -1448,15 +1425,6 @@ default-browser@^4.0.0: execa "^7.1.1" titleize "^3.0.0" -define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - define-lazy-prop@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" @@ -1523,18 +1491,6 @@ error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845" - integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ== - dependencies: - get-intrinsic "^1.2.4" - -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== - escalade@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" @@ -1583,12 +1539,7 @@ eslint-scope@^7.2.2: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: - version "3.4.2" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.2.tgz#8c2095440eca8c933bedcadf16fefa44dbe9ba5f" - integrity sha512-8drBzUEyZ2llkpCA67iYrgEssKDUu68V8ChqqOfFupIaG/LCVPUT+CoGJpT77zJprs4T/W7p07LP7zAIMuweVw== - -eslint-visitor-keys@^3.4.3: +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: version "3.4.3" resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== @@ -1746,18 +1697,7 @@ fast-glob@^3.2.12: merge2 "^1.3.0" micromatch "^4.0.4" -fast-glob@^3.2.9: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-glob@^3.3.0: +fast-glob@^3.2.9, fast-glob@^3.3.0: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -1779,9 +1719,9 @@ fast-levenshtein@^2.0.6: integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + version "1.17.1" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47" + integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w== dependencies: reusify "^1.0.4" @@ -1799,10 +1739,10 @@ file-entry-cache@^6.0.1: dependencies: flat-cache "^3.0.4" -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== +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" @@ -1882,17 +1822,6 @@ get-caller-file@^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.1.3, get-intrinsic@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd" - integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.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" @@ -1958,13 +1887,6 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" @@ -1985,23 +1907,6 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - -has-proto@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd" - integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q== - -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - hasown@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" @@ -2031,10 +1936,17 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" +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" + ignore@^5.2.0, ignore@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.2" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" + integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== import-fresh@^3.2.1: version "3.3.0" @@ -2570,9 +2482,9 @@ jest@^29.4.0: jest-cli "^29.7.0" jose@^4.14.4: - version "4.15.5" - resolved "https://registry.yarnpkg.com/jose/-/jose-4.15.5.tgz#6475d0f467ecd3c630a1b5dadd2735a7288df706" - integrity sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg== + version "4.15.9" + resolved "https://registry.yarnpkg.com/jose/-/jose-4.15.9.tgz#9b68eda29e9a0614c042fa29387196c7dd800100" + integrity sha512-1vUQX+IdDMVPj4k8kOxgUqlcK518yluMuGZwqlr44FS1ppZB/5GWh4rZG89erpOBOJjU/OBsnCVFfapsRz6nEA== js-tokens@^4.0.0: version "4.0.0" @@ -2715,11 +2627,11 @@ merge2@^1.3.0, merge2@^1.4.1: integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + 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.2" + braces "^3.0.3" picomatch "^2.3.1" mime-db@1.51.0: @@ -2744,6 +2656,13 @@ mimic-fn@^4.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== +minimatch@9.0.3: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -2751,29 +2670,17 @@ minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" -minimatch@^7.4.3: - version "7.4.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.6.tgz#845d6f254d8f4a5e4fd6baf44d5f10c8448365fb" - integrity sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw== - dependencies: - brace-expansion "^2.0.1" - minimist@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== -mkdirp@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19" - integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A== - ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0: +ms@^2.0.0, 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== @@ -2824,11 +2731,6 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" -object-inspect@^1.13.1: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== - once@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -2936,11 +2838,6 @@ parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -path-browserify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -3037,13 +2934,6 @@ pure-rand@^6.0.0: resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.4.tgz#50b737f6a925468679bff00ad20eade53f37d5c7" integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== -qs@^6.10.3: - version "6.12.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.12.1.tgz#39422111ca7cbdb70425541cba20c7d7b216599a" - integrity sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ== - dependencies: - side-channel "^1.0.6" - queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" @@ -3130,29 +3020,27 @@ safe-buffer@~5.2.0: 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== + 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.5.3, semver@^7.5.4: +semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -set-function-length@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" - integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" +semver@^7.5.4: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== shebang-command@^2.0.0: version "2.0.0" @@ -3166,16 +3054,6 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -side-channel@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.6.tgz#abd25fb7cd24baf45466406b1096b7831c9215f2" - integrity sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA== - dependencies: - call-bind "^1.0.7" - es-errors "^1.3.0" - get-intrinsic "^1.2.4" - object-inspect "^1.13.1" - 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" @@ -3360,9 +3238,9 @@ tr46@~0.0.3: integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= ts-api-utils@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.3.tgz#f12c1c781d04427313dbac808f453f050e54a331" - integrity sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg== + version "1.3.0" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" + integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== ts-jest@^29.1.0: version "29.1.1" @@ -3378,14 +3256,6 @@ ts-jest@^29.1.0: semver "^7.5.3" yargs-parser "^21.0.1" -ts-morph@^19.0.0: - version "19.0.0" - resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-19.0.0.tgz#43e95fb0156c3fe3c77c814ac26b7d0be2f93169" - integrity sha512-D6qcpiJdn46tUqV45vr5UGM2dnIEuTGNxVhg0sk5NX11orcouwj6i1bMqZIz2mZTZB1Hcgy7C3oEVhAT+f6mbQ== - dependencies: - "@ts-morph/common" "~0.20.0" - code-block-writer "^12.0.0" - ts-node@^10.5.0: version "10.7.0" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.7.0.tgz#35d503d0fab3e2baa672a0e94f4b40653c2463f5" @@ -3523,11 +3393,6 @@ web-streams-polyfill@4.0.0-beta.1: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.1.tgz#3b19b9817374b7cee06d374ba7eeb3aeb80e8c95" integrity sha512-3ux37gEX670UUphBF9AMCq8XM6iQ8Ac6A+DSRRjDoRBm1ufCkaCDdNVbaqq60PsEkdNlLKrGtv/YBP4EJXqNtQ== -web-streams-polyfill@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" - integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== - webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"