@boldvideo/bold-js 1.16.0 → 1.17.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @boldvideo/bold-js
2
2
 
3
+ ## 1.17.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 563730d: Add full options support to `videos.list()` for tag, collectionId, viewerId, and page filtering
8
+
9
+ **New features:**
10
+
11
+ - Filter videos by `tag` and `collectionId` on both endpoints
12
+ - Include watch progress with `viewerId` parameter
13
+ - Access paginated `/videos` endpoint using `page` parameter
14
+
15
+ **Usage:**
16
+
17
+ ```typescript
18
+ // Latest videos with filters
19
+ await bold.videos.list({ limit: 20, tag: "sales", collectionId: "col_123" });
20
+
21
+ // Include viewer watch progress
22
+ await bold.videos.list({ limit: 20, viewerId: "viewer_123" });
23
+
24
+ // Paginated index (uses /videos endpoint)
25
+ await bold.videos.list({ page: 2, tag: "sales" });
26
+ ```
27
+
28
+ **Breaking:** None. Existing `bold.videos.list()` and `bold.videos.list(12)` calls work unchanged.
29
+
3
30
  ## 1.16.0
4
31
 
5
32
  ### Minor Changes
package/README.md CHANGED
@@ -59,9 +59,27 @@ console.log(recs.guidance);
59
59
  ### Videos
60
60
 
61
61
  ```typescript
62
- // List latest videos
62
+ // List latest videos (default: 12)
63
63
  const videos = await bold.videos.list();
64
64
 
65
+ // With limit (backwards compatible)
66
+ const videos = await bold.videos.list(20);
67
+
68
+ // With filters
69
+ const videos = await bold.videos.list({
70
+ limit: 20,
71
+ tag: 'sales',
72
+ collectionId: 'col_123',
73
+ viewerId: 'viewer_123' // Include watch progress
74
+ });
75
+
76
+ // Paginated index (uses /videos endpoint)
77
+ const videos = await bold.videos.list({
78
+ page: 2,
79
+ tag: 'sales',
80
+ collectionId: 'col_123'
81
+ });
82
+
65
83
  // Get a single video by ID or slug
66
84
  const video = await bold.videos.get('video-id');
67
85
  const videoBySlug = await bold.videos.get('my-video-slug');
@@ -357,7 +375,10 @@ import type {
357
375
  Viewer,
358
376
  ViewerProgress,
359
377
  ViewerLookupParams,
360
- ListProgressOptions
378
+ ListProgressOptions,
379
+ ListVideosOptions,
380
+ ListVideosLatestOptions,
381
+ ListVideosIndexOptions
361
382
  } from '@boldvideo/bold-js';
362
383
  ```
363
384
 
package/dist/index.cjs CHANGED
@@ -64,6 +64,15 @@ function camelizeKeys(input, options = {}) {
64
64
  }
65
65
 
66
66
  // src/lib/fetchers.ts
