@knocklabs/react-core 0.7.1 → 0.7.3

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 (27) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/cjs/index.js +1 -1
  3. package/dist/cjs/modules/preferences/hooks/usePreferences.js +2 -0
  4. package/dist/cjs/modules/preferences/hooks/usePreferences.js.map +1 -0
  5. package/dist/cjs/modules/slack/hooks/useSlackConnectionStatus.js +1 -1
  6. package/dist/cjs/modules/slack/hooks/useSlackConnectionStatus.js.map +1 -1
  7. package/dist/esm/index.mjs +4 -2
  8. package/dist/esm/index.mjs.map +1 -1
  9. package/dist/esm/modules/preferences/hooks/usePreferences.mjs +37 -0
  10. package/dist/esm/modules/preferences/hooks/usePreferences.mjs.map +1 -0
  11. package/dist/esm/modules/slack/hooks/useSlackConnectionStatus.mjs +17 -15
  12. package/dist/esm/modules/slack/hooks/useSlackConnectionStatus.mjs.map +1 -1
  13. package/dist/types/index.d.ts +1 -0
  14. package/dist/types/index.d.ts.map +1 -1
  15. package/dist/types/modules/preferences/hooks/index.d.ts +2 -0
  16. package/dist/types/modules/preferences/hooks/index.d.ts.map +1 -0
  17. package/dist/types/modules/preferences/hooks/usePreferences.d.ts +13 -0
  18. package/dist/types/modules/preferences/hooks/usePreferences.d.ts.map +1 -0
  19. package/dist/types/modules/preferences/index.d.ts +2 -0
  20. package/dist/types/modules/preferences/index.d.ts.map +1 -0
  21. package/dist/types/modules/slack/hooks/useSlackConnectionStatus.d.ts.map +1 -1
  22. package/package.json +2 -2
  23. package/src/index.ts +2 -0
  24. package/src/modules/preferences/hooks/index.ts +1 -0
  25. package/src/modules/preferences/hooks/usePreferences.ts +69 -0
  26. package/src/modules/preferences/index.ts +1 -0
  27. package/src/modules/slack/hooks/useSlackConnectionStatus.ts +5 -7
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.7.3
4
+
5
+ ### Patch Changes
6
+
7
+ - c3efcf9: Resolve logic error in Slack connection status
8
+ - Updated dependencies [befd7b9]
9
+ - @knocklabs/client@0.15.1
10
+
11
+ ## 0.7.2
12
+
13
+ ### Patch Changes
14
+
15
+ - 3703cf6: feat: adds `usePreferences` hook for fetching and updating user preferences in react apps.
16
+ - fdc6d82: chore(deps): bump the telegraph-packages group across 1 directory with 9 updates
17
+
3
18
  ## 0.7.1
4
19
 
5
20
  ### Patch Changes
