@youversion/platform-react-hooks 0.4.2 → 0.4.4

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.
@@ -1,4 +1,4 @@
1
1
 
2
- > @youversion/platform-react-hooks@0.4.2 build /home/runner/work/platform-sdk-react/platform-sdk-react/packages/hooks
2
+ > @youversion/platform-react-hooks@0.4.4 build /home/runner/work/platform-sdk-react/platform-sdk-react/packages/hooks
3
3
  > tsc -p tsconfig.build.json
4
4
 
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @youversion/platform-react-hooks
2
2
 
3
+ ## 0.4.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 8dee8f6: chore: allow setting apiHost from React code
8
+ - Updated dependencies [8dee8f6]
9
+ - @youversion/platform-core@0.4.4
10
+
11
+ ## 0.4.3
12
+
13
+ ### Patch Changes
14
+
15
+ - 7b652f7: chore(docs): update documentation and readmes, and env var usage
16
+ - Updated dependencies [7b652f7]
17
+ - @youversion/platform-core@0.4.3
18
+
3
19
  ## 0.4.2
4
20
 
5
21
  ### Patch Changes
package/README.md ADDED
@@ -0,0 +1,138 @@
1
+ ![License](https://img.shields.io/badge/license-Apache%20License%202.0-blue)
2
+ ![React >= 19.0.0](https://img.shields.io/badge/React-%3E%3D%2019.0.0-61dafb?logo=react&logoColor=white)
3
+ ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white)
4
+
5
+ # @youversion/platform-react-hooks
6
+
7
+ A comprehensive collection of React hooks for accessing the YouVersion Platform APIs. Build Bible-based applications with type-safe hooks that handle loading states, error handling, and data fetching automatically.
8
+
9
+ ## Overview
10
+
11
+ `@youversion/platform-react-hooks` provides React hooks that wrap the [@youversion/platform-core](../core/README.md) SDK, offering a declarative way to access Bible data in your React applications. Features automatic loading and error state management, type-safe hooks with TypeScript support, and memoized data fetching.
12
+
13
+ > **📚 Full Documentation:** [developers.youversion.com/sdks/react](https://developers.youversion.com/sdks/react)
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pnpm add @youversion/platform-react-hooks
19
+ ```
20
+
21
+ ### Peer Dependencies
22
+
23
+ Requires React 19.0.0 or higher:
24
+
25
+ ```bash
26
+ pnpm install react@19.0.0
27
+ ```
28
+
29
+ ## When to Use This Package
30
+
31
+ Use `@youversion/platform-react-hooks` when you need:
32
+ - ✅ Building custom React components with Bible features
33
+ - ✅ Declarative data fetching with automatic loading/error states
34
+ - ✅ Control over component UI while using reusable hooks
35
+ - ✅ Server-side rendering compatible hooks
36
+
37
+ **Use other packages instead if:**
38
+ - ❌ Need direct API access → Use [@youversion/platform-core](../core/README.md) for low-level client
39
+ - ❌ Want ready-made UI → Use [@youversion/platform-react-ui](../ui/README.md) for production components
40
+
41
+ ## Related Packages
42
+
43
+ - **[@youversion/platform-core](../core/README.md)** - Core TypeScript SDK for direct API access
44
+ - **[@youversion/platform-react-ui](../ui/README.md)** - Pre-built React components
45
+
46
+ ## Setup
47
+
48
+ All hooks require the `BibleSDKProvider` to be wrapped around your application:
49
+
50
+ ```tsx
51
+ import { BibleSDKProvider } from '@youversion/platform-react-hooks';
52
+
53
+ function App() {
54
+ return (
55
+ <BibleSDKProvider appKey="YOUR_APP_KEY">
56
+ {/* All hooks work here */}
57
+ </BibleSDKProvider>
58
+ );
59
+ }
60
+ ```
61
+
62
+ > **⚠️ Missing Provider Error:** If you use a hook without wrapping it in `BibleSDKProvider`, you'll get: `Error: useBibleClient must be used within a BibleSDKProvider`.
63
+
64
+ ## Quick Start
65
+
66
+ ```tsx
67
+ import { BibleSDKProvider, useVersion, usePassage } from '@youversion/platform-react-hooks';
68
+
69
+ function BibleVerse() {
70
+ const { version, loading: versionLoading } = useVersion(111);
71
+ const { passage, loading: passageLoading } = usePassage(111, 'JHN.3.16');
72
+
73
+ if (versionLoading || passageLoading) return <div>Loading...</div>;
74
+
75
+ return (
76
+ <div>
77
+ <h1>{passage?.human_reference}</h1>
78
+ <p>Version: {version?.abbreviation}</p>
79
+ <div dangerouslySetInnerHTML={{ __html: passage?.content || '' }} />
80
+ </div>
81
+ );
82
+ }
83
+
84
+ function App() {
85
+ return (
86
+ <BibleSDKProvider appKey="YOUR_APP_KEY">
87
+ <BibleVerse />
88
+ </BibleSDKProvider>
89
+ );
90
+ }
91
+ ```
92
+
93
+ ## Features
94
+
95
+ - Fetch Bible versions, books, chapters, and verses
96
+ - Get formatted passages with HTML or text output
97
+ - Access Verse of the Day content
98
+ - Navigate between chapters and verses
99
+ - Query available languages and metadata
100
+ - Automatic loading/error state management
101
+
102
+ ## Troubleshooting
103
+
104
+ ### Provider Not Found Error
105
+
106
+ **Error:** `Error: useBibleClient must be used within a BibleSDKProvider`
107
+
108
+ **Solution:** Ensure `BibleSDKProvider` wraps your component tree:
109
+
110
+ ```tsx
111
+ // ✅ Correct
112
+ function App() {
113
+ return (
114
+ <BibleSDKProvider appKey="YOUR_APP_KEY">
115
+ <MyComponent />
116
+ </BibleSDKProvider>
117
+ );
118
+ }
119
+ ```
120
+
121
+ ### Invalid App Key Error
122
+
123
+ **Solution:** Get your App Key from [platform.youversion.com](https://platform.youversion.com/) and verify it's passed correctly.
124
+
125
+ ## Development
126
+
127
+ See [CONTRIBUTING.md](../../CONTRIBUTING.md) for development instructions.
128
+
129
+ ## License
130
+
131
+ See [LICENSE](../../LICENSE)
132
+
133
+ ## Support
134
+
135
+ - GitHub Issues: [Create an issue](https://github.com/youversion/platform-sdk-react/issues)
136
+ - Platform Docs: [platform.youversion.com](https://platform.youversion.com/)
137
+ - Core SDK: [@youversion/platform-core documentation](../core/README.md)
138
+ - Monorepo: [YouVersion Platform SDK](../../README.md)
@@ -1,5 +1,7 @@
1
1
  type BibleSDKContextData = {
2
- appId: string;
2
+ appKey: string;
3
+ apiHost?: string;
4
+ installationId?: string;
3
5
  };
4
6
  export declare const BibleSDKContext: import("react").Context<BibleSDKContextData | null>;
5
7
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"BibleSDKContext.d.ts","sourceRoot":"","sources":["../../src/context/BibleSDKContext.tsx"],"names":[],"mappings":"AAIA,KAAK,mBAAmB,GAAG;IACzB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,eAAe,qDAAkD,CAAC"}
1
+ {"version":3,"file":"BibleSDKContext.d.ts","sourceRoot":"","sources":["../../src/context/BibleSDKContext.tsx"],"names":[],"mappings":"AAIA,KAAK,mBAAmB,GAAG;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,eAAe,qDAAkD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"BibleSDKContext.js","sourceRoot":"","sources":["../../src/context/BibleSDKContext.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAMtC,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAA6B,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"BibleSDKContext.js","sourceRoot":"","sources":["../../src/context/BibleSDKContext.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAQtC,MAAM,CAAC,MAAM,eAAe,GAAG,aAAa,CAA6B,IAAI,CAAC,CAAC"}
@@ -1,8 +1,9 @@
1
1
  import type { PropsWithChildren, ReactNode } from 'react';
2
2
  type BibleSDKProviderProps = {
3
3
  children: ReactNode;
4
- appId: string;
4
+ appKey: string;
5
+ apiHost?: string;
5
6
  };
6
- export declare function BibleSDKProvider({ appId, children, }: PropsWithChildren<BibleSDKProviderProps>): React.ReactElement;
7
+ export declare function BibleSDKProvider({ appKey, apiHost, children, }: PropsWithChildren<BibleSDKProviderProps>): React.ReactElement;
7
8
  export {};
8
9
  //# sourceMappingURL=BibleSDKProvider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"BibleSDKProvider.d.ts","sourceRoot":"","sources":["../../src/context/BibleSDKProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG1D,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,SAAS,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,GACT,EAAE,iBAAiB,CAAC,qBAAqB,CAAC,GAAG,KAAK,CAAC,YAAY,CAE/D"}
1
+ {"version":3,"file":"BibleSDKProvider.d.ts","sourceRoot":"","sources":["../../src/context/BibleSDKProvider.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAK1D,KAAK,qBAAqB,GAAG;IAC3B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,OAA8B,EAC9B,QAAQ,GACT,EAAE,iBAAiB,CAAC,qBAAqB,CAAC,GAAG,KAAK,CAAC,YAAY,CAiB/D"}
@@ -1,7 +1,18 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { useEffect } from 'react';
3
4
  import { BibleSDKContext } from './BibleSDKContext';
4
- export function BibleSDKProvider({ appId, children, }) {
5
- return _jsx(BibleSDKContext.Provider, { value: { appId }, children: children });
5
+ import { YouVersionPlatformConfiguration } from '@youversion/platform-core';
6
+ export function BibleSDKProvider({ appKey, apiHost = 'api.youversion.com', children, }) {
7
+ // Syncing appKey and apiHost to YouVersionPlatformConfiguration
8
+ // so that this can be in sync with any other code that uses
9
+ // the YouVersionPlatformConfiguration, of which a lot of our
10
+ // core package uses this configuration.
11
+ useEffect(() => {
12
+ YouVersionPlatformConfiguration.appKey = appKey;
13
+ YouVersionPlatformConfiguration.apiHost = apiHost;
14
+ }, [appKey, apiHost]);
15
+ // Installation ID gets set automatically by YouVersionPlatformConfiguration
16
+ return (_jsx(BibleSDKContext.Provider, { value: { appKey, apiHost, installationId: YouVersionPlatformConfiguration.installationId }, children: children }));
6
17
  }
7
18
  //# sourceMappingURL=BibleSDKProvider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"BibleSDKProvider.js","sourceRoot":"","sources":["../../src/context/BibleSDKProvider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAOpD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,KAAK,EACL,QAAQ,GACiC;IACzC,OAAO,KAAC,eAAe,CAAC,QAAQ,IAAC,KAAK,EAAE,EAAE,KAAK,EAAE,YAAG,QAAQ,GAA4B,CAAC;AAC3F,CAAC"}
1
+ {"version":3,"file":"BibleSDKProvider.js","sourceRoot":"","sources":["../../src/context/BibleSDKProvider.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAGb,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AAQ5E,MAAM,UAAU,gBAAgB,CAAC,EAC/B,MAAM,EACN,OAAO,GAAG,oBAAoB,EAC9B,QAAQ,GACiC;IACzC,gEAAgE;IAChE,4DAA4D;IAC5D,6DAA6D;IAC7D,wCAAwC;IACxC,SAAS,CAAC,GAAG,EAAE;QACb,+BAA+B,CAAC,MAAM,GAAG,MAAM,CAAC;QAChD,+BAA+B,CAAC,OAAO,GAAG,OAAO,CAAC;IACpD,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACtB,4EAA4E;IAC5E,OAAO,CACL,KAAC,eAAe,CAAC,QAAQ,IACvB,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,+BAA+B,CAAC,cAAc,EAAE,YAEzF,QAAQ,GACgB,CAC5B,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useBibleClient.d.ts","sourceRoot":"","sources":["../src/useBibleClient.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAA8C,MAAM,2BAA2B,CAAC;AAEpG,wBAAgB,cAAc,IAAI,WAAW,CAe5C"}
1
+ {"version":3,"file":"useBibleClient.d.ts","sourceRoot":"","sources":["../src/useBibleClient.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,WAAW,EAAa,MAAM,2BAA2B,CAAC;AAEnE,wBAAgB,cAAc,IAAI,WAAW,CAkB5C"}
@@ -1,17 +1,18 @@
1
1
  'use client';
2
2
  import { useContext, useMemo } from 'react';
3
3
  import { BibleSDKContext } from './context';
4
- import { BibleClient, ApiClient, YouVersionPlatformConfiguration } from '@youversion/platform-core';
4
+ import { BibleClient, ApiClient } from '@youversion/platform-core';
5
5
  export function useBibleClient() {
6
6
  const context = useContext(BibleSDKContext);
7
7
  return useMemo(() => {
8
- if (!context?.appId) {
8
+ if (!context?.appKey) {
9
9
  throw new Error('BibleSDK context not found. Make sure your component is wrapped with BibleSDKProvider and an API key is provided.');
10
10
  }
11
11
  return new BibleClient(new ApiClient({
12
- appId: context.appId,
13
- installationId: YouVersionPlatformConfiguration.installationId,
12
+ appKey: context.appKey,
13
+ apiHost: context.apiHost,
14
+ installationId: context.installationId,
14
15
  }));
15
- }, [context?.appId]);
16
+ }, [context?.apiHost, context?.appKey, context?.installationId]);
16
17
  }
17
18
  //# sourceMappingURL=useBibleClient.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useBibleClient.js","sourceRoot":"","sources":["../src/useBibleClient.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,+BAA+B,EAAE,MAAM,2BAA2B,CAAC;AAEpG,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAC5C,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,WAAW,CACpB,IAAI,SAAS,CAAC;YACZ,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,cAAc,EAAE,+BAA+B,CAAC,cAAc;SAC/D,CAAC,CACH,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;AACvB,CAAC"}
1
+ {"version":3,"file":"useBibleClient.js","sourceRoot":"","sources":["../src/useBibleClient.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAEnE,MAAM,UAAU,cAAc;IAC5B,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;QACJ,CAAC;QAED,OAAO,IAAI,WAAW,CACpB,IAAI,SAAS,CAAC;YACZ,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,cAAc,EAAE,OAAO,CAAC,cAAc;SACvC,CAAC,CACH,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;AACnE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useHighlights.d.ts","sourceRoot":"","sources":["../src/useHighlights.ts"],"names":[],"mappings":"AAUA,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,2BAA2B,CAAC;AAEnC,wBAAgB,aAAa,CAC3B,OAAO,CAAC,EAAE,oBAAoB,EAC9B,UAAU,CAAC,EAAE,iBAAiB,GAC7B;IACD,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,eAAe,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/D,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/F,CAkDA"}
1
+ {"version":3,"file":"useHighlights.d.ts","sourceRoot":"","sources":["../src/useHighlights.ts"],"names":[],"mappings":"AAMA,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACL,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,eAAe,EACpB,KAAK,UAAU,EACf,KAAK,SAAS,EACf,MAAM,2BAA2B,CAAC;AAEnC,wBAAgB,aAAa,CAC3B,OAAO,CAAC,EAAE,oBAAoB,EAC9B,UAAU,CAAC,EAAE,iBAAiB,GAC7B;IACD,UAAU,EAAE,UAAU,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,eAAe,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/D,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,sBAAsB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/F,CAmDA"}
@@ -2,20 +2,21 @@
2
2
  import { useMemo, useCallback } from 'react';
3
3
  import { useContext } from 'react';
4
4
  import { BibleSDKContext } from './context';
5
- import { HighlightsClient, ApiClient, YouVersionPlatformConfiguration, } from '@youversion/platform-core';
5
+ import { HighlightsClient, ApiClient } from '@youversion/platform-core';
6
6
  import { useApiData } from './useApiData';
7
7
  import {} from '@youversion/platform-core';
8
8
  export function useHighlights(options, apiOptions) {
9
9
  const context = useContext(BibleSDKContext);
10
10
  const highlightsClient = useMemo(() => {
11
- if (!context?.appId) {
11
+ if (!context?.appKey) {
12
12
  throw new Error('BibleSDK context not found. Make sure your component is wrapped with BibleSDKProvider and an API key is provided.');
13
13
  }
14
14
  return new HighlightsClient(new ApiClient({
15
- appId: context.appId,
16
- installationId: YouVersionPlatformConfiguration.installationId,
15
+ appKey: context.appKey,
16
+ apiHost: context.apiHost,
17
+ installationId: context.installationId,
17
18
  }));
18
- }, [context?.appId]);
19
+ }, [context?.apiHost, context?.appKey, context?.installationId]);
19
20
  const { data, loading, error, refetch } = useApiData(() => highlightsClient.getHighlights(options), [highlightsClient, options?.version_id, options?.passage_id], {
20
21
  enabled: apiOptions?.enabled !== false,
21
22
  });
@@ -1 +1 @@
1
- {"version":3,"file":"useHighlights.js","sourceRoot":"","sources":["../src/useHighlights.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EACL,gBAAgB,EAChB,SAAS,EACT,+BAA+B,GAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,UAAU,EAA0B,MAAM,cAAc,CAAC;AAClE,OAAO,EAMN,MAAM,2BAA2B,CAAC;AAEnC,MAAM,UAAU,aAAa,CAC3B,OAA8B,EAC9B,UAA8B;IAS9B,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,EAAE;QACpC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,gBAAgB,CACzB,IAAI,SAAS,CAAC;YACZ,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,cAAc,EAAE,+BAA+B,CAAC,cAAc;SAC/D,CAAC,CACH,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAErB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,UAAU,CAClD,GAAG,EAAE,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,EAC7C,CAAC,gBAAgB,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,EAC5D;QACE,OAAO,EAAE,UAAU,EAAE,OAAO,KAAK,KAAK;KACvC,CACF,CAAC;IAEF,MAAM,eAAe,GAAG,WAAW,CACjC,KAAK,EAAE,IAAqB,EAAsB,EAAE;QAClD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5D,OAAO,EAAE,CAAC;QACV,OAAO,MAAM,CAAC;IAChB,CAAC,EACD,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAC5B,CAAC;IAEF,MAAM,eAAe,GAAG,WAAW,CACjC,KAAK,EAAE,SAAiB,EAAE,aAAsC,EAAiB,EAAE;QACjF,MAAM,gBAAgB,CAAC,eAAe,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACjE,OAAO,EAAE,CAAC;IACZ,CAAC,EACD,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAC5B,CAAC;IAEF,OAAO;QACL,UAAU,EAAE,IAAI;QAChB,OAAO;QACP,KAAK;QACL,OAAO;QACP,eAAe;QACf,eAAe;KAChB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"useHighlights.js","sourceRoot":"","sources":["../src/useHighlights.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,UAAU,EAA0B,MAAM,cAAc,CAAC;AAClE,OAAO,EAMN,MAAM,2BAA2B,CAAC;AAEnC,MAAM,UAAU,aAAa,CAC3B,OAA8B,EAC9B,UAA8B;IAS9B,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C,MAAM,gBAAgB,GAAG,OAAO,CAAC,GAAG,EAAE;QACpC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,gBAAgB,CACzB,IAAI,SAAS,CAAC;YACZ,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,cAAc,EAAE,OAAO,CAAC,cAAc;SACvC,CAAC,CACH,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;IAEjE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,UAAU,CAClD,GAAG,EAAE,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC,EAC7C,CAAC,gBAAgB,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,EAC5D;QACE,OAAO,EAAE,UAAU,EAAE,OAAO,KAAK,KAAK;KACvC,CACF,CAAC;IAEF,MAAM,eAAe,GAAG,WAAW,CACjC,KAAK,EAAE,IAAqB,EAAsB,EAAE;QAClD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAC5D,OAAO,EAAE,CAAC;QACV,OAAO,MAAM,CAAC;IAChB,CAAC,EACD,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAC5B,CAAC;IAEF,MAAM,eAAe,GAAG,WAAW,CACjC,KAAK,EAAE,SAAiB,EAAE,aAAsC,EAAiB,EAAE;QACjF,MAAM,gBAAgB,CAAC,eAAe,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;QACjE,OAAO,EAAE,CAAC;IACZ,CAAC,EACD,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAC5B,CAAC;IAEF,OAAO;QACL,UAAU,EAAE,IAAI;QAChB,OAAO;QACP,KAAK;QACL,OAAO;QACP,eAAe;QACf,eAAe;KAChB,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useLanguages.d.ts","sourceRoot":"","sources":["../src/useLanguages.ts"],"names":[],"mappings":"AAUA,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,QAAQ,EACd,MAAM,2BAA2B,CAAC;AAEnC,wBAAgB,YAAY,CAC1B,OAAO,EAAE,mBAAmB,EAC5B,UAAU,CAAC,EAAE,iBAAiB,GAC7B;IACD,SAAS,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CA+BA"}
1
+ {"version":3,"file":"useLanguages.d.ts","sourceRoot":"","sources":["../src/useLanguages.ts"],"names":[],"mappings":"AAMA,OAAO,EAAc,KAAK,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAClE,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,QAAQ,EACd,MAAM,2BAA2B,CAAC;AAEnC,wBAAgB,YAAY,CAC1B,OAAO,EAAE,mBAAmB,EAC5B,UAAU,CAAC,EAAE,iBAAiB,GAC7B;IACD,SAAS,EAAE,UAAU,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAgCA"}
@@ -2,20 +2,21 @@
2
2
  import { useMemo } from 'react';
3
3
  import { useContext } from 'react';
4
4
  import { BibleSDKContext } from './context';
5
- import { LanguagesClient, ApiClient, YouVersionPlatformConfiguration, } from '@youversion/platform-core';
5
+ import { LanguagesClient, ApiClient } from '@youversion/platform-core';
6
6
  import { useApiData } from './useApiData';
7
7
  import {} from '@youversion/platform-core';
8
8
  export function useLanguages(options, apiOptions) {
9
9
  const context = useContext(BibleSDKContext);
10
10
  const languagesClient = useMemo(() => {
11
- if (!context?.appId) {
11
+ if (!context?.appKey) {
12
12
  throw new Error('BibleSDK context not found. Make sure your component is wrapped with BibleSDKProvider and an API key is provided.');
13
13
  }
14
14
  return new LanguagesClient(new ApiClient({
15
- appId: context.appId,
16
- installationId: YouVersionPlatformConfiguration.installationId,
15
+ appKey: context.appKey,
16
+ apiHost: context.apiHost,
17
+ installationId: context.installationId,
17
18
  }));
18
- }, [context?.appId]);
19
+ }, [context?.apiHost, context?.appKey, context?.installationId]);
19
20
  const { data, loading, error, refetch } = useApiData(() => languagesClient.getLanguages(options), [languagesClient, options?.country, options?.page_size, options?.page_token], {
20
21
  enabled: apiOptions?.enabled !== false,
21
22
  });
@@ -1 +1 @@
1
- {"version":3,"file":"useLanguages.js","sourceRoot":"","sources":["../src/useLanguages.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EACL,eAAe,EACf,SAAS,EACT,+BAA+B,GAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,UAAU,EAA0B,MAAM,cAAc,CAAC;AAClE,OAAO,EAIN,MAAM,2BAA2B,CAAC;AAEnC,MAAM,UAAU,YAAY,CAC1B,OAA4B,EAC5B,UAA8B;IAO9B,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE;QACnC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,eAAe,CACxB,IAAI,SAAS,CAAC;YACZ,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,cAAc,EAAE,+BAA+B,CAAC,cAAc;SAC/D,CAAC,CACH,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAC;IAErB,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,UAAU,CAClD,GAAG,EAAE,CAAC,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,EAC3C,CAAC,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,EAC5E;QACE,OAAO,EAAE,UAAU,EAAE,OAAO,KAAK,KAAK;KACvC,CACF,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,IAAI;QACf,OAAO;QACP,KAAK;QACL,OAAO;KACR,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"useLanguages.js","sourceRoot":"","sources":["../src/useLanguages.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACvE,OAAO,EAAE,UAAU,EAA0B,MAAM,cAAc,CAAC;AAClE,OAAO,EAIN,MAAM,2BAA2B,CAAC;AAEnC,MAAM,UAAU,YAAY,CAC1B,OAA4B,EAC5B,UAA8B;IAO9B,MAAM,OAAO,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IAE5C,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE;QACnC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CACb,mHAAmH,CACpH,CAAC;QACJ,CAAC;QACD,OAAO,IAAI,eAAe,CACxB,IAAI,SAAS,CAAC;YACZ,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,cAAc,EAAE,OAAO,CAAC,cAAc;SACvC,CAAC,CACH,CAAC;IACJ,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC;IAEjE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,UAAU,CAClD,GAAG,EAAE,CAAC,eAAe,CAAC,YAAY,CAAC,OAAO,CAAC,EAC3C,CAAC,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,UAAU,CAAC,EAC5E;QACE,OAAO,EAAE,UAAU,EAAE,OAAO,KAAK,KAAK;KACvC,CACF,CAAC;IAEF,OAAO;QACL,SAAS,EAAE,IAAI;QACf,OAAO;QACP,KAAK;QACL,OAAO;KACR,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@youversion/platform-react-hooks",
3
- "version": "0.4.2",
3
+ "version": "0.4.4",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -21,7 +21,7 @@
21
21
  }
22
22
  },
23
23
  "dependencies": {
24
- "@youversion/platform-core": "0.4.2"
24
+ "@youversion/platform-core": "0.4.4"
25
25
  },
26
26
  "peerDependencies": {
27
27
  "react": ">=19.1.0 <20.0.0"
@@ -3,7 +3,9 @@
3
3
  import { createContext } from 'react';
4
4
 
5
5
  type BibleSDKContextData = {
6
- appId: string;
6
+ appKey: string;
7
+ apiHost?: string;
8
+ installationId?: string;
7
9
  };
8
10
 
9
11
  export const BibleSDKContext = createContext<BibleSDKContextData | null>(null);
@@ -1,16 +1,35 @@
1
1
  'use client';
2
2
 
3
3
  import type { PropsWithChildren, ReactNode } from 'react';
4
+ import { useEffect } from 'react';
4
5
  import { BibleSDKContext } from './BibleSDKContext';
6
+ import { YouVersionPlatformConfiguration } from '@youversion/platform-core';
5
7
 
6
8
  type BibleSDKProviderProps = {
7
9
  children: ReactNode;
8
- appId: string;
10
+ appKey: string;
11
+ apiHost?: string;
9
12
  };
10
13
 
11
14
  export function BibleSDKProvider({
12
- appId,
15
+ appKey,
16
+ apiHost = 'api.youversion.com',
13
17
  children,
14
18
  }: PropsWithChildren<BibleSDKProviderProps>): React.ReactElement {
15
- return <BibleSDKContext.Provider value={{ appId }}>{children}</BibleSDKContext.Provider>;
19
+ // Syncing appKey and apiHost to YouVersionPlatformConfiguration
20
+ // so that this can be in sync with any other code that uses
21
+ // the YouVersionPlatformConfiguration, of which a lot of our
22
+ // core package uses this configuration.
23
+ useEffect(() => {
24
+ YouVersionPlatformConfiguration.appKey = appKey;
25
+ YouVersionPlatformConfiguration.apiHost = apiHost;
26
+ }, [appKey, apiHost]);
27
+ // Installation ID gets set automatically by YouVersionPlatformConfiguration
28
+ return (
29
+ <BibleSDKContext.Provider
30
+ value={{ appKey, apiHost, installationId: YouVersionPlatformConfiguration.installationId }}
31
+ >
32
+ {children}
33
+ </BibleSDKContext.Provider>
34
+ );
16
35
  }
@@ -19,16 +19,11 @@ vi.mock('@youversion/platform-core', async () => {
19
19
  isApiClient: true,
20
20
  };
21
21
  }),
22
- YouVersionPlatformConfiguration: {
23
- get installationId() {
24
- return 'auto-generated-uuid';
25
- },
26
- },
27
22
  };
28
23
  });
29
24
 
30
25
  describe('useBibleClient', () => {
31
- const mockAppId = 'test-app-id';
26
+ const mockAppKey = 'test-app-key';
32
27
 
33
28
  beforeEach(() => {
34
29
  vi.clearAllMocks();
@@ -38,7 +33,7 @@ describe('useBibleClient', () => {
38
33
  const wrapper = ({ children }: { children: ReactNode }) => (
39
34
  <BibleSDKContext.Provider
40
35
  value={{
41
- appId: mockAppId,
36
+ appKey: mockAppKey,
42
37
  }}
43
38
  >
44
39
  {children}
@@ -48,8 +43,7 @@ describe('useBibleClient', () => {
48
43
  const { result } = renderHook(() => useBibleClient(), { wrapper });
49
44
 
50
45
  expect(ApiClient).toHaveBeenCalledWith({
51
- appId: mockAppId,
52
- installationId: 'auto-generated-uuid',
46
+ appKey: mockAppKey,
53
47
  });
54
48
  expect(BibleClient).toHaveBeenCalledWith(expect.objectContaining({ isApiClient: true }));
55
49
  expect(result.current).toEqual(expect.objectContaining({ isBibleClient: true }));
@@ -61,11 +55,11 @@ describe('useBibleClient', () => {
61
55
  );
62
56
  });
63
57
 
64
- it('should throw error when appId is missing', () => {
58
+ it('should throw error when appKey is missing', () => {
65
59
  const wrapper = ({ children }: { children: ReactNode }) => (
66
60
  <BibleSDKContext.Provider
67
61
  value={{
68
- appId: '',
62
+ appKey: '',
69
63
  }}
70
64
  >
71
65
  {children}
@@ -81,7 +75,7 @@ describe('useBibleClient', () => {
81
75
  const wrapper = ({ children }: { children: ReactNode }) => (
82
76
  <BibleSDKContext.Provider
83
77
  value={{
84
- appId: mockAppId,
78
+ appKey: mockAppKey,
85
79
  }}
86
80
  >
87
81
  {children}
@@ -98,13 +92,13 @@ describe('useBibleClient', () => {
98
92
  expect(BibleClient).toHaveBeenCalledTimes(1);
99
93
  });
100
94
 
101
- it('should create new BibleClient when appId changes', () => {
102
- let currentAppId = mockAppId;
95
+ it('should create new BibleClient when appKey changes', () => {
96
+ let currentAppKey = mockAppKey;
103
97
 
104
98
  const wrapper = ({ children }: { children: ReactNode }) => (
105
99
  <BibleSDKContext.Provider
106
100
  value={{
107
- appId: currentAppId,
101
+ appKey: currentAppKey,
108
102
  }}
109
103
  >
110
104
  {children}
@@ -116,11 +110,10 @@ describe('useBibleClient', () => {
116
110
  const firstClient = result.current;
117
111
  expect(BibleClient).toHaveBeenCalledTimes(1);
118
112
  expect(ApiClient).toHaveBeenCalledWith({
119
- appId: mockAppId,
120
- installationId: 'auto-generated-uuid',
113
+ appKey: mockAppKey,
121
114
  });
122
115
 
123
- currentAppId = 'new-app-id';
116
+ currentAppKey = 'new-app-key';
124
117
  rerender();
125
118
 
126
119
  const secondClient = result.current;
@@ -128,16 +121,15 @@ describe('useBibleClient', () => {
128
121
  expect(firstClient).not.toBe(secondClient);
129
122
 
130
123
  expect(ApiClient).toHaveBeenLastCalledWith({
131
- appId: 'new-app-id',
132
- installationId: 'auto-generated-uuid',
124
+ appKey: 'new-app-key',
133
125
  });
134
126
  });
135
127
 
136
- it('should throw error when appId is null', () => {
128
+ it('should throw error when appKey is null', () => {
137
129
  const wrapper = ({ children }: { children: ReactNode }) => (
138
130
  <BibleSDKContext.Provider
139
131
  value={{
140
- appId: null as unknown as string,
132
+ appKey: null as unknown as string,
141
133
  }}
142
134
  >
143
135
  {children}
@@ -2,21 +2,24 @@
2
2
 
3
3
  import { useContext, useMemo } from 'react';
4
4
  import { BibleSDKContext } from './context';
5
- import { BibleClient, ApiClient, YouVersionPlatformConfiguration } from '@youversion/platform-core';
5
+ import { BibleClient, ApiClient } from '@youversion/platform-core';
6
6
 
7
7
  export function useBibleClient(): BibleClient {
8
8
  const context = useContext(BibleSDKContext);
9
+
9
10
  return useMemo(() => {
10
- if (!context?.appId) {
11
+ if (!context?.appKey) {
11
12
  throw new Error(
12
13
  'BibleSDK context not found. Make sure your component is wrapped with BibleSDKProvider and an API key is provided.',
13
14
  );
14
15
  }
16
+
15
17
  return new BibleClient(
16
18
  new ApiClient({
17
- appId: context.appId,
18
- installationId: YouVersionPlatformConfiguration.installationId,
19
+ appKey: context.appKey,
20
+ apiHost: context.apiHost,
21
+ installationId: context.installationId,
19
22
  }),
20
23
  );
21
- }, [context?.appId]);
24
+ }, [context?.apiHost, context?.appKey, context?.installationId]);
22
25
  }
@@ -22,16 +22,11 @@ vi.mock('@youversion/platform-core', async () => {
22
22
  ApiClient: vi.fn(function () {
23
23
  return { isApiClient: true };
24
24
  }),
25
- YouVersionPlatformConfiguration: {
26
- get installationId() {
27
- return 'auto-generated-uuid';
28
- },
29
- },
30
25
  };
31
26
  });
32
27
 
33
28
  describe('useHighlights', () => {
34
- const mockAppId = 'test-app-id';
29
+ const mockAppKey = 'test-app-key';
35
30
 
36
31
  const mockHighlights: Collection<Highlight> = {
37
32
  data: [
@@ -59,7 +54,7 @@ describe('useHighlights', () => {
59
54
  let mockCreateHighlight: Mock;
60
55
  let mockDeleteHighlight: Mock;
61
56
 
62
- const createWrapper = (contextValue: { appId: string }) => {
57
+ const createWrapper = (contextValue: { appKey: string }) => {
63
58
  return ({ children }: { children: ReactNode }) => (
64
59
  <BibleSDKContext.Provider value={contextValue}>{children}</BibleSDKContext.Provider>
65
60
  );
@@ -94,9 +89,9 @@ describe('useHighlights', () => {
94
89
  );
95
90
  });
96
91
 
97
- it('should throw error when appId is missing', () => {
92
+ it('should throw error when appKey is missing', () => {
98
93
  const wrapper = createWrapper({
99
- appId: '',
94
+ appKey: '',
100
95
  });
101
96
 
102
97
  expect(() => renderHook(() => useHighlights(), { wrapper })).toThrow(
@@ -108,21 +103,20 @@ describe('useHighlights', () => {
108
103
  describe('client creation', () => {
109
104
  it('should create HighlightsClient with correct ApiClient config', () => {
110
105
  const wrapper = createWrapper({
111
- appId: mockAppId,
106
+ appKey: mockAppKey,
112
107
  });
113
108
 
114
109
  renderHook(() => useHighlights(), { wrapper });
115
110
 
116
111
  expect(ApiClient).toHaveBeenCalledWith({
117
- appId: mockAppId,
118
- installationId: 'auto-generated-uuid',
112
+ appKey: mockAppKey,
119
113
  });
120
114
  expect(HighlightsClient).toHaveBeenCalledWith(expect.objectContaining({ isApiClient: true }));
121
115
  });
122
116
 
123
117
  it('should memoize HighlightsClient instance', () => {
124
118
  const wrapper = createWrapper({
125
- appId: mockAppId,
119
+ appKey: mockAppKey,
126
120
  });
127
121
 
128
122
  const { rerender } = renderHook(() => useHighlights(), { wrapper });
@@ -134,12 +128,12 @@ describe('useHighlights', () => {
134
128
  });
135
129
 
136
130
  it('should create new HighlightsClient when context values change', () => {
137
- let currentAppId = mockAppId;
131
+ let currentAppKey = mockAppKey;
138
132
 
139
133
  const wrapper = ({ children }: { children: ReactNode }) => (
140
134
  <BibleSDKContext.Provider
141
135
  value={{
142
- appId: currentAppId,
136
+ appKey: currentAppKey,
143
137
  }}
144
138
  >
145
139
  {children}
@@ -150,7 +144,7 @@ describe('useHighlights', () => {
150
144
 
151
145
  expect(HighlightsClient).toHaveBeenCalledTimes(1);
152
146
 
153
- currentAppId = 'new-app-id';
147
+ currentAppKey = 'new-app-key';
154
148
 
155
149
  rerender();
156
150
 
@@ -161,7 +155,7 @@ describe('useHighlights', () => {
161
155
  describe('fetching highlights', () => {
162
156
  it('should fetch highlights with no options', async () => {
163
157
  const wrapper = createWrapper({
164
- appId: mockAppId,
158
+ appKey: mockAppKey,
165
159
  });
166
160
 
167
161
  const { result } = renderHook(() => useHighlights(), { wrapper });
@@ -179,7 +173,7 @@ describe('useHighlights', () => {
179
173
 
180
174
  it('should fetch highlights with version_id option', async () => {
181
175
  const wrapper = createWrapper({
182
- appId: mockAppId,
176
+ appKey: mockAppKey,
183
177
  });
184
178
 
185
179
  const { result } = renderHook(() => useHighlights({ version_id: 111 }), { wrapper });
@@ -194,7 +188,7 @@ describe('useHighlights', () => {
194
188
 
195
189
  it('should fetch highlights with passage_id option', async () => {
196
190
  const wrapper = createWrapper({
197
- appId: mockAppId,
191
+ appKey: mockAppKey,
198
192
  });
199
193
 
200
194
  const { result } = renderHook(() => useHighlights({ passage_id: 'MAT.1.1' }), { wrapper });
@@ -209,7 +203,7 @@ describe('useHighlights', () => {
209
203
 
210
204
  it('should fetch highlights with both options', async () => {
211
205
  const wrapper = createWrapper({
212
- appId: mockAppId,
206
+ appKey: mockAppKey,
213
207
  });
214
208
 
215
209
  const { result } = renderHook(
@@ -232,7 +226,7 @@ describe('useHighlights', () => {
232
226
 
233
227
  it('should refetch when options change', async () => {
234
228
  const wrapper = createWrapper({
235
- appId: mockAppId,
229
+ appKey: mockAppKey,
236
230
  });
237
231
 
238
232
  const { result, rerender } = renderHook(({ options }) => useHighlights(options), {
@@ -258,7 +252,7 @@ describe('useHighlights', () => {
258
252
 
259
253
  it('should not fetch when enabled is false', async () => {
260
254
  const wrapper = createWrapper({
261
- appId: mockAppId,
255
+ appKey: mockAppKey,
262
256
  });
263
257
 
264
258
  const { result } = renderHook(() => useHighlights(undefined, { enabled: false }), {
@@ -278,7 +272,7 @@ describe('useHighlights', () => {
278
272
  mockGetHighlights.mockRejectedValueOnce(error);
279
273
 
280
274
  const wrapper = createWrapper({
281
- appId: mockAppId,
275
+ appKey: mockAppKey,
282
276
  });
283
277
 
284
278
  const { result } = renderHook(() => useHighlights(), { wrapper });
@@ -293,7 +287,7 @@ describe('useHighlights', () => {
293
287
 
294
288
  it('should support manual refetch', async () => {
295
289
  const wrapper = createWrapper({
296
- appId: mockAppId,
290
+ appKey: mockAppKey,
297
291
  });
298
292
 
299
293
  const { result } = renderHook(() => useHighlights(), { wrapper });
@@ -315,7 +309,7 @@ describe('useHighlights', () => {
315
309
  describe('createHighlight mutation', () => {
316
310
  it('should create highlight and refetch', async () => {
317
311
  const wrapper = createWrapper({
318
- appId: mockAppId,
312
+ appKey: mockAppKey,
319
313
  });
320
314
 
321
315
  const { result } = renderHook(() => useHighlights(), { wrapper });
@@ -350,7 +344,7 @@ describe('useHighlights', () => {
350
344
  mockCreateHighlight.mockRejectedValueOnce(error);
351
345
 
352
346
  const wrapper = createWrapper({
353
- appId: mockAppId,
347
+ appKey: mockAppKey,
354
348
  });
355
349
 
356
350
  const { result } = renderHook(() => useHighlights(), { wrapper });
@@ -377,7 +371,7 @@ describe('useHighlights', () => {
377
371
  describe('deleteHighlight mutation', () => {
378
372
  it('should delete highlight and refetch', async () => {
379
373
  const wrapper = createWrapper({
380
- appId: mockAppId,
374
+ appKey: mockAppKey,
381
375
  });
382
376
 
383
377
  const { result } = renderHook(() => useHighlights(), { wrapper });
@@ -402,7 +396,7 @@ describe('useHighlights', () => {
402
396
 
403
397
  it('should delete highlight with options', async () => {
404
398
  const wrapper = createWrapper({
405
- appId: mockAppId,
399
+ appKey: mockAppKey,
406
400
  });
407
401
 
408
402
  const { result } = renderHook(() => useHighlights(), { wrapper });
@@ -428,7 +422,7 @@ describe('useHighlights', () => {
428
422
  mockDeleteHighlight.mockRejectedValueOnce(error);
429
423
 
430
424
  const wrapper = createWrapper({
431
- appId: mockAppId,
425
+ appKey: mockAppKey,
432
426
  });
433
427
 
434
428
  const { result } = renderHook(() => useHighlights(), { wrapper });
@@ -3,11 +3,7 @@
3
3
  import { useMemo, useCallback } from 'react';
4
4
  import { useContext } from 'react';
5
5
  import { BibleSDKContext } from './context';
6
- import {
7
- HighlightsClient,
8
- ApiClient,
9
- YouVersionPlatformConfiguration,
10
- } from '@youversion/platform-core';
6
+ import { HighlightsClient, ApiClient } from '@youversion/platform-core';
11
7
  import { useApiData, type UseApiDataOptions } from './useApiData';
12
8
  import {
13
9
  type GetHighlightsOptions,
@@ -31,18 +27,19 @@ export function useHighlights(
31
27
  const context = useContext(BibleSDKContext);
32
28
 
33
29
  const highlightsClient = useMemo(() => {
34
- if (!context?.appId) {
30
+ if (!context?.appKey) {
35
31
  throw new Error(
36
32
  'BibleSDK context not found. Make sure your component is wrapped with BibleSDKProvider and an API key is provided.',
37
33
  );
38
34
  }
39
35
  return new HighlightsClient(
40
36
  new ApiClient({
41
- appId: context.appId,
42
- installationId: YouVersionPlatformConfiguration.installationId,
37
+ appKey: context.appKey,
38
+ apiHost: context.apiHost,
39
+ installationId: context.installationId,
43
40
  }),
44
41
  );
45
- }, [context?.appId]);
42
+ }, [context?.apiHost, context?.appKey, context?.installationId]);
46
43
 
47
44
  const { data, loading, error, refetch } = useApiData<Collection<Highlight>>(
48
45
  () => highlightsClient.getHighlights(options),
@@ -22,16 +22,11 @@ vi.mock('@youversion/platform-core', async () => {
22
22
  ApiClient: vi.fn(function () {
23
23
  return { isApiClient: true };
24
24
  }),
25
- YouVersionPlatformConfiguration: {
26
- get installationId() {
27
- return 'auto-generated-uuid';
28
- },
29
- },
30
25
  };
31
26
  });
32
27
 
33
28
  describe('useLanguages', () => {
34
- const mockAppId = 'test-app-id';
29
+ const mockAppKey = 'test-app-key';
35
30
 
36
31
  const mockLanguages: Collection<Language> = {
37
32
  data: [
@@ -77,7 +72,7 @@ describe('useLanguages', () => {
77
72
 
78
73
  let mockGetLanguages: Mock;
79
74
 
80
- const createWrapper = (contextValue: { appId: string }) => {
75
+ const createWrapper = (contextValue: { appKey: string }) => {
81
76
  return ({ children }: { children: ReactNode }) => (
82
77
  <BibleSDKContext.Provider value={contextValue}>{children}</BibleSDKContext.Provider>
83
78
  );
@@ -108,9 +103,9 @@ describe('useLanguages', () => {
108
103
  );
109
104
  });
110
105
 
111
- it('should throw error when appId is missing', () => {
106
+ it('should throw error when appKey is missing', () => {
112
107
  const wrapper = createWrapper({
113
- appId: '',
108
+ appKey: '',
114
109
  });
115
110
 
116
111
  expect(() => renderHook(() => useLanguages({ country: 'US' }), { wrapper })).toThrow(
@@ -122,21 +117,20 @@ describe('useLanguages', () => {
122
117
  describe('client creation', () => {
123
118
  it('should create LanguagesClient with correct ApiClient config', () => {
124
119
  const wrapper = createWrapper({
125
- appId: mockAppId,
120
+ appKey: mockAppKey,
126
121
  });
127
122
 
128
123
  renderHook(() => useLanguages({ country: 'US' }), { wrapper });
129
124
 
130
125
  expect(ApiClient).toHaveBeenCalledWith({
131
- appId: mockAppId,
132
- installationId: 'auto-generated-uuid',
126
+ appKey: mockAppKey,
133
127
  });
134
128
  expect(LanguagesClient).toHaveBeenCalledWith(expect.objectContaining({ isApiClient: true }));
135
129
  });
136
130
 
137
131
  it('should memoize LanguagesClient instance', () => {
138
132
  const wrapper = createWrapper({
139
- appId: mockAppId,
133
+ appKey: mockAppKey,
140
134
  });
141
135
 
142
136
  const { result, rerender } = renderHook(() => useLanguages({ country: 'US' }), { wrapper });
@@ -149,12 +143,12 @@ describe('useLanguages', () => {
149
143
  });
150
144
 
151
145
  it('should create new LanguagesClient when context values change', () => {
152
- let currentAppId = mockAppId;
146
+ let currentAppKey = mockAppKey;
153
147
 
154
148
  const wrapper = ({ children }: { children: ReactNode }) => (
155
149
  <BibleSDKContext.Provider
156
150
  value={{
157
- appId: currentAppId,
151
+ appKey: currentAppKey,
158
152
  }}
159
153
  >
160
154
  {children}
@@ -165,7 +159,7 @@ describe('useLanguages', () => {
165
159
 
166
160
  expect(LanguagesClient).toHaveBeenCalledTimes(1);
167
161
 
168
- currentAppId = 'new-app-id';
162
+ currentAppKey = 'new-app-key';
169
163
  rerender();
170
164
 
171
165
  expect(LanguagesClient).toHaveBeenCalledTimes(2);
@@ -175,7 +169,7 @@ describe('useLanguages', () => {
175
169
  describe('fetching languages', () => {
176
170
  it('should fetch languages with required country', async () => {
177
171
  const wrapper = createWrapper({
178
- appId: mockAppId,
172
+ appKey: mockAppKey,
179
173
  });
180
174
 
181
175
  const { result } = renderHook(() => useLanguages({ country: 'US' }), { wrapper });
@@ -193,7 +187,7 @@ describe('useLanguages', () => {
193
187
 
194
188
  it('should fetch languages with all options', async () => {
195
189
  const wrapper = createWrapper({
196
- appId: mockAppId,
190
+ appKey: mockAppKey,
197
191
  });
198
192
 
199
193
  const options: GetLanguagesOptions = {
@@ -214,7 +208,7 @@ describe('useLanguages', () => {
214
208
 
215
209
  it('should refetch when options change', async () => {
216
210
  const wrapper = createWrapper({
217
- appId: mockAppId,
211
+ appKey: mockAppKey,
218
212
  });
219
213
 
220
214
  const { result, rerender } = renderHook(({ options }) => useLanguages(options), {
@@ -240,7 +234,7 @@ describe('useLanguages', () => {
240
234
 
241
235
  it('should not fetch when enabled is false', async () => {
242
236
  const wrapper = createWrapper({
243
- appId: mockAppId,
237
+ appKey: mockAppKey,
244
238
  });
245
239
 
246
240
  const { result } = renderHook(() => useLanguages({ country: 'US' }, { enabled: false }), {
@@ -260,7 +254,7 @@ describe('useLanguages', () => {
260
254
  mockGetLanguages.mockRejectedValueOnce(error);
261
255
 
262
256
  const wrapper = createWrapper({
263
- appId: mockAppId,
257
+ appKey: mockAppKey,
264
258
  });
265
259
 
266
260
  const { result } = renderHook(() => useLanguages({ country: 'US' }), { wrapper });
@@ -275,7 +269,7 @@ describe('useLanguages', () => {
275
269
 
276
270
  it('should support manual refetch', async () => {
277
271
  const wrapper = createWrapper({
278
- appId: mockAppId,
272
+ appKey: mockAppKey,
279
273
  });
280
274
 
281
275
  const { result } = renderHook(() => useLanguages({ country: 'US' }), { wrapper });
@@ -3,11 +3,7 @@
3
3
  import { useMemo } from 'react';
4
4
  import { useContext } from 'react';
5
5
  import { BibleSDKContext } from './context';
6
- import {
7
- LanguagesClient,
8
- ApiClient,
9
- YouVersionPlatformConfiguration,
10
- } from '@youversion/platform-core';
6
+ import { LanguagesClient, ApiClient } from '@youversion/platform-core';
11
7
  import { useApiData, type UseApiDataOptions } from './useApiData';
12
8
  import {
13
9
  type GetLanguagesOptions,
@@ -27,18 +23,19 @@ export function useLanguages(
27
23
  const context = useContext(BibleSDKContext);
28
24
 
29
25
  const languagesClient = useMemo(() => {
30
- if (!context?.appId) {
26
+ if (!context?.appKey) {
31
27
  throw new Error(
32
28
  'BibleSDK context not found. Make sure your component is wrapped with BibleSDKProvider and an API key is provided.',
33
29
  );
34
30
  }
35
31
  return new LanguagesClient(
36
32
  new ApiClient({
37
- appId: context.appId,
38
- installationId: YouVersionPlatformConfiguration.installationId,
33
+ appKey: context.appKey,
34
+ apiHost: context.apiHost,
35
+ installationId: context.installationId,
39
36
  }),
40
37
  );
41
- }, [context?.appId]);
38
+ }, [context?.apiHost, context?.appKey, context?.installationId]);
42
39
 
43
40
  const { data, loading, error, refetch } = useApiData<Collection<Language>>(
44
41
  () => languagesClient.getLanguages(options),
@@ -5,8 +5,6 @@ import { useVerseOfTheDay } from './useVOTD';
5
5
  import { BibleSDKContext } from './context';
6
6
  import { BibleClient, ApiClient, type VOTD } from '@youversion/platform-core';
7
7
 
8
- const MOCK_INSTALLATION_ID = 'auto-generated-uuid';
9
-
10
8
  // Mock the core package
11
9
  vi.mock('@youversion/platform-core', async () => {
12
10
  const actual = await vi.importActual('@youversion/platform-core');
@@ -18,16 +16,11 @@ vi.mock('@youversion/platform-core', async () => {
18
16
  ApiClient: vi.fn(function () {
19
17
  return { isApiClient: true };
20
18
  }),
21
- YouVersionPlatformConfiguration: {
22
- get installationId() {
23
- return MOCK_INSTALLATION_ID;
24
- },
25
- },
26
19
  };
27
20
  });
28
21
 
29
22
  describe('useVerseOfTheDay', () => {
30
- const mockAppId = 'test-app-id';
23
+ const mockAppKey = 'test-app-key';
31
24
 
32
25
  const mockVOTD: VOTD = {
33
26
  day: 1,
@@ -36,7 +29,7 @@ describe('useVerseOfTheDay', () => {
36
29
 
37
30
  let mockGetVOTD: Mock;
38
31
 
39
- const createWrapper = (contextValue: { appId: string }) => {
32
+ const createWrapper = (contextValue: { appKey: string }) => {
40
33
  return ({ children }: { children: ReactNode }) => (
41
34
  <BibleSDKContext.Provider value={contextValue}>{children}</BibleSDKContext.Provider>
42
35
  );
@@ -67,9 +60,9 @@ describe('useVerseOfTheDay', () => {
67
60
  );
68
61
  });
69
62
 
70
- it('should throw error when appId is missing', () => {
63
+ it('should throw error when appKey is missing', () => {
71
64
  const wrapper = createWrapper({
72
- appId: '',
65
+ appKey: '',
73
66
  });
74
67
 
75
68
  expect(() => renderHook(() => useVerseOfTheDay(1), { wrapper })).toThrow(
@@ -81,21 +74,20 @@ describe('useVerseOfTheDay', () => {
81
74
  describe('client creation', () => {
82
75
  it('should create BibleClient with correct ApiClient config', () => {
83
76
  const wrapper = createWrapper({
84
- appId: mockAppId,
77
+ appKey: mockAppKey,
85
78
  });
86
79
 
87
80
  renderHook(() => useVerseOfTheDay(1), { wrapper });
88
81
 
89
82
  expect(ApiClient).toHaveBeenCalledWith({
90
- appId: mockAppId,
91
- installationId: MOCK_INSTALLATION_ID,
83
+ appKey: mockAppKey,
92
84
  });
93
85
  expect(BibleClient).toHaveBeenCalledWith(expect.objectContaining({ isApiClient: true }));
94
86
  });
95
87
 
96
88
  it('should memoize BibleClient instance', () => {
97
89
  const wrapper = createWrapper({
98
- appId: mockAppId,
90
+ appKey: mockAppKey,
99
91
  });
100
92
 
101
93
  const { result, rerender } = renderHook(() => useVerseOfTheDay(1), { wrapper });
@@ -108,12 +100,12 @@ describe('useVerseOfTheDay', () => {
108
100
  });
109
101
 
110
102
  it('should create new BibleClient when context values change', () => {
111
- let currentAppId = mockAppId;
103
+ let currentAppKey = mockAppKey;
112
104
 
113
105
  const wrapper = ({ children }: { children: ReactNode }) => (
114
106
  <BibleSDKContext.Provider
115
107
  value={{
116
- appId: currentAppId,
108
+ appKey: currentAppKey,
117
109
  }}
118
110
  >
119
111
  {children}
@@ -124,7 +116,7 @@ describe('useVerseOfTheDay', () => {
124
116
 
125
117
  expect(BibleClient).toHaveBeenCalledTimes(1);
126
118
 
127
- currentAppId = 'new-app-id';
119
+ currentAppKey = 'new-app-key';
128
120
  rerender();
129
121
 
130
122
  expect(BibleClient).toHaveBeenCalledTimes(2);
@@ -134,7 +126,7 @@ describe('useVerseOfTheDay', () => {
134
126
  describe('fetching VOTD', () => {
135
127
  it('should fetch VOTD for day 1', async () => {
136
128
  const wrapper = createWrapper({
137
- appId: mockAppId,
129
+ appKey: mockAppKey,
138
130
  });
139
131
 
140
132
  const { result } = renderHook(() => useVerseOfTheDay(1), { wrapper });
@@ -155,7 +147,7 @@ describe('useVerseOfTheDay', () => {
155
147
  mockGetVOTD.mockResolvedValueOnce(mockVOTD100);
156
148
 
157
149
  const wrapper = createWrapper({
158
- appId: mockAppId,
150
+ appKey: mockAppKey,
159
151
  });
160
152
 
161
153
  const { result } = renderHook(() => useVerseOfTheDay(100), { wrapper });
@@ -173,7 +165,7 @@ describe('useVerseOfTheDay', () => {
173
165
  mockGetVOTD.mockResolvedValueOnce(mockVOTD366);
174
166
 
175
167
  const wrapper = createWrapper({
176
- appId: mockAppId,
168
+ appKey: mockAppKey,
177
169
  });
178
170
 
179
171
  const { result } = renderHook(() => useVerseOfTheDay(366), { wrapper });
@@ -188,7 +180,7 @@ describe('useVerseOfTheDay', () => {
188
180
 
189
181
  it('should refetch when day changes', async () => {
190
182
  const wrapper = createWrapper({
191
- appId: mockAppId,
183
+ appKey: mockAppKey,
192
184
  });
193
185
 
194
186
  const { result, rerender } = renderHook(({ day }) => useVerseOfTheDay(day), {
@@ -215,7 +207,7 @@ describe('useVerseOfTheDay', () => {
215
207
 
216
208
  it('should not fetch when enabled is false', async () => {
217
209
  const wrapper = createWrapper({
218
- appId: mockAppId,
210
+ appKey: mockAppKey,
219
211
  });
220
212
 
221
213
  const { result } = renderHook(() => useVerseOfTheDay(1, { enabled: false }), { wrapper });
@@ -233,7 +225,7 @@ describe('useVerseOfTheDay', () => {
233
225
  mockGetVOTD.mockRejectedValueOnce(error);
234
226
 
235
227
  const wrapper = createWrapper({
236
- appId: mockAppId,
228
+ appKey: mockAppKey,
237
229
  });
238
230
 
239
231
  const { result } = renderHook(() => useVerseOfTheDay(1), { wrapper });
@@ -248,7 +240,7 @@ describe('useVerseOfTheDay', () => {
248
240
 
249
241
  it('should support manual refetch', async () => {
250
242
  const wrapper = createWrapper({
251
- appId: mockAppId,
243
+ appKey: mockAppKey,
252
244
  });
253
245
 
254
246
  const { result } = renderHook(() => useVerseOfTheDay(1), { wrapper });