@integry/sdk 4.5.2 → 4.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (279) hide show
  1. package/.vscode/launch.json +2 -2
  2. package/THIRD_PARTY_LICENSES +0 -37
  3. package/dist/esm/index.csm.d.ts +12 -2
  4. package/dist/esm/index.csm.js +7262 -1
  5. package/dist/umd/index.umd.d.ts +9 -1
  6. package/dist/umd/index.umd.js +7262 -1
  7. package/jest.config.cjs +10 -0
  8. package/package.json +10 -4
  9. package/src/components/AddTagButton/index.ts +23 -0
  10. package/src/components/BasicSelect/index.ts +114 -0
  11. package/src/components/BasicSelect/styles.module.scss +44 -0
  12. package/src/components/Button/index.ts +94 -0
  13. package/src/components/Button/styles.module.scss +152 -0
  14. package/src/components/CheckboxGroup/Checkbox.ts +104 -0
  15. package/src/components/CheckboxGroup/index.ts +190 -0
  16. package/src/components/CheckboxGroup/styles.module.scss +63 -0
  17. package/src/components/CollapsedMenu/index.ts +101 -0
  18. package/src/components/CollapsedMenu/styles.module.scss +46 -0
  19. package/src/components/ConfigureFieldWrapper/index.ts +85 -0
  20. package/src/components/ConfigureFieldWrapper/styles.module.scss +57 -0
  21. package/src/components/EditableText/index.ts +121 -0
  22. package/src/components/EditableText/styles.module.scss +38 -0
  23. package/src/components/EditableTextArea/index.ts +143 -0
  24. package/src/components/EditableTextArea/styles.module.scss +91 -0
  25. package/src/components/ErrorMessage/index.ts +16 -0
  26. package/src/components/ErrorMessage/styles.module.scss +19 -0
  27. package/src/components/ErrorPage/index.ts +42 -0
  28. package/src/components/ErrorPage/styles.module.scss +26 -0
  29. package/src/components/Footer/index.ts +41 -0
  30. package/src/components/Footer/styles.module.scss +40 -0
  31. package/src/components/HTMLContent/index.tsx +275 -0
  32. package/src/components/HTMLContent/styles.module.scss +3 -0
  33. package/src/components/InfoBox/index.ts +48 -0
  34. package/src/components/InfoBox/styles.module.scss +21 -0
  35. package/src/components/Input/BaseInput/index.ts +170 -0
  36. package/src/components/Input/BaseInput/styles.module.scss +94 -0
  37. package/src/components/Input/DateInput/index.ts +103 -0
  38. package/src/components/Input/DateInput/styles.module.scss +50 -0
  39. package/src/components/Input/Input/index.ts +206 -0
  40. package/src/components/Input/Input/styles.module.scss +14 -0
  41. package/src/components/Input/PasswordInput/index.ts +164 -0
  42. package/src/components/Input/PasswordInput/styles.module.scss +37 -0
  43. package/src/components/Input/index.ts +7 -0
  44. package/src/components/Label/index.ts +61 -0
  45. package/src/components/Label/styles.module.scss +41 -0
  46. package/src/components/LargeLoader/index.ts +25 -0
  47. package/src/components/LargeLoader/styles.module.scss +16 -0
  48. package/src/components/Listbox/ListBoxItem.ts +57 -0
  49. package/src/components/Listbox/index.ts +479 -0
  50. package/src/components/Listbox/styles.module.scss +197 -0
  51. package/src/components/Loader/index.ts +25 -0
  52. package/src/components/Loader/styles.module.scss +16 -0
  53. package/src/components/MediaGallery/MediaGalleryModal.ts +82 -0
  54. package/src/components/MediaGallery/MediaSlider.ts +76 -0
  55. package/src/components/MediaGallery/index.ts +92 -0
  56. package/src/components/MediaGallery/styles.module.scss +156 -0
  57. package/src/components/MediaUpload/index.ts +233 -0
  58. package/src/components/MediaUpload/styles.module.scss +118 -0
  59. package/src/components/Modal/index.ts +87 -0
  60. package/src/components/Modal/styles.module.scss +441 -0
  61. package/src/components/MultipurposeField/Dropdown/ListBoxItem.tsx +58 -0
  62. package/src/components/MultipurposeField/Dropdown/index.tsx +981 -0
  63. package/src/components/MultipurposeField/Dropdown/styles.module.scss +208 -0
  64. package/src/components/MultipurposeField/TagMenu/index.ts +384 -0
  65. package/src/components/MultipurposeField/TagMenu/styles.module.scss +136 -0
  66. package/src/components/MultipurposeField/TagOptions/index.tsx +83 -0
  67. package/src/components/MultipurposeField/TagOptions/styles.module.scss +95 -0
  68. package/src/components/MultipurposeField/index.tsx +687 -0
  69. package/src/components/MultipurposeField/styles.module.scss +56 -0
  70. package/src/components/NewModal/index.ts +69 -0
  71. package/src/components/NewModal/styles.module.scss +70 -0
  72. package/src/components/OverflowTooltip/index.tsx +59 -0
  73. package/src/components/PopUp/ConfirmationPopUp/index.ts +58 -0
  74. package/src/components/PopUp/ConfirmationPopUp/styles.module.scss +49 -0
  75. package/src/components/PopUp/SuccessPopUp/index.ts +62 -0
  76. package/src/components/PopUp/SuccessPopUp/styles.module.scss +38 -0
  77. package/src/components/RadioGroup/Radio.ts +129 -0
  78. package/src/components/RadioGroup/index.ts +169 -0
  79. package/src/components/RadioGroup/styles.module.scss +81 -0
  80. package/src/components/Search/index.ts +69 -0
  81. package/src/components/Search/styles.module.scss +149 -0
  82. package/src/components/TabBar/Tab.ts +33 -0
  83. package/src/components/TabBar/index.ts +64 -0
  84. package/src/components/TabBar/styles.module.scss +43 -0
  85. package/src/components/Tag/index.ts +29 -0
  86. package/src/components/Tag/styles.module.scss +57 -0
  87. package/src/components/TextArea/index.ts +172 -0
  88. package/src/components/TextArea/styles.module.scss +70 -0
  89. package/src/components/TextContent/index.tsx +128 -0
  90. package/src/components/TextContent/styles.module.scss +6 -0
  91. package/src/components/ThreeDotLoader/index.ts +39 -0
  92. package/src/components/ThreeDotLoader/styles.module.scss +41 -0
  93. package/src/components/TimeInput/index.ts +129 -0
  94. package/src/components/TimeInput/styles.module.scss +16 -0
  95. package/src/components/Toggle/index.ts +34 -0
  96. package/src/components/Toggle/styles.module.scss +56 -0
  97. package/src/components/Toggle-v2/index.ts +40 -0
  98. package/src/components/Toggle-v2/styles.module.scss +86 -0
  99. package/src/components/Tooltip/index.ts +271 -0
  100. package/src/components/Tooltip/styles.module.scss +105 -0
  101. package/src/components/form/ObjectField/index.ts +364 -0
  102. package/src/components/form/ObjectField/styles.module.scss +103 -0
  103. package/src/components/form/index.ts +3 -0
  104. package/src/contexts/AppContext.ts +12 -0
  105. package/src/declaration.d.ts +7 -0
  106. package/src/extensions/HMAC.ts +25 -0
  107. package/src/extensions/IntegryAPIError.ts +19 -0
  108. package/src/features/common/AccountDropdown/index.ts +291 -0
  109. package/src/features/common/AccountDropdown/styles.module.scss +19 -0
  110. package/src/features/common/ActionForm/index.ts +1818 -0
  111. package/src/features/common/ActionForm/styles.module.scss +23 -0
  112. package/src/features/common/AppCard/index.ts +207 -0
  113. package/src/features/common/AppCard/styles.module.scss +117 -0
  114. package/src/features/common/AppCardCompact/index.ts +189 -0
  115. package/src/features/common/AppCardCompact/styles.module.scss +141 -0
  116. package/src/features/common/AuthSelector/index.ts +537 -0
  117. package/src/features/common/AuthSelector/styles.module.scss +161 -0
  118. package/src/features/common/AuthSelectorCompact/index.ts +706 -0
  119. package/src/features/common/AuthSelectorCompact/styles.module.scss +219 -0
  120. package/src/features/common/AuthSelectorDropdown/index.ts +704 -0
  121. package/src/features/common/AuthSelectorDropdown/styles.module.scss +361 -0
  122. package/src/features/common/DynamicField/index.ts +229 -0
  123. package/src/features/common/DynamicField/styles.module.scss +67 -0
  124. package/src/features/common/DynamicTypedField/index.ts +217 -0
  125. package/src/features/common/DynamicTypedField/styles.module.scss +67 -0
  126. package/src/features/common/FunctionForm/index.ts +862 -0
  127. package/src/features/common/FunctionForm/styles.module.scss +163 -0
  128. package/src/features/common/MappingUI/index.ts +649 -0
  129. package/src/features/common/MappingUI/styles.module.scss +121 -0
  130. package/src/features/common/MarketplaceAppCard/index.ts +279 -0
  131. package/src/features/common/MarketplaceAppCard/styles.module.scss +231 -0
  132. package/src/features/common/MarketplaceAppCardCompact/index.ts +283 -0
  133. package/src/features/common/MarketplaceAppCardCompact/styles.module.scss +255 -0
  134. package/src/features/common/NewMappingUI/index.ts +515 -0
  135. package/src/features/common/NewMappingUI/styles.module.scss +113 -0
  136. package/src/features/common/RequestAppWidget/RequestAppModal/index.ts +67 -0
  137. package/src/features/common/RequestAppWidget/RequestAppModal/styles.module.scss +23 -0
  138. package/src/features/common/RequestAppWidget/index.ts +48 -0
  139. package/src/features/common/RequestAppWidget/request-app-form.ts +89 -0
  140. package/src/features/common/RequestAppWidget/styles.module.scss +43 -0
  141. package/src/features/common/SectionField/index.ts +272 -0
  142. package/src/features/common/SectionField/styles.module.scss +67 -0
  143. package/src/features/common/Step/index.ts +827 -0
  144. package/src/features/common/Step/styles.module.scss +12 -0
  145. package/src/features/common/StepNavigation/CollapsedSteps.ts +125 -0
  146. package/src/features/common/StepNavigation/NavItem.ts +111 -0
  147. package/src/features/common/StepNavigation/index.ts +257 -0
  148. package/src/features/common/StepNavigation/styles.module.scss +117 -0
  149. package/src/features/common/Steps/index.ts +1139 -0
  150. package/src/features/common/Steps/styles.module.scss +314 -0
  151. package/src/features/containers/AppFlowContainer/AppFlowListing/compactStyles.module.scss +383 -0
  152. package/src/features/containers/AppFlowContainer/AppFlowListing/flow-instance.tsx +367 -0
  153. package/src/features/containers/AppFlowContainer/AppFlowListing/flowCard.tsx +194 -0
  154. package/src/features/containers/AppFlowContainer/AppFlowListing/flowCardCompact.tsx +389 -0
  155. package/src/features/containers/AppFlowContainer/AppFlowListing/flowInstanceCompact.tsx +577 -0
  156. package/src/features/containers/AppFlowContainer/AppFlowListing/index.tsx +83 -0
  157. package/src/features/containers/AppFlowContainer/AppFlowListing/styles.module.scss +212 -0
  158. package/src/features/containers/AppFlowContainer/AppFlowWrap/app-page-loader.tsx +45 -0
  159. package/src/features/containers/AppFlowContainer/AppFlowWrap/index.tsx +1081 -0
  160. package/src/features/containers/AppFlowContainer/AppFlowWrap/styles.module.scss +452 -0
  161. package/src/features/containers/AppFlowContainer/Authentication/index.ts +610 -0
  162. package/src/features/containers/AppFlowContainer/Authentication/styles.module.scss +468 -0
  163. package/src/features/containers/AppFlowContainer/index.ts +114 -0
  164. package/src/features/containers/AppPageContainer/AppPage/index.tsx +262 -0
  165. package/src/features/containers/AppPageContainer/AppPage/styles.module.scss +120 -0
  166. package/src/features/containers/AppPageContainer/IntegrationCard/index.ts +165 -0
  167. package/src/features/containers/AppPageContainer/IntegrationCard/styles.module.scss +81 -0
  168. package/src/features/containers/AppPageContainer/index.tsx +93 -0
  169. package/src/features/containers/AppPageContainer/styles.module.scss +0 -0
  170. package/src/features/containers/AppsForFlows/index.ts +161 -0
  171. package/src/features/containers/AppsForFlows/styles.module.scss +280 -0
  172. package/src/features/containers/AppsForFlowsCompact/index.ts +161 -0
  173. package/src/features/containers/AppsForFlowsCompact/styles.module.scss +279 -0
  174. package/src/features/containers/AuthSetupContainer/AppSelection.ts +73 -0
  175. package/src/features/containers/AuthSetupContainer/AuthTypeSelection.ts +67 -0
  176. package/src/features/containers/AuthSetupContainer/Footer.ts +32 -0
  177. package/src/features/containers/AuthSetupContainer/Header.ts +39 -0
  178. package/src/features/containers/AuthSetupContainer/PostAdditionPopup.ts +27 -0
  179. package/src/features/containers/AuthSetupContainer/index.ts +349 -0
  180. package/src/features/containers/AuthSetupContainer/styles.module.scss +229 -0
  181. package/src/features/containers/FlowSetupContainer/index.ts +390 -0
  182. package/src/features/containers/FlowSetupContainer/styles.module.scss +18 -0
  183. package/src/features/containers/MarkeplaceApps/index.ts +574 -0
  184. package/src/features/containers/MarkeplaceApps/styles.module.scss +559 -0
  185. package/src/features/containers/MarketplaceAppsCompact/index.ts +576 -0
  186. package/src/features/containers/MarketplaceAppsCompact/styles.module.scss +546 -0
  187. package/src/features/containers/MarketplaceAppsContainer/index.ts +83 -0
  188. package/src/features/containers/MarketplaceContainer/AppCard/index.ts +91 -0
  189. package/src/features/containers/MarketplaceContainer/AppCard/styles.module.scss +66 -0
  190. package/src/features/containers/MarketplaceContainer/AppListing/index.ts +34 -0
  191. package/src/features/containers/MarketplaceContainer/AppListing/styles.module.scss +10 -0
  192. package/src/features/containers/MarketplaceContainer/MarketplaceContentWrap/index.ts +132 -0
  193. package/src/features/containers/MarketplaceContainer/MarketplaceContentWrap/styles.module.scss +117 -0
  194. package/src/features/containers/MarketplaceContainer/index.ts +242 -0
  195. package/src/features/containers/MarketplaceContainer/styles.module.scss +84 -0
  196. package/src/features/containers/SDKContainer/index.ts +817 -0
  197. package/src/features/containers/SDKContainer/styles.module.scss +266 -0
  198. package/src/features/containers/SDKDebugContainer/index.ts +137 -0
  199. package/src/features/containers/SDKDebugContainer/styles.module.scss +37 -0
  200. package/src/features/containers/SDKFailedContainer/index.ts +117 -0
  201. package/src/features/containers/SDKFailedContainer/styles.module.scss +57 -0
  202. package/src/features/integrations/IntegrationRow/Icons.ts +77 -0
  203. package/src/features/integrations/IntegrationRow/index.ts +129 -0
  204. package/src/features/integrations/IntegrationRow/styles.module.scss +62 -0
  205. package/src/features/integrations/IntegrationsHeader/index.ts +34 -0
  206. package/src/features/integrations/IntegrationsHeader/styles.module.scss +47 -0
  207. package/src/features/integrations/IntegrationsList/index.ts +252 -0
  208. package/src/features/integrations/IntegrationsList/styles.module.scss +67 -0
  209. package/src/features/templates/Template/index.ts +295 -0
  210. package/src/features/templates/Template/styles.module.scss +226 -0
  211. package/src/features/templates/TemplatesView/index.ts +368 -0
  212. package/src/features/templates/TemplatesView/styles.module.scss +71 -0
  213. package/src/features/templates/TemplatesViewCompact/index.ts +364 -0
  214. package/src/features/templates/TemplatesViewCompact/styles.module.scss +141 -0
  215. package/src/hooks/useAutosizeTextArea.ts +22 -0
  216. package/src/hooks/useCustomRef.ts +13 -0
  217. package/src/hooks/useDebounce.ts +17 -0
  218. package/src/hooks/useElementResize.ts +40 -0
  219. package/src/hooks/useEventListener.ts +44 -0
  220. package/src/hooks/useHover.ts +40 -0
  221. package/src/hooks/useOnClickOutside.ts +32 -0
  222. package/src/index.ts +2051 -0
  223. package/src/index.umd.ts +13 -0
  224. package/src/interfaces/index.ts +924 -0
  225. package/src/modules/api/index.ts +1315 -0
  226. package/src/modules/api/responseHandler.ts +38 -0
  227. package/src/modules/event-emitter/index.ts +72 -0
  228. package/src/modules/event-emitter/runners/abstract.ts +21 -0
  229. package/src/modules/event-emitter/runners/default.ts +11 -0
  230. package/src/modules/event-emitter/runners/ntimes.ts +28 -0
  231. package/src/modules/event-emitter/types.ts +34 -0
  232. package/src/store/actionFunctions.ts +1573 -0
  233. package/src/store/index.ts +17 -0
  234. package/src/store/initialState.ts +58 -0
  235. package/src/stories/Button.stories.tsx +83 -0
  236. package/src/stories/Checkbox/Checkbox.stories.tsx +41 -0
  237. package/src/stories/Checkbox/CheckboxGroup.stories.tsx +46 -0
  238. package/src/stories/EditableText.stories.tsx +35 -0
  239. package/src/stories/Input/BaseInput.stories.tsx +48 -0
  240. package/src/stories/Input/DateInput.stories.tsx +28 -0
  241. package/src/stories/Input/Input.stories.tsx +24 -0
  242. package/src/stories/Input/PasswordInput.stories.tsx +26 -0
  243. package/src/stories/Introduction.stories.mdx +211 -0
  244. package/src/stories/Label.stories.tsx +27 -0
  245. package/src/stories/Listbox.stories.tsx +122 -0
  246. package/src/stories/Radio/Radio.stories.tsx +39 -0
  247. package/src/stories/Radio/RadioGroup.stories.tsx +46 -0
  248. package/src/stories/StepNavigation/NavItem.stories.tsx +31 -0
  249. package/src/stories/StepNavigation/StepNavigation.stories.tsx +50 -0
  250. package/src/stories/TabBar.stories.tsx +31 -0
  251. package/src/stories/TextArea.stories.tsx +23 -0
  252. package/src/stories/TimeInput.stories.tsx +37 -0
  253. package/src/stories/Toggle.stories.tsx +33 -0
  254. package/src/stories/assets/code-brackets.svg +1 -0
  255. package/src/stories/assets/colors.svg +1 -0
  256. package/src/stories/assets/comments.svg +1 -0
  257. package/src/stories/assets/direction.svg +1 -0
  258. package/src/stories/assets/flow.svg +1 -0
  259. package/src/stories/assets/plugin.svg +1 -0
  260. package/src/stories/assets/repo.svg +1 -0
  261. package/src/stories/assets/stackalt.svg +1 -0
  262. package/src/types/index.ts +293 -0
  263. package/src/types/store.ts +366 -0
  264. package/src/types/utils.ts +19 -0
  265. package/src/utils/ActivityOutputUtils.ts +163 -0
  266. package/src/utils/common.ts +20 -0
  267. package/src/utils/copyToClipboard.ts +24 -0
  268. package/src/utils/datetime.ts +101 -0
  269. package/src/utils/getUrlParam.ts +11 -0
  270. package/src/utils/isAuthMessage.ts +16 -0
  271. package/src/utils/isBrowser.ts +1 -0
  272. package/src/utils/jsonEncodeDecode.ts +15 -0
  273. package/src/utils/objectUtils.ts +116 -0
  274. package/src/utils/popup.ts +30 -0
  275. package/src/utils/searchJson.ts +51 -0
  276. package/src/utils/stepUtils.ts +45 -0
  277. package/src/utils/truncate.ts +6 -0
  278. package/test/setup.ts +1 -0
  279. package/vitest.config.ts +10 -0
