@churchapps/content-providers 0.6.0 → 0.7.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.cjs +123 -26
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +122 -26
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -16,6 +16,8 @@ interface ContentProviderConfig {
|
|
|
16
16
|
apiBase: string;
|
|
17
17
|
oauthBase: string;
|
|
18
18
|
clientId: string;
|
|
19
|
+
/** For confidential OAuth clients (e.g. WP OAuth Server); sent on token exchange and refresh. */
|
|
20
|
+
clientSecret?: string;
|
|
19
21
|
scopes: string[];
|
|
20
22
|
supportsDeviceFlow?: boolean;
|
|
21
23
|
deviceAuthEndpoint?: string;
|
|
@@ -269,6 +271,8 @@ declare class DeviceFlowHelper {
|
|
|
269
271
|
calculatePollDelay(baseInterval?: number, slowDownCount?: number): number;
|
|
270
272
|
}
|
|
271
273
|
|
|
274
|
+
declare const setProviderSecret: (providerId: string, secret: string) => void;
|
|
275
|
+
|
|
272
276
|
/** Base for providers; auth-flow methods are intentionally not here so consumers can feature-detect with `"method" in provider`. */
|
|
273
277
|
declare abstract class BaseProvider implements IProvider {
|
|
274
278
|
abstract readonly id: string;
|
|
@@ -393,7 +397,7 @@ declare class B1ChurchProvider extends BaseProvider {
|
|
|
393
397
|
private fetchPlanImages;
|
|
394
398
|
private planTypeId;
|
|
395
399
|
setPairingData(data: unknown): void;
|
|
396
|
-
getCurrentPlan(
|
|
400
|
+
getCurrentPlan(authData?: ContentProviderAuthData | null): Promise<CurrentPlan | null>;
|
|
397
401
|
getInstructions(path: string, authData?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
398
402
|
private processInstructionItems;
|
|
399
403
|
private findItemByPath;
|
|
@@ -573,4 +577,4 @@ declare function getAvailableProviders(ids?: string[]): ProviderInfo[];
|
|
|
573
577
|
*/
|
|
574
578
|
declare const VERSION: string;
|
|
575
579
|
|
|
576
|
-
export { APlayProvider, type AuthType, B1ChurchProvider, BaseProvider, BibleProjectProvider, CbnProvider, type ContentFile, type ContentFolder, type ContentItem, type ContentProviderAuthData, type ContentProviderConfig, type CurrentPlan, type DeviceAuthorizationResponse, DeviceFlowHelper, type DeviceFlowPollResult, type DeviceFlowState, DropboxProvider, type EndpointValue, type EndpointsConfig, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, HighVoltageKidsProvider, type IProvider, type InstructionItem, type Instructions, JesusFilmProvider, LessonsChurchProvider, LifeChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, type MessageFileInterface, OAuthHelper, type Plan, type PlanPresentation, type PlanSection, type PlanTimelineItem, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, SignPresenterProvider, TokenHelper, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, isContentFile, isContentFolder, navigateToPath, registerProvider, toAuthData };
|
|
580
|
+
export { APlayProvider, type AuthType, B1ChurchProvider, BaseProvider, BibleProjectProvider, CbnProvider, type ContentFile, type ContentFolder, type ContentItem, type ContentProviderAuthData, type ContentProviderConfig, type CurrentPlan, type DeviceAuthorizationResponse, DeviceFlowHelper, type DeviceFlowPollResult, type DeviceFlowState, DropboxProvider, type EndpointValue, type EndpointsConfig, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, HighVoltageKidsProvider, type IProvider, type InstructionItem, type Instructions, JesusFilmProvider, LessonsChurchProvider, LifeChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, type MessageFileInterface, OAuthHelper, type Plan, type PlanPresentation, type PlanSection, type PlanTimelineItem, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, SignPresenterProvider, TokenHelper, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, isContentFile, isContentFolder, navigateToPath, registerProvider, setProviderSecret, toAuthData };
|
package/dist/index.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ interface ContentProviderConfig {
|
|
|
16
16
|
apiBase: string;
|
|
17
17
|
oauthBase: string;
|
|
18
18
|
clientId: string;
|
|
19
|
+
/** For confidential OAuth clients (e.g. WP OAuth Server); sent on token exchange and refresh. */
|
|
20
|
+
clientSecret?: string;
|
|
19
21
|
scopes: string[];
|
|
20
22
|
supportsDeviceFlow?: boolean;
|
|
21
23
|
deviceAuthEndpoint?: string;
|
|
@@ -269,6 +271,8 @@ declare class DeviceFlowHelper {
|
|
|
269
271
|
calculatePollDelay(baseInterval?: number, slowDownCount?: number): number;
|
|
270
272
|
}
|
|
271
273
|
|
|
274
|
+
declare const setProviderSecret: (providerId: string, secret: string) => void;
|
|
275
|
+
|
|
272
276
|
/** Base for providers; auth-flow methods are intentionally not here so consumers can feature-detect with `"method" in provider`. */
|
|
273
277
|
declare abstract class BaseProvider implements IProvider {
|
|
274
278
|
abstract readonly id: string;
|
|
@@ -393,7 +397,7 @@ declare class B1ChurchProvider extends BaseProvider {
|
|
|
393
397
|
private fetchPlanImages;
|
|
394
398
|
private planTypeId;
|
|
395
399
|
setPairingData(data: unknown): void;
|
|
396
|
-
getCurrentPlan(
|
|
400
|
+
getCurrentPlan(authData?: ContentProviderAuthData | null): Promise<CurrentPlan | null>;
|
|
397
401
|
getInstructions(path: string, authData?: ContentProviderAuthData | null): Promise<Instructions | null>;
|
|
398
402
|
private processInstructionItems;
|
|
399
403
|
private findItemByPath;
|
|
@@ -573,4 +577,4 @@ declare function getAvailableProviders(ids?: string[]): ProviderInfo[];
|
|
|
573
577
|
*/
|
|
574
578
|
declare const VERSION: string;
|
|
575
579
|
|
|
576
|
-
export { APlayProvider, type AuthType, B1ChurchProvider, BaseProvider, BibleProjectProvider, CbnProvider, type ContentFile, type ContentFolder, type ContentItem, type ContentProviderAuthData, type ContentProviderConfig, type CurrentPlan, type DeviceAuthorizationResponse, DeviceFlowHelper, type DeviceFlowPollResult, type DeviceFlowState, DropboxProvider, type EndpointValue, type EndpointsConfig, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, HighVoltageKidsProvider, type IProvider, type InstructionItem, type Instructions, JesusFilmProvider, LessonsChurchProvider, LifeChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, type MessageFileInterface, OAuthHelper, type Plan, type PlanPresentation, type PlanSection, type PlanTimelineItem, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, SignPresenterProvider, TokenHelper, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, isContentFile, isContentFolder, navigateToPath, registerProvider, toAuthData };
|
|
580
|
+
export { APlayProvider, type AuthType, B1ChurchProvider, BaseProvider, BibleProjectProvider, CbnProvider, type ContentFile, type ContentFolder, type ContentItem, type ContentProviderAuthData, type ContentProviderConfig, type CurrentPlan, type DeviceAuthorizationResponse, DeviceFlowHelper, type DeviceFlowPollResult, type DeviceFlowState, DropboxProvider, type EndpointValue, type EndpointsConfig, type FeedActionInterface, type FeedFileInterface, type FeedSectionInterface, type FeedVenueInterface, HighVoltageKidsProvider, type IProvider, type InstructionItem, type Instructions, JesusFilmProvider, LessonsChurchProvider, LifeChurchProvider, type MediaLicenseResult, type MediaLicenseStatus, type MessageFileInterface, OAuthHelper, type Plan, type PlanPresentation, type PlanSection, type PlanTimelineItem, PlanningCenterProvider, type ProviderCapabilities, type ProviderInfo, type ProviderLogos, SignPresenterProvider, TokenHelper, VERSION, type VenueActionInterface, type VenueActionsResponseInterface, type VenueSectionActionsInterface, getAllProviders, getAvailableProviders, getProvider, getProviderConfig, isContentFile, isContentFolder, navigateToPath, registerProvider, setProviderSecret, toAuthData };
|
package/dist/index.js
CHANGED
|
@@ -47,6 +47,7 @@ var TokenHelper = class {
|
|
|
47
47
|
refresh_token: auth.refresh_token,
|
|
48
48
|
client_id: config.clientId
|
|
49
49
|
});
|
|
50
|
+
if (config.clientSecret) params.set("client_secret", config.clientSecret);
|
|
50
51
|
const response = await fetch(`${config.oauthBase}/token`, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: params.toString() });
|
|
51
52
|
if (!response.ok) {
|
|
52
53
|
console.warn(`[TokenHelper] Token refresh failed: ${response.status} ${response.statusText}`);
|
|
@@ -116,6 +117,7 @@ var OAuthHelper = class {
|
|
|
116
117
|
client_id: config.clientId,
|
|
117
118
|
code_verifier: codeVerifier
|
|
118
119
|
});
|
|
120
|
+
if (config.clientSecret) params.set("client_secret", config.clientSecret);
|
|
119
121
|
const tokenUrl = `${config.oauthBase}/token`;
|
|
120
122
|
const response = await fetch(tokenUrl, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: params.toString() });
|
|
121
123
|
if (!response.ok) {
|
|
@@ -199,6 +201,13 @@ var ApiHelper = class {
|
|
|
199
201
|
}
|
|
200
202
|
};
|
|
201
203
|
|
|
204
|
+
// src/helpers/ProviderSecrets.ts
|
|
205
|
+
var secrets = {};
|
|
206
|
+
var setProviderSecret = (providerId, secret) => {
|
|
207
|
+
secrets[providerId] = secret;
|
|
208
|
+
};
|
|
209
|
+
var getProviderSecret = (providerId) => secrets[providerId] || "";
|
|
210
|
+
|
|
202
211
|
// src/providers/BaseProvider.ts
|
|
203
212
|
var BaseProvider = class {
|
|
204
213
|
constructor() {
|
|
@@ -933,18 +942,6 @@ var LessonsChurchProvider = class extends BaseProvider {
|
|
|
933
942
|
}
|
|
934
943
|
};
|
|
935
944
|
|
|
936
|
-
// src/providers/registry.ts
|
|
937
|
-
var providerRegistry = /* @__PURE__ */ new Map();
|
|
938
|
-
function getProvider(providerId) {
|
|
939
|
-
return providerRegistry.get(providerId) || null;
|
|
940
|
-
}
|
|
941
|
-
function getAllProviders() {
|
|
942
|
-
return Array.from(providerRegistry.values());
|
|
943
|
-
}
|
|
944
|
-
function registerProvider(provider) {
|
|
945
|
-
providerRegistry.set(provider.id, provider);
|
|
946
|
-
}
|
|
947
|
-
|
|
948
945
|
// src/providers/b1Church/B1ChurchAuth.ts
|
|
949
946
|
function buildB1AuthUrlFromChallenge(config, appBase, redirectUri, codeChallenge, state) {
|
|
950
947
|
const oauthParams = new URLSearchParams({
|
|
@@ -1403,14 +1400,12 @@ var B1ChurchProvider = class extends BaseProvider {
|
|
|
1403
1400
|
this.planTypeId = null;
|
|
1404
1401
|
}
|
|
1405
1402
|
}
|
|
1406
|
-
async getCurrentPlan(
|
|
1403
|
+
async getCurrentPlan(authData) {
|
|
1407
1404
|
if (!this.planTypeId) return null;
|
|
1408
1405
|
const plan = await fetchCurrentPlanByType(this.planTypeId);
|
|
1409
|
-
if (!plan?.providerId || !plan.providerPlanId) return null;
|
|
1406
|
+
if (!plan?.providerId || !plan.providerPlanId || !plan.ministryId) return null;
|
|
1410
1407
|
const items = plan.churchId && plan.id ? await fetchPlanItems(plan.churchId, plan.id) : [];
|
|
1411
|
-
const
|
|
1412
|
-
if (!innerProvider?.getInstructions) return null;
|
|
1413
|
-
const instructions = await innerProvider.getInstructions(plan.providerPlanId, null);
|
|
1408
|
+
const instructions = await fetchFromProviderProxy("getInstructions", plan.ministryId, plan.providerId, plan.providerPlanId, authData);
|
|
1414
1409
|
if (!instructions) return null;
|
|
1415
1410
|
const files = getOrderedFiles(instructions, items);
|
|
1416
1411
|
const thumbnail = findFirstThumbnail(instructions.items);
|
|
@@ -16253,6 +16248,113 @@ var LifeChurchProvider = class extends BaseProvider {
|
|
|
16253
16248
|
}
|
|
16254
16249
|
};
|
|
16255
16250
|
|
|
16251
|
+
// src/providers/registry.ts
|
|
16252
|
+
var providerRegistry = /* @__PURE__ */ new Map();
|
|
16253
|
+
function getProvider(providerId) {
|
|
16254
|
+
return providerRegistry.get(providerId) || null;
|
|
16255
|
+
}
|
|
16256
|
+
function getAllProviders() {
|
|
16257
|
+
return Array.from(providerRegistry.values());
|
|
16258
|
+
}
|
|
16259
|
+
function registerProvider(provider) {
|
|
16260
|
+
providerRegistry.set(provider.id, provider);
|
|
16261
|
+
}
|
|
16262
|
+
|
|
16263
|
+
// src/providers/goCurriculum/data.json
|
|
16264
|
+
var data_default4 = {
|
|
16265
|
+
catalog: []
|
|
16266
|
+
};
|
|
16267
|
+
|
|
16268
|
+
// src/providers/goCurriculum/GoCurriculumProvider.ts
|
|
16269
|
+
var GoCurriculumProvider = class extends BaseProvider {
|
|
16270
|
+
constructor() {
|
|
16271
|
+
super(...arguments);
|
|
16272
|
+
this.oauthHelper = new OAuthHelper();
|
|
16273
|
+
this.verifiedTokens = /* @__PURE__ */ new Set();
|
|
16274
|
+
this.id = "gocurriculum";
|
|
16275
|
+
this.name = "Go Curriculum";
|
|
16276
|
+
this.logos = {
|
|
16277
|
+
light: "https://gocurriculum.com/wp-content/uploads/go-logo-curriculum-v2.png",
|
|
16278
|
+
dark: "https://gocurriculum.com/wp-content/uploads/go-logo-curriculum-v2.png"
|
|
16279
|
+
};
|
|
16280
|
+
this.config = {
|
|
16281
|
+
id: "gocurriculum",
|
|
16282
|
+
name: "Go Curriculum",
|
|
16283
|
+
apiBase: "https://gocurriculum.com",
|
|
16284
|
+
oauthBase: "https://gocurriculum.com/oauth",
|
|
16285
|
+
clientId: "Rdrvz9jz9nTNf8rCsbpuAgVLdoWHZmcjdmmrP0Bw",
|
|
16286
|
+
// supplied at runtime via setProviderSecret("gocurriculum", ...) — never commit the value
|
|
16287
|
+
get clientSecret() {
|
|
16288
|
+
return getProviderSecret("gocurriculum");
|
|
16289
|
+
},
|
|
16290
|
+
scopes: ["basic"]
|
|
16291
|
+
};
|
|
16292
|
+
this.data = data_default4;
|
|
16293
|
+
this.requiresAuth = true;
|
|
16294
|
+
this.authTypes = ["oauth_pkce"];
|
|
16295
|
+
this.capabilities = { browse: true, playlist: true, instructions: true, mediaLicensing: false };
|
|
16296
|
+
}
|
|
16297
|
+
// ponytail: any valid login unlocks everything for the pilot — per-tier (MemberPress) filtering waits on Go's membership endpoint
|
|
16298
|
+
async verifyAuth(auth) {
|
|
16299
|
+
const token = auth?.access_token;
|
|
16300
|
+
if (!token) return false;
|
|
16301
|
+
if (this.verifiedTokens.has(token)) return true;
|
|
16302
|
+
try {
|
|
16303
|
+
const response = await fetch(`${this.config.oauthBase}/me`, { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ access_token: token }).toString() });
|
|
16304
|
+
if (!response.ok) return false;
|
|
16305
|
+
this.verifiedTokens.add(token);
|
|
16306
|
+
return true;
|
|
16307
|
+
} catch {
|
|
16308
|
+
return false;
|
|
16309
|
+
}
|
|
16310
|
+
}
|
|
16311
|
+
async browse(path, auth) {
|
|
16312
|
+
if (!await this.verifyAuth(auth)) return [];
|
|
16313
|
+
const { segments, depth } = parsePath(path);
|
|
16314
|
+
if (depth === 0) return this.data.catalog.map((c) => createFolder(c.id, c.name, `/${c.id}`, c.thumbnail));
|
|
16315
|
+
const collection = this.data.catalog.find((c) => c.id === segments[0]);
|
|
16316
|
+
if (!collection) return [];
|
|
16317
|
+
if (depth === 1) return collection.lessons.map((l) => createFolder(l.id, l.name, `/${collection.id}/${l.id}`, l.thumbnail || collection.thumbnail, true));
|
|
16318
|
+
if (depth === 2) return this.getLessonFiles(collection, segments[1]);
|
|
16319
|
+
return [];
|
|
16320
|
+
}
|
|
16321
|
+
getLessonFiles(collection, lessonId) {
|
|
16322
|
+
const lesson = collection.lessons.find((l) => l.id === lessonId);
|
|
16323
|
+
if (!lesson) return [];
|
|
16324
|
+
return lesson.playlist.map((f) => createFile(slugify(f.file), f.title, f.url, { mediaType: detectMediaType(`${f.url} ${f.file}`, f.mediaType), thumbnail: f.thumbnail || lesson.thumbnail || collection.thumbnail, seconds: f.duration }));
|
|
16325
|
+
}
|
|
16326
|
+
async getPlaylist(path, auth, _resolution) {
|
|
16327
|
+
if (!await this.verifyAuth(auth)) return null;
|
|
16328
|
+
const { segments, depth } = parsePath(path);
|
|
16329
|
+
if (depth !== 2) return null;
|
|
16330
|
+
const collection = this.data.catalog.find((c) => c.id === segments[0]);
|
|
16331
|
+
if (!collection) return null;
|
|
16332
|
+
const files = this.getLessonFiles(collection, segments[1]);
|
|
16333
|
+
return files.length > 0 ? files : null;
|
|
16334
|
+
}
|
|
16335
|
+
async getInstructions(path, auth) {
|
|
16336
|
+
const { segments, depth } = parsePath(path);
|
|
16337
|
+
if (depth !== 2) return null;
|
|
16338
|
+
const files = await this.getPlaylist(path, auth);
|
|
16339
|
+
if (!files) return null;
|
|
16340
|
+
const collection = this.data.catalog.find((c) => c.id === segments[0]);
|
|
16341
|
+
const lesson = collection?.lessons.find((l) => l.id === segments[1]);
|
|
16342
|
+
return filesToInstructions(lesson?.name || "Lesson", files);
|
|
16343
|
+
}
|
|
16344
|
+
generateCodeVerifier() {
|
|
16345
|
+
return this.oauthHelper.generateCodeVerifier();
|
|
16346
|
+
}
|
|
16347
|
+
async buildAuthUrl(codeVerifier, redirectUri, state) {
|
|
16348
|
+
return this.oauthHelper.buildAuthUrl(this.config, codeVerifier, redirectUri, state || this.id);
|
|
16349
|
+
}
|
|
16350
|
+
buildAuthUrlFromChallenge(codeChallenge, redirectUri, state) {
|
|
16351
|
+
return this.oauthHelper.buildAuthUrlFromChallenge(this.config, codeChallenge, redirectUri, state);
|
|
16352
|
+
}
|
|
16353
|
+
async exchangeCodeForTokens(code, codeVerifier, redirectUri) {
|
|
16354
|
+
return this.oauthHelper.exchangeCodeForTokens(this.config, this.id, code, codeVerifier, redirectUri);
|
|
16355
|
+
}
|
|
16356
|
+
};
|
|
16357
|
+
|
|
16256
16358
|
// src/providers/index.ts
|
|
16257
16359
|
var unimplementedProviders = [
|
|
16258
16360
|
{
|
|
@@ -16271,14 +16373,6 @@ var unimplementedProviders = [
|
|
|
16271
16373
|
dark: "https://freeshow.app/images/favicon.png"
|
|
16272
16374
|
}
|
|
16273
16375
|
},
|
|
16274
|
-
{
|
|
16275
|
-
id: "gocurriculum",
|
|
16276
|
-
name: "Go Curriculum",
|
|
16277
|
-
logos: {
|
|
16278
|
-
light: "https://gocurriculum.com/wp-content/uploads/go-logo-curriculum-v2.png",
|
|
16279
|
-
dark: "https://gocurriculum.com/wp-content/uploads/go-logo-curriculum-v2.png"
|
|
16280
|
-
}
|
|
16281
|
-
},
|
|
16282
16376
|
{
|
|
16283
16377
|
id: "iteachchurch",
|
|
16284
16378
|
name: "iTeachChurch",
|
|
@@ -16301,6 +16395,7 @@ function initializeProviders() {
|
|
|
16301
16395
|
new APlayProvider(),
|
|
16302
16396
|
new B1ChurchProvider(),
|
|
16303
16397
|
new DropboxProvider(),
|
|
16398
|
+
new GoCurriculumProvider(),
|
|
16304
16399
|
new BibleProjectProvider(),
|
|
16305
16400
|
new HighVoltageKidsProvider(),
|
|
16306
16401
|
new JesusFilmProvider(),
|
|
@@ -16345,7 +16440,7 @@ function getAvailableProviders(ids) {
|
|
|
16345
16440
|
}
|
|
16346
16441
|
|
|
16347
16442
|
// src/index.ts
|
|
16348
|
-
var VERSION = true ? "0.
|
|
16443
|
+
var VERSION = true ? "0.7.0" : "dev";
|
|
16349
16444
|
export {
|
|
16350
16445
|
APlayProvider,
|
|
16351
16446
|
B1ChurchProvider,
|
|
@@ -16371,6 +16466,7 @@ export {
|
|
|
16371
16466
|
isContentFolder,
|
|
16372
16467
|
navigateToPath,
|
|
16373
16468
|
registerProvider,
|
|
16469
|
+
setProviderSecret,
|
|
16374
16470
|
toAuthData
|
|
16375
16471
|
};
|
|
16376
16472
|
//# sourceMappingURL=index.js.map
|