diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile deleted file mode 100644 index 8ea34be9..00000000 --- a/.devcontainer/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# syntax=docker/dockerfile:1 -FROM debian:bookworm-slim AS stainless - -RUN apt-get update && apt-get install -y \ - nodejs \ - npm \ - yarnpkg \ - && apt-get clean autoclean - -# Ensure UTF-8 encoding -ENV LANG=C.UTF-8 -ENV LC_ALL=C.UTF-8 - -# Yarn -RUN ln -sf /usr/bin/yarnpkg /usr/bin/yarn - -WORKDIR /workspace - -COPY package.json yarn.lock /workspace/ - -RUN yarn install - -COPY . /workspace diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d55fc4d6..763462fa 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,20 +1,17 @@ // For format details, see https://aka.ms/devcontainer.json. For config options, see the // README at: /~https://github.com/devcontainers/templates/tree/main/src/debian { - "name": "Debian", - "build": { - "dockerfile": "Dockerfile" + "name": "Development", + "image": "mcr.microsoft.com/devcontainers/typescript-node:latest", + "features": { + "ghcr.io/devcontainers/features/node:1": {} + }, + "postCreateCommand": "yarn install", + "customizations": { + "vscode": { + "extensions": [ + "esbenp.prettier-vscode" + ] + } } - - // Features to add to the dev container. More info: https://containers.dev/features. - // "features": {}, - - // Use 'forwardPorts' to make a list of ports inside the container available locally. - // "forwardPorts": [], - - // Configure tool-specific properties. - // "customizations": {}, - - // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root. - // "remoteUser": "root" } diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 256be89a..83908824 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "9.0.1" + ".": "10.0.0" } diff --git a/.stats.yml b/.stats.yml index b07b20ed..79079db7 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ configured_endpoints: 88 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mux%2Fmux-59cc6a0736ea7363f64111dcca8774fe5e7f353c547071c7064574456c178486.yml +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/mux%2Fmux-2eec862e75143314aec7ca531a90eecc404ce10a5038c2140810caaeb22cae43.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b410b3e..715c15ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,51 @@ # Changelog +## 10.0.0 (2025-02-21) + +Full Changelog: [v9.0.1...v10.0.0](/~https://github.com/muxinc/mux-node-sdk/compare/v9.0.1...v10.0.0) + +### ⚠ BREAKING CHANGES + +* deprecate `mp4_support` option ([#321](/~https://github.com/muxinc/mux-node-sdk/issues/321)) (#547) + +### Features + +* Add passthrough field on static renditions ([#320](/~https://github.com/muxinc/mux-node-sdk/issues/320)) ([#543](/~https://github.com/muxinc/mux-node-sdk/issues/543)) ([33ceef2](/~https://github.com/muxinc/mux-node-sdk/commit/33ceef2da37106ef2b2abef8a950544df279a42f)) +* Add video.asset.non_standard_input_detected webhook ([#317](/~https://github.com/muxinc/mux-node-sdk/issues/317)) ([#536](/~https://github.com/muxinc/mux-node-sdk/issues/536)) ([d39b407](/~https://github.com/muxinc/mux-node-sdk/commit/d39b407da4e2cf57e600a0181175de8e0ecd7aeb)) +* Additional Standard Dimensions ([#319](/~https://github.com/muxinc/mux-node-sdk/issues/319)) ([#544](/~https://github.com/muxinc/mux-node-sdk/issues/544)) ([22dbea3](/~https://github.com/muxinc/mux-node-sdk/commit/22dbea3eea8efcd8c9bd8e650f5af4f94ce44e3e)) +* **api:** api update ([#533](/~https://github.com/muxinc/mux-node-sdk/issues/533)) ([febeae5](/~https://github.com/muxinc/mux-node-sdk/commit/febeae5171526e60460024b6c46a142533eeb235)) +* **client:** send `X-Stainless-Timeout` header ([#542](/~https://github.com/muxinc/mux-node-sdk/issues/542)) ([bddd452](/~https://github.com/muxinc/mux-node-sdk/commit/bddd45248b23fb9b363ccdb75d442e9b6ff4aa1c)) +* generate more types that are used as request bodies ([#532](/~https://github.com/muxinc/mux-node-sdk/issues/532)) ([17dc3e2](/~https://github.com/muxinc/mux-node-sdk/commit/17dc3e216554bf18b3e015577f192c024c63bc38)) +* **internal:** make git install file structure match npm ([#527](/~https://github.com/muxinc/mux-node-sdk/issues/527)) ([10ae8eb](/~https://github.com/muxinc/mux-node-sdk/commit/10ae8ebf80dd4f2962739694229c700c55b682b3)) + + +### Bug Fixes + +* **client:** fix export map for index exports ([#545](/~https://github.com/muxinc/mux-node-sdk/issues/545)) ([228c810](/~https://github.com/muxinc/mux-node-sdk/commit/228c8101ed21732bca78383561cec082a0076e92)) +* **client:** normalize method ([#535](/~https://github.com/muxinc/mux-node-sdk/issues/535)) ([7993276](/~https://github.com/muxinc/mux-node-sdk/commit/799327684ce912491a776a272e0f13ad0ac23944)) + + +### Chores + +* deprecate `mp4_support` option ([#321](/~https://github.com/muxinc/mux-node-sdk/issues/321)) ([#547](/~https://github.com/muxinc/mux-node-sdk/issues/547)) ([1562daa](/~https://github.com/muxinc/mux-node-sdk/commit/1562daa64a421c7a31bf1330bc41c634b26b7319)) +* **internal:** bump cross-spawn to v7.0.6 ([#529](/~https://github.com/muxinc/mux-node-sdk/issues/529)) ([625f90b](/~https://github.com/muxinc/mux-node-sdk/commit/625f90b108126c7940dc668d5ee4e0bd6095b39a)) +* **internal:** codegen related update ([#538](/~https://github.com/muxinc/mux-node-sdk/issues/538)) ([7291076](/~https://github.com/muxinc/mux-node-sdk/commit/729107671e066d0966048f56ab97a42187632eb4)) +* **internal:** codegen related update ([#539](/~https://github.com/muxinc/mux-node-sdk/issues/539)) ([1ca421c](/~https://github.com/muxinc/mux-node-sdk/commit/1ca421c2aa6f3ec359d0d60f37535510a88c478f)) +* **internal:** codegen related update ([#541](/~https://github.com/muxinc/mux-node-sdk/issues/541)) ([81fe307](/~https://github.com/muxinc/mux-node-sdk/commit/81fe3077369f56adac67b69471a0512b65ed94d7)) +* **internal:** fix devcontainers setup ([#548](/~https://github.com/muxinc/mux-node-sdk/issues/548)) ([b916855](/~https://github.com/muxinc/mux-node-sdk/commit/b9168551c77fd14be61545fd8e680828e0892957)) +* **internal:** fix some typos ([#534](/~https://github.com/muxinc/mux-node-sdk/issues/534)) ([5ea0e8e](/~https://github.com/muxinc/mux-node-sdk/commit/5ea0e8e9c26fe491f63c44be522748c1e267bf5e)) +* **internal:** remove unnecessary getRequestClient function ([#528](/~https://github.com/muxinc/mux-node-sdk/issues/528)) ([a8a00ef](/~https://github.com/muxinc/mux-node-sdk/commit/a8a00eff2bb0586d5780c93199d120b5673f0d49)) +* **internal:** update isAbsoluteURL ([#531](/~https://github.com/muxinc/mux-node-sdk/issues/531)) ([e1b231d](/~https://github.com/muxinc/mux-node-sdk/commit/e1b231dabdd236cb773de2e9e13c26ca8866356b)) +* rebuild project due to codegen change ([#523](/~https://github.com/muxinc/mux-node-sdk/issues/523)) ([9cc566c](/~https://github.com/muxinc/mux-node-sdk/commit/9cc566cdeba6d3e1f6ed6bcd4643ecbafedda110)) +* remove redundant word in comment ([#526](/~https://github.com/muxinc/mux-node-sdk/issues/526)) ([f5dd390](/~https://github.com/muxinc/mux-node-sdk/commit/f5dd3901391cb3d210a42cbfe4874e203013107a)) +* **types:** nicer error class types + jsdocs ([#530](/~https://github.com/muxinc/mux-node-sdk/issues/530)) ([2b6cf7e](/~https://github.com/muxinc/mux-node-sdk/commit/2b6cf7e1da6895a7a1f5ab348f8b28f82dcc856d)) + + +### Documentation + +* minor formatting changes ([#537](/~https://github.com/muxinc/mux-node-sdk/issues/537)) ([69e736a](/~https://github.com/muxinc/mux-node-sdk/commit/69e736a7f8b7f24a23624f3ba9e0cefb35bd1415)) +* remove suggestion to use `npm` call out ([#525](/~https://github.com/muxinc/mux-node-sdk/issues/525)) ([a1250bc](/~https://github.com/muxinc/mux-node-sdk/commit/a1250bcb104d1e0a93cec2bcc19d96d56f323fe9)) + ## 9.0.1 (2024-11-15) Full Changelog: [v9.0.0...v9.0.1](/~https://github.com/muxinc/mux-node-sdk/compare/v9.0.0...v9.0.1) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4645e0eb..7028c3a9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ ## Setting up the environment -This repository uses [`yarn@v1`](https://classic.yarnpkg.com/lang/en/docs/install/#mac-stable). +This repository uses [`yarn@v1`](https://classic.yarnpkg.com/lang/en/docs/install). Other package managers may work but are not officially supported for development. To set up the repository, run: @@ -29,10 +29,10 @@ All files in the `examples/` directory are not modified by the generator and can … ``` -``` -chmod +x examples/.ts +```sh +$ chmod +x examples/.ts # run the example against your api -yarn tsn -T examples/.ts +$ yarn tsn -T examples/.ts ``` ## Using the repository from source diff --git a/LICENSE b/LICENSE index ec586984..f3477ce7 100644 --- a/LICENSE +++ b/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright 2024 Mux + Copyright 2025 Mux Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md index d645befa..9dd72726 100644 --- a/README.md +++ b/README.md @@ -518,7 +518,7 @@ await client.video.assets.retrieve('t02rm...', { This package generally follows [SemVer](https://semver.org/spec/v2.0.0.html) conventions, though certain backwards-incompatible changes may be released as minor versions: 1. Changes that only affect static types, without breaking runtime behavior. -2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals)_. +2. Changes to library internals which are technically public but not intended or documented for external use. _(Please open a GitHub issue to let us know if you are relying on such internals.)_ 3. Changes that we do not expect to impact the vast majority of users in practice. We take backwards-compatibility seriously and work hard to ensure you can rely on a smooth upgrade experience. @@ -533,7 +533,7 @@ 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"`. +- Deno v1.28.0 or higher. - Bun 1.0 or later. - Cloudflare Workers. - Vercel Edge Runtime. diff --git a/api.md b/api.md index 14c3e4dc..e4c05b69 100644 --- a/api.md +++ b/api.md @@ -337,6 +337,7 @@ Types: - VideoAssetTrackErroredWebhookEvent - VideoAssetTrackDeletedWebhookEvent - VideoAssetWarningWebhookEvent +- VideoAssetNonStandardInputDetectedWebhookEvent - VideoUploadAssetCreatedWebhookEvent - VideoUploadCancelledWebhookEvent - VideoUploadCreatedWebhookEvent diff --git a/package.json b/package.json index a475ccea..5822e195 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mux/mux-node", - "version": "9.0.1", + "version": "10.0.0", "description": "The official TypeScript library for the Mux API", "author": "Mux ", "types": "dist/index.d.ts", @@ -18,7 +18,7 @@ "build": "./scripts/build", "prepublishOnly": "echo 'to publish, run yarn build && (cd dist; yarn publish)' && exit 1", "format": "prettier --write --cache --cache-strategy metadata . !dist", - "prepare": "if ./scripts/utils/check-is-in-git-install.sh; then ./scripts/build; fi", + "prepare": "if ./scripts/utils/check-is-in-git-install.sh; then ./scripts/build && ./scripts/utils/git-swap.sh; fi", "tsn": "ts-node -r tsconfig-paths/register", "lint": "./scripts/lint", "fix": "./scripts/format" @@ -108,17 +108,38 @@ "default": "./dist/index.mjs" }, "./*.mjs": { - "types": "./dist/*.d.ts", - "default": "./dist/*.mjs" + "types": [ + "./dist/*.d.ts", + "./dist/*/index.d.ts" + ], + "default": [ + "./dist/*.mjs", + "./dist/*/index.mjs" + ] }, "./*.js": { - "types": "./dist/*.d.ts", - "default": "./dist/*.js" + "types": [ + "./dist/*.d.ts", + "./dist/*/index.d.ts" + ], + "default": [ + "./dist/*.js", + "./dist/*/index.js" + ] }, "./*": { - "types": "./dist/*.d.ts", - "require": "./dist/*.js", - "default": "./dist/*.mjs" + "types": [ + "./dist/*.d.ts", + "./dist/*/index.d.ts" + ], + "require": [ + "./dist/*.js", + "./dist/*/index.js" + ], + "default": [ + "./dist/*.mjs", + "./dist/*/index.mjs" + ] } } } diff --git a/scripts/build b/scripts/build index f46b7e6e..18c90823 100755 --- a/scripts/build +++ b/scripts/build @@ -32,7 +32,7 @@ npm exec tsc-multi # copy over handwritten .js/.mjs/.d.ts files cp src/_shims/*.{d.ts,js,mjs,md} dist/_shims cp src/_shims/auto/*.{d.ts,js,mjs} dist/_shims/auto -# we need to add exports = module.exports = Mux Node to index.js; +# we need to add exports = module.exports = Mux to index.js; # No way to get that from index.ts because it would cause compile errors # when building .mjs node scripts/utils/fix-index-exports.cjs diff --git a/scripts/utils/check-is-in-git-install.sh b/scripts/utils/check-is-in-git-install.sh index 36bcedc2..1354eb43 100755 --- a/scripts/utils/check-is-in-git-install.sh +++ b/scripts/utils/check-is-in-git-install.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # Check if you happen to call prepare for a repository that's already in node_modules. [ "$(basename "$(dirname "$PWD")")" = 'node_modules' ] || # The name of the containing directory that 'npm` uses, which looks like diff --git a/scripts/utils/git-swap.sh b/scripts/utils/git-swap.sh new file mode 100755 index 00000000..79d1888e --- /dev/null +++ b/scripts/utils/git-swap.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -exuo pipefail +# the package is published to NPM from ./dist +# we want the final file structure for git installs to match the npm installs, so we + +# delete everything except ./dist and ./node_modules +find . -maxdepth 1 -mindepth 1 ! -name 'dist' ! -name 'node_modules' -exec rm -rf '{}' + + +# move everything from ./dist to . +mv dist/* . + +# delete the now-empty ./dist +rmdir dist diff --git a/src/core.ts b/src/core.ts index 790e1848..d0731041 100644 --- a/src/core.ts +++ b/src/core.ts @@ -163,7 +163,7 @@ export abstract class APIClient { maxRetries = 2, timeout = 60000, // 1 minute httpAgent, - fetch: overridenFetch, + fetch: overriddenFetch, }: { baseURL: string; maxRetries?: number | undefined; @@ -176,7 +176,7 @@ export abstract class APIClient { this.timeout = validatePositiveInteger('timeout', timeout); this.httpAgent = httpAgent; - this.fetch = overridenFetch ?? fetch; + this.fetch = overriddenFetch ?? fetch; } protected authHeaders(opts: FinalRequestOptions): Headers { @@ -268,6 +268,7 @@ export abstract class APIClient { options: FinalRequestOptions, { retryCount = 0 }: { retryCount?: number } = {}, ): { req: RequestInit; url: string; timeout: number } { + options = { ...options }; const { method, path, query, headers: headers = {} } = options; const body = @@ -278,9 +279,9 @@ export abstract class APIClient { const url = this.buildURL(path!, query); if ('timeout' in options) validatePositiveInteger('timeout', options.timeout); - const timeout = options.timeout ?? this.timeout; + options.timeout = options.timeout ?? this.timeout; const httpAgent = options.httpAgent ?? this.httpAgent ?? getDefaultAgent(url); - const minAgentTimeout = timeout + 1000; + const minAgentTimeout = options.timeout + 1000; if ( typeof (httpAgent as any)?.options?.timeout === 'number' && minAgentTimeout > ((httpAgent as any).options.timeout ?? 0) @@ -309,7 +310,7 @@ export abstract class APIClient { signal: options.signal ?? null, }; - return { req, url, timeout }; + return { req, url, timeout: options.timeout }; } private buildHeaders({ @@ -337,15 +338,22 @@ 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. + // Don't set theses headers if they were 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); } + if ( + getHeader(defaultHeaders, 'x-stainless-timeout') === undefined && + getHeader(headers, 'x-stainless-timeout') === undefined && + options.timeout + ) { + reqHeaders['x-stainless-timeout'] = String(options.timeout); + } this.validateHeaders(reqHeaders, headers); @@ -508,20 +516,24 @@ export abstract class APIClient { const timeout = setTimeout(() => controller.abort(), ms); + const fetchOptions = { + signal: controller.signal as any, + ...options, + }; + if (fetchOptions.method) { + // Custom methods like 'patch' need to be uppercased + // See /~https://github.com/nodejs/undici/issues/2294 + fetchOptions.method = fetchOptions.method.toUpperCase(); + } + return ( - this.getRequestClient() - // use undefined this binding; fetch errors if bound to something else in browser/cloudflare - .fetch.call(undefined, url, { signal: controller.signal as any, ...options }) - .finally(() => { - clearTimeout(timeout); - }) + // use undefined this binding; fetch errors if bound to something else in browser/cloudflare + this.fetch.call(undefined, url, fetchOptions).finally(() => { + clearTimeout(timeout); + }) ); } - protected getRequestClient(): RequestClient { - return { fetch: this.fetch }; - } - private shouldRetry(response: Response): boolean { // Note this is not a standard header. const shouldRetryHeader = response.headers.get('x-should-retry'); @@ -957,8 +969,8 @@ export const safeJSON = (text: string) => { } }; -// https://stackoverflow.com/a/19709846 -const startsWithSchemeRegexp = new RegExp('^(?:[a-z]+:)?//', 'i'); +// https://url.spec.whatwg.org/#url-scheme-string +const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i; const isAbsoluteURL = (url: string): boolean => { return startsWithSchemeRegexp.test(url); }; diff --git a/src/error.ts b/src/error.ts index 764b9185..4485cb26 100644 --- a/src/error.ts +++ b/src/error.ts @@ -4,17 +4,19 @@ import { castToError, Headers } from './core'; export class MuxError extends Error {} -export class APIError extends MuxError { - readonly status: number | undefined; - readonly headers: Headers | undefined; - readonly error: Object | undefined; - - constructor( - status: number | undefined, - error: Object | undefined, - message: string | undefined, - headers: Headers | undefined, - ) { +export class APIError< + TStatus extends number | undefined = number | undefined, + THeaders extends Headers | undefined = Headers | undefined, + TError extends Object | undefined = Object | undefined, +> extends MuxError { + /** HTTP status for the response that caused the error */ + readonly status: TStatus; + /** HTTP headers for the response that caused the error */ + readonly headers: THeaders; + /** JSON body of the response that caused the error */ + readonly error: TError; + + constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) { super(`${APIError.makeMessage(status, error, message)}`); this.status = status; this.headers = headers; @@ -48,7 +50,7 @@ export class APIError extends MuxError { message: string | undefined, headers: Headers | undefined, ): APIError { - if (!status) { + if (!status || !headers) { return new APIConnectionError({ message, cause: castToError(errorResponse) }); } @@ -90,17 +92,13 @@ export class APIError extends MuxError { } } -export class APIUserAbortError extends APIError { - override readonly status: undefined = undefined; - +export class APIUserAbortError extends APIError { constructor({ message }: { message?: string } = {}) { super(undefined, undefined, message || 'Request was aborted.', undefined); } } -export class APIConnectionError extends APIError { - override readonly status: undefined = undefined; - +export class APIConnectionError extends APIError { 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 @@ -115,32 +113,18 @@ export class APIConnectionTimeoutError extends APIConnectionError { } } -export class BadRequestError extends APIError { - override readonly status: 400 = 400; -} +export class BadRequestError extends APIError<400, Headers> {} -export class AuthenticationError extends APIError { - override readonly status: 401 = 401; -} +export class AuthenticationError extends APIError<401, Headers> {} -export class PermissionDeniedError extends APIError { - override readonly status: 403 = 403; -} +export class PermissionDeniedError extends APIError<403, Headers> {} -export class NotFoundError extends APIError { - override readonly status: 404 = 404; -} +export class NotFoundError extends APIError<404, Headers> {} -export class ConflictError extends APIError { - override readonly status: 409 = 409; -} +export class ConflictError extends APIError<409, Headers> {} -export class UnprocessableEntityError extends APIError { - override readonly status: 422 = 422; -} +export class UnprocessableEntityError extends APIError<422, Headers> {} -export class RateLimitError extends APIError { - override readonly status: 429 = 429; -} +export class RateLimitError extends APIError<429, Headers> {} -export class InternalServerError extends APIError {} +export class InternalServerError extends APIError {} diff --git a/src/index.ts b/src/index.ts index 486c4a54..8015f909 100644 --- a/src/index.ts +++ b/src/index.ts @@ -58,7 +58,7 @@ export interface ClientOptions { * Note that request timeouts are retried by default, so in a worst-case scenario you may wait * much longer than this timeout before the promise succeeds or fails. */ - timeout?: number; + timeout?: number | undefined; /** * An HTTP agent used to manage HTTP(S) connections. @@ -66,7 +66,7 @@ export interface ClientOptions { * If not provided, an agent will be constructed by default in the Node.js environment, * otherwise no agent is used. */ - httpAgent?: Agent; + httpAgent?: Agent | undefined; /** * Specify a custom `fetch` function implementation. @@ -82,7 +82,7 @@ export interface ClientOptions { * * @default 2 */ - maxRetries?: number; + maxRetries?: number | undefined; /** * Default headers to include with every request to the API. @@ -90,7 +90,7 @@ export interface ClientOptions { * These can be removed in individual requests by explicitly setting the * header to `undefined` or `null` in request options. */ - defaultHeaders?: Core.Headers; + defaultHeaders?: Core.Headers | undefined; /** * Default query parameters to include with every request to the API. @@ -98,7 +98,7 @@ export interface ClientOptions { * These can be removed in individual requests by explicitly setting the * param to `undefined` in request options. */ - defaultQuery?: Core.DefaultQuery; + defaultQuery?: Core.DefaultQuery | undefined; } /** diff --git a/src/resources/data/metrics.ts b/src/resources/data/metrics.ts index 5953cf1e..061245a2 100644 --- a/src/resources/data/metrics.ts +++ b/src/resources/data/metrics.ts @@ -918,7 +918,23 @@ export interface MetricListParams { | 'viewer_user_id' | 'ad_playback_failure' | 'content_playback_failure' - | 'view_dropped'; + | 'view_dropped' + | 'client_application_name' + | 'client_application_version' + | 'video_affiliate' + | 'viewer_plan' + | 'viewer_plan_status' + | 'viewer_plan_category' + | 'view_drm_level' + | 'video_brand' + | 'used_pip' + | 'time_shift_enabled' + | 'used_captions' + | 'video_codec' + | 'audio_codec' + | 'video_dynamic_range_type' + | 'view_cdn_edge_pop' + | 'view_cdn_origin'; /** * Limit the results to rows that match conditions from provided key:value pairs. @@ -1276,7 +1292,23 @@ export interface MetricListBreakdownValuesParams extends BasePageParams { | 'viewer_user_id' | 'ad_playback_failure' | 'content_playback_failure' - | 'view_dropped'; + | 'view_dropped' + | 'client_application_name' + | 'client_application_version' + | 'video_affiliate' + | 'viewer_plan' + | 'viewer_plan_status' + | 'viewer_plan_category' + | 'view_drm_level' + | 'video_brand' + | 'used_pip' + | 'time_shift_enabled' + | 'used_captions' + | 'video_codec' + | 'audio_codec' + | 'video_dynamic_range_type' + | 'view_cdn_edge_pop' + | 'view_cdn_origin'; /** * Measurement for the provided metric. If omitted, the default for the metric will diff --git a/src/resources/data/video-views.ts b/src/resources/data/video-views.ts index 55864b10..9bac9b62 100644 --- a/src/resources/data/video-views.ts +++ b/src/resources/data/video-views.ts @@ -109,6 +109,8 @@ export namespace VideoViewResponse { asset_id: string | null; + audio_codec: string | null; + buffering_count: number | null; buffering_duration: number | null; @@ -119,6 +121,10 @@ export namespace VideoViewResponse { city: string | null; + client_application_name: string | null; + + client_application_version: string | null; + continent_code: string | null; country_code: string | null; @@ -283,16 +289,30 @@ export namespace VideoViewResponse { sub_property_id: string | null; + time_shift_enabled: boolean; + time_to_first_frame: number | null; updated_at: string; + used_captions: boolean; + used_fullscreen: boolean; + used_pip: boolean; + + video_affiliate: string | null; + + video_brand: string | null; + + video_codec: string | null; + video_content_type: string | null; video_duration: number | null; + video_dynamic_range_type: string | null; + video_encoding_variant: string | null; video_id: string | null; @@ -323,8 +343,14 @@ export namespace VideoViewResponse { view_average_request_throughput: number | null; + view_cdn_edge_pop: string | null; + + view_cdn_origin: string | null; + view_content_startup_time: number | null; + view_drm_level: string | null; + view_drm_type: string | null; view_dropped: boolean; @@ -387,6 +413,12 @@ export namespace VideoViewResponse { viewer_os_version: string | null; + viewer_plan: string | null; + + viewer_plan_category: string | null; + + viewer_plan_status: string | null; + viewer_user_agent: string | null; viewer_user_id: string | null; diff --git a/src/resources/video/assets.ts b/src/resources/video/assets.ts index 9460f327..b5128865 100644 --- a/src/resources/video/assets.ts +++ b/src/resources/video/assets.ts @@ -192,6 +192,8 @@ export class Assets extends APIResource { } /** + * This method has been deprecated. Please see the + * [Static Rendition API](https://www.mux.com/docs/guides/enable-static-mp4-renditions#after-asset-creation). * Allows you to add or remove mp4 support for assets that were created without it. * The values supported are `capped-1080p`, `audio-only`, * `audio-only,capped-1080p`, `standard`(deprecated), and `none`. `none` means that @@ -225,7 +227,7 @@ export interface Asset { created_at: string; /** - * @deprecated: This field is deprecated. Please use `video_quality` instead. The + * @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) @@ -240,8 +242,6 @@ export interface Asset { */ max_resolution_tier: '1080p' | '1440p' | '2160p'; - mp4_support: 'standard' | 'none' | 'capped-1080p' | 'audio-only' | 'audio-only,capped-1080p'; - /** * The status of the asset. */ @@ -297,13 +297,18 @@ export interface Asset { max_stored_frame_rate?: number; /** - * @deprecated: This field is deprecated. Please use `resolution_tier` instead. The + * @deprecated This field is deprecated. Please use `resolution_tier` instead. The * maximum resolution that has been stored for the asset. The asset may be * delivered at lower resolutions depending on the device and bandwidth, however it * cannot be delivered at a higher value than is stored. */ max_stored_resolution?: 'Audio only' | 'SD' | 'HD' | 'FHD' | 'UHD'; + /** + * @deprecated + */ + mp4_support?: 'standard' | 'none' | 'capped-1080p' | 'audio-only' | 'audio-only,capped-1080p'; + /** * An object containing one or more reasons the input file is non-standard. See * [the guide on minimizing processing time](https://docs.mux.com/guides/minimize-processing-time) @@ -535,13 +540,20 @@ export namespace Asset { files?: Array; /** - * Indicates the status of downloadable MP4 versions of this asset. + * Indicates the status of downloadable MP4 versions of this asset. This field is + * only valid when `mp4_support` is enabled */ status?: 'ready' | 'preparing' | 'disabled' | 'errored'; } export namespace StaticRenditions { export interface File { + /** + * The ID of this static rendition, used in managing this static rendition. This + * field is only valid for `static_renditions`, not for `mp4_support`. + */ + id?: string; + /** * The bitrate in bits per second */ @@ -562,7 +574,73 @@ export namespace Asset { */ height?: number; - name?: 'low.mp4' | 'medium.mp4' | 'high.mp4' | 'audio.m4a' | 'capped-1080p.mp4'; + /** + * Name of the static rendition file + */ + name?: + | 'low.mp4' + | 'medium.mp4' + | 'high.mp4' + | 'highest.mp4' + | 'audio.m4a' + | 'capped-1080p.mp4' + | '2160p.mp4' + | '1440p.mp4' + | '1080p.mp4' + | '720p.mp4' + | '540p.mp4' + | '480p.mp4' + | '360p.mp4' + | '270p.mp4'; + + /** + * Arbitrary user-supplied metadata set for the static rendition. Max 255 + * characters. + */ + passthrough?: string; + + /** + * Indicates the resolution of this specific MP4 version of this asset. This field + * is only valid for `static_renditions`, not for `mp4_support`. + */ + resolution?: + | 'highest' + | 'audio-only' + | '2160p' + | '1440p' + | '1080p' + | '720p' + | '540p' + | '480p' + | '360p' + | '270p'; + + /** + * Indicates the resolution tier of this specific MP4 version of this asset. This + * field is only valid for `static_renditions`, not for `mp4_support`. + */ + resolution_tier?: '2160p' | '1440p' | '1080p' | '720p'; + + /** + * Indicates the status of this specific MP4 version of this asset. This field is + * only valid for `static_renditions`, not for `mp4_support`. + * + * - `ready` indicates the MP4 has been generated and is ready for download + * - `preparing` indicates the asset has not been ingested or the static rendition + * is still being generated after an asset is ready + * - `skipped` indicates the static rendition will not be generated because the + * requested resolution conflicts with the asset attributes after the asset has + * been ingested + * - `errored` indicates the static rendition cannot be generated. For example, an + * asset could not be ingested + */ + status?: 'ready' | 'preparing' | 'skipped' | 'errored'; + + /** + * Indicates the static rendition type of this specific MP4 version of this asset. + * This field is only valid for `static_renditions`, not for `mp4_support`. + */ + type?: 'standard' | 'advanced'; /** * The width of the static rendition's file in pixels @@ -581,7 +659,7 @@ export interface AssetOptions { advanced_playback_policies?: Array; /** - * @deprecated: This field is deprecated. Please use `video_quality` instead. The + * @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) @@ -610,7 +688,12 @@ export interface AssetOptions { max_resolution_tier?: '1080p' | '1440p' | '2160p'; /** - * Specify what level of support for mp4 playback. + * @deprecated Deprecated. See the + * [Static Renditions API](https://www.mux.com/docs/guides/enable-static-mp4-renditions) + * for the updated API. + * + * Specify what level of support for mp4 playback. You may not enable both + * `mp4_support` and `static_renditions`. * * - The `capped-1080p` option produces a single MP4 file, called * `capped-1080p.mp4`, with the video resolution capped at 1080p. This option @@ -669,6 +752,12 @@ export interface AssetOptions { */ playback_policy?: Array; + /** + * An array of static renditions to create for this asset. You may not enable both + * `static_renditions` and `mp4_support (the latter being deprecated)` + */ + static_renditions?: Array; + /** * Marks the asset as a test asset when the value is set to true. A Test asset can * help evaluate the Mux Video APIs without incurring any cost. There is no limit @@ -769,7 +858,7 @@ export namespace AssetOptions { overlay_settings?: Input.OverlaySettings; /** - * This optional parameter should be used tracks with `type` of `text` and + * This optional parameter should be used for tracks with `type` of `text` and * `text_type` set to `subtitles`. */ passthrough?: string; @@ -921,6 +1010,26 @@ export namespace AssetOptions { width?: string; } } + + export interface StaticRendition { + resolution: + | 'highest' + | 'audio-only' + | '2160p' + | '1440p' + | '1080p' + | '720p' + | '540p' + | '480p' + | '360p' + | '270p'; + + /** + * Arbitrary user-supplied metadata set for the static rendition. Max 255 + * characters. + */ + passthrough?: string; + } } export interface AssetResponse { @@ -1027,7 +1136,7 @@ export namespace InputInfo { overlay_settings?: Settings.OverlaySettings; /** - * This optional parameter should be used tracks with `type` of `text` and + * This optional parameter should be used for tracks with `type` of `text` and * `text_type` set to `subtitles`. */ passthrough?: string; @@ -1210,7 +1319,7 @@ export interface Track { language_code?: string; /** - * @deprecated: Only set for the `audio` type track. + * @deprecated Only set for the `audio` type track. */ max_channel_layout?: string; @@ -1342,7 +1451,12 @@ export interface AssetCreateParams { max_resolution_tier?: '1080p' | '1440p' | '2160p'; /** - * Specify what level of support for mp4 playback. + * Deprecated. See the + * [Static Renditions API](https://www.mux.com/docs/guides/enable-static-mp4-renditions) + * for the updated API. + * + * Specify what level of support for mp4 playback. You may not enable both + * `mp4_support` and `static_renditions`. * * - The `capped-1080p` option produces a single MP4 file, called * `capped-1080p.mp4`, with the video resolution capped at 1080p. This option @@ -1398,6 +1512,12 @@ export interface AssetCreateParams { */ playback_policy?: Array; + /** + * An array of static renditions to create for this asset. You may not enable both + * `static_renditions` and `mp4_support (the latter being deprecated)` + */ + static_renditions?: Array; + /** * Marks the asset as a test asset when the value is set to true. A Test asset can * help evaluate the Mux Video APIs without incurring any cost. There is no limit @@ -1476,7 +1596,7 @@ export namespace AssetCreateParams { overlay_settings?: Input.OverlaySettings; /** - * This optional parameter should be used tracks with `type` of `text` and + * This optional parameter should be used for tracks with `type` of `text` and * `text_type` set to `subtitles`. */ passthrough?: string; @@ -1650,6 +1770,26 @@ export namespace AssetCreateParams { */ policy?: Shared.PlaybackPolicy; } + + export interface StaticRendition { + resolution: + | 'highest' + | 'audio-only' + | '2160p' + | '1440p' + | '1080p' + | '720p' + | '540p' + | '480p' + | '360p' + | '270p'; + + /** + * Arbitrary user-supplied metadata set for the static rendition. Max 255 + * characters. + */ + passthrough?: string; + } } export interface AssetUpdateParams { diff --git a/src/resources/video/delivery-usage.ts b/src/resources/video/delivery-usage.ts index b377eb87..6cf881bb 100644 --- a/src/resources/video/delivery-usage.ts +++ b/src/resources/video/delivery-usage.ts @@ -38,7 +38,7 @@ export interface DeliveryReport { asset_duration: number; /** - * @deprecated: This field is deprecated. Please use `asset_video_quality` instead. + * @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) */ diff --git a/src/resources/video/live-streams.ts b/src/resources/video/live-streams.ts index e170f083..eb525a5b 100644 --- a/src/resources/video/live-streams.ts +++ b/src/resources/video/live-streams.ts @@ -358,11 +358,11 @@ export interface LiveStream { generated_subtitles?: Array; /** - * @deprecated: This field is deprecated. Please use `latency_mode` instead. - * Latency is the time from when the streamer transmits a frame of video to when - * you see it in the player. Setting this option will enable compatibility with the - * LL-HLS specification for low-latency streaming. This typically has lower latency - * than Reduced Latency streams, and cannot be combined with Reduced Latency. + * @deprecated This field is deprecated. Please use `latency_mode` instead. Latency + * is the time from when the streamer transmits a frame of video to when you see it + * in the player. Setting this option will enable compatibility with the LL-HLS + * specification for low-latency streaming. This typically has lower latency than + * Reduced Latency streams, and cannot be combined with Reduced Latency. */ low_latency?: boolean; @@ -415,10 +415,9 @@ export interface LiveStream { reconnect_window?: number; /** - * @deprecated: This field is deprecated. Please use `latency_mode` instead. - * Latency is the time from when the streamer transmits a frame of video to when - * you see it in the player. Set this if you want lower latency for your live - * stream. See the + * @deprecated This field is deprecated. Please use `latency_mode` instead. Latency + * is the time from when the streamer transmits a frame of video to when you see it + * in the player. Set this if you want lower latency for your live stream. See the * [Reduce live stream latency guide](https://docs.mux.com/guides/reduce-live-stream-latency) * to understand the tradeoffs. */ @@ -805,7 +804,8 @@ export interface LiveStreamUpdateParams { /** * Updates the new asset settings to use to generate a new asset for this live - * stream. Only the `mp4_support` and `master_access` settings may be updated. + * stream. Only the `mp4_support`, `master_access`, and `video_quality` settings + * may be updated. */ new_asset_settings?: LiveStreamUpdateParams.NewAssetSettings; @@ -855,7 +855,8 @@ 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` and `master_access` settings may be updated. + * stream. Only the `mp4_support`, `master_access`, and `video_quality` settings + * may be updated. */ export interface NewAssetSettings { /** @@ -864,8 +865,10 @@ export namespace LiveStreamUpdateParams { master_access?: 'temporary' | 'none'; /** - * Specify what level of support for mp4 playback should be added to new assets - * generated from this live stream. + * @deprecated Deprecated. See the + * [Static Renditions API](https://www.mux.com/docs/guides/enable-static-mp4-renditions#during-live-stream-creation) + * for the updated API. Specify what level of support for mp4 playback should be + * added to new assets generated from this live stream. * * - The `none` option disables MP4 support for new assets. MP4 files will not be * produced for an asset generated from this live stream. @@ -884,6 +887,13 @@ export namespace LiveStreamUpdateParams { * `audio.m4a` for an audio-only asset). */ mp4_support?: 'none' | 'standard' | 'capped-1080p' | 'audio-only' | 'audio-only,capped-1080p'; + + /** + * The video quality controls the cost, quality, and available platform features + * for the asset. + * [See the video quality guide for more details.](https://docs.mux.com/guides/use-video-quality-levels) + */ + video_quality?: 'plus' | 'premium'; } } diff --git a/src/resources/webhooks.ts b/src/resources/webhooks.ts index c8272a26..4b59bad4 100644 --- a/src/resources/webhooks.ts +++ b/src/resources/webhooks.ts @@ -377,6 +377,12 @@ export interface VideoAssetWarningWebhookEvent extends BaseWebhookEvent { type: 'video.asset.warning'; } +export interface VideoAssetNonStandardInputDetectedWebhookEvent extends BaseWebhookEvent { + data: AssetsAPI.Asset; + + type: 'video.asset.non_standard_input_detected'; +} + export interface VideoUploadAssetCreatedWebhookEvent extends BaseWebhookEvent { data: UploadsAPI.Upload; @@ -537,7 +543,7 @@ export namespace VideoDeliveryHighTrafficWebhookEvent { asset_duration?: number; /** - * @deprecated: This field is deprecated. Please use `asset_video_quality` instead. + * @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) */ @@ -661,6 +667,7 @@ export type UnwrapWebhookEvent = | VideoAssetTrackErroredWebhookEvent | VideoAssetTrackDeletedWebhookEvent | VideoAssetWarningWebhookEvent + | VideoAssetNonStandardInputDetectedWebhookEvent | VideoUploadAssetCreatedWebhookEvent | VideoUploadCancelledWebhookEvent | VideoUploadCreatedWebhookEvent diff --git a/src/version.ts b/src/version.ts index 7706d0e9..0edc28fb 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '9.0.1'; // x-release-please-version +export const VERSION = '10.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 1fb76b31..a14961a4 100644 --- a/tests/api-resources/data/dimensions.test.ts +++ b/tests/api-resources/data/dimensions.test.ts @@ -51,13 +51,7 @@ describe('resource dimensions', () => { await expect( client.data.dimensions.listValues( 'abcd1234', - { - filters: ['string', 'string', 'string'], - limit: 0, - metric_filters: ['string', 'string', 'string'], - page: 0, - timeframe: ['string', 'string', 'string'], - }, + { filters: ['string'], limit: 0, metric_filters: ['string'], page: 0, timeframe: ['string'] }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Mux.NotFoundError); diff --git a/tests/api-resources/data/errors.test.ts b/tests/api-resources/data/errors.test.ts index e58581f0..410a4335 100644 --- a/tests/api-resources/data/errors.test.ts +++ b/tests/api-resources/data/errors.test.ts @@ -32,11 +32,7 @@ describe('resource errors', () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.data.errors.list( - { - filters: ['string', 'string', 'string'], - metric_filters: ['string', 'string', 'string'], - timeframe: ['string', 'string', 'string'], - }, + { filters: ['string'], metric_filters: ['string'], timeframe: ['string'] }, { 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 7acb4cf1..579d9a7e 100644 --- a/tests/api-resources/data/filters.test.ts +++ b/tests/api-resources/data/filters.test.ts @@ -33,12 +33,7 @@ describe('resource filters', () => { await expect( client.data.filters.listValues( 'abcd1234', - { - filters: ['string', 'string', 'string'], - limit: 0, - page: 0, - timeframe: ['string', 'string', 'string'], - }, + { filters: ['string'], limit: 0, page: 0, timeframe: ['string'] }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Mux.NotFoundError); diff --git a/tests/api-resources/data/metrics.test.ts b/tests/api-resources/data/metrics.test.ts index b1b16b97..d067f872 100644 --- a/tests/api-resources/data/metrics.test.ts +++ b/tests/api-resources/data/metrics.test.ts @@ -34,9 +34,9 @@ describe('resource metrics', () => { client.data.metrics.list( { dimension: 'asn', - filters: ['string', 'string', 'string'], - metric_filters: ['string', 'string', 'string'], - timeframe: ['string', 'string', 'string'], + filters: ['string'], + metric_filters: ['string'], + timeframe: ['string'], value: 'value', }, { path: '/_stainless_unknown_path' }, @@ -68,11 +68,11 @@ describe('resource metrics', () => { client.data.metrics.getInsights( 'aggregate_startup_time', { - filters: ['string', 'string', 'string'], + filters: ['string'], measurement: '95th', - metric_filters: ['string', 'string', 'string'], + metric_filters: ['string'], order_direction: 'asc', - timeframe: ['string', 'string', 'string'], + timeframe: ['string'], }, { path: '/_stainless_unknown_path' }, ), @@ -102,12 +102,7 @@ describe('resource metrics', () => { await expect( client.data.metrics.getOverallValues( 'aggregate_startup_time', - { - filters: ['string', 'string', 'string'], - measurement: '95th', - metric_filters: ['string', 'string', 'string'], - timeframe: ['string', 'string', 'string'], - }, + { filters: ['string'], measurement: '95th', metric_filters: ['string'], timeframe: ['string'] }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Mux.NotFoundError); @@ -137,12 +132,12 @@ describe('resource metrics', () => { client.data.metrics.getTimeseries( 'aggregate_startup_time', { - filters: ['string', 'string', 'string'], + filters: ['string'], group_by: 'minute', measurement: '95th', - metric_filters: ['string', 'string', 'string'], + metric_filters: ['string'], order_direction: 'asc', - timeframe: ['string', 'string', 'string'], + timeframe: ['string'], }, { path: '/_stainless_unknown_path' }, ), @@ -173,15 +168,15 @@ describe('resource metrics', () => { client.data.metrics.listBreakdownValues( 'aggregate_startup_time', { - filters: ['string', 'string', 'string'], + filters: ['string'], group_by: 'asn', limit: 0, measurement: '95th', - metric_filters: ['string', 'string', 'string'], + metric_filters: ['string'], order_by: 'negative_impact', order_direction: 'asc', page: 0, - timeframe: ['string', 'string', 'string'], + timeframe: ['string'], }, { path: '/_stainless_unknown_path' }, ), diff --git a/tests/api-resources/data/monitoring/metrics.test.ts b/tests/api-resources/data/monitoring/metrics.test.ts index cd195ac4..57ca0e47 100644 --- a/tests/api-resources/data/monitoring/metrics.test.ts +++ b/tests/api-resources/data/monitoring/metrics.test.ts @@ -55,7 +55,7 @@ describe('resource metrics', () => { 'current-concurrent-viewers', { dimension: 'asn', - filters: ['string', 'string', 'string'], + filters: ['string'], order_by: 'negative_impact', order_direction: 'asc', timestamp: 0, @@ -94,11 +94,11 @@ describe('resource metrics', () => { 'current-concurrent-viewers', { dimension: 'asn', - filters: ['string', 'string', 'string'], + filters: ['string'], limit: 0, order_by: 'negative_impact', order_direction: 'asc', - timeframe: ['string', 'string', 'string'], + timeframe: ['string'], }, { path: '/_stainless_unknown_path' }, ), @@ -130,7 +130,7 @@ describe('resource metrics', () => { await expect( client.data.monitoring.metrics.getHistogramTimeseries( 'video-startup-time', - { filters: ['string', 'string', 'string'] }, + { filters: ['string'] }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Mux.NotFoundError); @@ -161,7 +161,7 @@ describe('resource metrics', () => { await expect( client.data.monitoring.metrics.getTimeseries( 'current-concurrent-viewers', - { filters: ['string', 'string', 'string'], timestamp: 0 }, + { filters: ['string'], timestamp: 0 }, { 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 1c6a50b7..56c71383 100644 --- a/tests/api-resources/data/real-time.test.ts +++ b/tests/api-resources/data/real-time.test.ts @@ -73,7 +73,7 @@ describe('resource realTime', () => { 'current-concurrent-viewers', { dimension: 'asn', - filters: ['string', 'string', 'string'], + filters: ['string'], order_by: 'negative_impact', order_direction: 'asc', timestamp: 0, @@ -108,7 +108,7 @@ describe('resource realTime', () => { await expect( client.data.realTime.retrieveHistogramTimeseries( 'video-startup-time', - { filters: ['string', 'string', 'string'] }, + { filters: ['string'] }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Mux.NotFoundError); @@ -139,7 +139,7 @@ describe('resource realTime', () => { await expect( client.data.realTime.retrieveTimeseries( 'current-concurrent-viewers', - { filters: ['string', 'string', 'string'], timestamp: 0 }, + { filters: ['string'], timestamp: 0 }, { path: '/_stainless_unknown_path' }, ), ).rejects.toThrow(Mux.NotFoundError); diff --git a/tests/api-resources/data/video-views.test.ts b/tests/api-resources/data/video-views.test.ts index ca7707a6..504944cf 100644 --- a/tests/api-resources/data/video-views.test.ts +++ b/tests/api-resources/data/video-views.test.ts @@ -52,12 +52,12 @@ describe('resource videoViews', () => { client.data.videoViews.list( { error_id: 0, - filters: ['string', 'string', 'string'], + filters: ['string'], limit: 0, - metric_filters: ['string', 'string', 'string'], + metric_filters: ['string'], order_direction: 'asc', page: 0, - timeframe: ['string', 'string', 'string'], + timeframe: ['string'], viewer_id: 'viewer_id', }, { path: '/_stainless_unknown_path' }, diff --git a/tests/api-resources/video/assets.test.ts b/tests/api-resources/video/assets.test.ts index 9fee9b2b..30647e3a 100644 --- a/tests/api-resources/video/assets.test.ts +++ b/tests/api-resources/video/assets.test.ts @@ -27,11 +27,7 @@ describe('resource assets', () => { { 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' }, - ], + generated_subtitles: [{ language_code: 'en', name: 'name', passthrough: 'passthrough' }], language_code: 'language_code', name: 'name', overlay_settings: { @@ -50,11 +46,7 @@ describe('resource assets', () => { url: 'https://muxed.s3.amazonaws.com/leds.mp4', }, ], - 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' }, - ], + advanced_playback_policies: [{ drm_configuration_id: 'drm_configuration_id', policy: 'public' }], encoding_tier: 'smart', master_access: 'none', max_resolution_tier: '1080p', @@ -63,6 +55,7 @@ describe('resource assets', () => { passthrough: 'passthrough', per_title_encode: true, playback_policy: ['public'], + static_renditions: [{ resolution: 'highest', passthrough: 'passthrough' }], test: true, video_quality: 'basic', }); diff --git a/tests/api-resources/video/delivery-usage.test.ts b/tests/api-resources/video/delivery-usage.test.ts index f1c846f7..c4b9b676 100644 --- a/tests/api-resources/video/delivery-usage.test.ts +++ b/tests/api-resources/video/delivery-usage.test.ts @@ -32,13 +32,7 @@ describe('resource deliveryUsage', () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.video.deliveryUsage.list( - { - asset_id: 'asset_id', - limit: 0, - live_stream_id: 'live_stream_id', - page: 0, - timeframe: ['string', 'string', 'string'], - }, + { asset_id: 'asset_id', limit: 0, live_stream_id: 'live_stream_id', page: 0, timeframe: ['string'] }, { 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 6e158192..9171cbcd 100644 --- a/tests/api-resources/video/playback-restrictions.test.ts +++ b/tests/api-resources/video/playback-restrictions.test.ts @@ -98,7 +98,7 @@ describe('resource playbackRestrictions', () => { test('updateReferrer: only required params', async () => { const responsePromise = client.video.playbackRestrictions.updateReferrer('PLAYBACK_RESTRICTION_ID', { - allowed_domains: ['string', 'string', 'string'], + allowed_domains: ['*.example.com'], }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); @@ -111,7 +111,7 @@ describe('resource playbackRestrictions', () => { test('updateReferrer: required and optional params', async () => { const response = await client.video.playbackRestrictions.updateReferrer('PLAYBACK_RESTRICTION_ID', { - allowed_domains: ['string', 'string', 'string'], + allowed_domains: ['*.example.com'], allow_no_referrer: true, }); }); diff --git a/tests/api-resources/video/transcription-vocabularies.test.ts b/tests/api-resources/video/transcription-vocabularies.test.ts index 066a519d..5889f8ab 100644 --- a/tests/api-resources/video/transcription-vocabularies.test.ts +++ b/tests/api-resources/video/transcription-vocabularies.test.ts @@ -94,7 +94,7 @@ describe('resource transcriptionVocabularies', () => { // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error await expect( client.video.transcriptionVocabularies.list( - { limit: 0, page: 0 }, + { limit: 10, page: 0 }, { 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 f360a449..2f3e9551 100644 --- a/tests/api-resources/video/uploads.test.ts +++ b/tests/api-resources/video/uploads.test.ts @@ -25,71 +25,13 @@ describe('resource uploads', () => { 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' }, - ], + advanced_playback_policies: [{ drm_configuration_id: 'drm_configuration_id', policy: 'public' }], encoding_tier: 'smart', input: [ { 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: { - height: 'height', - horizontal_align: 'left', - horizontal_margin: 'horizontal_margin', - opacity: 'opacity', - vertical_align: 'top', - vertical_margin: 'vertical_margin', - width: 'width', - }, - passthrough: 'passthrough', - start_time: 0, - text_type: 'subtitles', - type: 'video', - url: 'url', - }, - { - 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: { - height: 'height', - horizontal_align: 'left', - horizontal_margin: 'horizontal_margin', - opacity: 'opacity', - vertical_align: 'top', - vertical_margin: 'vertical_margin', - width: 'width', - }, - passthrough: 'passthrough', - start_time: 0, - text_type: 'subtitles', - type: 'video', - url: 'url', - }, - { - 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' }, - ], + generated_subtitles: [{ language_code: 'en', name: 'name', passthrough: 'passthrough' }], language_code: 'language_code', name: 'name', overlay_settings: { @@ -115,6 +57,7 @@ describe('resource uploads', () => { passthrough: 'passthrough', per_title_encode: true, playback_policy: ['public'], + static_renditions: [{ resolution: 'highest', passthrough: 'passthrough' }], test: true, video_quality: 'basic', }, diff --git a/tests/index.test.ts b/tests/index.test.ts index ab42fae9..6b1f66a0 100644 --- a/tests/index.test.ts +++ b/tests/index.test.ts @@ -101,6 +101,16 @@ describe('instantiate client', () => { expect(response).toEqual({ url: 'http://localhost:5000/foo', custom: true }); }); + test('explicit global fetch', async () => { + // make sure the global fetch type is assignable to our Fetch type + const client = new Mux({ + baseURL: 'http://localhost:5000/', + tokenId: 'my token id', + tokenSecret: 'my secret', + fetch: defaultFetch, + }); + }); + test('custom signal', async () => { const client = new Mux({ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', @@ -128,6 +138,24 @@ describe('instantiate client', () => { expect(spy).toHaveBeenCalledTimes(1); }); + test('normalized method', async () => { + let capturedRequest: RequestInit | undefined; + const testFetch = async (url: RequestInfo, init: RequestInit = {}): Promise => { + capturedRequest = init; + return new Response(JSON.stringify({}), { headers: { 'Content-Type': 'application/json' } }); + }; + + const client = new Mux({ + baseURL: 'http://localhost:5000/', + tokenId: 'my token id', + tokenSecret: 'my secret', + fetch: testFetch, + }); + + await client.patch('/foo'); + expect(capturedRequest?.method).toEqual('PATCH'); + }); + describe('baseUrl', () => { test('trailing slash', () => { const client = new Mux({ @@ -197,7 +225,7 @@ describe('instantiate client', () => { expect(client.tokenSecret).toBe('my secret'); }); - test('with overriden environment variable arguments', () => { + test('with overridden environment variable arguments', () => { // set options via env var process.env['MUX_TOKEN_ID'] = 'another my token id'; process.env['MUX_TOKEN_SECRET'] = 'another my secret'; diff --git a/yarn.lock b/yarn.lock index 60a04a50..7ad1b05f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1370,9 +1370,9 @@ create-require@^1.1.0: integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0"