@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.
- package/build/contexts/chat_context.d.ts +4 -4
- package/build/contexts/chat_context.d.ts.map +1 -1
- package/build/contexts/chat_context.js +3 -3
- package/build/contexts/chat_context.js.map +1 -1
- package/build/hooks/use_api_client.d.ts.map +1 -1
- package/build/hooks/use_api_client.js +5 -3
- package/build/hooks/use_api_client.js.map +1 -1
- package/build/hooks/use_jolt.d.ts.map +1 -1
- package/build/hooks/use_jolt.js +7 -4
- package/build/hooks/use_jolt.js.map +1 -1
- package/build/navigation/index.d.ts +26 -10
- package/build/navigation/index.d.ts.map +1 -1
- package/build/navigation/index.js +5 -2
- package/build/navigation/index.js.map +1 -1
- package/build/screens/conversation_new/conversation_new_screen.d.ts +3 -0
- package/build/screens/conversation_new/conversation_new_screen.d.ts.map +1 -1
- package/build/screens/conversation_new/conversation_new_screen.js.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts +5 -2
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.d.ts.map +1 -1
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js +2 -1
- package/build/screens/conversation_select_recipients/conversation_select_recipients_screen.js.map +1 -1
- package/build/screens/conversations/conversations_screen.d.ts +2 -1
- package/build/screens/conversations/conversations_screen.d.ts.map +1 -1
- package/build/screens/conversations/conversations_screen.js +32 -1
- package/build/screens/conversations/conversations_screen.js.map +1 -1
- package/build/types/resources/oauth_token.d.ts +4 -4
- package/build/types/resources/oauth_token.d.ts.map +1 -1
- package/build/types/resources/oauth_token.js.map +1 -1
- package/build/utils/client/client.d.ts +4 -8
- package/build/utils/client/client.d.ts.map +1 -1
- package/build/utils/client/client.js +10 -9
- package/build/utils/client/client.js.map +1 -1
- package/build/utils/destructure_chat_group_graph_id.d.ts +10 -0
- package/build/utils/destructure_chat_group_graph_id.d.ts.map +1 -0
- package/build/utils/destructure_chat_group_graph_id.js +8 -0
- package/build/utils/destructure_chat_group_graph_id.js.map +1 -0
- package/build/utils/index.d.ts +1 -0
- package/build/utils/index.d.ts.map +1 -1
- package/build/utils/index.js +1 -0
- package/build/utils/index.js.map +1 -1
- package/build/utils/session.d.ts +6 -2
- package/build/utils/session.d.ts.map +1 -1
- package/build/utils/session.js +6 -1
- package/build/utils/session.js.map +1 -1
- package/build/utils/uri.d.ts +10 -2
- package/build/utils/uri.d.ts.map +1 -1
- package/build/utils/uri.js +24 -6
- package/build/utils/uri.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/hooks/useTheme.tsx +1 -1
- package/src/__tests__/{client.ts → utils/client.ts} +7 -115
- package/src/__tests__/{session.ts → utils/session.ts} +4 -4
- package/src/__tests__/utils/uri.ts +107 -0
- package/src/contexts/chat_context.tsx +7 -7
- package/src/hooks/use_api_client.ts +7 -3
- package/src/hooks/use_jolt.ts +9 -4
- package/src/navigation/index.tsx +10 -2
- package/src/screens/conversation_new/conversation_new_screen.tsx +3 -0
- package/src/screens/conversation_select_recipients/conversation_select_recipients_screen.tsx +8 -2
- package/src/screens/conversations/conversations_screen.tsx +37 -2
- package/src/types/resources/oauth_token.ts +4 -4
- package/src/utils/client/client.ts +13 -13
- package/src/utils/destructure_chat_group_graph_id.ts +25 -0
- package/src/utils/index.ts +1 -0
- package/src/utils/session.ts +10 -4
- 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
|
-
|
|
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
|
-
|
|
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
|
-
[
|
|
27
|
+
[uri, onUnauthorizedResponse]
|
|
24
28
|
)
|
|
25
29
|
|
|
26
30
|
return api
|
package/src/hooks/use_jolt.ts
CHANGED
|
@@ -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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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>>({
|
package/src/navigation/index.tsx
CHANGED
|
@@ -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) => {
|
package/src/screens/conversation_select_recipients/conversation_select_recipients_screen.tsx
CHANGED
|
@@ -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?:
|
|
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 = ({
|
|
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?:
|
|
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={
|
|
65
|
+
onPress={handleNewConversationNavigation}
|
|
31
66
|
/>
|
|
32
67
|
</View>
|
|
33
68
|
)
|
|
@@ -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
|
-
|
|
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 = {},
|
|
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.
|
|
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<
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
+
}
|
package/src/utils/index.ts
CHANGED
package/src/utils/session.ts
CHANGED
|
@@ -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
|
|
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
|
|
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 '
|
|
54
|
+
return 'test'
|
|
35
55
|
default:
|
|
36
|
-
return '
|
|
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
|
}
|