@planningcenter/chat-react-native 3.2.0-rc.14 → 3.2.0-rc.16

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.
Files changed (66) hide show
  1. package/build/contexts/chat_context.d.ts +4 -4
  2. package/build/contexts/chat_context.d.ts.map +1 -1
  3. package/build/contexts/chat_context.js +3 -3
  4. package/build/contexts/chat_context.js.map +1 -1
  5. package/build/hooks/use_api_client.d.ts.map +1 -1
  6. package/build/hooks/use_api_client.js +5 -3
  7. package/build/hooks/use_api_client.js.map +1 -1
  8. package/build/hooks/use_jolt.d.ts.map +1 -1
  9. package/build/hooks/use_jolt.js +7 -4
  10. package/build/hooks/use_jolt.js.map +1 -1
  11. package/build/navigation/index.d.ts +26 -10
  12. package/build/navigation/index.d.ts.map +1 -1
  13. package/build/navigation/index.js +5 -2
  14. package/build/navigation/index.js.map +1 -1
  15. package/build/screens/conversation_new/conversation_new_screen.d.ts +3 -0
  16. package/build/screens/conversation_new/conversation_new_screen.d.ts.map +1 -1
  17. package/build/screens/conversation_new/conversation_new_screen.js.map +1 -1
  18. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts +5 -2
  19. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts.map +1 -1
  20. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js +2 -1
  21. package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js.map +1 -1
  22. package/build/screens/conversations/conversations_screen.d.ts +2 -1
  23. package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
  24. package/build/screens/conversations/conversations_screen.js +32 -1
  25. package/build/screens/conversations/conversations_screen.js.map +1 -1
  26. package/build/types/resources/oauth_token.d.ts +4 -4
  27. package/build/types/resources/oauth_token.d.ts.map +1 -1
  28. package/build/types/resources/oauth_token.js.map +1 -1
  29. package/build/utils/client/client.d.ts +4 -8
  30. package/build/utils/client/client.d.ts.map +1 -1
  31. package/build/utils/client/client.js +10 -9
  32. package/build/utils/client/client.js.map +1 -1
  33. package/build/utils/destructure_chat_group_graph_id.d.ts +10 -0
  34. package/build/utils/destructure_chat_group_graph_id.d.ts.map +1 -0
  35. package/build/utils/destructure_chat_group_graph_id.js +8 -0
  36. package/build/utils/destructure_chat_group_graph_id.js.map +1 -0
  37. package/build/utils/index.d.ts +1 -0
  38. package/build/utils/index.d.ts.map +1 -1
  39. package/build/utils/index.js +1 -0
  40. package/build/utils/index.js.map +1 -1
  41. package/build/utils/session.d.ts +6 -2
  42. package/build/utils/session.d.ts.map +1 -1
  43. package/build/utils/session.js +6 -1
  44. package/build/utils/session.js.map +1 -1
  45. package/build/utils/uri.d.ts +10 -2
  46. package/build/utils/uri.d.ts.map +1 -1
  47. package/build/utils/uri.js +24 -6
  48. package/build/utils/uri.js.map +1 -1
  49. package/package.json +2 -2
  50. package/src/__tests__/hooks/useTheme.tsx +1 -1
  51. package/src/__tests__/{client.ts → utils/client.ts} +7 -115
  52. package/src/__tests__/{session.ts → utils/session.ts} +4 -4
  53. package/src/__tests__/utils/uri.ts +107 -0
  54. package/src/contexts/chat_context.tsx +7 -7
  55. package/src/hooks/use_api_client.ts +7 -3
  56. package/src/hooks/use_jolt.ts +9 -4
  57. package/src/navigation/index.tsx +10 -2
  58. package/src/screens/conversation_new/conversation_new_screen.tsx +3 -0
  59. package/src/screens/conversation_select_recipients/conversation_select_recipients_screen.tsx +8 -2
  60. package/src/screens/conversations/conversations_screen.tsx +37 -2
  61. package/src/types/resources/oauth_token.ts +4 -4
  62. package/src/utils/client/client.ts +13 -13
  63. package/src/utils/destructure_chat_group_graph_id.ts +25 -0
  64. package/src/utils/index.ts +1 -0
  65. package/src/utils/session.ts +10 -4
  66. package/src/utils/uri.ts +30 -6