67
+ function toQuery(params) {
68
+ const qs = new URLSearchParams();
69
+ for (const [k, v] of Object.entries(params)) {
70
+ if (v !== void 0 && v !== null)
71
+ qs.set(k, String(v));
72
+ }
73
+ const s = qs.toString();
74
+ return s ? `?${s}` : "";
75
+ }
67
76
  async function get(client, url) {
68
77
  try {
69
78
  const res = await client.get(url);
@@ -90,14 +99,44 @@ function fetchSettings(client) {
90
99
  };
91
100
  }
92
101
  function fetchVideos(client) {
93
- return async (videoLimit = 12) => {
102
+ return async (arg = 12) => {
94
103
  try {
104
+ if (typeof arg === "number") {
105
+ return await get(
106
+ client,
107
+ `videos/latest${toQuery({ limit: arg })}`
108
+ );
109
+ }
110
+ const opts = arg;
111
+ const hasPage = "page" in opts && opts.page !== void 0;
112
+ if (hasPage && ("limit" in opts || "viewerId" in opts)) {
113
+ throw new Error(
114
+ "videos.list(): cannot use `page` with `limit` or `viewerId` (these belong to different endpoints)"
115
+ );
116
+ }
117
+ if (hasPage) {
118
+ const { page, tag: tag2, collectionId: collectionId2 } = opts;
119
+ return await get(
120
+ client,
121
+ `videos${toQuery({
122
+ page,
123
+ tag: tag2,
124
+ collection_id: collectionId2
125
+ })}`
126
+ );
127
+ }
128
+ const { limit, tag, collectionId, viewerId } = opts;
95
129
  return await get(
96
130
  client,
97
- `videos/latest?limit=${videoLimit}`
131
+ `videos/latest${toQuery({
132
+ limit: limit ?? 12,
133
+ tag,
134
+ collection_id: collectionId,
135
+ viewer_id: viewerId
136
+ })}`
98
137
  );
99
138
  } catch (error) {
100
- console.error(`Error fetching videos with limit: ${videoLimit}`, error);
139
+ console.error(`Error fetching videos`, error);
101
140
  throw error;
102
141
  }
103
142
  };
package/dist/index.d.ts CHANGED
@@ -473,6 +473,44 @@ type ProgressListMeta = {
473
473
  /** Number of in-progress videos */
474
474
  inProgress: number;
475
475
  };
476
+ /**
477
+ * Options for listing videos from /videos/latest endpoint
478
+ */
479
+ type ListVideosLatestOptions = {
480
+ /** Max videos to return (default: 12) */
481
+ limit?: number;
482
+ /** Filter by tag */
483
+ tag?: string;
484
+ /** Filter to videos in a specific collection */
485
+ collectionId?: string;
486
+ /** Viewer UUID for watch progress */
487
+ viewerId?: string;
488
+ };
489
+ /**
490
+ * Options for listing videos from /videos (index) endpoint with pagination
491
+ */
492
+ type ListVideosIndexOptions = {
493
+ /** Page number for pagination */
494
+ page?: number;
495
+ /** Filter by tag */
496
+ tag?: string;
497
+ /** Filter to videos in a specific collection */
498
+ collectionId?: string;
499
+ };
500
+ /**
501
+ * Combined options for bold.videos.list()
502
+ *
503
+ * If `page` is provided, uses /videos (index) endpoint.
504
+ * Otherwise, uses /videos/latest endpoint.
505
+ *
506
+ * Note: `page` and `limit`/`viewerId` are mutually exclusive.
507
+ */
508
+ type ListVideosOptions = (ListVideosLatestOptions & {
509
+ page?: never;
510
+ }) | (ListVideosIndexOptions & {
511
+ limit?: never;
512
+ viewerId?: never;
513
+ });
476
514
 
477
515
  /**
478
516
  * AI client interface for type-safe method overloading
@@ -609,7 +647,7 @@ declare function createClient(apiKey: string, options?: ClientOptions): {
609
647
  data: Settings;
610
648
  }>;
611
649
  videos: {
612
- list: (videoLimit?: number) => Promise<{
650
+ list: (arg?: number | ListVideosOptions) => Promise<{
613
651
  data: Video[];
614
652
  }>;
615
653
  get: (id: string) => Promise<{
@@ -668,4 +706,4 @@ declare const DEFAULT_API_BASE_URL = "https://app.boldvideo.io/api/v1/";
668
706
  */
669
707
  declare const DEFAULT_INTERNAL_API_BASE_URL = "https://app.boldvideo.io/i/v1/";
670
708
 
671
- export { AIContextMessage, AIEvent, AIResponse, AIUsage, Account, AccountAI, AnalyticsProvider, AskOptions, AssistantConfig, ChatOptions, Citation, ClientOptions, Conversation, ConversationMessage, ConversationMetadata, CreateViewerData, CustomRedirect, DEFAULT_API_BASE_URL, DEFAULT_INTERNAL_API_BASE_URL, ListProgressOptions, MenuItem, Playlist, Portal, PortalDisplay, PortalHero, PortalLayout, PortalNavigation, PortalTheme, ProgressListMeta, RecommendOptions, RecommendResponse, Recommendation, RecommendationVideo, RecommendationsOptions, RecommendationsResponse, SaveProgressData, SearchOptions, Segment, Settings, Source, ThemeColors, ThemeConfig, UpdateViewerData, Video, VideoAttachment, VideoDownloadUrls, VideoMetadata, VideoSubtitles, VideoTranscript, Viewer, ViewerAPIError, ViewerLookupParams, ViewerProgress, createClient };
709
+ export { AIContextMessage, AIEvent, AIResponse, AIUsage, Account, AccountAI, AnalyticsProvider, AskOptions, AssistantConfig, ChatOptions, Citation, ClientOptions, Conversation, ConversationMessage, ConversationMetadata, CreateViewerData, CustomRedirect, DEFAULT_API_BASE_URL, DEFAULT_INTERNAL_API_BASE_URL, ListProgressOptions, ListVideosIndexOptions, ListVideosLatestOptions, ListVideosOptions, MenuItem, Playlist, Portal, PortalDisplay, PortalHero, PortalLayout, PortalNavigation, PortalTheme, ProgressListMeta, RecommendOptions, RecommendResponse, Recommendation, RecommendationVideo, RecommendationsOptions, RecommendationsResponse, SaveProgressData, SearchOptions, Segment, Settings, Source, ThemeColors, ThemeConfig, UpdateViewerData, Video, VideoAttachment, VideoDownloadUrls, VideoMetadata, VideoSubtitles, VideoTranscript, Viewer, ViewerAPIError, ViewerLookupParams, ViewerProgress, createClient };
package/dist/index.js CHANGED
@@ -25,6 +25,15 @@ function camelizeKeys(input, options = {}) {
25
25
  }
26
26
 
27
27
  // src/lib/fetchers.ts
28
+ function toQuery(params) {
29
+ const qs = new URLSearchParams();
30
+ for (const [k, v] of Object.entries(params)) {
31
+ if (v !== void 0 && v !== null)
32
+ qs.set(k, String(v));
33
+ }
34
+ const s = qs.toString();
35
+ return s ? `?${s}` : "";
36
+ }
28
37
  async function get(client, url) {
29
38
  try {
30
39
  const res = await client.get(url);
@@ -51,14 +60,44 @@ function fetchSettings(client) {
51
60
  };
52
61
  }
53
62
  function fetchVideos(client) {
54
- return async (videoLimit = 12) => {
63
+ return async (arg = 12) => {
55
64
  try {
65
+ if (typeof arg === "number") {
66
+ return await get(
67
+ client,
68
+ `videos/latest${toQuery({ limit: arg })}`
69
+ );
70
+ }
71
+ const opts = arg;
72
+ const hasPage = "page" in opts && opts.page !== void 0;
73
+ if (hasPage && ("limit" in opts || "viewerId" in opts)) {
74
+ throw new Error(
75
+ "videos.list(): cannot use `page` with `limit` or `viewerId` (these belong to different endpoints)"
76
+ );
77
+ }
78
+ if (hasPage) {
79
+ const { page, tag: tag2, collectionId: collectionId2 } = opts;
80
+ return await get(
81
+ client,
82
+ `videos${toQuery({
83
+ page,
84
+ tag: tag2,
85
+ collection_id: collectionId2
86
+ })}`
87
+ );
88
+ }
89
+ const { limit, tag, collectionId, viewerId } = opts;
56
90
  return await get(
57
91
  client,
58
- `videos/latest?limit=${videoLimit}`
92
+ `videos/latest${toQuery({
93
+ limit: limit ?? 12,
94
+ tag,
95
+ collection_id: collectionId,
96
+ viewer_id: viewerId
97
+ })}`
59
98
  );
60
99
  } catch (error) {
61
- console.error(`Error fetching videos with limit: ${videoLimit}`, error);
100
+ console.error(`Error fetching videos`, error);
62
101
  throw error;
63
102
  }
64
103
  };
package/llms.txt CHANGED
@@ -55,12 +55,35 @@ interface ClientOptions {
55
55
  All content methods return `Promise<{ data: T }>`.
56
56
 
57
57
  - `bold.settings(videoLimit?)` - Channel settings, menus, featured playlists
58
- - `bold.videos.list(limit?)` - List videos (default limit: 12)
58
+ - `bold.videos.list()` - List latest videos (default limit: 12)
59
+ - `bold.videos.list(limit)` - List with numeric limit (backwards compatible)
60
+ - `bold.videos.list(options)` - List with full options (see ListVideosOptions)
59
61
  - `bold.videos.get(id)` - Get video by ID or slug
60
62
  - `bold.videos.search(query)` - Search videos
61
63
  - `bold.playlists.list()` - List playlists
62
64
  - `bold.playlists.get(id)` - Get playlist with videos
63
65
 
66
+ ### ListVideosOptions
67
+
68
+ ```typescript
69
+ // For /videos/latest endpoint (default)
70
+ {
71
+ limit?: number; // Max videos (default: 12)
72
+ tag?: string; // Filter by tag
73
+ collectionId?: string; // Filter to collection
74
+ viewerId?: string; // Include watch progress
75
+ }
76
+
77
+ // For /videos (index) endpoint - use when you need pagination
78
+ {
79
+ page?: number; // Page number
80
+ tag?: string;
81
+ collectionId?: string;
82
+ }
83
+ ```
84
+
85
+ Note: If `page` is provided, SDK uses `/videos` (index); otherwise uses `/videos/latest`.
86
+
64
87
  ## Viewers API
65
88
 
66
89
  Manage external users and track video progress. Returns `Promise<{ data: T }>` (consistent with other SDK methods).
@@ -254,7 +277,7 @@ type AIEvent =
254
277
 
255
278
  ### Other types exported
256
279
 
257
- `Playlist`, `Settings`, `Portal`, `MenuItem`, `AIResponse`, `AIUsage`, `AIContextMessage`, `Conversation`, `ConversationMessage`, `RecommendationsResponse`, `Viewer`, `ViewerProgress`, `ViewerLookupParams`, `ListProgressOptions`
280
+ `Playlist`, `Settings`, `Portal`, `MenuItem`, `AIResponse`, `AIUsage`, `AIContextMessage`, `Conversation`, `ConversationMessage`, `RecommendationsResponse`, `Viewer`, `ViewerProgress`, `ViewerLookupParams`, `ListProgressOptions`, `ListVideosOptions`, `ListVideosLatestOptions`, `ListVideosIndexOptions`
258
281
 
259
282
  ## Error Handling
260
283
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@boldvideo/bold-js",
3
3
  "license": "MIT",
4
- "version": "1.16.0",
4
+ "version": "1.17.0",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",