@boldvideo/bold-js 0.7.1 → 0.8.1

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/AGENTS.md ADDED
@@ -0,0 +1,131 @@
1
+ # AGENTS.md
2
+
3
+ This file provides guidance to AI coding agents working with this repository.
4
+
5
+ ## Project Overview
6
+
7
+ This is the Bold JavaScript SDK (`@boldvideo/bold-js`) - a TypeScript client library for interacting with the Bold Video API. The SDK provides methods for fetching videos, playlists, channel settings, and tracking analytics events.
8
+
9
+ ## Tech Stack
10
+
11
+ - Language: TypeScript 4.9+ (strict mode enabled)
12
+ - Build Tool: tsup (outputs both ESM and CommonJS)
13
+ - Package Manager: pnpm
14
+ - Target: ES2020
15
+ - Runtime: Node.js 20+
16
+ - Dependencies: axios (only runtime dependency)
17
+
18
+ ## Commands
19
+
20
+ ```bash
21
+ pnpm install # Install dependencies
22
+ pnpm run build # Build to dist/ (ESM + CJS + type declarations)
23
+ pnpm run lint # Type checking with tsc
24
+ pnpm changeset # Create a changeset for versioning
25
+ ```
26
+
27
+ ## Release Workflow
28
+
29
+ This project uses [Changesets](https://github.com/changesets/changesets) with automated GitHub Actions for publishing.
30
+
31
+ ### How to Release
32
+
33
+ 1. **Create a changeset** when making changes that should be released:
34
+ ```bash
35
+ pnpm changeset
36
+ ```
37
+ This creates a markdown file in `.changeset/` describing the change and version bump type (patch/minor/major).
38
+
39
+ 2. **Commit and push** your changes (including the changeset file) to `main`.
40
+
41
+ 3. **Automated release process**:
42
+ - The `changeset-release.yml` workflow runs on push to `main`
43
+ - If changesets exist, it creates a "Release PR" that:
44
+ - Bumps the version in `package.json`
45
+ - Updates `CHANGELOG.md`
46
+ - Removes the changeset files
47
+ - When you merge that Release PR, the workflow automatically publishes to npm
48
+
49
+ ### Important Notes
50
+
51
+ - **Never run `pnpm changeset version` or `pnpm changeset publish` locally** - the GitHub Action handles this automatically
52
+ - The CI workflow (`ci.yml`) runs `pnpm run build` which generates the `dist/` folder - this ensures compiled files are always included in the published package
53
+ - The `release.yml` workflow can also publish when a `v*` tag is pushed (alternative release method)
54
+
55
+ ## Project Structure
56
+
57
+ ```
58
+ /src
59
+ index.ts # Main entry point - exports createClient and all types
60
+ /lib
61
+ client.ts # Client factory (createClient function)
62
+ fetchers.ts # API endpoint implementations (videos, playlists, settings)
63
+ ai.ts # AI streaming endpoints (coach, ask) using native fetch + SSE
64
+ types.ts # TypeScript interfaces (Video, Playlist, Settings, etc.)
65
+ tracking.ts # Analytics event tracking with throttling
66
+ constants.ts # Shared constants (API base URLs)
67
+ /util
68
+ throttle.ts # Rate limiting utility for high-frequency events
69
+ /dist # Build output (generated)
70
+ ```
71
+
72
+ ## Architecture
73
+
74
+ The SDK uses a **factory pattern** where `createClient(apiKey)` returns an object with namespaced methods:
75
+
76
+ ```typescript
77
+ const bold = createClient('API_KEY');
78
+
79
+ // Available methods:
80
+ bold.settings() // Fetch channel settings
81
+ bold.videos.list() // List latest videos
82
+ bold.videos.get(id) // Get single video
83
+ bold.videos.search(query) // Search videos
84
+ bold.playlists.list() // List playlists
85
+ bold.playlists.get(id) // Get single playlist
86
+ bold.ai.coach(opts) // AI RAG assistant (streaming)
87
+ bold.ai.ask(videoId, opts)// Video Q&A (streaming)
88
+ bold.trackEvent() // Track video events
89
+ bold.trackPageView() // Track page views
90
+ ```
91
+
92
+ ## Code Style
93
+
94
+ - Use functional patterns (factory functions, not classes)
95
+ - Export all public types from `src/index.ts`
96
+ - All API methods return Promises
97
+ - Use TypeScript strict mode
98
+ - camelCase for functions and variables
99
+ - PascalCase for types and interfaces
100
+ - Wrap API calls with try/catch and log errors
101
+
102
+ ## API Integration
103
+
104
+ - Base URL: `https://app.boldvideo.io/api/v1/`
105
+ - Authentication: API key in Authorization header
106
+ - All responses wrapped in `{ data: T }` structure
107
+
108
+ ## Testing
109
+
110
+ - Run `pnpm run lint` before committing
111
+ - Ensure TypeScript compilation succeeds with no errors
112
+ - No test framework currently configured - manual testing required
113
+
114
+ ## Boundaries
115
+
116
+ **Always:**
117
+ - Ensure TypeScript types are properly defined in `types.ts`
118
+ - Support both ESM and CommonJS consumers
119
+ - Follow existing patterns in the codebase
120
+ - Run `pnpm run lint` before committing
121
+ - Keep the SDK lightweight (minimal dependencies)
122
+
123
+ **Ask first:**
124
+ - Adding new dependencies
125
+ - Changing the public API surface
126
+ - Major architectural changes
127
+
128
+ **Never:**
129
+ - Commit API keys or secrets
130
+ - Remove or change existing public type exports without versioning
131
+ - Add test files without setting up a test framework first
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # @boldvideo/bold-js
2
2
 
3
+ ## 0.8.1
4
+
5
+ ### Patch Changes
6
+
7
+ - c643c04: Fix missing compiled dist files in published package
8
+
9
+ ## 0.8.0
10
+
11
+ ### Minor Changes
12
+
13
+ - b0c770d: Add streaming AI endpoints
14
+
15
+ - `bold.ai.coach()` - Library-wide RAG assistant with conversation support
16
+ - `bold.ai.ask()` - Video-specific Q&A
17
+
18
+ Both return `AsyncIterable<CoachEvent>` for type-safe streaming. New types: `CoachEvent`, `CoachOptions`, `AskOptions`, `Citation`, `Usage`.
19
+
20
+ Also includes:
21
+
22
+ - Custom headers support via `createClient(key, { headers })`
23
+ - Exported `DEFAULT_API_BASE_URL` constant
24
+
3
25
  ## 0.7.1
4
26
 
5
27
  ### Patch Changes
package/llms.txt ADDED
@@ -0,0 +1,45 @@
1
+ # Bold Video JavaScript SDK
2
+
3
+ > TypeScript client for the Bold Video API. Fetch videos, playlists, settings. Stream AI responses. Track analytics.
4
+
5
+ ## Quick Start
6
+
7
+ ```typescript
8
+ import { createClient } from '@boldvideo/bold-js';
9
+
10
+ const bold = createClient('your-api-key');
11
+
12
+ // Fetch videos
13
+ const videos = await bold.videos.list();
14
+ const video = await bold.videos.get('video-id');
15
+
16
+ // AI streaming
17
+ const stream = await bold.ai.coach({ message: "How do I price my SaaS?" });
18
+ for await (const event of stream) {
19
+ if (event.type === 'token') process.stdout.write(event.content);
20
+ }
21
+ ```
22
+
23
+ ## API Reference
24
+
25
+ - `createClient(apiKey, options?)` - Create SDK instance
26
+ - `bold.settings()` - Channel settings, menus, featured playlists
27
+ - `bold.videos.list()` - List videos
28
+ - `bold.videos.get(id)` - Get video by ID
29
+ - `bold.videos.search(query)` - Search videos
30
+ - `bold.playlists.list()` - List playlists
31
+ - `bold.playlists.get(id)` - Get playlist by ID
32
+ - `bold.ai.coach(options)` - AI RAG assistant, returns `AsyncIterable<CoachEvent>`
33
+ - `bold.ai.ask(videoId, options)` - Video Q&A, returns `AsyncIterable<CoachEvent>`
34
+ - `bold.trackEvent(event)` - Track video analytics
35
+ - `bold.trackPageView(data)` - Track page views
36
+
37
+ ## Types
38
+
39
+ Key types exported: `Video`, `Playlist`, `Settings`, `Portal`, `CoachEvent`, `CoachOptions`, `AskOptions`, `Citation`
40
+
41
+ ## Links
42
+
43
+ - [GitHub](https://github.com/boldvideo/bold-js)
44
+ - [npm](https://www.npmjs.com/package/@boldvideo/bold-js)
45
+ - [Types Source](https://github.com/boldvideo/bold-js/blob/main/src/lib/types.ts)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@boldvideo/bold-js",
3
3
  "license": "MIT",
4
- "version": "0.7.1",
4
+ "version": "0.8.1",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
@@ -25,7 +25,7 @@
25
25
  "axios": "^1.3.6"
26
26
  },
27
27
  "scripts": {
28
- "build": "tsup src/index.ts --format cjs,esm --dts",
28
+ "build": "tsup src/index.ts --format cjs,esm --dts --target es2020",
29
29
  "lint": "tsc"
30
30
  }
31
31
  }
package/dist/index.cjs DELETED
@@ -1,299 +0,0 @@
1
- "use strict";
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __defProps = Object.defineProperties;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
7
- var __getOwnPropNames = Object.getOwnPropertyNames;
8
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
9
- var __getProtoOf = Object.getPrototypeOf;
10
- var __hasOwnProp = Object.prototype.hasOwnProperty;
11
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
12
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
13
- var __spreadValues = (a, b) => {
14
- for (var prop in b || (b = {}))
15
- if (__hasOwnProp.call(b, prop))
16
- __defNormalProp(a, prop, b[prop]);
17
- if (__getOwnPropSymbols)
18
- for (var prop of __getOwnPropSymbols(b)) {
19
- if (__propIsEnum.call(b, prop))
20
- __defNormalProp(a, prop, b[prop]);
21
- }
22
- return a;
23
- };
24
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
25
- var __export = (target, all) => {
26
- for (var name in all)
27
- __defProp(target, name, { get: all[name], enumerable: true });
28
- };
29
- var __copyProps = (to, from, except, desc) => {
30
- if (from && typeof from === "object" || typeof from === "function") {
31
- for (let key of __getOwnPropNames(from))
32
- if (!__hasOwnProp.call(to, key) && key !== except)
33
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
34
- }
35
- return to;
36
- };
37
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
- // If the importer is in node compatibility mode or this is not an ESM
39
- // file that has been converted to a CommonJS file using a Babel-
40
- // compatible transform (i.e. "__esModule" has not been set), then set
41
- // "default" to the CommonJS "module.exports" for node compatibility.
42
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
43
- mod
44
- ));
45
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
46
- var __async = (__this, __arguments, generator) => {
47
- return new Promise((resolve, reject) => {
48
- var fulfilled = (value) => {
49
- try {
50
- step(generator.next(value));
51
- } catch (e) {
52
- reject(e);
53
- }
54
- };
55
- var rejected = (value) => {
56
- try {
57
- step(generator.throw(value));
58
- } catch (e) {
59
- reject(e);
60
- }
61
- };
62
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
63
- step((generator = generator.apply(__this, __arguments)).next());
64
- });
65
- };
66
-
67
- // src/index.ts
68
- var src_exports = {};
69
- __export(src_exports, {
70
- createClient: () => createClient
71
- });
72
- module.exports = __toCommonJS(src_exports);
73
-
74
- // src/lib/client.ts
75
- var import_axios = __toESM(require("axios"), 1);
76
-
77
- // src/lib/fetchers.ts
78
- function get(client, url) {
79
- return __async(this, null, function* () {
80
- try {
81
- const res = yield client.get(url);
82
- if (res.status !== 200) {
83
- throw new Error(`Unexpected response status: ${res.status}`);
84
- }
85
- return res.data;
86
- } catch (error) {
87
- console.error(`Error fetching data from URL: ${url}`, error);
88
- throw error;
89
- }
90
- });
91
- }
92
- function fetchSettings(client) {
93
- return (videoLimit = 12) => __async(this, null, function* () {
94
- try {
95
- return yield get(
96
- client,
97
- `settings?limit=${videoLimit}`
98
- );
99
- } catch (error) {
100
- console.error(`Error fetching settings with limit: ${videoLimit}`, error);
101
- throw error;
102
- }
103
- });
104
- }
105
- function fetchVideos(client) {
106
- return (videoLimit = 12) => __async(this, null, function* () {
107
- try {
108
- return yield get(
109
- client,
110
- `videos/latest?limit=${videoLimit}`
111
- );
112
- } catch (error) {
113
- console.error(`Error fetching videos with limit: ${videoLimit}`, error);
114
- throw error;
115
- }
116
- });
117
- }
118
- function searchVideos(client) {
119
- return (term) => __async(this, null, function* () {
120
- try {
121
- return yield get(client, `videos?query=${term}`);
122
- } catch (error) {
123
- console.error(`Error searching for videos with term: ${term}`, error);
124
- throw error;
125
- }
126
- });
127
- }
128
- function fetchVideo(client) {
129
- return (id) => __async(this, null, function* () {
130
- try {
131
- return yield get(client, `videos/${id}`);
132
- } catch (error) {
133
- console.error(`Error fetching video with ID: ${id}`, error);
134
- throw error;
135
- }
136
- });
137
- }
138
- function fetchPlaylists(client) {
139
- return () => __async(this, null, function* () {
140
- try {
141
- return yield get(client, "playlists");
142
- } catch (error) {
143
- console.error("Error fetching playlists", error);
144
- throw error;
145
- }
146
- });
147
- }
148
- function fetchPlaylist(client) {
149
- return (id) => __async(this, null, function* () {
150
- try {
151
- return yield get(client, `playlists/${id}`);
152
- } catch (error) {
153
- console.error(`Error fetching playlist with ID: ${id}`, error);
154
- throw error;
155
- }
156
- });
157
- }
158
-
159
- // src/util/throttle.ts
160
- var throttle = (fn, delay) => {
161
- let wait = false;
162
- let timeout;
163
- let cancelled = false;
164
- return [
165
- (...args) => {
166
- if (cancelled)
167
- return void 0;
168
- if (wait)
169
- return void 0;
170
- const val = fn(...args);
171
- wait = true;
172
- timeout = window.setTimeout(() => {
173
- wait = false;
174
- }, delay);
175
- return val;
176
- },
177
- () => {
178
- cancelled = true;
179
- clearTimeout(timeout);
180
- }
181
- ];
182
- };
183
-
184
- // src/lib/tracking.ts
185
- function sendEvent(client, eventName, data, debug) {
186
- const payload = {
187
- n: eventName,
188
- u: data.url,
189
- usr: data.userId,
190
- d: data.domain,
191
- ua: data.userAgent,
192
- w: data.deviceWidth,
193
- vid: (data == null ? void 0 : data.videoId) || void 0,
194
- vt: data.title,
195
- vdur: (data == null ? void 0 : data.videoDuration) || void 0,
196
- time: (data == null ? void 0 : data.currentTime) || void 0
197
- };
198
- if (debug)
199
- console.log(`Bold SDK - Logging event '${eventName}'`, payload);
200
- client.post("/event", payload);
201
- }
202
- var [throttledSendEvent] = throttle(sendEvent, 5e3);
203
- function trackEvent(client, userId, options) {
204
- return (video, event) => {
205
- var _a;
206
- const eventDetails = __spreadProps(__spreadValues({}, basicInfos()), {
207
- userId,
208
- videoId: video.id,
209
- title: video.title,
210
- videoDuration: video.duration,
211
- currentTime: ((_a = event.target) == null ? void 0 : _a.currentTime) || 0
212
- });
213
- if (event.type == "timeupdate" || event.type == "time-update") {
214
- throttledSendEvent(
215
- client,
216
- getEventName(event),
217
- eventDetails,
218
- options.debug
219
- );
220
- } else {
221
- sendEvent(client, getEventName(event), eventDetails, options.debug);
222
- }
223
- };
224
- }
225
- function trackPageView(client, userId, options) {
226
- return (title) => {
227
- const eventDetails = __spreadProps(__spreadValues({}, basicInfos()), {
228
- userId,
229
- title
230
- });
231
- sendEvent(client, "page_view", eventDetails, options.debug);
232
- };
233
- }
234
- function getEventName(event) {
235
- switch (event.type) {
236
- case "pause":
237
- return "video_pause";
238
- case "play":
239
- return "video_resume";
240
- case "loadedmetadata":
241
- case "loaded-metadata":
242
- return "video_load";
243
- case "time-update":
244
- case "timeupdate":
245
- return "video_progress";
246
- default:
247
- return "unknown_event";
248
- }
249
- }
250
- function basicInfos() {
251
- return {
252
- url: location.href,
253
- domain: location.hostname,
254
- referrer: document.referrer || null,
255
- deviceWidth: window.innerWidth,
256
- userAgent: navigator.userAgent
257
- };
258
- }
259
-
260
- // src/lib/client.ts
261
- function createClient(apiKey, options = { debug: false }) {
262
- var _a;
263
- if (!apiKey || typeof apiKey !== "string") {
264
- throw new Error("API key is missing or invalid");
265
- }
266
- const { debug } = options;
267
- const apiClientOptions = {
268
- baseURL: (_a = options.baseURL) != null ? _a : "https://app.boldvideo.io/api/v1/",
269
- headers: {
270
- Authorization: apiKey
271
- }
272
- };
273
- let apiClient;
274
- try {
275
- apiClient = import_axios.default.create(apiClientOptions);
276
- } catch (error) {
277
- console.error("Error creating API client", error);
278
- throw error;
279
- }
280
- const userId = [...Array(30)].map(() => Math.random().toString(36)[2]).join("");
281
- return {
282
- settings: fetchSettings(apiClient),
283
- videos: {
284
- list: fetchVideos(apiClient),
285
- get: fetchVideo(apiClient),
286
- search: searchVideos(apiClient)
287
- },
288
- playlists: {
289
- list: fetchPlaylists(apiClient),
290
- get: fetchPlaylist(apiClient)
291
- },
292
- trackEvent: trackEvent(apiClient, userId, { debug }),
293
- trackPageView: trackPageView(apiClient, userId, { debug })
294
- };
295
- }
296
- // Annotate the CommonJS export names for ESM import in node:
297
- 0 && (module.exports = {
298
- createClient
299
- });
package/dist/index.d.ts DELETED
@@ -1,197 +0,0 @@
1
- type VideoAttachment = {
2
- id: string;
3
- title: string;
4
- file_url: string;
5
- file_size?: number;
6
- file_type?: string;
7
- };
8
- type VideoDownloadUrls = {
9
- mp4?: string;
10
- audio?: string;
11
- legacy_mp4?: string;
12
- };
13
- type VideoSubtitles = {
14
- label: string;
15
- url: string;
16
- engine?: string;
17
- language: string;
18
- };
19
- type VideoTranscript = {
20
- text: string;
21
- json: any;
22
- };
23
- type VideoMetadata = {
24
- description: string;
25
- title: string;
26
- image: string | null;
27
- };
28
- type Video = {
29
- captions: string;
30
- captions_label: string;
31
- captions_lang: string;
32
- description: string | null;
33
- duration: number;
34
- id: string;
35
- imported_from: string | null;
36
- legacy_video_url: string | null;
37
- playback_id: string;
38
- published_at: string;
39
- stream_url: string;
40
- teaser: string | null;
41
- thumbnail: string;
42
- title: string;
43
- type: string;
44
- meta_data: VideoMetadata;
45
- chapters?: string;
46
- attachments?: VideoAttachment[];
47
- cta?: any | null;
48
- download_urls?: VideoDownloadUrls;
49
- internal_id?: string;
50
- playback_speed?: number;
51
- subtitles?: VideoSubtitles;
52
- tags?: string[];
53
- transcript?: VideoTranscript;
54
- };
55
- type Playlist = {
56
- description?: string;
57
- id: string;
58
- is_private: boolean;
59
- title: string;
60
- type: string;
61
- videos: Video[];
62
- };
63
- type MenuItem = {
64
- icon: string;
65
- is_ext: boolean;
66
- label: string;
67
- url: string;
68
- };
69
- type PortalDisplay = {
70
- show_chapters: boolean;
71
- show_transcripts: boolean;
72
- };
73
- type AssistantConfig = {
74
- headline: string;
75
- subheadline: string;
76
- suggestions: string[];
77
- };
78
- type PortalLayout = {
79
- assistant_config: AssistantConfig | null;
80
- show_playlists: boolean;
81
- type: string;
82
- videos_limit: number;
83
- };
84
- type PortalNavigation = {
85
- show_ai_search: boolean;
86
- show_header: boolean;
87
- show_search: boolean;
88
- };
89
- type PortalTheme = {
90
- background: string;
91
- font_body: string;
92
- font_header: string;
93
- foreground: string;
94
- logo_height: number;
95
- logo_url: string;
96
- logo_width: number;
97
- primary: string;
98
- };
99
- type Portal = {
100
- color_scheme?: 'toggle' | 'light' | 'dark';
101
- display: PortalDisplay;
102
- layout: PortalLayout;
103
- navigation: PortalNavigation;
104
- theme: PortalTheme;
105
- };
106
- type ThemeColors = {
107
- background: string;
108
- border: string;
109
- card: string;
110
- "card-foreground": string;
111
- destructive: string;
112
- "destructive-foreground": string;
113
- foreground: string;
114
- input: string;
115
- muted: string;
116
- "muted-foreground": string;
117
- popover: string;
118
- "popover-foreground": string;
119
- primary: string;
120
- "primary-foreground": string;
121
- ring: string;
122
- secondary: string;
123
- "secondary-foreground": string;
124
- };
125
- type ThemeConfig = {
126
- dark: ThemeColors;
127
- light: ThemeColors;
128
- radius: string;
129
- };
130
- type AccountAI = {
131
- avatar_url: string;
132
- enabled: boolean;
133
- greeting: string;
134
- name: string;
135
- };
136
- type Account = {
137
- ai: AccountAI;
138
- name: string;
139
- slug: string;
140
- };
141
- type Settings = {
142
- featured_playlists: Playlist[];
143
- menu_items: MenuItem[];
144
- ai_avatar: string;
145
- ai_name: string;
146
- ai_greeting?: string;
147
- has_ai: boolean;
148
- account: Account;
149
- favicon_url?: string;
150
- logo_dark_url?: string;
151
- logo_url?: string;
152
- meta_data: {
153
- channel_name: string;
154
- description: string;
155
- image: string | null;
156
- no_seo: boolean;
157
- social_graph_image_url?: string;
158
- title: string;
159
- title_suffix: string;
160
- };
161
- portal: Portal;
162
- theme_config: ThemeConfig;
163
- version: string;
164
- };
165
-
166
- type ClientOptions = {
167
- baseURL?: string;
168
- debug: boolean;
169
- };
170
- declare function createClient(apiKey: string, options?: ClientOptions): {
171
- settings: (videoLimit?: number) => Promise<{
172
- data: Settings;
173
- }>;
174
- videos: {
175
- list: (videoLimit?: number) => Promise<{
176
- data: Video[];
177
- }>;
178
- get: (id: string) => Promise<{
179
- data: Video;
180
- }>;
181
- search: (term: string) => Promise<{
182
- data: Video[];
183
- }>;
184
- };
185
- playlists: {
186
- list: () => Promise<{
187
- data: Playlist[];
188
- }>;
189
- get: (id: string) => Promise<{
190
- data: Playlist;
191
- }>;
192
- };
193
- trackEvent: (video: any, event: Event) => void;
194
- trackPageView: (title: string) => void;
195
- };
196
-
197
- export { Account, AccountAI, AssistantConfig, MenuItem, Playlist, Portal, PortalDisplay, PortalLayout, PortalNavigation, PortalTheme, Settings, ThemeColors, ThemeConfig, Video, VideoAttachment, VideoDownloadUrls, VideoMetadata, VideoSubtitles, VideoTranscript, createClient };
package/dist/index.js DELETED
@@ -1,265 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defProps = Object.defineProperties;
3
- var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
- var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
- var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
- var __spreadValues = (a, b) => {
9
- for (var prop in b || (b = {}))
10
- if (__hasOwnProp.call(b, prop))
11
- __defNormalProp(a, prop, b[prop]);
12
- if (__getOwnPropSymbols)
13
- for (var prop of __getOwnPropSymbols(b)) {
14
- if (__propIsEnum.call(b, prop))
15
- __defNormalProp(a, prop, b[prop]);
16
- }
17
- return a;
18
- };
19
- var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
- var __async = (__this, __arguments, generator) => {
21
- return new Promise((resolve, reject) => {
22
- var fulfilled = (value) => {
23
- try {
24
- step(generator.next(value));
25
- } catch (e) {
26
- reject(e);
27
- }
28
- };
29
- var rejected = (value) => {
30
- try {
31
- step(generator.throw(value));
32
- } catch (e) {
33
- reject(e);
34
- }
35
- };
36
- var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
37
- step((generator = generator.apply(__this, __arguments)).next());
38
- });
39
- };
40
-
41
- // src/lib/client.ts
42
- import axios from "axios";
43
-
44
- // src/lib/fetchers.ts
45
- function get(client, url) {
46
- return __async(this, null, function* () {
47
- try {
48
- const res = yield client.get(url);
49
- if (res.status !== 200) {
50
- throw new Error(`Unexpected response status: ${res.status}`);
51
- }
52
- return res.data;
53
- } catch (error) {
54
- console.error(`Error fetching data from URL: ${url}`, error);
55
- throw error;
56
- }
57
- });
58
- }
59
- function fetchSettings(client) {
60
- return (videoLimit = 12) => __async(this, null, function* () {
61
- try {
62
- return yield get(
63
- client,
64
- `settings?limit=${videoLimit}`
65
- );
66
- } catch (error) {
67
- console.error(`Error fetching settings with limit: ${videoLimit}`, error);
68
- throw error;
69
- }
70
- });
71
- }
72
- function fetchVideos(client) {
73
- return (videoLimit = 12) => __async(this, null, function* () {
74
- try {
75
- return yield get(
76
- client,
77
- `videos/latest?limit=${videoLimit}`
78
- );
79
- } catch (error) {
80
- console.error(`Error fetching videos with limit: ${videoLimit}`, error);
81
- throw error;
82
- }
83
- });
84
- }
85
- function searchVideos(client) {
86
- return (term) => __async(this, null, function* () {
87
- try {
88
- return yield get(client, `videos?query=${term}`);
89
- } catch (error) {
90
- console.error(`Error searching for videos with term: ${term}`, error);
91
- throw error;
92
- }
93
- });
94
- }
95
- function fetchVideo(client) {
96
- return (id) => __async(this, null, function* () {
97
- try {
98
- return yield get(client, `videos/${id}`);
99
- } catch (error) {
100
- console.error(`Error fetching video with ID: ${id}`, error);
101
- throw error;
102
- }
103
- });
104
- }
105
- function fetchPlaylists(client) {
106
- return () => __async(this, null, function* () {
107
- try {
108
- return yield get(client, "playlists");
109
- } catch (error) {
110
- console.error("Error fetching playlists", error);
111
- throw error;
112
- }
113
- });
114
- }
115
- function fetchPlaylist(client) {
116
- return (id) => __async(this, null, function* () {
117
- try {
118
- return yield get(client, `playlists/${id}`);
119
- } catch (error) {
120
- console.error(`Error fetching playlist with ID: ${id}`, error);
121
- throw error;
122
- }
123
- });
124
- }
125
-
126
- // src/util/throttle.ts
127
- var throttle = (fn, delay) => {
128
- let wait = false;
129
- let timeout;
130
- let cancelled = false;
131
- return [
132
- (...args) => {
133
- if (cancelled)
134
- return void 0;
135
- if (wait)
136
- return void 0;
137
- const val = fn(...args);
138
- wait = true;
139
- timeout = window.setTimeout(() => {
140
- wait = false;
141
- }, delay);
142
- return val;
143
- },
144
- () => {
145
- cancelled = true;
146
- clearTimeout(timeout);
147
- }
148
- ];
149
- };
150
-
151
- // src/lib/tracking.ts
152
- function sendEvent(client, eventName, data, debug) {
153
- const payload = {
154
- n: eventName,
155
- u: data.url,
156
- usr: data.userId,
157
- d: data.domain,
158
- ua: data.userAgent,
159
- w: data.deviceWidth,
160
- vid: (data == null ? void 0 : data.videoId) || void 0,
161
- vt: data.title,
162
- vdur: (data == null ? void 0 : data.videoDuration) || void 0,
163
- time: (data == null ? void 0 : data.currentTime) || void 0
164
- };
165
- if (debug)
166
- console.log(`Bold SDK - Logging event '${eventName}'`, payload);
167
- client.post("/event", payload);
168
- }
169
- var [throttledSendEvent] = throttle(sendEvent, 5e3);
170
- function trackEvent(client, userId, options) {
171
- return (video, event) => {
172
- var _a;
173
- const eventDetails = __spreadProps(__spreadValues({}, basicInfos()), {
174
- userId,
175
- videoId: video.id,
176
- title: video.title,
177
- videoDuration: video.duration,
178
- currentTime: ((_a = event.target) == null ? void 0 : _a.currentTime) || 0
179
- });
180
- if (event.type == "timeupdate" || event.type == "time-update") {
181
- throttledSendEvent(
182
- client,
183
- getEventName(event),
184
- eventDetails,
185
- options.debug
186
- );
187
- } else {
188
- sendEvent(client, getEventName(event), eventDetails, options.debug);
189
- }
190
- };
191
- }
192
- function trackPageView(client, userId, options) {
193
- return (title) => {
194
- const eventDetails = __spreadProps(__spreadValues({}, basicInfos()), {
195
- userId,
196
- title
197
- });
198
- sendEvent(client, "page_view", eventDetails, options.debug);
199
- };
200
- }
201
- function getEventName(event) {
202
- switch (event.type) {
203
- case "pause":
204
- return "video_pause";
205
- case "play":
206
- return "video_resume";
207
- case "loadedmetadata":
208
- case "loaded-metadata":
209
- return "video_load";
210
- case "time-update":
211
- case "timeupdate":
212
- return "video_progress";
213
- default:
214
- return "unknown_event";
215
- }
216
- }
217
- function basicInfos() {
218
- return {
219
- url: location.href,
220
- domain: location.hostname,
221
- referrer: document.referrer || null,
222
- deviceWidth: window.innerWidth,
223
- userAgent: navigator.userAgent
224
- };
225
- }
226
-
227
- // src/lib/client.ts
228
- function createClient(apiKey, options = { debug: false }) {
229
- var _a;
230
- if (!apiKey || typeof apiKey !== "string") {
231
- throw new Error("API key is missing or invalid");
232
- }
233
- const { debug } = options;
234
- const apiClientOptions = {
235
- baseURL: (_a = options.baseURL) != null ? _a : "https://app.boldvideo.io/api/v1/",
236
- headers: {
237
- Authorization: apiKey
238
- }
239
- };
240
- let apiClient;
241
- try {
242
- apiClient = axios.create(apiClientOptions);
243
- } catch (error) {
244
- console.error("Error creating API client", error);
245
- throw error;
246
- }
247
- const userId = [...Array(30)].map(() => Math.random().toString(36)[2]).join("");
248
- return {
249
- settings: fetchSettings(apiClient),
250
- videos: {
251
- list: fetchVideos(apiClient),
252
- get: fetchVideo(apiClient),
253
- search: searchVideos(apiClient)
254
- },
255
- playlists: {
256
- list: fetchPlaylists(apiClient),
257
- get: fetchPlaylist(apiClient)
258
- },
259
- trackEvent: trackEvent(apiClient, userId, { debug }),
260
- trackPageView: trackPageView(apiClient, userId, { debug })
261
- };
262
- }
263
- export {
264
- createClient
265
- };