package/dist/cjs/index.js CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./modules/core/context/KnockProvider.js"),c=require("./modules/core/hooks/useAuthenticatedKnockClient.js"),a=require("./modules/core/hooks/useStableOptions.js"),d=require("./modules/core/constants.js"),e=require("./modules/core/utils.js"),n=require("./modules/feed/context/KnockFeedProvider.js"),l=require("./modules/feed/hooks/useNotifications.js"),k=require("./modules/feed/hooks/useFeedSettings.js"),o=require("./modules/feed/hooks/useNotificationStore.js"),t=require("./modules/guide/context/KnockGuideProvider.js"),K=require("./modules/guide/hooks/useGuide.js"),r=require("./modules/ms-teams/context/KnockMsTeamsProvider.js"),C=require("./modules/ms-teams/hooks/useMsTeamsConnectionStatus.js"),S=require("./modules/ms-teams/hooks/useMsTeamsAuth.js"),m=require("./modules/ms-teams/hooks/useMsTeamsTeams.js"),q=require("./modules/ms-teams/hooks/useMsTeamsChannels.js"),v=require("./modules/ms-teams/hooks/useConnectedMsTeamsChannels.js"),i=require("./modules/slack/context/KnockSlackProvider.js"),P=require("./modules/slack/hooks/useSlackConnectionStatus.js"),T=require("./modules/slack/hooks/useSlackChannels.js"),M=require("./modules/slack/hooks/useConnectedSlackChannels.js"),f=require("./modules/slack/hooks/useSlackAuth.js"),u=require("./modules/i18n/context/KnockI18nProvider.js"),h=require("./modules/i18n/hooks/useTranslations.js"),F=require("./modules/i18n/languages/index.js");exports.KnockProvider=s.KnockProvider;exports.useKnockClient=s.useKnockClient;exports.useAuthenticatedKnockClient=c;exports.useStableOptions=a;exports.FilterStatus=d.FilterStatus;exports.feedProviderKey=e.feedProviderKey;exports.formatBadgeCount=e.formatBadgeCount;exports.formatTimestamp=e.formatTimestamp;exports.msTeamsProviderKey=e.msTeamsProviderKey;exports.renderNodeOrFallback=e.renderNodeOrFallback;exports.slackProviderKey=e.slackProviderKey;exports.toSentenceCase=e.toSentenceCase;exports.KnockFeedProvider=n.KnockFeedProvider;exports.useKnockFeed=n.useKnockFeed;exports.useNotifications=l;exports.useFeedSettings=k;exports.useCreateNotificationStore=o.useCreateNotificationStore;exports.useNotificationStore=o.default;exports.KnockGuideContext=t.KnockGuideContext;exports.KnockGuideProvider=t.KnockGuideProvider;exports.useGuide=K.useGuide;exports.KnockMsTeamsProvider=r.KnockMsTeamsProvider;exports.useKnockMsTeamsClient=r.useKnockMsTeamsClient;exports.useMsTeamsConnectionStatus=C;exports.useMsTeamsAuth=S;exports.useMsTeamsTeams=m;exports.useMsTeamsChannels=q;exports.useConnectedMsTeamsChannels=v;exports.KnockSlackProvider=i.KnockSlackProvider;exports.useKnockSlackClient=i.useKnockSlackClient;exports.useSlackConnectionStatus=P;exports.useSlackChannels=T;exports.useConnectedSlackChannels=M;exports.useSlackAuth=f;exports.I18nContext=u.I18nContext;exports.KnockI18nProvider=u.KnockI18nProvider;exports.useTranslations=h.useTranslations;exports.locales=F.locales;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const s=require("./modules/core/context/KnockProvider.js"),c=require("./modules/core/hooks/useAuthenticatedKnockClient.js"),a=require("./modules/core/hooks/useStableOptions.js"),d=require("./modules/core/constants.js"),e=require("./modules/core/utils.js"),n=require("./modules/feed/context/KnockFeedProvider.js"),l=require("./modules/feed/hooks/useNotifications.js"),k=require("./modules/feed/hooks/useFeedSettings.js"),o=require("./modules/feed/hooks/useNotificationStore.js"),r=require("./modules/guide/context/KnockGuideProvider.js"),K=require("./modules/guide/hooks/useGuide.js"),t=require("./modules/ms-teams/context/KnockMsTeamsProvider.js"),C=require("./modules/ms-teams/hooks/useMsTeamsConnectionStatus.js"),S=require("./modules/ms-teams/hooks/useMsTeamsAuth.js"),m=require("./modules/ms-teams/hooks/useMsTeamsTeams.js"),P=require("./modules/ms-teams/hooks/useMsTeamsChannels.js"),q=require("./modules/ms-teams/hooks/useConnectedMsTeamsChannels.js"),i=require("./modules/slack/context/KnockSlackProvider.js"),v=require("./modules/slack/hooks/useSlackConnectionStatus.js"),T=require("./modules/slack/hooks/useSlackChannels.js"),f=require("./modules/slack/hooks/useConnectedSlackChannels.js"),M=require("./modules/slack/hooks/useSlackAuth.js"),u=require("./modules/i18n/context/KnockI18nProvider.js"),h=require("./modules/i18n/hooks/useTranslations.js"),F=require("./modules/i18n/languages/index.js"),y=require("./modules/preferences/hooks/usePreferences.js");exports.KnockProvider=s.KnockProvider;exports.useKnockClient=s.useKnockClient;exports.useAuthenticatedKnockClient=c;exports.useStableOptions=a;exports.FilterStatus=d.FilterStatus;exports.feedProviderKey=e.feedProviderKey;exports.formatBadgeCount=e.formatBadgeCount;exports.formatTimestamp=e.formatTimestamp;exports.msTeamsProviderKey=e.msTeamsProviderKey;exports.renderNodeOrFallback=e.renderNodeOrFallback;exports.slackProviderKey=e.slackProviderKey;exports.toSentenceCase=e.toSentenceCase;exports.KnockFeedProvider=n.KnockFeedProvider;exports.useKnockFeed=n.useKnockFeed;exports.useNotifications=l;exports.useFeedSettings=k;exports.useCreateNotificationStore=o.useCreateNotificationStore;exports.useNotificationStore=o.default;exports.KnockGuideContext=r.KnockGuideContext;exports.KnockGuideProvider=r.KnockGuideProvider;exports.useGuide=K.useGuide;exports.KnockMsTeamsProvider=t.KnockMsTeamsProvider;exports.useKnockMsTeamsClient=t.useKnockMsTeamsClient;exports.useMsTeamsConnectionStatus=C;exports.useMsTeamsAuth=S;exports.useMsTeamsTeams=m;exports.useMsTeamsChannels=P;exports.useConnectedMsTeamsChannels=q;exports.KnockSlackProvider=i.KnockSlackProvider;exports.useKnockSlackClient=i.useKnockSlackClient;exports.useSlackConnectionStatus=v;exports.useSlackChannels=T;exports.useConnectedSlackChannels=f;exports.useSlackAuth=M;exports.I18nContext=u.I18nContext;exports.KnockI18nProvider=u.KnockI18nProvider;exports.useTranslations=h.useTranslations;exports.locales=F.locales;exports.usePreferences=y.usePreferences;
2
2
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const n=require("react"),d=require("swr"),P=require("../../core/context/KnockProvider.js");require("@knocklabs/client");require("fast-deep-equal");require("date-fns");const g=e=>e&&typeof e=="object"&&"default"in e?e:{default:e},k=g(d),p=(e={})=>{const r=P.useKnockClient(),{preferenceSet:t,tenant:c}=e,u=["preferences",e.preferenceSet,e.tenant,r.userId],{data:a,isLoading:l,isValidating:o,mutate:s}=k.default(r.userId?u:null,()=>r.user.getPreferences({preferenceSet:t,tenant:c})),f=n.useCallback(i=>{s(r.user.setPreferences(i,{preferenceSet:t}),{revalidate:!1})},[s,r.user,t]);return{getAllPreferences:n.useCallback(async()=>await r.user.getAllPreferences(),[r.user]),setPreferences:f,preferences:a,isLoading:l,isValidating:o}};exports.usePreferences=p;
2
+ //# sourceMappingURL=usePreferences.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePreferences.js","sources":["../../../../../src/modules/preferences/hooks/usePreferences.ts"],"sourcesContent":["import type {\n GetPreferencesOptions,\n PreferenceSet,\n SetPreferencesProperties,\n} from \"@knocklabs/client\";\nimport { useCallback } from \"react\";\nimport useSWR, { type SWRResponse } from \"swr\";\n\nimport { useKnockClient } from \"../../core\";\n\ntype UsePreferencesReturn = {\n preferences: PreferenceSet | undefined;\n setPreferences: (setPreferencesProperties: SetPreferencesProperties) => void;\n getAllPreferences: ReturnType<\n typeof useKnockClient\n >[\"user\"][\"getAllPreferences\"];\n isLoading: SWRResponse[\"isLoading\"];\n isValidating: SWRResponse[\"isValidating\"];\n};\n\nconst usePreferences = (\n options: GetPreferencesOptions = {},\n): UsePreferencesReturn => {\n const knock = useKnockClient();\n\n const { preferenceSet, tenant } = options;\n\n const CACHE_KEY = [\n \"preferences\",\n options.preferenceSet,\n options.tenant,\n knock.userId,\n ];\n\n const {\n data: preferences,\n isLoading,\n isValidating,\n mutate,\n } = useSWR(knock.userId ? CACHE_KEY : null, () => {\n return knock.user.getPreferences({ preferenceSet, tenant });\n });\n\n const setPreferences = useCallback(\n (preferenceSetProperties: SetPreferencesProperties) => {\n mutate(\n knock.user.setPreferences(preferenceSetProperties, { preferenceSet }),\n {\n revalidate: false,\n },\n );\n },\n [mutate, knock.user, preferenceSet],\n );\n\n const getAllPreferences = useCallback(async () => {\n return await knock.user.getAllPreferences();\n }, [knock.user]);\n\n return {\n getAllPreferences,\n setPreferences,\n preferences,\n isLoading,\n isValidating,\n };\n};\n\nexport { usePreferences };\n"],"names":["usePreferences","options","knock","useKnockClient","preferenceSet","tenant","CACHE_KEY","userId","data","preferences","isLoading","isValidating","mutate","useSWR","user","getPreferences","setPreferences","useCallback","preferenceSetProperties","revalidate","getAllPreferences"],"mappings":"4TAoBMA,EAAiBA,CACrBC,EAAiC,KACR,CACzB,MAAMC,EAAQC,EAAAA,eAAe,EAEvB,CAAEC,cAAAA,EAAeC,OAAAA,CAAAA,EAAWJ,EAE5BK,EAAY,CAChB,cACAL,EAAQG,cACRH,EAAQI,OACRH,EAAMK,MAAM,EAGR,CACJC,KAAMC,EACNC,UAAAA,EACAC,aAAAA,EACAC,OAAAA,GACEC,EAAOX,QAAAA,EAAMK,OAASD,EAAY,KAAM,IACnCJ,EAAMY,KAAKC,eAAe,CAAEX,cAAAA,EAAeC,OAAAA,CAAAA,CAAQ,CAC3D,EAEKW,EAAiBC,cACpBC,GAAsD,CAEnDhB,EAAAA,EAAMY,KAAKE,eAAeE,EAAyB,CAAEd,cAAAA,CAAAA,CAAe,EACpE,CACEe,WAAY,EAAA,CAEhB,GAEF,CAACP,EAAQV,EAAMY,KAAMV,CAAa,CACpC,EAMO,MAAA,CACLgB,kBALwBH,EAAAA,YAAY,SAC7B,MAAMf,EAAMY,KAAKM,kBAAkB,EACzC,CAAClB,EAAMY,IAAI,CAAC,EAIbE,eAAAA,EACAP,YAAAA,EACAC,UAAAA,EACAC,aAAAA,CACF,CACF"}
@@ -1,2 +1,2 @@
1
- "use strict";const r=require("react");require("../../i18n/context/KnockI18nProvider.js");const A=require("../../i18n/hooks/useTranslations.js"),R=c=>{const n=c.substring(0,1).toUpperCase(),o=c.substring(1);return n==null?void 0:n.concat(o).replace("_"," ")};function C(c,n,o){const{t:a}=A.useTranslations(),[s,e]=r.useState("connecting"),[d,u]=r.useState(null),[E,g]=r.useState(null);return r.useEffect(()=>{(async()=>{var i,l,S,k,f,h,b;if(s==="connecting")try{const t=await c.slack.authCheck({tenant:o,knockChannelId:n});if((i=t.connection)!=null&&i.ok)return e("connected");if(!((l=t.connection)!=null&&l.ok)||t.code==="ERR_BAD_REQUEST"&&((k=(S=t.response)==null?void 0:S.data)==null?void 0:k.message)===a("slackAccessTokenNotSet"))return e("disconnected");if(!((f=t.connection)!=null&&f.ok)&&((h=t.connection)!=null&&h.error)){const p=R((b=t.connection)==null?void 0:b.error);u(p),e("error");return}e("error")}catch{e("error")}})()},[s,o,n,c.slack,a]),{connectionStatus:s,setConnectionStatus:e,errorLabel:d,setErrorLabel:u,actionLabel:E,setActionLabel:g}}module.exports=C;
1
+ "use strict";const o=require("react");require("../../i18n/context/KnockI18nProvider.js");const d=require("../../i18n/hooks/useTranslations.js"),E=c=>{const n=c.substring(0,1).toUpperCase(),r=c.substring(1);return n==null?void 0:n.concat(r).replace("_"," ")};function g(c,n,r){const{t:a}=d.useTranslations(),[s,e]=o.useState("connecting"),[f,u]=o.useState(null),[h,b]=o.useState(null);return o.useEffect(()=>{(async()=>{var i,l,S;if(s==="connecting")try{const t=await c.slack.authCheck({tenant:r,knockChannelId:n});if((i=t.connection)!=null&&i.ok)return e("connected");if(t.code==="ERR_BAD_REQUEST"&&((S=(l=t.response)==null?void 0:l.data)==null?void 0:S.message)===a("slackAccessTokenNotSet"))return e("disconnected");if(t.connection&&t.connection.error){const k=E(t.connection.error);u(k),e("error");return}if(t.connection)return e("disconnected");e("error")}catch{e("error")}})()},[s,r,n,c.slack,a]),{connectionStatus:s,setConnectionStatus:e,errorLabel:f,setErrorLabel:u,actionLabel:h,setActionLabel:b}}module.exports=g;
2
2
  //# sourceMappingURL=useSlackConnectionStatus.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSlackConnectionStatus.js","sources":["../../../../../src/modules/slack/hooks/useSlackConnectionStatus.ts"],"sourcesContent":["import Knock from \"@knocklabs/client\";\nimport { useEffect, useState } from \"react\";\n\nimport { useTranslations } from \"../../i18n\";\n\nexport type ConnectionStatus =\n | \"connecting\"\n | \"connected\"\n | \"disconnected\"\n | \"error\"\n | \"disconnecting\";\n\ntype UseSlackConnectionStatusOutput = {\n connectionStatus: ConnectionStatus;\n setConnectionStatus: (status: ConnectionStatus) => void;\n errorLabel: string | null;\n setErrorLabel: (errorLabel: string) => void;\n actionLabel: string | null;\n setActionLabel: (actionLabel: string | null) => void;\n};\n\n/**\n * Transforms a slack error message into\n * a formatted one. Slack error messages: https://api.slack.com/methods/auth.test#errors\n *\n * Ex.: \"account_inactive\" -> \"Account inactive\"\n */\nconst formatSlackErrorMessage = (errorMessage: string) => {\n const firstLetter = errorMessage.substring(0, 1).toUpperCase();\n const rest = errorMessage.substring(1);\n return firstLetter?.concat(rest).replace(\"_\", \" \");\n};\n\nfunction useSlackConnectionStatus(\n knock: Knock,\n knockSlackChannelId: string,\n tenantId: string,\n): UseSlackConnectionStatusOutput {\n const { t } = useTranslations();\n const [connectionStatus, setConnectionStatus] =\n useState<ConnectionStatus>(\"connecting\");\n const [errorLabel, setErrorLabel] = useState<string | null>(null);\n const [actionLabel, setActionLabel] = useState<string | null>(null);\n\n useEffect(() => {\n const checkAuthStatus = async () => {\n if (connectionStatus !== \"connecting\") return;\n\n try {\n const authRes = await knock.slack.authCheck({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n });\n\n if (authRes.connection?.ok) {\n return setConnectionStatus(\"connected\");\n }\n\n if (!authRes.connection?.ok) {\n return setConnectionStatus(\"disconnected\");\n }\n\n // This is a normal response for a tenant that doesn't have an access\n // token set on it, meaning it's not connected to Slack, so we\n // give it a \"disconnected\" status instead of an error status.\n if (\n authRes.code === \"ERR_BAD_REQUEST\" &&\n authRes.response?.data?.message === t(\"slackAccessTokenNotSet\")\n ) {\n return setConnectionStatus(\"disconnected\");\n }\n\n // This is for an error coming directly from Slack.\n if (!authRes.connection?.ok && authRes.connection?.error) {\n const errorLabel = formatSlackErrorMessage(authRes.connection?.error);\n setErrorLabel(errorLabel);\n setConnectionStatus(\"error\");\n return;\n }\n\n // This is for any Knock errors that would require a reconnect.\n\n setConnectionStatus(\"error\");\n } catch (_error) {\n setConnectionStatus(\"error\");\n }\n };\n\n checkAuthStatus();\n }, [connectionStatus, tenantId, knockSlackChannelId, knock.slack, t]);\n\n return {\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n };\n}\n\nexport default useSlackConnectionStatus;\n"],"names":["formatSlackErrorMessage","errorMessage","firstLetter","substring","toUpperCase","rest","concat","replace","useSlackConnectionStatus","knock","knockSlackChannelId","tenantId","t","useTranslations","connectionStatus","setConnectionStatus","useState","errorLabel","setErrorLabel","actionLabel","setActionLabel","useEffect","authRes","slack","authCheck","tenant","knockChannelId","connection","ok","code","response","data","message","error"],"mappings":"gJA2BMA,EAA2BC,GAAyB,CACxD,MAAMC,EAAcD,EAAaE,UAAU,EAAG,CAAC,EAAEC,YAAY,EACvDC,EAAOJ,EAAaE,UAAU,CAAC,EACrC,OAAOD,GAAAA,YAAAA,EAAaI,OAAOD,GAAME,QAAQ,IAAK,IAChD,EAEA,SAASC,EACPC,EACAC,EACAC,EACgC,CAC1B,KAAA,CAAEC,EAAAA,GAAMC,kBAAgB,EACxB,CAACC,EAAkBC,CAAmB,EAC1CC,EAAAA,SAA2B,YAAY,EACnC,CAACC,EAAYC,CAAa,EAAIF,EAAAA,SAAwB,IAAI,EAC1D,CAACG,EAAaC,CAAc,EAAIJ,EAAAA,SAAwB,IAAI,EAElEK,OAAAA,EAAAA,UAAU,IAAM,EACU,SAAY,mBAClC,GAAIP,IAAqB,aAErB,GAAA,CACF,MAAMQ,EAAU,MAAMb,EAAMc,MAAMC,UAAU,CAC1CC,OAAQd,EACRe,eAAgBhB,CAAAA,CACjB,EAEGY,IAAAA,EAAAA,EAAQK,aAARL,MAAAA,EAAoBM,GACtB,OAAOb,EAAoB,WAAW,EAWtCO,GARE,GAACA,EAAAA,EAAQK,aAARL,MAAAA,EAAoBM,KAQvBN,EAAQO,OAAS,qBACjBP,GAAAA,EAAAA,EAAQQ,WAARR,YAAAA,EAAkBS,OAAlBT,YAAAA,EAAwBU,WAAYpB,EAAE,wBAAwB,EAE9D,OAAOG,EAAoB,cAAc,EAI3C,GAAI,GAACO,EAAAA,EAAQK,aAARL,MAAAA,EAAoBM,OAAMN,EAAAA,EAAQK,aAARL,MAAAA,EAAoBW,OAAO,CACxD,MAAMhB,EAAajB,GAAwBsB,EAAAA,EAAQK,aAARL,YAAAA,EAAoBW,KAAK,EACpEf,EAAcD,CAAU,EACxBF,EAAoB,OAAO,EAC3B,MAAA,CAKFA,EAAoB,OAAO,OACZ,CACfA,EAAoB,OAAO,CAAA,CAE/B,GAEgB,CAAA,EACf,CAACD,EAAkBH,EAAUD,EAAqBD,EAAMc,MAAOX,CAAC,CAAC,EAE7D,CACLE,iBAAAA,EACAC,oBAAAA,EACAE,WAAAA,EACAC,cAAAA,EACAC,YAAAA,EACAC,eAAAA,CACF,CACF"}
