@mux/ai 0.44.0 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import { S as SafetyReport, e as PromptOverrides, h as SceneContextItemV1, D as
3
3
  import { createAnthropic } from '@ai-sdk/anthropic';
4
4
  import { createGoogleGenerativeAI } from '@ai-sdk/google';
5
5
  import { createOpenAI } from '@ai-sdk/openai';
6
- import { l as WorkflowCredentialsInput, d as MuxAsset, A as AssetTextTrack, f as ScopedMuxAIOptions, I as ImageSubmissionMode, i as TokenUsage, M as MuxAIOptions, b as ChunkingStrategy, k as VideoEmbeddingsResult, H as Hotspot, v as Shot, j as ToneType, g as StorageAdapter } from './shots-CUI09Ohe.js';
6
+ import { l as WorkflowCredentialsInput, d as MuxAsset, A as AssetTextTrack, f as ScopedMuxAIOptions, I as ImageSubmissionMode, i as TokenUsage, M as MuxAIOptions, b as ChunkingStrategy, k as VideoEmbeddingsResult, H as Hotspot, v as Shot, j as ToneType, g as StorageAdapter } from './shots-BwpjZDpr.js';
7
7
 
8
8
  /**
9
9
  * Language Code Conversion Utilities
@@ -490,17 +490,17 @@ declare const questionAnswerSchema: z.ZodObject<{
490
490
  reasoning: z.ZodString;
491
491
  skipped: z.ZodBoolean;
492
492
  }, "strip", z.ZodTypeAny, {
493
+ skipped: boolean;
493
494
  question: string;
494
495
  answer: string | null;
495
496
  confidence: number;
496
497
  reasoning: string;
497
- skipped: boolean;
498
498
  }, {
499
+ skipped: boolean;
499
500
  question: string;
500
501
  answer: string | null;
501
502
  confidence: number;
502
503
  reasoning: string;
503
- skipped: boolean;
504
504
  }>;
505
505
  type QuestionAnswerType = z.infer<typeof questionAnswerSchema>;
506
506
  /**
@@ -517,33 +517,33 @@ declare function createAskQuestionsSchema(answerSchema: z.ZodType<string>): z.Zo
517
517
  } & {
518
518
  answer: z.ZodType<string, z.ZodTypeDef, string>;
519
519
  }, "strip", z.ZodTypeAny, {
520
+ skipped: boolean;
520
521
  question: string;
521
522
  answer: string;
522
523
  confidence: number;
523
524
  reasoning: string;
524
- skipped: boolean;
525
525
  }, {
526
+ skipped: boolean;
526
527
  question: string;
527
528
  answer: string;
528
529
  confidence: number;
529
530
  reasoning: string;
530
- skipped: boolean;
531
531
  }>, "many">;
532
532
  }, "strip", z.ZodTypeAny, {
533
533
  answers: {
534
+ skipped: boolean;
534
535
  question: string;
535
536
  answer: string;
536
537
  confidence: number;
537
538
  reasoning: string;
538
- skipped: boolean;
539
539
  }[];
540
540
  }, {
541
541
  answers: {
542
+ skipped: boolean;
542
543
  question: string;
543
544
  answer: string;
544
545
  confidence: number;
545
546
  reasoning: string;
546
- skipped: boolean;
547
547
  }[];
548
548
  }>;
549
549
  type AskQuestionsSchema = ReturnType<typeof createAskQuestionsSchema>;
@@ -1,4 +1,4 @@
1
- import { l as WorkflowCredentialsInput, n as WorkflowScope, A as AssetTextTrack, d as MuxAsset, T as TextChunk, b as ChunkingStrategy, q as CompletedShotsResult, r as ErroredShotsResult, H as Hotspot, s as HotspotOptions, t as HotspotResponse, u as PendingShotsResult, v as Shot, w as ShotRequestOptions, x as ShotsResult, y as WaitForShotsOptions, z as getHotspotsForAsset, B as getHotspotsForPlaybackId, D as getHotspotsForVideo, F as getShotsForAsset, G as requestShotsForAsset, J as waitForShotsForAsset } from './shots-CUI09Ohe.js';
1
+ import { l as WorkflowCredentialsInput, n as WorkflowScope, A as AssetTextTrack, d as MuxAsset, T as TextChunk, b as ChunkingStrategy, q as CompletedShotsResult, r as ErroredShotsResult, H as Hotspot, s as HotspotOptions, t as HotspotResponse, u as PendingShotsResult, v as Shot, w as ShotRequestOptions, x as ShotsResult, y as WaitForShotsOptions, z as getHotspotsForAsset, B as getHotspotsForPlaybackId, D as getHotspotsForVideo, F as getShotsForAsset, G as requestShotsForAsset, J as waitForShotsForAsset } from './shots-BwpjZDpr.js';
2
2
 
3
3
  interface HeatmapOptions {
4
4
  /** Time window for results, e.g., '7:days' (default: '7:days') */
@@ -10,38 +10,38 @@ interface HeatmapResponse {
10
10
  assetId?: string;
11
11
  videoId?: string;
12
12
  playbackId?: string;
13
- /** Array of 100 values representing engagement for each 1/100th of the video */
13
+ /** Engagement values across the video timeline, one per equal slice (currently 100) */
14
14
  heatmap: number[];
15
15
  timeframe: [number, number];
16
16
  }
17
17
  /**
18
18
  * Fetches engagement heatmap for a Mux asset.
19
- * Returns a length 100 array where each value represents how many times
20
- * that 1/100th of the video was watched.
19
+ * Returns an array where each value represents how many times
20
+ * that slice of the video was watched.
21
21
  *
22
22
  * @param assetId - The Mux asset ID
23
23
  * @param options - Heatmap query options
24
- * @returns Heatmap data with 100 engagement values
24
+ * @returns Heatmap data with per-bucket engagement values
25
25
  */
26
26
  declare function getHeatmapForAsset(assetId: string, options?: HeatmapOptions): Promise<HeatmapResponse>;
27
27
  /**
28
28
  * Fetches engagement heatmap for a Mux video ID.
29
- * Returns a length 100 array where each value represents how many times
30
- * that 1/100th of the video was watched.
29
+ * Returns an array where each value represents how many times
30
+ * that slice of the video was watched.
31
31
  *
32
32
  * @param videoId - The Mux video ID
33
33
  * @param options - Heatmap query options
34
- * @returns Heatmap data with 100 engagement values
34
+ * @returns Heatmap data with per-bucket engagement values
35
35
  */
36
36
  declare function getHeatmapForVideo(videoId: string, options?: HeatmapOptions): Promise<HeatmapResponse>;
37
37
  /**
38
38
  * Fetches engagement heatmap for a Mux playback ID.
39
- * Returns a length 100 array where each value represents how many times
40
- * that 1/100th of the video was watched.
39
+ * Returns an array where each value represents how many times
40
+ * that slice of the video was watched.
41
41
  *
42
42
  * @param playbackId - The Mux playback ID
43
43
  * @param options - Heatmap query options
44
- * @returns Heatmap data with 100 engagement values
44
+ * @returns Heatmap data with per-bucket engagement values
45
45
  */
46
46
  declare function getHeatmapForPlaybackId(playbackId: string, options?: HeatmapOptions): Promise<HeatmapResponse>;
47
47
 
package/dist/index.d.ts CHANGED
@@ -1,16 +1,16 @@
1
- export { I as ISO639_1, a as ISO639_3, L as LanguageCodePair, M as MUX_TRACK_PASSTHROUGH_MAX_CHARS, R as ReplaceAndCreateTextTrackInput, b as ReplaceAndCreateTextTrackResult, c as ReplaceAndCreateTrackInput, d as ReplaceExistingTracksPolicy, e as ReplaceableTrackType, S as SupportedISO639_1, f as SupportedISO639_3, T as TextTrackReplacementPlan, g as TextTrackSummary, h as TextTrackTarget, i as TrackSummary, j as TrackTarget, k as buildMuxAiTrackPassthrough, l as findNameCollisionTextTracks, m as findSameLanguageTextTracks, n as getLanguageCodePair, o as getLanguageName, p as isDuplicateTrackNameError, q as isMuxGeneratedTextTrack, r as isUndeterminedLanguageCode, s as isValidISO639_1, t as isValidISO639_3, u as normalizeTrackLanguageCode, v as normalizeTrackName, w as planTextTrackReplacement, x as replaceAndCreateTextTrack, y as replaceAndCreateTrack, z as summarizeTextTrack, A as toISO639_1, B as toISO639_3, C as validateTrackPassthrough, D as workflows } from './index-DigKByh7.js';
2
- import { W as WorkflowCredentials, S as StoragePutObjectInput, a as StoragePresignGetObjectInput } from './shots-CUI09Ohe.js';
3
- export { A as AssetTextTrack, C as ChunkEmbedding, b as ChunkingStrategy, E as Encrypted, c as EncryptedPayload, I as ImageSubmissionMode, M as MuxAIOptions, d as MuxAsset, P as PlaybackAsset, e as PlaybackPolicy, f as ScopedMuxAIOptions, g as StorageAdapter, T as TextChunk, h as TokenChunkingConfig, i as TokenUsage, j as ToneType, U as UsageMetadata, V as VTTChunkingConfig, k as VideoEmbeddingsResult, l as WorkflowCredentialsInput, m as WorkflowMuxClient, n as WorkflowScope, o as decryptFromWorkflow, p as encryptForWorkflow } from './shots-CUI09Ohe.js';
1
+ export { I as ISO639_1, a as ISO639_3, L as LanguageCodePair, M as MUX_TRACK_PASSTHROUGH_MAX_CHARS, R as ReplaceAndCreateTextTrackInput, b as ReplaceAndCreateTextTrackResult, c as ReplaceAndCreateTrackInput, d as ReplaceExistingTracksPolicy, e as ReplaceableTrackType, S as SupportedISO639_1, f as SupportedISO639_3, T as TextTrackReplacementPlan, g as TextTrackSummary, h as TextTrackTarget, i as TrackSummary, j as TrackTarget, k as buildMuxAiTrackPassthrough, l as findNameCollisionTextTracks, m as findSameLanguageTextTracks, n as getLanguageCodePair, o as getLanguageName, p as isDuplicateTrackNameError, q as isMuxGeneratedTextTrack, r as isUndeterminedLanguageCode, s as isValidISO639_1, t as isValidISO639_3, u as normalizeTrackLanguageCode, v as normalizeTrackName, w as planTextTrackReplacement, x as replaceAndCreateTextTrack, y as replaceAndCreateTrack, z as summarizeTextTrack, A as toISO639_1, B as toISO639_3, C as validateTrackPassthrough, D as workflows } from './index-CIcGZD3x.js';
2
+ import { W as WorkflowCredentials, S as StoragePutObjectInput, a as StoragePresignGetObjectInput } from './shots-BwpjZDpr.js';
3
+ export { A as AssetTextTrack, C as ChunkEmbedding, b as ChunkingStrategy, E as Encrypted, c as EncryptedPayload, I as ImageSubmissionMode, M as MuxAIOptions, d as MuxAsset, P as PlaybackAsset, e as PlaybackPolicy, f as ScopedMuxAIOptions, g as StorageAdapter, T as TextChunk, h as TokenChunkingConfig, i as TokenUsage, j as ToneType, U as UsageMetadata, V as VTTChunkingConfig, k as VideoEmbeddingsResult, l as WorkflowCredentialsInput, m as WorkflowMuxClient, n as WorkflowScope, o as decryptFromWorkflow, p as encryptForWorkflow } from './shots-BwpjZDpr.js';
4
4
  import { WORKFLOW_SERIALIZE, WORKFLOW_DESERIALIZE } from '@workflow/serde';
5
- export { i as primitives } from './index-C2Pk7bbF.js';
5
+ export { i as primitives } from './index-DAuzEXly.js';
6
6
  import 'zod';
7
7
  import './summarization-BFmhXeAu.js';
8
8
  import '@ai-sdk/anthropic';
9
9
  import '@ai-sdk/google';
10
10
  import '@ai-sdk/openai';
11
- import '@mux/mux-node';
11
+ import '@mux/ts';
12
12
 
13
- var version = "0.44.0";
13
+ var version = "0.46.0";
14
14
 
15
15
  type MuxAiErrorType = "validation_error" | "processing_error" | "timeout_error" | "content_policy_error";
16
16
  /**
@@ -43,6 +43,13 @@ declare class MuxAiError extends Error {
43
43
  }
44
44
  declare function wrapError(error: unknown, message: string): never;
45
45
 
46
+ type MuxPlaybackService = "image" | "stream";
47
+ /**
48
+ * Builds the playback origin for a Mux domain, matching Mux Player's `customDomain`
49
+ * expansion (e.g. "media.example.com" becomes "https://image.media.example.com").
50
+ */
51
+ declare function getMuxPlaybackOrigin(service: MuxPlaybackService, customDomain?: string): string;
52
+
46
53
  /**
47
54
  * A function that returns workflow credentials, either synchronously or asynchronously.
48
55
  * Used to inject credentials from external sources (e.g., a secrets manager).
@@ -77,4 +84,4 @@ declare class WorkflowStorageClient {
77
84
  }
78
85
  declare function createWorkflowStorageClient(options?: WorkflowStorageClientOptions): WorkflowStorageClient;
79
86
 
80
- export { MuxAiError, type MuxAiErrorType, StoragePresignGetObjectInput, StoragePutObjectInput, WorkflowCredentials, type WorkflowCredentialsProvider, WorkflowStorageClient, createWorkflowStorageClient, setWorkflowCredentialsProvider, version, wrapError };
87
+ export { MuxAiError, type MuxAiErrorType, type MuxPlaybackService, StoragePresignGetObjectInput, StoragePutObjectInput, WorkflowCredentials, type WorkflowCredentialsProvider, WorkflowStorageClient, createWorkflowStorageClient, getMuxPlaybackOrigin, setWorkflowCredentialsProvider, version, wrapError };
package/dist/index.js CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // package.json
8
- var version = "0.44.0";
8
+ var version = "0.46.0";
9
9
 
10
10
  // src/lib/language-codes.ts
11
11
  var ISO639_1_TO_3 = {
@@ -204,12 +204,16 @@ var EnvSchema = z.object({
204
204
  ),
205
205
  MUX_SIGNING_KEY: optionalString("Mux signing key ID for signed playback URLs.", "Used to sign playback URLs"),
206
206
  MUX_PRIVATE_KEY: optionalString("Mux signing private key for signed playback URLs.", "Used to sign playback URLs"),
207
+ MUX_CUSTOM_DOMAIN: optionalString(
208
+ "Mux domain for image.* and stream.* playback URLs, e.g. staging.mux.com or a custom domain (defaults to mux.com).",
209
+ "Mux custom domain"
210
+ ),
207
211
  MUX_IMAGE_URL_OVERRIDE: optionalString(
208
- "Override for Mux image base URL (defaults to https://image.mux.com).",
212
+ "Deprecated: use MUX_CUSTOM_DOMAIN. Override for Mux image base URL (defaults to https://image.mux.com).",
209
213
  "Mux image URL override"
210
214
  ),
211
215
  MUX_STREAM_URL_OVERRIDE: optionalString(
212
- "Override for Mux stream base URL (defaults to https://stream.mux.com).",
216
+ "Deprecated: use MUX_CUSTOM_DOMAIN. Override for Mux stream base URL (defaults to https://stream.mux.com).",
213
217
  "Mux stream URL override"
214
218
  ),
215
219
  MUX_BASE_URL: optionalString(
@@ -328,7 +332,18 @@ function parseEnv() {
328
332
  }
329
333
  return parsedEnv.data;
330
334
  }
335
+ var hasWarnedAboutDeprecatedUrlOverrides = false;
336
+ function warnOnDeprecatedUrlOverrides(parsed) {
337
+ if (hasWarnedAboutDeprecatedUrlOverrides || !parsed.MUX_IMAGE_URL_OVERRIDE && !parsed.MUX_STREAM_URL_OVERRIDE) {
338
+ return;
339
+ }
340
+ hasWarnedAboutDeprecatedUrlOverrides = true;
341
+ console.warn(
342
+ "MUX_IMAGE_URL_OVERRIDE and MUX_STREAM_URL_OVERRIDE are deprecated and will be removed in a future release. Set MUX_CUSTOM_DOMAIN instead (e.g. MUX_CUSTOM_DOMAIN=staging.mux.com for image.staging.mux.com and stream.staging.mux.com)."
343
+ );
344
+ }
331
345
  var env = parseEnv();
346
+ warnOnDeprecatedUrlOverrides(env);
332
347
  var env_default = env;
333
348
 
334
349
  // src/lib/prompt-fragments.ts
@@ -1040,7 +1055,7 @@ function resolveDirectMuxCredentials(record) {
1040
1055
  function createWorkflowMuxClient(options) {
1041
1056
  return {
1042
1057
  async createClient() {
1043
- const { default: MuxClient } = await import("@mux/mux-node");
1058
+ const { default: MuxClient } = await import("@mux/ts");
1044
1059
  return new MuxClient({
1045
1060
  tokenId: options.tokenId,
1046
1061
  tokenSecret: options.tokenSecret,
@@ -1354,6 +1369,82 @@ async function replaceAndCreateTextTrack(input) {
1354
1369
  return replaceAndCreateTrack({ ...input, target: { ...input.target, type: "text" } });
1355
1370
  }
1356
1371
 
1372
+ // src/lib/mux-url.ts
1373
+ var DEFAULT_MUX_DOMAIN = "mux.com";
1374
+ function normalizeOrigin(value, envVarName) {
1375
+ const trimmed = value.trim();
1376
+ const candidate = trimmed.includes("://") ? trimmed : `https://${trimmed}`;
1377
+ const exampleHostname = envVarName === "MUX_IMAGE_URL_OVERRIDE" ? "image.example.mux.com" : "stream.example.mux.com";
1378
+ let parsed;
1379
+ try {
1380
+ parsed = new URL(candidate);
1381
+ } catch {
1382
+ throw new Error(
1383
+ `Invalid ${envVarName}. Provide a hostname (e.g. "${exampleHostname}") or a URL origin (e.g. "https://${exampleHostname}").`
1384
+ );
1385
+ }
1386
+ if (parsed.username || parsed.password || parsed.search || parsed.hash || parsed.pathname && parsed.pathname !== "/") {
1387
+ throw new Error(
1388
+ `Invalid ${envVarName}. Only a hostname/origin is allowed (no credentials, query params, hash fragments, or path).`
1389
+ );
1390
+ }
1391
+ return parsed.origin;
1392
+ }
1393
+ function buildPlaybackOrigin(service, customDomain, source) {
1394
+ const invalidDomainError = new Error(
1395
+ `Invalid ${source}. Provide a bare hostname (e.g. "media.example.com") with no scheme, port, credentials, query params, hash fragments, or path.`
1396
+ );
1397
+ const trimmed = customDomain.trim();
1398
+ if (!trimmed) {
1399
+ throw invalidDomainError;
1400
+ }
1401
+ let parsed;
1402
+ try {
1403
+ parsed = new URL(`https://${service}.${trimmed}`);
1404
+ } catch {
1405
+ throw invalidDomainError;
1406
+ }
1407
+ if (parsed.port || parsed.username || parsed.password || parsed.search || parsed.hash || parsed.pathname !== "/") {
1408
+ throw invalidDomainError;
1409
+ }
1410
+ return parsed.origin;
1411
+ }
1412
+ function getMuxPlaybackOrigin(service, customDomain = DEFAULT_MUX_DOMAIN) {
1413
+ return buildPlaybackOrigin(service, customDomain, "custom domain");
1414
+ }
1415
+ async function resolveMuxPlaybackOrigin(service, credentials) {
1416
+ "use step";
1417
+ const { muxCustomDomain } = await resolveWorkflowCredentials(credentials);
1418
+ if (muxCustomDomain) {
1419
+ return buildPlaybackOrigin(service, muxCustomDomain, "muxCustomDomain");
1420
+ }
1421
+ const legacyOverrideEnvVarName = service === "image" ? "MUX_IMAGE_URL_OVERRIDE" : "MUX_STREAM_URL_OVERRIDE";
1422
+ const legacyOverride = env_default[legacyOverrideEnvVarName];
1423
+ if (legacyOverride) {
1424
+ return normalizeOrigin(legacyOverride, legacyOverrideEnvVarName);
1425
+ }
1426
+ if (env_default.MUX_CUSTOM_DOMAIN) {
1427
+ return buildPlaybackOrigin(service, env_default.MUX_CUSTOM_DOMAIN, "MUX_CUSTOM_DOMAIN");
1428
+ }
1429
+ return buildPlaybackOrigin(service, DEFAULT_MUX_DOMAIN, "custom domain");
1430
+ }
1431
+ async function getMuxImageOrigin(credentials) {
1432
+ return resolveMuxPlaybackOrigin("image", credentials);
1433
+ }
1434
+ async function getMuxStreamOrigin(credentials) {
1435
+ return resolveMuxPlaybackOrigin("stream", credentials);
1436
+ }
1437
+ async function getMuxImageBaseUrl(playbackId, assetType, credentials) {
1438
+ const origin = await getMuxImageOrigin(credentials);
1439
+ return `${origin}/${playbackId}/${assetType}.png`;
1440
+ }
1441
+ async function getMuxStoryboardBaseUrl(playbackId, credentials) {
1442
+ return getMuxImageBaseUrl(playbackId, "storyboard", credentials);
1443
+ }
1444
+ async function getMuxThumbnailBaseUrl(playbackId, credentials) {
1445
+ return getMuxImageBaseUrl(playbackId, "thumbnail", credentials);
1446
+ }
1447
+
1357
1448
  // node_modules/@workflow/serde/dist/index.js
1358
1449
  var WORKFLOW_SERIALIZE = /* @__PURE__ */ Symbol.for("workflow-serialize");
1359
1450
  var WORKFLOW_DESERIALIZE = /* @__PURE__ */ Symbol.for("workflow-deserialize");
@@ -2091,25 +2182,22 @@ async function getHeatmapForPlaybackId(playbackId, options = {}) {
2091
2182
  "use step";
2092
2183
  return fetchHeatmap("playback-ids", playbackId, options);
2093
2184
  }
2094
- function transformHeatmapResponse(response) {
2095
- return {
2096
- assetId: response.data.asset_id,
2097
- videoId: response.data.video_id,
2098
- playbackId: response.data.playback_id,
2099
- heatmap: response.data.heatmap,
2100
- timeframe: response.timeframe
2101
- };
2102
- }
2103
2185
  async function fetchHeatmap(identifierType, id, options) {
2104
2186
  "use step";
2105
2187
  const { timeframe = "7:days", credentials } = options;
2106
2188
  const muxClient = await getMuxClientFromEnv(credentials);
2107
2189
  const mux = await muxClient.createClient();
2108
- const queryParams = new URLSearchParams();
2109
- queryParams.append("timeframe[]", timeframe);
2110
- const path = `/data/v1/engagement/${identifierType}/${id}/heatmap?${queryParams.toString()}`;
2111
- const response = await mux.get(path);
2112
- return transformHeatmapResponse(response);
2190
+ const query = { timeframe: [timeframe] };
2191
+ const resource = identifierType === "playback-ids" ? mux.data.engagement.playbackIds : mux.data.engagement[identifierType];
2192
+ const response = await resource.heatmap(id, query);
2193
+ const { data } = response;
2194
+ return {
2195
+ assetId: data.asset_id ?? (identifierType === "assets" ? id : void 0),
2196
+ videoId: data.video_id ?? (identifierType === "videos" ? id : void 0),
2197
+ playbackId: data.playback_id ?? (identifierType === "playback-ids" ? id : void 0),
2198
+ heatmap: data.heatmap,
2199
+ timeframe: response.timeframe
2200
+ };
2113
2201
  }
2114
2202
 
2115
2203
  // src/primitives/hotspots.ts
@@ -2128,37 +2216,34 @@ async function getHotspotsForPlaybackId(playbackId, options = {}) {
2128
2216
  const response = await fetchHotspots("playback-ids", playbackId, options);
2129
2217
  return response.hotspots;
2130
2218
  }
2131
- function transformHotspotResponse(response) {
2132
- return {
2133
- assetId: response.data.asset_id,
2134
- videoId: response.data.video_id,
2135
- playbackId: response.data.playback_id,
2136
- hotspots: response.data.hotspots.map((h) => ({
2137
- startMs: h.start_ms,
2138
- endMs: h.end_ms,
2139
- score: h.score
2140
- }))
2141
- };
2142
- }
2143
2219
  async function fetchHotspots(identifierType, id, options) {
2144
2220
  "use step";
2145
2221
  const {
2146
2222
  limit = 5,
2147
2223
  orderDirection = "desc",
2148
- orderBy = "score",
2149
2224
  timeframe = "7:days",
2150
2225
  credentials
2151
2226
  } = options;
2152
2227
  const muxClient = await getMuxClientFromEnv(credentials);
2153
2228
  const mux = await muxClient.createClient();
2154
- const queryParams = new URLSearchParams();
2155
- queryParams.append("limit", String(limit));
2156
- queryParams.append("order_direction", orderDirection);
2157
- queryParams.append("order_by", orderBy);
2158
- queryParams.append("timeframe[]", timeframe);
2159
- const path = `/data/v1/engagement/${identifierType}/${id}/hotspots?${queryParams.toString()}`;
2160
- const response = await mux.get(path);
2161
- return transformHotspotResponse(response);
2229
+ const query = {
2230
+ limit,
2231
+ order_direction: orderDirection,
2232
+ timeframe: [timeframe]
2233
+ };
2234
+ const resource = identifierType === "playback-ids" ? mux.data.engagement.playbackIds : mux.data.engagement[identifierType];
2235
+ const response = await resource.hotspots(id, query);
2236
+ const { data } = response;
2237
+ return {
2238
+ assetId: data.asset_id ?? (identifierType === "assets" ? id : void 0),
2239
+ videoId: data.video_id ?? (identifierType === "videos" ? id : void 0),
2240
+ playbackId: data.playback_id ?? (identifierType === "playback-ids" ? id : void 0),
2241
+ hotspots: data.hotspots.map((h) => ({
2242
+ startMs: h.start_ms,
2243
+ endMs: h.end_ms,
2244
+ score: h.score
2245
+ }))
2246
+ };
2162
2247
  }
2163
2248
 
2164
2249
  // src/primitives/shots.ts
@@ -2166,9 +2251,6 @@ var DEFAULT_POLL_INTERVAL_MS = 2e3;
2166
2251
  var MIN_POLL_INTERVAL_MS = 1e3;
2167
2252
  var DEFAULT_MAX_ATTEMPTS = 60;
2168
2253
  var SHOTS_ALREADY_REQUESTED_MESSAGE = "shots generation has already been requested";
2169
- function getShotsPath(assetId) {
2170
- return `/video/v1/assets/${assetId}/shots`;
2171
- }
2172
2254
  function mapManifestShots(shots) {
2173
2255
  let usedDeprecatedField = false;
2174
2256
  const mapped = shots.map((shot, index) => {
@@ -2208,29 +2290,35 @@ async function fetchShotsFromManifest(shotsManifestUrl) {
2208
2290
  }
2209
2291
  return mapManifestShots(manifest.shots);
2210
2292
  }
2211
- async function transformShotsResponse(response) {
2212
- switch (response.data.status) {
2293
+ async function transformShotsResponse(data) {
2294
+ switch (data.status) {
2213
2295
  case "pending":
2214
2296
  return {
2215
2297
  status: "pending",
2216
- createdAt: response.data.created_at
2298
+ createdAt: data.created_at
2217
2299
  };
2218
- case "errored":
2300
+ case "errored": {
2301
+ const details = data.errors ?? data.error;
2219
2302
  return {
2220
2303
  status: "errored",
2221
- createdAt: response.data.created_at,
2222
- error: response.data.error
2304
+ createdAt: data.created_at,
2305
+ error: {
2306
+ type: details?.type ?? "unknown",
2307
+ messages: details?.messages ?? []
2308
+ }
2223
2309
  };
2310
+ }
2224
2311
  case "completed":
2312
+ if (!data.shots_manifest_url) {
2313
+ throw new Error("Completed shots response is missing shots_manifest_url");
2314
+ }
2225
2315
  return {
2226
2316
  status: "completed",
2227
- createdAt: response.data.created_at,
2228
- shots: await fetchShotsFromManifest(response.data.shots_manifest_url)
2317
+ createdAt: data.created_at,
2318
+ shots: await fetchShotsFromManifest(data.shots_manifest_url)
2229
2319
  };
2230
- default: {
2231
- const exhaustiveCheck = response.data;
2232
- throw new Error(`Unsupported shots response: ${JSON.stringify(exhaustiveCheck)}`);
2233
- }
2320
+ default:
2321
+ throw new Error(`Unsupported shots status '${data.status}'`);
2234
2322
  }
2235
2323
  }
2236
2324
  function sleep(ms) {
@@ -2238,7 +2326,8 @@ function sleep(ms) {
2238
2326
  }
2239
2327
  function isShotsAlreadyRequestedError(error) {
2240
2328
  const statusCode = error?.status ?? error?.statusCode;
2241
- const messages = error?.error?.messages;
2329
+ const body = error?.error;
2330
+ const messages = body?.error?.messages ?? body?.messages;
2242
2331
  const lowerCaseMessages = messages?.map((message) => message.toLowerCase()) ?? [];
2243
2332
  const errorMessage = error instanceof Error ? error.message.toLowerCase() : "";
2244
2333
  return statusCode === 400 && (lowerCaseMessages.some((message) => message.includes(SHOTS_ALREADY_REQUESTED_MESSAGE)) || errorMessage.includes(SHOTS_ALREADY_REQUESTED_MESSAGE));
@@ -2248,11 +2337,8 @@ async function requestShotsForAsset(assetId, options = {}) {
2248
2337
  const { credentials } = options;
2249
2338
  const muxClient = await getMuxClientFromEnv(credentials);
2250
2339
  const mux = await muxClient.createClient();
2251
- const response = await mux.post(
2252
- getShotsPath(assetId),
2253
- { body: {} }
2254
- );
2255
- const result = await transformShotsResponse(response);
2340
+ const data = await mux.video.assets.generateShots(assetId, {});
2341
+ const result = await transformShotsResponse(data);
2256
2342
  if (result.status !== "pending") {
2257
2343
  throw new Error(
2258
2344
  `Expected pending status after requesting shots for asset '${assetId}', received '${result.status}'`
@@ -2265,10 +2351,8 @@ async function getShotsForAsset(assetId, options = {}) {
2265
2351
  const { credentials } = options;
2266
2352
  const muxClient = await getMuxClientFromEnv(credentials);
2267
2353
  const mux = await muxClient.createClient();
2268
- const response = await mux.get(
2269
- getShotsPath(assetId)
2270
- );
2271
- return await transformShotsResponse(response);
2354
+ const data = await mux.video.assets.retrieveShots(assetId);
2355
+ return await transformShotsResponse(data);
2272
2356
  }
2273
2357
  async function waitForShotsForAsset(assetId, options = {}) {
2274
2358
  "use step";
@@ -2309,61 +2393,10 @@ async function waitForShotsForAsset(assetId, options = {}) {
2309
2393
  );
2310
2394
  }
2311
2395
 
2312
- // src/lib/mux-url.ts
2313
- var DEFAULT_MUX_IMAGE_ORIGIN = "https://image.mux.com";
2314
- var DEFAULT_MUX_STREAM_ORIGIN = "https://stream.mux.com";
2315
- function normalizeOrigin(value, envVarName) {
2316
- const trimmed = value.trim();
2317
- const candidate = trimmed.includes("://") ? trimmed : `https://${trimmed}`;
2318
- const exampleHostname = envVarName === "MUX_IMAGE_URL_OVERRIDE" ? "image.example.mux.com" : "stream.example.mux.com";
2319
- let parsed;
2320
- try {
2321
- parsed = new URL(candidate);
2322
- } catch {
2323
- throw new Error(
2324
- `Invalid ${envVarName}. Provide a hostname (e.g. "${exampleHostname}") or a URL origin (e.g. "https://${exampleHostname}").`
2325
- );
2326
- }
2327
- if (parsed.username || parsed.password || parsed.search || parsed.hash || parsed.pathname && parsed.pathname !== "/") {
2328
- throw new Error(
2329
- `Invalid ${envVarName}. Only a hostname/origin is allowed (no credentials, query params, hash fragments, or path).`
2330
- );
2331
- }
2332
- return parsed.origin;
2333
- }
2334
- function getMuxImageOrigin() {
2335
- const override = env_default.MUX_IMAGE_URL_OVERRIDE;
2336
- if (!override) {
2337
- return DEFAULT_MUX_IMAGE_ORIGIN;
2338
- }
2339
- return normalizeOrigin(override, "MUX_IMAGE_URL_OVERRIDE");
2340
- }
2341
- function getMuxStreamOrigin() {
2342
- const override = env_default.MUX_STREAM_URL_OVERRIDE;
2343
- if (!override) {
2344
- return DEFAULT_MUX_STREAM_ORIGIN;
2345
- }
2346
- return normalizeOrigin(override, "MUX_STREAM_URL_OVERRIDE");
2347
- }
2348
- function getMuxImageBaseUrl(playbackId, assetType) {
2349
- const origin = getMuxImageOrigin();
2350
- return `${origin}/${playbackId}/${assetType}.png`;
2351
- }
2352
- function getMuxStoryboardBaseUrl(playbackId) {
2353
- return getMuxImageBaseUrl(playbackId, "storyboard");
2354
- }
2355
- function getMuxThumbnailBaseUrl(playbackId) {
2356
- return getMuxImageBaseUrl(playbackId, "thumbnail");
2357
- }
2358
-
2359
2396
  // src/lib/url-signing.ts
2360
2397
  async function createSigningClient(context) {
2361
- const { default: MuxClient } = await import("@mux/mux-node");
2398
+ const { default: MuxClient } = await import("@mux/ts");
2362
2399
  return new MuxClient({
2363
- // These are not needed for signing, but the SDK requires them
2364
- // Using empty strings as we only need the jwt functionality
2365
- tokenId: env_default.MUX_TOKEN_ID || "",
2366
- tokenSecret: env_default.MUX_TOKEN_SECRET || "",
2367
2400
  jwtSigningKey: context.keyId,
2368
2401
  jwtPrivateKey: context.keySecret
2369
2402
  });
@@ -2397,7 +2430,7 @@ async function signUrl(url, playbackId, type = "video", params, credentials) {
2397
2430
  var DEFAULT_STORYBOARD_WIDTH = 640;
2398
2431
  async function getStoryboardUrl(playbackId, width = DEFAULT_STORYBOARD_WIDTH, shouldSign = false, credentials, scope) {
2399
2432
  "use step";
2400
- const baseUrl = getMuxStoryboardBaseUrl(playbackId);
2433
+ const baseUrl = await getMuxStoryboardBaseUrl(playbackId, credentials);
2401
2434
  const params = { width };
2402
2435
  if (scope?.startTime !== void 0) {
2403
2436
  params.asset_start_time = scope.startTime;
@@ -2746,7 +2779,7 @@ async function getThumbnailUrls(playbackId, duration, options = {}) {
2746
2779
  }
2747
2780
  timestamps = newTimestamps;
2748
2781
  }
2749
- const baseUrl = getMuxThumbnailBaseUrl(playbackId);
2782
+ const baseUrl = await getMuxThumbnailBaseUrl(playbackId, credentials);
2750
2783
  const urlPromises = timestamps.map(async (time) => {
2751
2784
  const url = shouldSign ? await signUrl(baseUrl, playbackId, "thumbnail", { time, width }, credentials) : `${baseUrl}?time=${time}&width=${width}`;
2752
2785
  return { url, time };
@@ -3189,7 +3222,7 @@ function concatenateVttSegments(segments, preamble = "WEBVTT") {
3189
3222
  }
3190
3223
  async function buildTranscriptUrl(playbackId, trackId, shouldSign = false, credentials) {
3191
3224
  "use step";
3192
- const baseUrl = `${getMuxStreamOrigin()}/${playbackId}/text/${trackId}.vtt`;
3225
+ const baseUrl = `${await getMuxStreamOrigin(credentials)}/${playbackId}/text/${trackId}.vtt`;
3193
3226
  if (shouldSign) {
3194
3227
  return signUrl(baseUrl, playbackId, "video", void 0, credentials);
3195
3228
  }
@@ -6115,7 +6148,7 @@ function mapShotsToHotspots(shots, hotspots) {
6115
6148
  }
6116
6149
  async function getThumbnailUrlsForHotspots(playbackId, hotspots, options = {}) {
6117
6150
  const { width = 640, shouldSign = false, credentials } = options;
6118
- const baseUrl = getMuxThumbnailBaseUrl(playbackId);
6151
+ const baseUrl = await getMuxThumbnailBaseUrl(playbackId, credentials);
6119
6152
  const urlPromises = hotspots.map(async (h) => {
6120
6153
  const time = Math.floor(h.startMs / 1e3);
6121
6154
  if (shouldSign) {
@@ -7639,7 +7672,7 @@ function filterTimestampsWithinExclusiveScope(timestampsMs, scope) {
7639
7672
  async function getThumbnailUrlsFromTimestamps(playbackId, timestampsMs, options) {
7640
7673
  "use step";
7641
7674
  const { width, shouldSign, credentials } = options;
7642
- const baseUrl = getMuxThumbnailBaseUrl(playbackId);
7675
+ const baseUrl = await getMuxThumbnailBaseUrl(playbackId, credentials);
7643
7676
  const times = [...new Set(timestampsMs.map(toThumbnailTimeSeconds))];
7644
7677
  const urlPromises = times.map(async (time) => {
7645
7678
  const url = shouldSign ? await signUrl(baseUrl, playbackId, "thumbnail", { time, width }, credentials) : `${baseUrl}?time=${time}&width=${width}`;
@@ -8823,7 +8856,7 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
8823
8856
  { type: "validation_error" }
8824
8857
  );
8825
8858
  }
8826
- let audioUrl = `${getMuxStreamOrigin()}/${playbackId}/audio.m4a`;
8859
+ let audioUrl = `${await getMuxStreamOrigin(credentials)}/${playbackId}/audio.m4a`;
8827
8860
  if (policy === "signed") {
8828
8861
  audioUrl = await signUrl(audioUrl, playbackId, "video", void 0, credentials);
8829
8862
  }
@@ -9848,6 +9881,7 @@ export {
9848
9881
  findSameLanguageTextTracks,
9849
9882
  getLanguageCodePair,
9850
9883
  getLanguageName,
9884
+ getMuxPlaybackOrigin,
9851
9885
  isDuplicateTrackNameError,
9852
9886
  isMuxGeneratedTextTrack,
9853
9887
  isUndeterminedLanguageCode,