@churchapps/content-providers 0.2.0 → 0.3.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/dist/index.d.cts CHANGED
@@ -687,6 +687,40 @@ declare class JesusFilmProvider implements IProvider {
687
687
  supportsDeviceFlow(): boolean;
688
688
  }
689
689
 
690
+ /**
691
+ * CBN Provider
692
+ *
693
+ * Faith-based kids' video curriculum. Auth uses OAuth 2.0 Device Flow.
694
+ *
695
+ * Path structure:
696
+ * / -> single "Catalog" root folder
697
+ * /catalog -> course folders (GET /catalog)
698
+ * /catalog/{courseId} -> lesson folders (GET /catalog/{courseId})
699
+ * /catalog/{courseId}/{lessonId} -> video files (GET /lesson-playlist/{lessonId})
700
+ */
701
+ declare class CbnProvider implements IProvider {
702
+ private readonly apiHelper;
703
+ private readonly deviceFlowHelper;
704
+ private apiRequest;
705
+ readonly id = "cbn";
706
+ readonly name = "CBN";
707
+ readonly logos: ProviderLogos;
708
+ readonly config: ContentProviderConfig;
709
+ readonly requiresAuth = true;
710
+ readonly authTypes: AuthType[];
711
+ readonly capabilities: ProviderCapabilities;
712
+ browse(path?: string | null, auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
713
+ private getCourses;
714
+ private getLessons;
715
+ private getVideos;
716
+ private fetchPlaylist;
717
+ getPlaylist(path: string, auth?: ContentProviderAuthData | null, _resolution?: number): Promise<ContentFile[] | null>;
718
+ getInstructions(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
719
+ supportsDeviceFlow(): boolean;
720
+ initiateDeviceFlow(): Promise<DeviceAuthorizationResponse | null>;
721
+ pollDeviceFlowToken(deviceCode: string): Promise<DeviceFlowPollResult>;
722
+ }
723
+
690
724
  declare function getProvider(providerId: string): IProvider | null;
691
725
  declare function getAllProviders(): IProvider[];
692
726
  declare function registerProvider(provider: IProvider): void;
@@ -708,4 +742,4 @@ declare function getAvailableProviders(ids?: string[]): ProviderInfo[];
708
742
  */
709
743
  declare const VERSION = "0.0.5";
710
744
 
711
- export { APlayProvider, ApiHelper, type AuthType, B1ChurchProvider, BibleProjectProvider, type ContentFile, type ContentFolder, type ContentItem, type ContentProviderAuthData, type ContentProviderConfig, type CurrentPlan, DEFAULT_DURATION_CONFIG, type DeviceAuthorizationResponse, DeviceFlowHelper, type DeviceFlowPollResult, type DeviceFlowState, DropboxProvider, type DurationEstimationConfig, type EndpointValue, type EndpointsConfig, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, FormatConverters, FormatResolver, type FormatResolverOptions, HighVoltageKidsProvider, type IProvider, type InstructionItem, type Instructions, JesusFilmProvider, LessonsChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, type MessageFileInterface, OAuthHelper, type Plan, type PlanPresentation, type PlanSection, type PlanTimelineItem, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, type ResolvedFormatMeta, SignPresenterProvider, TokenHelper, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, appendToPath, buildPath, countWords, createFile, createFolder, detectMediaType, estimateDuration, estimateImageDuration, estimateTextDuration, generatePath, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, getSegment, isContentFile, isContentFolder, isMediaFile, navigateToPath, parsePath, registerProvider };
745
+ export { APlayProvider, ApiHelper, type AuthType, B1ChurchProvider, BibleProjectProvider, CbnProvider, type ContentFile, type ContentFolder, type ContentItem, type ContentProviderAuthData, type ContentProviderConfig, type CurrentPlan, DEFAULT_DURATION_CONFIG, type DeviceAuthorizationResponse, DeviceFlowHelper, type DeviceFlowPollResult, type DeviceFlowState, DropboxProvider, type DurationEstimationConfig, type EndpointValue, type EndpointsConfig, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, FormatConverters, FormatResolver, type FormatResolverOptions, HighVoltageKidsProvider, type IProvider, type InstructionItem, type Instructions, JesusFilmProvider, LessonsChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, type MessageFileInterface, OAuthHelper, type Plan, type PlanPresentation, type PlanSection, type PlanTimelineItem, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, type ResolvedFormatMeta, SignPresenterProvider, TokenHelper, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, appendToPath, buildPath, countWords, createFile, createFolder, detectMediaType, estimateDuration, estimateImageDuration, estimateTextDuration, generatePath, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, getSegment, isContentFile, isContentFolder, isMediaFile, navigateToPath, parsePath, registerProvider };
package/dist/index.d.ts CHANGED
@@ -687,6 +687,40 @@ declare class JesusFilmProvider implements IProvider {
687
687
  supportsDeviceFlow(): boolean;
688
688
  }
689
689
 
690
+ /**
691
+ * CBN Provider
692
+ *
693
+ * Faith-based kids' video curriculum. Auth uses OAuth 2.0 Device Flow.
694
+ *
695
+ * Path structure:
696
+ * / -> single "Catalog" root folder
697
+ * /catalog -> course folders (GET /catalog)
698
+ * /catalog/{courseId} -> lesson folders (GET /catalog/{courseId})
699
+ * /catalog/{courseId}/{lessonId} -> video files (GET /lesson-playlist/{lessonId})
700
+ */
701
+ declare class CbnProvider implements IProvider {
702
+ private readonly apiHelper;
703
+ private readonly deviceFlowHelper;
704
+ private apiRequest;
705
+ readonly id = "cbn";
706
+ readonly name = "CBN";
707
+ readonly logos: ProviderLogos;
708
+ readonly config: ContentProviderConfig;
709
+ readonly requiresAuth = true;
710
+ readonly authTypes: AuthType[];
711
+ readonly capabilities: ProviderCapabilities;
712
+ browse(path?: string | null, auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
713
+ private getCourses;
714
+ private getLessons;
715
+ private getVideos;
716
+ private fetchPlaylist;
717
+ getPlaylist(path: string, auth?: ContentProviderAuthData | null, _resolution?: number): Promise<ContentFile[] | null>;
718
+ getInstructions(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
719
+ supportsDeviceFlow(): boolean;
720
+ initiateDeviceFlow(): Promise<DeviceAuthorizationResponse | null>;
721
+ pollDeviceFlowToken(deviceCode: string): Promise<DeviceFlowPollResult>;
722
+ }
723
+
690
724
  declare function getProvider(providerId: string): IProvider | null;
691
725
  declare function getAllProviders(): IProvider[];
692
726
  declare function registerProvider(provider: IProvider): void;
@@ -708,4 +742,4 @@ declare function getAvailableProviders(ids?: string[]): ProviderInfo[];
708
742
  */
709
743
  declare const VERSION = "0.0.5";
710
744
 
711
- export { APlayProvider, ApiHelper, type AuthType, B1ChurchProvider, BibleProjectProvider, type ContentFile, type ContentFolder, type ContentItem, type ContentProviderAuthData, type ContentProviderConfig, type CurrentPlan, DEFAULT_DURATION_CONFIG, type DeviceAuthorizationResponse, DeviceFlowHelper, type DeviceFlowPollResult, type DeviceFlowState, DropboxProvider, type DurationEstimationConfig, type EndpointValue, type EndpointsConfig, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, FormatConverters, FormatResolver, type FormatResolverOptions, HighVoltageKidsProvider, type IProvider, type InstructionItem, type Instructions, JesusFilmProvider, LessonsChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, type MessageFileInterface, OAuthHelper, type Plan, type PlanPresentation, type PlanSection, type PlanTimelineItem, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, type ResolvedFormatMeta, SignPresenterProvider, TokenHelper, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, appendToPath, buildPath, countWords, createFile, createFolder, detectMediaType, estimateDuration, estimateImageDuration, estimateTextDuration, generatePath, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, getSegment, isContentFile, isContentFolder, isMediaFile, navigateToPath, parsePath, registerProvider };
745
+ export { APlayProvider, ApiHelper, type AuthType, B1ChurchProvider, BibleProjectProvider, CbnProvider, type ContentFile, type ContentFolder, type ContentItem, type ContentProviderAuthData, type ContentProviderConfig, type CurrentPlan, DEFAULT_DURATION_CONFIG, type DeviceAuthorizationResponse, DeviceFlowHelper, type DeviceFlowPollResult, type DeviceFlowState, DropboxProvider, type DurationEstimationConfig, type EndpointValue, type EndpointsConfig, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, FormatConverters, FormatResolver, type FormatResolverOptions, HighVoltageKidsProvider, type IProvider, type InstructionItem, type Instructions, JesusFilmProvider, LessonsChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, type MessageFileInterface, OAuthHelper, type Plan, type PlanPresentation, type PlanSection, type PlanTimelineItem, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, type ResolvedFormatMeta, SignPresenterProvider, TokenHelper, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, appendToPath, buildPath, countWords, createFile, createFolder, detectMediaType, estimateDuration, estimateImageDuration, estimateTextDuration, generatePath, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, getSegment, isContentFile, isContentFolder, isMediaFile, navigateToPath, parsePath, registerProvider };
package/dist/index.js CHANGED
@@ -13173,6 +13173,156 @@ var JesusFilmProvider = class {
13173
13173
  }
13174
13174
  };
13175
13175
 
13176
+ // src/providers/cbn/CbnConverters.ts
13177
+ function resolveThumb(thumb) {
13178
+ if (typeof thumb === "string") return thumb || void 0;
13179
+ if (thumb && typeof thumb === "object") {
13180
+ const medium = thumb.sizes?.medium;
13181
+ if (typeof medium === "string") return medium;
13182
+ if (typeof thumb.url === "string") return thumb.url;
13183
+ }
13184
+ return void 0;
13185
+ }
13186
+ function convertCoursesToFolders(courses) {
13187
+ return courses.map((c) => {
13188
+ const id = String(c.id);
13189
+ return createFolder(id, c.title, `/catalog/${id}`, resolveThumb(c.thumb));
13190
+ });
13191
+ }
13192
+ function convertLessonsToFolders(lessons, coursePath) {
13193
+ return lessons.map((l) => {
13194
+ const id = String(l.id);
13195
+ return createFolder(id, l.title, `${coursePath}/${id}`, resolveThumb(l.thumb), true);
13196
+ });
13197
+ }
13198
+ function convertPlaylistToFiles(playlist) {
13199
+ return playlist.playlist.map((v) => {
13200
+ const file = createFile(v.video_id, v.title, v.mp4_url || v.playback_url, {
13201
+ mediaType: "video",
13202
+ thumbnail: void 0
13203
+ });
13204
+ file.mediaId = v.video_id;
13205
+ file.downloadUrl = v.mp4_url ?? void 0;
13206
+ file.providerData = {
13207
+ brightcovePolicyKey: playlist.brightcove_policy_key,
13208
+ brightcoveAccountId: v.account_id,
13209
+ brightcoveVideoId: v.video_id,
13210
+ brightcovePlaybackUrl: v.playback_url,
13211
+ brightcoveMp4Url: v.mp4_url
13212
+ };
13213
+ return file;
13214
+ });
13215
+ }
13216
+ function convertPlaylistToInstructions(playlist) {
13217
+ const files = convertPlaylistToFiles(playlist);
13218
+ const items = files.map((file) => ({
13219
+ id: file.id + "-action",
13220
+ itemType: "action",
13221
+ label: file.title,
13222
+ actionType: "play",
13223
+ children: [
13224
+ {
13225
+ id: file.id,
13226
+ itemType: "file",
13227
+ label: file.title,
13228
+ seconds: file.seconds,
13229
+ downloadUrl: file.url,
13230
+ thumbnail: file.thumbnail
13231
+ }
13232
+ ]
13233
+ }));
13234
+ return { name: playlist.lesson_title || "Lesson", items };
13235
+ }
13236
+
13237
+ // src/providers/cbn/logo.ts
13238
+ var CBN_LOGO = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAMAAAC3Ycb+AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA/tpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDcuMi1jMDAwIDc5LjFiNjVhNzliNCwgMjAyMi8wNi8xMy0yMjowMTowMSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1wTU06T3JpZ2luYWxEb2N1bWVudElEPSJ1dWlkOjVEMjA4OTI0OTNCRkRCMTE5MTRBODU5MEQzMTUwOEM4IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjczNTFDMjdFNENEMDExRURCNUVBQkI4RUVDOUM5MkUwIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjczNTFDMjdENENEMDExRURCNUVBQkI4RUVDOUM5MkUwIiB4bXA6Q3JlYXRvclRvb2w9IkFkb2JlIElsbHVzdHJhdG9yIENDIDIwMTcgKE1hY2ludG9zaCkiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0idXVpZDo4NGJiYzc1OC1iNjBhLTFlNGQtODJlMS1mYTQyNzhlMmZhMTciIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6OTQzMjNlNWMtYjBlMS00YTliLWJjZWUtODljYjRlOGVjZjAwIi8+IDxkYzp0aXRsZT4gPHJkZjpBbHQ+IDxyZGY6bGkgeG1sOmxhbmc9IngtZGVmYXVsdCI+Q0JOLUZMQU1FPC9yZGY6bGk+IDwvcmRmOkFsdD4gPC9kYzp0aXRsZT4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz40pvOUAAAC2VBMVEUdmtYhnNf8/v/7/f4emtb9/v8fm9by+f0nntjU7Pf6/f4gm9b2+/0lntfk8/q43/L3+/5Nr9/5/P4poNg1pdovotnj8voknddQsd84ptsqoNjp9fve8PnX7fgpn9hRsd/1+/3M6Pba7vhmuuO/4vMinNfG5vUtodmGyenm9Pq64PKOzOrz+f2c0+15w+fw+PyVz+zx+fyq2fCl1+9tvuREq91ateGx3PHv+Pz4/P6d0+0mnthxwOXf8fng8fkroNlhuOI3pduk1u7B4/Ts9/zq9ftAqdxHrd54w+ft9/yu2/CKy+pOsN88qNxft+I+qdy74fNIrd7n9PtDq93z+v1Ws+BrveTS6/eW0OxCq91/xuiz3fFvvuXN6fYzpNqZ0e2Ly+oxo9q94fO94vPc7/nF5fSn2O/o9ft2wuYwotk2pdtVs+Du9/ySzutqvOQjnddPsN8uotl3wubY7vjC5PSEyOl1weZpvORSsuBctuHl9Po5p9vT6/eMzOo7p9uBx+iv2/GTz+vh8vq03fFguOLs9vvV7Pe23/JXtOBkuuMon9i+4vOQzetfuOKg1e6Jyurr9vvi8vp+xuhnu+Op2e/R6vf0+v3c8Pnb7/h+xehLr946p9ssodmj1u40pNqUz+zd8PlJrt57xOdXtOFdt+Kw3PFAqtxbtuG33/J8xOd6xOet2vDI5vW54PJwv+VBqt1FrN2a0u1luuOAxuhsveSh1e6s2vCNzOqt2/Ci1e7E5PTJ5/XH5vXL6PY9qNx0weZ9xedYteHK5/WFyOmCx+hnu+TQ6vZovOS13vLD5PSb0u1Mr9/O6fay3fG84fPZ7vhiueNKrt5zwObP6vZZteFjueOm1+9TsuCf1O6o2O+DyOhUs+DF5fWPzeuX0ezW7fhGrN0wo9qOzetet+IypNqr2fC13vGY0exvv+WRzuue1O2IyumHyulywOVuvuU/qdye0+3A4/T///96A0GMAAAA83RSTlP//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wB12P98AAAWOklEQVR42uzd5YMUx9YG8JpZN3ZZdHFblg3u7u7uGtzdITgkwUJCsBCc4CRA8BASEgJxtxtPbpKrr52/4EUvK3VqWk5V9+ye5+vOdE3Xb2e6u1QAx1cRXAUMwmEQBuEwCINwGIRBOAzCIBwG4TAIg3AYhEE4DMIgHAZhEA6DcBiEQTgMwiAcBmEQDoMwCIdBOAzCIBwGYRAOgzAIh0EYhMMgHAZhEA6DMAiHQRiEwyAMwmEQDoMwCIdBsmdfcwbxVeLWt2EQX2WT2BrDID7KcCGWDWQQH2WKEOnjGcQ/eU/cyZAgg/gm9e+KfFmTQfyS8XdBRM/9DOKTpBS5J1KkPIP4JFXugYikxxjEH1kVeV8k+iKD+COHxYM0YRBf5PRDEFGLQfyQ4F7/i+Sv5vd/C9+L5C+Q/Y9AxE8M4oOUzSJyhUG8z1+ygIgVDOJ5+jXNAhJoyyCeZ0DWr0jsLQbxOqOzgohfizKIx4kokk1kcAyDeJwT2UDE0SCDeJvy2UHEmwzicdJyiFxkEG8zJAdIsYEM4ml+yAEi0qYyiKf3WS/mFNnEIJ7mXE4QMZJBvMzIXCCBWwziYT7MBSKWVWMQDy8igdwiExnEwwzODSJGM4h3eUcCMmIqg3iWJyQgoh6DeJY2MhCxgUG8ymkpSFoig3iU4VIQ8TaDeJSf5SAJcQziTYrKQcQ3DOIvELGaQfwFsqQxg3iRChiIWMkgXmQgChLbjkE8yHsoiBjCIB7kJA5SLJNBzGcfDiI6MYj5dFKABJoziPFMUYCI+QxiPBkqkEBJBjGckkKZ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";
13239
+
13240
+ // src/providers/cbn/CbnProvider.ts
13241
+ var API_BASE5 = "https://sbamemberdev.wpenginepowered.com/wp-json/superbook/v1";
13242
+ var CbnProvider = class {
13243
+ constructor() {
13244
+ this.apiHelper = new ApiHelper();
13245
+ this.deviceFlowHelper = new DeviceFlowHelper();
13246
+ this.id = "cbn";
13247
+ this.name = "CBN";
13248
+ this.logos = { light: CBN_LOGO, dark: CBN_LOGO };
13249
+ this.config = {
13250
+ id: "cbn",
13251
+ name: "CBN",
13252
+ apiBase: API_BASE5,
13253
+ oauthBase: `${API_BASE5}/auth`,
13254
+ clientId: "freeplay",
13255
+ scopes: [],
13256
+ supportsDeviceFlow: true,
13257
+ deviceAuthEndpoint: "/device",
13258
+ endpoints: {
13259
+ catalog: "/catalog",
13260
+ courseDetail: (courseId) => `/catalog/${courseId}`,
13261
+ lessonPlaylist: (lessonId) => `/lesson-playlist/${lessonId}`
13262
+ }
13263
+ };
13264
+ this.requiresAuth = true;
13265
+ this.authTypes = ["device_flow"];
13266
+ this.capabilities = { browse: true, presentations: false, playlist: true, instructions: true, mediaLicensing: false };
13267
+ }
13268
+ async apiRequest(path, auth) {
13269
+ return this.apiHelper.apiRequest(this.config, this.id, path, auth);
13270
+ }
13271
+ async browse(path, auth) {
13272
+ const { segments, depth } = parsePath(path);
13273
+ if (depth === 0) {
13274
+ return [{ type: "folder", id: "catalog-root", title: "Catalog", path: "/catalog" }];
13275
+ }
13276
+ if (segments[0] !== "catalog") return [];
13277
+ if (depth === 1) return this.getCourses(auth);
13278
+ if (depth === 2) return this.getLessons(segments[1], path, auth);
13279
+ if (depth === 3) return this.getVideos(segments[2], auth);
13280
+ return [];
13281
+ }
13282
+ async getCourses(auth) {
13283
+ const response = await this.apiRequest(this.config.endpoints.catalog, auth);
13284
+ if (!Array.isArray(response)) return [];
13285
+ return convertCoursesToFolders(response);
13286
+ }
13287
+ async getLessons(courseId, coursePath, auth) {
13288
+ const pathFn = this.config.endpoints.courseDetail;
13289
+ const response = await this.apiRequest(pathFn(courseId), auth);
13290
+ if (!response?.lessons) return [];
13291
+ return convertLessonsToFolders(response.lessons, coursePath);
13292
+ }
13293
+ async getVideos(lessonId, auth) {
13294
+ const playlist = await this.fetchPlaylist(lessonId, auth);
13295
+ return playlist ? convertPlaylistToFiles(playlist) : [];
13296
+ }
13297
+ async fetchPlaylist(lessonId, auth) {
13298
+ const pathFn = this.config.endpoints.lessonPlaylist;
13299
+ return this.apiRequest(pathFn(lessonId), auth);
13300
+ }
13301
+ async getPlaylist(path, auth, _resolution) {
13302
+ const { segments, depth } = parsePath(path);
13303
+ if (depth !== 3 || segments[0] !== "catalog") return null;
13304
+ const playlist = await this.fetchPlaylist(segments[2], auth);
13305
+ if (!playlist || playlist.playlist.length === 0) return null;
13306
+ return convertPlaylistToFiles(playlist);
13307
+ }
13308
+ async getInstructions(path, auth) {
13309
+ const { segments, depth } = parsePath(path);
13310
+ if (depth !== 3 || segments[0] !== "catalog") return null;
13311
+ const playlist = await this.fetchPlaylist(segments[2], auth);
13312
+ if (!playlist || playlist.playlist.length === 0) return null;
13313
+ return convertPlaylistToInstructions(playlist);
13314
+ }
13315
+ supportsDeviceFlow() {
13316
+ return this.deviceFlowHelper.supportsDeviceFlow(this.config);
13317
+ }
13318
+ async initiateDeviceFlow() {
13319
+ return this.deviceFlowHelper.initiateDeviceFlow(this.config);
13320
+ }
13321
+ async pollDeviceFlowToken(deviceCode) {
13322
+ return this.deviceFlowHelper.pollDeviceFlowToken(this.config, deviceCode);
13323
+ }
13324
+ };
13325
+
13176
13326
  // src/providers/lifeChurch/data.json
13177
13327
  var data_default3 = {
13178
13328
  generatedAt: "2026-05-09T20:14:53.089Z",
@@ -17075,6 +17225,7 @@ function initializeProviders() {
17075
17225
  const planningCenter = new PlanningCenterProvider();
17076
17226
  const signPresenter = new SignPresenterProvider();
17077
17227
  const jesusFilm = new JesusFilmProvider();
17228
+ const cbn = new CbnProvider();
17078
17229
  providerRegistry.set(aplay.id, aplay);
17079
17230
  providerRegistry.set(b1Church.id, b1Church);
17080
17231
  providerRegistry.set(dropbox.id, dropbox);
@@ -17085,6 +17236,7 @@ function initializeProviders() {
17085
17236
  providerRegistry.set(lifeChurch.id, lifeChurch);
17086
17237
  providerRegistry.set(planningCenter.id, planningCenter);
17087
17238
  providerRegistry.set(signPresenter.id, signPresenter);
17239
+ providerRegistry.set(cbn.id, cbn);
17088
17240
  }
17089
17241
  initializeProviders();
17090
17242
  function getProviderConfig(providerId) {
@@ -17125,6 +17277,7 @@ export {
17125
17277
  ApiHelper,
17126
17278
  B1ChurchProvider,
17127
17279
  BibleProjectProvider,
17280
+ CbnProvider,
17128
17281
  DEFAULT_DURATION_CONFIG,
17129
17282
  DeviceFlowHelper,
17130
17283
  DropboxProvider,