1
+ {"version":3,"file":"useSlackConnectionStatus.js","sources":["../../../../../src/modules/slack/hooks/useSlackConnectionStatus.ts"],"sourcesContent":["import Knock from \"@knocklabs/client\";\nimport { useEffect, useState } from \"react\";\n\nimport { useTranslations } from \"../../i18n\";\n\nexport type ConnectionStatus =\n | \"connecting\"\n | \"connected\"\n | \"disconnected\"\n | \"error\"\n | \"disconnecting\";\n\ntype UseSlackConnectionStatusOutput = {\n connectionStatus: ConnectionStatus;\n setConnectionStatus: (status: ConnectionStatus) => void;\n errorLabel: string | null;\n setErrorLabel: (errorLabel: string) => void;\n actionLabel: string | null;\n setActionLabel: (actionLabel: string | null) => void;\n};\n\n/**\n * Transforms a slack error message into\n * a formatted one. Slack error messages: https://api.slack.com/methods/auth.test#errors\n *\n * Ex.: \"account_inactive\" -> \"Account inactive\"\n */\nconst formatSlackErrorMessage = (errorMessage: string) => {\n const firstLetter = errorMessage.substring(0, 1).toUpperCase();\n const rest = errorMessage.substring(1);\n return firstLetter?.concat(rest).replace(\"_\", \" \");\n};\n\nfunction useSlackConnectionStatus(\n knock: Knock,\n knockSlackChannelId: string,\n tenantId: string,\n): UseSlackConnectionStatusOutput {\n const { t } = useTranslations();\n const [connectionStatus, setConnectionStatus] =\n useState<ConnectionStatus>(\"connecting\");\n const [errorLabel, setErrorLabel] = useState<string | null>(null);\n const [actionLabel, setActionLabel] = useState<string | null>(null);\n\n useEffect(() => {\n const checkAuthStatus = async () => {\n if (connectionStatus !== \"connecting\") return;\n\n try {\n const authRes = await knock.slack.authCheck({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n });\n\n if (authRes.connection?.ok) {\n return setConnectionStatus(\"connected\");\n }\n\n // This is a normal response for a tenant that doesn't have an access\n // token set on it, meaning it's not connected to Slack, so we\n // give it a \"disconnected\" status instead of an error status.\n if (\n authRes.code === \"ERR_BAD_REQUEST\" &&\n authRes.response?.data?.message === t(\"slackAccessTokenNotSet\")\n ) {\n return setConnectionStatus(\"disconnected\");\n }\n\n // This is for an error coming directly from Slack.\n if (authRes.connection && authRes.connection.error) {\n const errorLabel = formatSlackErrorMessage(authRes.connection.error);\n setErrorLabel(errorLabel);\n setConnectionStatus(\"error\");\n return;\n }\n\n if (authRes.connection) {\n return setConnectionStatus(\"disconnected\");\n }\n\n setConnectionStatus(\"error\");\n } catch (_error) {\n setConnectionStatus(\"error\");\n }\n };\n\n checkAuthStatus();\n }, [connectionStatus, tenantId, knockSlackChannelId, knock.slack, t]);\n\n return {\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n };\n}\n\nexport default useSlackConnectionStatus;\n"],"names":["formatSlackErrorMessage","errorMessage","firstLetter","substring","toUpperCase","rest","concat","replace","useSlackConnectionStatus","knock","knockSlackChannelId","tenantId","t","useTranslations","connectionStatus","setConnectionStatus","useState","errorLabel","setErrorLabel","actionLabel","setActionLabel","useEffect","authRes","slack","authCheck","tenant","knockChannelId","connection","ok","code","response","data","message","error"],"mappings":"gJA2BMA,EAA2BC,GAAyB,CACxD,MAAMC,EAAcD,EAAaE,UAAU,EAAG,CAAC,EAAEC,YAAY,EACvDC,EAAOJ,EAAaE,UAAU,CAAC,EACrC,OAAOD,GAAAA,YAAAA,EAAaI,OAAOD,GAAME,QAAQ,IAAK,IAChD,EAEA,SAASC,EACPC,EACAC,EACAC,EACgC,CAC1B,KAAA,CAAEC,EAAAA,GAAMC,kBAAgB,EACxB,CAACC,EAAkBC,CAAmB,EAC1CC,EAAAA,SAA2B,YAAY,EACnC,CAACC,EAAYC,CAAa,EAAIF,EAAAA,SAAwB,IAAI,EAC1D,CAACG,EAAaC,CAAc,EAAIJ,EAAAA,SAAwB,IAAI,EAElEK,OAAAA,EAAAA,UAAU,IAAM,EACU,SAAY,WAClC,GAAIP,IAAqB,aAErB,GAAA,CACF,MAAMQ,EAAU,MAAMb,EAAMc,MAAMC,UAAU,CAC1CC,OAAQd,EACRe,eAAgBhB,CAAAA,CACjB,EAEGY,IAAAA,EAAAA,EAAQK,aAARL,MAAAA,EAAoBM,GACtB,OAAOb,EAAoB,WAAW,EAOtCO,GAAAA,EAAQO,OAAS,qBACjBP,GAAAA,EAAAA,EAAQQ,WAARR,YAAAA,EAAkBS,OAAlBT,YAAAA,EAAwBU,WAAYpB,EAAE,wBAAwB,EAE9D,OAAOG,EAAoB,cAAc,EAI3C,GAAIO,EAAQK,YAAcL,EAAQK,WAAWM,MAAO,CAClD,MAAMhB,EAAajB,EAAwBsB,EAAQK,WAAWM,KAAK,EACnEf,EAAcD,CAAU,EACxBF,EAAoB,OAAO,EAC3B,MAAA,CAGF,GAAIO,EAAQK,WACV,OAAOZ,EAAoB,cAAc,EAG3CA,EAAoB,OAAO,OACZ,CACfA,EAAoB,OAAO,CAAA,CAE/B,GAEgB,CAAA,EACf,CAACD,EAAkBH,EAAUD,EAAqBD,EAAMc,MAAOX,CAAC,CAAC,EAE7D,CACLE,iBAAAA,EACAC,oBAAAA,EACAE,WAAAA,EACAC,cAAAA,EACAC,YAAAA,EACAC,eAAAA,CACF,CACF"}
@@ -4,7 +4,7 @@ import { default as f } from "./modules/core/hooks/useStableOptions.mjs";
4
4
  import { FilterStatus as m } from "./modules/core/constants.mjs";
