@boldvideo/bold-js 0.5.0 → 0.6.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/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @boldvideo/bold-js
2
2
 
3
+ ## 0.6.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix missing compiled dist files in published package by adding .npmignore
8
+
9
+ ## 0.6.0
10
+
11
+ ### Minor Changes
12
+
13
+ - Add complete type definitions for Settings and Video API responses
14
+
15
+ **Settings updates:**
16
+
17
+ - Add `portal` object with display, layout, navigation, and theme settings
18
+ - Add `portal.navigation.show_header` field (BOLD-687)
19
+ - Add `account` object with nested AI configuration
20
+ - Add top-level fields: `favicon_url`, `logo_dark_url`, `logo_url`, `version`
21
+ - Add `theme_config` with dark/light theme definitions
22
+ - Expand `meta_data` to include `social_graph_image_url`
23
+ - Maintain backward compatibility with flat AI fields
24
+
25
+ **Video updates:**
26
+
27
+ - Add missing fields: `chapters`, `attachments`, `download_urls`, `transcript`
28
+ - Add `internal_id`, `playback_speed`, `subtitles`, `tags`, `cta`
29
+ - Fix `meta_data` type from array to object
30
+ - Replace incorrect `transcription` field with correct `transcript` field
31
+ - Mark optional fields appropriately
32
+
3
33
  ## 0.5.0
4
34
 
5
35
  ### Minor Changes
Binary file
package/dist/index.cjs ADDED
@@ -0,0 +1,299 @@
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
+ });
@@ -0,0 +1,196 @@
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
+ display: PortalDisplay;
101
+ layout: PortalLayout;
102
+ navigation: PortalNavigation;
103
+ theme: PortalTheme;
104
+ };
105
+ type ThemeColors = {
106
+ background: string;
107
+ border: string;
108
+ card: string;
109
+ "card-foreground": string;
110
+ destructive: string;
111
+ "destructive-foreground": string;
112
+ foreground: string;
113
+ input: string;
114
+ muted: string;
115
+ "muted-foreground": string;
116
+ popover: string;
117
+ "popover-foreground": string;
118
+ primary: string;
119
+ "primary-foreground": string;
120
+ ring: string;
121
+ secondary: string;
122
+ "secondary-foreground": string;
123
+ };
124
+ type ThemeConfig = {
125
+ dark: ThemeColors;
126
+ light: ThemeColors;
127
+ radius: string;
128
+ };
129
+ type AccountAI = {
130
+ avatar_url: string;
131
+ enabled: boolean;
132
+ greeting: string;
133
+ name: string;
134
+ };
135
+ type Account = {
136
+ ai: AccountAI;
137
+ name: string;
138
+ slug: string;
139
+ };
140
+ type Settings = {
141
+ featured_playlists: Playlist[];
142
+ menu_items: MenuItem[];
143
+ ai_avatar: string;
144
+ ai_name: string;
145
+ ai_greeting?: string;
146
+ has_ai: boolean;
147
+ account: Account;
148
+ favicon_url?: string;
149
+ logo_dark_url?: string;
150
+ logo_url?: string;
151
+ meta_data: {
152
+ channel_name: string;
153
+ description: string;
154
+ image: string | null;
155
+ no_seo: boolean;
156
+ social_graph_image_url?: string;
157
+ title: string;
158
+ title_suffix: string;
159
+ };
160
+ portal: Portal;
161
+ theme_config: ThemeConfig;
162
+ version: string;
163
+ };
164
+
165
+ type ClientOptions = {
166
+ baseURL?: string;
167
+ debug: boolean;
168
+ };
169
+ declare function createClient(apiKey: string, options?: ClientOptions): {
170
+ settings: (videoLimit?: number) => Promise<{
171
+ data: Settings;
172
+ }>;
173
+ videos: {
174
+ list: (videoLimit?: number) => Promise<{
175
+ data: Video[];
176
+ }>;
177
+ get: (id: string) => Promise<{
178
+ data: Video;
179
+ }>;
180
+ search: (term: string) => Promise<{
181
+ data: Video[];
182
+ }>;
183
+ };
184
+ playlists: {
185
+ list: () => Promise<{
186
+ data: Playlist[];
187
+ }>;
188
+ get: (id: string) => Promise<{
189
+ data: Playlist;
190
+ }>;
191
+ };
192
+ trackEvent: (video: any, event: Event) => void;
193
+ trackPageView: (title: string) => void;
194
+ };
195
+
196
+ export { Account, AccountAI, AssistantConfig, MenuItem, Playlist, Portal, PortalDisplay, PortalLayout, PortalNavigation, PortalTheme, Settings, ThemeColors, ThemeConfig, Video, VideoAttachment, VideoDownloadUrls, VideoMetadata, VideoSubtitles, VideoTranscript, createClient };