@@ -0,0 +1,107 @@
1
+ import { Uri } from '../../utils'
2
+
3
+ describe('URI', () => {
4
+ it('should be defined', () => {
5
+ expect(Uri).toBeDefined()
6
+ })
7
+
8
+ it('should create a new instance', () => {
9
+ const uri = new Uri({
10
+ session: {
11
+ env: 'production',
12
+ token: undefined,
13
+ type: 'OAuth',
14
+ isAuthenticated: false,
15
+ isChurchCenterToken: false,
16
+ },
17
+ })
18
+ expect(uri).toBeDefined()
19
+ })
20
+
21
+ describe('baseUrl', () => {
22
+ describe('planning center', () => {
23
+ it('should return the correct base URL for production', () => {
24
+ const uri = new Uri({
25
+ session: {
26
+ env: 'production',
27
+ token: undefined,
28
+ type: 'OAuth',
29
+ isAuthenticated: false,
30
+ isChurchCenterToken: false,
31
+ },
32
+ })
33
+ expect(uri.baseUrl).toBe('https://api.planningcenteronline.com')
34
+ })
35
+
36
+ it('should return the correct base URL for staging', () => {
37
+ const uri = new Uri({
38
+ session: {
39
+ env: 'staging',
40
+ token: undefined,
41
+ type: 'OAuth',
42
+ isAuthenticated: false,
43
+ isChurchCenterToken: false,
44
+ },
45
+ })
46
+ expect(uri.baseUrl).toBe('https://api-staging.planningcenteronline.com')
47
+ })
48
+
49
+ it('should return the correct base URL for development', () => {
50
+ const uri = new Uri({
51
+ session: {
52
+ env: 'development',
53
+ token: undefined,
54
+ type: 'OAuth',
55
+ isAuthenticated: false,
56
+ isChurchCenterToken: false,
57
+ },
58
+ })
59
+ expect(uri.baseUrl).toBe('http://api.pco.test')
60
+ })
61
+ })
62
+
63
+ describe('church center', () => {
64
+ it('should return the correct base URL for production', () => {
65
+ const uri = new Uri({
66
+ session: {
67
+ env: 'production',
68
+ token: undefined,
69
+ type: 'ChurchCenterOauth',
70
+ isAuthenticated: false,
71
+ isChurchCenterToken: true,
72
+ },
73
+ graph: 'churchcenter',
74
+ })
75
+ expect(uri.baseUrl).toBe('https://api.churchcenter.com')
76
+ })
77
+
78
+ it('should return the correct base URL for staging', () => {
79
+ const uri = new Uri({
80
+ session: {
81
+ env: 'staging',
82
+ token: undefined,
83
+ type: 'ChurchCenterOauth',
84
+ isAuthenticated: false,
85
+ isChurchCenterToken: true,
86
+ },
87
+ graph: 'churchcenter',
88
+ })
89
+ expect(uri.baseUrl).toBe('https://api.staging.churchcenter.com')
90
+ })
91
+
92
+ it('should return the correct base URL for development', () => {
93
+ const uri = new Uri({
94
+ session: {
95
+ env: 'development',
96
+ token: undefined,
97
+ type: 'ChurchCenterOauth',
98
+ isAuthenticated: false,
99
+ isChurchCenterToken: true,
100
+ },
101
+ graph: 'churchcenter',
102
+ })
103
+ expect(uri.baseUrl).toBe('http://api.churchcenter.test')
104
+ })
105
+ })
106
+ })
107
+ })
@@ -6,12 +6,12 @@ import { ENV, PartialToken, ResponseError, Session } from '../utils'
6
6
  import { ChatTheme, defaultTheme, DefaultTheme } from '../utils/theme'
