@churchapps/content-provider-helper 0.0.2 → 0.0.3
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.cjs +1239 -1599
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +340 -95
- package/dist/index.d.ts +340 -95
- package/dist/index.js +1228 -1599
- package/dist/index.js.map +1 -1
- package/package.json +9 -2
package/dist/index.d.cts
CHANGED
|
@@ -26,12 +26,12 @@ interface DeviceAuthorizationResponse {
|
|
|
26
26
|
interval?: number;
|
|
27
27
|
}
|
|
28
28
|
interface DeviceFlowState {
|
|
29
|
-
status:
|
|
29
|
+
status: "loading" | "awaiting_user" | "polling" | "success" | "error" | "expired";
|
|
30
30
|
deviceAuth?: DeviceAuthorizationResponse;
|
|
31
31
|
error?: string;
|
|
32
32
|
pollCount?: number;
|
|
33
33
|
}
|
|
34
|
-
type AuthType =
|
|
34
|
+
type AuthType = "none" | "oauth_pkce" | "device_flow" | "form_login";
|
|
35
35
|
interface ProviderLogos {
|
|
36
36
|
light: string;
|
|
37
37
|
dark: string;
|
|
@@ -46,17 +46,19 @@ interface ProviderInfo {
|
|
|
46
46
|
capabilities: ProviderCapabilities;
|
|
47
47
|
}
|
|
48
48
|
interface ContentFolder {
|
|
49
|
-
type:
|
|
49
|
+
type: "folder";
|
|
50
50
|
id: string;
|
|
51
51
|
title: string;
|
|
52
52
|
image?: string;
|
|
53
|
+
isLeaf?: boolean;
|
|
54
|
+
path: string;
|
|
53
55
|
providerData?: Record<string, unknown>;
|
|
54
56
|
}
|
|
55
57
|
interface ContentFile {
|
|
56
|
-
type:
|
|
58
|
+
type: "file";
|
|
57
59
|
id: string;
|
|
58
60
|
title: string;
|
|
59
|
-
mediaType:
|
|
61
|
+
mediaType: "video" | "image";
|
|
60
62
|
image?: string;
|
|
61
63
|
url: string;
|
|
62
64
|
embedUrl?: string;
|
|
@@ -76,7 +78,7 @@ type DeviceFlowPollResult = ContentProviderAuthData | {
|
|
|
76
78
|
interface PlanPresentation {
|
|
77
79
|
id: string;
|
|
78
80
|
name: string;
|
|
79
|
-
actionType:
|
|
81
|
+
actionType: "play" | "add-on" | "other";
|
|
80
82
|
files: ContentFile[];
|
|
81
83
|
}
|
|
82
84
|
interface PlanSection {
|
|
@@ -157,15 +159,114 @@ interface ProviderCapabilities {
|
|
|
157
159
|
expandedInstructions: boolean;
|
|
158
160
|
mediaLicensing: boolean;
|
|
159
161
|
}
|
|
160
|
-
type MediaLicenseStatus =
|
|
162
|
+
type MediaLicenseStatus = "valid" | "expired" | "not_licensed" | "unknown";
|
|
161
163
|
interface MediaLicenseResult {
|
|
162
164
|
mediaId: string;
|
|
163
165
|
status: MediaLicenseStatus;
|
|
164
166
|
message?: string;
|
|
165
167
|
expiresAt?: string | number;
|
|
166
168
|
}
|
|
169
|
+
/**
|
|
170
|
+
* Core provider interface - all providers should implement this
|
|
171
|
+
*/
|
|
172
|
+
interface IProvider {
|
|
173
|
+
readonly id: string;
|
|
174
|
+
readonly name: string;
|
|
175
|
+
readonly logos: ProviderLogos;
|
|
176
|
+
readonly config: ContentProviderConfig;
|
|
177
|
+
readonly requiresAuth: boolean;
|
|
178
|
+
readonly capabilities: ProviderCapabilities;
|
|
179
|
+
readonly authTypes: AuthType[];
|
|
180
|
+
browse(path?: string | null, auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
181
|
+
getPresentations(path: string, auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
182
|
+
getPlaylist?(path: string, auth?: ContentProviderAuthData | null, resolution?: number): Promise<ContentFile[] | null>;
|
|
183
|
+
getInstructions?(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
184
|
+
getExpandedInstructions?(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
185
|
+
checkMediaLicense?(mediaId: string, auth?: ContentProviderAuthData | null): Promise<MediaLicenseResult | null>;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* @deprecated Use IProvider instead. This interface will be removed in a future version.
|
|
189
|
+
*/
|
|
190
|
+
interface IContentProvider {
|
|
191
|
+
readonly id: string;
|
|
192
|
+
readonly name: string;
|
|
193
|
+
readonly logos: ProviderLogos;
|
|
194
|
+
readonly config: ContentProviderConfig;
|
|
195
|
+
browse(path?: string | null, auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
196
|
+
getPresentations(path: string, auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
197
|
+
getPlaylist(path: string, auth?: ContentProviderAuthData | null, resolution?: number): Promise<ContentFile[] | null>;
|
|
198
|
+
getInstructions(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
199
|
+
getExpandedInstructions(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
200
|
+
requiresAuth(): boolean;
|
|
201
|
+
getCapabilities(): ProviderCapabilities;
|
|
202
|
+
checkMediaLicense(mediaId: string, auth?: ContentProviderAuthData | null): Promise<MediaLicenseResult | null>;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* @deprecated Use auth helpers directly (OAuthHelper, DeviceFlowHelper, TokenHelper) with provider.config.
|
|
206
|
+
* This interface will be removed in a future version.
|
|
207
|
+
*/
|
|
208
|
+
interface IAuthProvider {
|
|
209
|
+
getAuthTypes(): AuthType[];
|
|
210
|
+
isAuthValid(auth: ContentProviderAuthData | null | undefined): boolean;
|
|
211
|
+
isTokenExpired(auth: ContentProviderAuthData): boolean;
|
|
212
|
+
refreshToken(auth: ContentProviderAuthData): Promise<ContentProviderAuthData | null>;
|
|
213
|
+
generateCodeVerifier(): string;
|
|
214
|
+
generateCodeChallenge(verifier: string): Promise<string>;
|
|
215
|
+
buildAuthUrl(codeVerifier: string, redirectUri: string, state?: string): Promise<{
|
|
216
|
+
url: string;
|
|
217
|
+
challengeMethod: string;
|
|
218
|
+
}>;
|
|
219
|
+
exchangeCodeForTokens(code: string, codeVerifier: string, redirectUri: string): Promise<ContentProviderAuthData | null>;
|
|
220
|
+
supportsDeviceFlow(): boolean;
|
|
221
|
+
initiateDeviceFlow(): Promise<DeviceAuthorizationResponse | null>;
|
|
222
|
+
pollDeviceFlowToken(deviceCode: string): Promise<DeviceFlowPollResult>;
|
|
223
|
+
calculatePollDelay(baseInterval?: number, slowDownCount?: number): number;
|
|
224
|
+
}
|
|
167
225
|
|
|
168
|
-
declare function detectMediaType(url: string, explicitType?: string):
|
|
226
|
+
declare function detectMediaType(url: string, explicitType?: string): "video" | "image";
|
|
227
|
+
declare function createFolder(id: string, title: string, path: string, image?: string, providerData?: Record<string, unknown>, isLeaf?: boolean): ContentFolder;
|
|
228
|
+
declare function createFile(id: string, title: string, url: string, options?: {
|
|
229
|
+
mediaType?: "video" | "image";
|
|
230
|
+
image?: string;
|
|
231
|
+
muxPlaybackId?: string;
|
|
232
|
+
providerData?: Record<string, unknown>;
|
|
233
|
+
}): ContentFile;
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Path parsing utilities for content providers.
|
|
237
|
+
* Paths follow the format: /segment1/segment2/segment3/...
|
|
238
|
+
* Example: /lessons/programId/studyId/lessonId/venueId
|
|
239
|
+
*/
|
|
240
|
+
interface ParsedPath {
|
|
241
|
+
segments: string[];
|
|
242
|
+
depth: number;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Parse a path string into segments and depth.
|
|
246
|
+
* @param path - The path to parse (e.g., "/lessons/abc123/def456")
|
|
247
|
+
* @returns Object with segments array and depth count
|
|
248
|
+
*/
|
|
249
|
+
declare function parsePath(path: string | null | undefined): ParsedPath;
|
|
250
|
+
/**
|
|
251
|
+
* Get a specific segment from a path by index.
|
|
252
|
+
* @param path - The path to parse
|
|
253
|
+
* @param index - Zero-based index of the segment to retrieve
|
|
254
|
+
* @returns The segment at the given index, or null if not found
|
|
255
|
+
*/
|
|
256
|
+
declare function getSegment(path: string | null | undefined, index: number): string | null;
|
|
257
|
+
/**
|
|
258
|
+
* Build a path string from segments.
|
|
259
|
+
* @param segments - Array of path segments
|
|
260
|
+
* @returns Path string with leading slash
|
|
261
|
+
*/
|
|
262
|
+
declare function buildPath(segments: string[]): string;
|
|
263
|
+
/**
|
|
264
|
+
* Append a segment to an existing path.
|
|
265
|
+
* @param basePath - The base path
|
|
266
|
+
* @param segment - The segment to append
|
|
267
|
+
* @returns New path with segment appended
|
|
268
|
+
*/
|
|
269
|
+
declare function appendToPath(basePath: string | null | undefined, segment: string): string;
|
|
169
270
|
|
|
170
271
|
declare function presentationsToPlaylist(plan: Plan): ContentFile[];
|
|
171
272
|
declare function presentationsToInstructions(plan: Plan): Instructions;
|
|
@@ -194,22 +295,97 @@ declare namespace FormatConverters {
|
|
|
194
295
|
export { FormatConverters_collapseInstructions as collapseInstructions, FormatConverters_expandedInstructionsToPlaylist as expandedInstructionsToPlaylist, FormatConverters_expandedInstructionsToPresentations as expandedInstructionsToPresentations, FormatConverters_instructionsToPlaylist as instructionsToPlaylist, FormatConverters_instructionsToPresentations as instructionsToPresentations, FormatConverters_playlistToExpandedInstructions as playlistToExpandedInstructions, FormatConverters_playlistToInstructions as playlistToInstructions, FormatConverters_playlistToPresentations as playlistToPresentations, FormatConverters_presentationsToExpandedInstructions as presentationsToExpandedInstructions, FormatConverters_presentationsToInstructions as presentationsToInstructions, FormatConverters_presentationsToPlaylist as presentationsToPlaylist };
|
|
195
296
|
}
|
|
196
297
|
|
|
197
|
-
|
|
298
|
+
interface FormatResolverOptions {
|
|
299
|
+
allowLossy?: boolean;
|
|
300
|
+
}
|
|
301
|
+
interface ResolvedFormatMeta {
|
|
302
|
+
isNative: boolean;
|
|
303
|
+
sourceFormat?: "playlist" | "presentations" | "instructions" | "expandedInstructions";
|
|
304
|
+
isLossy: boolean;
|
|
305
|
+
}
|
|
306
|
+
declare class FormatResolver {
|
|
307
|
+
private provider;
|
|
308
|
+
private options;
|
|
309
|
+
constructor(provider: IProvider, options?: FormatResolverOptions);
|
|
310
|
+
getProvider(): IProvider;
|
|
311
|
+
/** Extract the last segment from a path to use as fallback ID/title */
|
|
312
|
+
private getIdFromPath;
|
|
313
|
+
getPlaylist(path: string, auth?: ContentProviderAuthData | null): Promise<ContentFile[] | null>;
|
|
314
|
+
getPlaylistWithMeta(path: string, auth?: ContentProviderAuthData | null): Promise<{
|
|
315
|
+
data: ContentFile[] | null;
|
|
316
|
+
meta: ResolvedFormatMeta;
|
|
317
|
+
}>;
|
|
318
|
+
getPresentations(path: string, auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
319
|
+
getPresentationsWithMeta(path: string, auth?: ContentProviderAuthData | null): Promise<{
|
|
320
|
+
data: Plan | null;
|
|
321
|
+
meta: ResolvedFormatMeta;
|
|
322
|
+
}>;
|
|
323
|
+
getInstructions(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
324
|
+
getInstructionsWithMeta(path: string, auth?: ContentProviderAuthData | null): Promise<{
|
|
325
|
+
data: Instructions | null;
|
|
326
|
+
meta: ResolvedFormatMeta;
|
|
327
|
+
}>;
|
|
328
|
+
getExpandedInstructions(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
329
|
+
getExpandedInstructionsWithMeta(path: string, auth?: ContentProviderAuthData | null): Promise<{
|
|
330
|
+
data: Instructions | null;
|
|
331
|
+
meta: ResolvedFormatMeta;
|
|
332
|
+
}>;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
declare class OAuthHelper {
|
|
336
|
+
generateCodeVerifier(): string;
|
|
337
|
+
generateCodeChallenge(verifier: string): Promise<string>;
|
|
338
|
+
buildAuthUrl(config: ContentProviderConfig, codeVerifier: string, redirectUri: string, state?: string): Promise<{
|
|
339
|
+
url: string;
|
|
340
|
+
challengeMethod: string;
|
|
341
|
+
}>;
|
|
342
|
+
exchangeCodeForTokens(config: ContentProviderConfig, providerId: string, code: string, codeVerifier: string, redirectUri: string): Promise<ContentProviderAuthData | null>;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
declare class TokenHelper {
|
|
346
|
+
isAuthValid(auth: ContentProviderAuthData | null | undefined): boolean;
|
|
347
|
+
isTokenExpired(auth: ContentProviderAuthData): boolean;
|
|
348
|
+
refreshToken(config: ContentProviderConfig, auth: ContentProviderAuthData): Promise<ContentProviderAuthData | null>;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
declare class DeviceFlowHelper {
|
|
352
|
+
supportsDeviceFlow(config: ContentProviderConfig): boolean;
|
|
353
|
+
initiateDeviceFlow(config: ContentProviderConfig): Promise<DeviceAuthorizationResponse | null>;
|
|
354
|
+
pollDeviceFlowToken(config: ContentProviderConfig, deviceCode: string): Promise<DeviceFlowPollResult>;
|
|
355
|
+
calculatePollDelay(baseInterval?: number, slowDownCount?: number): number;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
declare class ApiHelper {
|
|
359
|
+
createAuthHeaders(auth: ContentProviderAuthData | null | undefined): Record<string, string> | null;
|
|
360
|
+
apiRequest<T>(config: ContentProviderConfig, providerId: string, path: string, auth?: ContentProviderAuthData | null, method?: "GET" | "POST", body?: unknown): Promise<T | null>;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* @deprecated Use IProvider interface instead. Providers should implement IProvider directly
|
|
365
|
+
* and use helper classes (OAuthHelper, TokenHelper, DeviceFlowHelper, ApiHelper) via composition.
|
|
366
|
+
* This class will be removed in a future version.
|
|
367
|
+
*/
|
|
368
|
+
declare abstract class ContentProvider implements IContentProvider, IAuthProvider {
|
|
198
369
|
abstract readonly id: string;
|
|
199
370
|
abstract readonly name: string;
|
|
200
371
|
abstract readonly logos: ProviderLogos;
|
|
201
372
|
abstract readonly config: ContentProviderConfig;
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
373
|
+
protected readonly oauthHelper: OAuthHelper;
|
|
374
|
+
protected readonly tokenHelper: TokenHelper;
|
|
375
|
+
protected readonly deviceFlowHelper: DeviceFlowHelper;
|
|
376
|
+
protected readonly apiHelper: ApiHelper;
|
|
377
|
+
abstract browse(path?: string | null, auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
378
|
+
abstract getPresentations(path: string, auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
379
|
+
getPlaylist(path: string, auth?: ContentProviderAuthData | null, _resolution?: number): Promise<ContentFile[] | null>;
|
|
380
|
+
getInstructions(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
381
|
+
getExpandedInstructions(path: string, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
207
382
|
requiresAuth(): boolean;
|
|
208
383
|
getCapabilities(): ProviderCapabilities;
|
|
209
384
|
checkMediaLicense(_mediaId: string, _auth?: ContentProviderAuthData | null): Promise<MediaLicenseResult | null>;
|
|
210
385
|
getAuthTypes(): AuthType[];
|
|
211
386
|
isAuthValid(auth: ContentProviderAuthData | null | undefined): boolean;
|
|
212
387
|
isTokenExpired(auth: ContentProviderAuthData): boolean;
|
|
388
|
+
refreshToken(auth: ContentProviderAuthData): Promise<ContentProviderAuthData | null>;
|
|
213
389
|
generateCodeVerifier(): string;
|
|
214
390
|
generateCodeChallenge(verifier: string): Promise<string>;
|
|
215
391
|
buildAuthUrl(codeVerifier: string, redirectUri: string, state?: string): Promise<{
|
|
@@ -217,174 +393,242 @@ declare abstract class ContentProvider {
|
|
|
217
393
|
challengeMethod: string;
|
|
218
394
|
}>;
|
|
219
395
|
exchangeCodeForTokens(code: string, codeVerifier: string, redirectUri: string): Promise<ContentProviderAuthData | null>;
|
|
220
|
-
refreshToken(auth: ContentProviderAuthData): Promise<ContentProviderAuthData | null>;
|
|
221
396
|
supportsDeviceFlow(): boolean;
|
|
222
397
|
initiateDeviceFlow(): Promise<DeviceAuthorizationResponse | null>;
|
|
223
398
|
pollDeviceFlowToken(deviceCode: string): Promise<DeviceFlowPollResult>;
|
|
224
399
|
calculatePollDelay(baseInterval?: number, slowDownCount?: number): number;
|
|
225
400
|
protected createAuthHeaders(auth: ContentProviderAuthData | null | undefined): Record<string, string> | null;
|
|
226
|
-
protected apiRequest<T>(path: string, auth?: ContentProviderAuthData | null, method?:
|
|
227
|
-
protected createFolder(id: string, title: string, image?: string, providerData?: Record<string, unknown
|
|
401
|
+
protected apiRequest<T>(path: string, auth?: ContentProviderAuthData | null, method?: "GET" | "POST", body?: unknown): Promise<T | null>;
|
|
402
|
+
protected createFolder(id: string, title: string, path: string, image?: string, providerData?: Record<string, unknown>, isLeaf?: boolean): ContentFolder;
|
|
228
403
|
protected createFile(id: string, title: string, url: string, options?: {
|
|
229
|
-
mediaType?:
|
|
404
|
+
mediaType?: "video" | "image";
|
|
230
405
|
image?: string;
|
|
231
406
|
muxPlaybackId?: string;
|
|
232
407
|
providerData?: Record<string, unknown>;
|
|
233
408
|
}): ContentFile;
|
|
234
409
|
}
|
|
235
410
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
getPlaylist(folder: ContentFolder, auth?: ContentProviderAuthData | null): Promise<ContentFile[] | null>;
|
|
250
|
-
getPlaylistWithMeta(folder: ContentFolder, auth?: ContentProviderAuthData | null): Promise<{
|
|
251
|
-
data: ContentFile[] | null;
|
|
252
|
-
meta: ResolvedFormatMeta;
|
|
253
|
-
}>;
|
|
254
|
-
getPresentations(folder: ContentFolder, auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
255
|
-
getPresentationsWithMeta(folder: ContentFolder, auth?: ContentProviderAuthData | null): Promise<{
|
|
256
|
-
data: Plan | null;
|
|
257
|
-
meta: ResolvedFormatMeta;
|
|
258
|
-
}>;
|
|
259
|
-
getInstructions(folder: ContentFolder, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
260
|
-
getInstructionsWithMeta(folder: ContentFolder, auth?: ContentProviderAuthData | null): Promise<{
|
|
261
|
-
data: Instructions | null;
|
|
262
|
-
meta: ResolvedFormatMeta;
|
|
263
|
-
}>;
|
|
264
|
-
getExpandedInstructions(folder: ContentFolder, auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
265
|
-
getExpandedInstructionsWithMeta(folder: ContentFolder, auth?: ContentProviderAuthData | null): Promise<{
|
|
266
|
-
data: Instructions | null;
|
|
267
|
-
meta: ResolvedFormatMeta;
|
|
268
|
-
}>;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
declare class APlayProvider extends ContentProvider {
|
|
411
|
+
/**
|
|
412
|
+
* APlay Provider
|
|
413
|
+
*
|
|
414
|
+
* Path structure (variable depth based on module products):
|
|
415
|
+
* /modules -> list modules
|
|
416
|
+
* /modules/{moduleId} -> list products OR libraries (depends on module)
|
|
417
|
+
* /modules/{moduleId}/products/{productId} -> list libraries (if module has multiple products)
|
|
418
|
+
* /modules/{moduleId}/products/{productId}/{libraryId} -> media files
|
|
419
|
+
* /modules/{moduleId}/libraries/{libraryId} -> media files (if module has 0-1 products)
|
|
420
|
+
*/
|
|
421
|
+
declare class APlayProvider implements IProvider {
|
|
422
|
+
private readonly apiHelper;
|
|
423
|
+
private apiRequest;
|
|
272
424
|
readonly id = "aplay";
|
|
273
425
|
readonly name = "APlay";
|
|
274
426
|
readonly logos: ProviderLogos;
|
|
275
427
|
readonly config: ContentProviderConfig;
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
428
|
+
readonly requiresAuth = true;
|
|
429
|
+
readonly authTypes: AuthType[];
|
|
430
|
+
readonly capabilities: ProviderCapabilities;
|
|
431
|
+
browse(path?: string | null, auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
432
|
+
private getModules;
|
|
433
|
+
private getModuleContent;
|
|
279
434
|
private getLibraryFolders;
|
|
280
435
|
private getMediaFiles;
|
|
281
|
-
getPresentations(
|
|
436
|
+
getPresentations(path: string, auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
282
437
|
checkMediaLicense(mediaId: string, auth?: ContentProviderAuthData | null): Promise<MediaLicenseResult | null>;
|
|
283
438
|
}
|
|
284
439
|
|
|
285
|
-
|
|
440
|
+
/**
|
|
441
|
+
* SignPresenter Provider
|
|
442
|
+
*
|
|
443
|
+
* Path structure:
|
|
444
|
+
* /playlists -> list playlists
|
|
445
|
+
* /playlists/{playlistId} -> list messages (files)
|
|
446
|
+
*/
|
|
447
|
+
declare class SignPresenterProvider implements IProvider {
|
|
448
|
+
private readonly apiHelper;
|
|
449
|
+
private apiRequest;
|
|
286
450
|
readonly id = "signpresenter";
|
|
287
451
|
readonly name = "SignPresenter";
|
|
288
452
|
readonly logos: ProviderLogos;
|
|
289
453
|
readonly config: ContentProviderConfig;
|
|
290
|
-
|
|
291
|
-
|
|
454
|
+
readonly requiresAuth = true;
|
|
455
|
+
readonly authTypes: AuthType[];
|
|
456
|
+
readonly capabilities: ProviderCapabilities;
|
|
457
|
+
browse(path?: string | null, auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
458
|
+
private getPlaylists;
|
|
292
459
|
private getMessages;
|
|
293
|
-
getPresentations(
|
|
460
|
+
getPresentations(path: string, auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
294
461
|
}
|
|
295
462
|
|
|
296
|
-
|
|
463
|
+
/**
|
|
464
|
+
* LessonsChurch Provider
|
|
465
|
+
*
|
|
466
|
+
* Path structure:
|
|
467
|
+
* /lessons -> programs
|
|
468
|
+
* /lessons/{programId} -> studies
|
|
469
|
+
* /lessons/{programId}/{studyId} -> lessons
|
|
470
|
+
* /lessons/{programId}/{studyId}/{lessonId} -> venues
|
|
471
|
+
* /lessons/{programId}/{studyId}/{lessonId}/{venueId} -> playlist files
|
|
472
|
+
*
|
|
473
|
+
* /addons -> categories
|
|
474
|
+
* /addons/{category} -> add-on files
|
|
475
|
+
*/
|
|
476
|
+
declare class LessonsChurchProvider implements IProvider {
|
|
297
477
|
readonly id = "lessonschurch";
|
|
298
478
|
readonly name = "Lessons.church";
|
|
299
479
|
readonly logos: ProviderLogos;
|
|
300
480
|
readonly config: ContentProviderConfig;
|
|
301
|
-
requiresAuth
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
481
|
+
readonly requiresAuth = false;
|
|
482
|
+
readonly authTypes: AuthType[];
|
|
483
|
+
readonly capabilities: ProviderCapabilities;
|
|
484
|
+
getPlaylist(path: string, _auth?: ContentProviderAuthData | null, resolution?: number): Promise<ContentFile[] | null>;
|
|
485
|
+
private apiRequest;
|
|
486
|
+
browse(path?: string | null, _auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
487
|
+
private browseLessons;
|
|
306
488
|
private getPrograms;
|
|
307
489
|
private getStudies;
|
|
308
490
|
private getLessons;
|
|
309
491
|
private getVenues;
|
|
310
492
|
private getPlaylistFiles;
|
|
493
|
+
private browseAddOns;
|
|
311
494
|
private getAddOnCategories;
|
|
312
495
|
private getAddOnsByCategory;
|
|
313
496
|
private convertAddOnToFile;
|
|
314
|
-
getPresentations(
|
|
315
|
-
getInstructions(
|
|
316
|
-
getExpandedInstructions(
|
|
497
|
+
getPresentations(path: string, _auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
498
|
+
getInstructions(path: string, _auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
499
|
+
getExpandedInstructions(path: string, _auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
500
|
+
private normalizeItemType;
|
|
317
501
|
private getEmbedUrl;
|
|
318
502
|
private convertVenueToPlan;
|
|
319
503
|
}
|
|
320
504
|
|
|
321
|
-
declare class B1ChurchProvider
|
|
505
|
+
declare class B1ChurchProvider implements IProvider {
|
|
506
|
+
private readonly apiHelper;
|
|
507
|
+
private apiRequest;
|
|
322
508
|
readonly id = "b1church";
|
|
323
509
|
readonly name = "B1.Church";
|
|
324
510
|
readonly logos: ProviderLogos;
|
|
325
511
|
readonly config: ContentProviderConfig;
|
|
326
512
|
private appBase;
|
|
327
|
-
requiresAuth
|
|
328
|
-
|
|
329
|
-
|
|
513
|
+
readonly requiresAuth = true;
|
|
514
|
+
readonly authTypes: AuthType[];
|
|
515
|
+
readonly capabilities: ProviderCapabilities;
|
|
516
|
+
buildAuthUrl(codeVerifier: string, redirectUri: string, state?: string): Promise<{
|
|
330
517
|
url: string;
|
|
331
518
|
challengeMethod: string;
|
|
332
519
|
}>;
|
|
520
|
+
exchangeCodeForTokensWithPKCE(code: string, redirectUri: string, codeVerifier: string): Promise<ContentProviderAuthData | null>;
|
|
333
521
|
exchangeCodeForTokensWithSecret(code: string, redirectUri: string, clientSecret: string): Promise<ContentProviderAuthData | null>;
|
|
334
522
|
refreshTokenWithSecret(authData: ContentProviderAuthData, clientSecret: string): Promise<ContentProviderAuthData | null>;
|
|
335
523
|
initiateDeviceFlow(): Promise<DeviceAuthorizationResponse | null>;
|
|
336
524
|
pollDeviceFlowToken(deviceCode: string): Promise<DeviceFlowPollResult>;
|
|
337
|
-
browse(
|
|
338
|
-
getPresentations(
|
|
339
|
-
getInstructions(
|
|
340
|
-
|
|
525
|
+
browse(path?: string | null, authData?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
526
|
+
getPresentations(path: string, authData?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
527
|
+
getInstructions(path: string, authData?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
528
|
+
getExpandedInstructions(path: string, authData?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
529
|
+
private processInstructionItems;
|
|
530
|
+
getPlaylist(path: string, authData?: ContentProviderAuthData | null, resolution?: number): Promise<ContentFile[] | null>;
|
|
341
531
|
}
|
|
342
532
|
|
|
343
|
-
|
|
533
|
+
/**
|
|
534
|
+
* PlanningCenter Provider
|
|
535
|
+
*
|
|
536
|
+
* Path structure:
|
|
537
|
+
* /serviceTypes -> list service types
|
|
538
|
+
* /serviceTypes/{serviceTypeId} -> list plans
|
|
539
|
+
* /serviceTypes/{serviceTypeId}/{planId} -> plan items (leaf)
|
|
540
|
+
*/
|
|
541
|
+
declare class PlanningCenterProvider implements IProvider {
|
|
542
|
+
private readonly apiHelper;
|
|
543
|
+
private apiRequest;
|
|
344
544
|
readonly id = "planningcenter";
|
|
345
545
|
readonly name = "Planning Center";
|
|
346
546
|
readonly logos: ProviderLogos;
|
|
347
547
|
readonly config: ContentProviderConfig;
|
|
348
548
|
private readonly ONE_WEEK_MS;
|
|
349
|
-
requiresAuth
|
|
350
|
-
|
|
351
|
-
|
|
549
|
+
readonly requiresAuth = true;
|
|
550
|
+
readonly authTypes: AuthType[];
|
|
551
|
+
readonly capabilities: ProviderCapabilities;
|
|
552
|
+
browse(path?: string | null, auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
553
|
+
private getServiceTypes;
|
|
352
554
|
private getPlans;
|
|
353
555
|
private getPlanItems;
|
|
354
|
-
getPresentations(
|
|
556
|
+
getPresentations(path: string, auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
355
557
|
private convertToPresentation;
|
|
356
558
|
private convertSongToPresentation;
|
|
357
559
|
private convertMediaToPresentation;
|
|
358
560
|
private formatDate;
|
|
359
561
|
}
|
|
360
562
|
|
|
361
|
-
|
|
563
|
+
/**
|
|
564
|
+
* BibleProject Provider
|
|
565
|
+
*
|
|
566
|
+
* Path structure:
|
|
567
|
+
* / -> list collections
|
|
568
|
+
* /{collectionSlug} -> list videos in collection
|
|
569
|
+
* /{collectionSlug}/{videoId} -> single video
|
|
570
|
+
*/
|
|
571
|
+
declare class BibleProjectProvider implements IProvider {
|
|
362
572
|
readonly id = "bibleproject";
|
|
363
573
|
readonly name = "The Bible Project";
|
|
364
574
|
readonly logos: ProviderLogos;
|
|
365
575
|
readonly config: ContentProviderConfig;
|
|
366
576
|
private data;
|
|
367
|
-
requiresAuth
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
577
|
+
readonly requiresAuth = false;
|
|
578
|
+
readonly authTypes: AuthType[];
|
|
579
|
+
readonly capabilities: ProviderCapabilities;
|
|
580
|
+
browse(path?: string | null, _auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
581
|
+
private getCollections;
|
|
582
|
+
private getLessonFolders;
|
|
583
|
+
private getVideoFile;
|
|
584
|
+
getPresentations(path: string, _auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
585
|
+
getPlaylist(path: string, _auth?: ContentProviderAuthData | null, _resolution?: number): Promise<ContentFile[] | null>;
|
|
586
|
+
private slugify;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
/**
|
|
590
|
+
* HighVoltageKids Provider
|
|
591
|
+
*
|
|
592
|
+
* Path structure:
|
|
593
|
+
* / -> list collections (Elementary, Preschool)
|
|
594
|
+
* /{collectionSlug} -> list studies
|
|
595
|
+
* /{collectionSlug}/{studyId} -> list lessons
|
|
596
|
+
* /{collectionSlug}/{studyId}/{lessonId} -> lesson files (leaf)
|
|
597
|
+
*/
|
|
598
|
+
declare class HighVoltageKidsProvider implements IProvider {
|
|
599
|
+
readonly id = "highvoltagekids";
|
|
600
|
+
readonly name = "High Voltage Kids";
|
|
601
|
+
readonly logos: ProviderLogos;
|
|
602
|
+
readonly config: ContentProviderConfig;
|
|
603
|
+
private data;
|
|
604
|
+
readonly requiresAuth = false;
|
|
605
|
+
readonly authTypes: AuthType[];
|
|
606
|
+
readonly capabilities: ProviderCapabilities;
|
|
607
|
+
browse(path?: string | null, _auth?: ContentProviderAuthData | null): Promise<ContentItem[]>;
|
|
608
|
+
private getCollections;
|
|
609
|
+
private getStudyFolders;
|
|
372
610
|
private getLessonFolders;
|
|
611
|
+
private getLessonFiles;
|
|
612
|
+
getPresentations(path: string, _auth?: ContentProviderAuthData | null): Promise<Plan | null>;
|
|
613
|
+
getPlaylist(path: string, _auth?: ContentProviderAuthData | null, _resolution?: number): Promise<ContentFile[] | null>;
|
|
614
|
+
getExpandedInstructions(path: string, _auth?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
373
615
|
private slugify;
|
|
616
|
+
private groupFilesIntoActions;
|
|
617
|
+
private getBaseName;
|
|
374
618
|
}
|
|
375
619
|
|
|
376
620
|
/**
|
|
377
621
|
* Get a provider by ID.
|
|
378
622
|
*/
|
|
379
|
-
declare function getProvider(providerId: string):
|
|
623
|
+
declare function getProvider(providerId: string): IProvider | null;
|
|
380
624
|
/**
|
|
381
625
|
* Get all registered providers.
|
|
382
626
|
*/
|
|
383
|
-
declare function getAllProviders():
|
|
627
|
+
declare function getAllProviders(): IProvider[];
|
|
384
628
|
/**
|
|
385
629
|
* Register a custom provider.
|
|
386
630
|
*/
|
|
387
|
-
declare function registerProvider(provider:
|
|
631
|
+
declare function registerProvider(provider: IProvider): void;
|
|
388
632
|
/**
|
|
389
633
|
* Get provider configuration by ID (for backward compatibility).
|
|
390
634
|
*/
|
|
@@ -392,8 +636,9 @@ declare function getProviderConfig(providerId: string): ContentProviderConfig |
|
|
|
392
636
|
/**
|
|
393
637
|
* Get list of available providers with their info including logos and auth types.
|
|
394
638
|
* Includes both implemented providers and coming soon providers.
|
|
639
|
+
* @param ids - Optional array of provider IDs to filter the results. If provided, only providers with matching IDs will be returned.
|
|
395
640
|
*/
|
|
396
|
-
declare function getAvailableProviders(): ProviderInfo[];
|
|
641
|
+
declare function getAvailableProviders(ids?: string[]): ProviderInfo[];
|
|
397
642
|
|
|
398
643
|
/**
|
|
399
644
|
* @churchapps/content-provider-helper
|
|
@@ -401,4 +646,4 @@ declare function getAvailableProviders(): ProviderInfo[];
|
|
|
401
646
|
*/
|
|
402
647
|
declare const VERSION = "0.0.1";
|
|
403
648
|
|
|
404
|
-
export { APlayProvider, type AuthType, B1ChurchProvider, BibleProjectProvider, type ContentFile, type ContentFolder, type ContentItem, ContentProvider, type ContentProviderAuthData, type ContentProviderConfig, type DeviceAuthorizationResponse, type DeviceFlowPollResult, type DeviceFlowState, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, FormatConverters, FormatResolver, type FormatResolverOptions, type InstructionItem, type Instructions, LessonsChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, type Plan, type PlanPresentation, type PlanSection, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, type ResolvedFormatMeta, SignPresenterProvider, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, collapseInstructions, detectMediaType, expandedInstructionsToPlaylist, expandedInstructionsToPresentations, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, instructionsToPlaylist, instructionsToPresentations, isContentFile, isContentFolder, playlistToExpandedInstructions, playlistToInstructions, playlistToPresentations, presentationsToExpandedInstructions, presentationsToInstructions, presentationsToPlaylist, registerProvider };
|
|
649
|
+
export { APlayProvider, ApiHelper, type AuthType, B1ChurchProvider, BibleProjectProvider, type ContentFile, type ContentFolder, type ContentItem, ContentProvider, type ContentProviderAuthData, type ContentProviderConfig, type DeviceAuthorizationResponse, DeviceFlowHelper, type DeviceFlowPollResult, type DeviceFlowState, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, FormatConverters, FormatResolver, type FormatResolverOptions, HighVoltageKidsProvider, type IAuthProvider, type IContentProvider, type IProvider, type InstructionItem, type Instructions, LessonsChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, OAuthHelper, type Plan, type PlanPresentation, type PlanSection, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, type ResolvedFormatMeta, SignPresenterProvider, TokenHelper, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, appendToPath, buildPath, collapseInstructions, createFile, createFolder, detectMediaType, expandedInstructionsToPlaylist, expandedInstructionsToPresentations, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, getSegment, instructionsToPlaylist, instructionsToPresentations, isContentFile, isContentFolder, parsePath, playlistToExpandedInstructions, playlistToInstructions, playlistToPresentations, presentationsToExpandedInstructions, presentationsToInstructions, presentationsToPlaylist, registerProvider };
|