package/src/index.ts ADDED
@@ -0,0 +1,2051 @@
1
+ import { html, render } from 'htm/preact';
2
+ import { Provider } from 'unistore/preact';
3
+
4
+ import { IntegryAPI } from '@/modules/api';
5
+ import {
6
+ InitConfig,
7
+ ConfigWithObject,
8
+ ConfigWithUrlParams,
9
+ APIConfig,
10
+ PreviewPayload,
11
+ MarketplaceConfig,
12
+ MultipurposeFieldType,
13
+ ConnectedAccount,
14
+ MarketplaceApp,
15
+ } from '@/interfaces';
16
+
17
+ import { HMAC } from '@/extensions/HMAC';
18
+
19
+ import { EventEmitter } from '@/modules/event-emitter';
20
+ import AppContext from '@/contexts/AppContext';
21
+
22
+ import {
23
+ IntegrySDKEvents,
24
+ MarketplaceRenderModes,
25
+ TemplateFormRenderModes,
26
+ TemplateListingRenderModes,
27
+ ViewStyles,
28
+ RenderModes,
29
+ Layouts,
30
+ SetupIntegrationOptions,
31
+ } from '@/types';
32
+
33
+ import { createSDKStore, initialState } from '@/store';
34
+ import isBrowser from '@/utils/isBrowser';
35
+ import { getUrlParam } from '@/utils/getUrlParam';
36
+
37
+ import SDKContainer from '@/features/containers/SDKContainer';
38
+ import SDKFailedContainer from '@/features/containers/SDKFailedContainer';
39
+ import AuthSetupContainer from '@/features/containers/AuthSetupContainer';
40
+ import FlowSetupContainer from '@/features/containers/FlowSetupContainer';
41
+ import MarketplaceContainer from '@/features/containers/MarketplaceContainer';
42
+ import AppFlowContainer from '@/features/containers/AppFlowContainer';
43
+ import MarketplaceAppsContainer from '@/features/containers/MarketplaceAppsContainer';
44
+
45
+ import FunctionForm from '@/features/common/FunctionForm';
46
+ import { openPopupWindow } from '@/utils/popup';
47
+ import { Modal } from '@/components/Modal';
48
+ import { ListBox } from '@/components/MultipurposeField/Dropdown';
49
+ import { MultipurposeField } from './components/MultipurposeField';
50
+ import SDKDebugContainer from './features/containers/SDKDebugContainer';
51
+
52
+ const Helpers = { getAuthHash: HMAC };
53
+
54
+ // eslint-disable-next-line no-underscore-dangle
55
+ const __buildVersion__ = '';
56
+
57
+ /**
58
+ * Integry JS SDK
59
+ */
60
+ export class IntegryJS {
61
+ static SDK_VERSION = __buildVersion__;
62
+
63
+ private config: ConfigWithObject & ConfigWithUrlParams;
64
+
65
+ private apiHandler: IntegryAPI;
66
+
67
+ private initConfig: InitConfig;
68
+
69
+ eventEmitter = new EventEmitter<IntegrySDKEvents>();
70
+
71
+ // allow customers to use template tagging
72
+ static html = html;
73
+
74
+ static RenderModes: typeof RenderModes = RenderModes;
75
+
76
+ static TemplateFormRenderModes: typeof TemplateFormRenderModes = TemplateFormRenderModes;
77
+
78
+ static Layouts: typeof Layouts = Layouts;
79
+
80
+ static ViewStyles: typeof ViewStyles = ViewStyles;
81
+
82
+ static MarketplaceRenderModes: typeof MarketplaceRenderModes = MarketplaceRenderModes;
83
+
84
+ static Helpers: {
85
+ getAuthHash: (key: string, message: string) => Promise<string>;
86
+ };
87
+
88
+ private authModalId = '';
89
+
90
+ private forceRerender = false;
91
+
92
+ constructor(config: ConfigWithObject | ConfigWithUrlParams) {
93
+ let integryAPIParams: APIConfig;
94
+
95
+ const baseUrl = config.baseUrl || 'https://app.integry.io';
96
+
97
+ const baseAPIUrl = 'https://api.integry.io';
98
+
99
+ const configUpdated = config;
100
+
101
+ // perform the overrides according to new configuration syntax
102
+ if (configUpdated.user) {
103
+ const { userId, apiKey, ...extras } = configUpdated.user;
104
+ if (!('userId' in configUpdated)) {
105
+ (configUpdated as any).userId = '';
106
+ }
107
+ if ('userId' in configUpdated) {
108
+ configUpdated.userId = userId.toString();
109
+ }
110
+ if (!configUpdated.xIntegryConfig) {
111
+ configUpdated.xIntegryConfig = {};
112
+ }
113
+
114
+ if (!configUpdated.xIntegryConfig.appAuth) {
115
+ configUpdated.xIntegryConfig.appAuth = {};
116
+ }
117
+
118
+ if (!configUpdated.xIntegryConfig.appAuth.extras) {
119
+ configUpdated.xIntegryConfig.appAuth.extras = {};
120
+ }
121
+
122
+ configUpdated.xIntegryConfig.appAuth.apiKey = (apiKey || '').toString();
123
+ configUpdated.xIntegryConfig.appAuth.extras = extras as Record<
124
+ string,
125
+ string | number
126
+ >;
127
+ }
128
+
129
+ const apiConfig = {
130
+ oauthVerifyPath: 'auth/verify',
131
+ endpointsUrl: 'https://integry-app.appspot.com',
132
+ baseUrl,
133
+ baseUrlv2: `${baseUrl}/v2`,
134
+ baseAPIUrl: `${baseAPIUrl}`,
135
+ apiKey: configUpdated.xIntegryConfig?.appAuth?.apiKey,
136
+ authId: configUpdated.xIntegryConfig?.appAuth?.authId,
137
+ extras: configUpdated.xIntegryConfig?.appAuth?.extras,
138
+ };
139
+
140
+ const userConfig = configUpdated.options || configUpdated.userConfig || {};
141
+ if (configUpdated.options && configUpdated.payloads) {
142
+ configUpdated.options.objects = config.payloads;
143
+ }
144
+
145
+ if ('appKey' in configUpdated) {
146
+ integryAPIParams = {
147
+ ...configUpdated,
148
+ ...apiConfig,
149
+ appKey: configUpdated.appKey,
150
+ hash: configUpdated.hash,
151
+ userId: configUpdated.userId,
152
+ };
153
+ this.config = {
154
+ ...configUpdated,
155
+ ...apiConfig,
156
+ appKey: configUpdated.appKey,
157
+ hash: configUpdated.hash,
158
+ userId: configUpdated.userId,
159
+ deploymentId: configUpdated.deploymentId,
160
+ userConfig: configUpdated.deploymentId
161
+ ? {
162
+ ...userConfig,
163
+ tags: userConfig?.tags
164
+ ? [...userConfig?.tags, `${configUpdated.deploymentId}`]
165
+ : [`${configUpdated.deploymentId}`],
166
+ }
167
+ : userConfig,
168
+ };
169
+ } else {
170
+ const urlparams = this.getAuthParamsFromUrl() || {};
171
+ integryAPIParams = {
172
+ ...apiConfig,
173
+ ...urlparams,
174
+ };
175
+ this.config = {
176
+ ...apiConfig,
177
+ ...urlparams,
178
+ userConfig: configUpdated.userConfig,
179
+ };
180
+ }
181
+ this.authModalId = this.getRandomFlowId(6);
182
+ this.apiHandler = new IntegryAPI(integryAPIParams);
183
+ this.verifyAuthConfig()
184
+ .then((response) => {
185
+ if (!response?.config_verified) {
186
+ console.error(
187
+ 'IntegrySDK: Auth config verification failed, are your auth parameters correct?',
188
+ );
189
+ } else {
190
+ this.eventEmitter.emit('ready', {
191
+ isReady: true,
192
+ });
193
+ }
194
+ })
195
+ .catch((err) => console.error(err));
196
+ this.initConfig = {
197
+ containerId: '',
198
+ renderMode: TemplateFormRenderModes.INLINE,
199
+ };
200
+ }
201
+
202
+ /**
203
+ * Handler function when SDK has failed to load.
204
+ */
205
+ private SDKFailedHandler = (config: any, containerId: string) => {
206
+ const userConfig = config.options || config.userConfig || {};
207
+ const targetEl = document.getElementById(containerId);
208
+ if (targetEl) {
209
+ render(
210
+ html`
211
+ <${SDKFailedContainer}
212
+ message="SDK failed to load"
213
+ debug=${userConfig.debug}
214
+ config=${userConfig.debug ? config : null}
215
+ >
216
+ <//>
217
+ `,
218
+ targetEl,
219
+ );
220
+ }
221
+ throw new Error('IntegrySDK: SDK failed to load');
222
+ };
223
+
224
+ /**
225
+ *
226
+ * @param length Length of string to randomly generate
227
+ * @returns {string} Returns a random string
228
+ */
229
+ private getRandomFlowId = (length: number): string => {
230
+ const result = [];
231
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
232
+ const charactersLength = characters.length;
233
+ for (let i = 0; i < length; i += 1) {
234
+ result.push(
235
+ characters.charAt(Math.floor(Math.random() * charactersLength)),
236
+ );
237
+ }
238
+ return `x-integry-modal-${result.join('')}`;
239
+ };
240
+
241
+ private getAuthParamsFromUrl = (): ConfigWithObject => {
242
+ const urlParams =
243
+ isBrowser() && new URLSearchParams(window.location.search);
244
+ if (urlParams) {
245
+ const userId = urlParams.get('user_id');
246
+ const appKey = urlParams.get('app_key');
247
+ const hash = urlParams.get('hash');
248
+ const deploymentId = urlParams.get('deployment_id');
249
+ if (!userId || !appKey || !hash || !deploymentId) {
250
+ throw new Error(
251
+ `The following auth variables are undefined: ${
252
+ !userId ? 'userId' : ''
253
+ } ${!appKey ? 'appKey' : ''} ${!hash ? 'hash' : ''} ${
254
+ !deploymentId ? 'deploymentId' : ''
255
+ }`,
256
+ );
257
+ }
258
+ return {
259
+ userId,
260
+ appKey,
261
+ hash,
262
+ deploymentId,
263
+ };
264
+ }
265
+ return {
266
+ userId: '',
267
+ appKey: '',
268
+ hash: '',
269
+ deploymentId: '',
270
+ };
271
+ };
272
+
273
+ /**
274
+ * Prints version number of this SDK version
275
+ */
276
+ public printVersion = (): void => {
277
+ console.info(`@integry/sdk@${IntegryJS.SDK_VERSION}`);
278
+ };
279
+
280
+ /**
281
+ *
282
+ * @param renderMode
283
+ * @param templateContainerId
284
+ * @returns {HTMLElement | null}
285
+ */
286
+ private setupFlowFormDestination = (
287
+ renderMode: TemplateFormRenderModes,
288
+ templateContainerId?: string,
289
+ ): HTMLElement | null => {
290
+ let el: HTMLElement | null = null;
291
+
292
+ if (templateContainerId) {
293
+ if (
294
+ renderMode === TemplateFormRenderModes.MODAL ||
295
+ renderMode === TemplateFormRenderModes.INLINE
296
+ ) {
297
+ throw new Error(
298
+ 'The `templateContainerId` property is unsupported when render mode is set to "MODAL" or "INLINE"',
299
+ );
300
+ }
301
+ el = document.getElementById(templateContainerId);
302
+ if (!el) {
303
+ console.warn(
304
+ `The template form render target with id ${templateContainerId} was not found`,
305
+ );
306
+ // throw new Error('The template form render target was not found');
307
+ }
308
+ }
309
+
310
+ switch (renderMode) {
311
+ case TemplateFormRenderModes.MODAL:
312
+ el = document.createElement('div');
313
+ el.id = this.getRandomFlowId(8);
314
+ document.body.appendChild(el);
315
+ return el;
316
+ case TemplateFormRenderModes.INLINE:
317
+ return null;
318
+ case TemplateFormRenderModes.DETACHED:
319
+ return el;
320
+ case TemplateFormRenderModes.CUSTOM:
321
+ return el;
322
+ default:
323
+ throw new Error(
324
+ `Unsupported renderMode ${renderMode} configuration, please provide one of ${JSON.stringify(
325
+ Object.keys(TemplateFormRenderModes),
326
+ )}`,
327
+ );
328
+ }
329
+ };
330
+
331
+ /**
332
+ * Render the template form we ship
333
+ * @param data
334
+ */
335
+ public renderFlowSetupForm = (data: {
336
+ flowId?: string;
337
+ integrationId?: number;
338
+ flowContainerId: string;
339
+ versionId?: number;
340
+ viewStyle?: string;
341
+ }): void => {
342
+ const { flowId, flowContainerId, versionId, viewStyle } = data;
343
+ const targetEl = document.getElementById(flowContainerId);
344
+ if (!targetEl) {
345
+ console.warn(
346
+ `Integry template form render target with id ${flowContainerId} was not found`,
347
+ );
348
+ return;
349
+ }
350
+ let parsedFlowId = Number(flowId);
351
+ let parsedIntegrationId = this.config.integrationId || data.integrationId;
352
+
353
+ if (!parsedIntegrationId) {
354
+ parsedIntegrationId = Number(getUrlParam('integrationId'));
355
+ }
356
+
357
+ if (!parsedFlowId) {
358
+ parsedFlowId = Number(getUrlParam('flowId'));
359
+ }
360
+
361
+ const store = createSDKStore();
362
+
363
+ store.setState({
364
+ integrationIdToEdit: parsedIntegrationId,
365
+ userConfig: this.config.userConfig,
366
+ genericData: {
367
+ ...initialState.genericData,
368
+ implicitAuthEnabled: !!this.config.xIntegryConfig?.appAuth?.apiKey,
369
+ deploymentId: Number(this.config.deploymentId),
370
+ isAnonymous: !!this.config.xIntegryConfig?.isAnonymous,
371
+ viewStyle: viewStyle || ViewStyles.COMFORTABLE,
372
+ testMultipurpose: true,
373
+ customFlowSetupRender: true,
374
+ },
375
+ });
376
+
377
+ render(
378
+ html`
379
+ <${AppContext.Provider}
380
+ value=${{
381
+ apiHandler: this.apiHandler,
382
+ eventEmitter: this.eventEmitter,
383
+ isPreviewMode: false,
384
+ }}
385
+ >
386
+ <${Provider} store=${store} key=${this.getRandomFlowId(10)}>
387
+ <${SDKContainer}
388
+ deploymentId=${this.config.deploymentId}
389
+ userConfig=${this.config.userConfig}
390
+ layout=${TemplateListingRenderModes.LIST}
391
+ renderMode=${this.initConfig.renderMode}
392
+ renderFlowsMode=${this.initConfig.renderFlowsMode ||
393
+ TemplateFormRenderModes.INLINE}
394
+ flowId=${parsedFlowId}
395
+ integrationId=${parsedIntegrationId}
396
+ >
397
+ <//>
398
+ <//>
399
+ <//>
400
+ `,
401
+ targetEl,
402
+ );
403
+ };
404
+
405
+ public setupIntegration = (
406
+ flowId: string,
407
+ options: SetupIntegrationOptions = {
408
+ containerId: 'integry-marketplace',
409
+ renderMode: RenderModes.MODAL,
410
+ layout: Layouts.WIDE,
411
+ params: {},
412
+ },
413
+ ): void => {
414
+ const targetEl = document.getElementById(options.containerId || '');
415
+ if (!targetEl) {
416
+ console.warn(
417
+ `Integry template form render target with id ${options.containerId} was not found`,
418
+ );
419
+ return;
420
+ }
421
+ let parsedFlowId = Number(flowId);
422
+ let parsedIntegrationId = options.integrationId || null;
423
+
424
+ if (!parsedIntegrationId) {
425
+ parsedIntegrationId = Number(getUrlParam('integrationId'));
426
+ }
427
+
428
+ if (!parsedFlowId) {
429
+ parsedFlowId = Number(getUrlParam('flowId'));
430
+ }
431
+
432
+ const store = createSDKStore();
433
+
434
+ store.setState({
435
+ integrationIdToEdit: parsedIntegrationId,
436
+ userConfig: this.config.userConfig,
437
+ genericData: {
438
+ ...initialState.genericData,
439
+ implicitAuthEnabled: !!this.config.xIntegryConfig?.appAuth?.apiKey,
440
+ deploymentId: Number(this.config.deploymentId),
441
+ isAnonymous: !!this.config.xIntegryConfig?.isAnonymous,
442
+ viewStyle: options.layout || ViewStyles.COMFORTABLE,
443
+ testMultipurpose: true,
444
+ customFlowSetupRender: true,
445
+ },
446
+ });
447
+
448
+ render(
449
+ html`
450
+ <${AppContext.Provider}
451
+ value=${{
452
+ apiHandler: this.apiHandler,
453
+ eventEmitter: this.eventEmitter,
454
+ isPreviewMode: false,
455
+ }}
456
+ >
457
+ <${Provider} store=${store} key=${this.getRandomFlowId(10)}>
458
+ <${SDKContainer}
459
+ deploymentId=${this.config.deploymentId}
460
+ userConfig=${this.config.userConfig}
461
+ layout=${TemplateListingRenderModes.LIST}
462
+ renderMode=${options.renderMode}
463
+ renderFlowsMode=${options.renderMode}
464
+ flowId=${parsedFlowId}
465
+ integrationId="${parsedIntegrationId}"
466
+ params=${options.params}
467
+ >
468
+ <//>
469
+ <//>
470
+ <//>
471
+ `,
472
+ targetEl,
473
+ );
474
+ };
475
+
476
+ public showFunctionUI = (
477
+ functionName: string,
478
+ functionArguments: {
479
+ [key: string]: any;
480
+ } = {},
481
+ connectedAccountId?: string,
482
+ ): Promise<Record<any, any>> => {
483
+ const store = createSDKStore();
484
+
485
+ return new Promise((resolve, reject) => {
486
+ this.apiHandler
487
+ .getFunctionDetails(functionName)
488
+ .then((response: any) => {
489
+ if (!response) {
490
+ return reject(new Error('Function not found.'));
491
+ }
492
+ if (response.meta.app.connected_accounts.length === 0) {
493
+ return reject(new Error('No connected account found.'));
494
+ }
495
+ if (
496
+ connectedAccountId &&
497
+ !response.meta.app.connected_accounts.find(
498
+ (account: any) => account.id === connectedAccountId,
499
+ )
500
+ ) {
501
+ return reject(new Error('Connected account not found.'));
502
+ }
503
+
504
+ let targetEl = document.getElementById(this.initConfig.containerId);
505
+ if (!targetEl) {
506
+ targetEl = document.createElement('div');
507
+ targetEl.id = this.authModalId;
508
+ document.body.appendChild(targetEl);
509
+ }
510
+
511
+ store.setState({
512
+ userConfig: this.config.userConfig,
513
+ genericData: {
514
+ ...initialState.genericData,
515
+ implicitAuthEnabled: !!this.config.xIntegryConfig?.appAuth
516
+ ?.apiKey,
517
+ deploymentId: Number(this.config.deploymentId),
518
+ isAnonymous: !!this.config.xIntegryConfig?.isAnonymous,
519
+ },
520
+ });
521
+
522
+ render(
523
+ html`
524
+ <div id="functionFormWrap">
525
+ <${Modal}
526
+ isOpen=${true}
527
+ onClose=${() => {
528
+ const authIdElement = document.getElementById(
529
+ this.authModalId,
530
+ );
531
+ if (authIdElement) {
532
+ authIdElement.remove();
533
+ this.eventEmitter.emit('modal-closed', {});
534
+ }
535
+ }}
536
+ className="flowAppsModal"
537
+ isCompact=${false}
538
+ >
539
+ ${html`<${AppContext.Provider}
540
+ value=${{
541
+ apiHandler: this.apiHandler,
542
+ eventEmitter: this.eventEmitter,
543
+ isPreviewMode: false,
544
+ }}
545
+ >
546
+ <${Provider} store=${store}>
547
+ <${FunctionForm}
548
+ functionName=${functionName}
549
+ connectedAccountId=${connectedAccountId}
550
+ functionArguments=${functionArguments}
551
+ apiHandler=${this.apiHandler}
552
+ onClose=${(functionUIResponse: any) => {
553
+ const authIdElement = document.getElementById(
554
+ this.authModalId,
555
+ );
556
+ if (authIdElement) {
557
+ authIdElement.remove();
558
+ }
559
+ resolve(functionUIResponse);
560
+ }}
561
+ >
562
+ <//>
563
+ </${AppContext.Provider}>`}
564
+ <//>
565
+ </div>
566
+ `,
567
+ targetEl,
568
+ );
569
+
570
+ // Ensure the function has a return value
571
+ return null;
572
+ })
573
+ .catch((err) => {
574
+ reject(err);
575
+ });
576
+ });
577
+ };
578
+
579
+ public showFunction = (
580
+ functionName: string,
581
+ params: {
582
+ [key: string]: any;
583
+ } = {},
584
+ vars: {
585
+ [key: string]: any;
586
+ } = {},
587
+ autoMapVars = false,
588
+ connectedAccountId?: string,
589
+ ): Promise<Record<any, any>> => {
590
+ const store = createSDKStore();
591
+
592
+ return new Promise((resolve, reject) => {
593
+ this.apiHandler
594
+ .getFunctionDetails(functionName, autoMapVars ? vars : {})
595
+ .then((response: any) => {
596
+ if (!response) {
597
+ return reject(new Error('Function not found.'));
598
+ }
599
+ if (response.meta.app.connected_accounts.length === 0) {
600
+ return reject(new Error('No connected account found.'));
601
+ }
602
+ if (
603
+ connectedAccountId &&
604
+ !response.meta.app.connected_accounts.find(
605
+ (account: any) => account.id === connectedAccountId,
606
+ )
607
+ ) {
608
+ return reject(new Error('Connected account not found.'));
609
+ }
610
+
611
+ let targetEl = document.getElementById(this.initConfig.containerId);
612
+ if (!targetEl) {
613
+ targetEl = document.createElement('div');
614
+ targetEl.id = this.authModalId;
615
+ document.body.appendChild(targetEl);
616
+ }
617
+
618
+ store.setState({
619
+ userConfig: this.config.userConfig,
620
+ genericData: {
621
+ ...initialState.genericData,
622
+ implicitAuthEnabled: !!this.config.xIntegryConfig?.appAuth
623
+ ?.apiKey,
624
+ deploymentId: Number(this.config.deploymentId),
625
+ isAnonymous: !!this.config.xIntegryConfig?.isAnonymous,
626
+ },
627
+ });
628
+
629
+ render(
630
+ html`
631
+ <div id="functionFormWrap">
632
+ <${Modal}
633
+ isOpen=${true}
634
+ onClose=${() => {
635
+ const authIdElement = document.getElementById(
636
+ this.authModalId,
637
+ );
638
+ if (authIdElement) {
639
+ authIdElement.remove();
640
+ this.eventEmitter.emit('modal-closed', {});
641
+ }
642
+ }}
643
+ className="flowAppsModal"
644
+ isCompact=${false}
645
+ >
646
+ ${html`<${AppContext.Provider}
647
+ value=${{
648
+ apiHandler: this.apiHandler,
649
+ eventEmitter: this.eventEmitter,
650
+ isPreviewMode: false,
651
+ }}
652
+ >
653
+ <${Provider} store=${store}>
654
+ <${FunctionForm}
655
+ functionName=${functionName}
656
+ connectedAccountId=${connectedAccountId}
657
+ functionArguments=${params}
658
+ variables=${vars}
659
+ autoMapVars=${autoMapVars}
660
+ apiHandler=${this.apiHandler}
661
+ onClose=${(functionUIResponse: any) => {
662
+ const authIdElement = document.getElementById(
663
+ this.authModalId,
664
+ );
665
+ if (authIdElement) {
666
+ authIdElement.remove();
667
+ }
668
+ resolve(functionUIResponse);
669
+ }}
670
+ >
671
+ <//>
672
+ </${AppContext.Provider}>`}
673
+ <//>
674
+ </div>
675
+ `,
676
+ targetEl,
677
+ );
678
+
679
+ // Ensure the function has a return value
680
+ return null;
681
+ })
682
+ .catch((err) => {
683
+ reject(err);
684
+ });
685
+ });
686
+ };
687
+
688
+ public invokeFunction = (
689
+ functionName: string,
690
+ params: {
691
+ [key: string]: any;
692
+ },
693
+ connectedAccountId: string,
694
+ ): Promise<Record<any, any>> =>
695
+ new Promise((resolve, reject) => {
696
+ // Prepare the request body by encoding `args` to JSON
697
+ const functionDetails = {
698
+ method: this.getMethod(),
699
+ url: `${this.getBaseAPIUrl()}/functions/${functionName}/call/`,
700
+ headers: this.getHeaders(),
701
+ args: params,
702
+ };
703
+ this.apiHandler
704
+ .invokeFunction(functionDetails, connectedAccountId)
705
+ .then((response: any) => {
706
+ // Check if the response has an error or is not valid (you can customize this check based on the API response structure)
707
+ resolve(response);
708
+ })
709
+ .catch((error: any) => {
710
+ reject(
711
+ new Error(
712
+ `Failed to invoke function: ${error.message || 'Unknown error'}`,
713
+ ),
714
+ );
715
+ });
716
+ });
717
+
718
+ public callFunction = (
719
+ functionName: string,
720
+ params: {
721
+ [key: string]: any;
722
+ },
723
+ vars: {
724
+ [key: string]: any;
725
+ } = {},
726
+ connectedAccountId: string,
727
+ ): Promise<Record<any, any>> =>
728
+ new Promise((resolve, reject) => {
729
+ // Prepare the request body by encoding `args` to JSON
730
+ const functionDetails = {
731
+ method: this.getMethod(),
732
+ url: `${this.getBaseAPIUrl()}/functions/${functionName}/call/`,
733
+ headers: this.getHeaders(),
734
+ args: params,
735
+ vars,
736
+ };
737
+ this.apiHandler
738
+ .invokeFunction(functionDetails, connectedAccountId)
739
+ .then((response: any) => {
740
+ // Check if the response has an error or is not valid (you can customize this check based on the API response structure)
741
+ resolve(response);
742
+ })
743
+ .catch((error: any) => {
744
+ reject(
745
+ new Error(
746
+ `Failed to call function: ${error.message || 'Unknown error'}`,
747
+ ),
748
+ );
749
+ });
750
+ });
751
+
752
+ public connectApp = (appName: string): Promise<string> =>
753
+ new Promise((resolve, reject) => {
754
+ // Open the child window
755
+ this.apiHandler.getApp(appName).then((app) => {
756
+ if (!app || !app.login_url || app.login_url === '') {
757
+ reject(
758
+ new Error(
759
+ `App not found or doesn't require an authentication: ${appName}`,
760
+ ),
761
+ );
762
+ return;
763
+ }
764
+ const authWindow = openPopupWindow(
765
+ app.login_url,
766
+ 'Auth Window',
767
+ window,
768
+ 800,
769
+ 600,
770
+ );
771
+
772
+ // Function to handle the auth response from the child window
773
+ const onAuthResponseReceived = (event: MessageEvent) => {
774
+ // Verify the message origin (for security)
775
+ if (event.origin !== 'https://app.integry.io') return;
776
+
777
+ // Check if the message contains the connectedAccountId
778
+ if (
779
+ typeof event.data === 'object' &&
780
+ event.data !== null &&
781
+ 'authorization_id' in event.data
782
+ ) {
783
+ const { authorization_id } = event.data;
784
+ // Resolve the Promise with the connectedAccountId
785
+ resolve(`${authorization_id}`);
786
+
787
+ // Clean up event listener
788
+ window.removeEventListener('message', onAuthResponseReceived);
789
+ // Close the auth window
790
+ if (authWindow) authWindow.close();
791
+ this.eventEmitter.emit('app-connected', app);
792
+ } else {
793
+ reject(new Error('No connected account ID received'));
794
+ }
795
+ };
796
+
797
+ // Add the message event listener
798
+ window.addEventListener('message', onAuthResponseReceived);
799
+
800
+ // Handle cases where the user closes the auth window without completing auth
801
+ const checkWindowClosed = setInterval(() => {
802
+ if (authWindow && authWindow.closed) {
803
+ clearInterval(checkWindowClosed);
804
+ window.removeEventListener('message', onAuthResponseReceived);
805
+ reject(new Error('Auth window closed by user'));
806
+ }
807
+ }, 500);
808
+ });
809
+ });
810
+
811
+ public disconnectApp = (
812
+ appName: string,
813
+ connectedAccountId?: string,
814
+ ): Promise<any> => {
815
+ if (!connectedAccountId && !appName) {
816
+ return Promise.reject(
817
+ new Error(
818
+ `'appName' or 'connectedAccountId' are required when calling 'disconnectApp'`,
819
+ ),
820
+ );
821
+ }
822
+
823
+ if (connectedAccountId) {
824
+ return this.apiHandler
825
+ .deleteAuth(Number(connectedAccountId))
826
+ .then((response) => {
827
+ this.getApp(appName).then((app) => {
828
+ this.eventEmitter.emit('app-disconnected', app);
829
+ });
830
+ return response;
831
+ })
832
+ .catch((error) => Promise.reject(error));
833
+ }
834
+ return this.getApp(appName).then((app: any | null) => {
835
+ // If no connected accounts were found
836
+ if (
837
+ !app ||
838
+ !app.connected_accounts ||
839
+ app.connected_accounts.length === 0
840
+ ) {
841
+ return Promise.reject(
842
+ new Error(`No connected accounts found for app: ${appName}`),
843
+ );
844
+ }
845
+
846
+ // If exactly one account is found
847
+ if (app.connected_accounts.length === 1) {
848
+ return this.apiHandler
849
+ .deleteAuth(Number(app.connected_accounts[0].id))
850
+ .then((response) => {
851
+ const appUpdated = app;
852
+ appUpdated.connected_accounts = [];
853
+ this.eventEmitter.emit('app-disconnected', appUpdated);
854
+ return response;
855
+ })
856
+ .catch((error) => Promise.reject(error));
857
+ }
858
+
859
+ // If more than one account is found
860
+ return Promise.reject(
861
+ new Error(`Multiple connected accounts found for app: ${appName}`),
862
+ );
863
+ });
864
+ };
865
+
866
+ public isAppConnected = (appName: string): Promise<any> => {
867
+ if (!appName) {
868
+ return Promise.reject(
869
+ new Error(`'appName' is required when calling 'isConnected'`),
870
+ );
871
+ }
872
+
873
+ return this.apiHandler
874
+ .getConnectedAccounts(appName)
875
+ .then((response) => {
876
+ if (response && response.connected_accounts.length > 0) {
877
+ return Promise.resolve(true);
878
+ }
879
+ return Promise.resolve(false);
880
+ })
881
+ .catch((error) => Promise.reject(error));
882
+ };
883
+
884
+ public getFunction = (functionName: string): Promise<any> => {
885
+ if (!functionName) {
886
+ return Promise.reject(
887
+ new Error(
888
+ `'functionName' is required when calling 'getFunctionSignature'`,
889
+ ),
890
+ );
891
+ }
892
+
893
+ return this.apiHandler.getFunctionSignature(functionName);
894
+ };
895
+
896
+ public getConnectedAccounts = (
897
+ appName: string,
898
+ ): Promise<ConnectedAccount[] | null> => {
899
+ if (!appName) {
900
+ return Promise.reject(
901
+ new Error(`'appName' is required when calling 'getConnectedAccounts'`),
902
+ );
903
+ }
904
+
905
+ return this.apiHandler.getConnectedAccounts(appName).then((response) => {
906
+ // Check if response and connected_accounts are valid and not empty
907
+ if (response && response.connected_accounts.length > 0) {
908
+ // Return an array of strings containing only the ids
909
+
910
+ return Promise.resolve(response.connected_accounts); // Resolve with the array of ids as strings
911
+ }
912
+ return Promise.resolve([]); // Return an empty array if no connected accounts
913
+ });
914
+ };
915
+
916
+ private getApp = (appName: string): Promise<MarketplaceApp | null> => {
917
+ if (!appName) {
918
+ return Promise.reject(
919
+ new Error(`'appName' is required when calling 'getApp'`),
920
+ );
921
+ }
922
+
923
+ return this.apiHandler.getApp(appName).then((response) => response);
924
+ };
925
+
926
+ /**
927
+ * Render the template form we ship
928
+ * @param data
929
+ */
930
+ public renderAccountConnectionModal = (data?: {
931
+ deploymentId?: string;
932
+ appId?: number;
933
+ authTypeId?: number;
934
+ }): void => {
935
+ const store = createSDKStore();
936
+ if (data) {
937
+ const { appId, authTypeId } = data;
938
+ if (!appId && authTypeId) {
939
+ throw new Error(
940
+ `IntegrySDK: 'authTypeId' cannot be used without providing 'appId' when calling 'renderAccountConnectionModal'`,
941
+ );
942
+ }
943
+ }
944
+
945
+ let targetEl = document.getElementById(this.authModalId);
946
+ if (!targetEl) {
947
+ targetEl = document.createElement('div');
948
+ targetEl.id = this.authModalId;
949
+ document.body.appendChild(targetEl);
950
+ } else {
951
+ store.setState({
952
+ genericData: {
953
+ ...initialState.genericData,
954
+ showAppAuthModal: true,
955
+ },
956
+ });
957
+ }
958
+ if (data && data.authTypeId) {
959
+ this.forceRerender = !this.forceRerender;
960
+ }
961
+
962
+ store.setState({
963
+ userConfig: this.config.userConfig,
964
+ genericData: {
965
+ ...initialState.genericData,
966
+ deploymentId:
967
+ data && data.deploymentId ? Number(data.deploymentId) : null,
968
+ authConnection: {
969
+ appId: data && data.appId ? Number(data.appId) : null,
970
+ authTypeId: data && data.authTypeId ? Number(data.authTypeId) : null,
971
+ },
972
+ authModalId: this.authModalId,
973
+ showAppAuthModal: !data?.authTypeId,
974
+ isAnonymous: !!this.config.xIntegryConfig?.isAnonymous,
975
+ },
976
+ });
977
+
978
+ render(
979
+ html`
980
+ <${AppContext.Provider}
981
+ value=${{
982
+ apiHandler: this.apiHandler,
983
+ eventEmitter: this.eventEmitter,
984
+ isPreviewMode: false,
985
+ }}
986
+ >
987
+ <${Provider} store=${store}>
988
+ <${AuthSetupContainer}
989
+ deploymentId=${data?.deploymentId}
990
+ appId=${data?.appId}
991
+ authTypeId=${data?.authTypeId}
992
+ forceRerender=${this.forceRerender}
993
+ onClose=${() => {
994
+ const authIdElement = document.getElementById(this.authModalId);
995
+ if (authIdElement) {
996
+ authIdElement.remove();
997
+ }
998
+ }}
999
+ >
1000
+ <//>
1001
+ <//>
1002
+ <//>
1003
+ `,
1004
+ targetEl,
1005
+ );
1006
+ };
1007
+
1008
+ public async removeAuthorization(data: {
1009
+ authorizationId: number;
1010
+ }): Promise<{
1011
+ data: string | null;
1012
+ status: number;
1013
+ } | null> {
1014
+ /// throw error if authId is not provided
1015
+ if (!data.authorizationId) {
1016
+ throw new Error(
1017
+ `'authorizationId' is required when calling 'removeAuthorization'`,
1018
+ );
1019
+ }
1020
+ return this.apiHandler.deleteAuth(data.authorizationId).then((response) => {
1021
+ this.eventEmitter.emit('did-remove-authorization', {
1022
+ authorizationId: Number(data.authorizationId),
1023
+ });
1024
+ this.init({ ...this.initConfig, skipAccountConnectionOnLoad: true });
1025
+ return response
1026
+ ? {
1027
+ status: response.status,
1028
+ data: response.data,
1029
+ }
1030
+ : null;
1031
+ });
1032
+ }
1033
+
1034
+ /**
1035
+ * Render the template form we ship
1036
+ * @param params
1037
+ */
1038
+ public renderPreview = (params: PreviewPayload): void => {
1039
+ const { templateData, metadata, previewContainerId } = params;
1040
+ const targetEl = document.getElementById(previewContainerId);
1041
+ if (!targetEl) {
1042
+ console.warn(
1043
+ `Integry template form render target with id ${previewContainerId} was not found`,
1044
+ );
1045
+ return;
1046
+ }
1047
+ const store = createSDKStore();
1048
+
1049
+ store.setState({
1050
+ genericData: {
1051
+ ...initialState.genericData,
1052
+ implicitAuthEnabled: !!this.config.xIntegryConfig?.appAuth?.apiKey,
1053
+ },
1054
+ });
1055
+
1056
+ render(
1057
+ html`
1058
+ <${AppContext.Provider}
1059
+ value=${{
1060
+ apiHandler: this.apiHandler,
1061
+ eventEmitter: this.eventEmitter,
1062
+ isPreviewMode: true,
1063
+ }}
1064
+ >
1065
+ <${Provider} store=${store}>
1066
+ <${FlowSetupContainer}
1067
+ deploymentId=${this.config.deploymentId}
1068
+ isPreviewMode=${true}
1069
+ templatePreviewData=${templateData}
1070
+ previewMetadata=${metadata}
1071
+ >
1072
+ <//>
1073
+ <//>
1074
+ <//>
1075
+ `,
1076
+ targetEl,
1077
+ );
1078
+ };
1079
+
1080
+ /**
1081
+ *
1082
+ * @param initConfig
1083
+ */
1084
+ public init = (initConfig: InitConfig) => {
1085
+ const { appId, showApps = false } = initConfig;
1086
+ if (!this.config.appKey || !this.config.hash || !this.config.userId) {
1087
+ this.SDKFailedHandler(this.config, initConfig.containerId);
1088
+ }
1089
+ this.initConfig = initConfig;
1090
+ if (!appId) {
1091
+ if (showApps) {
1092
+ this.renderAppFlows(initConfig);
1093
+ } else {
1094
+ this.initializeMarketplace(initConfig);
1095
+ }
1096
+ } else {
1097
+ this.renderAppFlows(initConfig);
1098
+ }
1099
+ };
1100
+
1101
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1102
+ public updateSdkUserConfig = (config: any) => {
1103
+ const store = createSDKStore();
1104
+ const currentConfig = store.getState();
1105
+ store.setState({
1106
+ userConfig: { ...currentConfig.userConfig, ...config.userConfig },
1107
+ });
1108
+ };
1109
+
1110
+ public initializeMarketplace = (initConfig: InitConfig) => {
1111
+ const {
1112
+ containerId,
1113
+ templateContainerId,
1114
+ renderMode,
1115
+ renderFlowsMode,
1116
+ skipAccountConnectionOnLoad = false,
1117
+ testMultipurpose = true,
1118
+ flowId = null,
1119
+ integrationId = null,
1120
+ viewStyle = testMultipurpose === false
1121
+ ? ViewStyles.COMFORTABLE
1122
+ : ViewStyles.COMFORTABLE,
1123
+ } = initConfig;
1124
+
1125
+ const target = document.getElementById(containerId);
1126
+
1127
+ if (!renderMode) {
1128
+ throw new Error('Template form render mode needs to be defined');
1129
+ }
1130
+
1131
+ this.setupFlowFormDestination(renderMode, templateContainerId);
1132
+ if (target) {
1133
+ const layout = TemplateListingRenderModes.LIST;
1134
+ /** REMOVED THIS TO SUPPRESS x-integry-layout dom attribute to avoid grid */
1135
+ // (target.getAttribute(
1136
+ // 'x-integry-layout',
1137
+ // ) as TemplateListingRenderModes) || TemplateListingRenderModes.LIST;
1138
+ // this.renderMode = renderMode;
1139
+ const store = createSDKStore();
1140
+ store.setState({
1141
+ userConfig: this.config.userConfig,
1142
+ xIntegryConfig: this.config.xIntegryConfig || {},
1143
+ integrationIdToEdit: integrationId,
1144
+ showSetupModal: flowId
1145
+ ? renderMode === TemplateFormRenderModes.MODAL
1146
+ : false,
1147
+ showSetupInline: flowId
1148
+ ? renderMode === TemplateFormRenderModes.INLINE
1149
+ : false,
1150
+ genericData: {
1151
+ ...initialState.genericData,
1152
+ templateId: flowId,
1153
+ implicitAuthEnabled: !!this.config.xIntegryConfig?.appAuth?.apiKey,
1154
+ deploymentId: Number(this.config.deploymentId),
1155
+ isAnonymous: !!this.config.xIntegryConfig?.isAnonymous,
1156
+ skipAccountConnectionOnLoad,
1157
+ deploymentIdFromConfig: this.config.deploymentId
1158
+ ? Number(this.config.deploymentId)
1159
+ : null,
1160
+ testMultipurpose,
1161
+ viewStyle,
1162
+ },
1163
+ customComponents: this.config.userConfig?.customComponents,
1164
+ ...(renderFlowsMode === TemplateFormRenderModes.MODAL && {
1165
+ showFlowsListModal: true,
1166
+ }),
1167
+ });
1168
+
1169
+ this.verifyAuthConfig()
1170
+ .then((response) => {
1171
+ if (!response?.config_verified) {
1172
+ console.error(
1173
+ 'IntegrySDK: Auth config verification failed, are your auth parameters correct?',
1174
+ );
1175
+ } else {
1176
+ const currentState = store.getState();
1177
+ store.setState({
1178
+ genericData: {
1179
+ ...currentState.genericData,
1180
+ customerAppName: response.meta.app.name,
1181
+ },
1182
+ });
1183
+ this.eventEmitter.emit('ready', {
1184
+ isReady: true,
1185
+ });
1186
+ this.getUserVariables().then((userVariables) => {
1187
+ let userVariablesValidation = true;
1188
+ userVariables.forEach((variable: any) => {
1189
+ if (
1190
+ (variable.key !== 'api_key' &&
1191
+ (!this.config.xIntegryConfig?.appAuth?.extras ||
1192
+ !this.config.xIntegryConfig?.appAuth?.extras[
1193
+ variable.key
1194
+ ])) ||
1195
+ (variable.key === 'api_key' &&
1196
+ !this.config.xIntegryConfig?.appAuth?.apiKey)
1197
+ ) {
1198
+ userVariablesValidation = false;
1199
+ }
1200
+ });
1201
+ if (!userVariablesValidation) {
1202
+ this.eventEmitter.emit('did-raise-sdk-embed-warning', {
1203
+ type: 'missing-user-variable-values',
1204
+ message:
1205
+ 'One or more user variables or their values are missing.',
1206
+ });
1207
+ }
1208
+ store.setState({
1209
+ genericData: {
1210
+ ...currentState.genericData,
1211
+ userVariables,
1212
+ userVariablesValidation,
1213
+ storage: response.meta.storage,
1214
+ },
1215
+ });
1216
+ });
1217
+ }
1218
+ })
1219
+ .catch((err) => console.error(err));
1220
+
1221
+ render(
1222
+ html`
1223
+ <${AppContext.Provider}
1224
+ value=${{
1225
+ apiHandler: this.apiHandler,
1226
+ eventEmitter: this.eventEmitter,
1227
+ isPreviewMode: false,
1228
+ }}
1229
+ >
1230
+ <${Provider} store=${store} key=${this.getRandomFlowId(10)}>
1231
+ <${SDKContainer}
1232
+ deploymentId=${this.config.deploymentId}
1233
+ userConfig=${this.config.userConfig}
1234
+ layout=${layout}
1235
+ renderMode=${renderMode}
1236
+ renderFlowsMode=${renderFlowsMode ||
1237
+ TemplateFormRenderModes.INLINE}
1238
+ >
1239
+ <//>
1240
+ <//>
1241
+ <//>
1242
+ ${this.config.userConfig?.debug &&
1243
+ html`<${SDKDebugContainer}
1244
+ message=""
1245
+ config=${this.config}
1246
+ eventEmitter=${this.eventEmitter}
1247
+ >
1248
+ <//>`}
1249
+ `,
1250
+ target,
1251
+ );
1252
+ } else {
1253
+ console.warn(
1254
+ `Integry SDK render target with id ${containerId} was not found`,
1255
+ );
1256
+ // throw new Error('The render target was not found');
1257
+ }
1258
+ };
1259
+
1260
+ public showFlows = (
1261
+ renderMode: RenderModes = RenderModes.MODAL,
1262
+ containerId = 'integry-marketplace',
1263
+ layout = Layouts.WIDE,
1264
+ ) => {
1265
+ const target = document.getElementById(containerId);
1266
+
1267
+ if (!renderMode) {
1268
+ throw new Error('Template form render mode needs to be defined');
1269
+ }
1270
+
1271
+ if (target) {
1272
+ const templateListLayout = TemplateListingRenderModes.LIST;
1273
+
1274
+ const store = createSDKStore();
1275
+ store.setState({
1276
+ userConfig: this.config.userConfig,
1277
+ xIntegryConfig: this.config.xIntegryConfig || {},
1278
+ showSetupModal: false,
1279
+ showSetupInline: false,
1280
+ genericData: {
1281
+ ...initialState.genericData,
1282
+ templateId: null,
1283
+ implicitAuthEnabled: !!this.config.xIntegryConfig?.appAuth?.apiKey,
1284
+ deploymentId: Number(this.config.deploymentId),
1285
+ isAnonymous: !!this.config.xIntegryConfig?.isAnonymous,
1286
+ skipAccountConnectionOnLoad: false,
1287
+ deploymentIdFromConfig: this.config.deploymentId
1288
+ ? Number(this.config.deploymentId)
1289
+ : null,
1290
+ testMultipurpose: true,
1291
+ showTemplates: true,
1292
+ showApps: false,
1293
+ viewStyle: layout,
1294
+ },
1295
+ customComponents: this.config.userConfig?.customComponents,
1296
+ ...(renderMode === RenderModes.MODAL && {
1297
+ showMarketplaceModal: true,
1298
+ }),
1299
+ });
1300
+
1301
+ this.verifyAuthConfig()
1302
+ .then((response) => {
1303
+ if (!response?.config_verified) {
1304
+ console.error(
1305
+ 'IntegrySDK: Auth config verification failed, are your auth parameters correct?',
1306
+ );
1307
+ } else {
1308
+ const currentState = store.getState();
1309
+ store.setState({
1310
+ genericData: {
1311
+ ...currentState.genericData,
1312
+ customerAppName: response.meta.app.name,
1313
+ },
1314
+ });
1315
+ this.eventEmitter.emit('ready', {
1316
+ isReady: true,
1317
+ });
1318
+ this.getUserVariables().then((userVariables) => {
1319
+ let userVariablesValidation = true;
1320
+ userVariables.forEach((variable: any) => {
1321
+ if (
1322
+ (variable.key !== 'api_key' &&
1323
+ (!this.config.xIntegryConfig?.appAuth?.extras ||
1324
+ !this.config.xIntegryConfig?.appAuth?.extras[
1325
+ variable.key
1326
+ ])) ||
1327
+ (variable.key === 'api_key' &&
1328
+ !this.config.xIntegryConfig?.appAuth?.apiKey)
1329
+ ) {
1330
+ userVariablesValidation = false;
1331
+ }
1332
+ });
1333
+ if (!userVariablesValidation) {
1334
+ this.eventEmitter.emit('did-raise-sdk-embed-warning', {
1335
+ type: 'missing-user-variable-values',
1336
+ message:
1337
+ 'One or more user variables or their values are missing.',
1338
+ });
1339
+ }
1340
+ store.setState({
1341
+ genericData: {
1342
+ ...currentState.genericData,
1343
+ userVariables,
1344
+ userVariablesValidation,
1345
+ storage: response.meta.storage,
1346
+ },
1347
+ });
1348
+ });
1349
+ }
1350
+ })
1351
+ .catch((err) => console.error(err));
1352
+
1353
+ render(
1354
+ html`
1355
+ <${AppContext.Provider}
1356
+ value=${{
1357
+ apiHandler: this.apiHandler,
1358
+ eventEmitter: this.eventEmitter,
1359
+ isPreviewMode: false,
1360
+ }}
1361
+ >
1362
+ <${Provider} store=${store} key=${this.getRandomFlowId(10)}>
1363
+ <${SDKContainer}
1364
+ deploymentId=${this.config.deploymentId}
1365
+ userConfig=${this.config.userConfig}
1366
+ layout=${templateListLayout}
1367
+ renderMode=${renderMode}
1368
+ renderFlowsMode=${renderMode || TemplateFormRenderModes.INLINE}
1369
+ >
1370
+ <//>
1371
+ <//>
1372
+ <//>
1373
+ ${this.config.userConfig?.debug &&
1374
+ html`<${SDKDebugContainer}
1375
+ message=""
1376
+ config=${this.config}
1377
+ eventEmitter=${this.eventEmitter}
1378
+ >
1379
+ <//>`}
1380
+ `,
1381
+ target,
1382
+ );
1383
+ } else {
1384
+ console.warn(
1385
+ `Integry SDK render target with id ${containerId} was not found`,
1386
+ );
1387
+ // throw new Error('The render target was not found');
1388
+ }
1389
+ };
1390
+
1391
+ /**
1392
+ *
1393
+ * @param marketplaceConfig
1394
+ */
1395
+ public renderMarketplace = (marketplaceConfig: MarketplaceConfig) => {
1396
+ const { containerId, renderMode } = marketplaceConfig;
1397
+
1398
+ const target = document.getElementById(containerId);
1399
+
1400
+ if (!renderMode) {
1401
+ throw new Error('Marketplace render mode needs to be defined');
1402
+ }
1403
+
1404
+ if (target) {
1405
+ const store = createSDKStore();
1406
+ store.setState({
1407
+ userConfig: this.config.userConfig,
1408
+ genericData: {
1409
+ ...initialState.genericData,
1410
+ implicitAuthEnabled: !!this.config.xIntegryConfig?.appAuth?.apiKey,
1411
+ deploymentId: Number(this.config.marketplaceId),
1412
+ marketplaceId: Number(this.config.marketplaceId),
1413
+ isAnonymous: !!this.config.xIntegryConfig?.isAnonymous,
1414
+ },
1415
+ customComponents: this.config.userConfig?.customComponents,
1416
+ ...(renderMode === MarketplaceRenderModes.MODAL && {
1417
+ showMarketplaceModal: true,
1418
+ }),
1419
+ });
1420
+
1421
+ render(
1422
+ html`
1423
+ <${AppContext.Provider}
1424
+ value=${{
1425
+ apiHandler: this.apiHandler,
1426
+ eventEmitter: this.eventEmitter,
1427
+ isPreviewMode: false,
1428
+ }}
1429
+ >
1430
+ <${Provider} store=${store} key=${this.getRandomFlowId(6)}>
1431
+ <${MarketplaceContainer}
1432
+ marketplaceId=${this.config.marketplaceId}
1433
+ userConfig=${this.config.userConfig}
1434
+ renderMode=${renderMode}
1435
+ >
1436
+ <//>
1437
+ <//>
1438
+ <//>
1439
+ `,
1440
+ target,
1441
+ );
1442
+ } else {
1443
+ console.warn(
1444
+ `Integry SDK render target with id ${containerId} was not found`,
1445
+ );
1446
+ }
1447
+ };
1448
+
1449
+ public renderAppFlows = (appFlowConfig: InitConfig) => {
1450
+ const {
1451
+ containerId,
1452
+ renderMode,
1453
+ appId,
1454
+ renderAppPageMode,
1455
+ renderFlowSetupMode,
1456
+ showApps = false,
1457
+ skipOnDemand = false,
1458
+ skipAccountConnectionOnLoad = false,
1459
+ testMultipurpose = true,
1460
+ viewStyle = testMultipurpose === false
1461
+ ? ViewStyles.COMFORTABLE
1462
+ : ViewStyles.COMFORTABLE,
1463
+ } = appFlowConfig;
1464
+ /// const hostApiKey = this.config.xIntegryConfig?.appAuth?.apiKey;
1465
+ const target = document.getElementById(containerId);
1466
+ if (!renderMode) {
1467
+ throw new Error('App Page render mode needs to be defined');
1468
+ }
1469
+ /* if (!hostApiKey && !showApps) {
1470
+ throw new Error('API key for host app needs to be defined');
1471
+ } */
1472
+ if (target) {
1473
+ const store = createSDKStore();
1474
+ store.setState({
1475
+ userConfig: {
1476
+ ...this.config.userConfig,
1477
+ hideWebhookUrlScreen: false,
1478
+ hideExistingIntegrations:
1479
+ this.config.userConfig &&
1480
+ Object.prototype.hasOwnProperty.call(
1481
+ this.config.userConfig,
1482
+ 'hideExistingIntegrations',
1483
+ )
1484
+ ? this.config.userConfig.hideExistingIntegrations
1485
+ : false,
1486
+ },
1487
+ xIntegryConfig: this.config.xIntegryConfig || {},
1488
+ genericData: {
1489
+ ...initialState.genericData,
1490
+ app_id: appId,
1491
+ deploymentId: Number(this.config.deploymentId),
1492
+ showTemplates: !!appFlowConfig.showTemplates,
1493
+ showApps,
1494
+ skipOnDemand,
1495
+ skipAccountConnectionOnLoad,
1496
+ testMultipurpose,
1497
+ viewStyle,
1498
+ },
1499
+ ...((renderMode === TemplateFormRenderModes.MODAL ||
1500
+ renderAppPageMode === TemplateFormRenderModes.MODAL) && {
1501
+ showMarketplaceModal: true,
1502
+ }),
1503
+ });
1504
+
1505
+ this.verifyAuthConfig()
1506
+ .then((response) => {
1507
+ if (!response?.config_verified) {
1508
+ console.error(
1509
+ 'IntegrySDK: Auth config verification failed, are your auth parameters correct?',
1510
+ );
1511
+ } else {
1512
+ const currentState = store.getState();
1513
+ store.setState({
1514
+ genericData: {
1515
+ ...currentState.genericData,
1516
+ customerAppName: response.meta.app.name,
1517
+ },
1518
+ });
1519
+ this.eventEmitter.emit('ready', {
1520
+ isReady: true,
1521
+ });
1522
+ this.getUserVariables().then((userVariables) => {
1523
+ let userVariablesValidation = true;
1524
+ userVariables.forEach((variable: any) => {
1525
+ if (
1526
+ (variable.is_required &&
1527
+ variable.key !== 'api_key' &&
1528
+ (!this.config.xIntegryConfig?.appAuth?.extras ||
1529
+ !this.config.xIntegryConfig?.appAuth?.extras[
1530
+ variable.key
1531
+ ])) ||
1532
+ (variable.key === 'api_key' &&
1533
+ !this.config.xIntegryConfig?.appAuth?.apiKey)
1534
+ ) {
1535
+ userVariablesValidation = false;
1536
+ }
1537
+ });
1538
+ if (!userVariablesValidation) {
1539
+ this.eventEmitter.emit('did-raise-sdk-embed-warning', {
1540
+ type: 'missing-user-variable-values',
1541
+ message:
1542
+ 'One or more user variables or their values are missing.',
1543
+ });
1544
+ }
1545
+ store.setState({
1546
+ genericData: {
1547
+ ...currentState.genericData,
1548
+ userVariables,
1549
+ userVariablesValidation,
1550
+ storage: response.meta.storage,
1551
+ },
1552
+ });
1553
+ });
1554
+ }
1555
+ })
1556
+ .catch((err) => console.error(err));
1557
+
1558
+ render(
1559
+ html`
1560
+ <${AppContext.Provider}
1561
+ value=${{
1562
+ apiHandler: this.apiHandler,
1563
+ eventEmitter: this.eventEmitter,
1564
+ isPreviewMode: false,
1565
+ }}
1566
+ >
1567
+ <${Provider} store=${store} key=${this.getRandomFlowId(6)}>
1568
+ <${AppFlowContainer}
1569
+ marketplaceId=${this.config.marketplaceId}
1570
+ userConfig=${this.config.userConfig}
1571
+ renderMode=${renderMode}
1572
+ renderAppPageMode=${renderAppPageMode || renderMode}
1573
+ renderFlowSetupMode=${renderFlowSetupMode ||
1574
+ TemplateFormRenderModes.INLINE}
1575
+ >
1576
+ <//>
1577
+ <//>
1578
+ <//>
1579
+ ${this.config.userConfig?.debug &&
1580
+ html`<${SDKDebugContainer}
1581
+ message=""
1582
+ config=${this.config}
1583
+ eventEmitter=${this.eventEmitter}
1584
+ >
1585
+ <//>`}
1586
+ `,
1587
+ target,
1588
+ );
1589
+ } else {
1590
+ console.warn(
1591
+ `Integry SDK render target with id ${containerId} was not found`,
1592
+ );
1593
+ }
1594
+ };
1595
+
1596
+ public showApp = (
1597
+ appName: string,
1598
+ renderMode: RenderModes = RenderModes.MODAL,
1599
+ containerId = 'integry-marketplace',
1600
+ layout: Layouts = Layouts.WIDE,
1601
+ ) => {
1602
+ /// const hostApiKey = this.config.xIntegryConfig?.appAuth?.apiKey;
1603
+ let target = document.getElementById(containerId);
1604
+ if (!appName) {
1605
+ throw new Error('App name needs to be defined');
1606
+ }
1607
+ if (!target && renderMode !== RenderModes.MODAL) {
1608
+ console.warn(
1609
+ `Integry SDK render target with id ${containerId} was not found`,
1610
+ );
1611
+ return;
1612
+ }
1613
+
1614
+ if (!target && renderMode === RenderModes.MODAL) {
1615
+ const targetEl = document.createElement('div');
1616
+ targetEl.id = containerId;
1617
+ document.body.appendChild(targetEl);
1618
+ target = targetEl;
1619
+ }
1620
+ if (target) {
1621
+ const store = createSDKStore();
1622
+ store.setState({
1623
+ userConfig: {
1624
+ ...this.config.userConfig,
1625
+ hideWebhookUrlScreen: false,
1626
+ hideExistingIntegrations:
1627
+ this.config.userConfig &&
1628
+ Object.prototype.hasOwnProperty.call(
1629
+ this.config.userConfig,
1630
+ 'hideExistingIntegrations',
1631
+ )
1632
+ ? this.config.userConfig.hideExistingIntegrations
1633
+ : false,
1634
+ },
1635
+ xIntegryConfig: this.config.xIntegryConfig || {},
1636
+ genericData: {
1637
+ ...initialState.genericData,
1638
+ app_id: appName,
1639
+ deploymentId: Number(this.config.deploymentId),
1640
+ showTemplates: false,
1641
+ showApps: false,
1642
+ skipOnDemand: false,
1643
+ skipAccountConnectionOnLoad: false,
1644
+ testMultipurpose: true,
1645
+ viewStyle: layout,
1646
+ },
1647
+ ...(renderMode === RenderModes.MODAL && {
1648
+ showMarketplaceModal: true,
1649
+ }),
1650
+ });
1651
+
1652
+ this.verifyAuthConfig()
1653
+ .then((response) => {
1654
+ if (!response?.config_verified) {
1655
+ console.error(
1656
+ 'IntegrySDK: Auth config verification failed, are your auth parameters correct?',
1657
+ );
1658
+ } else {
1659
+ const currentState = store.getState();
1660
+ store.setState({
1661
+ genericData: {
1662
+ ...currentState.genericData,
1663
+ customerAppName: response.meta.app.name,
1664
+ },
1665
+ });
1666
+ this.eventEmitter.emit('ready', {
1667
+ isReady: true,
1668
+ });
1669
+ this.getUserVariables().then((userVariables) => {
1670
+ let userVariablesValidation = true;
1671
+ userVariables.forEach((variable: any) => {
1672
+ if (
1673
+ (variable.is_required &&
1674
+ variable.key !== 'api_key' &&
1675
+ (!this.config.xIntegryConfig?.appAuth?.extras ||
1676
+ !this.config.xIntegryConfig?.appAuth?.extras[
1677
+ variable.key
1678
+ ])) ||
1679
+ (variable.key === 'api_key' &&
1680
+ !this.config.xIntegryConfig?.appAuth?.apiKey)
1681
+ ) {
1682
+ userVariablesValidation = false;
1683
+ }
1684
+ });
1685
+ if (!userVariablesValidation) {
1686
+ this.eventEmitter.emit('did-raise-sdk-embed-warning', {
1687
+ type: 'missing-user-variable-values',
1688
+ message:
1689
+ 'One or more user variables or their values are missing.',
1690
+ });
1691
+ }
1692
+ store.setState({
1693
+ genericData: {
1694
+ ...currentState.genericData,
1695
+ userVariables,
1696
+ userVariablesValidation,
1697
+ storage: response.meta.storage,
1698
+ },
1699
+ });
1700
+ });
1701
+ }
1702
+ })
1703
+ .catch((err) => console.error(err));
1704
+
1705
+ render(
1706
+ html`
1707
+ <${AppContext.Provider}
1708
+ value=${{
1709
+ apiHandler: this.apiHandler,
1710
+ eventEmitter: this.eventEmitter,
1711
+ isPreviewMode: false,
1712
+ }}
1713
+ >
1714
+ <${Provider} store=${store} key=${this.getRandomFlowId(6)}>
1715
+ <${AppFlowContainer}
1716
+ marketplaceId=${this.config.marketplaceId}
1717
+ userConfig=${this.config.userConfig}
1718
+ renderMode=${renderMode}
1719
+ renderAppPageMode=${renderMode}
1720
+ renderFlowSetupMode=${renderMode}
1721
+ >
1722
+ <//>
1723
+ <//>
1724
+ <//>
1725
+ ${this.config.userConfig?.debug &&
1726
+ html`<${SDKDebugContainer}
1727
+ message=""
1728
+ config=${this.config}
1729
+ eventEmitter=${this.eventEmitter}
1730
+ >
1731
+ <//>`}
1732
+ `,
1733
+ target,
1734
+ );
1735
+ } else {
1736
+ console.warn(
1737
+ `Integry SDK render target with id ${containerId} was not found`,
1738
+ );
1739
+ }
1740
+ };
1741
+
1742
+ public showApps = (
1743
+ renderMode: RenderModes = RenderModes.MODAL,
1744
+ containerId = 'integry-marketplace',
1745
+ layout = Layouts.WIDE,
1746
+ ) => {
1747
+ let target = document.getElementById(containerId);
1748
+ if (!target) {
1749
+ const targetEl = document.createElement('div');
1750
+ targetEl.id = containerId;
1751
+ document.body.appendChild(targetEl);
1752
+ target = targetEl;
1753
+ }
1754
+
1755
+ if (target) {
1756
+ const store = createSDKStore();
1757
+ store.setState({
1758
+ userConfig: {
1759
+ ...this.config.userConfig,
1760
+ hideWebhookUrlScreen: false,
1761
+ hideExistingIntegrations:
1762
+ this.config.userConfig &&
1763
+ Object.prototype.hasOwnProperty.call(
1764
+ this.config.userConfig,
1765
+ 'hideExistingIntegrations',
1766
+ )
1767
+ ? this.config.userConfig.hideExistingIntegrations
1768
+ : false,
1769
+ },
1770
+ xIntegryConfig: this.config.xIntegryConfig || {},
1771
+ genericData: {
1772
+ ...initialState.genericData,
1773
+ deploymentId: Number(this.config.deploymentId),
1774
+ showTemplates: false,
1775
+ showApps: true,
1776
+ skipOnDemand: false,
1777
+ skipAccountConnectionOnLoad: false,
1778
+ testMultipurpose: true,
1779
+ viewStyle: layout,
1780
+ },
1781
+ ...(renderMode === RenderModes.MODAL && {
1782
+ showMarketplaceModal: true,
1783
+ }),
1784
+ });
1785
+
1786
+ this.verifyAuthConfig()
1787
+ .then((response) => {
1788
+ if (!response?.config_verified) {
1789
+ console.error(
1790
+ 'IntegrySDK: Auth config verification failed, are your auth parameters correct?',
1791
+ );
1792
+ } else {
1793
+ const currentState = store.getState();
1794
+ store.setState({
1795
+ genericData: {
1796
+ ...currentState.genericData,
1797
+ customerAppName: response.meta.app.name,
1798
+ },
1799
+ });
1800
+ }
1801
+ })
1802
+ .catch((err) => console.error(err));
1803
+
1804
+ render(
1805
+ html`
1806
+ <${AppContext.Provider}
1807
+ value=${{
1808
+ apiHandler: this.apiHandler,
1809
+ eventEmitter: this.eventEmitter,
1810
+ isPreviewMode: false,
1811
+ }}
1812
+ >
1813
+ <${Provider} store=${store} key=${this.getRandomFlowId(6)}>
1814
+ <${MarketplaceAppsContainer}
1815
+ marketplaceId=${this.config.marketplaceId}
1816
+ userConfig=${this.config.userConfig}
1817
+ renderMode=${renderMode}
1818
+ renderAppPageMode=${renderMode}
1819
+ renderFlowSetupMode=${TemplateFormRenderModes.INLINE}
1820
+ >
1821
+ <//>
1822
+ <//>
1823
+ <//>
1824
+ `,
1825
+ target,
1826
+ );
1827
+ } else {
1828
+ console.warn(
1829
+ `Integry SDK render target with id ${containerId} was not found`,
1830
+ );
1831
+ }
1832
+ };
1833
+
1834
+ public showConnectedAccounts = (
1835
+ appName: string,
1836
+ renderMode: RenderModes = RenderModes.MODAL,
1837
+ containerId = 'integry-marketplace',
1838
+ layout = Layouts.WIDE,
1839
+ ) => {
1840
+ let target = document.getElementById(containerId);
1841
+ if (!target) {
1842
+ const targetEl = document.createElement('div');
1843
+ targetEl.id = containerId;
1844
+ document.body.appendChild(targetEl);
1845
+ target = targetEl;
1846
+ }
1847
+
1848
+ if (target) {
1849
+ const store = createSDKStore();
1850
+ store.setState({
1851
+ userConfig: {
1852
+ ...this.config.userConfig,
1853
+ hideWebhookUrlScreen: false,
1854
+ hideExistingIntegrations:
1855
+ this.config.userConfig &&
1856
+ Object.prototype.hasOwnProperty.call(
1857
+ this.config.userConfig,
1858
+ 'hideExistingIntegrations',
1859
+ )
1860
+ ? this.config.userConfig.hideExistingIntegrations
1861
+ : false,
1862
+ },
1863
+ xIntegryConfig: this.config.xIntegryConfig || {},
1864
+ genericData: {
1865
+ ...initialState.genericData,
1866
+ deploymentId: Number(this.config.deploymentId),
1867
+ showTemplates: false,
1868
+ showApps: true,
1869
+ skipOnDemand: false,
1870
+ skipAccountConnectionOnLoad: false,
1871
+ testMultipurpose: true,
1872
+ viewStyle: layout,
1873
+ },
1874
+ ...(renderMode === RenderModes.MODAL && {
1875
+ showMarketplaceModal: true,
1876
+ }),
1877
+ });
1878
+
1879
+ this.verifyAuthConfig()
1880
+ .then((response) => {
1881
+ if (!response?.config_verified) {
1882
+ console.error(
1883
+ 'IntegrySDK: Auth config verification failed, are your auth parameters correct?',
1884
+ );
1885
+ } else {
1886
+ const currentState = store.getState();
1887
+ store.setState({
1888
+ genericData: {
1889
+ ...currentState.genericData,
1890
+ customerAppName: response.meta.app.name,
1891
+ },
1892
+ });
1893
+ }
1894
+ })
1895
+ .catch((err) => console.error(err));
1896
+
1897
+ render(
1898
+ html`
1899
+ <${AppContext.Provider}
1900
+ value=${{
1901
+ apiHandler: this.apiHandler,
1902
+ eventEmitter: this.eventEmitter,
1903
+ isPreviewMode: false,
1904
+ }}
1905
+ >
1906
+ <${Provider} store=${store} key=${this.getRandomFlowId(6)}>
1907
+ <${MarketplaceAppsContainer}
1908
+ marketplaceId=${this.config.marketplaceId}
1909
+ userConfig=${this.config.userConfig}
1910
+ renderMode=${renderMode}
1911
+ renderAppPageMode=${renderMode}
1912
+ renderFlowSetupMode=${TemplateFormRenderModes.INLINE}
1913
+ appName=${appName}
1914
+ >
1915
+ <//>
1916
+ <//>
1917
+ <//>
1918
+ `,
1919
+ target,
1920
+ );
1921
+ } else {
1922
+ console.warn(
1923
+ `Integry SDK render target with id ${containerId} was not found`,
1924
+ );
1925
+ }
1926
+ };
1927
+
1928
+ public renderMultipurposeField = ({
1929
+ containerId,
1930
+ multipurposeFieldProps,
1931
+ }: {
1932
+ containerId: string;
1933
+ multipurposeFieldProps: MultipurposeFieldType;
1934
+ }) => {
1935
+ const target = document.getElementById(containerId);
1936
+
1937
+ if (target) {
1938
+ render(
1939
+ html`<div>
1940
+ ${multipurposeFieldProps.type === 'CHECKBOX' ||
1941
+ multipurposeFieldProps.type === 'RADIO' ||
1942
+ multipurposeFieldProps.type === 'SELECT'
1943
+ ? html`<${ListBox}
1944
+ activityOutputData=${multipurposeFieldProps.activityOutputData}
1945
+ title=${multipurposeFieldProps.title}
1946
+ description=${multipurposeFieldProps.description}
1947
+ placeholder=${multipurposeFieldProps.placeholder}
1948
+ value=${multipurposeFieldProps.value}
1949
+ type=${multipurposeFieldProps.type}
1950
+ onChange=${multipurposeFieldProps.onChange}
1951
+ endpointUrl=${multipurposeFieldProps.endpointUrl}
1952
+ isSearchable=${multipurposeFieldProps.isSearchable}
1953
+ allowTagsInText=${multipurposeFieldProps.allowTagsInText}
1954
+ isMappable=${multipurposeFieldProps.isMappable}
1955
+ isEditable=${multipurposeFieldProps.isEditable}
1956
+ hideTabs=${multipurposeFieldProps.hideTabs}
1957
+ />`
1958
+ : html`<${MultipurposeField}
1959
+ activityOutputData=${multipurposeFieldProps.activityOutputData}
1960
+ title=${multipurposeFieldProps.title}
1961
+ description=${multipurposeFieldProps.description}
1962
+ placeholder=${multipurposeFieldProps.placeholder}
1963
+ value=${multipurposeFieldProps.value}
1964
+ type=${multipurposeFieldProps.type}
1965
+ onChange=${multipurposeFieldProps.onChange}
1966
+ isMappable=${multipurposeFieldProps.isMappable}
1967
+ allowTagsInText=${multipurposeFieldProps.allowTagsInText}
1968
+ isSearchable=${multipurposeFieldProps.isSearchable}
1969
+ isEditable=${multipurposeFieldProps.isEditable}
1970
+ fieldId=${multipurposeFieldProps.fieldId}
1971
+ enableTagify=${multipurposeFieldProps.enableTagify}
1972
+ />`}
1973
+ </div>`,
1974
+ target,
1975
+ );
1976
+ } else {
1977
+ console.warn(
1978
+ `Integry SDK render target with id ${containerId} was not found`,
1979
+ );
1980
+ }
1981
+ };
1982
+
1983
+ public verifyAuthConfig = () =>
1984
+ this.apiHandler.verifyAuthConfig({
1985
+ deploymentId: this.config.deploymentId,
1986
+ });
1987
+
1988
+ private getUserVariables = async () => {
1989
+ try {
1990
+ const res = await this.apiHandler.getUserVariables();
1991
+ return res ? res.results : [];
1992
+ } catch (err) {
1993
+ console.error(err);
1994
+ return [];
1995
+ }
1996
+ };
1997
+
1998
+ /**
1999
+ * Destroy SDK instance and cleanup store
2000
+ */
2001
+ public destroy = () => {
2002
+ try {
2003
+ this.eventEmitter.offAll();
2004
+ const authIdElement = document.getElementById(this.authModalId);
2005
+ if (authIdElement) {
2006
+ authIdElement.remove();
2007
+ }
2008
+ } catch (error) {
2009
+ console.error('There was an error unsubscribing from all events');
2010
+ }
2011
+ };
2012
+
2013
+ static setFieldValue = (fieldId: string, value: string) => {
2014
+ const fieldElement = document
2015
+ .getElementById(fieldId)
2016
+ ?.querySelector('input') as HTMLInputElement | null;
2017
+ if (fieldElement) {
2018
+ if (fieldElement instanceof HTMLInputElement) {
2019
+ fieldElement.value = value;
2020
+ const keyupEvent = new KeyboardEvent('keyup', {
2021
+ key: 'a', // Specify the key (optional)
2022
+ bubbles: true, // Allow event to bubble up
2023
+ cancelable: true, // Allow event to be cancelable
2024
+ });
2025
+ fieldElement.dispatchEvent(keyupEvent);
2026
+ }
2027
+ }
2028
+ const tagifyFieldElement = document.getElementById(`tagify_${fieldId}`);
2029
+ if (tagifyFieldElement) {
2030
+ if (tagifyFieldElement instanceof HTMLInputElement) {
2031
+ tagifyFieldElement.value = value;
2032
+ const keyupEvent = new KeyboardEvent('keyup', {
2033
+ key: 'a', // Specify the key (optional)
2034
+ bubbles: true, // Allow event to bubble up
2035
+ cancelable: true, // Allow event to be cancelable
2036
+ });
2037
+ tagifyFieldElement.dispatchEvent(keyupEvent);
2038
+ }
2039
+ }
2040
+ };
2041
+
2042
+ private getMethod = () => 'POST';
2043
+
2044
+ private getBaseAPIUrl = () => 'https://api.integry.io';
2045
+
2046
+ private getHeaders = () => ({
2047
+ 'Content-Type': 'application/json',
2048
+ });
2049
+ }
2050
+
2051
+ export { Helpers, html };