7
7
 
8
8
  export type ChatContextValue = {
9
- token?: PartialToken
10
- onUnauthorizedResponse: (_response: ResponseError) => void
11
- theme: ChatTheme
12
9
  env?: ENV
13
- session: Session
14
10
  giphyApiKey?: string
11
+ onUnauthorizedResponse: (_response: ResponseError) => void
12
+ session: Session
13
+ theme: ChatTheme
14
+ token?: PartialToken
15
15
  }
16
16
 
17
17
  export interface ChatProviderProps extends Omit<ChatContextValue, 'client' | 'theme' | 'session'> {
@@ -19,12 +19,12 @@ export interface ChatProviderProps extends Omit<ChatContextValue, 'client' | 'th
19
19
  }
20
20
 
21
21
  export const ChatContext = createContext<ChatContextValue>({
22
- theme: defaultTheme('light'),
23
- token: undefined,
24
22
  env: undefined,
23
+ giphyApiKey: undefined,
25
24
  onUnauthorizedResponse: () => {},
26
25
  session: new Session(),
27
- giphyApiKey: undefined,
26
+ theme: defaultTheme('light'),
27
+ token: undefined,
28
28
  })
29
29
 
30
30
  export function ChatProvider({ children, value }: { children: any; value: ChatProviderProps }) {
@@ -1,6 +1,7 @@
1
1
  import { useContext, useMemo } from 'react'
2
2
  import { ChatContext } from '../contexts/chat_context'
3
3
  import { Client } from '../utils/client'
4
+ import { Uri } from '../utils'
4
5
 
5
6
  export type App = 'chat' | 'groups' | 'services'
6
7
  const apps: App[] = ['chat', 'groups', 'services']
@@ -9,18 +10,21 @@ export type ApiClient = { [_K in App]: Client }
9
10
 
10
11
  export const useApiClient = () => {
11
12
  const { session, onUnauthorizedResponse } = useContext(ChatContext)
13
+
14
+ const uri = useMemo(() => new Uri({ session }), [session])
15
+
12
16
  const api = useMemo(
13
17
  () =>
14
18
  apps.reduce((acc, app) => {
15
19
  acc[app] = new Client({
16
- app,
17
- session,
20
+ root: uri.api(`/${app}/v2`),
21
+ defaultHeaders: uri.headers,
18
22
  version: '2018-11-01',
19
23
  onUnauthorizedResponse,
20
24
  })
21
25
  return acc
22
26
  }, {} as ApiClient),
23
- [session, onUnauthorizedResponse]
27
+ [uri, onUnauthorizedResponse]
24
28
  )
25
29
 
26
30
  return api
@@ -11,7 +11,7 @@ import { useQuery, useQueryClient, useSuspenseQuery } from '@tanstack/react-quer
11
11
  import { useEffect, useMemo, useState } from 'react'
12
12
  import { useChatContext } from '../contexts/chat_context'
13
13
  import { ApiResource } from '../types'
14
- import { Client } from '../utils'
14
+ import { Client, Uri } from '../utils'
15
15
 
16
16
  interface JoltResponse {
17
17
  type: 'JoltToken'
@@ -22,10 +22,15 @@ interface JoltResponse {
22
22
  export const useJoltClient = (): JoltClient | undefined => {
23
23
  const { session } = useChatContext()
24
24
  const queryClient = useQueryClient()
25
+ const uri = useMemo(() => new Uri({ session }), [session])
25
26
  const apiClient = useMemo(
26
- // Client that does not relay 401 errors
27
- () => new Client({ app: 'chat', session, version: '2018-11-01' }),
28
- [session]
27
+ () =>
28
+ new Client({
29
+ root: uri.api(`/chat/v2`),
30
+ defaultHeaders: uri.headers,
31
+ version: '2018-11-01',
32
+ }),
33
+ [uri]
29
34
  )
30
35
 
31
36
  const { data: joltToken } = useSuspenseQuery<ApiResource<JoltResponse>>({
@@ -54,10 +54,18 @@ export const NewConversationStack = createNativeStackNavigator({
54
54
  },
55
55
  ConversationNew: {
56
56
  screen: ConversationNewScreen,
57
- options: {
57
+ options: ({ navigation, route }) => ({
58
58
  title: 'New conversation',
59
59
  headerLeft: () => null,
60
- },
60
+ headerRight: (props: NativeStackHeaderRightProps) => (
61
+ <HeaderRightButton
62
+ {...props}
63
+ onPress={() => navigation.popTo('Conversations', route.params)}
64
+ >
65
+ Cancel
66
+ </HeaderRightButton>
67
+ ),
68
+ }),
61
69
  },
62
70
  },
63
71
  })
@@ -4,12 +4,15 @@ import { GroupsForm } from './components/groups_form'
4
4
  import { TeamsForm } from './components/team_form'
5
5
  import { SourceAppErrorCard } from './components/source_app_error_card'
6
6
  import { AppName } from '../../types/resources/app_name'
7
+ import { GraphId } from '../../types/resources/group_resource'
7
8
 
8
9
  type ConversationNewScreenProps = StaticScreenProps<{
9
10
  group_id?: number
10
11
  team_ids?: number[]
11
12
  plan_id?: number
12
13
  source_app_name: AppName
14
+ chat_group_graph_id?: GraphId
15
+ group_source_app_name?: AppName
13
16
  }>
14
17
 
15
18
  export const ConversationNewScreen = ({ route }: ConversationNewScreenProps) => {
@@ -7,17 +7,22 @@ import { Button, Heading, Icon, Image, Text } from '../../components'
7
7
  import { useTheme } from '../../hooks'
8
8
  import { GroupsGroupResource } from '../../types'
9
9
  import { useGroupsGroups } from '../../hooks/use_groups_groups'
10
+ import { GraphId } from '../../types/resources/group_resource'
11
+ import { AppName } from '../../types/resources/app_name'
10
12
  import { platformFontWeightMedium, pluralize } from '../../utils'
11
13
 
12
14
  type ConversationSelectRecipientsScreenProps = StaticScreenProps<{
13
- chat_group_graph_id?: string
15
+ chat_group_graph_id?: GraphId
16
+ group_source_app_name?: AppName
14
17
  }>
15
18
 
16
19
  const ASPECT_RATIO = 16 / 9
17
20
  const THUMBNAIL_WIDTH = 80
18
21
  const THUMBNAIL_HEIGHT = THUMBNAIL_WIDTH / ASPECT_RATIO
19
22
 
20
- export const ConversationSelectRecipientsScreen = ({}: ConversationSelectRecipientsScreenProps) => {
23
+ export const ConversationSelectRecipientsScreen = ({
24
+ route,
25
+ }: ConversationSelectRecipientsScreenProps) => {
21
26
  const styles = useStyles()
22
27
  const navigation = useNavigation()
23
28
  const { data: groups = [] } = useGroupsGroups()
@@ -29,6 +34,7 @@ export const ConversationSelectRecipientsScreen = ({}: ConversationSelectRecipie
29
34
  params: {
30
35
  group_id: group.id,
31
36
  source_app_name: 'Groups',
37
+ ...route.params,
32
38
  },
33
39
  })
34
40
  }
@@ -6,12 +6,14 @@ import { ActionButton } from '../../components/display/action_button'
6
6
  import { ConversationsContextProvider } from '../../contexts/conversations_context'
7
7
  import { useCanCreateConversations } from '../../hooks'
8
8
  import { GraphId } from '../../types/resources/group_resource'
9
+ import { destructureChatGroupGraphId } from '../../utils'
9
10
  import { ListHeaderComponent } from './components/list_header_component'
11
+ import { AppName } from '../../types/resources/app_name'
10
12
 
11
13
  export type ConversationScreenProps = StaticScreenProps<{
12
14
  title?: string
13
15
  chat_group_graph_id?: GraphId
14
- group_source_app_name?: string
16
+ group_source_app_name?: AppName
15
17
  }>
16
18
 
17
19
  export function ConversationsScreen({ route }: ConversationScreenProps) {
@@ -19,6 +21,39 @@ export function ConversationsScreen({ route }: ConversationScreenProps) {
19
21
  const canCreateConversations = useCanCreateConversations()
20
22
  const styles = useStyles()
21
23
 
24
+ const { chat_group_graph_id } = route.params
25
+ const { sourceAppName, sourceId } = destructureChatGroupGraphId(chat_group_graph_id)
26
+
27
+ const handleNewConversationNavigation = () => {
28
+ if (sourceAppName === 'Services') {
29
+ return navigation.navigate('New', {
30
+ screen: 'ConversationNew',
31
+ params: {
32
+ team_ids: sourceId ? [sourceId] : [],
33
+ source_app_name: sourceAppName,
34
+ ...route.params,
35
+ },
36
+ })
37
+ }
38
+ if (sourceAppName === 'Groups') {
39
+ return navigation.navigate('New', {
40
+ screen: 'ConversationNew',
41
+ params: {
42
+ group_id: sourceId,
43
+ source_app_name: sourceAppName,
44
+ ...route.params,
45
+ },
46
+ })
47
+ }
48
+
49
+ return navigation.navigate('New', {
50
+ screen: 'ConversationSelectRecipients',
51
+ params: {
52
+ ...route.params,
53
+ },
54
+ })
55
+ }
56
+
22
57
  return (
23
58
  <View style={styles.container}>
24
59
  <ConversationsContextProvider args={route.params}>
@@ -27,7 +62,7 @@ export function ConversationsScreen({ route }: ConversationScreenProps) {
27
62
  <ActionButton
28
63
  visible={canCreateConversations}
29
64
  title="New conversation"
30
- onPress={() => navigation.navigate('New')}
65
+ onPress={handleNewConversationNavigation}
31
66
  />
32
67
  </View>
33
68
  )
@@ -1,8 +1,8 @@
1
1
  export type OAuthToken = {
2
- token_type: any
3
- access_token: any
2
+ token_type: string
3
+ access_token: string
4
4
  created_at: number
5
- expires_in: any
5
+ expires_in: number
6
6
  scope: string
7
- refresh_token: any
7
+ refresh_token: string
8
8
  }
@@ -1,6 +1,4 @@
1
1
  import { ApiCollection, ApiError, ApiResource } from '../../types'
2
- import { Session } from '../session'
3
- import { Uri } from '../uri'
4
2
  import {
5
3
  concatRecords,
6
4
  ensureNoQueryParamsInDev,
@@ -22,28 +20,27 @@ type ClientArgs = {
22
20
  version: string
23
21
  defaultHeaders?: Record<string, string>
24
22
  onUnauthorizedResponse?: OnUnauthorizedResponse
25
- session: Session
26
- app: string
23
+ root?: string
27
24
  }
28
25
 
29
26
  export class Client {
30
27
  version: string = ''
31
28
  defaultHeaders: Record<string, string> = {}
32
- uri: Uri
33
29
  onUnauthorizedResponse?: OnUnauthorizedResponse
30
+ root?: string
34
31
 
35
- constructor({ version, defaultHeaders = {}, session, app, onUnauthorizedResponse }: ClientArgs) {
32
+ constructor({ version, defaultHeaders = {}, onUnauthorizedResponse, root }: ClientArgs) {
36
33
  this.version = version
37
- this.uri = new Uri({ session, app })
38
34
  this.defaultHeaders = defaultHeaders
39
35
  this.onUnauthorizedResponse = onUnauthorizedResponse
36
+ this.root = root
40
37
  }
41
38
 
42
39
  async get<T extends ApiCollection | ApiResource>(args: GetRequest): Promise<T> {
43
40
  const { walk, ...data } = args.data
44
41
  const isWalking = Boolean(walk)
45
42
  const headers = { ...this.headers, ...args.headers }
46
- const url = this.uri.appUrl(args.url)
43
+ const url = this.appUrl(args.url)
47
44
 
48
45
  await throwErrorIfQueryParams(url)
49
46
 
@@ -54,7 +51,7 @@ export class Client {
54
51
  data: d = { fields: {} },
55
52
  acc = { data: [], included: [], meta: {}, links: {} },
56
53
  ...options
57
- }: WalkRequest): Promise<ApiCollection | ApiResource> => {
54
+ }: WalkRequest): Promise<T> => {
58
55
  return makeRequest({
59
56
  action: 'GET',
60
57
  data: d,
@@ -84,7 +81,7 @@ export class Client {
84
81
 
85
82
  async patch<T extends ApiCollection | ApiResource>(args: PatchRequest): Promise<T> {
86
83
  const headers = { ...this.headers, ...args.headers }
87
- const url = this.uri.appUrl(args.url)
84
+ const url = this.appUrl(args.url)
88
85
 
89
86
  const requestArgs: MakeRequestArgs = { data: args.data, url, action: 'PATCH', headers }
90
87
 
@@ -95,7 +92,7 @@ export class Client {
95
92
 
96
93
  async post<T extends ApiCollection | ApiResource>(args: PostRequest): Promise<T> {
97
94
  const headers = { ...this.headers, ...args.headers }
98
- const url = this.uri.appUrl(args.url)
95
+ const url = this.appUrl(args.url)
99
96
 
100
97
  const requestArgs: MakeRequestArgs = { ...args, data: args.data, url, action: 'POST', headers }
101
98
 
@@ -106,7 +103,7 @@ export class Client {
106
103
 
107
104
  async delete(args: DeleteRequest) {
108
105
  const headers = { ...this.headers, ...args.headers }
109
- const url = this.uri.appUrl(args.url)
106
+ const url = this.appUrl(args.url)
110
107
 
111
108
  const requestArgs: MakeRequestArgs = { url, action: 'DELETE', headers }
112
109
 
@@ -133,12 +130,15 @@ export class Client {
133
130
  }
134
131
  }
135
132
 
133
+ appUrl(url: string) {
134
+ return `${this.root}${url}`
135
+ }
136
+
136
137
  get headers() {
137
138
  return {
138
139
  Accept: 'application/vnd.api+json',
139
140
  'Content-Type': 'application/json',
140
141
  'X-PCO-API-Version': this.version,
141
- ...this.uri.headers,
142
142
  ...this.defaultHeaders,
143
143
  }
144
144
  }
@@ -0,0 +1,25 @@
1
+ import { AppName } from '../types/resources/app_name'
2
+ import { SourceType, GraphId } from '../types/resources/group_resource'
3
+
4
+ interface DestructuredChatGroupGraphIdType {
5
+ sourceAppName?: AppName
6
+ sourceType?: SourceType
7
+ sourceId?: number
8
+ }
9
+
10
+ export function destructureChatGroupGraphId(
11
+ chatGroupGraphId?: GraphId
12
+ ): DestructuredChatGroupGraphIdType {
13
+ if (!chatGroupGraphId)
14
+ return { sourceAppName: undefined, sourceType: undefined, sourceId: undefined }
15
+
16
+ const [sourceAppName, sourceType, sourceIdString] = chatGroupGraphId.split('-') as [
17
+ AppName,
18
+ SourceType,
19
+ string,
20
+ ]
21
+
22
+ const sourceIdNumber = Number(sourceIdString)
23
+
24
+ return { sourceAppName, sourceType, sourceId: sourceIdNumber }
25
+ }
@@ -7,3 +7,4 @@ export * from './uri'
7
7
  export * from './cache'
8
8
  export * from './native_adapters'
9
9
  export * from './pluralize'
10
+ export * from './destructure_chat_group_graph_id'
@@ -1,28 +1,34 @@
1
1
  import { OAuthToken } from '../types'
2
2
 
3
3
  export type ENV = 'production' | 'staging' | 'development'
4
-
4
+ export type OauthType = 'OAuth' | 'ChurchCenterOauth'
5
5
  export type PartialToken = Pick<OAuthToken, 'access_token'> & Partial<OAuthToken>
6
- export type SessionProps<T = PartialToken> = { env?: ENV; token?: T }
6
+ export type SessionProps<T extends PartialToken> = { env?: ENV; token?: T; type?: OauthType }
7
7
 
8
8
  /**
9
9
  * Session class to track the environment and token
10
10
  * Not intended to make network requests or handle authentication
11
11
  */
12
- export class Session<T = PartialToken> {
12
+ export class Session<T extends PartialToken = PartialToken> {
13
13
  env: ENV
14
14
  token: T | undefined
15
+ type: OauthType
15
16
 
16
17
  constructor(props?: SessionProps<T>) {
17
- const { env = 'production', token } = props || {}
18
+ const { env = 'production', token, type } = props || {}
18
19
  this.env = env
19
20
  this.token = token
21
+ this.type = type || 'OAuth'
20
22
  }
21
23
 
22
24
  get isAuthenticated() {
23
25
  return Boolean(this.token)
24
26
  }
25
27
 
28
+ get isChurchCenterToken() {
29
+ return this.type === 'ChurchCenterOauth'
30
+ }
31
+
26
32
  toString() {
27
33
  return JSON.stringify({ env: this.env, token: this.token })
28
34
  }
package/src/utils/uri.ts CHANGED
@@ -7,13 +7,16 @@ const systemVersion = DeviceInfo.getSystemVersion()
7
7
  const readableVersion = DeviceInfo.getReadableVersion()
8
8
  const appName = DeviceInfo.getApplicationName()
9
9
 
10
+ type Graph = 'churchcenter' | 'planningcenter'
10
11
  export class Uri {
11
12
  session: Session
13
+ graph: Graph = 'planningcenter'
12
14
  app?: string
13
15
 
14
- constructor({ session, app }: { session: Session; app?: string }) {
16
+ constructor({ session, app, graph }: { session: Session; app?: string; graph?: Graph }) {
15
17
  this.session = session
16
18
  this.app = app
19
+ this.graph = graph || 'planningcenter'
17
20
  }
18
21
 
19
22
  get schema() {
@@ -25,18 +28,39 @@ export class Uri {
25
28
  }
26
29
 
27
30
  get host() {
31
+ return `${this.subdomain}.${this.domain}.${this.tld}`
32
+ }
33
+
34
+ get subdomain() {
28
35
  switch (this.env) {
29
- case 'production':
30
- return 'api.planningcenteronline.com'
31
36
  case 'staging':
32
- return 'api-staging.planningcenteronline.com'
37
+ return this.isChurchCenter ? 'api.staging' : 'api-staging'
38
+ default:
39
+ return 'api'
40
+ }
41
+ }
42
+
43
+ get domain(): 'pco' | 'planningcenteronline' | 'churchcenter' {
44
+ if (this.isChurchCenter) {
45
+ return 'churchcenter'
46
+ }
47
+
48
+ return this.env === 'development' ? 'pco' : 'planningcenteronline'
49
+ }
50
+
51
+ get tld() {
52
+ switch (this.env) {
33
53
  case 'development':
34
- return 'api.pco.test'
54
+ return 'test'
35
55
  default:
36
- return 'api.planningcenteronline.com'
56
+ return 'com'
37
57
  }
38
58
  }
39
59
 
60
+ get isChurchCenter() {
61
+ return this.session.isChurchCenterToken
62
+ }
63
+
40
64
  get env() {
41
65
  return this.session?.env || 'production'
42
66
  }