5
5
  import { feedProviderKey as l, formatBadgeCount as i, formatTimestamp as c, msTeamsProviderKey as p, renderNodeOrFallback as x, slackProviderKey as k, toSentenceCase as C } from "./modules/core/utils.mjs";
6
6
  import { KnockFeedProvider as S, useKnockFeed as T } from "./modules/feed/context/KnockFeedProvider.mjs";
7
- import { default as P } from "./modules/feed/hooks/useNotifications.mjs";
7
+ import { default as v } from "./modules/feed/hooks/useNotifications.mjs";
8
8
  import { default as M } from "./modules/feed/hooks/useFeedSettings.mjs";
9
9
  import { useCreateNotificationStore as N, default as y } from "./modules/feed/hooks/useNotificationStore.mjs";
10
10
  import { KnockGuideContext as G, KnockGuideProvider as b } from "./modules/guide/context/KnockGuideProvider.mjs";
@@ -23,6 +23,7 @@ import { default as te } from "./modules/slack/hooks/useSlackAuth.mjs";
23
23
  import { I18nContext as se, KnockI18nProvider as ae } from "./modules/i18n/context/KnockI18nProvider.mjs";
24
24
  import { useTranslations as fe } from "./modules/i18n/hooks/useTranslations.mjs";
25
25
  import { locales as me } from "./modules/i18n/languages/index.mjs";
