@planningcenter/chat-react-native 2.3.0-rc.2 → 3.0.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/contexts/chat_context.d.ts +2 -3
- package/build/contexts/chat_context.d.ts.map +1 -1
- package/build/contexts/chat_context.js +3 -5
- package/build/contexts/chat_context.js.map +1 -1
- package/build/hooks/use_api_client.js +3 -3
- package/build/hooks/use_api_client.js.map +1 -1
- package/build/index.d.ts +3 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -1
- package/build/index.js.map +1 -1
- package/build/utils/client/client.d.ts +8 -6
- package/build/utils/client/client.d.ts.map +1 -1
- package/build/utils/client/client.js +9 -12
- package/build/utils/client/client.js.map +1 -1
- package/build/utils/session.d.ts +7 -7
- package/build/utils/session.d.ts.map +1 -1
- package/build/utils/session.js.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/client.ts +5 -21
- package/src/contexts/chat_context.tsx +5 -8
- package/src/hooks/use_api_client.ts +3 -3
- package/src/index.tsx +4 -1
- package/src/utils/client/client.ts +18 -23
- package/src/utils/session.ts +7 -7
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ColorSchemeName } from 'react-native';
|
|
3
3
|
import { DeepPartial } from '../types';
|
|
4
|
-
import { ENV, PartialToken, Session } from '../utils';
|
|
4
|
+
import { ENV, PartialToken, ResponseError, Session } from '../utils';
|
|
5
5
|
import { ChatTheme, DefaultTheme } from '../utils/theme';
|
|
6
6
|
export type ChatContextValue = {
|
|
7
7
|
token?: PartialToken;
|
|
8
|
-
|
|
9
|
-
onTokenExpired: () => void;
|
|
8
|
+
onUnauthorizedResponse: (_response: ResponseError) => void;
|
|
10
9
|
theme: ChatTheme;
|
|
11
10
|
env?: ENV;
|
|
12
11
|
session: Session;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat_context.d.ts","sourceRoot":"","sources":["../../src/contexts/chat_context.tsx"],"names":[],"mappings":"AACA,OAAO,KAAiC,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,eAAe,EAAkB,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;
|
|
1
|
+
{"version":3,"file":"chat_context.d.ts","sourceRoot":"","sources":["../../src/contexts/chat_context.tsx"],"names":[],"mappings":"AACA,OAAO,KAAiC,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,eAAe,EAAkB,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AACtC,OAAO,EAAE,GAAG,EAAE,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,EAAE,SAAS,EAAgB,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAEtE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB,sBAAsB,EAAE,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI,CAAA;IAC1D,KAAK,EAAE,SAAS,CAAA;IAChB,GAAG,CAAC,EAAE,GAAG,CAAA;IACT,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,gBAAgB,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;IAC/F,KAAK,EAAE,oBAAoB,CAAA;CAC5B;AAED,eAAO,MAAM,WAAW,iCAMtB,CAAA;AAEF,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE,iBAAiB,CAAA;CAAE,qBAc5F;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAA;IACjC,WAAW,CAAC,EAAE,eAAe,CAAA;CAC9B;AAED,eAAO,MAAM,kBAAkB,yDAG5B,oBAAoB,KAAG,SAYzB,CAAA"}
|
|
@@ -7,19 +7,17 @@ export const ChatContext = createContext({
|
|
|
7
7
|
theme: defaultTheme('light'),
|
|
8
8
|
token: undefined,
|
|
9
9
|
env: undefined,
|
|
10
|
-
|
|
11
|
-
onTokenExpired: () => { },
|
|
10
|
+
onUnauthorizedResponse: () => { },
|
|
12
11
|
session: new Session(),
|
|
13
12
|
});
|
|
14
13
|
export function ChatProvider({ children, value }) {
|
|
15
|
-
const { env, token,
|
|
14
|
+
const { env, token, onUnauthorizedResponse } = value;
|
|
16
15
|
const theme = useCreateChatTheme(value.theme || {});
|
|
17
16
|
const session = useMemo(() => new Session({ token, env }), [env, token]);
|
|
18
17
|
const contextValue = {
|
|
19
18
|
env,
|
|
20
19
|
token,
|
|
21
|
-
|
|
22
|
-
onForceLogout,
|
|
20
|
+
onUnauthorizedResponse,
|
|
23
21
|
session,
|
|
24
22
|
theme,
|
|
25
23
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat_context.js","sourceRoot":"","sources":["../../src/contexts/chat_context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9B,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAmB,cAAc,EAAE,MAAM,cAAc,CAAA;AAE9D,OAAO,
|
|
1
|
+
{"version":3,"file":"chat_context.js","sourceRoot":"","sources":["../../src/contexts/chat_context.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9B,OAAO,KAAK,EAAE,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAmB,cAAc,EAAE,MAAM,cAAc,CAAA;AAE9D,OAAO,EAAoC,OAAO,EAAE,MAAM,UAAU,CAAA;AACpE,OAAO,EAAa,YAAY,EAAgB,MAAM,gBAAgB,CAAA;AActE,MAAM,CAAC,MAAM,WAAW,GAAG,aAAa,CAAmB;IACzD,KAAK,EAAE,YAAY,CAAC,OAAO,CAAC;IAC5B,KAAK,EAAE,SAAS;IAChB,GAAG,EAAE,SAAS;IACd,sBAAsB,EAAE,GAAG,EAAE,GAAE,CAAC;IAChC,OAAO,EAAE,IAAI,OAAO,EAAE;CACvB,CAAC,CAAA;AAEF,MAAM,UAAU,YAAY,CAAC,EAAE,QAAQ,EAAE,KAAK,EAA+C;IAC3F,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,sBAAsB,EAAE,GAAG,KAAK,CAAA;IACpD,MAAM,KAAK,GAAG,kBAAkB,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC,CAAA;IACnD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAA;IAExE,MAAM,YAAY,GAAqB;QACrC,GAAG;QACH,KAAK;QACL,sBAAsB;QACtB,OAAO;QACP,KAAK;KACN,CAAA;IAED,OAAO,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAA;AACrF,CAAC;AAOD,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EACjC,KAAK,EAAE,WAAW,GAAG,EAAE,EACvB,WAAW,EAAE,cAAc,GACN,EAAa,EAAE;IACpC,MAAM,mBAAmB,GAAG,cAAc,EAAE,IAAI,OAAO,CAAA;IACvD,MAAM,WAAW,GAAG,cAAc,IAAI,mBAAmB,CAAA;IAEzD,MAAM,KAAK,GAAG;QACZ,GAAG,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,WAAW,CAAC,EAAE,WAAW,CAAC;QACpD,MAAM,EAAE;YACN,GAAG,KAAK,CAAC,EAAE,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC;SACpE;KACF,CAAA;IAED,OAAO,KAAK,CAAA;AACd,CAAC,CAAA","sourcesContent":["import { merge } from 'lodash'\nimport React, { createContext, useMemo } from 'react'\nimport { ColorSchemeName, useColorScheme } from 'react-native'\nimport { DeepPartial } from '../types'\nimport { ENV, PartialToken, ResponseError, Session } from '../utils'\nimport { ChatTheme, defaultTheme, DefaultTheme } from '../utils/theme'\n\nexport type ChatContextValue = {\n token?: PartialToken\n onUnauthorizedResponse: (_response: ResponseError) => void\n theme: ChatTheme\n env?: ENV\n session: Session\n}\n\nexport interface ChatProviderProps extends Omit<ChatContextValue, 'client' | 'theme' | 'session'> {\n theme: CreateChatThemeProps\n}\n\nexport const ChatContext = createContext<ChatContextValue>({\n theme: defaultTheme('light'),\n token: undefined,\n env: undefined,\n onUnauthorizedResponse: () => {},\n session: new Session(),\n})\n\nexport function ChatProvider({ children, value }: { children: any; value: ChatProviderProps }) {\n const { env, token, onUnauthorizedResponse } = value\n const theme = useCreateChatTheme(value.theme || {})\n const session = useMemo(() => new Session({ token, env }), [env, token])\n\n const contextValue: ChatContextValue = {\n env,\n token,\n onUnauthorizedResponse,\n session,\n theme,\n }\n\n return <ChatContext.Provider value={contextValue}>{children}</ChatContext.Provider>\n}\n\nexport interface CreateChatThemeProps {\n theme?: DeepPartial<DefaultTheme>\n colorScheme?: ColorSchemeName\n}\n\nexport const useCreateChatTheme = ({\n theme: customTheme = {},\n colorScheme: appColorScheme,\n}: CreateChatThemeProps): ChatTheme => {\n const internalColorScheme = useColorScheme() || 'light'\n const colorScheme = appColorScheme || internalColorScheme\n\n const theme = {\n ...merge({}, defaultTheme(colorScheme), customTheme),\n colors: {\n ...merge({}, defaultTheme(colorScheme).colors, customTheme?.colors),\n },\n }\n\n return theme\n}\n"]}
|
|
@@ -3,16 +3,16 @@ import { ChatContext } from '../contexts/chat_context';
|
|
|
3
3
|
import { Client } from '../utils/client';
|
|
4
4
|
const apps = ['chat', 'groups', 'services'];
|
|
5
5
|
export const useApiClient = () => {
|
|
6
|
-
const { session,
|
|
6
|
+
const { session, onUnauthorizedResponse } = useContext(ChatContext);
|
|
7
7
|
const api = useMemo(() => apps.reduce((acc, app) => {
|
|
8
8
|
acc[app] = new Client({
|
|
9
9
|
app,
|
|
10
10
|
session,
|
|
11
11
|
version: '2018-11-01',
|
|
12
|
-
|
|
12
|
+
onUnauthorizedResponse,
|
|
13
13
|
});
|
|
14
14
|
return acc;
|
|
15
|
-
}, {}), [session,
|
|
15
|
+
}, {}), [session, onUnauthorizedResponse]);
|
|
16
16
|
return api;
|
|
17
17
|
};
|
|
18
18
|
//# sourceMappingURL=use_api_client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use_api_client.js","sourceRoot":"","sources":["../../src/hooks/use_api_client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAGxC,MAAM,IAAI,GAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;AAIlD,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE;IAC/B,MAAM,EAAE,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"use_api_client.js","sourceRoot":"","sources":["../../src/hooks/use_api_client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AAGxC,MAAM,IAAI,GAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAA;AAIlD,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,EAAE;IAC/B,MAAM,EAAE,OAAO,EAAE,sBAAsB,EAAE,GAAG,UAAU,CAAC,WAAW,CAAC,CAAA;IACnE,MAAM,GAAG,GAAG,OAAO,CACjB,GAAG,EAAE,CACH,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QACvB,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,MAAM,CAAC;YACpB,GAAG;YACH,OAAO;YACP,OAAO,EAAE,YAAY;YACrB,sBAAsB;SACvB,CAAC,CAAA;QACF,OAAO,GAAG,CAAA;IACZ,CAAC,EAAE,EAAe,CAAC,EACrB,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAClC,CAAA;IAED,OAAO,GAAG,CAAA;AACZ,CAAC,CAAA","sourcesContent":["import { useContext, useMemo } from 'react'\nimport { ChatContext } from '../contexts/chat_context'\nimport { Client } from '../utils/client'\n\ntype App = 'chat' | 'groups' | 'services'\nconst apps: App[] = ['chat', 'groups', 'services']\n\nexport type ApiClient = { [_K in App]: Client }\n\nexport const useApiClient = () => {\n const { session, onUnauthorizedResponse } = useContext(ChatContext)\n const api = useMemo(\n () =>\n apps.reduce((acc, app) => {\n acc[app] = new Client({\n app,\n session,\n version: '2018-11-01',\n onUnauthorizedResponse,\n })\n return acc\n }, {} as ApiClient),\n [session, onUnauthorizedResponse]\n )\n\n return api\n}\n"]}
|
package/build/index.d.ts
CHANGED
|
@@ -2,5 +2,7 @@ export * from './contexts/chat_context';
|
|
|
2
2
|
export { ApiProvider } from './contexts/api_provider';
|
|
3
3
|
export { DesignSystemScreen } from './screens';
|
|
4
4
|
export * from './navigation';
|
|
5
|
-
export
|
|
5
|
+
export * from './types';
|
|
6
|
+
export * from './utils/client';
|
|
7
|
+
export { TemporaryDefaultColorsType, ChatAdapters, ClipboardAdapter, Session, platformFontWeightBold, } from './utils';
|
|
6
8
|
//# sourceMappingURL=index.d.ts.map
|
package/build/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAC9C,cAAc,cAAc,CAAA;AAC5B,OAAO,EACL,0BAA0B,EAC1B,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAC9C,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAE9B,OAAO,EACL,0BAA0B,EAC1B,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,sBAAsB,GACvB,MAAM,SAAS,CAAA"}
|
package/build/index.js
CHANGED
|
@@ -2,5 +2,7 @@ export * from './contexts/chat_context';
|
|
|
2
2
|
export { ApiProvider } from './contexts/api_provider';
|
|
3
3
|
export { DesignSystemScreen } from './screens';
|
|
4
4
|
export * from './navigation';
|
|
5
|
-
export
|
|
5
|
+
export * from './types';
|
|
6
|
+
export * from './utils/client';
|
|
7
|
+
export { ChatAdapters, ClipboardAdapter, Session, platformFontWeightBold, } from './utils';
|
|
6
8
|
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAC9C,cAAc,cAAc,CAAA;AAC5B,OAAO,EAEL,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAA;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAC9C,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AACvB,cAAc,gBAAgB,CAAA;AAE9B,OAAO,EAEL,YAAY,EACZ,gBAAgB,EAChB,OAAO,EACP,sBAAsB,GACvB,MAAM,SAAS,CAAA","sourcesContent":["export * from './contexts/chat_context'\nexport { ApiProvider } from './contexts/api_provider'\nexport { DesignSystemScreen } from './screens'\nexport * from './navigation'\nexport * from './types'\nexport * from './utils/client'\n\nexport {\n TemporaryDefaultColorsType,\n ChatAdapters,\n ClipboardAdapter,\n Session,\n platformFontWeightBold,\n} from './utils'\n"]}
|
|
@@ -2,11 +2,14 @@ import { ApiCollection, ApiError, ApiResource } from '../../types';
|
|
|
2
2
|
import { Session } from '../session';
|
|
3
3
|
import { Uri } from '../uri';
|
|
4
4
|
import { DeleteRequest, GetRequest, PatchRequest, PostRequest } from './types';
|
|
5
|
+
export interface ResponseError extends Response {
|
|
6
|
+
errors: ApiError['errors'];
|
|
7
|
+
}
|
|
8
|
+
export type OnUnauthorizedResponse = (_response: ResponseError) => void;
|
|
5
9
|
type ClientArgs = {
|
|
6
10
|
version: string;
|
|
7
11
|
defaultHeaders?: Record<string, string>;
|
|
8
|
-
|
|
9
|
-
onTokenExpired?: () => void;
|
|
12
|
+
onUnauthorizedResponse?: OnUnauthorizedResponse;
|
|
10
13
|
session: Session;
|
|
11
14
|
app: string;
|
|
12
15
|
};
|
|
@@ -14,15 +17,14 @@ export declare class Client {
|
|
|
14
17
|
version: string;
|
|
15
18
|
defaultHeaders: Record<string, string>;
|
|
16
19
|
uri: Uri;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
constructor({ version, defaultHeaders, session, app, onTokenExpired, onForceLogout, }: ClientArgs);
|
|
20
|
+
onUnauthorizedResponse?: OnUnauthorizedResponse;
|
|
21
|
+
constructor({ version, defaultHeaders, session, app, onUnauthorizedResponse }: ClientArgs);
|
|
20
22
|
get<T extends ApiCollection | ApiResource>(args: GetRequest): Promise<T>;
|
|
21
23
|
patch(args: PatchRequest): Promise<any>;
|
|
22
24
|
post(args: PostRequest): Promise<any>;
|
|
23
25
|
delete(args: DeleteRequest): Promise<any>;
|
|
24
26
|
handleNotOk: (response: Response) => Promise<never>;
|
|
25
|
-
parseErrorResponse: (response: Response) => Promise<ApiError
|
|
27
|
+
parseErrorResponse: (response: Response) => Promise<Partial<ApiError>>;
|
|
26
28
|
get headers(): {
|
|
27
29
|
'User-Agent': string;
|
|
28
30
|
Authorization: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/utils/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;AAU5B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAe,MAAM,SAAS,CAAA;AAE3F,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/utils/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAClE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAA;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;AAU5B,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAe,MAAM,SAAS,CAAA;AAE3F,MAAM,WAAW,aAAc,SAAQ,QAAQ;IAC7C,MAAM,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;CAC3B;AAED,MAAM,MAAM,sBAAsB,GAAG,CAAC,SAAS,EAAE,aAAa,KAAK,IAAI,CAAA;AAEvE,KAAK,UAAU,GAAG;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACvC,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;IAC/C,OAAO,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,MAAM,CAAA;CACZ,CAAA;AAED,qBAAa,MAAM;IACjB,OAAO,EAAE,MAAM,CAAK;IACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAK;IAC3C,GAAG,EAAE,GAAG,CAAA;IACR,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;gBAEnC,EAAE,OAAO,EAAE,cAAmB,EAAE,OAAO,EAAE,GAAG,EAAE,sBAAsB,EAAE,EAAE,UAAU;IAOxF,GAAG,CAAC,CAAC,SAAS,aAAa,GAAG,WAAW,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC;IAuCxE,KAAK,CAAC,IAAI,EAAE,YAAY;IASxB,IAAI,CAAC,IAAI,EAAE,WAAW;IAStB,MAAM,CAAC,IAAI,EAAE,aAAa;IAShC,WAAW,aAAoB,QAAQ,oBAUtC;IAED,kBAAkB,aAAoB,QAAQ,KAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAM1E;IAED,IAAI,OAAO;;;;;;MAQV;CACF;AAED,eAAe,MAAM,CAAA"}
|
|
@@ -4,14 +4,12 @@ export class Client {
|
|
|
4
4
|
version = '';
|
|
5
5
|
defaultHeaders = {};
|
|
6
6
|
uri;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
constructor({ version, defaultHeaders = {}, session, app, onTokenExpired, onForceLogout, }) {
|
|
7
|
+
onUnauthorizedResponse;
|
|
8
|
+
constructor({ version, defaultHeaders = {}, session, app, onUnauthorizedResponse }) {
|
|
10
9
|
this.version = version;
|
|
11
10
|
this.uri = new Uri({ session, app });
|
|
12
11
|
this.defaultHeaders = defaultHeaders;
|
|
13
|
-
this.
|
|
14
|
-
this.onForceLogout = onForceLogout;
|
|
12
|
+
this.onUnauthorizedResponse = onUnauthorizedResponse;
|
|
15
13
|
}
|
|
16
14
|
async get(args) {
|
|
17
15
|
const { walk, ...data } = args.data;
|
|
@@ -61,12 +59,11 @@ export class Client {
|
|
|
61
59
|
}
|
|
62
60
|
handleNotOk = async (response) => {
|
|
63
61
|
if (response.status === 401) {
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
isForceLogout && this.onForceLogout?.();
|
|
62
|
+
const { errors } = await this.parseErrorResponse(response);
|
|
63
|
+
this.onUnauthorizedResponse?.({
|
|
64
|
+
...response,
|
|
65
|
+
errors: errors || [],
|
|
66
|
+
});
|
|
70
67
|
}
|
|
71
68
|
return Promise.reject(response);
|
|
72
69
|
};
|
|
@@ -75,7 +72,7 @@ export class Client {
|
|
|
75
72
|
return (await response.json());
|
|
76
73
|
}
|
|
77
74
|
catch {
|
|
78
|
-
return
|
|
75
|
+
return {};
|
|
79
76
|
}
|
|
80
77
|
};
|
|
81
78
|
get headers() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/utils/client/client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,GAAG,EAAE,MAAM,QAAQ,CAAA;AAC5B,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,WAAW,EAEX,yBAAyB,EACzB,uBAAuB,GACxB,MAAM,mBAAmB,CAAA;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/utils/client/client.ts"],"names":[],"mappings":"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","sourcesContent":["import { ApiCollection, ApiError, ApiResource } from '../../types'\nimport { Session } from '../session'\nimport { Uri } from '../uri'\nimport {\n concatRecords,\n ensureNoQueryParamsInDev,\n makeRequest,\n MakeRequestArgs,\n throwErrorIfFieldsMissing,\n throwErrorIfQueryParams,\n} from './request_helpers'\n\nimport { DeleteRequest, GetRequest, PatchRequest, PostRequest, WalkRequest } from './types'\n\nexport interface ResponseError extends Response {\n errors: ApiError['errors']\n}\n\nexport type OnUnauthorizedResponse = (_response: ResponseError) => void\n\ntype ClientArgs = {\n version: string\n defaultHeaders?: Record<string, string>\n onUnauthorizedResponse?: OnUnauthorizedResponse\n session: Session\n app: string\n}\n\nexport class Client {\n version: string = ''\n defaultHeaders: Record<string, string> = {}\n uri: Uri\n onUnauthorizedResponse?: OnUnauthorizedResponse\n\n constructor({ version, defaultHeaders = {}, session, app, onUnauthorizedResponse }: ClientArgs) {\n this.version = version\n this.uri = new Uri({ session, app })\n this.defaultHeaders = defaultHeaders\n this.onUnauthorizedResponse = onUnauthorizedResponse\n }\n\n async get<T extends ApiCollection | ApiResource>(args: GetRequest): Promise<T> {\n const { walk, ...data } = args.data\n const isWalking = Boolean(walk)\n const headers = { ...this.headers, ...args.headers }\n const url = this.uri.appUrl(args.url)\n\n await throwErrorIfQueryParams(url)\n\n const requestArgs: MakeRequestArgs = { data, url, action: 'GET', headers }\n\n const walkRequest = ({\n url: requestUrl,\n data: d = { fields: {} },\n acc = { data: [], included: [], meta: {}, links: {} },\n ...options\n }: WalkRequest) => {\n return makeRequest({\n action: 'GET',\n data: d,\n url: requestUrl,\n ...options,\n headers,\n }).then(({ links, ...rest }) => {\n const records = Array.isArray(rest.data) ? concatRecords(acc, rest) : rest\n\n // `next` will have our params in the link so we do not want to pass them back in\n if (links?.next) {\n return walkRequest({ ...options, data: d, url: links.next, acc: records })\n } else {\n return records\n }\n })\n }\n\n const handler = isWalking ? walkRequest : makeRequest\n\n return throwErrorIfFieldsMissing(handler, requestArgs).catch(this.handleNotOk)\n }\n\n async patch(args: PatchRequest) {\n const headers = { ...this.headers, ...args.headers }\n const url = this.uri.appUrl(args.url)\n\n const requestArgs: MakeRequestArgs = { data: args.data, url, action: 'PATCH', headers }\n\n return ensureNoQueryParamsInDev(makeRequest, requestArgs).catch(this.handleNotOk)\n }\n\n async post(args: PostRequest) {\n const headers = { ...this.headers, ...args.headers }\n const url = this.uri.appUrl(args.url)\n\n const requestArgs: MakeRequestArgs = { ...args, data: args.data, url, action: 'POST', headers }\n\n return ensureNoQueryParamsInDev(makeRequest, requestArgs).catch(this.handleNotOk)\n }\n\n async delete(args: DeleteRequest) {\n const headers = { ...this.headers, ...args.headers }\n const url = this.uri.appUrl(args.url)\n\n const requestArgs: MakeRequestArgs = { url, action: 'DELETE', headers }\n\n return makeRequest(requestArgs).catch(this.handleNotOk)\n }\n\n handleNotOk = async (response: Response) => {\n if (response.status === 401) {\n const { errors } = await this.parseErrorResponse(response)\n this.onUnauthorizedResponse?.({\n ...response,\n errors: errors || [],\n })\n }\n\n return Promise.reject(response)\n }\n\n parseErrorResponse = async (response: Response): Promise<Partial<ApiError>> => {\n try {\n return (await response.json()) as ApiError\n } catch {\n return {}\n }\n }\n\n get headers() {\n return {\n Accept: 'application/vnd.api+json',\n 'Content-Type': 'application/json',\n 'X-PCO-API-Version': this.version,\n ...this.uri.headers,\n ...this.defaultHeaders,\n }\n }\n}\n\nexport default Client\n"]}
|
package/build/utils/session.d.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { OAuthToken } from '../types';
|
|
2
2
|
export type ENV = 'production' | 'staging' | 'development';
|
|
3
3
|
export type PartialToken = Pick<OAuthToken, 'access_token'> & Partial<OAuthToken>;
|
|
4
|
-
export type SessionProps = {
|
|
4
|
+
export type SessionProps<T = PartialToken> = {
|
|
5
5
|
env?: ENV;
|
|
6
|
-
token?:
|
|
7
|
-
}
|
|
6
|
+
token?: T;
|
|
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 declare class Session {
|
|
12
|
+
export declare class Session<T = PartialToken> {
|
|
13
13
|
env: ENV;
|
|
14
|
-
token:
|
|
15
|
-
constructor(props?: SessionProps);
|
|
14
|
+
token: T | undefined;
|
|
15
|
+
constructor(props?: SessionProps<T>);
|
|
16
16
|
get isAuthenticated(): boolean;
|
|
17
17
|
toString(): string;
|
|
18
|
-
static hydrate(sessionString: string): Session
|
|
18
|
+
static hydrate<T extends PartialToken>(sessionString: string): Session<T>;
|
|
19
19
|
}
|
|
20
20
|
//# sourceMappingURL=session.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAErC,MAAM,MAAM,GAAG,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAA;AAE1D,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AACjF,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,CAAC,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAErC,MAAM,MAAM,GAAG,GAAG,YAAY,GAAG,SAAS,GAAG,aAAa,CAAA;AAE1D,MAAM,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AACjF,MAAM,MAAM,YAAY,CAAC,CAAC,GAAG,YAAY,IAAI;IAAE,GAAG,CAAC,EAAE,GAAG,CAAC;IAAC,KAAK,CAAC,EAAE,CAAC,CAAA;CAAE,CAAA;AAErE;;;GAGG;AACH,qBAAa,OAAO,CAAC,CAAC,GAAG,YAAY;IACnC,GAAG,EAAE,GAAG,CAAA;IACR,KAAK,EAAE,CAAC,GAAG,SAAS,CAAA;gBAER,KAAK,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IAMnC,IAAI,eAAe,YAElB;IAED,QAAQ;IAIR,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,YAAY,EAAE,aAAa,EAAE,MAAM;CAQ7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,OAAO,OAAO;IAClB,GAAG,CAAK;IACR,KAAK,
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,OAAO,OAAO;IAClB,GAAG,CAAK;IACR,KAAK,CAAe;IAEpB,YAAY,KAAuB;QACjC,MAAM,EAAE,GAAG,GAAG,YAAY,EAAE,KAAK,EAAE,GAAG,KAAK,IAAI,EAAE,CAAA;QACjD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;QACd,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;IAED,IAAI,eAAe;QACjB,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IAC5B,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAA;IAC7D,CAAC;IAED,MAAM,CAAC,OAAO,CAAyB,aAAqB;QAC1D,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;YACvC,OAAO,IAAI,OAAO,CAAI,KAAK,CAAC,CAAA;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,IAAI,OAAO,EAAK,CAAA;QACzB,CAAC;IACH,CAAC;CACF","sourcesContent":["import { OAuthToken } from '../types'\n\nexport type ENV = 'production' | 'staging' | 'development'\n\nexport type PartialToken = Pick<OAuthToken, 'access_token'> & Partial<OAuthToken>\nexport type SessionProps<T = PartialToken> = { env?: ENV; token?: T }\n\n/**\n * Session class to track the environment and token\n * Not intended to make network requests or handle authentication\n */\nexport class Session<T = PartialToken> {\n env: ENV\n token: T | undefined\n\n constructor(props?: SessionProps<T>) {\n const { env = 'production', token } = props || {}\n this.env = env\n this.token = token\n }\n\n get isAuthenticated() {\n return Boolean(this.token)\n }\n\n toString() {\n return JSON.stringify({ env: this.env, token: this.token })\n }\n\n static hydrate<T extends PartialToken>(sessionString: string) {\n try {\n const props = JSON.parse(sessionString)\n return new Session<T>(props)\n } catch (error) {\n return new Session<T>()\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@planningcenter/chat-react-native",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0-rc.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"prettier": "^3.4.2",
|
|
53
53
|
"typescript": "<5.6.0"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "fc8a135074133d4b38064a2191e5fb2de3f9df12"
|
|
56
56
|
}
|
package/src/__tests__/client.ts
CHANGED
|
@@ -16,8 +16,7 @@ beforeAll(() => MockServer.server().listen())
|
|
|
16
16
|
afterEach(() => MockServer.server().resetHandlers())
|
|
17
17
|
afterAll(() => MockServer.server().close())
|
|
18
18
|
|
|
19
|
-
const
|
|
20
|
-
const onForceLogout = jest.fn()
|
|
19
|
+
const onUnauthorizedResponse = jest.fn()
|
|
21
20
|
|
|
22
21
|
beforeEach(() => {
|
|
23
22
|
jest.clearAllMocks()
|
|
@@ -27,8 +26,7 @@ beforeEach(() => {
|
|
|
27
26
|
app: 'chat',
|
|
28
27
|
version: '2018-11-01',
|
|
29
28
|
session,
|
|
30
|
-
|
|
31
|
-
onForceLogout,
|
|
29
|
+
onUnauthorizedResponse,
|
|
32
30
|
})
|
|
33
31
|
clientWithDefaultHeaders = new Client({
|
|
34
32
|
app: 'chat',
|
|
@@ -37,8 +35,7 @@ beforeEach(() => {
|
|
|
37
35
|
'X-Custom-Default-Header': 'important data',
|
|
38
36
|
},
|
|
39
37
|
session,
|
|
40
|
-
|
|
41
|
-
onForceLogout,
|
|
38
|
+
onUnauthorizedResponse,
|
|
42
39
|
})
|
|
43
40
|
})
|
|
44
41
|
|
|
@@ -361,7 +358,7 @@ describe('url switching', () => {
|
|
|
361
358
|
app: 'chat',
|
|
362
359
|
session,
|
|
363
360
|
version: '2018-11-01',
|
|
364
|
-
|
|
361
|
+
onUnauthorizedResponse: () => {},
|
|
365
362
|
})
|
|
366
363
|
|
|
367
364
|
await newClient.get({
|
|
@@ -442,20 +439,7 @@ describe('error handling', () => {
|
|
|
442
439
|
describe('401 errors', () => {
|
|
443
440
|
it('defaults', async () => {
|
|
444
441
|
await test401({ secretWord: '' })
|
|
445
|
-
expect(
|
|
446
|
-
expect(onForceLogout).not.toHaveBeenCalled()
|
|
447
|
-
})
|
|
448
|
-
|
|
449
|
-
it('handles forced logout', async () => {
|
|
450
|
-
await test401({ secretWord: 'CAPUCHIN' })
|
|
451
|
-
expect(onTokenExpired).not.toHaveBeenCalled()
|
|
452
|
-
expect(onForceLogout).toHaveBeenCalled()
|
|
453
|
-
})
|
|
454
|
-
|
|
455
|
-
it('handles token refresh', async () => {
|
|
456
|
-
await test401({ secretWord: 'BABOON' })
|
|
457
|
-
expect(onTokenExpired).toHaveBeenCalled()
|
|
458
|
-
expect(onForceLogout).not.toHaveBeenCalled()
|
|
442
|
+
expect(onUnauthorizedResponse).toHaveBeenCalled()
|
|
459
443
|
})
|
|
460
444
|
|
|
461
445
|
const test401 = async ({ secretWord }: { secretWord: string }) => {
|
|
@@ -2,13 +2,12 @@ import { merge } from 'lodash'
|
|
|
2
2
|
import React, { createContext, useMemo } from 'react'
|
|
3
3
|
import { ColorSchemeName, useColorScheme } from 'react-native'
|
|
4
4
|
import { DeepPartial } from '../types'
|
|
5
|
-
import { ENV, PartialToken, Session } from '../utils'
|
|
5
|
+
import { ENV, PartialToken, ResponseError, Session } from '../utils'
|
|
6
6
|
import { ChatTheme, defaultTheme, DefaultTheme } from '../utils/theme'
|
|
7
7
|
|
|
8
8
|
export type ChatContextValue = {
|
|
9
9
|
token?: PartialToken
|
|
10
|
-
|
|
11
|
-
onTokenExpired: () => void
|
|
10
|
+
onUnauthorizedResponse: (_response: ResponseError) => void
|
|
12
11
|
theme: ChatTheme
|
|
13
12
|
env?: ENV
|
|
14
13
|
session: Session
|
|
@@ -22,21 +21,19 @@ export const ChatContext = createContext<ChatContextValue>({
|
|
|
22
21
|
theme: defaultTheme('light'),
|
|
23
22
|
token: undefined,
|
|
24
23
|
env: undefined,
|
|
25
|
-
|
|
26
|
-
onTokenExpired: () => {},
|
|
24
|
+
onUnauthorizedResponse: () => {},
|
|
27
25
|
session: new Session(),
|
|
28
26
|
})
|
|
29
27
|
|
|
30
28
|
export function ChatProvider({ children, value }: { children: any; value: ChatProviderProps }) {
|
|
31
|
-
const { env, token,
|
|
29
|
+
const { env, token, onUnauthorizedResponse } = value
|
|
32
30
|
const theme = useCreateChatTheme(value.theme || {})
|
|
33
31
|
const session = useMemo(() => new Session({ token, env }), [env, token])
|
|
34
32
|
|
|
35
33
|
const contextValue: ChatContextValue = {
|
|
36
34
|
env,
|
|
37
35
|
token,
|
|
38
|
-
|
|
39
|
-
onForceLogout,
|
|
36
|
+
onUnauthorizedResponse,
|
|
40
37
|
session,
|
|
41
38
|
theme,
|
|
42
39
|
}
|
|
@@ -8,7 +8,7 @@ const apps: App[] = ['chat', 'groups', 'services']
|
|
|
8
8
|
export type ApiClient = { [_K in App]: Client }
|
|
9
9
|
|
|
10
10
|
export const useApiClient = () => {
|
|
11
|
-
const { session,
|
|
11
|
+
const { session, onUnauthorizedResponse } = useContext(ChatContext)
|
|
12
12
|
const api = useMemo(
|
|
13
13
|
() =>
|
|
14
14
|
apps.reduce((acc, app) => {
|
|
@@ -16,11 +16,11 @@ export const useApiClient = () => {
|
|
|
16
16
|
app,
|
|
17
17
|
session,
|
|
18
18
|
version: '2018-11-01',
|
|
19
|
-
|
|
19
|
+
onUnauthorizedResponse,
|
|
20
20
|
})
|
|
21
21
|
return acc
|
|
22
22
|
}, {} as ApiClient),
|
|
23
|
-
[session,
|
|
23
|
+
[session, onUnauthorizedResponse]
|
|
24
24
|
)
|
|
25
25
|
|
|
26
26
|
return api
|
package/src/index.tsx
CHANGED
|
@@ -2,10 +2,13 @@ export * from './contexts/chat_context'
|
|
|
2
2
|
export { ApiProvider } from './contexts/api_provider'
|
|
3
3
|
export { DesignSystemScreen } from './screens'
|
|
4
4
|
export * from './navigation'
|
|
5
|
+
export * from './types'
|
|
6
|
+
export * from './utils/client'
|
|
7
|
+
|
|
5
8
|
export {
|
|
6
9
|
TemporaryDefaultColorsType,
|
|
7
10
|
ChatAdapters,
|
|
8
11
|
ClipboardAdapter,
|
|
9
12
|
Session,
|
|
10
|
-
|
|
13
|
+
platformFontWeightBold,
|
|
11
14
|
} from './utils'
|
|
@@ -12,11 +12,16 @@ import {
|
|
|
12
12
|
|
|
13
13
|
import { DeleteRequest, GetRequest, PatchRequest, PostRequest, WalkRequest } from './types'
|
|
14
14
|
|
|
15
|
+
export interface ResponseError extends Response {
|
|
16
|
+
errors: ApiError['errors']
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type OnUnauthorizedResponse = (_response: ResponseError) => void
|
|
20
|
+
|
|
15
21
|
type ClientArgs = {
|
|
16
22
|
version: string
|
|
17
23
|
defaultHeaders?: Record<string, string>
|
|
18
|
-
|
|
19
|
-
onTokenExpired?: () => void
|
|
24
|
+
onUnauthorizedResponse?: OnUnauthorizedResponse
|
|
20
25
|
session: Session
|
|
21
26
|
app: string
|
|
22
27
|
}
|
|
@@ -25,22 +30,13 @@ export class Client {
|
|
|
25
30
|
version: string = ''
|
|
26
31
|
defaultHeaders: Record<string, string> = {}
|
|
27
32
|
uri: Uri
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
constructor({
|
|
32
|
-
version,
|
|
33
|
-
defaultHeaders = {},
|
|
34
|
-
session,
|
|
35
|
-
app,
|
|
36
|
-
onTokenExpired,
|
|
37
|
-
onForceLogout,
|
|
38
|
-
}: ClientArgs) {
|
|
33
|
+
onUnauthorizedResponse?: OnUnauthorizedResponse
|
|
34
|
+
|
|
35
|
+
constructor({ version, defaultHeaders = {}, session, app, onUnauthorizedResponse }: ClientArgs) {
|
|
39
36
|
this.version = version
|
|
40
37
|
this.uri = new Uri({ session, app })
|
|
41
38
|
this.defaultHeaders = defaultHeaders
|
|
42
|
-
this.
|
|
43
|
-
this.onForceLogout = onForceLogout
|
|
39
|
+
this.onUnauthorizedResponse = onUnauthorizedResponse
|
|
44
40
|
}
|
|
45
41
|
|
|
46
42
|
async get<T extends ApiCollection | ApiResource>(args: GetRequest): Promise<T> {
|
|
@@ -111,22 +107,21 @@ export class Client {
|
|
|
111
107
|
|
|
112
108
|
handleNotOk = async (response: Response) => {
|
|
113
109
|
if (response.status === 401) {
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
isForceLogout && this.onForceLogout?.()
|
|
110
|
+
const { errors } = await this.parseErrorResponse(response)
|
|
111
|
+
this.onUnauthorizedResponse?.({
|
|
112
|
+
...response,
|
|
113
|
+
errors: errors || [],
|
|
114
|
+
})
|
|
120
115
|
}
|
|
121
116
|
|
|
122
117
|
return Promise.reject(response)
|
|
123
118
|
}
|
|
124
119
|
|
|
125
|
-
parseErrorResponse = async (response: Response): Promise<ApiError
|
|
120
|
+
parseErrorResponse = async (response: Response): Promise<Partial<ApiError>> => {
|
|
126
121
|
try {
|
|
127
122
|
return (await response.json()) as ApiError
|
|
128
123
|
} catch {
|
|
129
|
-
return
|
|
124
|
+
return {}
|
|
130
125
|
}
|
|
131
126
|
}
|
|
132
127
|
|
package/src/utils/session.ts
CHANGED
|
@@ -3,17 +3,17 @@ import { OAuthToken } from '../types'
|
|
|
3
3
|
export type ENV = 'production' | 'staging' | 'development'
|
|
4
4
|
|
|
5
5
|
export type PartialToken = Pick<OAuthToken, 'access_token'> & Partial<OAuthToken>
|
|
6
|
-
export type SessionProps = { env?: ENV; token?:
|
|
6
|
+
export type SessionProps<T = PartialToken> = { env?: ENV; token?: T }
|
|
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 {
|
|
12
|
+
export class Session<T = PartialToken> {
|
|
13
13
|
env: ENV
|
|
14
|
-
token:
|
|
14
|
+
token: T | undefined
|
|
15
15
|
|
|
16
|
-
constructor(props?: SessionProps) {
|
|
16
|
+
constructor(props?: SessionProps<T>) {
|
|
17
17
|
const { env = 'production', token } = props || {}
|
|
18
18
|
this.env = env
|
|
19
19
|
this.token = token
|
|
@@ -27,12 +27,12 @@ export class Session {
|
|
|
27
27
|
return JSON.stringify({ env: this.env, token: this.token })
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
static hydrate(sessionString: string) {
|
|
30
|
+
static hydrate<T extends PartialToken>(sessionString: string) {
|
|
31
31
|
try {
|
|
32
32
|
const props = JSON.parse(sessionString)
|
|
33
|
-
return new Session(props)
|
|
33
|
+
return new Session<T>(props)
|
|
34
34
|
} catch (error) {
|
|
35
|
-
return new Session()
|
|
35
|
+
return new Session<T>()
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
}
|