26
+ import { usePreferences as le } from "./modules/preferences/hooks/usePreferences.mjs";
26
27
  export {
27
28
  m as FilterStatus,
28
29
  se as I18nContext,
@@ -56,7 +57,8 @@ export {
56
57
  w as useMsTeamsConnectionStatus,
57
58
  H as useMsTeamsTeams,
58
59
  y as useNotificationStore,
59
- P as useNotifications,
60
+ v as useNotifications,
61
+ le as usePreferences,
60
62
  te as useSlackAuth,
61
63
  _ as useSlackChannels,
62
64
  Y as useSlackConnectionStatus,
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,37 @@
1
+ import { useCallback as n } from "react";
2
+ import m from "swr";
3
+ import { useKnockClient as p } from "../../core/context/KnockProvider.mjs";
4
+ import "@knocklabs/client";
5
+ import "fast-deep-equal";
6
+ import "date-fns";
7
+ const E = (r = {}) => {
8
+ const e = p(), {
9
+ preferenceSet: t,
10
+ tenant: c
11
+ } = r, a = ["preferences", r.preferenceSet, r.tenant, e.userId], {
12
+ data: o,
13
+ isLoading: u,
14
+ isValidating: f,
15
+ mutate: s
16
+ } = m(e.userId ? a : null, () => e.user.getPreferences({
17
+ preferenceSet: t,
18
+ tenant: c
19
+ })), l = n((i) => {
20
+ s(e.user.setPreferences(i, {
21
+ preferenceSet: t
22
+ }), {
23
+ revalidate: !1
24
+ });
25
+ }, [s, e.user, t]);
26
+ return {
27
+ getAllPreferences: n(async () => await e.user.getAllPreferences(), [e.user]),
28
+ setPreferences: l,
29
+ preferences: o,
30
+ isLoading: u,
31
+ isValidating: f
32
+ };
33
+ };
34
+ export {
35
+ E as usePreferences
36
+ };
37
+ //# sourceMappingURL=usePreferences.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePreferences.mjs","sources":["../../../../../src/modules/preferences/hooks/usePreferences.ts"],"sourcesContent":["import type {\n GetPreferencesOptions,\n PreferenceSet,\n SetPreferencesProperties,\n} from \"@knocklabs/client\";\nimport { useCallback } from \"react\";\nimport useSWR, { type SWRResponse } from \"swr\";\n\nimport { useKnockClient } from \"../../core\";\n\ntype UsePreferencesReturn = {\n preferences: PreferenceSet | undefined;\n setPreferences: (setPreferencesProperties: SetPreferencesProperties) => void;\n getAllPreferences: ReturnType<\n typeof useKnockClient\n >[\"user\"][\"getAllPreferences\"];\n isLoading: SWRResponse[\"isLoading\"];\n isValidating: SWRResponse[\"isValidating\"];\n};\n\nconst usePreferences = (\n options: GetPreferencesOptions = {},\n): UsePreferencesReturn => {\n const knock = useKnockClient();\n\n const { preferenceSet, tenant } = options;\n\n const CACHE_KEY = [\n \"preferences\",\n options.preferenceSet,\n options.tenant,\n knock.userId,\n ];\n\n const {\n data: preferences,\n isLoading,\n isValidating,\n mutate,\n } = useSWR(knock.userId ? CACHE_KEY : null, () => {\n return knock.user.getPreferences({ preferenceSet, tenant });\n });\n\n const setPreferences = useCallback(\n (preferenceSetProperties: SetPreferencesProperties) => {\n mutate(\n knock.user.setPreferences(preferenceSetProperties, { preferenceSet }),\n {\n revalidate: false,\n },\n );\n },\n [mutate, knock.user, preferenceSet],\n );\n\n const getAllPreferences = useCallback(async () => {\n return await knock.user.getAllPreferences();\n }, [knock.user]);\n\n return {\n getAllPreferences,\n setPreferences,\n preferences,\n isLoading,\n isValidating,\n };\n};\n\nexport { usePreferences };\n"],"names":["usePreferences","options","knock","useKnockClient","preferenceSet","tenant","CACHE_KEY","userId","data","preferences","isLoading","isValidating","mutate","useSWR","user","getPreferences","setPreferences","useCallback","preferenceSetProperties","revalidate","getAllPreferences"],"mappings":";;;;;;AAoBA,MAAMA,IAAiBA,CACrBC,IAAiC,OACR;AACzB,QAAMC,IAAQC,EAAe,GAEvB;AAAA,IAAEC,eAAAA;AAAAA,IAAeC,QAAAA;AAAAA,EAAAA,IAAWJ,GAE5BK,IAAY,CAChB,eACAL,EAAQG,eACRH,EAAQI,QACRH,EAAMK,MAAM,GAGR;AAAA,IACJC,MAAMC;AAAAA,IACNC,WAAAA;AAAAA,IACAC,cAAAA;AAAAA,IACAC,QAAAA;AAAAA,MACEC,EAAOX,EAAMK,SAASD,IAAY,MAAM,MACnCJ,EAAMY,KAAKC,eAAe;AAAA,IAAEX,eAAAA;AAAAA,IAAeC,QAAAA;AAAAA,EAAAA,CAAQ,CAC3D,GAEKW,IAAiBC,EACrB,CAACC,MAAsD;AAEnDhB,IAAAA,EAAAA,EAAMY,KAAKE,eAAeE,GAAyB;AAAA,MAAEd,eAAAA;AAAAA,IAAAA,CAAe,GACpE;AAAA,MACEe,YAAY;AAAA,IAAA,CAEhB;AAAA,KAEF,CAACP,GAAQV,EAAMY,MAAMV,CAAa,CACpC;AAMO,SAAA;AAAA,IACLgB,mBALwBH,EAAY,YAC7B,MAAMf,EAAMY,KAAKM,kBAAkB,GACzC,CAAClB,EAAMY,IAAI,CAAC;AAAA,IAIbE,gBAAAA;AAAAA,IACAP,aAAAA;AAAAA,IACAC,WAAAA;AAAAA,IACAC,cAAAA;AAAAA,EACF;AACF;"}
@@ -1,17 +1,17 @@
1
- import { useState as s, useEffect as g } from "react";
1
+ import { useState as s, useEffect as d } from "react";
2
2
  import "../../i18n/context/KnockI18nProvider.mjs";
3
- import { useTranslations as A } from "../../i18n/hooks/useTranslations.mjs";
4
- const C = (o) => {
3
+ import { useTranslations as k } from "../../i18n/hooks/useTranslations.mjs";
4
+ const m = (o) => {
5
5
  const e = o.substring(0, 1).toUpperCase(), c = o.substring(1);
6
6
  return e == null ? void 0 : e.concat(c).replace("_", " ");
7
7
  };
8
- function y(o, e, c) {
8
+ function L(o, e, c) {
9
9
  const {
10
10
  t: a
11
- } = A(), [r, n] = s("connecting"), [b, i] = s(null), [d, m] = s(null);
12
- return g(() => {
11
+ } = k(), [r, n] = s("connecting"), [S, i] = s(null), [h, p] = s(null);
12
+ return d(() => {
13
13
  (async () => {
14
- var u, l, f, k, S, h, p;
14
+ var u, l, f;
15
15
  if (r === "connecting")
16
16
  try {
17
17
  const t = await o.slack.authCheck({
@@ -20,13 +20,15 @@ function y(o, e, c) {
20
20
  });
21
21
  if ((u = t.connection) != null && u.ok)
22
22
  return n("connected");
23
- if (!((l = t.connection) != null && l.ok) || t.code === "ERR_BAD_REQUEST" && ((k = (f = t.response) == null ? void 0 : f.data) == null ? void 0 : k.message) === a("slackAccessTokenNotSet"))
23
+ if (t.code === "ERR_BAD_REQUEST" && ((f = (l = t.response) == null ? void 0 : l.data) == null ? void 0 : f.message) === a("slackAccessTokenNotSet"))
24
24
  return n("disconnected");
25
- if (!((S = t.connection) != null && S.ok) && ((h = t.connection) != null && h.error)) {
26
- const E = C((p = t.connection) == null ? void 0 : p.error);
27
- i(E), n("error");
25
+ if (t.connection && t.connection.error) {
26
+ const b = m(t.connection.error);
27
+ i(b), n("error");
28
28
  return;
29
29
  }
30
+ if (t.connection)
31
+ return n("disconnected");
30
32
  n("error");
31
33
  } catch {
32
34
  n("error");
@@ -35,13 +37,13 @@ function y(o, e, c) {
35
37
  }, [r, c, e, o.slack, a]), {
36
38
  connectionStatus: r,
37
39
  setConnectionStatus: n,
38
- errorLabel: b,
40
+ errorLabel: S,
39
41
  setErrorLabel: i,
40
- actionLabel: d,
41
- setActionLabel: m
42
+ actionLabel: h,
43
+ setActionLabel: p
42
44
  };
43
45
  }
44
46
  export {
45
- y as default
47
+ L as default
46
48
  };
47
49
  //# sourceMappingURL=useSlackConnectionStatus.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useSlackConnectionStatus.mjs","sources":["../../../../../src/modules/slack/hooks/useSlackConnectionStatus.ts"],"sourcesContent":["import Knock from \"@knocklabs/client\";\nimport { useEffect, useState } from \"react\";\n\nimport { useTranslations } from \"../../i18n\";\n\nexport type ConnectionStatus =\n | \"connecting\"\n | \"connected\"\n | \"disconnected\"\n | \"error\"\n | \"disconnecting\";\n\ntype UseSlackConnectionStatusOutput = {\n connectionStatus: ConnectionStatus;\n setConnectionStatus: (status: ConnectionStatus) => void;\n errorLabel: string | null;\n setErrorLabel: (errorLabel: string) => void;\n actionLabel: string | null;\n setActionLabel: (actionLabel: string | null) => void;\n};\n\n/**\n * Transforms a slack error message into\n * a formatted one. Slack error messages: https://api.slack.com/methods/auth.test#errors\n *\n * Ex.: \"account_inactive\" -> \"Account inactive\"\n */\nconst formatSlackErrorMessage = (errorMessage: string) => {\n const firstLetter = errorMessage.substring(0, 1).toUpperCase();\n const rest = errorMessage.substring(1);\n return firstLetter?.concat(rest).replace(\"_\", \" \");\n};\n\nfunction useSlackConnectionStatus(\n knock: Knock,\n knockSlackChannelId: string,\n tenantId: string,\n): UseSlackConnectionStatusOutput {\n const { t } = useTranslations();\n const [connectionStatus, setConnectionStatus] =\n useState<ConnectionStatus>(\"connecting\");\n const [errorLabel, setErrorLabel] = useState<string | null>(null);\n const [actionLabel, setActionLabel] = useState<string | null>(null);\n\n useEffect(() => {\n const checkAuthStatus = async () => {\n if (connectionStatus !== \"connecting\") return;\n\n try {\n const authRes = await knock.slack.authCheck({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n });\n\n if (authRes.connection?.ok) {\n return setConnectionStatus(\"connected\");\n }\n\n if (!authRes.connection?.ok) {\n return setConnectionStatus(\"disconnected\");\n }\n\n // This is a normal response for a tenant that doesn't have an access\n // token set on it, meaning it's not connected to Slack, so we\n // give it a \"disconnected\" status instead of an error status.\n if (\n authRes.code === \"ERR_BAD_REQUEST\" &&\n authRes.response?.data?.message === t(\"slackAccessTokenNotSet\")\n ) {\n return setConnectionStatus(\"disconnected\");\n }\n\n // This is for an error coming directly from Slack.\n if (!authRes.connection?.ok && authRes.connection?.error) {\n const errorLabel = formatSlackErrorMessage(authRes.connection?.error);\n setErrorLabel(errorLabel);\n setConnectionStatus(\"error\");\n return;\n }\n\n // This is for any Knock errors that would require a reconnect.\n\n setConnectionStatus(\"error\");\n } catch (_error) {\n setConnectionStatus(\"error\");\n }\n };\n\n checkAuthStatus();\n }, [connectionStatus, tenantId, knockSlackChannelId, knock.slack, t]);\n\n return {\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n };\n}\n\nexport default useSlackConnectionStatus;\n"],"names":["formatSlackErrorMessage","errorMessage","firstLetter","substring","toUpperCase","rest","concat","replace","useSlackConnectionStatus","knock","knockSlackChannelId","tenantId","t","useTranslations","connectionStatus","setConnectionStatus","useState","errorLabel","setErrorLabel","actionLabel","setActionLabel","useEffect","authRes","slack","authCheck","tenant","knockChannelId","connection","ok","code","response","data","message","error"],"mappings":";;;AA2BA,MAAMA,IAA0BA,CAACC,MAAyB;AACxD,QAAMC,IAAcD,EAAaE,UAAU,GAAG,CAAC,EAAEC,YAAY,GACvDC,IAAOJ,EAAaE,UAAU,CAAC;AACrC,SAAOD,KAAAA,gBAAAA,EAAaI,OAAOD,GAAME,QAAQ,KAAK;AAChD;AAEA,SAASC,EACPC,GACAC,GACAC,GACgC;AAC1B,QAAA;AAAA,IAAEC,GAAAA;AAAAA,MAAMC,EAAgB,GACxB,CAACC,GAAkBC,CAAmB,IAC1CC,EAA2B,YAAY,GACnC,CAACC,GAAYC,CAAa,IAAIF,EAAwB,IAAI,GAC1D,CAACG,GAAaC,CAAc,IAAIJ,EAAwB,IAAI;AAElEK,SAAAA,EAAU,MAAM;AA4CE,KA3CQ,YAAY;;AAClC,UAAIP,MAAqB;AAErB,YAAA;AACF,gBAAMQ,IAAU,MAAMb,EAAMc,MAAMC,UAAU;AAAA,YAC1CC,QAAQd;AAAAA,YACRe,gBAAgBhB;AAAAA,UAAAA,CACjB;AAEGY,eAAAA,IAAAA,EAAQK,eAARL,QAAAA,EAAoBM;AACtB,mBAAOb,EAAoB,WAAW;AAWtCO,cARE,GAACA,IAAAA,EAAQK,eAARL,QAAAA,EAAoBM,OAQvBN,EAAQO,SAAS,uBACjBP,KAAAA,IAAAA,EAAQQ,aAARR,gBAAAA,EAAkBS,SAAlBT,gBAAAA,EAAwBU,aAAYpB,EAAE,wBAAwB;AAE9D,mBAAOG,EAAoB,cAAc;AAI3C,cAAI,GAACO,IAAAA,EAAQK,eAARL,QAAAA,EAAoBM,SAAMN,IAAAA,EAAQK,eAARL,QAAAA,EAAoBW,QAAO;AACxD,kBAAMhB,IAAajB,GAAwBsB,IAAAA,EAAQK,eAARL,gBAAAA,EAAoBW,KAAK;AACpEf,YAAAA,EAAcD,CAAU,GACxBF,EAAoB,OAAO;AAC3B;AAAA,UAAA;AAKFA,UAAAA,EAAoB,OAAO;AAAA,gBACZ;AACfA,UAAAA,EAAoB,OAAO;AAAA,QAAA;AAAA,IAE/B,GAEgB;AAAA,EAAA,GACf,CAACD,GAAkBH,GAAUD,GAAqBD,EAAMc,OAAOX,CAAC,CAAC,GAE7D;AAAA,IACLE,kBAAAA;AAAAA,IACAC,qBAAAA;AAAAA,IACAE,YAAAA;AAAAA,IACAC,eAAAA;AAAAA,IACAC,aAAAA;AAAAA,IACAC,gBAAAA;AAAAA,EACF;AACF;"}
1
+ {"version":3,"file":"useSlackConnectionStatus.mjs","sources":["../../../../../src/modules/slack/hooks/useSlackConnectionStatus.ts"],"sourcesContent":["import Knock from \"@knocklabs/client\";\nimport { useEffect, useState } from \"react\";\n\nimport { useTranslations } from \"../../i18n\";\n\nexport type ConnectionStatus =\n | \"connecting\"\n | \"connected\"\n | \"disconnected\"\n | \"error\"\n | \"disconnecting\";\n\ntype UseSlackConnectionStatusOutput = {\n connectionStatus: ConnectionStatus;\n setConnectionStatus: (status: ConnectionStatus) => void;\n errorLabel: string | null;\n setErrorLabel: (errorLabel: string) => void;\n actionLabel: string | null;\n setActionLabel: (actionLabel: string | null) => void;\n};\n\n/**\n * Transforms a slack error message into\n * a formatted one. Slack error messages: https://api.slack.com/methods/auth.test#errors\n *\n * Ex.: \"account_inactive\" -> \"Account inactive\"\n */\nconst formatSlackErrorMessage = (errorMessage: string) => {\n const firstLetter = errorMessage.substring(0, 1).toUpperCase();\n const rest = errorMessage.substring(1);\n return firstLetter?.concat(rest).replace(\"_\", \" \");\n};\n\nfunction useSlackConnectionStatus(\n knock: Knock,\n knockSlackChannelId: string,\n tenantId: string,\n): UseSlackConnectionStatusOutput {\n const { t } = useTranslations();\n const [connectionStatus, setConnectionStatus] =\n useState<ConnectionStatus>(\"connecting\");\n const [errorLabel, setErrorLabel] = useState<string | null>(null);\n const [actionLabel, setActionLabel] = useState<string | null>(null);\n\n useEffect(() => {\n const checkAuthStatus = async () => {\n if (connectionStatus !== \"connecting\") return;\n\n try {\n const authRes = await knock.slack.authCheck({\n tenant: tenantId,\n knockChannelId: knockSlackChannelId,\n });\n\n if (authRes.connection?.ok) {\n return setConnectionStatus(\"connected\");\n }\n\n // This is a normal response for a tenant that doesn't have an access\n // token set on it, meaning it's not connected to Slack, so we\n // give it a \"disconnected\" status instead of an error status.\n if (\n authRes.code === \"ERR_BAD_REQUEST\" &&\n authRes.response?.data?.message === t(\"slackAccessTokenNotSet\")\n ) {\n return setConnectionStatus(\"disconnected\");\n }\n\n // This is for an error coming directly from Slack.\n if (authRes.connection && authRes.connection.error) {\n const errorLabel = formatSlackErrorMessage(authRes.connection.error);\n setErrorLabel(errorLabel);\n setConnectionStatus(\"error\");\n return;\n }\n\n if (authRes.connection) {\n return setConnectionStatus(\"disconnected\");\n }\n\n setConnectionStatus(\"error\");\n } catch (_error) {\n setConnectionStatus(\"error\");\n }\n };\n\n checkAuthStatus();\n }, [connectionStatus, tenantId, knockSlackChannelId, knock.slack, t]);\n\n return {\n connectionStatus,\n setConnectionStatus,\n errorLabel,\n setErrorLabel,\n actionLabel,\n setActionLabel,\n };\n}\n\nexport default useSlackConnectionStatus;\n"],"names":["formatSlackErrorMessage","errorMessage","firstLetter","substring","toUpperCase","rest","concat","replace","useSlackConnectionStatus","knock","knockSlackChannelId","tenantId","t","useTranslations","connectionStatus","setConnectionStatus","useState","errorLabel","setErrorLabel","actionLabel","setActionLabel","useEffect","authRes","slack","authCheck","tenant","knockChannelId","connection","ok","code","response","data","message","error"],"mappings":";;;AA2BA,MAAMA,IAA0BA,CAACC,MAAyB;AACxD,QAAMC,IAAcD,EAAaE,UAAU,GAAG,CAAC,EAAEC,YAAY,GACvDC,IAAOJ,EAAaE,UAAU,CAAC;AACrC,SAAOD,KAAAA,gBAAAA,EAAaI,OAAOD,GAAME,QAAQ,KAAK;AAChD;AAEA,SAASC,EACPC,GACAC,GACAC,GACgC;AAC1B,QAAA;AAAA,IAAEC,GAAAA;AAAAA,MAAMC,EAAgB,GACxB,CAACC,GAAkBC,CAAmB,IAC1CC,EAA2B,YAAY,GACnC,CAACC,GAAYC,CAAa,IAAIF,EAAwB,IAAI,GAC1D,CAACG,GAAaC,CAAc,IAAIJ,EAAwB,IAAI;AAElEK,SAAAA,EAAU,MAAM;AA0CE,KAzCQ,YAAY;;AAClC,UAAIP,MAAqB;AAErB,YAAA;AACF,gBAAMQ,IAAU,MAAMb,EAAMc,MAAMC,UAAU;AAAA,YAC1CC,QAAQd;AAAAA,YACRe,gBAAgBhB;AAAAA,UAAAA,CACjB;AAEGY,eAAAA,IAAAA,EAAQK,eAARL,QAAAA,EAAoBM;AACtB,mBAAOb,EAAoB,WAAW;AAOtCO,cAAAA,EAAQO,SAAS,uBACjBP,KAAAA,IAAAA,EAAQQ,aAARR,gBAAAA,EAAkBS,SAAlBT,gBAAAA,EAAwBU,aAAYpB,EAAE,wBAAwB;AAE9D,mBAAOG,EAAoB,cAAc;AAI3C,cAAIO,EAAQK,cAAcL,EAAQK,WAAWM,OAAO;AAClD,kBAAMhB,IAAajB,EAAwBsB,EAAQK,WAAWM,KAAK;AACnEf,YAAAA,EAAcD,CAAU,GACxBF,EAAoB,OAAO;AAC3B;AAAA,UAAA;AAGF,cAAIO,EAAQK;AACV,mBAAOZ,EAAoB,cAAc;AAG3CA,UAAAA,EAAoB,OAAO;AAAA,gBACZ;AACfA,UAAAA,EAAoB,OAAO;AAAA,QAAA;AAAA,IAE/B,GAEgB;AAAA,EAAA,GACf,CAACD,GAAkBH,GAAUD,GAAqBD,EAAMc,OAAOX,CAAC,CAAC,GAE7D;AAAA,IACLE,kBAAAA;AAAAA,IACAC,qBAAAA;AAAAA,IACAE,YAAAA;AAAAA,IACAC,eAAAA;AAAAA,IACAC,aAAAA;AAAAA,IACAC,gBAAAA;AAAAA,EACF;AACF;"}
@@ -5,4 +5,5 @@ export { type MsTeamsChannelQueryOptions, type MsTeamsTeamQueryOptions, KnockMsT
5
5
  export { KnockSlackProvider, type ContainerObject, type KnockSlackProviderProps, type KnockSlackProviderState, type SlackChannelQueryOptions, useConnectedSlackChannels, useKnockSlackClient, useSlackAuth, useSlackChannels, useSlackConnectionStatus, } from './modules/slack';
6
6
  export { I18nContext, KnockI18nProvider, locales, type I18nContent, type KnockI18nProviderProps, type Translations, useTranslations, } from './modules/i18n';
7
7
  export { type RecipientObject } from './interfaces';
8
+ export { usePreferences } from './modules/preferences';
8
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,2BAA2B,EAC3B,cAAc,EACd,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,QAAQ,EACb,0BAA0B,EAC1B,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,GACT,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,oBAAoB,EACpB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,0BAA0B,EAC1B,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,yBAAyB,EACzB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,OAAO,EACP,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,KAAK,SAAS,EACd,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,2BAA2B,EAC3B,cAAc,EACd,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,iBAAiB,EACjB,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,QAAQ,EACb,0BAA0B,EAC1B,eAAe,EACf,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,QAAQ,GACT,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,KAAK,0BAA0B,EAC/B,KAAK,uBAAuB,EAC5B,oBAAoB,EACpB,KAAK,yBAAyB,EAC9B,KAAK,yBAAyB,EAC9B,2BAA2B,EAC3B,qBAAqB,EACrB,cAAc,EACd,kBAAkB,EAClB,0BAA0B,EAC1B,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,kBAAkB,EAClB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,wBAAwB,EAC7B,yBAAyB,EACzB,mBAAmB,EACnB,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,WAAW,EACX,iBAAiB,EACjB,OAAO,EACP,KAAK,WAAW,EAChB,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,eAAe,GAChB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { usePreferences } from './usePreferences';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/modules/preferences/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { GetPreferencesOptions, PreferenceSet, SetPreferencesProperties } from '@knocklabs/client';
2
+ import { SWRResponse } from 'swr';
3
+ import { useKnockClient } from '../../core';
4
+ type UsePreferencesReturn = {
5
+ preferences: PreferenceSet | undefined;
6
+ setPreferences: (setPreferencesProperties: SetPreferencesProperties) => void;
7
+ getAllPreferences: ReturnType<typeof useKnockClient>["user"]["getAllPreferences"];
8
+ isLoading: SWRResponse["isLoading"];
9
+ isValidating: SWRResponse["isValidating"];
10
+ };
11
+ declare const usePreferences: (options?: GetPreferencesOptions) => UsePreferencesReturn;
12
+ export { usePreferences };
13
+ //# sourceMappingURL=usePreferences.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePreferences.d.ts","sourceRoot":"","sources":["../../../../../src/modules/preferences/hooks/usePreferences.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,qBAAqB,EACrB,aAAa,EACb,wBAAwB,EACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,KAAK,CAAC;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,KAAK,oBAAoB,GAAG;IAC1B,WAAW,EAAE,aAAa,GAAG,SAAS,CAAC;IACvC,cAAc,EAAE,CAAC,wBAAwB,EAAE,wBAAwB,KAAK,IAAI,CAAC;IAC7E,iBAAiB,EAAE,UAAU,CAC3B,OAAO,cAAc,CACtB,CAAC,MAAM,CAAC,CAAC,mBAAmB,CAAC,CAAC;IAC/B,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACpC,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,CAAC;CAC3C,CAAC;AAEF,QAAA,MAAM,cAAc,GAClB,UAAS,qBAA0B,KAClC,oBA4CF,CAAC;AAEF,OAAO,EAAE,cAAc,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { usePreferences } from './hooks';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/modules/preferences/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useSlackConnectionStatus.d.ts","sourceRoot":"","sources":["../../../../../src/modules/slack/hooks/useSlackConnectionStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAKtC,MAAM,MAAM,gBAAgB,GACxB,YAAY,GACZ,WAAW,GACX,cAAc,GACd,OAAO,GACP,eAAe,CAAC;AAEpB,KAAK,8BAA8B,GAAG;IACpC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,mBAAmB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACtD,CAAC;AAcF,iBAAS,wBAAwB,CAC/B,KAAK,EAAE,KAAK,EACZ,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,GACf,8BAA8B,CA8DhC;AAED,eAAe,wBAAwB,CAAC"}
1
+ {"version":3,"file":"useSlackConnectionStatus.d.ts","sourceRoot":"","sources":["../../../../../src/modules/slack/hooks/useSlackConnectionStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,mBAAmB,CAAC;AAKtC,MAAM,MAAM,gBAAgB,GACxB,YAAY,GACZ,WAAW,GACX,cAAc,GACd,OAAO,GACP,eAAe,CAAC;AAEpB,KAAK,8BAA8B,GAAG;IACpC,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,mBAAmB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACxD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,cAAc,EAAE,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;CACtD,CAAC;AAcF,iBAAS,wBAAwB,CAC/B,KAAK,EAAE,KAAK,EACZ,mBAAmB,EAAE,MAAM,EAC3B,QAAQ,EAAE,MAAM,GACf,8BAA8B,CA4DhC;AAED,eAAe,wBAAwB,CAAC"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@knocklabs/react-core",
3
3
  "description": "A set of React components to build notification experiences powered by Knock",
4
4
  "author": "@knocklabs",
5
- "version": "0.7.1",
5
+ "version": "0.7.3",
6
6
  "license": "MIT",
7
7
  "main": "dist/cjs/index.js",
8
8
  "module": "dist/esm/index.mjs",
@@ -47,7 +47,7 @@
47
47
  "react": "^16.11.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
48
48
  },
49
49
  "dependencies": {
50
- "@knocklabs/client": "^0.15.0",
50
+ "@knocklabs/client": "^0.15.1",
51
51
  "@tanstack/react-store": "^0.7.1",
52
52
  "date-fns": "^4.0.0",
53
53
  "fast-deep-equal": "^3.1.3",
package/src/index.ts CHANGED
@@ -66,3 +66,5 @@ export {
66
66
  useTranslations,
67
67
  } from "./modules/i18n";
68
68
  export { type RecipientObject } from "./interfaces";
69
+
70
+ export { usePreferences } from "./modules/preferences";
@@ -0,0 +1 @@
1
+ export { usePreferences } from "./usePreferences";
@@ -0,0 +1,69 @@
1
+ import type {
2
+ GetPreferencesOptions,
3
+ PreferenceSet,
4
+ SetPreferencesProperties,
5
+ } from "@knocklabs/client";
6
+ import { useCallback } from "react";
7
+ import useSWR, { type SWRResponse } from "swr";
8
+
9
+ import { useKnockClient } from "../../core";
10
+
11
+ type UsePreferencesReturn = {
12
+ preferences: PreferenceSet | undefined;
13
+ setPreferences: (setPreferencesProperties: SetPreferencesProperties) => void;
14
+ getAllPreferences: ReturnType<
15
+ typeof useKnockClient
16
+ >["user"]["getAllPreferences"];
17
+ isLoading: SWRResponse["isLoading"];
18
+ isValidating: SWRResponse["isValidating"];
19
+ };
20
+
21
+ const usePreferences = (
22
+ options: GetPreferencesOptions = {},
23
+ ): UsePreferencesReturn => {
24
+ const knock = useKnockClient();
25
+
26
+ const { preferenceSet, tenant } = options;
27
+
28
+ const CACHE_KEY = [
29
+ "preferences",
30
+ options.preferenceSet,
31
+ options.tenant,
32
+ knock.userId,
33
+ ];
34
+
35
+ const {
36
+ data: preferences,
37
+ isLoading,
38
+ isValidating,
39
+ mutate,
40
+ } = useSWR(knock.userId ? CACHE_KEY : null, () => {
41
+ return knock.user.getPreferences({ preferenceSet, tenant });
42
+ });
43
+
44
+ const setPreferences = useCallback(
45
+ (preferenceSetProperties: SetPreferencesProperties) => {
46
+ mutate(
47
+ knock.user.setPreferences(preferenceSetProperties, { preferenceSet }),
48
+ {
49
+ revalidate: false,
50
+ },
51
+ );
52
+ },
53
+ [mutate, knock.user, preferenceSet],
54
+ );
55
+
56
+ const getAllPreferences = useCallback(async () => {
57
+ return await knock.user.getAllPreferences();
58
+ }, [knock.user]);
59
+
60
+ return {
61
+ getAllPreferences,
62
+ setPreferences,
63
+ preferences,
64
+ isLoading,
65
+ isValidating,
66
+ };
67
+ };
68
+
69
+ export { usePreferences };
@@ -0,0 +1 @@
1
+ export { usePreferences } from "./hooks";
@@ -56,10 +56,6 @@ function useSlackConnectionStatus(
56
56
  return setConnectionStatus("connected");
57
57
  }
58
58
 
59
- if (!authRes.connection?.ok) {
60
- return setConnectionStatus("disconnected");
61
- }
62
-
63
59
  // This is a normal response for a tenant that doesn't have an access
64
60
  // token set on it, meaning it's not connected to Slack, so we
65
61
  // give it a "disconnected" status instead of an error status.
@@ -71,14 +67,16 @@ function useSlackConnectionStatus(
71
67
  }
72
68
 
73
69
  // This is for an error coming directly from Slack.
74
- if (!authRes.connection?.ok && authRes.connection?.error) {
75
- const errorLabel = formatSlackErrorMessage(authRes.connection?.error);
70
+ if (authRes.connection && authRes.connection.error) {
71
+ const errorLabel = formatSlackErrorMessage(authRes.connection.error);
76
72
  setErrorLabel(errorLabel);
77
73
  setConnectionStatus("error");
78
74
  return;
79
75
  }
80
76
 
81
- // This is for any Knock errors that would require a reconnect.
77
+ if (authRes.connection) {
78
+ return setConnectionStatus("disconnected");
79
+ }
82
80
 
83
81
  setConnectionStatus("error");
84
82
  } catch (_error) {